Browse Source

Scrub privkeys from memory after done

warmup
jl777 5 years ago
parent
commit
ab4619c98b
  1. 2
      src/cc/CCtx.cpp
  2. 1
      src/cc/channels.cpp
  3. 1
      src/cc/dice.cpp
  4. 104
      src/cc/dilithium.c
  5. 23
      src/cc/gamescc.cpp
  6. 1
      src/cc/heir.cpp
  7. 2
      src/cc/heir_validate.h
  8. 1
      src/cc/marmara.cpp
  9. 2
      src/cc/musig.cpp
  10. 1
      src/cc/oracles.cpp
  11. 20
      src/cc/pegs.cpp
  12. 2
      src/cc/rogue_rpc.cpp
  13. 2
      src/komodo_nSPV.h
  14. 1
      src/wallet/rpcwallet.cpp

2
src/cc/CCtx.cpp

@ -108,6 +108,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
else
{
fprintf(stderr,"vin.%d vout.%d is bigger than vintx.%d\n",i,mtx.vin[i].prevout.n,(int32_t)vintx.vout.size());
memset(myprivkey,0,32);
return("");
}
}
@ -280,6 +281,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
if ( flag == 0 )
{
fprintf(stderr,"CC signing error: vini.%d has unknown CC address.(%s)\n",i,destaddr);
memset(myprivkey,0,32);
return("");
}
}

1
src/cc/channels.cpp

@ -453,6 +453,7 @@ int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, C
Myprivkey(myprivkey);
if (tokenid!=zeroid) CCaddrTokens1of2set(cp,srcpub,destpub,myprivkey,coinaddr);
else CCaddr1of2set(cp,srcpub,destpub,myprivkey,coinaddr);
memset(myprivkey,0,32);
return totalinputs;
}
else return 0;

1
src/cc/dice.cpp

@ -587,6 +587,7 @@ uint256 DiceHashEntropy(uint256 &entropy,uint256 _txidpriv,int32_t vout,int32_t
fprintf(stderr,"%02x",ssecret2.bytes[i]);
fprintf(stderr," ssecret2 dont match\n");
}
memset(tmp256.bytes,0,32);
//char str[65],str2[65];
//fprintf(stderr,"generated house hentropy.%s <- entropy.%s\n",uint256_str(str,hentropy),uint256_str(str2,entropy));
return(hentropy);

104
src/cc/dilithium.c

@ -3148,6 +3148,8 @@ UniValue dilithium_keypair(uint64_t txfee,struct CCcontract_info *cp,cJSON *para
if ( externalflag == 0 )
result.push_back(Pair("warning","test mode using privkey for -pubkey, only for testing. there is no point using quantum secure signing if you are using a privkey with a known secp256k1 pubkey!!"));
result.push_back(Pair("result","success"));
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(result);
}
@ -3194,9 +3196,23 @@ UniValue dilithium_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *par
if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,dilithiumpk));
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,dilithium_registeropret(handle,mypk,bigpub));
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(musig_rawtxresult(result,rawtx));
} else return(cclib_error(result,"couldnt find enough funds"));
} else return(cclib_error(result,"not enough parameters"));
}
else
{
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(cclib_error(result,"couldnt find enough funds"));
}
}
else
{
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(cclib_error(result,"not enough parameters"));
}
} else return(cclib_error(result,"not dilithiumpk funds"));
}
@ -3222,9 +3238,23 @@ UniValue dilithium_sign(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
result.push_back(Pair("signature",dilithium_hexstr(str,sm,smlen)));
calc_rmd160_sha256(rmd160,sm,smlen);
result.push_back(Pair("sighash",dilithium_hexstr(str,rmd160,20)));
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(result);
} else return(cclib_error(result,"unexpected signed message len"));
} else return(cclib_error(result,"not enough parameters"));
}
else
{
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(cclib_error(result,"unexpected signed message len"));
}
}
else
{
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(cclib_error(result,"not enough parameters"));
}
}
UniValue dilithium_verify(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
@ -3289,7 +3319,7 @@ UniValue dilithium_send(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
UniValue dilithium_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey mypk,destpub33; CTransaction vintx; uint256 prevhash,hashBlock,destpubtxid; int32_t i,smlen,n,numvouts; char str[129],*scriptstr; CTxOut vout; std::string handle; uint8_t pk[CRYPTO_PUBLICKEYBYTES],pk2[CRYPTO_PUBLICKEYBYTES],sk[CRYPTO_SECRETKEYBYTES],msg[32],seed[32]; std::vector<uint8_t> sig;
UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey mypk,destpub33; CTransaction vintx; uint256 prevhash,hashBlock,destpubtxid; int32_t i,smlen,n,numvouts; char str[129],*scriptstr,*retstr=""; CTxOut vout; std::string handle; uint8_t pk[CRYPTO_PUBLICKEYBYTES],pk2[CRYPTO_PUBLICKEYBYTES],sk[CRYPTO_SECRETKEYBYTES],msg[32],seed[32]; std::vector<uint8_t> sig;
if ( txfee == 0 )
txfee = DILITHIUM_TXFEE;
mypk = pubkey2pk(Mypubkey());
@ -3317,23 +3347,31 @@ UniValue dilithium_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params
if ( dilithium_sendopretdecode(destpubtxid,vintx.vout[numvouts-1].scriptPubKey) == 'x' )
{
if ( dilithium_bigpubget(handle,destpub33,pk2,destpubtxid) < 0 )
return(cclib_error(result,"couldnt get bigpub"));
retstr = (char *)"couldnt get bigpub";
else if ( memcmp(pk,pk2,sizeof(pk)) != 0 )
return(cclib_error(result,"dilithium bigpub mismatch"));
retstr = (char *)"dilithium bigpub mismatch";
else if ( destpub33 != mypk )
return(cclib_error(result,"destpub33 is not for this -pubkey"));
retstr = (char *)"destpub33 is not for this -pubkey";
else if ( _dilithium_sign(&sig[0],&smlen,msg,32,sk) < 0 )
return(cclib_error(result,"dilithium signing error"));
retstr = (char *)"dilithium signing error";
else if ( smlen != 32+CRYPTO_BYTES )
return(cclib_error(result,"siglen error"));
mtx.vin.push_back(CTxIn(prevhash,0));
mtx.vout.push_back(vout);
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,dilithium_spendopret(destpubtxid,sig));
return(dilithium_rawtxresult(result,rawtx));
} else return(cclib_error(result,"couldnt decode send opret"));
} else return(cclib_error(result,"couldnt find vin0"));
} else return(cclib_error(result,"script or bad destpubtxid is not hex"));
} else return(cclib_error(result,"need to have exactly 2 params sendtxid, scriptPubKey"));
retstr = (char *)"siglen error";
else
{
mtx.vin.push_back(CTxIn(prevhash,0));
mtx.vout.push_back(vout);
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,dilithium_spendopret(destpubtxid,sig));
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(dilithium_rawtxresult(result,rawtx));
}
} else retstr = (char *)"couldnt decode send opret";
} else retstr = (char *)"couldnt find vin0";
} else retstr = (char *)"script or bad destpubtxid is not hex";
} else retstr = (char *)"need to have exactly 2 params sendtxid, scriptPubKey";
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(cclib_error(result,retstr));
}
int64_t dilithium_inputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 destpubtxid,int64_t total,int32_t maxinputs,char *cmpaddr)
@ -3377,7 +3415,7 @@ int64_t dilithium_inputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPu
UniValue dilithium_Qsend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey mypk,destpub33; CTransaction tx,vintx; uint256 prevhash,mypubtxid,hashBlock,destpubtxid; int64_t amount,inputsum,outputsum,change; int32_t i,smlen,n,numvouts; char str[129],myCCaddr[64],*scriptstr; CTxOut vout; std::string handle; uint8_t pk[CRYPTO_PUBLICKEYBYTES],pk2[CRYPTO_PUBLICKEYBYTES],sk[CRYPTO_SECRETKEYBYTES],msg[32],seed[32]; std::vector<uint8_t> sig; std::vector<uint256> voutpubtxids;
UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey mypk,destpub33; CTransaction tx,vintx; uint256 prevhash,mypubtxid,hashBlock,destpubtxid; int64_t amount,inputsum,outputsum,change; int32_t i,smlen,n,numvouts; char str[129],myCCaddr[64],*scriptstr,*retstr=""; CTxOut vout; std::string handle; uint8_t pk[CRYPTO_PUBLICKEYBYTES],pk2[CRYPTO_PUBLICKEYBYTES],sk[CRYPTO_SECRETKEYBYTES],msg[32],seed[32]; std::vector<uint8_t> sig; std::vector<uint256> voutpubtxids;
if ( txfee == 0 )
txfee = DILITHIUM_TXFEE;
mypk = pubkey2pk(Mypubkey());
@ -3402,6 +3440,8 @@ UniValue dilithium_Qsend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params
if ( dilithium_bigpubget(handle,destpub33,pk2,prevhash) < 0 )
{
result.push_back(Pair("destpubtxid",prevhash.GetHex().c_str()));
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(cclib_error(result,"couldnt find bigpub at destpubtxid"));
}
else
@ -3437,19 +3477,27 @@ UniValue dilithium_Qsend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params
//fprintf(stderr," msg\n");
sig.resize(32+CRYPTO_BYTES);
if ( dilithium_bigpubget(handle,destpub33,pk2,mypubtxid) < 0 )
return(cclib_error(result,"couldnt get bigpub"));
retstr = (char *)"couldnt get bigpub";
else if ( memcmp(pk,pk2,sizeof(pk)) != 0 )
return(cclib_error(result,"dilithium bigpub mismatch"));
retstr = (char *)"dilithium bigpub mismatch";
else if ( destpub33 != mypk )
return(cclib_error(result,"destpub33 is not for this -pubkey"));
retstr = (char *)"destpub33 is not for this -pubkey";
else if ( _dilithium_sign(&sig[0],&smlen,msg,32,sk) < 0 )
return(cclib_error(result,"dilithium signing error"));
retstr = (char *)"dilithium signing error";
else if ( smlen != 32+CRYPTO_BYTES )
return(cclib_error(result,"siglen error"));
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,dilithium_Qsendopret(mypubtxid,sig,voutpubtxids));
return(dilithium_rawtxresult(result,rawtx));
} else return(cclib_error(result,"Q couldnt find enough Q or x inputs"));
} else return(cclib_error(result,"need to have exactly 2 params sendtxid, scriptPubKey"));
retstr = (char *)"siglen error";
else
{
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,dilithium_Qsendopret(mypubtxid,sig,voutpubtxids));
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(dilithium_rawtxresult(result,rawtx));
}
} else retstr = (char *)"Q couldnt find enough Q or x inputs";
} else retstr = (char *)"need to have exactly 2 params sendtxid, scriptPubKey";
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(cclib_error(result,retstr));
}
bool dilithium_Qvalidate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx)

23
src/cc/gamescc.cpp

@ -411,7 +411,7 @@ UniValue games_rng(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
int32_t games_eventsign(uint32_t &timestamp,std::vector<uint8_t> &sig,std::vector<uint8_t> payload,CPubKey pk)
{
static secp256k1_context *ctx;
size_t siglen = 74; secp256k1_pubkey pubkey; secp256k1_ecdsa_signature signature; int32_t len,verifyflag = 1; uint8_t privkey[32]; uint256 hash; uint32_t t;
size_t siglen = 74; secp256k1_pubkey pubkey; secp256k1_ecdsa_signature signature; int32_t len,verifyflag = 1,retval=-100; uint8_t privkey[32]; uint256 hash; uint32_t t;
if ( ctx == 0 )
ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
if ( ctx != 0 )
@ -439,10 +439,9 @@ int32_t games_eventsign(uint32_t &timestamp,std::vector<uint8_t> &sig,std::vecto
{
if ( siglen != sig.size() )
sig.resize(siglen);
return(0);
}
else return(-3);
} else return(-2);
retval = 0;
} else retval = -3;
} else retval = -2;
}
else
{
@ -451,12 +450,14 @@ int32_t games_eventsign(uint32_t &timestamp,std::vector<uint8_t> &sig,std::vecto
if ( secp256k1_ecdsa_signature_parse_der(ctx,&signature,&sig[0],sig.size()) > 0 )
{
if ( secp256k1_ecdsa_verify(ctx,&signature,(uint8_t *)&hash,&pubkey) > 0 )
return(0);
else return(-4);
} else return(-3);
} else return(-2);
retval = 0;
else retval = -4;
} else retval = -3;
} else retval = -2;
}
} else return(-1);
} else retval = -1;
memset(privkey,0,sizeof(privkey));
return(retval);
}
int32_t games_event(uint32_t timestamp,uint256 gametxid,int32_t eventid,std::vector<uint8_t> payload)
@ -1339,6 +1340,7 @@ UniValue games_keystrokes(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
CCaddr1of2set(cp,gamespk,mypk,mypriv,destaddr);
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,games_keystrokesopret(gametxid,batontxid,mypk,keystrokes));
//fprintf(stderr,"KEYSTROKES.(%s)\n",rawtx.c_str());
memset(mypriv,0,sizeof(mypriv));
return(games_rawtxresult(result,rawtx,1));
} else return(cclib_error(result,"keystrokes tx was too late"));
} else return(cclib_error(result,"couldnt find batontxid"));
@ -1612,6 +1614,7 @@ UniValue games_finish(uint64_t txfee,struct CCcontract_info *cp,cJSON *params,ch
GetOpReturnData(opret, vopretNonfungible);
rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, EncodeTokenCreateOpRet('c', Mypubkey(), std::string(seedstr), gametxid.GetHex(), vopretNonfungible));
}
memset(mypriv,0,sizeof(mypriv));
return(games_rawtxresult(result,rawtx,1));
}
result.push_back(Pair("result","success"));

1
src/cc/heir.cpp

@ -967,6 +967,7 @@ template <typename Helper>UniValue _HeirClaim(uint256 fundingtxid, int64_t txfee
std::string rawhextx = FinalizeCCTx(0, cp, mtx, myPubkey, txfee,
Helper::makeClaimOpRet(tokenid, voutTokenPubkeys, fundingtxid, (myPubkey == heirPubkey) ? 1 : hasHeirSpendingBegun)); // forward isHeirSpending to the next latest tx
memset(myprivkey,0,sizeof(myprivkey));
if (!rawhextx.empty()) {
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", rawhextx));

2
src/cc/heir_validate.h

@ -56,6 +56,7 @@ public:
uint8_t mypriv[32];
Myprivkey(mypriv);
CCaddr1of2set(cp, ownerPubkey, heirPubkey,mypriv, coinaddr);
memset(mypriv,0,sizeof(mypriv));
}
};
@ -101,6 +102,7 @@ public:
uint8_t mypriv[32];
Myprivkey(mypriv);
CCaddrTokens1of2set(cp, ownerPubkey, heirPubkey, mypriv, coinaddr);
memset(mypriv,0,sizeof(mypriv));
}
};

1
src/cc/marmara.cpp

@ -488,6 +488,7 @@ UniValue MarmaraLock(uint64_t txfee,int64_t amount,int32_t height)
}
}
}
memset(mypriv,0,sizeof(mypriv));
}
if ( inputsum >= amount+txfee )
{

2
src/cc/musig.cpp

@ -482,10 +482,12 @@ UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
MUSIG[musiglocation]->numcommits = 1;
result.push_back(Pair("commitment",str));
result.push_back(Pair("result","success"));
memset(privkey,0,sizeof(privkey));
return(result);
}
else
{
memset(privkey,0,sizeof(privkey));
memset(session,0,sizeof(session));
return(cclib_error(result,"couldnt initialize session"));
}

1
src/cc/oracles.cpp

@ -193,6 +193,7 @@ CPubKey OracleBatonPk(char *batonaddr,struct CCcontract_info *cp)
//fprintf(stderr,"batonpk.(%s) -> %s\n",(char *)HexStr(batonpk).c_str(),batonaddr);
strcpy(cp->unspendableaddr2,batonaddr);
} else fprintf(stderr,"error creating pubkey\n");
memset(priv,0,sizeof(priv));
return(batonpk);
}

20
src/cc/pegs.cpp

@ -439,7 +439,8 @@ int64_t AddPegsTokenInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,u
uint8_t mypriv[32];
Myprivkey(mypriv);
CCaddrTokens1of2set(cp,pk1,pk2,mypriv,coinaddr);
}
memset(mypriv,0,sizeof(mypriv));
}
}
return(totalinputs);
}
@ -753,6 +754,7 @@ std::string PegsFund(uint64_t txfee,uint256 pegstxid, uint256 tokenid,int64_t am
mtx.vin.push_back(CTxIn(accounttxid,1,CScript()));
GetCCaddress1of2(cp,coinaddr,mypk,pegspk);
CCaddr1of2set(cp,mypk,pegspk,mypriv,coinaddr);
memset(mypriv,0,sizeof(mypriv));
}
else funds=AddPegsInputs(cp,mtx,pegspk,CPubKey(),txfee+2*CC_MARKER_VALUE,3);
if (funds>=txfee+2*CC_MARKER_VALUE)
@ -839,7 +841,9 @@ std::string PegsGet(uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t am
Myprivkey(mypriv);
GetCCaddress1of2(cp,coinaddr,mypk,pegspk);
CCaddr1of2set(cp,mypk,pegspk,mypriv,coinaddr);
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
std::string retstr = FinalizeCCTx(0,cp,mtx,mypk,txfee,opret);
memset(mypriv,0,sizeof(mypriv));
return(retstr);
}
std::string PegsRedeem(uint64_t txfee,uint256 pegstxid, uint256 tokenid)
@ -929,28 +933,34 @@ std::string PegsRedeem(uint64_t txfee,uint256 pegstxid, uint256 tokenid)
account.first=0;
account.second=0;
LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "new account [deposit=" << account.first << ",debt=" << account.second << "]" << std::endl);
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodePegsReedemOpRet(tokenid,pegstxid,mypk,amount,account)));
std::string retstr = FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodePegsReedemOpRet(tokenid,pegstxid,mypk,amount,account));
memset(mypriv,0,32);
return(retstr);
}
else
{
CCerror = strprintf("not enough balance in pegs global CC address");
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
memset(mypriv,0,32);
return("");
}
}
CCerror = strprintf("not enough tokens in pegs account (%lld) to redeem this amount of tokens %lld",tokenfunds,account.first);
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
memset(mypriv,0,32);
return("");
}
else
{
CCerror = strprintf("not enough balance in pegs global CC address");
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
memset(mypriv,0,32);
return("");
}
}
CCerror = strprintf("to redeem from account and close it you must redeem full debt ammount %lld instead of %lld",account.second,funds);
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
memset(mypriv,0,32);
return("");
}

2
src/cc/rogue_rpc.cpp

@ -963,6 +963,7 @@ UniValue rogue_keystrokes(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
CCaddr1of2set(cp,roguepk,mypk,mypriv,destaddr);
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,rogue_keystrokesopret(gametxid,batontxid,mypk,keystrokes));
//fprintf(stderr,"KEYSTROKES.(%s)\n",rawtx.c_str());
memset(mypriv,0,32);
return(rogue_rawtxresult(result,rawtx,1));
} else return(cclib_error(result,"keystrokes tx was too late"));
} else return(cclib_error(result,"couldnt find batontxid"));
@ -1330,6 +1331,7 @@ UniValue rogue_finishgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
GetOpReturnData(opret, vopretNonfungible);
rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, EncodeTokenCreateOpRet('c', Mypubkey(), std::string(seedstr), gametxid.GetHex(), vopretNonfungible));
}
memset(mypriv,0,32);
return(rogue_rawtxresult(result,rawtx,1));
}
result.push_back(Pair("result","success"));

2
src/komodo_nSPV.h

@ -16,7 +16,7 @@
// todo:
// new p2p messages: getrawmempool and support myIsutxo_spentinmempool and mytxid_inmempool
// use mempool functions in CC: myIsutxo_spentinmempool and mytxid_inmempool
// headers "sync" make sure it connects to prior blocks to notarization. use getinfo hdrht to get missing hdrs

1
src/wallet/rpcwallet.cpp

@ -5399,6 +5399,7 @@ UniValue CCaddress(struct CCcontract_info *cp,char *name,std::vector<unsigned ch
Myprivkey(priv); // it is assumed the CC's normal address'es -pubkey was used
fprintf(stderr,"fix mismatched CCaddr %s -> %s\n",cp->unspendableCCaddr,destaddr);
strcpy(cp->unspendableCCaddr,destaddr);
memset(priv,0,32);
}
result.push_back(Pair("result", "success"));
sprintf(str,"%sCCAddress",name);

Loading…
Cancel
Save