From 325d3231851d54879f554497e864e5edeaf77980 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 19 Jul 2018 21:41:52 -1100 Subject: [PATCH 01/15] Complete core coding for AE with partial fills --- src/cc/assets.cpp | 631 +++++++++++++++++++++++----------------------- 1 file changed, 314 insertions(+), 317 deletions(-) diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index 8e5cc6cbd..cf88b0757 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -20,6 +20,9 @@ #include "../script/standard.h" #include "../base58.h" +// debugging: need to clarify tx, inputTx, origTx +// code rpc + /* Assets can be created or transferred. @@ -61,66 +64,69 @@ vout.n-2: normal output for change (if any) vout.n-1: opreturn [EVAL_ASSETS] ['t'] [assetid] + buyoffer: + vins.*: normal inputs (bid + change) + vout.0: amount of bid to unspendable + vout.1: normal output for change (if any) + vout.n-1: opreturn [EVAL_ASSETS] ['b'] [assetid] [amount of asset required] [origpubkey] + + cancelbuy: + vin.0: normal input + vin.1: unspendable.(vout.0 from buyoffer) buyTx.vout[0] + vout.0: vin.1 value to original pubkey buyTx.vout[0].nValue -> [origpubkey] + vout.1: normal output for change (if any) + vout.n-1: opreturn [EVAL_ASSETS] ['o'] + + fillbuy: + vin.0: normal input + vin.1: unspendable.(vout.0 from buyoffer) buyTx.vout[0] + vin.2: valid CC output satisfies buyoffer (*tx.vin[2])->nValue + vout.0: remaining amount of bid to unspendable + vout.1: vin.1 value to signer of vin.2 + vout.2: vin.2 assetoshis to original pubkey + vout.3: normal output for change (if any) + vout.n-1: opreturn [EVAL_ASSETS] ['B'] [assetid] [remaining asset required] [origpubkey] + selloffer: vin.0: normal input vin.1: valid CC output for sale vout.0: vin.1 assetoshis output to CC to unspendable vout.1: normal output for change (if any) - vout.n-1: opreturn [EVAL_ASSETS] ['s'] [assetid] [amount of native coin required] - - buyoffer: - vins.*: normal inputs (bid + change) - vout.0: amount of bid to unspendable - vout.1: normal output for change (if any) - vout.n-1: opreturn [EVAL_ASSETS] ['b'] [assetid] [amount of asset required] + vout.n-1: opreturn [EVAL_ASSETS] ['s'] [assetid] [amount of native coin required] [origpubkey] exchange: vin.0: normal input vin.1: valid CC output vout.0: vin.1 assetoshis output to CC to unspendable vout.1: normal output for change (if any) - vout.n-1: opreturn [EVAL_ASSETS] ['e'] [assetid] [assetid2] [amount of asset2 required] - - cancelbuy: - vin.0: normal input - vin.1: unspendable.(vout.1 from buyoffer) - vout.0: vin.1 value to original pubkey - vout.1: normal output for change (if any) - vout.n-1: opreturn [EVAL_ASSETS] ['o'] [assetid] + vout.n-1: opreturn [EVAL_ASSETS] ['e'] [assetid] [assetid2] [amount of asset2 required] [origpubkey] cancel: vin.0: normal input - vin.1: unspendable.(vout.1 from exchange or selloffer) - vout.0: vin.1 assetoshis to original pubkey CC + vin.1: unspendable.(vout.0 from exchange or selloffer) sellTx/exchangeTx.vout[0] inputTx + vout.0: vin.1 assetoshis to original pubkey CC sellTx/exchangeTx.vout[0].nValue -> [origpubkey] vout.1: normal output for change (if any) vout.n-1: opreturn [EVAL_ASSETS] ['x'] [assetid] fillsell: vin.0: normal input - vin.1: unspendable.(vout.1 assetoshis from selloffer) - vin.2: normal output that satisfies selloffer - vout.0: vin.1 assetoshis to signer of vin.2 - vout.1: vin.2 value to original pubkey - vout.2: normal output for change (if any) - vout.n-1: opreturn [EVAL_ASSETS] ['S'] [assetid] - - fillbuy: - vin.0: normal input - vin.1: unspendable.(vout.1 from buyoffer) - vin.2: valid CC output satisfies buyoffer - vout.0: vin.1 value to signer of vin.2 - vout.1: vin.2 assetoshis to original pubkey - vout.2: normal output for change (if any) - vout.n-1: opreturn [EVAL_ASSETS] ['B'] [assetid] + vin.1: unspendable.(vout.0 assetoshis from selloffer) sellTx.vout[0] + vin.2: normal output that satisfies selloffer (*tx.vin[2])->nValue + vout.0: remaining assetoshis -> unspendable + vout.1: vin.1 assetoshis to signer of vin.2 sellTx.vout[0].nValue -> any + vout.2: vin.2 value to original pubkey [origpubkey] + vout.3: normal output for change (if any) + vout.n-1: opreturn [EVAL_ASSETS] ['S'] [assetid] [amount of coin still required] [origpubkey] fillexchange: vin.0: normal input - vin.1: unspendable.(vout.1 assetoshis from exchange) - vin.2: valid CC output that satisfies exchange - vout.0: vin.1 assetoshis to signer of vin.2 - vout.1: vin.2 assetoshis to original pubkey - vout.2: normal output for change (if any) - vout.n-1: opreturn [EVAL_ASSETS] ['E'] [assetid vin1] [assetid vin2] + vin.1: unspendable.(vout.0 assetoshis from exchange) exchangeTx.vout[0] + vin.2: valid CC assetid2 output that satisfies exchange (*tx.vin[2])->nValue + vout.0: remaining assetoshis -> unspendable + vout.1: vin.1 assetoshis to signer of vin.2 exchangeTx.vout[0].nValue -> any + vout.2: vin.2 assetoshis2 to original pubkey [origpubkey] + vout.3: normal output for change (if any) + vout.n-1: opreturn [EVAL_ASSETS] ['E'] [assetid vin0+1] [assetid vin2] [remaining asset2 required] [origpubkey] */ @@ -150,6 +156,60 @@ signEncodeTx "$transferTx" const char *Unspendableaddr = "RHTcNNYXEZhLGRcXspA2H4gw2v4u6w8MNp"; +bool Getscriptaddress(char *destaddr,CScript &scriptPubKey) +{ + CTxDestination address; + if ( ExtractDestination(scriptPubKey,address) != 0 ) + { + strcpy(destaddr,(char *)CBitcoinAddress(address).ToString().c_str()); + return(true); + } + return(false) +} + +uint8_t DecodeOpRet(CScript const& scriptPubKey,uint256 &assetid,uint256 &assetid2,uint64_t &price,std::vector &origpubkey) +{ + std::vector vopret; uint8_t funcid=0,*script; + GetOpReturnData(scriptPubKey, vopret); + script = (uint8_t *)vopret.data(); + memset(&assetid,0,sizeof(assetid)); + memset(&assetid2,0,sizeof(assetid2)); + price = 0; + if ( script[0] == EVAL_ASSETS ) + { + funcid = script[1]; + switch ( funcid ) + { + case 'o': + return(funcid); + break; + case 't': case 'x': + if ( E_UNMARSHAL(vopret, ss >> assetid) != 0 ) + return(funcid); + break; + case 's': case 'b': case 'S': case 'B': + if ( E_UNMARSHAL(vopret, ss >> assetid; ss >> price; ss >> origpubkey) != 0 ) + return(funcid); + break; + case 'E': case 'e': + if ( E_UNMARSHAL(vopret, ss >> assetid; ss >> assetid2; ss >> price; ss >> origpubkey) != 0 ) + return(funcid); + break; + } + } + return(funcid); +} + +bool Getorigaddr(char *destaddr,CTransaction& tx) +{ + uint256 assetid,assetid2; uint64_t price,nValue=0; int32_t n; uint8_t funcid; std::vector origpubkey; CScript script; + n = tx.vout.size(); + if ( n == 0 || (funcid= DecodeOpRet(tx.vout[n-1].scriptPubKey,assetid,assetid2,price,origpubkey)) == 0 ) + return(false); + script = CScript() << origpubkey << OP_CHECKSIG; + return(Getscriptaddress(destaddr,script)) +} + CC* GetCryptoCondition(CScript const& scriptSig) { auto pc = scriptSig.begin(); @@ -176,158 +236,102 @@ bool IsAssetInput(CScript const& scriptSig) return out; } -uint8_t DecodeOpRet(CScript const& scriptPubKey,uint256 &assetid,uint256 &assetid2,uint64_t &amount) +uint64_t IsAssetvout(uint64_t &price,std::vector &origpubkey,CTransaction& tx,int32_t v,uint256 refassetid) { - std::vector vopret; uint8_t funcid=0,*script; - GetOpReturnData(scriptPubKey, vopret); - script = (uint8_t *)vopret.data(); - memset(&assetid,0,sizeof(assetid)); - memset(&assetid2,0,sizeof(assetid2)); - amount = 0; - if ( script[0] == EVAL_ASSETS ) + uint256 assetid,assetid2; uint64_t nValue=0; int32_t n; uint8_t funcid; + if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) { - funcid = script[1]; - switch ( funcid ) - { - case 't': case 'o': case 'x': case 'S': case 'B': - if ( E_UNMARSHAL(vopret, ss >> assetid) != 0 ) - return(funcid); - break; - case 's': case 'b': - if ( E_UNMARSHAL(vopret, ss >> assetid; ss >> amount) != 0 ) - return(funcid); - break; - case 'E': - if ( E_UNMARSHAL(vopret, ss >> assetid; ss >> assetid2) != 0 ) - return(funcid); - break; - case 'e': - if ( E_UNMARSHAL(vopret, ss >> assetid; ss >> assetid2; ss >> amount) != 0 ) - return(funcid); - break; - } - } - return(funcid); -} - -uint64_t IsAssetTx(uint64_t *origamountp,uint8_t funcid,int32_t vini,uint256 assetid,CTransaction& inputTx,int32_t v) -{ - // Either the tx will be a CREATE (no CC inputs) or a TRANSFER (1 or more CC inputs) - uint256 inputassetid,inputassetid2; uint64_t amount; uint8_t inputfuncid; unsigned int i,n,r = 0; - if ( origamountp != 0 ) - *origamountp = 0; - for (i=0; i 0 ) - { - n = inputTx.vout.size(); - if ( (inputfuncid= DecodeOpRet(inputTx.vout[n-1].scriptPubKey,inputassetid,inputassetid2,amount)) == 0 ) - return(0); - if ( origamountp != 0 ) - *origamountp = amount; + n = tx.vout.size(); if ( v >= n-1 ) return(0); - if ( inputfuncid != 'E' || vini == 1 ) + nValue = tx.vout[v].nValue; + if ( (funcid= DecodeOpRet(tx.vout[n-1].scriptPubKey,assetid,assetid2,price,origpubkey)) == 0 ) + return(0); + if ( funcid == 'c' ) { - if ( inputassetid == assetid ) - return(inputTx.vout[v].nValue); + if ( refassetid == tTx.GetHash() && v == 0 ) + return(nValue); } - else // 'E' and vini == 2 + else if ( funcid != 'E' ) { - if ( inputassetid2 == assetid ) - return(inputTx.vout[v].nValue); + if ( assetid == refassetid ) + return(nValue); + } + else if ( funcid == 'E' ) + { + if ( v < 2 && assetid == refassetid ) + return(nValue); + else if ( v == 2 && assetid2 == refassetid ) + return(nValue); } } - else if ( r == 0 ) // It's a CREATE, compare hash directly - { - if ( assetid == inputTx.GetHash() && v == 0 ) // asset create must use vout[0] for the asset - return(inputTx.vout[v].nValue); - } - // should never happen - fprintf(stderr, "Illegal state detected, mixed inputs for asset at: %s\n",assetid.GetHex().data()); return(0); } -uint64_t AssetIsvalidCCvin(Eval* eval,uint8_t funcid,uint256 assetid,uint64_t *origamountp,uint64_t *origoutp,char *origaddr,const CTransaction &tx,int32_t vini) +uint64_t AssetValidatevin(Eval* eval,char *origaddr,const CTransaction &tx,const CTransaction &vinTx) { - CTransaction inputTx,origTx; CTxDestination address; uint256 hashBlock; int32_t v; uint64_t nValue = 0; - v = tx.vin[vini].prevout.n; - if ( eval->GetTxUnconfirmed(tx.vin[vini].prevout.hash,inputTx,hashBlock) == 0 ) + uint256 hashBlock; char destaddr[64]; + origaddr[0] = destaddr[0] = 0; + if ( tx.vin[1].prevout.n != 0 ) + return eval->Invalid("vin1 needs to be buyvin.vout[0]"); + else if ( eval->GetTxUnconfirmed(tx.vin[1].prevout.hash,vinTx,hashBlock) == 0 ) return eval->Invalid("always should find vin, but didnt"); - if ( IsAssetInput(tx.vin[vini].scriptSig) != 0 ) - { - if ( (nValue= IsAssetTx(origamountp,funcid,vini,assetid,inputTx,v)) == 0 ) - return eval->Invalid("Non asset / wrong asset input tx"); - } - if ( origaddr != 0 && origoutp != 0 ) - { - origaddr[0] = 0; - *origoutp = 0; - if ( eval->GetTxUnconfirmed(inputTx.vin[vini].prevout.hash,origTx,hashBlock) == 0 ) - return eval->Invalid("always should find origtx, but didnt for cancelbuy"); - if ( ExtractDestination(origTx.vout[inputTx.vin[vini].prevout.n].scriptPubKey,address) == 0 ) - return eval->Invalid("no origtx address for cancelbuy"); - strcpy(origaddr,(char *)CBitcoinAddress(address).ToString().c_str()); - *origoutp = inputTx.vout[0].nValue; - } - return(nValue); + else if ( Getscriptaddress(destaddr,vinTx.vout[0].scriptPubKey) == 0 || strcmp(destaddr,Unspendableaddr) != 0 ) + return eval->Invalid("invalid vin unspendableaddr"); + else if ( vinTx.vout[0].nValue < 10000 ) + return eval->Invalid("invalid dust for buyvin"); + else if ( Getorigaddr(origaddr,vinTx) == 0 ) + return eval->Invalid("couldnt get origaddr for buyvin"); + else return(vinTx.vout[0].nValue); } -uint64_t AssetIsvalidvin(Eval* eval,uint64_t *origamountp,uint64_t *origoutp,char *origaddr,const CTransaction &tx,int32_t vini) +uint64_t AssetValidateBuyvin(Eval* eval,uint64_t &tmpprice,std::vector &tmporigpubkey,char *origaddr,const CTransaction &tx) { - CTransaction inputTx,origTx; CTxDestination address; uint256 hashBlock,inputassetid,inputassetid2; int32_t v; uint8_t inputfuncid; uint64_t amount,nValue = 0; - v = tx.vin[vini].prevout.n; - *origamountp = 0; - if ( eval->GetTxUnconfirmed(tx.vin[vini].prevout.hash,inputTx,hashBlock) == 0 ) - return eval->Invalid("always should find vin, but didnt"); - if ( (inputfuncid= DecodeOpRet(inputTx.vout[inputTx.vout.size()-1].scriptPubKey,inputassetid,inputassetid2,amount)) == 0 ) + const CTransaction vinTx; uint64_t nValue; uint256 assetid,assetid2; + if ( (nValue= AssetValidatevin(eval,origaddr,tx,vinTx)) == 0 ) return(0); - nValue = inputTx.vout[v].nValue; - *origamountp = amount; - if ( origaddr != 0 && origoutp != 0 ) + else if ( vinTx.vout[0].scriptPubKey.IsPayToCryptoCondition() != 0 ) + return eval->Invalid("invalid CC vout0 for buyvin"); + else if ( DecodeOpRet(vinTx.vout[vinTx.vout.size()-1].scriptPubKey,assetid,assetid2,tmpprice,tmporigpubkey)) == 0 ) + return eval->Invalid("invalid opreturn for buyvin"); + else return(nValue); +} + +uint64_t AssetValidateSellvin(Eval* eval,uint64_t &tmpprice,std::vector &tmporigpubkey,char *origaddr,const CTransaction &tx,uint256 assetid) +{ + const CTransaction vinTx; uint64_t nValue,assetoshis; + if ( (nValue= AssetValidatevin(eval,origaddr,tx,vinTx)) == 0 ) + return(0); + if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,vinTx,0,assetid)) != 0 ) + return eval->Invalid("invalid missing CC vout0 for sellvin"); + else return(assetoshis); +} + +bool ValidateRemainder(uint64_t remaining_price,uint64_t remaining_nValue,uint64_t orig_nValue,uint64_t received,uint64_t paid,uint64_t totalprice) +{ + uint64_t price,recvprice; + if ( orig_nValue == 0 || received == 0 || paid == 0 || totalprice == 0 ) + return(false); + else if ( remaining_price < (totalprice - received) ) + return(false); + else if ( remaining_nValue < (orig_nValue - paid) ) + return(false); + else if ( remaining_nValue > 0 ) { - origaddr[0] = 0; - *origoutp = 0; - if ( eval->GetTxUnconfirmed(inputTx.vin[vini].prevout.hash,origTx,hashBlock) == 0 ) - return eval->Invalid("always should find origtx, but didnt for cancelbuy"); - if ( ExtractDestination(origTx.vout[inputTx.vin[vini].prevout.n].scriptPubKey,address) == 0 ) - return eval->Invalid("no origtx address for cancelbuy"); - strcpy(origaddr,(char *)CBitcoinAddress(address).ToString().c_str()); - *origoutp = inputTx.vout[0].nValue; + price = (totalprice * COIN) / orig_nValue; + recvprice = (received * COIN) / paid; + if ( recvprice < price ) + return(false); } - return(nValue); + return(true); } -uint64_t Assetvini2val(Eval* eval,int32_t needasset,uint256 assetid,const CTransaction &tx) -{ - CTransaction inputTx; uint256 hashBlock; - if ( needasset != 0 && IsAssetInput(tx.vin[2].scriptSig) == 0 ) - return eval->Invalid("vini2 is not CC"); - if ( eval->GetTxUnconfirmed(tx.vin[2].prevout.hash,inputTx,hashBlock) == 0 ) - return eval->Invalid("always should find vin, but didnt"); - return(inputTx.vout[tx.vin[2].prevout.n].nValue); -} - -uint64_t AssetIsvalidvout0(Eval* eval,const CTransaction &tx,uint64_t nValue) -{ - CTxDestination address; - if ( tx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 ) - return eval->Invalid("illegal normal vout0"); - if ( tx.vout[0].nValue != nValue ) - return eval->Invalid("nValue mismatch vout0"); - if ( ExtractDestination(tx.vout[0].scriptPubKey,address) == 0 ) - return eval->Invalid("no vout0 address"); - if ( strcmp(Unspendableaddr,(char *)CBitcoinAddress(address).ToString().c_str()) != 0 ) - return eval->Invalid("invalid vout0 address"); - return(nValue); -} - -bool AssetValidate(Eval* eval,const CTransaction &tx,int32_t numvouts,uint8_t funcid,uint256 assetid,uint256 assetid2,uint64_t amount) +bool AssetValidate(Eval* eval,const CTransaction &tx,int32_t numvouts,uint8_t funcid,uint256 assetid,uint256 assetid2,uint64_t remaining_price,std::vector origpubkey) { static uint256 zero; - CTxDestination address; uint256 hashBlock; int32_t i,r,numvins; uint64_t nValue,vini2val,origamount,outputs,assetoshis,origout; char origaddr[64]; + CTxDestination address; const CTransaction vinTx; uint256 hashBlock; int32_t i,numvins; uint64_t nValue,assetoshis,outputs,inputs,tmpprice,ignore; std::vector tmporigpubkey,ignorepubkey; char destaddr[64],origaddr[64]; numvins = tx.vin.size(); - assetoshis = outputs = 0; + outputs = inputs = 0; if ( IsAssetInput(tx.vin[0].scriptSig) != 0 ) return eval->Invalid("illegal asset vin0"); if ( funcid != 'c' && assetid == zero ) @@ -339,8 +343,7 @@ bool AssetValidate(Eval* eval,const CTransaction &tx,int32_t numvouts,uint8_t fu //vout.0: issuance assetoshis to CC //vout.1: normal output for change (if any) //vout.n-1: opreturn [EVAL_ASSETS] ['c'] [{"":""}] - if ( tx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 ) - return eval->Invalid("illegal normal vout0 for createasset"); + return eval->Invalid("unexpected AssetValidate for createasset"); break; case 't': // transfer @@ -349,172 +352,184 @@ bool AssetValidate(Eval* eval,const CTransaction &tx,int32_t numvouts,uint8_t fu //vout.0 to n-2: assetoshis output to CC //vout.n-2: normal output for change (if any) //vout.n-1: opreturn [EVAL_ASSETS] ['t'] [assetid] - for (r=0,i=1; iInvalid("illegal normal vin for transfer"); + if ( IsAssetInput(tx.vin[i].scriptSig) != 0 ) + { + if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 ) + return eval->Invalid("always should find vin, but didnt"); + else if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,vinTx,tx.vin[i].prevout.n,assetid)) != 0 ) + inputs += assetoshis; + } } for (i=0; iInvalid("non-CC asset transfer vout"); + if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,tx,i,assetid)) != 0 ) + outputs += assetoshis; } - if ( assetoshis == 0 ) + if ( inputs == 0 ) return eval->Invalid("no asset inputs for transfer"); - else if ( assetoshis != outputs ) + else if ( inputs != outputs ) return eval->Invalid("mismatched inputs and outputs for transfer"); break; - - case 's': // selloffer - //vin.0: normal input - //vin.1: valid CC output for sale - //vout.0: vin.1 assetoshis output to CC to unspendable - //vout.1: normal output for change (if any) - //vout.n-1: opreturn [EVAL_ASSETS] ['s'] [assetid] [amount of native coin required] - if ( amount == 0 ) - return eval->Invalid("illegal null amount for selloffer"); - if ( (nValue= AssetIsvalidCCvin(eval,funcid,assetid,0,0,0,tx,1)) != 0 ) - { - if ( AssetIsvalidvout0(eval,tx,nValue) != nValue ) - return(false); - } else return eval->Invalid("illegal standard vini.1 for selloffer"); - break; - + case 'b': // buyoffer //vins.*: normal inputs (bid + change) //vout.0: amount of bid to unspendable //vout.1: normal output for change (if any) - //vout.n-1: opreturn [EVAL_ASSETS] ['b'] [assetid] [amount of asset required] - if ( amount == 0 ) + // vout.n-1: opreturn [EVAL_ASSETS] ['b'] [assetid] [amount of asset required] [origpubkey] + if ( remaining_price == 0 ) return eval->Invalid("illegal null amount for buyoffer"); for (i=1; iInvalid("invalid CC vin for buyoffer"); } for (i=0; iInvalid("invalid CC vout for buyoffer"); + if ( i == 0 ) + { + if ( Getscriptaddress(destaddr,tx.vout[i].scriptPubKey) == 0 || strcmp(destaddr,Unspendableaddr) != 0) )) + return eval->Invalid("invalid vout0 destaddr for buyoffer"); + else if ( tx.vout[i].nValue < 10000 ) + return eval->Invalid("invalid vout0 dust for buyoffer"); + } } break; - - case 'e': // exchange - //vin.0: normal input - //vin.1: valid CC output - //vout.0: vin.1 assetoshis output to CC to unspendable - //vout.1: normal output for change (if any) - //vout.n-1: opreturn [EVAL_ASSETS] ['e'] [assetid] [assetid2] [amount of asset2 required] - if ( assetid2 == zero ) - return eval->Invalid("illegal assetid2 for exchange"); - if ( amount == 0 ) - return eval->Invalid("illegal null amount for exchange"); - if ( (nValue= AssetIsvalidCCvin(eval,funcid,assetid,0,0,0,tx,1)) != 0 ) - { - if ( AssetIsvalidvout0(eval,tx,nValue) != nValue ) - return(false); - } else return eval->Invalid("illegal standard vini.1 for exchange"); - break; - + case 'o': // cancelbuy //vin.0: normal input - //vin.1: unspendable.(vout.1 from buyoffer) - //vout.0: vin.1 value to original pubkey + //vin.1: unspendable.(vout.0 from buyoffer) buyTx.vout[0] + //vout.0: vin.1 value to original pubkey buyTx.vout[0].nValue -> [origpubkey] //vout.1: normal output for change (if any) - //vout.n-1: opreturn [EVAL_ASSETS] ['o'] [assetid] - if ( AssetIsvalidCCvin(eval,funcid,assetid,&origamount,&origout,origaddr,tx,1) != 0 ) - return eval->Invalid("illegal CC vin.1 for cancelbuy"); - if ( strcmp(Unspendableaddr,(char *)CBitcoinAddress(address).ToString().c_str()) != 0 ) - return eval->Invalid("invalid vout0 address for cancelbuy"); - if ( origout != tx.vout[0].nValue ) - return eval->Invalid("mismatched value for cancelbuy"); - if ( ExtractDestination(tx.vout[0].scriptPubKey,address) == 0 ) - return eval->Invalid("no vout0 address for cancelbuy"); - if ( strcmp(origaddr,(char *)CBitcoinAddress(address).ToString().c_str()) != 0 ) - return eval->Invalid("mismatched origaddr for cancelbuy"); + //vout.n-1: opreturn [EVAL_ASSETS] ['o'] + if ( (nValue= AssetValidateBuyvin(eval,tmpprice,tmporigpubkey,origaddr,tx)) == 0 ) + return(false); + else if ( nValue != tx.vout[0].nValue ) + return eval->Invalid("mismatched refund for cancelbuy"); + else if ( Getscriptaddress(destaddr,tx.vout[0].scriptPubKey) == 0 || strcmp(destaddr,origaddr) != 0) )) + return eval->Invalid("invalid vout0 destaddr for cancelbuy"); break; + case 'B': // fillbuy: + //vin.0: normal input + //vin.1: unspendable.(vout.0 from buyoffer) buyTx.vout[0] + //vin.2: valid CC output satisfies buyoffer (*tx.vin[2])->nValue + //vout.0: remaining amount of bid to unspendable + //vout.1: vin.1 value to signer of vin.2 + //vout.2: vin.2 assetoshis to original pubkey + //vout.3: normal output for change (if any) + //vout.n-1: opreturn [EVAL_ASSETS] ['B'] [assetid] [remaining asset required] [origpubkey] + if ( (nValue= AssetValidateBuyvin(eval,tmpprice,tmporigpubkey,origaddr,tx)) == 0 ) + return(false); + else if ( tmporigpubkey != origpubkey ) + return eval->Invalid("mismatched origpubkeys for fillbuy"); + else if ( IsAssetInput(tx.vin[2].scriptSig) != 0 ) + { + if ( eval->GetTxUnconfirmed(tx.vin[2].prevout.hash,vinTx,hashBlock) == 0 ) + return eval->Invalid("always should find vin, but didnt"); + else if ( (assetoshis= IsAssetvout(ignore,ignorepubkey,vinTx,tx.vin[2].prevout.n,assetid)) != 0 ) + { + if ( tx.vout[2].nValue != assetoshis ) + return eval->Invalid("mismatched assetoshis for fillbuy"); + else if ( Getscriptaddress(destaddr,tx.vout[2].scriptPubKey) == 0 || strcmp(destaddr,origaddr) != 0) )) + return eval->Invalid("mismatched vout2 destaddr for fillbuy"); + else if ( ValidateRemainder(remaining_price,tx.vout[0].nValue,nValue,tx.vout[1].nValue,assetoshis,tmpprice) == false ) + return eval->Invalid("mismatched remainder for fillbuy"); + else if ( remaining_price != 0 ) + { + if ( remaining_price < 10000 ) + return eval->Invalid("dust vout0 to unspendableaddr for fillbuy"); + else if ( Getscriptaddress(destaddr,tx.vout[0].scriptPubKey) == 0 || strcmp(destaddr,Unspendableaddr) != 0 ) + return eval->Invalid("mismatched vout0 unspendableaddr for fillbuy"); + } + } else return eval->Invalid("vin2 not enough asset2 for fillbuy"); + } else return eval->Invalid("vin2 not asset for fillbuy"); + break; + + case 's': // selloffer + case 'e': // exchange + //vin.0: normal input + //vin.1: valid CC output for sale + //vout.0: vin.1 assetoshis output to CC to unspendable + //vout.1: normal output for change (if any) + //'s'.vout.n-1: opreturn [EVAL_ASSETS] ['s'] [assetid] [amount of native coin required] [origpubkey] + //'e'.vout.n-1: opreturn [EVAL_ASSETS] ['e'] [assetid] [assetid2] [amount of asset2 required] [origpubkey] + if ( remaining_price == 0 ) + return eval->Invalid("illegal null remaining_price for selloffer"); + if ( IsAssetInput(tx.vin[1].scriptSig) != 0 ) + { + if ( eval->GetTxUnconfirmed(tx.vin[1].prevout.hash,vinTx,hashBlock) == 0 ) + return eval->Invalid("always should find vin, but didnt"); + else if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,vinTx,tx.vin[1].prevout.n,assetid)) == 0 ) + return eval->Invalid("illegal missing assetvin for selloffer"); + else if ( Getscriptaddress(destaddr,tx.vout[0].scriptPubKey) == 0 || strcmp(destaddr,Unspendableaddr) != 0) )) + return eval->Invalid("mismatched vout0 unspendableaddr for selloffer"); + else if ( tx.vout[0].nValue != assetoshis ) + return eval->Invalid("mismatched assetoshis for selloffer"); + } else return eval->Invalid("illegal normal vin1 for selloffer"); + break; + case 'x': // cancel //vin.0: normal input - //vin.1: unspendable.(vout.1 from exchange or selloffer) - //vout.0: vin.1 assetoshis to original pubkey CC + //vin.1: unspendable.(vout.0 from exchange or selloffer) sellTx/exchangeTx.vout[0] inputTx + //vout.0: vin.1 assetoshis to original pubkey CC sellTx/exchangeTx.vout[0].nValue -> [origpubkey] //vout.1: normal output for change (if any) //vout.n-1: opreturn [EVAL_ASSETS] ['x'] [assetid] - if ( (nValue= AssetIsvalidCCvin(eval,funcid,assetid,&origamount,&origout,origaddr,tx,1)) != 0 ) - { - if ( origout != tx.vout[0].nValue ) - return eval->Invalid("mismatched value for cancel"); - if ( ExtractDestination(tx.vout[0].scriptPubKey,address) == 0 ) - return eval->Invalid("no vout0 address for cancel"); - if ( strcmp(origaddr,(char *)CBitcoinAddress(address).ToString().c_str()) != 0 ) - return eval->Invalid("mismatched origaddr for cancel"); - } else return eval->Invalid("illegal standard vini.1 for cancel"); + if ( (assetoshis= AssetValidateSellvin(eval,tmpprice,tmporigpubkey,origaddr,tx,assetid)) == 0 ) + return(false); + else if ( assetoshis != tx.vout[0].nValue ) + return eval->Invalid("mismatched refund for cancelbuy"); + else if ( Getscriptaddress(destaddr,tx.vout[0].scriptPubKey) == 0 || strcmp(destaddr,origaddr) != 0) )) + return eval->Invalid("invalid vout0 destaddr for cancel"); break; case 'S': // fillsell + case 'E': // fillexchange //vin.0: normal input - //vin.1: unspendable.(vout.1 assetoshis from selloffer) - //vin.2: normal output that satisfies selloffer, need to extract from opreturn - //vout.0: vin.1 assetoshis to signer of vin.2 - //vout.1: vin.2 value to original pubkey - //vout.2: normal output for change (if any) - //vout.n-1: opreturn [EVAL_ASSETS] ['S'] [assetid] - if ( (vini2val= Assetvini2val(eval,0,assetid,tx)) == 0 ) - return eval->Invalid("no vini2val for fillsell"); - if ( (nValue= AssetIsvalidCCvin(eval,funcid,assetid,&origamount,&origout,origaddr,tx,1)) != 0 ) + //vin.1: unspendable.(vout.0 assetoshis from selloffer) sellTx.vout[0] + //'S'.vin.2: normal output that satisfies selloffer (*tx.vin[2])->nValue + //'E'.vin.2: valid CC assetid2 output that satisfies exchange (*tx.vin[2])->nValue + //vout.0: remaining assetoshis -> unspendable + //vout.1: vin.1 assetoshis to signer of vin.2 sellTx.vout[0].nValue -> any + //'S'.vout.2: vin.2 value to original pubkey [origpubkey] + //'E'.vout.2: vin.2 assetoshis2 to original pubkey [origpubkey] + //vout.3: normal output for change (if any) + //'S'.vout.n-1: opreturn [EVAL_ASSETS] ['S'] [assetid] [amount of coin still required] [origpubkey] + //'E'.vout.n-1: opreturn [EVAL_ASSETS] ['E'] [assetid vin0+1] [assetid vin2] [remaining asset2 required] [origpubkey] + if ( (assetoshis= AssetValidateSellvin(eval,tmpprice,tmporigpubkey,origaddr,tx,assetid)) == 0 ) + return(false); + else if ( tmporigpubkey != origpubkey ) + return eval->Invalid("mismatched origpubkeys for fillsell"); + else if ( funcid == 'S' && IsAssetInput(tx.vin[2].scriptSig) != 0 ) + return eval->Invalid("invalid vin2 is CC for fillsell"); + else if ( funcid == 'E' && IsAssetInput(tx.vin[2].scriptSig) == 0 ) + return eval->Invalid("invalid vin2 is CC for fillexchange"); + else if ( eval->GetTxUnconfirmed(tx.vin[2].prevout.hash,vinTx,hashBlock) == 0 ) + return eval->Invalid("always should find vin, but didnt"); + else if ( funcid == 'E' && (IsAssetvout(ignore,ignorepubkey,vinTx,tx.vin[2].prevout.n,assetid2) != tx.vout[2].nValue || tx.vout[2].nvalue == 0) ) + return eval->Invalid("invalid asset2 vin value for fillexchange"); + else if ( funcid == 'E' && IsAssetvout(ignore,ignorepubkey,tx,2,assetid2) == 0 ) + return eval->Invalid("invalid asset2 voutvalue for fillexchange"); + else if ( Getscriptaddress(destaddr,tx.vout[2].scriptPubKey) == 0 || strcmp(destaddr,origaddr) != 0) )) + return eval->Invalid("mismatched vout2 destaddr for fill"); + else if ( vinTx.vout[tx.vin[2].prevout.n].nValue = tx.vout[2].nValue ) + return eval->Invalid("mismatched vout2 nValue for fill"); + else if ( ValidateRemainder(remaining_price,tx.vout[0].nValue,assetoshis,tx.vout[2].nValue,tx.vout[1].nValue,tmpprice) == false ) + return eval->Invalid("mismatched remainder for fill"); + else if ( IsAssetvout(ignore,ignorepubkey,vinTx,tx.vin[1].prevout.n,assetid) == 0 ) + return eval->Invalid("mismatched vout0 unspendableaddr for fill"); + else if ( remaining_price != 0 ) { - if ( origout != tx.vout[0].nValue ) - return eval->Invalid("mismatched value for fillsell"); - // vout address can be any - if ( ExtractDestination(tx.vout[1].scriptPubKey,address) == 0 ) - return eval->Invalid("no vout0 address for fillsell"); - if ( strcmp(origaddr,(char *)CBitcoinAddress(address).ToString().c_str()) != 0 ) - return eval->Invalid("mismatched origaddr for fillsell"); - if ( vini2val < origamount ) - return eval->Invalid("not enough paid for fillsell"); - if ( vini2val != tx.vout[1].nValue ) - return eval->Invalid("mismatched vout.1 val for fillsell"); - } else return eval->Invalid("illegal standard vini.1 for fillsell"); - break; - - case 'B': // fillbuy: - //vin.0: normal input - //vin.1: unspendable.(vout.1 from buyoffer) - //vin.2: valid CC output satisfies buyoffer - //vout.0: vin.1 value to signer of vin.2 - //vout.1: vin.2 assetoshis to original pubkey - //vout.2: normal output for change (if any) - //vout.n-1: opreturn [EVAL_ASSETS] ['B'] [assetid] - if ( (vini2val= Assetvini2val(eval,1,assetid,tx)) == 0 ) - return eval->Invalid("no vini2val for fillbuy"); - if ( (nValue= AssetIsvalidvin(eval,&origamount,&origout,origaddr,tx,1)) != 0 ) - { - if ( origout != tx.vout[0].nValue ) - return eval->Invalid("mismatched value for fillbuy"); - if ( ExtractDestination(tx.vout[1].scriptPubKey,address) == 0 ) - return eval->Invalid("no vout0 address for fillbuy"); - if ( strcmp(origaddr,(char *)CBitcoinAddress(address).ToString().c_str()) != 0 ) - return eval->Invalid("mismatched origaddr for fillbuy"); - if ( vini2val < origamount ) - return eval->Invalid("not enough paid for fillbuy"); - if ( vini2val != tx.vout[1].nValue ) - return eval->Invalid("mismatched vout.1 val for fillbuy"); - } else return eval->Invalid("illegal CC vini.1 for fillbuy"); - break; - - case 'E': // fillexchange: - //vin.0: normal input - /*vin.1: unspendable.(vout.1 assetoshis from exchange) - vin.2: valid CC output that satisfies exchange - vout.0: vin.1 assetoshis to signer of vin.2 - vout.1: vin.2 assetoshis to original pubkey*/ - //vout.2: normal output for change (if any) - //vout.n-1: opreturn [EVAL_ASSETS] ['E'] [assetid vin1] [assetid vin2] - if ( assetid2 == zero ) - return eval->Invalid("illegal assetid2 for fillexchange"); + if ( Getscriptaddress(destaddr,tx.vout[0].scriptPubKey) == 0 || strcmp(destaddr,Unspendableaddr) != 0 ) + return eval->Invalid("mismatched vout0 unspendableaddr for fill"); + else if ( IsAssetvout(ignore,ignorepubkey,tx,0,assetid) == 0 ) + return eval->Invalid("not asset vout0 to unspendableaddr for fill"); + else if ( funcid == 'S' && remaining_price < 10000 ) + return eval->Invalid("dust vout0 to unspendableaddr for fill"); + } break; } return(true); @@ -523,34 +538,16 @@ bool AssetValidate(Eval* eval,const CTransaction &tx,int32_t numvouts,uint8_t fu bool ProcessAssets(Eval* eval, std::vector paramsNull, const CTransaction &tx, unsigned int nIn) { static uint256 zero; - CTransaction createTx; uint256 assetid,assetid2,hashBlock; uint8_t funcid; int32_t i,n; uint64_t amount; + CTransaction createTx; uint256 assetid,assetid2,hashBlock; uint8_t funcid; int32_t i,n; uint64_t amount; std::vector origpubkey; if ( paramsNull.size() != 0 ) // Don't expect params return eval->Invalid("Cannot have params"); if ( (n= tx.vout.size()) == 0 ) return eval->Invalid("no-vouts"); - if ( (funcid= DecodeOpRet(tx.vout[n-1].scriptPubKey,assetid,assetid2,amount)) == 0 ) + if ( (funcid= DecodeOpRet(tx.vout[n-1].scriptPubKey,assetid,assetid2,amount,origpubkey)) == 0 ) return eval->Invalid("Invalid opreturn payload"); if ( eval->GetTxUnconfirmed(assetid,createTx,hashBlock) == 0 ) return eval->Invalid("cant find asset create txid"); if ( assetid2 != zero && eval->GetTxUnconfirmed(assetid2,createTx,hashBlock) == 0 ) return eval->Invalid("cant find asset2 create txid"); - return(AssetValidate(eval,tx,n,funcid,assetid,assetid2,amount)); - - // We're unable to ensure that all the outputs have the correct - // CC Eval code because we only have the scriptPubKey which is a hash of the - // condition. The effect of this is that we cannot control the outputs, and therefore - // are able to burn or "lose" units or our colored token and they will be spent as the - // regular chain token, but we are able to control when units of the asset get - // created because we can always vet the inputs. - // - // Units of the colored token are always 1:1 with the token being input. No additional - // supply is created on the chain. Effectively, fees are paid in units of the colored token. - // This leaves something to be desired, because for example, if you wanted to create a - // single asset that could transfer ownership, usually you would create an asset with a - // supply of 1, ie can not be divided further, however in this case there would be nothing - // left to pay fees with. Implementing separate supply and other details are possible, by - // encoding further information in the OP_RETURNS. - - // It's valid - //return true; + return(AssetValidate(eval,tx,n,funcid,assetid,assetid2,amount,origpubkey)); } From ac17dd76ae93bed3c9d6b5897148d2a0f23a7980 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 19 Jul 2018 21:43:01 -1100 Subject: [PATCH 02/15] Fix --- src/cc/assets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index cf88b0757..df8f04d7f 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -164,7 +164,7 @@ bool Getscriptaddress(char *destaddr,CScript &scriptPubKey) strcpy(destaddr,(char *)CBitcoinAddress(address).ToString().c_str()); return(true); } - return(false) + return(false); } uint8_t DecodeOpRet(CScript const& scriptPubKey,uint256 &assetid,uint256 &assetid2,uint64_t &price,std::vector &origpubkey) From 517ab98c4747c629ce382e45fe5bd6b0c9144781 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 19 Jul 2018 21:45:01 -1100 Subject: [PATCH 03/15] ; --- src/cc/assets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index df8f04d7f..052f68a99 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -207,7 +207,7 @@ bool Getorigaddr(char *destaddr,CTransaction& tx) if ( n == 0 || (funcid= DecodeOpRet(tx.vout[n-1].scriptPubKey,assetid,assetid2,price,origpubkey)) == 0 ) return(false); script = CScript() << origpubkey << OP_CHECKSIG; - return(Getscriptaddress(destaddr,script)) + return(Getscriptaddress(destaddr,script)); } CC* GetCryptoCondition(CScript const& scriptSig) From 6f667a100e25a0212a93fe9cd86c4cfa083a825c Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 19 Jul 2018 21:47:37 -1100 Subject: [PATCH 04/15] Fix --- src/cc/assets.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index 052f68a99..963dfe664 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -249,7 +249,7 @@ uint64_t IsAssetvout(uint64_t &price,std::vector &origpubkey,CTransacti return(0); if ( funcid == 'c' ) { - if ( refassetid == tTx.GetHash() && v == 0 ) + if ( refassetid == tx.GetHash() && v == 0 ) return(nValue); } else if ( funcid != 'E' ) @@ -268,7 +268,7 @@ uint64_t IsAssetvout(uint64_t &price,std::vector &origpubkey,CTransacti return(0); } -uint64_t AssetValidatevin(Eval* eval,char *origaddr,const CTransaction &tx,const CTransaction &vinTx) +uint64_t AssetValidatevin(Eval* eval,char *origaddr,CTransaction &tx,CTransaction &vinTx) { uint256 hashBlock; char destaddr[64]; origaddr[0] = destaddr[0] = 0; @@ -285,9 +285,9 @@ uint64_t AssetValidatevin(Eval* eval,char *origaddr,const CTransaction &tx,const else return(vinTx.vout[0].nValue); } -uint64_t AssetValidateBuyvin(Eval* eval,uint64_t &tmpprice,std::vector &tmporigpubkey,char *origaddr,const CTransaction &tx) +uint64_t AssetValidateBuyvin(Eval* eval,uint64_t &tmpprice,std::vector &tmporigpubkey,char *origaddr,CTransaction &tx) { - const CTransaction vinTx; uint64_t nValue; uint256 assetid,assetid2; + CTransaction vinTx; uint64_t nValue; uint256 assetid,assetid2; if ( (nValue= AssetValidatevin(eval,origaddr,tx,vinTx)) == 0 ) return(0); else if ( vinTx.vout[0].scriptPubKey.IsPayToCryptoCondition() != 0 ) @@ -297,9 +297,9 @@ uint64_t AssetValidateBuyvin(Eval* eval,uint64_t &tmpprice,std::vector else return(nValue); } -uint64_t AssetValidateSellvin(Eval* eval,uint64_t &tmpprice,std::vector &tmporigpubkey,char *origaddr,const CTransaction &tx,uint256 assetid) +uint64_t AssetValidateSellvin(Eval* eval,uint64_t &tmpprice,std::vector &tmporigpubkey,char *origaddr,CTransaction &tx,uint256 assetid) { - const CTransaction vinTx; uint64_t nValue,assetoshis; + CTransaction vinTx; uint64_t nValue,assetoshis; if ( (nValue= AssetValidatevin(eval,origaddr,tx,vinTx)) == 0 ) return(0); if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,vinTx,0,assetid)) != 0 ) @@ -326,10 +326,10 @@ bool ValidateRemainder(uint64_t remaining_price,uint64_t remaining_nValue,uint64 return(true); } -bool AssetValidate(Eval* eval,const CTransaction &tx,int32_t numvouts,uint8_t funcid,uint256 assetid,uint256 assetid2,uint64_t remaining_price,std::vector origpubkey) +bool AssetValidate(Eval* eval,CTransaction &tx,int32_t numvouts,uint8_t funcid,uint256 assetid,uint256 assetid2,uint64_t remaining_price,std::vector origpubkey) { static uint256 zero; - CTxDestination address; const CTransaction vinTx; uint256 hashBlock; int32_t i,numvins; uint64_t nValue,assetoshis,outputs,inputs,tmpprice,ignore; std::vector tmporigpubkey,ignorepubkey; char destaddr[64],origaddr[64]; + CTxDestination address; CTransaction vinTx; uint256 hashBlock; int32_t i,numvins; uint64_t nValue,assetoshis,outputs,inputs,tmpprice,ignore; std::vector tmporigpubkey,ignorepubkey; char destaddr[64],origaddr[64]; numvins = tx.vin.size(); outputs = inputs = 0; if ( IsAssetInput(tx.vin[0].scriptSig) != 0 ) From 4bbb5ff7e3171a605cec168471e1d318114459ce Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 19 Jul 2018 21:49:31 -1100 Subject: [PATCH 05/15] Test --- src/cc/assets.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index 963dfe664..b111fa136 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -167,7 +167,7 @@ bool Getscriptaddress(char *destaddr,CScript &scriptPubKey) return(false); } -uint8_t DecodeOpRet(CScript const& scriptPubKey,uint256 &assetid,uint256 &assetid2,uint64_t &price,std::vector &origpubkey) +uint8_t DecodeOpRet(CScript &scriptPubKey,uint256 &assetid,uint256 &assetid2,uint64_t &price,std::vector &origpubkey) { std::vector vopret; uint8_t funcid=0,*script; GetOpReturnData(scriptPubKey, vopret); @@ -292,7 +292,7 @@ uint64_t AssetValidateBuyvin(Eval* eval,uint64_t &tmpprice,std::vector return(0); else if ( vinTx.vout[0].scriptPubKey.IsPayToCryptoCondition() != 0 ) return eval->Invalid("invalid CC vout0 for buyvin"); - else if ( DecodeOpRet(vinTx.vout[vinTx.vout.size()-1].scriptPubKey,assetid,assetid2,tmpprice,tmporigpubkey)) == 0 ) + else if ( DecodeOpRet(vinTx.vout[vinTx.vout.size()-1].scriptPubKey,assetid,assetid2,tmpprice,tmporigpubkey) == 0 ) return eval->Invalid("invalid opreturn for buyvin"); else return(nValue); } From fd672a2b11805904760a6212383c9f51e36f4d82 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 19 Jul 2018 21:51:51 -1100 Subject: [PATCH 06/15] Test --- src/cc/assets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index b111fa136..f4e31e3a0 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -167,7 +167,7 @@ bool Getscriptaddress(char *destaddr,CScript &scriptPubKey) return(false); } -uint8_t DecodeOpRet(CScript &scriptPubKey,uint256 &assetid,uint256 &assetid2,uint64_t &price,std::vector &origpubkey) +uint8_t DecodeOpRet(const CScript &scriptPubKey,uint256 &assetid,uint256 &assetid2,uint64_t &price,std::vector &origpubkey) { std::vector vopret; uint8_t funcid=0,*script; GetOpReturnData(scriptPubKey, vopret); From d8427807592f53557b5cd926e1f1987fa965e548 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 19 Jul 2018 21:52:50 -1100 Subject: [PATCH 07/15] Test --- src/cc/assets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index f4e31e3a0..f55626df3 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -156,7 +156,7 @@ signEncodeTx "$transferTx" const char *Unspendableaddr = "RHTcNNYXEZhLGRcXspA2H4gw2v4u6w8MNp"; -bool Getscriptaddress(char *destaddr,CScript &scriptPubKey) +bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey) { CTxDestination address; if ( ExtractDestination(scriptPubKey,address) != 0 ) From 9e1c41c4cecda28370710aabcba76c2a094c1095 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 19 Jul 2018 21:55:51 -1100 Subject: [PATCH 08/15] Fix --- src/cc/assets.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index f55626df3..e4dc9b118 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -391,7 +391,7 @@ bool AssetValidate(Eval* eval,CTransaction &tx,int32_t numvouts,uint8_t funcid,u return eval->Invalid("invalid CC vout for buyoffer"); if ( i == 0 ) { - if ( Getscriptaddress(destaddr,tx.vout[i].scriptPubKey) == 0 || strcmp(destaddr,Unspendableaddr) != 0) )) + if ( Getscriptaddress(destaddr,tx.vout[i].scriptPubKey) == 0 || strcmp(destaddr,Unspendableaddr) != 0 ) return eval->Invalid("invalid vout0 destaddr for buyoffer"); else if ( tx.vout[i].nValue < 10000 ) return eval->Invalid("invalid vout0 dust for buyoffer"); @@ -409,7 +409,7 @@ bool AssetValidate(Eval* eval,CTransaction &tx,int32_t numvouts,uint8_t funcid,u return(false); else if ( nValue != tx.vout[0].nValue ) return eval->Invalid("mismatched refund for cancelbuy"); - else if ( Getscriptaddress(destaddr,tx.vout[0].scriptPubKey) == 0 || strcmp(destaddr,origaddr) != 0) )) + else if ( Getscriptaddress(destaddr,tx.vout[0].scriptPubKey) == 0 || strcmp(destaddr,origaddr) != 0 ) return eval->Invalid("invalid vout0 destaddr for cancelbuy"); break; @@ -434,7 +434,7 @@ bool AssetValidate(Eval* eval,CTransaction &tx,int32_t numvouts,uint8_t funcid,u { if ( tx.vout[2].nValue != assetoshis ) return eval->Invalid("mismatched assetoshis for fillbuy"); - else if ( Getscriptaddress(destaddr,tx.vout[2].scriptPubKey) == 0 || strcmp(destaddr,origaddr) != 0) )) + else if ( Getscriptaddress(destaddr,tx.vout[2].scriptPubKey) == 0 || strcmp(destaddr,origaddr) != 0 ) return eval->Invalid("mismatched vout2 destaddr for fillbuy"); else if ( ValidateRemainder(remaining_price,tx.vout[0].nValue,nValue,tx.vout[1].nValue,assetoshis,tmpprice) == false ) return eval->Invalid("mismatched remainder for fillbuy"); @@ -465,7 +465,7 @@ bool AssetValidate(Eval* eval,CTransaction &tx,int32_t numvouts,uint8_t funcid,u return eval->Invalid("always should find vin, but didnt"); else if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,vinTx,tx.vin[1].prevout.n,assetid)) == 0 ) return eval->Invalid("illegal missing assetvin for selloffer"); - else if ( Getscriptaddress(destaddr,tx.vout[0].scriptPubKey) == 0 || strcmp(destaddr,Unspendableaddr) != 0) )) + else if ( Getscriptaddress(destaddr,tx.vout[0].scriptPubKey) == 0 || strcmp(destaddr,Unspendableaddr) != 0) ) return eval->Invalid("mismatched vout0 unspendableaddr for selloffer"); else if ( tx.vout[0].nValue != assetoshis ) return eval->Invalid("mismatched assetoshis for selloffer"); @@ -482,7 +482,7 @@ bool AssetValidate(Eval* eval,CTransaction &tx,int32_t numvouts,uint8_t funcid,u return(false); else if ( assetoshis != tx.vout[0].nValue ) return eval->Invalid("mismatched refund for cancelbuy"); - else if ( Getscriptaddress(destaddr,tx.vout[0].scriptPubKey) == 0 || strcmp(destaddr,origaddr) != 0) )) + else if ( Getscriptaddress(destaddr,tx.vout[0].scriptPubKey) == 0 || strcmp(destaddr,origaddr) != 0 ) return eval->Invalid("invalid vout0 destaddr for cancel"); break; @@ -513,7 +513,7 @@ bool AssetValidate(Eval* eval,CTransaction &tx,int32_t numvouts,uint8_t funcid,u return eval->Invalid("invalid asset2 vin value for fillexchange"); else if ( funcid == 'E' && IsAssetvout(ignore,ignorepubkey,tx,2,assetid2) == 0 ) return eval->Invalid("invalid asset2 voutvalue for fillexchange"); - else if ( Getscriptaddress(destaddr,tx.vout[2].scriptPubKey) == 0 || strcmp(destaddr,origaddr) != 0) )) + else if ( Getscriptaddress(destaddr,tx.vout[2].scriptPubKey) == 0 || strcmp(destaddr,origaddr) != 0 ) return eval->Invalid("mismatched vout2 destaddr for fill"); else if ( vinTx.vout[tx.vin[2].prevout.n].nValue = tx.vout[2].nValue ) return eval->Invalid("mismatched vout2 nValue for fill"); From 27e76cd845c9effc9ee835982536d806a82c4761 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 19 Jul 2018 21:58:13 -1100 Subject: [PATCH 09/15] Test --- src/cc/assets.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index e4dc9b118..6b49ecc2d 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -326,7 +326,7 @@ bool ValidateRemainder(uint64_t remaining_price,uint64_t remaining_nValue,uint64 return(true); } -bool AssetValidate(Eval* eval,CTransaction &tx,int32_t numvouts,uint8_t funcid,uint256 assetid,uint256 assetid2,uint64_t remaining_price,std::vector origpubkey) +bool AssetValidate(Eval* eval,const CTransaction &tx,int32_t numvouts,uint8_t funcid,uint256 assetid,uint256 assetid2,uint64_t remaining_price,std::vector origpubkey) { static uint256 zero; CTxDestination address; CTransaction vinTx; uint256 hashBlock; int32_t i,numvins; uint64_t nValue,assetoshis,outputs,inputs,tmpprice,ignore; std::vector tmporigpubkey,ignorepubkey; char destaddr[64],origaddr[64]; @@ -465,7 +465,7 @@ bool AssetValidate(Eval* eval,CTransaction &tx,int32_t numvouts,uint8_t funcid,u return eval->Invalid("always should find vin, but didnt"); else if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,vinTx,tx.vin[1].prevout.n,assetid)) == 0 ) return eval->Invalid("illegal missing assetvin for selloffer"); - else if ( Getscriptaddress(destaddr,tx.vout[0].scriptPubKey) == 0 || strcmp(destaddr,Unspendableaddr) != 0) ) + else if ( Getscriptaddress(destaddr,tx.vout[0].scriptPubKey) == 0 || strcmp(destaddr,Unspendableaddr) != 0 ) return eval->Invalid("mismatched vout0 unspendableaddr for selloffer"); else if ( tx.vout[0].nValue != assetoshis ) return eval->Invalid("mismatched assetoshis for selloffer"); @@ -509,13 +509,13 @@ bool AssetValidate(Eval* eval,CTransaction &tx,int32_t numvouts,uint8_t funcid,u return eval->Invalid("invalid vin2 is CC for fillexchange"); else if ( eval->GetTxUnconfirmed(tx.vin[2].prevout.hash,vinTx,hashBlock) == 0 ) return eval->Invalid("always should find vin, but didnt"); - else if ( funcid == 'E' && (IsAssetvout(ignore,ignorepubkey,vinTx,tx.vin[2].prevout.n,assetid2) != tx.vout[2].nValue || tx.vout[2].nvalue == 0) ) + else if ( funcid == 'E' && (IsAssetvout(ignore,ignorepubkey,vinTx,tx.vin[2].prevout.n,assetid2) != tx.vout[2].nValue || tx.vout[2].nValue == 0) ) return eval->Invalid("invalid asset2 vin value for fillexchange"); else if ( funcid == 'E' && IsAssetvout(ignore,ignorepubkey,tx,2,assetid2) == 0 ) return eval->Invalid("invalid asset2 voutvalue for fillexchange"); else if ( Getscriptaddress(destaddr,tx.vout[2].scriptPubKey) == 0 || strcmp(destaddr,origaddr) != 0 ) return eval->Invalid("mismatched vout2 destaddr for fill"); - else if ( vinTx.vout[tx.vin[2].prevout.n].nValue = tx.vout[2].nValue ) + else if ( vinTx.vout[tx.vin[2].prevout.n].nValue != tx.vout[2].nValue ) return eval->Invalid("mismatched vout2 nValue for fill"); else if ( ValidateRemainder(remaining_price,tx.vout[0].nValue,assetoshis,tx.vout[2].nValue,tx.vout[1].nValue,tmpprice) == false ) return eval->Invalid("mismatched remainder for fill"); From a87883d543100f1cb839b6d50c15983b044f2675 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 19 Jul 2018 21:59:39 -1100 Subject: [PATCH 10/15] Test --- src/cc/assets.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index 6b49ecc2d..be73f069c 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -236,7 +236,7 @@ bool IsAssetInput(CScript const& scriptSig) return out; } -uint64_t IsAssetvout(uint64_t &price,std::vector &origpubkey,CTransaction& tx,int32_t v,uint256 refassetid) +uint64_t IsAssetvout(uint64_t &price,std::vector &origpubkey,const CTransaction& tx,int32_t v,uint256 refassetid) { uint256 assetid,assetid2; uint64_t nValue=0; int32_t n; uint8_t funcid; if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) @@ -268,7 +268,7 @@ uint64_t IsAssetvout(uint64_t &price,std::vector &origpubkey,CTransacti return(0); } -uint64_t AssetValidatevin(Eval* eval,char *origaddr,CTransaction &tx,CTransaction &vinTx) +uint64_t AssetValidatevin(Eval* eval,char *origaddr,const CTransaction &tx,CTransaction &vinTx) { uint256 hashBlock; char destaddr[64]; origaddr[0] = destaddr[0] = 0; @@ -285,9 +285,9 @@ uint64_t AssetValidatevin(Eval* eval,char *origaddr,CTransaction &tx,CTransactio else return(vinTx.vout[0].nValue); } -uint64_t AssetValidateBuyvin(Eval* eval,uint64_t &tmpprice,std::vector &tmporigpubkey,char *origaddr,CTransaction &tx) +uint64_t AssetValidateBuyvin(Eval* eval,uint64_t &tmpprice,std::vector &tmporigpubkey,char *origaddr,const CTransaction &tx) { - CTransaction vinTx; uint64_t nValue; uint256 assetid,assetid2; + const CTransaction vinTx; uint64_t nValue; uint256 assetid,assetid2; if ( (nValue= AssetValidatevin(eval,origaddr,tx,vinTx)) == 0 ) return(0); else if ( vinTx.vout[0].scriptPubKey.IsPayToCryptoCondition() != 0 ) @@ -297,9 +297,9 @@ uint64_t AssetValidateBuyvin(Eval* eval,uint64_t &tmpprice,std::vector else return(nValue); } -uint64_t AssetValidateSellvin(Eval* eval,uint64_t &tmpprice,std::vector &tmporigpubkey,char *origaddr,CTransaction &tx,uint256 assetid) +uint64_t AssetValidateSellvin(Eval* eval,uint64_t &tmpprice,std::vector &tmporigpubkey,char *origaddr,const CTransaction &tx,uint256 assetid) { - CTransaction vinTx; uint64_t nValue,assetoshis; + const CTransaction vinTx; uint64_t nValue,assetoshis; if ( (nValue= AssetValidatevin(eval,origaddr,tx,vinTx)) == 0 ) return(0); if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,vinTx,0,assetid)) != 0 ) @@ -329,7 +329,7 @@ bool ValidateRemainder(uint64_t remaining_price,uint64_t remaining_nValue,uint64 bool AssetValidate(Eval* eval,const CTransaction &tx,int32_t numvouts,uint8_t funcid,uint256 assetid,uint256 assetid2,uint64_t remaining_price,std::vector origpubkey) { static uint256 zero; - CTxDestination address; CTransaction vinTx; uint256 hashBlock; int32_t i,numvins; uint64_t nValue,assetoshis,outputs,inputs,tmpprice,ignore; std::vector tmporigpubkey,ignorepubkey; char destaddr[64],origaddr[64]; + CTxDestination address; const CTransaction vinTx; uint256 hashBlock; int32_t i,numvins; uint64_t nValue,assetoshis,outputs,inputs,tmpprice,ignore; std::vector tmporigpubkey,ignorepubkey; char destaddr[64],origaddr[64]; numvins = tx.vin.size(); outputs = inputs = 0; if ( IsAssetInput(tx.vin[0].scriptSig) != 0 ) From 128976d345050ac5c226c241752903981bf4d13d Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 19 Jul 2018 22:00:52 -1100 Subject: [PATCH 11/15] Test --- src/cc/assets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index be73f069c..987564893 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -268,7 +268,7 @@ uint64_t IsAssetvout(uint64_t &price,std::vector &origpubkey,const CTra return(0); } -uint64_t AssetValidatevin(Eval* eval,char *origaddr,const CTransaction &tx,CTransaction &vinTx) +uint64_t AssetValidatevin(Eval* eval,char *origaddr,const CTransaction &tx,const CTransaction &vinTx) { uint256 hashBlock; char destaddr[64]; origaddr[0] = destaddr[0] = 0; From d9316bd11df33909a49631432444263ec244e426 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 19 Jul 2018 22:02:47 -1100 Subject: [PATCH 12/15] Test --- src/cc/assets.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index 987564893..1b556a6be 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -200,7 +200,7 @@ uint8_t DecodeOpRet(const CScript &scriptPubKey,uint256 &assetid,uint256 &asseti return(funcid); } -bool Getorigaddr(char *destaddr,CTransaction& tx) +bool Getorigaddr(char *destaddr,const CTransaction& tx) { uint256 assetid,assetid2; uint64_t price,nValue=0; int32_t n; uint8_t funcid; std::vector origpubkey; CScript script; n = tx.vout.size(); @@ -538,7 +538,7 @@ bool AssetValidate(Eval* eval,const CTransaction &tx,int32_t numvouts,uint8_t fu bool ProcessAssets(Eval* eval, std::vector paramsNull, const CTransaction &tx, unsigned int nIn) { static uint256 zero; - CTransaction createTx; uint256 assetid,assetid2,hashBlock; uint8_t funcid; int32_t i,n; uint64_t amount; std::vector origpubkey; + const CTransaction createTx; uint256 assetid,assetid2,hashBlock; uint8_t funcid; int32_t i,n; uint64_t amount; std::vector origpubkey; if ( paramsNull.size() != 0 ) // Don't expect params return eval->Invalid("Cannot have params"); if ( (n= tx.vout.size()) == 0 ) From d90e961beea803287a9b1e373cb64b7978665e86 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 19 Jul 2018 22:05:38 -1100 Subject: [PATCH 13/15] Test --- src/cc/eval.cpp | 2 +- src/cc/eval.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/eval.cpp b/src/cc/eval.cpp index b8044e0dd..2405c2375 100644 --- a/src/cc/eval.cpp +++ b/src/cc/eval.cpp @@ -84,7 +84,7 @@ bool Eval::GetSpendsConfirmed(uint256 hash, std::vector &spends) c } -bool Eval::GetTxUnconfirmed(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) const +bool Eval::GetTxUnconfirmed(const uint256 &hash, const CTransaction &txOut, uint256 &hashBlock) const { bool fAllowSlow = false; // Don't allow slow return GetTransaction(hash, txOut, hashBlock, fAllowSlow); diff --git a/src/cc/eval.h b/src/cc/eval.h index 96af359f1..edff3d96b 100644 --- a/src/cc/eval.h +++ b/src/cc/eval.h @@ -81,7 +81,7 @@ public: /* * IO functions */ - virtual bool GetTxUnconfirmed(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) const; + virtual bool GetTxUnconfirmed(const uint256 &hash, const CTransaction &txOut, uint256 &hashBlock) const; virtual bool GetTxConfirmed(const uint256 &hash, CTransaction &txOut, CBlockIndex &block) const; virtual unsigned int GetCurrentHeight() const; virtual bool GetSpendsConfirmed(uint256 hash, std::vector &spends) const; From aedc638dff4ded92055a348e1fa3a382df4227f8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 19 Jul 2018 22:08:24 -1100 Subject: [PATCH 14/15] -const --- src/cc/assets.cpp | 22 +++++++++++----------- src/cc/eval.cpp | 2 +- src/cc/eval.h | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index 1b556a6be..883d140e7 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -200,7 +200,7 @@ uint8_t DecodeOpRet(const CScript &scriptPubKey,uint256 &assetid,uint256 &asseti return(funcid); } -bool Getorigaddr(char *destaddr,const CTransaction& tx) +bool Getorigaddr(char *destaddr,CTransaction& tx) { uint256 assetid,assetid2; uint64_t price,nValue=0; int32_t n; uint8_t funcid; std::vector origpubkey; CScript script; n = tx.vout.size(); @@ -236,7 +236,7 @@ bool IsAssetInput(CScript const& scriptSig) return out; } -uint64_t IsAssetvout(uint64_t &price,std::vector &origpubkey,const CTransaction& tx,int32_t v,uint256 refassetid) +uint64_t IsAssetvout(uint64_t &price,std::vector &origpubkey,CTransaction& tx,int32_t v,uint256 refassetid) { uint256 assetid,assetid2; uint64_t nValue=0; int32_t n; uint8_t funcid; if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) @@ -268,7 +268,7 @@ uint64_t IsAssetvout(uint64_t &price,std::vector &origpubkey,const CTra return(0); } -uint64_t AssetValidatevin(Eval* eval,char *origaddr,const CTransaction &tx,const CTransaction &vinTx) +uint64_t AssetValidatevin(Eval* eval,char *origaddr,CTransaction &tx,CTransaction &vinTx) { uint256 hashBlock; char destaddr[64]; origaddr[0] = destaddr[0] = 0; @@ -285,9 +285,9 @@ uint64_t AssetValidatevin(Eval* eval,char *origaddr,const CTransaction &tx,const else return(vinTx.vout[0].nValue); } -uint64_t AssetValidateBuyvin(Eval* eval,uint64_t &tmpprice,std::vector &tmporigpubkey,char *origaddr,const CTransaction &tx) +uint64_t AssetValidateBuyvin(Eval* eval,uint64_t &tmpprice,std::vector &tmporigpubkey,char *origaddr,CTransaction &tx) { - const CTransaction vinTx; uint64_t nValue; uint256 assetid,assetid2; + CTransaction vinTx; uint64_t nValue; uint256 assetid,assetid2; if ( (nValue= AssetValidatevin(eval,origaddr,tx,vinTx)) == 0 ) return(0); else if ( vinTx.vout[0].scriptPubKey.IsPayToCryptoCondition() != 0 ) @@ -297,9 +297,9 @@ uint64_t AssetValidateBuyvin(Eval* eval,uint64_t &tmpprice,std::vector else return(nValue); } -uint64_t AssetValidateSellvin(Eval* eval,uint64_t &tmpprice,std::vector &tmporigpubkey,char *origaddr,const CTransaction &tx,uint256 assetid) +uint64_t AssetValidateSellvin(Eval* eval,uint64_t &tmpprice,std::vector &tmporigpubkey,char *origaddr,CTransaction &tx,uint256 assetid) { - const CTransaction vinTx; uint64_t nValue,assetoshis; + CTransaction vinTx; uint64_t nValue,assetoshis; if ( (nValue= AssetValidatevin(eval,origaddr,tx,vinTx)) == 0 ) return(0); if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,vinTx,0,assetid)) != 0 ) @@ -326,10 +326,10 @@ bool ValidateRemainder(uint64_t remaining_price,uint64_t remaining_nValue,uint64 return(true); } -bool AssetValidate(Eval* eval,const CTransaction &tx,int32_t numvouts,uint8_t funcid,uint256 assetid,uint256 assetid2,uint64_t remaining_price,std::vector origpubkey) +bool AssetValidate(Eval* eval,CTransaction &tx,int32_t numvouts,uint8_t funcid,uint256 assetid,uint256 assetid2,uint64_t remaining_price,std::vector origpubkey) { static uint256 zero; - CTxDestination address; const CTransaction vinTx; uint256 hashBlock; int32_t i,numvins; uint64_t nValue,assetoshis,outputs,inputs,tmpprice,ignore; std::vector tmporigpubkey,ignorepubkey; char destaddr[64],origaddr[64]; + CTxDestination address; CTransaction vinTx; uint256 hashBlock; int32_t i,numvins; uint64_t nValue,assetoshis,outputs,inputs,tmpprice,ignore; std::vector tmporigpubkey,ignorepubkey; char destaddr[64],origaddr[64]; numvins = tx.vin.size(); outputs = inputs = 0; if ( IsAssetInput(tx.vin[0].scriptSig) != 0 ) @@ -535,10 +535,10 @@ bool AssetValidate(Eval* eval,const CTransaction &tx,int32_t numvouts,uint8_t fu return(true); } -bool ProcessAssets(Eval* eval, std::vector paramsNull, const CTransaction &tx, unsigned int nIn) +bool ProcessAssets(Eval* eval, std::vector paramsNull, CTransaction &tx, unsigned int nIn) { static uint256 zero; - const CTransaction createTx; uint256 assetid,assetid2,hashBlock; uint8_t funcid; int32_t i,n; uint64_t amount; std::vector origpubkey; + CTransaction createTx; uint256 assetid,assetid2,hashBlock; uint8_t funcid; int32_t i,n; uint64_t amount; std::vector origpubkey; if ( paramsNull.size() != 0 ) // Don't expect params return eval->Invalid("Cannot have params"); if ( (n= tx.vout.size()) == 0 ) diff --git a/src/cc/eval.cpp b/src/cc/eval.cpp index 2405c2375..b8044e0dd 100644 --- a/src/cc/eval.cpp +++ b/src/cc/eval.cpp @@ -84,7 +84,7 @@ bool Eval::GetSpendsConfirmed(uint256 hash, std::vector &spends) c } -bool Eval::GetTxUnconfirmed(const uint256 &hash, const CTransaction &txOut, uint256 &hashBlock) const +bool Eval::GetTxUnconfirmed(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) const { bool fAllowSlow = false; // Don't allow slow return GetTransaction(hash, txOut, hashBlock, fAllowSlow); diff --git a/src/cc/eval.h b/src/cc/eval.h index edff3d96b..96af359f1 100644 --- a/src/cc/eval.h +++ b/src/cc/eval.h @@ -81,7 +81,7 @@ public: /* * IO functions */ - virtual bool GetTxUnconfirmed(const uint256 &hash, const CTransaction &txOut, uint256 &hashBlock) const; + virtual bool GetTxUnconfirmed(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) const; virtual bool GetTxConfirmed(const uint256 &hash, CTransaction &txOut, CBlockIndex &block) const; virtual unsigned int GetCurrentHeight() const; virtual bool GetSpendsConfirmed(uint256 hash, std::vector &spends) const; From badcb33241c7882ec2e7d15af55e8067d5875444 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 19 Jul 2018 22:13:13 -1100 Subject: [PATCH 15/15] Test --- src/cc/assets.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index 883d140e7..2e222a444 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -535,10 +535,11 @@ bool AssetValidate(Eval* eval,CTransaction &tx,int32_t numvouts,uint8_t funcid,u return(true); } -bool ProcessAssets(Eval* eval, std::vector paramsNull, CTransaction &tx, unsigned int nIn) +bool ProcessAssets(Eval* eval, std::vector paramsNull,const CTransaction &ctx, unsigned int nIn) { static uint256 zero; CTransaction createTx; uint256 assetid,assetid2,hashBlock; uint8_t funcid; int32_t i,n; uint64_t amount; std::vector origpubkey; + CTransaction tx = *(CTransaction *)&ctx; if ( paramsNull.size() != 0 ) // Don't expect params return eval->Invalid("Cannot have params"); if ( (n= tx.vout.size()) == 0 )