Browse Source

Added CCaddr1of2set and FinalizeCCtx modified to support it

(small test CCerror code added - temp)
metaverse
dimxy 6 years ago
parent
commit
be71d108b2
  1. 65
      src/cc/CCassetstx.cpp
  2. 28
      src/cc/CCinclude.h
  3. 24
      src/cc/CCtx.cpp
  4. 8
      src/cc/CCutils.cpp
  5. 9
      src/cc/heir.cpp
  6. 8
      src/wallet/rpcwallet.cpp

65
src/cc/CCassetstx.cpp

@ -393,7 +393,7 @@ std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t p
uint64_t mask;
int64_t inputs, CCchange;
CScript opret;
struct CCcontract_info *cp,C;
struct CCcontract_info *cpTokens,C;
//std::cerr << "CreateSell() askamount=" << askamount << " pricetotal=" << pricetotal << std::endl;
@ -402,16 +402,16 @@ std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t p
return("");
}
cp = CCinit(&C, EVAL_TOKENS); // NOTE: tokens is here
cpTokens = CCinit(&C, EVAL_TOKENS); // NOTE: tokens is here
if ( txfee == 0 )
if (txfee == 0)
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
if (AddNormalinputs(mtx, mypk, txfee, 3) > 0)
{
mask = ~((1LL << mtx.vin.size()) - 1);
if ((inputs = AddTokenCCInputs(cp, mtx, mypk, assetid, askamount, 60)) > 0)
if ((inputs = AddTokenCCInputs(cpTokens, mtx, mypk, assetid, askamount, 60)) > 0)
{
if (inputs < askamount) {
//was: askamount = inputs;
@ -420,14 +420,14 @@ std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t p
return ("");
}
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS,askamount, GetUnspendable(cp,0)));
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS,askamount, GetUnspendable(cpTokens,0)));
if (inputs > askamount)
CCchange = (inputs - askamount);
if (CCchange != 0)
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, CCchange, mypk));
opret = EncodeAssetOpRet('s',assetid, zeroid, pricetotal, Mypubkey());
return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,opret));
return(FinalizeCCTx(mask,cpTokens,mtx,mypk,txfee,opret));
}
else {
fprintf(stderr, "need some tokens to place ask\n");
@ -439,6 +439,7 @@ std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t p
return("");
}
////////////////////////// NOT IMPLEMENTED YET/////////////////////////////////
std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 assetid2,int64_t pricetotal)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
@ -497,7 +498,7 @@ std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 a
}
return("");
}
} ////////////////////////// NOT IMPLEMENTED YET/////////////////////////////////
// unlocks coins
std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid)
@ -508,11 +509,11 @@ std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid)
uint256 hashBlock;
int64_t bidamount;
CPubKey mypk;
struct CCcontract_info *cp,C;
struct CCcontract_info *cpAssets, C;
cp = CCinit(&C, EVAL_ASSETS);
cpAssets = CCinit(&C, EVAL_ASSETS);
if ( txfee == 0 )
if (txfee == 0)
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
@ -525,7 +526,7 @@ std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid)
bidamount = vintx.vout[0].nValue;
mtx.vin.push_back(CTxIn(bidtxid, 0, CScript()));
mtx.vout.push_back(CTxOut(bidamount,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
return(FinalizeCCTx(mask, cp, mtx, mypk, txfee, EncodeAssetOpRet('o', assetid, zeroid, 0, Mypubkey())));
return(FinalizeCCTx(mask, cpAssets, mtx, mypk, txfee, EncodeAssetOpRet('o', assetid, zeroid, 0, Mypubkey())));
}
}
return("");
@ -536,11 +537,11 @@ std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CTransaction vintx; uint64_t mask; uint256 hashBlock; int64_t askamount; CPubKey mypk;
struct CCcontract_info *cp,C;
struct CCcontract_info *cpTokens, C;
cp = CCinit(&C, EVAL_TOKENS);
cpTokens = CCinit(&C, EVAL_TOKENS);
if ( txfee == 0 )
if (txfee == 0)
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
@ -553,7 +554,7 @@ std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid)
askamount = vintx.vout[0].nValue;
mtx.vin.push_back(CTxIn(asktxid, 0, CScript()));
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, askamount, mypk));
return(FinalizeCCTx(mask, cp, mtx, mypk, txfee, EncodeAssetOpRet('x', assetid, zeroid, 0, Mypubkey())));
return(FinalizeCCTx(mask, cpTokens, mtx, mypk, txfee, EncodeAssetOpRet('x', assetid, zeroid, 0, Mypubkey())));
}
}
return("");
@ -570,16 +571,18 @@ std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t f
int32_t bidvout=0;
uint64_t mask;
int64_t origprice, bidamount, paid_amount, remaining_required, inputs, CCchange=0;
struct CCcontract_info *cp,C;
struct CCcontract_info *cpTokens, tokensC;
struct CCcontract_info *cpAssets, assetsC;
if (fillamount < 0)
{
fprintf(stderr,"negative fillamount %lld\n", (long long)fillamount);
return("");
}
cp = CCinit(&C, EVAL_TOKENS);
cpTokens = CCinit(&tokensC, EVAL_TOKENS);
cpAssets = CCinit(&assetsC, EVAL_ASSETS);
if ( txfee == 0 )
if (txfee == 0)
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
@ -594,7 +597,7 @@ std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t f
mtx.vin.push_back(CTxIn(bidtxid, bidvout, CScript()));
if ((inputs = AddTokenCCInputs(cp, mtx, mypk, assetid, fillamount, 60)) > 0)
if ((inputs = AddTokenCCInputs(cpTokens, mtx, mypk, assetid, fillamount, 60)) > 0)
{
if (inputs < fillamount) {
std::cerr << "FillBuyOffer(): insufficient tokens to fill buy offer" << std::endl;
@ -607,16 +610,24 @@ std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t f
if (inputs > fillamount)
CCchange = (inputs - fillamount);
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, bidamount - paid_amount, GetUnspendable(cp,0))); // tokens
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, bidamount - paid_amount, GetUnspendable(cpTokens, NULL))); // tokens
mtx.vout.push_back(CTxOut(paid_amount,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, fillamount, pubkey2pk(origpubkey))); // coins
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, fillamount, pubkey2pk(origpubkey))); // coins on assets
if (CCchange != 0)
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, CCchange, mypk)); // coins
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, CCchange, mypk)); // coins on assets
fprintf(stderr,"remaining %llu -> origpubkey\n", (long long)remaining_required);
return(FinalizeCCTx(mask,cp,mtx,mypk,txfee, EncodeAssetOpRet('B', assetid, zeroid, remaining_required, origpubkey)));
// add additional unspendable addr from Assets:
char unspendableAssetsAddr[64];
uint8_t unspendableAssetsPrivkey[32];
CPubKey unspendableAssetsPk = GetUnspendable(cpAssets, unspendableAssetsPrivkey);
GetCCaddress(cpAssets, unspendableAssetsAddr, unspendableAssetsPk);
CCaddr2set(cpTokens, EVAL_ASSETS, unspendableAssetsPk, unspendableAssetsPrivkey, unspendableAssetsAddr);
return(FinalizeCCTx(mask,cpTokens,mtx,mypk,txfee, EncodeAssetOpRet('B', assetid, zeroid, remaining_required, origpubkey)));
} else return("dont have any assets to fill bid\n");
}
}
@ -694,16 +705,16 @@ std::string FillSell(int64_t txfee,uint256 assetid,uint256 assetid2,uint256 askt
if (assetid2 != zeroid && inputs > paid_nValue)
CCchange = (inputs - paid_nValue);
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, orig_assetoshis - received_assetoshis, GetUnspendable(cpAssets, NULL))); // coins
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, orig_assetoshis - received_assetoshis, GetUnspendable(cpAssets, NULL))); // coins in Assets cc addr
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, received_assetoshis, mypk)); // tokens
if (assetid2 != zeroid)
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, paid_nValue, origpubkey)); // tokens (not implemented correctly)
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, paid_nValue, origpubkey)); // tokens... (swap is not implemented yet)
else
mtx.vout.push_back(CTxOut(paid_nValue, CScript() << origpubkey << OP_CHECKSIG)); // coins
mtx.vout.push_back(CTxOut(paid_nValue, CScript() << origpubkey << OP_CHECKSIG)); // coins normal
if (CCchange != 0)
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, CCchange, mypk)); // coins
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, CCchange, mypk)); // coins in Assets cc addr
return(FinalizeCCTx(mask,cpTokens,mtx,mypk,txfee,EncodeAssetOpRet(assetid2 != zeroid ? 'E' : 'S', assetid, assetid2, remaining_nValue, origpubkey)));
} else {

28
src/cc/CCinclude.h

@ -86,12 +86,27 @@ struct CC_meta
struct CCcontract_info
{
char unspendableCCaddr[64],CChexstr[72],normaladdr[64],unspendableaddr2[64],unspendableaddr3[64];
uint8_t CCpriv[32],unspendablepriv2[32],unspendablepriv3[32];
CPubKey unspendablepk2,unspendablepk3;
bool (*validate)(struct CCcontract_info *cp, Eval* eval, const CTransaction &tx, uint32_t nIn);
bool (*ismyvin)(CScript const& scriptSig);
uint8_t evalcode,evalcode2,evalcode3,didinit;
// this is for spending from 'unspendable' CC address
uint8_t evalcode;
char unspendableCCaddr[64], CChexstr[72], normaladdr[64];
uint8_t CCpriv[32];
// this for 1of2 key spending condition (for this evalcode)
// NOTE: only one evalcode is allowed at this time
char unspendable1of2addr[64];
CPubKey unspendable1of2pk[2];
// this is for spending from two additional 'unspendable' CC addresses of other eval codes
// (that is, for spending from several cc contract 'unspendable' addresses):
uint8_t evalcode2, evalcode3;
char unspendableaddr2[64], unspendableaddr3[64];
uint8_t unspendablepriv2[32], unspendablepriv3[32];
CPubKey unspendablepk2, unspendablepk3;
bool (*validate)(struct CCcontract_info *cp, Eval* eval, const CTransaction &tx, uint32_t nIn); // cc contract tx validation callback
bool (*ismyvin)(CScript const& scriptSig); // checks if evalcode is present in the scriptSig param
uint8_t didinit;
};
struct CCcontract_info *CCinit(struct CCcontract_info *cp,uint8_t evalcode);
@ -164,6 +179,7 @@ CC *MakeCCcond1of2(uint8_t evalcode,CPubKey pk1,CPubKey pk2);
CC* GetCryptoCondition(CScript const& scriptSig);
void CCaddr2set(struct CCcontract_info *cp,uint8_t evalcode,CPubKey pk,uint8_t *priv,char *coinaddr);
void CCaddr3set(struct CCcontract_info *cp,uint8_t evalcode,CPubKey pk,uint8_t *priv,char *coinaddr);
void CCaddr1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2, char *coinaddr);
bool IsCCInput(CScript const& scriptSig);
int32_t unstringbits(char *buf,uint64_t bits);
uint64_t stringbits(char *str);

24
src/cc/CCtx.cpp

@ -44,7 +44,10 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
CTransaction vintx; std::string hex; uint256 hashBlock; uint64_t mask=0,nmask=0,vinimask=0;
int64_t utxovalues[CC_MAXVINS],change,normalinputs=0,totaloutputs=0,normaloutputs=0,totalinputs=0,normalvins=0,ccvins=0;
int32_t i,utxovout,n,err = 0; char myaddr[64],destaddr[64],unspendable[64];
uint8_t *privkey,myprivkey[32],unspendablepriv[32],*msg32 = 0; CC *mycond=0,*othercond=0,*othercond2=0,*othercond3=0,*cond; CPubKey unspendablepk;
uint8_t *privkey,myprivkey[32],unspendablepriv[32],*msg32 = 0;
CC *mycond=0, *othercond=0, *othercond2=0, *othercond3=0, *othercond1of2=NULL, *cond;
CPubKey unspendablepk;
n = mtx.vout.size();
for (i=0; i<n; i++)
{
@ -140,16 +143,18 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
cond = othercond;
//fprintf(stderr,"unspendable CC addr.(%s)\n",unspendable);
}
// check if this is the 2nd additional evalcode + 'unspendable' cc addr:
else if ( strcmp(destaddr,cp->unspendableaddr2) == 0)
{
//fprintf(stderr,"matched %s unspendable2!\n",cp->unspendableaddr2);
privkey = cp->unspendablepriv2;
if ( othercond2 == 0 && cp->evalcode != EVAL_CHANNELS && cp->evalcode != EVAL_HEIR && cp->evalcode != EVAL_ASSETS && cp->evalcode != EVAL_TOKENS)
othercond2 = MakeCCcond1(cp->evalcode2,cp->unspendablepk2);
else if ( othercond2 == 0 && (cp->evalcode == EVAL_CHANNELS || cp->evalcode == EVAL_HEIR || cp->evalcode == EVAL_ASSETS || cp->evalcode == EVAL_TOKENS) )
othercond2 = MakeCCcond1of2(cp->evalcode2,cp->unspendablepk2,cp->unspendablepk3);
if ( othercond2 == 0 ) //&& cp->evalcode != EVAL_CHANNELS && cp->evalcode != EVAL_HEIR && cp->evalcode != EVAL_ASSETS && cp->evalcode != EVAL_TOKENS)
othercond2 = MakeCCcond1(cp->evalcode2, cp->unspendablepk2);
//else if ( othercond2 == 0 && (cp->evalcode == EVAL_CHANNELS || cp->evalcode == EVAL_HEIR || cp->evalcode == EVAL_ASSETS || cp->evalcode == EVAL_TOKENS) )
// othercond2 = MakeCCcond1of2(cp->evalcode2,cp->unspendablepk2,cp->unspendablepk3);
cond = othercond2;
}
// check if this is 3rd additional evalcode + 'unspendable' cc addr:
else if ( strcmp(destaddr,cp->unspendableaddr3) == 0 )
{
//fprintf(stderr,"matched %s unspendable3!\n",cp->unspendableaddr3);
@ -158,6 +163,15 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
othercond3 = MakeCCcond1(cp->evalcode3,cp->unspendablepk3);
cond = othercond3;
}
// check if this is spending from 1of2 cc addr:
else if (strcmp(cp->unspendable1of2addr, destaddr) == 0)
{
//fprintf(stderr,"matched %s unspendable1of2!\n",cp->unspendable1of2addr);
privkey = myprivkey;
if (othercond1of2 == 0)
othercond1of2 = MakeCCcond1of2(cp->evalcode, cp->unspendable1of2pk[0], cp->unspendable1of2pk[1]);
cond = othercond1of2;
}
else
{
fprintf(stderr,"CC signing error: vini.%d has unknown CC address.(%s)\n",i,destaddr);

8
src/cc/CCutils.cpp

@ -195,6 +195,14 @@ void CCaddr3set(struct CCcontract_info *cp,uint8_t evalcode,CPubKey pk,uint8_t *
strcpy(cp->unspendableaddr3,coinaddr);
}
// set pubkeys, myprivkey and 1of2 cc addr for spending from 1of2 cryptocondition vout:
void CCaddr1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2, char *coinaddr)
{
cp->unspendable1of2pk[0] = pk1;
cp->unspendable1of2pk[1] = pk2;
strcpy(cp->unspendable1of2addr, coinaddr);
}
bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey)
{
CTxDestination address; txnouttype whichType;

9
src/cc/heir.cpp

@ -1061,11 +1061,12 @@ template <typename Helper>UniValue HeirClaim(uint256 fundingtxid, uint64_t txfee
GetCCaddress1of2(cp, coinaddr, ownerPubkey, heirPubkey);
Myprivkey(myprivkey);
//fprintf(stderr,"HeirClaim() before setting unspendable CC addr2= (%s) addr3= (%s)\n", cp->unspendableaddr2, cp->unspendableaddr3);
CCaddr2set(cp, Helper::getMyEval(), ownerPubkey, myprivkey, coinaddr);
CCaddr3set(cp, Helper::getMyEval(), heirPubkey, myprivkey, coinaddr);
////fprintf(stderr,"HeirClaim() before setting unspendable CC addr2= (%s) addr3= (%s)\n", cp->unspendableaddr2, cp->unspendableaddr3);
//CCaddr2set(cp, Helper::getMyEval(), ownerPubkey, myprivkey, coinaddr);
//CCaddr3set(cp, Helper::getMyEval(), heirPubkey, myprivkey, coinaddr);
////fprintf(stderr, "HeirClaim() after setting unspendable CC addr2=(%s) addr3=(%s)\n", cp->unspendableaddr2, cp->unspendableaddr3);
fprintf(stderr, "HeirClaim() after setting unspendable CC addr2=(%s) addr3=(%s)\n", cp->unspendableaddr2, cp->unspendableaddr3);
CCaddr1of2set(cp, ownerPubkey, heirPubkey, coinaddr);
// add opreturn 'C' and sign tx: // this txfee will be ignored
std::string rawhextx = FinalizeCCTx(0, cp, mtx, myPubkey, txfee,

8
src/wallet/rpcwallet.cpp

@ -6952,12 +6952,20 @@ UniValue tokenlist(const UniValue& params, bool fHelp)
UniValue tokeninfo(const UniValue& params, bool fHelp)
{
#ifdef TESTMODE
std::cerr << "is CCerror clear? CCerror=" << CCerror << std::endl;
#endif
uint256 tokenid;
if ( fHelp || params.size() != 1 )
throw runtime_error("tokeninfo tokenid\n");
if ( ensure_CCrequirements() < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
tokenid = Parseuint256((char *)params[0].get_str().c_str());
#ifdef TESTMODE
CCerror = "test error";
#endif
return(AssetInfo(tokenid));
}

Loading…
Cancel
Save