Merge branch 'FSM' into jl777
This commit is contained in:
@@ -35,7 +35,7 @@ CScript EncodeAssetOpRet(uint8_t funcid,uint256 assetid,uint256 assetid2,int64_t
|
|||||||
bool DecodeAssetCreateOpRet(const CScript &scriptPubKey,std::vector<uint8_t> &origpubkey,std::string &name,std::string &description);
|
bool DecodeAssetCreateOpRet(const CScript &scriptPubKey,std::vector<uint8_t> &origpubkey,std::string &name,std::string &description);
|
||||||
uint8_t DecodeAssetOpRet(const CScript &scriptPubKey,uint256 &assetid,uint256 &assetid2,int64_t &price,std::vector<uint8_t> &origpubkey);
|
uint8_t DecodeAssetOpRet(const CScript &scriptPubKey,uint256 &assetid,uint256 &assetid2,int64_t &price,std::vector<uint8_t> &origpubkey);
|
||||||
bool SetAssetOrigpubkey(std::vector<uint8_t> &origpubkey,int64_t &price,const CTransaction &tx);
|
bool SetAssetOrigpubkey(std::vector<uint8_t> &origpubkey,int64_t &price,const CTransaction &tx);
|
||||||
int64_t IsAssetvout(int64_t &price,std::vector<uint8_t> &origpubkey,const CTransaction& tx,int32_t v,uint256 refassetid);
|
int64_t IsAssetvout(int32_t maxAssetExactAmountDepth, struct CCcontract_info *cp, Eval* eval, int64_t &price,std::vector<uint8_t> &origpubkey,const CTransaction& tx,int32_t v,uint256 refassetid);
|
||||||
bool ValidateBidRemainder(int64_t remaining_price,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidprice,int64_t totalprice);
|
bool ValidateBidRemainder(int64_t remaining_price,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidprice,int64_t totalprice);
|
||||||
bool ValidateAskRemainder(int64_t remaining_price,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidprice,int64_t totalprice);
|
bool ValidateAskRemainder(int64_t remaining_price,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidprice,int64_t totalprice);
|
||||||
bool ValidateSwapRemainder(int64_t remaining_price,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidprice,int64_t totalprice);
|
bool ValidateSwapRemainder(int64_t remaining_price,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidprice,int64_t totalprice);
|
||||||
@@ -44,7 +44,8 @@ bool SetAskFillamounts(int64_t &paid,int64_t &remaining_price,int64_t orig_nValu
|
|||||||
bool SetSwapFillamounts(int64_t &paid,int64_t &remaining_price,int64_t orig_nValue,int64_t &received,int64_t totalprice);
|
bool SetSwapFillamounts(int64_t &paid,int64_t &remaining_price,int64_t orig_nValue,int64_t &received,int64_t totalprice);
|
||||||
int64_t AssetValidateBuyvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpprice,std::vector<uint8_t> &tmporigpubkey,char *CCaddr,char *origaddr,const CTransaction &tx,uint256 refassetid);
|
int64_t AssetValidateBuyvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpprice,std::vector<uint8_t> &tmporigpubkey,char *CCaddr,char *origaddr,const CTransaction &tx,uint256 refassetid);
|
||||||
int64_t AssetValidateSellvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpprice,std::vector<uint8_t> &tmporigpubkey,char *CCaddr,char *origaddr,const CTransaction &tx,uint256 assetid);
|
int64_t AssetValidateSellvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpprice,std::vector<uint8_t> &tmporigpubkey,char *CCaddr,char *origaddr,const CTransaction &tx,uint256 assetid);
|
||||||
bool AssetExactAmounts(struct CCcontract_info *cp,int64_t &inputs,int32_t starti,int64_t &outputs,Eval* eval,const CTransaction &tx,uint256 assetid);
|
bool AssetExactAmounts(int32_t maxDepth, struct CCcontract_info *cp,int64_t &inputs,int32_t starti,int64_t &outputs,Eval* eval,const CTransaction &tx,uint256 assetid);
|
||||||
|
//bool AssetExactAmounts(bool doValidateTx, struct CCcontract_info *cp, int64_t &inputs, int32_t starti, int64_t &outputs, Eval* eval, const CTransaction &tx, uint256 assetid, std::vector<CTransaction> &ccVinsTxs);
|
||||||
|
|
||||||
// CCassetstx
|
// CCassetstx
|
||||||
int64_t GetAssetBalance(CPubKey pk,uint256 tokenid);
|
int64_t GetAssetBalance(CPubKey pk,uint256 tokenid);
|
||||||
|
|||||||
@@ -342,25 +342,54 @@ bool GetAssetorigaddrs(struct CCcontract_info *cp,char *CCaddr,char *destaddr,co
|
|||||||
else return(false);
|
else return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t IsAssetvout(int64_t &price,std::vector<uint8_t> &origpubkey,const CTransaction& tx,int32_t v,uint256 refassetid)
|
|
||||||
|
// Checks if the vout is a really Asset CC vout
|
||||||
|
// if maxAssetExactAmountDepth > 0, it also validates the vin transaction itself:
|
||||||
|
// it should be either sum(cc vins) == sum(cc vouts) or the transaction is the 'tokenbase' ('c') tx
|
||||||
|
int64_t IsAssetvout(int32_t maxAssetExactAmountDepth, struct CCcontract_info *cp, Eval* eval, int64_t &price,std::vector<uint8_t> &origpubkey,const CTransaction& tx,int32_t v,uint256 refassetid)
|
||||||
{
|
{
|
||||||
uint256 assetid,assetid2; int64_t nValue=0; int32_t n; uint8_t funcid;
|
uint256 assetid,assetid2; int64_t nValue=0; int32_t n; uint8_t funcid;
|
||||||
|
|
||||||
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) // maybe check address too?
|
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) // maybe check address too?
|
||||||
{
|
{
|
||||||
n = tx.vout.size();
|
|
||||||
|
if (maxAssetExactAmountDepth > 0) {
|
||||||
|
//validate all tx
|
||||||
|
int64_t myCCVinsAmount = 0, myCCVoutsAmount = 0;
|
||||||
|
std::vector<CTransaction> ccVinsTxs;
|
||||||
|
|
||||||
|
//std::cerr << "IsAssetvout() validate=yes" << std::endl;
|
||||||
|
const bool validateVinTxs = false;
|
||||||
|
bool isEqualAmounts = AssetExactAmounts(maxAssetExactAmountDepth, cp, myCCVinsAmount, 0, myCCVoutsAmount, eval, tx, refassetid);
|
||||||
|
|
||||||
|
// if ccInputs != ccOutputs and it is not the tokenbase tx means it is possibly fake tx (dimxy):
|
||||||
|
if (!isEqualAmounts && refassetid != tx.GetHash()) { // checking that this is the true tokenbase tx, by verifying that funcid=c, is done further in this function (dimxy)
|
||||||
|
std::cerr << "IsAssetvout() detected bad tx=" << tx.GetHash().GetHex() << ": cc inputs != cc outputs and not the 'tokenbase' tx" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
n = tx.vout.size();
|
||||||
|
if (v >= n - 1) { // just moved this up (dimxy)
|
||||||
|
std::cerr << "isAssetVout() internal err: (v >= n - 1), returning 0" << std::endl;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
nValue = tx.vout[v].nValue;
|
nValue = tx.vout[v].nValue;
|
||||||
//fprintf(stderr,"CC vout v.%d of n.%d %.8f\n",v,n,(double)nValue/COIN);
|
|
||||||
if ( v >= n-1 )
|
// fprintf(stderr,"IsAssetvout() CC vout v.%d of n=%d amount=%.8f\n",v,n,(double)nValue/COIN);
|
||||||
return(0);
|
|
||||||
if ( (funcid= DecodeAssetOpRet(tx.vout[n-1].scriptPubKey,assetid,assetid2,price,origpubkey)) == 0 )
|
if ( (funcid= DecodeAssetOpRet(tx.vout[n-1].scriptPubKey,assetid,assetid2,price,origpubkey)) == 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"null decodeopret v.%d\n",v);
|
fprintf(stderr,"IsAssetvout() null decodeopret v.%d\n",v);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
else if ( funcid == 'c' )
|
else if ( funcid == 'c' )
|
||||||
{
|
{
|
||||||
if ( refassetid == tx.GetHash() && v == 0 )
|
if (refassetid == tx.GetHash() && v == 0) {
|
||||||
return(nValue);
|
std::cerr << "isAssetVout() this is the tokenbase 'c' tx, txid=" << tx.GetHash().GetHex() << " returning nValue=" << nValue << std::endl;
|
||||||
|
return(nValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ( (funcid == 'b' || funcid == 'B') && v == 0 ) // critical! 'b'/'B' vout0 is NOT asset
|
else if ( (funcid == 'b' || funcid == 'B') && v == 0 ) // critical! 'b'/'B' vout0 is NOT asset
|
||||||
return(0);
|
return(0);
|
||||||
@@ -368,7 +397,7 @@ int64_t IsAssetvout(int64_t &price,std::vector<uint8_t> &origpubkey,const CTrans
|
|||||||
{
|
{
|
||||||
if ( assetid == refassetid )
|
if ( assetid == refassetid )
|
||||||
{
|
{
|
||||||
//fprintf(stderr,"returning %.8f\n",(double)nValue/COIN);
|
fprintf(stderr,"IsAssetvout() returning %.8f\n",(double)nValue/COIN);
|
||||||
return(nValue);
|
return(nValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -443,29 +472,37 @@ int64_t AssetValidateSellvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpp
|
|||||||
fprintf(stderr,"AssetValidateSellvin\n");
|
fprintf(stderr,"AssetValidateSellvin\n");
|
||||||
if ( (nValue= AssetValidateCCvin(cp,eval,CCaddr,origaddr,tx,1,vinTx)) == 0 )
|
if ( (nValue= AssetValidateCCvin(cp,eval,CCaddr,origaddr,tx,1,vinTx)) == 0 )
|
||||||
return(0);
|
return(0);
|
||||||
if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,vinTx,0,assetid)) == 0 )
|
if ( (assetoshis= IsAssetvout(1, cp, NULL, tmpprice,tmporigpubkey,vinTx,0,assetid)) == 0 )
|
||||||
return eval->Invalid("invalid missing CC vout0 for sellvin");
|
return eval->Invalid("invalid missing CC vout0 for sellvin");
|
||||||
else return(assetoshis);
|
else return(assetoshis);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AssetExactAmounts(struct CCcontract_info *cp,int64_t &inputs,int32_t starti,int64_t &outputs,Eval* eval,const CTransaction &tx,uint256 assetid)
|
|
||||||
|
// overload with additional params for deep tx validation (dimxy)
|
||||||
|
bool AssetExactAmounts(int maxDepth, struct CCcontract_info *cp, int64_t &inputs, int32_t starti, int64_t &outputs, Eval* eval, const CTransaction &tx, uint256 assetid)
|
||||||
{
|
{
|
||||||
CTransaction vinTx; uint256 hashBlock,id,id2; int32_t i,flag,numvins,numvouts; int64_t assetoshis; std::vector<uint8_t> tmporigpubkey; int64_t tmpprice;
|
CTransaction vinTx; uint256 hashBlock,id,id2; int32_t i,flag,numvins,numvouts; int64_t assetoshis; std::vector<uint8_t> tmporigpubkey; int64_t tmpprice;
|
||||||
numvins = tx.vin.size();
|
numvins = tx.vin.size();
|
||||||
numvouts = tx.vout.size();
|
numvouts = tx.vout.size();
|
||||||
inputs = outputs = 0;
|
inputs = outputs = 0;
|
||||||
|
|
||||||
|
maxDepth--;
|
||||||
|
|
||||||
for (i=starti; i<numvins; i++)
|
for (i=starti; i<numvins; i++)
|
||||||
{
|
{
|
||||||
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) != 0 )
|
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) != 0 )
|
||||||
{
|
{
|
||||||
if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 )
|
//std::cerr << "AssetExactAmounts() eval is true=" << (eval != NULL) << " ismyvin=ok for_i=" << i << std::endl;
|
||||||
|
// we are really not inside validation! -- dimxy
|
||||||
|
if ( (eval && eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0) || (!eval && !myGetTransaction(tx.vin[i].prevout.hash, vinTx, hashBlock)) )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"i.%d starti.%d numvins.%d\n",i,starti,numvins);
|
fprintf(stderr,"AssetExactAmounts() cannot read vintx i.%d starti.%d numvins.%d\n", i,starti,numvins);
|
||||||
return eval->Invalid("always should find vin, but didnt");
|
return (!eval) ? false : eval->Invalid("always should find vin, but didnt");
|
||||||
}
|
|
||||||
else if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,vinTx,tx.vin[i].prevout.n,assetid)) != 0 )
|
} // false means 'don't go deeper' -- dimxy
|
||||||
|
else if ( (assetoshis= IsAssetvout( maxDepth, cp, eval, tmpprice,tmporigpubkey,vinTx,tx.vin[i].prevout.n,assetid)) != 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"vin%d %llu, ",i,(long long)assetoshis);
|
fprintf(stderr,"AssetExactAmounts() vin%d %llu, ",i,(long long)assetoshis);
|
||||||
inputs += assetoshis;
|
inputs += assetoshis;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -473,33 +510,47 @@ bool AssetExactAmounts(struct CCcontract_info *cp,int64_t &inputs,int32_t starti
|
|||||||
if ( vinTx.vout[i].scriptPubKey.IsPayToCryptoCondition() != 0 && DecodeAssetOpRet(vinTx.vout[vinTx.vout.size()-1].scriptPubKey,id,id2,tmpprice,tmporigpubkey) == 't' && id == assetid )
|
if ( vinTx.vout[i].scriptPubKey.IsPayToCryptoCondition() != 0 && DecodeAssetOpRet(vinTx.vout[vinTx.vout.size()-1].scriptPubKey,id,id2,tmpprice,tmporigpubkey) == 't' && id == assetid )
|
||||||
{
|
{
|
||||||
assetoshis = vinTx.vout[i].nValue;
|
assetoshis = vinTx.vout[i].nValue;
|
||||||
fprintf(stderr,"vin%d %llu special case, ",i,(long long)assetoshis);
|
fprintf(stderr,"AssetExactAmounts() vin%d assetoshis=%llu special case, ",i,(long long)assetoshis);
|
||||||
inputs += assetoshis;
|
inputs += assetoshis;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( DecodeAssetOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,id,id2,tmpprice,tmporigpubkey) == 't' && id == assetid )
|
if ( DecodeAssetOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,id,id2,tmpprice,tmporigpubkey) == 't' && id == assetid )
|
||||||
flag = 1;
|
flag = 1;
|
||||||
else flag = 0;
|
else flag = 0;
|
||||||
|
|
||||||
for (i=0; i<numvouts; i++)
|
for (i=0; i<numvouts; i++)
|
||||||
{
|
{ // 'false' means 'dont go deep' -- dimxy
|
||||||
if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,tx,i,assetid)) != 0 )
|
if ( (assetoshis= IsAssetvout(maxDepth, cp, eval, tmpprice,tmporigpubkey,tx,i,assetid)) != 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"vout%d %llu, ",i,(long long)assetoshis);
|
fprintf(stderr,"AssetExactAmounts() vout%d assetoshis=%llu, ",i,(long long)assetoshis);
|
||||||
outputs += assetoshis;
|
outputs += assetoshis;
|
||||||
}
|
}
|
||||||
|
// Note: account it only if this is 'transfer' tx -- dimxy
|
||||||
else if ( flag != 0 && tx.vout[i].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
else if ( flag != 0 && tx.vout[i].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||||
{
|
{
|
||||||
assetoshis = tx.vout[i].nValue;
|
assetoshis = tx.vout[i].nValue;
|
||||||
fprintf(stderr,"vout%d %llu special case, ",i,(long long)assetoshis);
|
fprintf(stderr,"AssetExactAmounts() vout%d assetoshis=%llu special case, ",i,(long long)assetoshis);
|
||||||
outputs += assetoshis;
|
outputs += assetoshis;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//std::cerr << "AssetExactAmounts() inputs=" << inputs << " outputs=" << outputs << " for txid=" << tx.GetHash().GetHex() << std::endl;
|
||||||
|
|
||||||
if ( inputs != outputs )
|
if ( inputs != outputs )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"inputs %.8f vs %.8f outputs\n",(double)inputs/COIN,(double)outputs/COIN);
|
std::cerr << "AssetExactAmounts() incorrect inputs=" << (double)inputs / COIN << " vs outputs=" << (double)outputs/COIN << " for txid=" << tx.GetHash().GetHex() << std::endl;
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
else return(true);
|
else return(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// overload for existing calls of this function (dimxy)
|
||||||
|
/*bool AssetExactAmounts(struct CCcontract_info *cp, int64_t &inputs, int32_t starti, int64_t &outputs, Eval* eval, const CTransaction &tx, uint256 assetid) {
|
||||||
|
std::vector<CTransaction> ccVinsTxs;
|
||||||
|
|
||||||
|
return AssetExactAmounts(true, cp, inputs, starti, outputs, eval, tx, assetid);
|
||||||
|
}*/
|
||||||
@@ -38,19 +38,22 @@ int64_t AddAssetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK
|
|||||||
Getscriptaddress(destaddr,vintx.vout[vout].scriptPubKey);
|
Getscriptaddress(destaddr,vintx.vout[vout].scriptPubKey);
|
||||||
if ( strcmp(destaddr,coinaddr) != 0 && strcmp(destaddr,cp->unspendableCCaddr) != 0 && strcmp(destaddr,cp->unspendableaddr2) != 0 )
|
if ( strcmp(destaddr,coinaddr) != 0 && strcmp(destaddr,cp->unspendableCCaddr) != 0 && strcmp(destaddr,cp->unspendableaddr2) != 0 )
|
||||||
continue;
|
continue;
|
||||||
fprintf(stderr,"check %s %.8f\n",destaddr,(double)vintx.vout[vout].nValue/COIN);
|
fprintf(stderr,"AddAssetInputs() check destaddress=%s vout amount=%.8f\n",destaddr,(double)vintx.vout[vout].nValue/COIN);
|
||||||
if ( (nValue= IsAssetvout(price,origpubkey,vintx,vout,assetid)) > 0 && myIsutxo_spentinmempool(txid,vout) == 0 )
|
if ( (nValue= IsAssetvout(1, cp, NULL, price,origpubkey,vintx,vout,assetid)) > 0 && myIsutxo_spentinmempool(txid,vout) == 0 )
|
||||||
{
|
{
|
||||||
if ( total != 0 && maxinputs != 0 )
|
if ( total != 0 && maxinputs != 0 )
|
||||||
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
||||||
nValue = it->second.satoshis;
|
nValue = it->second.satoshis;
|
||||||
totalinputs += nValue;
|
totalinputs += nValue;
|
||||||
|
//std::cerr << "AddAssetInputs() adding input nValue=" << nValue << std::endl;
|
||||||
n++;
|
n++;
|
||||||
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
|
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//std::cerr << "AddAssetInputs() found totalinputs=" << totalinputs << std::endl;
|
||||||
return(totalinputs);
|
return(totalinputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,6 +238,11 @@ std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector<uint8_t> des
|
|||||||
mask = ~((1LL << mtx.vin.size()) - 1);
|
mask = ~((1LL << mtx.vin.size()) - 1);
|
||||||
if ( (inputs= AddAssetInputs(cp,mtx,mypk,assetid,total,60)) > 0 )
|
if ( (inputs= AddAssetInputs(cp,mtx,mypk,assetid,total,60)) > 0 )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (inputs < total) { //added dimxy
|
||||||
|
std::cerr << "AssetTransfer(): insufficient funds" << std::endl;
|
||||||
|
return ("");
|
||||||
|
}
|
||||||
if ( inputs > total )
|
if ( inputs > total )
|
||||||
CCchange = (inputs - total);
|
CCchange = (inputs - total);
|
||||||
//for (i=0; i<n; i++)
|
//for (i=0; i<n; i++)
|
||||||
@@ -310,6 +318,9 @@ std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t p
|
|||||||
{
|
{
|
||||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||||
CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C;
|
CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C;
|
||||||
|
|
||||||
|
//std::cerr << "CreateSell() askamount=" << askamount << " pricetotal=" << pricetotal << std::endl;
|
||||||
|
|
||||||
if ( askamount < 0 || pricetotal < 0 )
|
if ( askamount < 0 || pricetotal < 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"negative askamount %lld, askamount %lld\n",(long long)pricetotal,(long long)askamount);
|
fprintf(stderr,"negative askamount %lld, askamount %lld\n",(long long)pricetotal,(long long)askamount);
|
||||||
@@ -324,8 +335,12 @@ std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t p
|
|||||||
mask = ~((1LL << mtx.vin.size()) - 1);
|
mask = ~((1LL << mtx.vin.size()) - 1);
|
||||||
if ( (inputs= AddAssetInputs(cp,mtx,mypk,assetid,askamount,60)) > 0 )
|
if ( (inputs= AddAssetInputs(cp,mtx,mypk,assetid,askamount,60)) > 0 )
|
||||||
{
|
{
|
||||||
if ( inputs < askamount )
|
if (inputs < askamount) {
|
||||||
askamount = inputs;
|
//askamount = inputs;
|
||||||
|
std::cerr << "CreateSell(): insufficient tokens for ask" << std::endl;
|
||||||
|
return ("");
|
||||||
|
}
|
||||||
|
|
||||||
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,askamount,GetUnspendable(cp,0)));
|
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,askamount,GetUnspendable(cp,0)));
|
||||||
if ( inputs > askamount )
|
if ( inputs > askamount )
|
||||||
CCchange = (inputs - askamount);
|
CCchange = (inputs - askamount);
|
||||||
@@ -333,9 +348,14 @@ std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t p
|
|||||||
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,mypk));
|
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,mypk));
|
||||||
opret = EncodeAssetOpRet('s',assetid,zeroid,pricetotal,Mypubkey());
|
opret = EncodeAssetOpRet('s',assetid,zeroid,pricetotal,Mypubkey());
|
||||||
return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,opret));
|
return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,opret));
|
||||||
} else fprintf(stderr,"need some assets to place ask\n");
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "need some assets to place ask\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fprintf(stderr,"need some native coins to place ask\n");
|
else { // dimxy added 'else', because it was misleading message before
|
||||||
|
fprintf(stderr, "need some native coins to place ask\n");
|
||||||
|
}
|
||||||
return("");
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,9 +393,15 @@ std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 a
|
|||||||
opret = EncodeAssetOpRet('e',assetid,assetid2,pricetotal,Mypubkey());
|
opret = EncodeAssetOpRet('e',assetid,assetid2,pricetotal,Mypubkey());
|
||||||
}
|
}
|
||||||
return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,opret));
|
return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,opret));
|
||||||
} else fprintf(stderr,"need some assets to place ask\n");
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "need some assets to place ask\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fprintf(stderr,"need some native coins to place ask\n");
|
else { // dimxy added 'else', because it was misleading message before
|
||||||
|
fprintf(stderr,"need some native coins to place ask\n");
|
||||||
|
}
|
||||||
|
|
||||||
return("");
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -129,6 +129,10 @@
|
|||||||
vout.n-1: opreturn [EVAL_ASSETS] ['E'] [assetid vin0+1] [assetid vin2] [remaining asset2 required] [origpubkey]
|
vout.n-1: opreturn [EVAL_ASSETS] ['E'] [assetid vin0+1] [assetid vin2] [remaining asset2 required] [origpubkey]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// tx validation
|
||||||
bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
|
bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
|
||||||
{
|
{
|
||||||
static uint256 zero;
|
static uint256 zero;
|
||||||
@@ -155,9 +159,11 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
|
|||||||
else starti = 1;
|
else starti = 1;
|
||||||
if ( assetid == zero )
|
if ( assetid == zero )
|
||||||
return eval->Invalid("illegal assetid");
|
return eval->Invalid("illegal assetid");
|
||||||
else if ( AssetExactAmounts(cp,inputs,starti,outputs,eval,tx,assetid) == false )
|
else if ( AssetExactAmounts(2, cp,inputs,starti,outputs,eval,tx,assetid) == false )
|
||||||
return eval->Invalid("asset inputs != outputs");
|
return eval->Invalid("asset inputs != outputs");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch ( funcid )
|
switch ( funcid )
|
||||||
{
|
{
|
||||||
case 'c': // create wont be called to be verified as it has no CC inputs
|
case 'c': // create wont be called to be verified as it has no CC inputs
|
||||||
@@ -321,7 +327,7 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
|
|||||||
}
|
}
|
||||||
fprintf(stderr,"fill validated\n");
|
fprintf(stderr,"fill validated\n");
|
||||||
break;
|
break;
|
||||||
case 'E': // fillexchange
|
case 'E': // fillexchange
|
||||||
return eval->Invalid("unexpected assets fillexchange funcid");
|
return eval->Invalid("unexpected assets fillexchange funcid");
|
||||||
break; // disable asset swaps
|
break; // disable asset swaps
|
||||||
//vin.0: normal input
|
//vin.0: normal input
|
||||||
@@ -333,7 +339,7 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
|
|||||||
//vout.3: CC output for asset2 change (if any)
|
//vout.3: CC output for asset2 change (if any)
|
||||||
//vout.3/4: normal output for change (if any)
|
//vout.3/4: normal output for change (if any)
|
||||||
//vout.n-1: opreturn [EVAL_ASSETS] ['E'] [assetid vin0+1] [assetid vin2] [remaining asset2 required] [origpubkey]
|
//vout.n-1: opreturn [EVAL_ASSETS] ['E'] [assetid vin0+1] [assetid vin2] [remaining asset2 required] [origpubkey]
|
||||||
if ( AssetExactAmounts(cp,inputs,1,outputs,eval,tx,assetid2) == false )
|
if ( AssetExactAmounts(1, cp,inputs,1,outputs,eval,tx,assetid2) == false )
|
||||||
eval->Invalid("asset2 inputs != outputs");
|
eval->Invalid("asset2 inputs != outputs");
|
||||||
if ( (assetoshis= AssetValidateSellvin(cp,eval,totalunits,tmporigpubkey,CCaddr,origaddr,tx,assetid)) == 0 )
|
if ( (assetoshis= AssetValidateSellvin(cp,eval,totalunits,tmporigpubkey,CCaddr,origaddr,tx,assetid)) == 0 )
|
||||||
return(false);
|
return(false);
|
||||||
|
|||||||
@@ -5310,6 +5310,7 @@ int32_t ensure_CCrequirements()
|
|||||||
#include "../cc/CCOracles.h"
|
#include "../cc/CCOracles.h"
|
||||||
#include "../cc/CCGateways.h"
|
#include "../cc/CCGateways.h"
|
||||||
#include "../cc/CCPrices.h"
|
#include "../cc/CCPrices.h"
|
||||||
|
#include "../cc/CCHeir.h"
|
||||||
|
|
||||||
UniValue CCaddress(struct CCcontract_info *cp,char *name,std::vector<unsigned char> &pubkey)
|
UniValue CCaddress(struct CCcontract_info *cp,char *name,std::vector<unsigned char> &pubkey)
|
||||||
{
|
{
|
||||||
@@ -5531,15 +5532,25 @@ UniValue gatewaysaddress(const UniValue& params, bool fHelp)
|
|||||||
|
|
||||||
UniValue heiraddress(const UniValue& params, bool fHelp)
|
UniValue heiraddress(const UniValue& params, bool fHelp)
|
||||||
{
|
{
|
||||||
struct CCcontract_info *cp,C; std::vector<unsigned char> pubkey;
|
struct CCcontract_info *cp,C; std::vector<unsigned char> destPubkey;
|
||||||
|
|
||||||
cp = CCinit(&C,EVAL_HEIR);
|
cp = CCinit(&C,EVAL_HEIR);
|
||||||
if ( fHelp || params.size() > 1 )
|
if ( fHelp || (params.size() != 4 && params.size() != 3))
|
||||||
throw runtime_error("heiraddress [pubkey]\n");
|
throw runtime_error("heiraddress func txid amount [destpubkey]\n");
|
||||||
if ( ensure_CCrequirements() < 0 )
|
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");
|
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||||
if ( params.size() == 1 )
|
//if ( params.size() == 1 )
|
||||||
pubkey = ParseHex(params[0].get_str().c_str());
|
// pubkey = ParseHex(params[0].get_str().c_str());
|
||||||
return(CCaddress(cp,(char *)"Heir",pubkey));
|
|
||||||
|
char funcid = ((char *)params[0].get_str().c_str())[0];
|
||||||
|
uint256 assetid = Parseuint256((char *)params[1].get_str().c_str());
|
||||||
|
int64_t funds = atof(params[2].get_str().c_str()) * COIN ;
|
||||||
|
if(params.size() == 4)
|
||||||
|
destPubkey = ParseHex(params[3].get_str().c_str());
|
||||||
|
|
||||||
|
return HeirFundBad(funcid, assetid, funds, destPubkey);
|
||||||
|
|
||||||
|
//return(CCaddress(cp,(char *)"Heir",pubkey));
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue lottoaddress(const UniValue& params, bool fHelp)
|
UniValue lottoaddress(const UniValue& params, bool fHelp)
|
||||||
@@ -6837,7 +6848,7 @@ UniValue tokencreate(const UniValue& params, bool fHelp)
|
|||||||
const CKeyStore& keystore = *pwalletMain;
|
const CKeyStore& keystore = *pwalletMain;
|
||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
name = params[0].get_str();
|
name = params[0].get_str();
|
||||||
supply = atof(params[1].get_str().c_str()) * COIN + 0.00000000499999;
|
supply = atof(params[1].get_str().c_str()) * COIN + 0.00000000499999; // what for is this '+0.00000000499999'? it will be lost while converting double to int64_t (dimxy)
|
||||||
if ( name.size() == 0 || name.size() > 32)
|
if ( name.size() == 0 || name.size() > 32)
|
||||||
{
|
{
|
||||||
ERR_RESULT("Token name must not be empty and up to 32 characters");
|
ERR_RESULT("Token name must not be empty and up to 32 characters");
|
||||||
@@ -6877,7 +6888,8 @@ UniValue tokentransfer(const UniValue& params, bool fHelp)
|
|||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
||||||
std::vector<unsigned char> pubkey(ParseHex(params[1].get_str().c_str()));
|
std::vector<unsigned char> pubkey(ParseHex(params[1].get_str().c_str()));
|
||||||
amount = atol(params[2].get_str().c_str());
|
//amount = atol(params[2].get_str().c_str());
|
||||||
|
amount = atoll(params[2].get_str().c_str()); // dimxy changed to prevent loss of significance
|
||||||
if ( tokenid == zeroid )
|
if ( tokenid == zeroid )
|
||||||
{
|
{
|
||||||
ERR_RESULT("invalid tokenid");
|
ERR_RESULT("invalid tokenid");
|
||||||
@@ -6913,7 +6925,8 @@ UniValue tokenconvert(const UniValue& params, bool fHelp)
|
|||||||
evalcode = atoi(params[0].get_str().c_str());
|
evalcode = atoi(params[0].get_str().c_str());
|
||||||
tokenid = Parseuint256((char *)params[1].get_str().c_str());
|
tokenid = Parseuint256((char *)params[1].get_str().c_str());
|
||||||
std::vector<unsigned char> pubkey(ParseHex(params[2].get_str().c_str()));
|
std::vector<unsigned char> pubkey(ParseHex(params[2].get_str().c_str()));
|
||||||
amount = atol(params[3].get_str().c_str());
|
//amount = atol(params[3].get_str().c_str());
|
||||||
|
amount = atoll(params[3].get_str().c_str()); // dimxy changed to prevent loss of significance
|
||||||
if ( tokenid == zeroid )
|
if ( tokenid == zeroid )
|
||||||
{
|
{
|
||||||
ERR_RESULT("invalid tokenid");
|
ERR_RESULT("invalid tokenid");
|
||||||
@@ -6946,7 +6959,8 @@ UniValue tokenbid(const UniValue& params, bool fHelp)
|
|||||||
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||||
const CKeyStore& keystore = *pwalletMain;
|
const CKeyStore& keystore = *pwalletMain;
|
||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
numtokens = atoi(params[0].get_str().c_str());
|
//numtokens = atoi(params[0].get_str().c_str());
|
||||||
|
numtokens = atoll(params[0].get_str().c_str()); // dimxy changed to prevent loss of significance
|
||||||
tokenid = Parseuint256((char *)params[1].get_str().c_str());
|
tokenid = Parseuint256((char *)params[1].get_str().c_str());
|
||||||
price = atof(params[2].get_str().c_str());
|
price = atof(params[2].get_str().c_str());
|
||||||
bidamount = (price * numtokens) * COIN + 0.0000000049999;
|
bidamount = (price * numtokens) * COIN + 0.0000000049999;
|
||||||
@@ -7014,7 +7028,8 @@ UniValue tokenfillbid(const UniValue& params, bool fHelp)
|
|||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
||||||
bidtxid = Parseuint256((char *)params[1].get_str().c_str());
|
bidtxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||||
fillamount = atol(params[2].get_str().c_str());
|
// fillamount = atol(params[2].get_str().c_str());
|
||||||
|
fillamount = atoll(params[2].get_str().c_str()); // dimxy changed to prevent loss of significance
|
||||||
if ( fillamount <= 0 )
|
if ( fillamount <= 0 )
|
||||||
{
|
{
|
||||||
ERR_RESULT("fillamount must be positive");
|
ERR_RESULT("fillamount must be positive");
|
||||||
@@ -7043,10 +7058,12 @@ UniValue tokenask(const UniValue& params, bool fHelp)
|
|||||||
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||||
const CKeyStore& keystore = *pwalletMain;
|
const CKeyStore& keystore = *pwalletMain;
|
||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
numtokens = atoi(params[0].get_str().c_str());
|
//numtokens = atoi(params[0].get_str().c_str());
|
||||||
|
numtokens = atoll(params[0].get_str().c_str()); // dimxy changed to prevent loss of significance
|
||||||
tokenid = Parseuint256((char *)params[1].get_str().c_str());
|
tokenid = Parseuint256((char *)params[1].get_str().c_str());
|
||||||
price = atof(params[2].get_str().c_str());
|
price = atof(params[2].get_str().c_str());
|
||||||
askamount = (price * numtokens) * COIN + 0.0000000049999;
|
askamount = (price * numtokens) * COIN + 0.0000000049999;
|
||||||
|
//std::cerr << std::boolalpha << "tokenask(): (tokenid == zeroid) is " << (tokenid == zeroid) << " (numtokens <= 0) is " << (numtokens <= 0) << " (price <= 0) is " << (price <= 0) << " (askamount <= 0) is " << (askamount <= 0) << std::endl;
|
||||||
if ( tokenid == zeroid || numtokens <= 0 || price <= 0 || askamount <= 0 )
|
if ( tokenid == zeroid || numtokens <= 0 || price <= 0 || askamount <= 0 )
|
||||||
{
|
{
|
||||||
ERR_RESULT("invalid parameter");
|
ERR_RESULT("invalid parameter");
|
||||||
@@ -7075,7 +7092,8 @@ UniValue tokenswapask(const UniValue& params, bool fHelp)
|
|||||||
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||||
const CKeyStore& keystore = *pwalletMain;
|
const CKeyStore& keystore = *pwalletMain;
|
||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
numtokens = atoi(params[0].get_str().c_str());
|
//numtokens = atoi(params[0].get_str().c_str());
|
||||||
|
numtokens = atoll(params[0].get_str().c_str()); // dimxy changed to prevent loss of significance
|
||||||
tokenid = Parseuint256((char *)params[1].get_str().c_str());
|
tokenid = Parseuint256((char *)params[1].get_str().c_str());
|
||||||
otherid = Parseuint256((char *)params[2].get_str().c_str());
|
otherid = Parseuint256((char *)params[2].get_str().c_str());
|
||||||
price = atof(params[3].get_str().c_str());
|
price = atof(params[3].get_str().c_str());
|
||||||
@@ -7129,7 +7147,8 @@ UniValue tokenfillask(const UniValue& params, bool fHelp)
|
|||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
||||||
asktxid = Parseuint256((char *)params[1].get_str().c_str());
|
asktxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||||
fillunits = atol(params[2].get_str().c_str());
|
//fillunits = atol(params[2].get_str().c_str());
|
||||||
|
fillunits = atoll(params[2].get_str().c_str()); // dimxy changed to prevent loss of significance
|
||||||
if ( fillunits <= 0 )
|
if ( fillunits <= 0 )
|
||||||
{
|
{
|
||||||
ERR_RESULT("fillunits must be positive");
|
ERR_RESULT("fillunits must be positive");
|
||||||
@@ -7169,7 +7188,8 @@ UniValue tokenfillswap(const UniValue& params, bool fHelp)
|
|||||||
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
||||||
otherid = Parseuint256((char *)params[1].get_str().c_str());
|
otherid = Parseuint256((char *)params[1].get_str().c_str());
|
||||||
asktxid = Parseuint256((char *)params[2].get_str().c_str());
|
asktxid = Parseuint256((char *)params[2].get_str().c_str());
|
||||||
fillunits = atol(params[3].get_str().c_str());
|
//fillunits = atol(params[3].get_str().c_str());
|
||||||
|
fillunits = atoll(params[3].get_str().c_str()); // dimxy changed to prevent loss of significance
|
||||||
hex = FillSell(0,tokenid,otherid,asktxid,fillunits);
|
hex = FillSell(0,tokenid,otherid,asktxid,fillunits);
|
||||||
if (fillunits > 0) {
|
if (fillunits > 0) {
|
||||||
if ( hex.size() > 0 ) {
|
if ( hex.size() > 0 ) {
|
||||||
|
|||||||
Reference in New Issue
Block a user