Merge pull request #884 from jl777/FSM

ac_private to allow notary p2pk vouts
This commit is contained in:
jl777
2018-09-21 23:35:16 -11:00
committed by GitHub
16 changed files with 695 additions and 229 deletions

View File

@@ -22,6 +22,13 @@
bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
// CCcustom // CCcustom
UniValue PricesInfo(); UniValue PricesList();
UniValue PricesInfo(uint256 fundingtxid);
UniValue PricesStatus(uint64_t txfee,uint256 refbettoken,uint256 fundingtxid,uint256 bettxid);
std::string PricesCreateFunding(uint64_t txfee,uint256 bettoken,uint256 oracletxid,uint64_t margin,uint64_t mode,uint256 longtoken,uint256 shorttoken,int32_t maxleverage,int64_t funding,std::vector<CPubKey> pubkeys);
std::string PricesAddFunding(uint64_t txfee,uint256 bettoken,uint256 fundingtxid,int64_t amount);
std::string PricesBet(uint64_t txfee,uint256 bettoken,uint256 fundingtxid,int64_t amount,int32_t leverage);
std::string PricesFinish(uint64_t txfee,uint256 bettoken,uint256 fundingtxid,uint256 bettxid);
#endif #endif

View File

@@ -54,6 +54,8 @@ UniValue AssetInfo(uint256 tokenid);
UniValue AssetList(); UniValue AssetList();
std::string CreateAsset(int64_t txfee,int64_t assetsupply,std::string name,std::string description); std::string CreateAsset(int64_t txfee,int64_t assetsupply,std::string name,std::string description);
std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector<uint8_t> destpubkey,int64_t total); std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector<uint8_t> destpubkey,int64_t total);
std::string AssetConvert(int64_t txfee,uint256 assetid,std::vector<uint8_t> destpubkey,int64_t total,int32_t evalcode);
std::string CreateBuyOffer(int64_t txfee,int64_t bidamount,uint256 assetid,int64_t pricetotal); std::string CreateBuyOffer(int64_t txfee,int64_t bidamount,uint256 assetid,int64_t pricetotal);
std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid); std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid);
std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t fillamount); std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t fillamount);

View File

@@ -367,8 +367,11 @@ int64_t IsAssetvout(int64_t &price,std::vector<uint8_t> &origpubkey,const CTrans
else if ( funcid != 'E' ) else if ( funcid != 'E' )
{ {
if ( assetid == refassetid ) if ( assetid == refassetid )
{
//fprintf(stderr,"returning %.8f\n",(double)nValue/COIN);
return(nValue); return(nValue);
} }
}
else if ( funcid == 'E' ) else if ( funcid == 'E' )
{ {
if ( v < 2 && assetid == refassetid ) if ( v < 2 && assetid == refassetid )
@@ -447,7 +450,7 @@ int64_t AssetValidateSellvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpp
bool AssetExactAmounts(struct CCcontract_info *cp,int64_t &inputs,int32_t starti,int64_t &outputs,Eval* eval,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)
{ {
CTransaction vinTx; uint256 hashBlock; int32_t i,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;
@@ -465,8 +468,20 @@ bool AssetExactAmounts(struct CCcontract_info *cp,int64_t &inputs,int32_t starti
fprintf(stderr,"vin%d %llu, ",i,(long long)assetoshis); fprintf(stderr,"vin%d %llu, ",i,(long long)assetoshis);
inputs += assetoshis; inputs += assetoshis;
} }
else
{
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;
fprintf(stderr,"vin%d %llu special case, ",i,(long long)assetoshis);
inputs += assetoshis;
} }
} }
}
}
if ( DecodeAssetOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,id,id2,tmpprice,tmporigpubkey) == 't' && id == assetid )
flag = 1;
else flag = 0;
for (i=0; i<numvouts; i++) for (i=0; i<numvouts; i++)
{ {
if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,tx,i,assetid)) != 0 ) if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,tx,i,assetid)) != 0 )
@@ -474,6 +489,12 @@ bool AssetExactAmounts(struct CCcontract_info *cp,int64_t &inputs,int32_t starti
fprintf(stderr,"vout%d %llu, ",i,(long long)assetoshis); fprintf(stderr,"vout%d %llu, ",i,(long long)assetoshis);
outputs += assetoshis; outputs += assetoshis;
} }
else if ( flag != 0 && tx.vout[i].scriptPubKey.IsPayToCryptoCondition() != 0 )
{
assetoshis = tx.vout[i].nValue;
fprintf(stderr,"vout%d %llu special case, ",i,(long long)assetoshis);
outputs += assetoshis;
}
} }
if ( inputs != outputs ) if ( inputs != outputs )
{ {

View File

@@ -243,6 +243,32 @@ std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector<uint8_t> des
return(""); return("");
} }
std::string AssetConvert(int64_t txfee,uint256 assetid,std::vector<uint8_t> destpubkey,int64_t total,int32_t evalcode)
{
CMutableTransaction mtx; CPubKey mypk; int64_t CCchange=0,inputs=0; struct CCcontract_info *cp,C;
if ( total < 0 )
{
fprintf(stderr,"negative total %lld\n",(long long)total);
return("");
}
cp = CCinit(&C,EVAL_ASSETS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
{
if ( (inputs= AddAssetInputs(cp,mtx,mypk,assetid,total,60)) > 0 )
{
if ( inputs > total )
CCchange = (inputs - total);
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,mypk));
mtx.vout.push_back(MakeCC1vout(evalcode,total,pubkey2pk(destpubkey)));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetOpRet('t',assetid,zeroid,0,Mypubkey())));
} else fprintf(stderr,"not enough CC asset inputs for %.8f\n",(double)total/COIN);
}
return("");
}
std::string CreateBuyOffer(int64_t txfee,int64_t bidamount,uint256 assetid,int64_t pricetotal) std::string CreateBuyOffer(int64_t txfee,int64_t bidamount,uint256 assetid,int64_t pricetotal)
{ {
CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C; uint256 hashBlock; CTransaction vintx; std::vector<uint8_t> origpubkey; std::string name,description; CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C; uint256 hashBlock; CTransaction vintx; std::vector<uint8_t> origpubkey; std::string name,description;

View File

@@ -250,7 +250,8 @@ int64_t CCfullsupply(uint256 tokenid)
int64_t CCtoken_balance(char *coinaddr,uint256 tokenid) int64_t CCtoken_balance(char *coinaddr,uint256 tokenid)
{ {
int64_t price,sum = 0; int32_t numvouts; CTransaction tx; uint256 assetid,assetid2,txid,hashBlock; std::vector<uint8_t> origpubkey; std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; int64_t price,sum = 0; int32_t numvouts; CTransaction tx; uint256 assetid,assetid2,txid,hashBlock; std::vector<uint8_t> origpubkey;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
SetCCunspents(unspentOutputs,coinaddr); SetCCunspents(unspentOutputs,coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{ {

View File

@@ -63,6 +63,7 @@ CTxOut MakeCC1of2vout(uint8_t evalcode,CAmount nValue,CPubKey pk1,CPubKey pk2)
CTxOut vout; CTxOut vout;
CC *payoutCond = MakeCCcond1of2(evalcode,pk1,pk2); CC *payoutCond = MakeCCcond1of2(evalcode,pk1,pk2);
vout = CTxOut(nValue,CCPubKey(payoutCond)); vout = CTxOut(nValue,CCPubKey(payoutCond));
fprintf(stderr,"payoutCond: %s\n",cc_conditionToJSONString(payoutCond));
cc_free(payoutCond); cc_free(payoutCond);
return(vout); return(vout);
} }

View File

@@ -167,7 +167,6 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
//vout.n-1: opreturn [EVAL_ASSETS] ['c'] [{"<assetname>":"<description>"}] //vout.n-1: opreturn [EVAL_ASSETS] ['c'] [{"<assetname>":"<description>"}]
return eval->Invalid("unexpected AssetValidate for createasset"); return eval->Invalid("unexpected AssetValidate for createasset");
break; break;
case 't': // transfer case 't': // transfer
//vin.0: normal input //vin.0: normal input
//vin.1 .. vin.n-1: valid CC outputs //vin.1 .. vin.n-1: valid CC outputs

View File

@@ -130,6 +130,16 @@ string oracles
gatewayspending will display all pending withdraws and if it is done on one of the msigpubkeys, then it will queue it for processing gatewayspending will display all pending withdraws and if it is done on one of the msigpubkeys, then it will queue it for processing
./c gatewayspending e6c99f79d4afb216aa8063658b4222edb773dd24bb0f8e91bd4ef341f3e47e5e KMD ./c gatewayspending e6c99f79d4afb216aa8063658b4222edb773dd24bb0f8e91bd4ef341f3e47e5e KMD
Implementation Issues:
When thinking about validation, it is clear that we cant use EVAL_ASSETS for the locked coins as there wont be any enforcement of the gateways locking. This means we need a way to transfer assets into gateways outputs and back. It seems a tokenconvert rpc will be needed and hopefully that will be enough to make it all work properly.
Care must be taken so that tokens are not lost and can be converted back.
This changes the usage to require tokenconvert before doing the bind and also tokenconvert before doing a withdraw. EVAL_GATEWAYS has evalcode of 251
The gatewaysclaim automatically converts the deposit amount of tokens back to EVAL_ASSETS.
*/ */
@@ -282,9 +292,9 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &
// helper functions for rpc calls in rpcwallet.cpp // helper functions for rpc calls in rpcwallet.cpp
/*int64_t AddGatewaysInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs) int64_t AddGatewaysInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 refassetid,int64_t total,int32_t maxinputs)
{ {
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0; char coinaddr[64],destaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 assetid,txid,hashBlock; std::vector<uint8_t> origpubkey; std::vector<uint8_t> vopret; CTransaction vintx; int32_t j,vout,n = 0; uint8_t evalcode,funcid;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk); GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr); SetCCunspents(unspentOutputs,coinaddr);
@@ -292,10 +302,21 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &
{ {
txid = it->first.txhash; txid = it->first.txhash;
vout = (int32_t)it->first.index; vout = (int32_t)it->first.index;
// no need to prevent dup for (j=0; j<mtx.vin.size(); j++)
if ( txid == mtx.vin[j].prevout.hash && vout == mtx.vin[j].prevout.n )
break;
if ( j != mtx.vin.size() )
continue;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{ {
if ( (nValue= IsGatewaysvout(cp,vintx,vout)) > 10000 && myIsutxo_spentinmempool(txid,vout) == 0 ) Getscriptaddress(destaddr,vintx.vout[vout].scriptPubKey);
if ( strcmp(destaddr,coinaddr) != 0 && strcmp(destaddr,cp->unspendableCCaddr) != 0 && strcmp(destaddr,cp->unspendableaddr2) != 0 )
continue;
GetOpReturnData(vintx.vout[vintx.vout.size()-1].scriptPubKey, vopret);
if ( E_UNMARSHAL(vopret,ss >> evalcode; ss >> funcid; ss >> assetid) != 0 )
{
assetid = revuint256(assetid);
if ( evalcode == cp->evalcode && assetid == refassetid && funcid == 't' && (nValue= vintx.vout[vout].nValue) > 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()));
@@ -307,8 +328,9 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &
} }
} }
} }
}
return(totalinputs); return(totalinputs);
}*/ }
int32_t GatewaysBindExists(struct CCcontract_info *cp,CPubKey gatewayspk,uint256 reftokenid) // dont forget to check mempool! int32_t GatewaysBindExists(struct CCcontract_info *cp,CPubKey gatewayspk,uint256 reftokenid) // dont forget to check mempool!
{ {
@@ -377,7 +399,7 @@ UniValue GatewaysInfo(uint256 bindtxid)
result.push_back(Pair("name","Gateways")); result.push_back(Pair("name","Gateways"));
cp = CCinit(&C,EVAL_GATEWAYS); cp = CCinit(&C,EVAL_GATEWAYS);
Gatewayspk = GetUnspendable(cp,0); Gatewayspk = GetUnspendable(cp,0);
_GetCCaddress(gatewaysassets,EVAL_ASSETS,Gatewayspk); _GetCCaddress(gatewaysassets,EVAL_GATEWAYS,Gatewayspk);
if ( GetTransaction(bindtxid,tx,hashBlock,false) != 0 ) if ( GetTransaction(bindtxid,tx,hashBlock,false) != 0 )
{ {
depositaddr[0] = 0; depositaddr[0] = 0;
@@ -433,19 +455,24 @@ std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t
{ {
CMutableTransaction mtx; CTransaction oracletx; uint8_t taddr,prefix,prefix2; CPubKey mypk,gatewayspk; CScript opret; uint256 hashBlock; struct CCcontract_info *cp,C; std::string name,description,format; int32_t i,numvouts; int64_t fullsupply; char destaddr[64],coinaddr[64],str[65],*fstr; CMutableTransaction mtx; CTransaction oracletx; uint8_t taddr,prefix,prefix2; CPubKey mypk,gatewayspk; CScript opret; uint256 hashBlock; struct CCcontract_info *cp,C; std::string name,description,format; int32_t i,numvouts; int64_t fullsupply; char destaddr[64],coinaddr[64],str[65],*fstr;
cp = CCinit(&C,EVAL_GATEWAYS); cp = CCinit(&C,EVAL_GATEWAYS);
if ( strcmp((char *)"KMD",coin.c_str()) == 0 )
{
taddr = 0;
prefix = 60;
prefix2 = 85;
}
else
{
fprintf(stderr,"set taddr, prefix, prefix2 for %s\n",coin.c_str());
taddr = 0;
prefix = 60;
prefix2 = 85;
}
if ( N == 0 || N > 15 || M > N ) if ( N == 0 || N > 15 || M > N )
{ {
fprintf(stderr,"illegal M.%d or N.%d\n",M,N); fprintf(stderr,"illegal M.%d or N.%d\n",M,N);
return(""); return("");
} }
if ( strcmp((char *)"KMD",coin.c_str()) != 0 )
{
fprintf(stderr,"only KMD supported for now\n");
return("");
}
taddr = 0;
prefix = 60;
prefix2 = 85;
if ( pubkeys.size() != N ) if ( pubkeys.size() != N )
{ {
fprintf(stderr,"M.%d N.%d but pubkeys[%d]\n",M,N,(int32_t)pubkeys.size()); fprintf(stderr,"M.%d N.%d but pubkeys[%d]\n",M,N,(int32_t)pubkeys.size());
@@ -464,7 +491,7 @@ std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t
txfee = 10000; txfee = 10000;
mypk = pubkey2pk(Mypubkey()); mypk = pubkey2pk(Mypubkey());
gatewayspk = GetUnspendable(cp,0); gatewayspk = GetUnspendable(cp,0);
if ( _GetCCaddress(destaddr,EVAL_ASSETS,gatewayspk) == 0 ) if ( _GetCCaddress(destaddr,EVAL_GATEWAYS,gatewayspk) == 0 )
{ {
fprintf(stderr,"Gateway bind.%s (%s) cant create globaladdr\n",coin.c_str(),uint256_str(str,tokenid)); fprintf(stderr,"Gateway bind.%s (%s) cant create globaladdr\n",coin.c_str(),uint256_str(str,tokenid));
return(""); return("");
@@ -671,18 +698,12 @@ std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std::
std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,uint256 deposittxid,CPubKey destpub,int64_t amount) std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,uint256 deposittxid,CPubKey destpub,int64_t amount)
{ {
CMutableTransaction mtx; CTransaction tx; CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C,*assetscp,C2; uint8_t M,N,taddr,prefix,prefix2,mypriv[32]; std::string coin; std::vector<CPubKey> msigpubkeys; int64_t totalsupply,depositamount,inputs,CCchange=0; int32_t numvouts; uint256 hashBlock,assetid,oracletxid; char str[65],depositaddr[64],coinaddr[64]; CMutableTransaction mtx; CTransaction tx; CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C; uint8_t M,N,taddr,prefix,prefix2; std::string coin; std::vector<CPubKey> msigpubkeys; int64_t totalsupply,depositamount,inputs,CCchange=0; int32_t numvouts; uint256 hashBlock,assetid,oracletxid; char str[65],depositaddr[64],coinaddr[64];
cp = CCinit(&C,EVAL_GATEWAYS); cp = CCinit(&C,EVAL_GATEWAYS);
assetscp = CCinit(&C2,EVAL_ASSETS);
if ( txfee == 0 ) if ( txfee == 0 )
txfee = 10000; txfee = 10000;
mypk = pubkey2pk(Mypubkey()); mypk = pubkey2pk(Mypubkey());
gatewayspk = GetUnspendable(cp,0); gatewayspk = GetUnspendable(cp,0);
_GetCCaddress(coinaddr,EVAL_ASSETS,gatewayspk);
CCaddr2set(assetscp,EVAL_ASSETS,gatewayspk,cp->CCpriv,coinaddr);
Myprivkey(mypriv);
_GetCCaddress(coinaddr,EVAL_GATEWAYS,mypk);
CCaddr3set(assetscp,EVAL_GATEWAYS,mypk,mypriv,coinaddr);
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 ) if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
{ {
fprintf(stderr,"cant find bindtxid %s\n",uint256_str(str,bindtxid)); fprintf(stderr,"cant find bindtxid %s\n",uint256_str(str,bindtxid));
@@ -706,15 +727,15 @@ std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,ui
//fprintf(stderr,"depositaddr.(%s) vs %s\n",depositaddr,cp->unspendableaddr2); //fprintf(stderr,"depositaddr.(%s) vs %s\n",depositaddr,cp->unspendableaddr2);
if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 ) if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
{ {
if ( (inputs= AddAssetInputs(assetscp,mtx,gatewayspk,assetid,amount,60)) > 0 ) if ( (inputs= AddGatewaysInputs(cp,mtx,gatewayspk,assetid,amount,60)) > 0 )
{ {
if ( inputs > amount ) if ( inputs > amount )
CCchange = (inputs - amount); CCchange = (inputs - amount);
mtx.vin.push_back(CTxIn(deposittxid,0,CScript())); // triggers EVAL_GATEWAYS validation mtx.vin.push_back(CTxIn(deposittxid,0,CScript())); // triggers EVAL_GATEWAYS validation
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,amount,mypk)); mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,amount,mypk)); // transfer back to normal token
if ( CCchange != 0 ) if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,gatewayspk)); mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,CCchange,gatewayspk));
return(FinalizeCCTx(0,assetscp,mtx,mypk,txfee,EncodeAssetOpRet('t',assetid,zeroid,0,Mypubkey()))); return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetOpRet('t',assetid,zeroid,0,Mypubkey())));
} }
} }
fprintf(stderr,"cant find enough inputs or mismatched total\n"); fprintf(stderr,"cant find enough inputs or mismatched total\n");
@@ -723,18 +744,12 @@ std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,ui
std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,std::vector<uint8_t> withdrawpub,int64_t amount) std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,std::vector<uint8_t> withdrawpub,int64_t amount)
{ {
CMutableTransaction mtx; CTransaction tx; CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C,*assetscp,C2; uint256 assetid,hashBlock,oracletxid; int32_t numvouts; int64_t totalsupply,inputs,CCchange=0; uint8_t M,N,taddr,prefix,prefix2,mypriv[32]; std::string coin; std::vector<CPubKey> msigpubkeys; char depositaddr[64],str[65],coinaddr[64]; CMutableTransaction mtx; CTransaction tx; CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C; uint256 assetid,hashBlock,oracletxid; int32_t numvouts; int64_t totalsupply,inputs,CCchange=0; uint8_t M,N,taddr,prefix,prefix2; std::string coin; std::vector<CPubKey> msigpubkeys; char depositaddr[64],str[65],coinaddr[64];
cp = CCinit(&C,EVAL_GATEWAYS); cp = CCinit(&C,EVAL_GATEWAYS);
assetscp = CCinit(&C2,EVAL_ASSETS);
if ( txfee == 0 ) if ( txfee == 0 )
txfee = 10000; txfee = 10000;
mypk = pubkey2pk(Mypubkey()); mypk = pubkey2pk(Mypubkey());
gatewayspk = GetUnspendable(cp,0); gatewayspk = GetUnspendable(cp,0);
_GetCCaddress(coinaddr,EVAL_ASSETS,gatewayspk);
CCaddr2set(assetscp,EVAL_ASSETS,gatewayspk,cp->CCpriv,coinaddr);
Myprivkey(mypriv);
_GetCCaddress(coinaddr,EVAL_GATEWAYS,mypk);
CCaddr3set(assetscp,EVAL_GATEWAYS,mypk,mypriv,coinaddr);
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 ) if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
{ {
fprintf(stderr,"cant find bindtxid %s\n",uint256_str(str,bindtxid)); fprintf(stderr,"cant find bindtxid %s\n",uint256_str(str,bindtxid));
@@ -747,16 +762,16 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin
} }
if ( AddNormalinputs(mtx,mypk,3*txfee,3) > 0 ) if ( AddNormalinputs(mtx,mypk,3*txfee,3) > 0 )
{ {
if ( (inputs= AddAssetInputs(assetscp,mtx,mypk,assetid,amount,60)) > 0 ) if ( (inputs= AddGatewaysInputs(cp,mtx,mypk,assetid,amount,60)) > 0 )
{ {
if ( inputs > amount ) if ( inputs > amount )
CCchange = (inputs - amount); CCchange = (inputs - amount);
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,amount,gatewayspk)); mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,amount,gatewayspk));
mtx.vout.push_back(CTxOut(txfee,CScript() << withdrawpub << OP_CHECKSIG)); mtx.vout.push_back(CTxOut(txfee,CScript() << withdrawpub << OP_CHECKSIG));
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(gatewayspk)) << OP_CHECKSIG)); mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(gatewayspk)) << OP_CHECKSIG));
if ( CCchange != 0 ) if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,mypk)); mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,CCchange,mypk));
return(FinalizeCCTx(0,assetscp,mtx,mypk,txfee,EncodeAssetOpRet('t',assetid,zeroid,0,Mypubkey()))); return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetOpRet('t',assetid,zeroid,0,Mypubkey())));
} }
} }
fprintf(stderr,"cant find enough inputs or mismatched total\n"); fprintf(stderr,"cant find enough inputs or mismatched total\n");
@@ -783,7 +798,7 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
cp = CCinit(&C,EVAL_GATEWAYS); cp = CCinit(&C,EVAL_GATEWAYS);
mypk = pubkey2pk(Mypubkey()); mypk = pubkey2pk(Mypubkey());
gatewayspk = GetUnspendable(cp,0); gatewayspk = GetUnspendable(cp,0);
_GetCCaddress(coinaddr,EVAL_ASSETS,gatewayspk); _GetCCaddress(coinaddr,EVAL_GATEWAYS,gatewayspk);
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 ) if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
{ {
fprintf(stderr,"cant find bindtxid %s\n",uint256_str(str,bindtxid)); fprintf(stderr,"cant find bindtxid %s\n",uint256_str(str,bindtxid));
@@ -846,7 +861,7 @@ std::string GatewaysMultisig(uint64_t txfee,std::string refcoin,uint256 bindtxid
complete = partialtx = 0; complete = partialtx = 0;
mypk = pubkey2pk(Mypubkey()); mypk = pubkey2pk(Mypubkey());
Gatewayspk = GetUnspendable(cp,0); Gatewayspk = GetUnspendable(cp,0);
_GetCCaddress(gatewaysassets,EVAL_ASSETS,Gatewayspk); _GetCCaddress(gatewaysassets,EVAL_GATEWAYS,Gatewayspk);
if ( GetTransaction(bindtxid,tx,hashBlock,false) != 0 ) if ( GetTransaction(bindtxid,tx,hashBlock,false) != 0 )
{ {
depositaddr[0] = 0; depositaddr[0] = 0;

View File

@@ -28,7 +28,9 @@
Funds work like with dice, ie. there is a Prices plan that traders bet against. Funds work like with dice, ie. there is a Prices plan that traders bet against.
PricesOpen -> oracletxid start with 'L' price, leverage, amount PricesFunding oracletxid, margin, priceaveraging, maxleverage, funding, longtoken, shorttoken, N [pubkeys]
PricesBet -> oracletxid start with 'L', leverage, funding, direction
funds are locked into global CC address funds are locked into global CC address
it can be closed at anytime by the trader for cash settlement it can be closed at anytime by the trader for cash settlement
the house account can close it if rekt the house account can close it if rekt
@@ -36,59 +38,50 @@
Implementation Notes: Implementation Notes:
In order to eliminate the need for worrying about sybil attacks, each prices plan would be able to specific pubkey(s?) for whitelisted publishers. It would be possible to have a non-whitelisted plan that would use 50% correlation between publishers. In order to eliminate the need for worrying about sybil attacks, each prices plan would be able to specific pubkey(s?) for whitelisted publishers. It would be possible to have a non-whitelisted plan that would use 50% correlation between publishers.
delta neutral balancing of risk exposure delta neutral balancing of riskexposure: fabs(long exposure - short exposure)
bet +B at leverage L
absval(sum(+BLi) - sum(-Bli))
validate: update riskexposure and it needs to be <= funds
PricesProfits: limit withdraw to funds in excess of riskexposure
PricesFinish: payout (if winning) and update riskexposure
need long/short exposure assets
funding -> 1of2 CC global CC address and dealer address, exposure tokens to global 1of2 assets CC address
pricebet -> user funds and exposure token to 1of2 address.
pricewin -> winnings from dealer funds, exposure token back to global address
priceloss -> exposuretoken back to global address
exposure address, funds address
*/ */
// start of consensus code // start of consensus code
int64_t IsPricesvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v) int64_t PricesOraclePrice(int64_t &rektprice,uint64_t mode,uint256 oracletxid,std::vector<CPubKey>pubkeys,int32_t dir,int64_t amount,int32_t leverage)
{ {
char destaddr[64]; int64_t price;
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) // howto ensure price when block it confirms it not known
{ // get price from oracle + current chaintip
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 ) // normalize leveraged amount
return(tx.vout[v].nValue); if ( dir > 0 )
} rektprice = price * leverage / (leverage-1);
return(0); else rektprice = price * (leverage-1) / leverage;
return(price);
} }
bool PricesExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee) CScript EncodePricesFundingOpRet(uint8_t funcid,CPubKey planpk,uint256 oracletxid,uint256 longtoken,uint256 shorttoken,int32_t millimargin,uint64_t mode,int32_t maxleverage,std::vector<CPubKey> pubkeys,uint256 bettoken)
{ {
static uint256 zerohash; CScript opret;
CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis; fprintf(stderr,"implement EncodePricesFundingOpRet\n");
numvins = tx.vin.size(); return(opret);
numvouts = tx.vout.size();
for (i=0; i<numvins; i++)
{
//fprintf(stderr,"vini.%d\n",i);
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) != 0 )
{
//fprintf(stderr,"vini.%d check mempool\n",i);
if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 )
return eval->Invalid("cant find vinTx");
else
{
//fprintf(stderr,"vini.%d check hash and vout\n",i);
if ( hashBlock == zerohash )
return eval->Invalid("cant Prices from mempool");
if ( (assetoshis= IsPricesvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
inputs += assetoshis;
} }
}
} uint8_t DecodePricesFundingOpRet(CScript scriptPubKey,CPubKey &planpk,uint256 &oracletxid,uint256 &longtoken,uint256 &shorttoken,int32_t &millimargin,uint64_t &mode,int32_t &maxleverage,std::vector<CPubKey> &pubkeys,uint256 &bettoken)
for (i=0; i<numvouts; i++)
{ {
//fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts); fprintf(stderr,"implement DecodePricesFundingOpRet\n");
if ( (assetoshis= IsPricesvout(cp,tx,i)) != 0 ) return(0);
outputs += assetoshis;
}
if ( inputs != outputs+txfee )
{
fprintf(stderr,"inputs %llu vs outputs %llu\n",(long long)inputs,(long long)outputs);
return eval->Invalid("mismatched inputs != outputs + txfee");
}
else return(true);
} }
bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx) bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
@@ -111,12 +104,12 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
} }
} }
//fprintf(stderr,"check amounts\n"); //fprintf(stderr,"check amounts\n");
if ( PricesExactAmounts(cp,eval,tx,1,10000) == false ) //if ( PricesExactAmounts(cp,eval,tx,1,10000) == false )
{ {
fprintf(stderr,"Pricesget invalid amount\n"); fprintf(stderr,"Pricesget invalid amount\n");
return false; return false;
} }
else //else
{ {
txid = tx.GetHash(); txid = tx.GetHash();
memcpy(hash,&txid,sizeof(hash)); memcpy(hash,&txid,sizeof(hash));
@@ -132,20 +125,20 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
// helper functions for rpc calls in rpcwallet.cpp // helper functions for rpc calls in rpcwallet.cpp
int64_t AddPricesInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs) int64_t AddTokensInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,char *destaddr,uint256 tolenid,int64_t total,int32_t maxinputs)
{ {
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk); SetCCunspents(unspentOutputs,destaddr);
SetCCunspents(unspentOutputs,coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{ {
txid = it->first.txhash; txid = it->first.txhash;
vout = (int32_t)it->first.index; vout = (int32_t)it->first.index;
// no need to prevent dup // need to prevent dup
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) if ( GetTransaction(txid,vintx,hashBlock,false) != 0 && vout < vintx.vout.size() )
{ {
if ( (nValue= IsPricesvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 ) // need to verify assetid
if ( (nValue= vintx.vout[vout].nValue) > 10000 && 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()));
@@ -160,49 +153,18 @@ int64_t AddPricesInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub
return(totalinputs); return(totalinputs);
} }
#ifdef later
UniValue PricesInfo(uint256 pricesid)
{
UniValue result(UniValue::VOBJ); CPubKey pricepk; uint256 hashBlock,oracletxid; CTransaction vintx; int64_t minbet,maxbet,maxodds; uint64_t funding; char numstr[65]; struct CCcontract_info *cp,C;
if ( GetTransaction(pricesid,vintx,hashBlock,false) == 0 )
{
fprintf(stderr,"cant find fundingtxid\n");
ERR_RESULT("cant find fundingtxid");
return(result);
}
if ( vintx.vout.size() > 0 && DecodePricesFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,oracletxid,minbet,maxbet,maxodds) == 0 )
{
fprintf(stderr,"fundingtxid isnt price creation txid\n");
ERR_RESULT("fundingtxid isnt price creation txid");
return(result);
}
result.push_back(Pair("result","success"));
result.push_back(Pair("pricesid",uint256_str(str,pricesid)));
result.push_back(Pair("oracletxid",uint256_str(str,oracletxid)));
sprintf(numstr,"%.8f",(double)minbet/COIN);
result.push_back(Pair("minbet",numstr));
sprintf(numstr,"%.8f",(double)maxbet/COIN);
result.push_back(Pair("maxbet",numstr));
result.push_back(Pair("maxodds",maxodds));
cp = CCinit(&C,EVAL_PRICES);
pricepk = GetUnspendable(cp,0);
funding = PricePlanFunds(cp,pricepk,pricesid);
sprintf(numstr,"%.8f",(double)funding/COIN);
result.push_back(Pair("funding",numstr));
return(result);
}
UniValue PricesList() UniValue PricesList()
{ {
UniValue result(UniValue::VARR); std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex; struct CCcontract_info *cp,C; uint256 txid,hashBlock,oracletxid; CTransaction vintx; int64_t minbet,maxbet,maxodds; char str[65]; UniValue result(UniValue::VARR); std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex; struct CCcontract_info *cp,C; uint64_t mode; int32_t margin,maxleverage; std::vector<CPubKey>pubkeys; uint256 txid,hashBlock,oracletxid,longtoken,shorttoken,bettoken; CPubKey planpk,pricespk; char str[65]; CTransaction vintx;
cp = CCinit(&C,EVAL_PRICES); cp = CCinit(&C,EVAL_PRICES);
pricespk = GetUnspendable(cp,0);
SetCCtxids(addressIndex,cp->normaladdr); SetCCtxids(addressIndex,cp->normaladdr);
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++)
{ {
txid = it->first.txhash; txid = it->first.txhash;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{ {
if ( vintx.vout.size() > 0 && DecodePricesFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,oracletxid,minbet,maxbet,maxodds) != 0 ) if ( vintx.vout.size() > 0 && DecodePricesFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,planpk,oracletxid,longtoken,shorttoken,margin,mode,maxleverage,pubkeys,bettoken) == 'F' )
{ {
result.push_back(uint256_str(str,txid)); result.push_back(uint256_str(str,txid));
} }
@@ -211,59 +173,164 @@ UniValue PricesList()
return(result); return(result);
} }
std::string PricesCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t timeoutblocks) // longtoken satoshis limits long exposure
// shorttoken satoshis limits short exposure
// both must be in the 1of2 CC address with its total supply
// bettoken
std::string PricesCreateFunding(uint64_t txfee,uint256 bettoken,uint256 oracletxid,uint64_t margin,uint64_t mode,uint256 longtoken,uint256 shorttoken,int32_t maxleverage,int64_t funding,std::vector<CPubKey> pubkeys)
{ {
CMutableTransaction mtx; uint256 zero; CScript fundingPubKey; CPubKey mypk,pricepk; int64_t a,b,c,d; uint64_t sbits; struct CCcontract_info *cp,C; CMutableTransaction mtx; CTransaction oracletx; int64_t fullsupply,inputs,CCchange=0; uint256 hashBlock; char str[65],coinaddr[64],houseaddr[64]; CPubKey mypk,pricespk; int32_t i,N,numvouts; struct CCcontract_info *cp,C,*assetscp,C2;
if ( funds < 0 || minbet < 0 || maxbet < 0 || maxodds < 1 || maxodds > 9999 || timeoutblocks < 0 || timeoutblocks > 1440 ) if ( funding < 100*COIN || maxleverage <= 0 || maxleverage > 10000 )
{ {
CCerror = "invalid parameter error"; CCerror = "invalid parameter error";
fprintf(stderr,"%s\n", CCerror.c_str() ); fprintf(stderr,"%s\n", CCerror.c_str() );
return(""); return("");
} }
if ( funds < 100*COIN ) cp = CCinit(&C,EVAL_PRICES);
assetscp = CCinit(&C2,EVAL_ASSETS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
pricespk = GetUnspendable(cp,0);
if ( (N= (int32_t)pubkeys.size()) || N > 15 )
{ {
CCerror = "price plan needs at least 100 coins"; fprintf(stderr,"too many pubkeys N.%d\n",N);
fprintf(stderr,"%s\n", CCerror.c_str() );
return(""); return("");
} }
memset(&zero,0,sizeof(zero)); for (i=0; i<N; i++)
if ( (cp= Pricesinit(fundingPubKey,zero,&C,planstr,txfee,mypk,pricepk,sbits,a,b,c,d)) == 0 )
{ {
CCerror = "Priceinit error in create funding"; Getscriptaddress(coinaddr,CScript() << ParseHex(HexStr(pubkeys[i])) << OP_CHECKSIG);
fprintf(stderr,"%s\n", CCerror.c_str() ); if ( CCaddress_balance(coinaddr) == 0 )
{
fprintf(stderr,"N.%d but pubkeys[%d] has no balance\n",N,i);
return(""); return("");
} }
if ( AddNormalinputs(mtx,mypk,funds+3*txfee,60) > 0 ) }
if ( GetCCaddress1of2(cp,houseaddr,pricespk,mypk) == 0 )
{
fprintf(stderr,"PricesCreateFunding cant create globaladdr\n");
return("");
}
if ( CCtoken_balance(houseaddr,longtoken) != CCfullsupply(longtoken) )
{
fprintf(stderr,"PricesCreateFunding (%s) globaladdr.%s token balance %.8f != %.8f\n",uint256_str(str,longtoken),houseaddr,(double)CCtoken_balance(houseaddr,longtoken)/COIN,(double)CCfullsupply(longtoken)/COIN);
return("");
}
if ( CCtoken_balance(houseaddr,shorttoken) != CCfullsupply(shorttoken) )
{
fprintf(stderr,"PricesCreateFunding (%s) globaladdr.%s token balance %.8f != %.8f\n",uint256_str(str,longtoken),houseaddr,(double)CCtoken_balance(houseaddr,longtoken)/COIN,(double)CCfullsupply(shorttoken)/COIN);
return("");
}
if ( GetTransaction(oracletxid,oracletx,hashBlock,false) == 0 || (numvouts= oracletx.vout.size()) <= 0 )
{
fprintf(stderr,"cant find oracletxid %s\n",uint256_str(str,oracletxid));
return("");
}
fprintf(stderr,"error check bettoken\n");
if ( AddNormalinputs(mtx,mypk,3*txfee,3) > 0 )
{ {
mtx.vout.push_back(MakeCC1vout(cp->evalcode,funds,pricepk));
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(pricepk)) << OP_CHECKSIG)); mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodePricesFundingOpRet('F',sbits,minbet,maxbet,maxodds,timeoutblocks))); return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodePricesFundingOpRet('F',mypk,oracletxid,longtoken,shorttoken,margin,mode,maxleverage,pubkeys,bettoken)));
} }
else
{
CCerror = "cant find enough inputs"; CCerror = "cant find enough inputs";
fprintf(stderr,"%s\n", CCerror.c_str() ); fprintf(stderr,"%s\n", CCerror.c_str() );
}
return(""); return("");
} }
std::string PricesAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount) UniValue PricesInfo(uint256 fundingtxid)
{ {
CMutableTransaction mtx; CScript fundingPubKey,scriptPubKey; CPubKey mypk,pricepk; struct CCcontract_info *cp,C; int64_t minbet,maxbet,maxodds; UniValue result(UniValue::VOBJ),a(UniValue::VARR); CPubKey pricespk,planpk; uint256 hashBlock,oracletxid,longtoken,shorttoken,bettoken; CTransaction vintx; int64_t balance,supply,exposure; uint64_t funding,mode; int32_t i,margin,maxleverage; char numstr[65],houseaddr[64],exposureaddr[64],str[65]; std::vector<CPubKey>pubkeys; struct CCcontract_info *cp,C,*assetscp,C2;
if ( amount < 0 ) cp = CCinit(&C,EVAL_PRICES);
assetscp = CCinit(&C2,EVAL_ASSETS);
pricespk = GetUnspendable(cp,0);
if ( GetTransaction(fundingtxid,vintx,hashBlock,false) == 0 )
{
fprintf(stderr,"cant find fundingtxid\n");
ERR_RESULT("cant find fundingtxid");
return(result);
}
if ( vintx.vout.size() > 0 && DecodePricesFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,planpk,oracletxid,longtoken,shorttoken,margin,mode,maxleverage,pubkeys,bettoken) == 'F' )
{
result.push_back(Pair("result","success"));
result.push_back(Pair("fundingtxid",uint256_str(str,fundingtxid)));
result.push_back(Pair("bettoken",uint256_str(str,bettoken)));
result.push_back(Pair("oracletxid",uint256_str(str,oracletxid)));
sprintf(numstr,"%.3f",(double)margin/1000);
result.push_back(Pair("profitmargin",numstr));
result.push_back(Pair("maxleverage",maxleverage));
result.push_back(Pair("mode",(int64_t)mode));
for (i=0; i<pubkeys.size(); i++)
a.push_back(pubkey33_str(str,(uint8_t *)&pubkeys[i]));
result.push_back(Pair("pubkeys",a));
GetCCaddress1of2(assetscp,houseaddr,pricespk,planpk);
GetCCaddress1of2(assetscp,exposureaddr,pricespk,pricespk); // assets addr
result.push_back(Pair("houseaddr",houseaddr));
result.push_back(Pair("betaddr",exposureaddr));
result.push_back(Pair("longtoken",uint256_str(str,longtoken)));
supply = CCfullsupply(longtoken);
result.push_back(Pair("longsupply",supply));
balance = CCtoken_balance(houseaddr,longtoken);
result.push_back(Pair("longavail",balance));
exposure = CCtoken_balance(exposureaddr,longtoken);
result.push_back(Pair("longexposure",exposure));
result.push_back(Pair("shorttoken",uint256_str(str,shorttoken)));
supply = CCfullsupply(shorttoken);
result.push_back(Pair("shortsupply",supply));
balance = CCtoken_balance(houseaddr,shorttoken);
result.push_back(Pair("shortavail",balance));
exposure = CCtoken_balance(exposureaddr,shorttoken);
result.push_back(Pair("shortexposure",exposure));
sprintf(numstr,"%.8f",(double)CCtoken_balance(houseaddr,bettoken)/COIN);
result.push_back(Pair("funds",numstr));
}
return(result);
}
std::string PricesAddFunding(uint64_t txfee,uint256 refbettoken,uint256 fundingtxid,int64_t amount)
{
CMutableTransaction mtx; struct CCcontract_info *cp,C,*assetscp,C2; CPubKey pricespk,planpk,mypk; uint256 hashBlock,oracletxid,longtoken,shorttoken,bettoken; CTransaction tx; int64_t balance,supply,exposure,inputs,CCchange = 0; uint64_t funding,mode; int32_t margin,maxleverage; char houseaddr[64],myaddr[64]; std::vector<CPubKey>pubkeys;
if ( amount < 10000 )
{ {
CCerror = "amount must be positive"; CCerror = "amount must be positive";
fprintf(stderr,"%s\n", CCerror.c_str() ); fprintf(stderr,"%s\n", CCerror.c_str() );
return(""); return("");
} }
if ( (cp= Pricesinit(fundingPubKey,fundingtxid,&C,planstr,txfee,mypk,pricepk,sbits,minbet,maxbet,maxodds,timeoutblocks)) == 0 ) cp = CCinit(&C,EVAL_PRICES);
assetscp = CCinit(&C2,EVAL_ASSETS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
pricespk = GetUnspendable(cp,0);
GetCCaddress(assetscp,myaddr,mypk);
if ( GetTransaction(fundingtxid,tx,hashBlock,false) == 0 )
{
fprintf(stderr,"cant find fundingtxid\n");
return(""); return("");
scriptPubKey = CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG; }
if ( scriptPubKey == fundingPubKey ) if ( tx.vout.size() > 0 && DecodePricesFundingOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,planpk,oracletxid,longtoken,shorttoken,margin,mode,maxleverage,pubkeys,bettoken) == 'F' && bettoken == refbettoken )
{ {
if ( AddNormalinputs(mtx,mypk,amount+2*txfee,60) > 0 ) GetCCaddress1of2(assetscp,houseaddr,pricespk,planpk);
if ( AddNormalinputs(mtx,mypk,2*txfee,3) > 0 )
{ {
mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,pricepk)); if ( (inputs= AddTokensInputs(assetscp,mtx,myaddr,bettoken,amount,60)) >= amount )
mtx.vout.push_back(CTxOut(txfee,fundingPubKey)); {
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodePricesOpRet('E',sbits,fundingtxid,hentropy,zeroid))); mtx.vout.push_back(MakeCC1of2vout(assetscp->evalcode,amount,pricespk,planpk));
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(planpk)) << OP_CHECKSIG));
if ( inputs > amount+txfee )
CCchange = (inputs - amount);
mtx.vout.push_back(MakeCC1vout(assetscp->evalcode,CCchange,mypk));
// add addr2
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetOpRet('t',bettoken,zeroid,0,Mypubkey())));
}
else
{
CCerror = "cant find enough bet inputs";
fprintf(stderr,"%s\n", CCerror.c_str() );
}
} }
else else
{ {
@@ -271,66 +338,107 @@ std::string PricesAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,in
fprintf(stderr,"%s\n", CCerror.c_str() ); fprintf(stderr,"%s\n", CCerror.c_str() );
} }
} }
return("");
}
std::string PricesBet(uint64_t txfee,uint256 refbettoken,uint256 fundingtxid,int64_t amount,int32_t leverage)
{
CMutableTransaction mtx; struct CCcontract_info *cp,C,*assetscp,C2; CPubKey pricespk,planpk,mypk; uint256 hashBlock,oracletxid,longtoken,shorttoken,tokenid,bettoken; CTransaction tx; int64_t balance,supply,exposure,inputs,inputs2,longexposure,netexposure,shortexposure,CCchange = 0,CCchange2 = 0; uint64_t funding,mode; int32_t dir,margin,maxleverage; char houseaddr[64],myaddr[64],exposureaddr[64]; std::vector<CPubKey>pubkeys;
if ( amount < 0 )
{
amount = -amount;
dir = -1;
} else dir = 1;
cp = CCinit(&C,EVAL_PRICES);
assetscp = CCinit(&C2,EVAL_ASSETS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
pricespk = GetUnspendable(cp,0);
GetCCaddress(assetscp,myaddr,mypk);
if ( GetTransaction(fundingtxid,tx,hashBlock,false) == 0 )
{
fprintf(stderr,"cant find fundingtxid\n");
return("");
}
if ( tx.vout.size() > 0 && DecodePricesFundingOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,planpk,oracletxid,longtoken,shorttoken,margin,mode,maxleverage,pubkeys,bettoken) == 'F' && bettoken == refbettoken )
{
if ( leverage > maxleverage || leverage < 1 )
{
fprintf(stderr,"illegal leverage\n");
return("");
}
GetCCaddress1of2(assetscp,houseaddr,pricespk,planpk);
GetCCaddress1of2(assetscp,exposureaddr,pricespk,pricespk);
if ( dir < 0 )
tokenid = shorttoken;
else tokenid = longtoken;
exposure = leverage * amount;
longexposure = CCtoken_balance(exposureaddr,longtoken);
shortexposure = CCtoken_balance(exposureaddr,shorttoken);
netexposure = (longexposure - shortexposure + exposure*dir);
if ( netexposure < 0 )
netexposure = -netexposure;
balance = CCtoken_balance(myaddr,bettoken) / COIN;
if ( balance < netexposure*9/10 ) // 10% extra room for dynamically closed bets in wrong direction
{
fprintf(stderr,"balance %lld < 90%% netexposure %lld, refuse bet\n",(long long)balance,(long long)netexposure);
return("");
}
if ( AddNormalinputs(mtx,mypk,txfee,3) > 0 )
{
if ( (inputs= AddTokensInputs(assetscp,mtx,houseaddr,tokenid,exposure,30)) >= exposure )
{
if ( (inputs2= AddTokensInputs(assetscp,mtx,myaddr,bettoken,amount,30)) >= amount )
{
mtx.vout.push_back(MakeCC1of2vout(assetscp->evalcode,amount,pricespk,planpk));
mtx.vout.push_back(MakeCC1of2vout(assetscp->evalcode,exposure,pricespk,pricespk));
if ( inputs > exposure+txfee )
CCchange = (inputs - exposure);
if ( inputs2 > amount+txfee )
CCchange2 = (inputs2 - amount);
mtx.vout.push_back(MakeCC1of2vout(assetscp->evalcode,CCchange,pricespk,planpk));
mtx.vout.push_back(MakeCC1vout(assetscp->evalcode,CCchange2,mypk));
// add addr2 and addr3
//return(FinalizeCCTx(0,assetscp,mtx,mypk,txfee,EncodePricesExtra('T',tokenid,bettoken,zeroid,dir*leverage)));
CScript opret;
return(FinalizeCCTx(0,assetscp,mtx,mypk,txfee,opret));
}
else else
{ {
CCerror = "only fund creator can add more funds (entropy)"; fprintf(stderr,"cant find enough bettoken inputs\n");
return("");
}
}
else
{
fprintf(stderr,"cant find enough exposure inputs\n");
return("");
}
}
else
{
CCerror = "cant find enough inputsB";
fprintf(stderr,"%s\n", CCerror.c_str() ); fprintf(stderr,"%s\n", CCerror.c_str() );
} }
}
return(""); return("");
} }
std::string PricesBet(uint64_t txfee,uint256 pricesid,int64_t bet,int32_t odds) UniValue PricesStatus(uint64_t txfee,uint256 refbettoken,uint256 fundingtxid,uint256 bettxid)
{ {
CMutableTransaction mtx; CScript fundingPubKey; CPubKey mypk,pricepk; int64_t funding,minbet,maxbet,maxodds; struct CCcontract_info *cp,C; UniValue result(UniValue::VOBJ);
if ( bet < 0 ) // get height of bettxid
{ // get price and rekt
CCerror = "bet must be positive"; // get current height and price
fprintf(stderr,"%s\n", CCerror.c_str() ); // what about if rekt in the past?
return(""); return(result);
} }
if ( odds < 1 || odds > 9999 )
std::string PricesFinish(uint64_t txfee,uint256 refbettoken,uint256 fundingtxid,uint256 bettxid)
{ {
CCerror = "odds must be between 1 and 9999";
fprintf(stderr,"%s\n", CCerror.c_str() );
return("");
}
if ( (cp= Pricesinit(fundingPubKey,pricesid,&C,txfee,mypk,pricepk,minbet,maxbet,maxodds)) == 0 )
return("");
if ( bet < minbet || bet > maxbet || odds > maxodds )
{
CCerror = strprintf("Price plan %s illegal bet %.8f: minbet %.8f maxbet %.8f or odds %d vs max.%d\n",planstr,(double)bet/COIN,(double)minbet/COIN,(double)maxbet/COIN,(int32_t)odds,(int32_t)maxodds);
fprintf(stderr,"%s\n", CCerror.c_str() );
return("");
}
if ( (funding= PricesPlanFunds(cp,pricepk,pricesid)) >= 2*bet*odds+txfee )
{
if ( myIsutxo_spentinmempool(entropytxid,0) != 0 )
{
CCerror = "entropy txid is spent";
fprintf(stderr,"%s\n", CCerror.c_str() );
return("");
}
if ( AddNormalinputs(mtx,mypk,bet+2*txfee+odds,60) > 0 )
{
mtx.vout.push_back(MakeCC1vout(cp->evalcode,entropyval,pricepk));
mtx.vout.push_back(MakeCC1vout(cp->evalcode,bet,pricepk));
mtx.vout.push_back(CTxOut(txfee+odds,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodePricesOpRet('B',pricesid)));
} else fprintf(stderr,"cant find enough normal inputs for %.8f, plan funding %.8f\n",(double)bet/COIN,(double)funding/COIN);
}
if ( entropyval == 0 && funding != 0 )
CCerror = "cant find price entropy inputs";
else CCerror = "cant find price input";
fprintf(stderr,"%s\n", CCerror.c_str() );
return(""); return("");
} }
std::string PricesBetFinish(int32_t *resultp,uint64_t txfee,uint256 pricesid,uint256 bettxid)
{
*resultp = -1;
CCerror = "couldnt find bettx or entropytx";
fprintf(stderr,"%s\n", CCerror.c_str() );
return("");
}
#endif

View File

@@ -198,6 +198,21 @@ const char *Notaries_elected1[][2] =
{"xrobesx_NA", "03f0cc6d142d14a40937f12dbd99dbd9021328f45759e26f1877f2a838876709e1" }, {"xrobesx_NA", "03f0cc6d142d14a40937f12dbd99dbd9021328f45759e26f1877f2a838876709e1" },
}; };
int32_t komodo_isnotaryvout(uint8_t *script) // from ac_private chains only
{
uint8_t pubkey33[33]; int32_t i;
if ( script[0] == 33 && script[34] == 0xac )
{
for (i=0; i<sizeof(Notaries_elected1)/sizeof(*Notaries_elected1); i++)
{
decode_hex(pubkey33,33,(char *)Notaries_elected1[i][1]);
if ( memcmp(script+1,pubkey33,33) == 0 )
return(1);
}
}
return(0);
}
int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp) int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp)
{ {
static uint8_t elected_pubkeys0[64][33],elected_pubkeys1[64][33],did0,did1; static int32_t n0,n1; static uint8_t elected_pubkeys0[64][33],elected_pubkeys1[64][33],did0,did1; static int32_t n0,n1;

View File

@@ -1628,6 +1628,11 @@ void komodo_args(char *argv0)
{ {
int32_t komodo_baseid(char *origbase); int32_t komodo_baseid(char *origbase);
extern int COINBASE_MATURITY; extern int COINBASE_MATURITY;
if ( strcmp(ASSETCHAINS_SYMBOL,"KMD") == 0 )
{
fprintf(stderr,"cant have assetchain named KMD\n");
exit(0);
}
if ( (port= komodo_userpass(ASSETCHAINS_USERPASS,ASSETCHAINS_SYMBOL)) != 0 ) if ( (port= komodo_userpass(ASSETCHAINS_USERPASS,ASSETCHAINS_SYMBOL)) != 0 )
ASSETCHAINS_RPCPORT = port; ASSETCHAINS_RPCPORT = port;
else komodo_configfile(ASSETCHAINS_SYMBOL,ASSETCHAINS_P2PPORT + 1); else komodo_configfile(ASSETCHAINS_SYMBOL,ASSETCHAINS_P2PPORT + 1);

View File

@@ -60,6 +60,7 @@ extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN,KOMODO_INSYNC,KOMODO_CON
int32_t KOMODO_NEWBLOCKS; int32_t KOMODO_NEWBLOCKS;
int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block); int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block);
void komodo_broadcast(CBlock *pblock,int32_t limit); void komodo_broadcast(CBlock *pblock,int32_t limit);
int32_t komodo_isnotaryvout(CScript scriptPubKey);
BlockMap mapBlockIndex; BlockMap mapBlockIndex;
CChain chainActive; CChain chainActive;
@@ -1119,8 +1120,11 @@ bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidatio
{ {
fprintf(stderr,"private chain nValue %.8f iscoinbase.%d\n",(double)txout.nValue/COIN,iscoinbase); fprintf(stderr,"private chain nValue %.8f iscoinbase.%d\n",(double)txout.nValue/COIN,iscoinbase);
if ( (txout.nValue > 0 && iscoinbase == 0) || tx.GetJoinSplitValueOut() > 0 ) if ( (txout.nValue > 0 && iscoinbase == 0) || tx.GetJoinSplitValueOut() > 0 )
{
if ( txout.scriptPubKey.size() == 35 && komodo_isnotaryvout((uint8_t *)txout.scriptPubKey.data()) == 0 )
return state.DoS(100, error("CheckTransaction(): this is a private chain, no public allowed"),REJECT_INVALID, "bad-txns-acprivacy-chain"); return state.DoS(100, error("CheckTransaction(): this is a private chain, no public allowed"),REJECT_INVALID, "bad-txns-acprivacy-chain");
} }
}
if ( txout.scriptPubKey.size() > IGUANA_MAXSCRIPTSIZE ) if ( txout.scriptPubKey.size() > IGUANA_MAXSCRIPTSIZE )
return state.DoS(100, error("CheckTransaction(): txout.scriptPubKey.size() too big"),REJECT_INVALID, "bad-txns-vout-negative"); return state.DoS(100, error("CheckTransaction(): txout.scriptPubKey.size() too big"),REJECT_INVALID, "bad-txns-vout-negative");
nValueOut += txout.nValue; nValueOut += txout.nValue;

View File

@@ -1377,6 +1377,8 @@ struct CompareBlocksByHeight
} }
}; };
#include <pthread.h>
UniValue getchaintips(const UniValue& params, bool fHelp) UniValue getchaintips(const UniValue& params, bool fHelp)
{ {
if (fHelp || params.size() != 0) if (fHelp || params.size() != 0)
@@ -1415,17 +1417,33 @@ UniValue getchaintips(const UniValue& params, bool fHelp)
/* Build up a list of chain tips. We start with the list of all /* Build up a list of chain tips. We start with the list of all
known blocks, and successively remove blocks that appear as pprev known blocks, and successively remove blocks that appear as pprev
of another block. */ of another block. */
/*static pthread_mutex_t mutex; static int32_t didinit;
if ( didinit == 0 )
{
pthread_mutex_init(&mutex,NULL);
didinit = 1;
}
pthread_mutex_lock(&mutex);*/
std::set<const CBlockIndex*, CompareBlocksByHeight> setTips; std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
int32_t n = 0;
BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex) BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
{
n++;
setTips.insert(item.second); setTips.insert(item.second);
}
fprintf(stderr,"iterations getchaintips %d\n",n);
n = 0;
BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex) BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
{ {
const CBlockIndex* pprev=0; const CBlockIndex* pprev=0;
n++;
if ( item.second != 0 ) if ( item.second != 0 )
pprev = item.second->pprev; pprev = item.second->pprev;
if (pprev) if (pprev)
setTips.erase(pprev); setTips.erase(pprev);
} }
fprintf(stderr,"iterations getchaintips %d\n",n);
//pthread_mutex_unlock(&mutex);
// Always report the currently active tip. // Always report the currently active tip.
setTips.insert(chainActive.LastTip()); setTips.insert(chainActive.LastTip());

View File

@@ -399,6 +399,13 @@ static const CRPCCommand vRPCCommands[] =
/* Prices */ /* Prices */
{ "prices", "pricesaddress", &pricesaddress, true }, { "prices", "pricesaddress", &pricesaddress, true },
{ "prices", "priceslist", &priceslist, true },
{ "prices", "pricesinfo", &pricesinfo, true },
{ "prices", "pricescreate", &pricescreate, true },
{ "prices", "pricesaddfunding", &pricesaddfunding, true },
{ "prices", "pricesbet", &pricesbet, true },
{ "prices", "pricesstatus", &pricesstatus, true },
{ "prices", "pricesfinish", &pricesfinish, true },
/* Pegs */ /* Pegs */
{ "pegs", "pegsaddress", &pegsaddress, true }, { "pegs", "pegsaddress", &pegsaddress, true },
@@ -447,6 +454,7 @@ static const CRPCCommand vRPCCommands[] =
{ "tokens", "tokencancelask", &tokencancelask, true }, { "tokens", "tokencancelask", &tokencancelask, true },
{ "tokens", "tokenfillask", &tokenfillask, true }, { "tokens", "tokenfillask", &tokenfillask, true },
//{ "tokens", "tokenfillswap", &tokenfillswap, true }, //{ "tokens", "tokenfillswap", &tokenfillswap, true },
{ "tokens", "tokenconvert", &tokenconvert, true },
/* Address index */ /* Address index */
{ "addressindex", "getaddressmempool", &getaddressmempool, true }, { "addressindex", "getaddressmempool", &getaddressmempool, true },

View File

@@ -221,6 +221,7 @@ extern UniValue tokenfillbid(const UniValue& params, bool fHelp);
extern UniValue tokenask(const UniValue& params, bool fHelp); extern UniValue tokenask(const UniValue& params, bool fHelp);
extern UniValue tokencancelask(const UniValue& params, bool fHelp); extern UniValue tokencancelask(const UniValue& params, bool fHelp);
extern UniValue tokenfillask(const UniValue& params, bool fHelp); extern UniValue tokenfillask(const UniValue& params, bool fHelp);
extern UniValue tokenconvert(const UniValue& params, bool fHelp);
extern UniValue mofnaddress(const UniValue& params, bool fHelp); extern UniValue mofnaddress(const UniValue& params, bool fHelp);
extern UniValue channelsaddress(const UniValue& params, bool fHelp); extern UniValue channelsaddress(const UniValue& params, bool fHelp);
extern UniValue oraclesaddress(const UniValue& params, bool fHelp); extern UniValue oraclesaddress(const UniValue& params, bool fHelp);
@@ -232,6 +233,13 @@ extern UniValue oraclessubscribe(const UniValue& params, bool fHelp);
extern UniValue oraclesdata(const UniValue& params, bool fHelp); extern UniValue oraclesdata(const UniValue& params, bool fHelp);
extern UniValue oraclessamples(const UniValue& params, bool fHelp); extern UniValue oraclessamples(const UniValue& params, bool fHelp);
extern UniValue pricesaddress(const UniValue& params, bool fHelp); extern UniValue pricesaddress(const UniValue& params, bool fHelp);
extern UniValue priceslist(const UniValue& params, bool fHelp);
extern UniValue pricesinfo(const UniValue& params, bool fHelp);
extern UniValue pricescreate(const UniValue& params, bool fHelp);
extern UniValue pricesaddfunding(const UniValue& params, bool fHelp);
extern UniValue pricesbet(const UniValue& params, bool fHelp);
extern UniValue pricesstatus(const UniValue& params, bool fHelp);
extern UniValue pricesfinish(const UniValue& params, bool fHelp);
extern UniValue pegsaddress(const UniValue& params, bool fHelp); extern UniValue pegsaddress(const UniValue& params, bool fHelp);
extern UniValue triggersaddress(const UniValue& params, bool fHelp); extern UniValue triggersaddress(const UniValue& params, bool fHelp);
extern UniValue paymentsaddress(const UniValue& params, bool fHelp); extern UniValue paymentsaddress(const UniValue& params, bool fHelp);

View File

@@ -4858,6 +4858,7 @@ int32_t ensure_CCrequirements()
#include "../cc/CCchannels.h" #include "../cc/CCchannels.h"
#include "../cc/CCOracles.h" #include "../cc/CCOracles.h"
#include "../cc/CCGateways.h" #include "../cc/CCGateways.h"
#include "../cc/CCPrices.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)
{ {
@@ -4909,6 +4910,15 @@ UniValue channelsaddress(const UniValue& params, bool fHelp)
result.push_back(Pair("otherpubkey", params[0].get_str())); result.push_back(Pair("otherpubkey", params[0].get_str()));
GetCCaddress1of2(cp,destaddr,pk,pk2); GetCCaddress1of2(cp,destaddr,pk,pk2);
result.push_back(Pair("channeladdress",destaddr)); result.push_back(Pair("channeladdress",destaddr));
if ( 0 )
{
int32_t i;
for (i=0; i<100; i++)
{
GetCCaddress1of2(cp,destaddr,pk,pk2);
fprintf(stderr,"i.%d %s\n",i,destaddr);
}
}
return(result); return(result);
} }
@@ -4927,15 +4937,25 @@ UniValue oraclesaddress(const UniValue& params, bool fHelp)
UniValue pricesaddress(const UniValue& params, bool fHelp) UniValue pricesaddress(const UniValue& params, bool fHelp)
{ {
struct CCcontract_info *cp,C; std::vector<unsigned char> pubkey; UniValue result(UniValue::VOBJ); struct CCcontract_info *cp,C,*assetscp,C2; std::vector<unsigned char> pubkey; CPubKey mypk,planpk,pricespk; char myaddr[64],houseaddr[64],exposureaddr[64];
cp = CCinit(&C,EVAL_PRICES); cp = CCinit(&C,EVAL_PRICES);
assetscp = CCinit(&C2,EVAL_PRICES);
if ( fHelp || params.size() > 1 ) if ( fHelp || params.size() > 1 )
throw runtime_error("pricesaddress [pubkey]\n"); throw runtime_error("pricesaddress [pubkey]\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 *)"Prices",pubkey)); result = CCaddress(cp,(char *)"Prices",pubkey);
mypk = pubkey2pk(Mypubkey());
pricespk = GetUnspendable(cp,0);
GetCCaddress(assetscp,myaddr,mypk);
GetCCaddress1of2(assetscp,houseaddr,pricespk,planpk);
GetCCaddress1of2(assetscp,exposureaddr,pricespk,pricespk);
result.push_back(Pair("myaddr",myaddr)); // for holding my asssets
result.push_back(Pair("houseaddr",houseaddr)); // globally accessible house assets
result.push_back(Pair("exposureaddr",exposureaddr)); // tracking of exposure
return(result);
} }
UniValue pegsaddress(const UniValue& params, bool fHelp) UniValue pegsaddress(const UniValue& params, bool fHelp)
@@ -5113,7 +5133,8 @@ UniValue channelsopen(const UniValue& params, bool fHelp)
throw runtime_error("channelsopen destpubkey numpayments payment\n"); throw runtime_error("channelsopen destpubkey numpayments payment\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");
LOCK(cs_main); const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
destpub = ParseHex(params[0].get_str().c_str()); destpub = ParseHex(params[0].get_str().c_str());
numpayments = atoi(params[1].get_str().c_str()); numpayments = atoi(params[1].get_str().c_str());
payment = atol(params[2].get_str().c_str()); payment = atol(params[2].get_str().c_str());
@@ -5134,7 +5155,8 @@ UniValue channelsstop(const UniValue& params, bool fHelp)
throw runtime_error("channelsstop destpubkey origtxid\n"); throw runtime_error("channelsstop destpubkey origtxid\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");
LOCK(cs_main); const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
destpub = ParseHex(params[0].get_str().c_str()); destpub = ParseHex(params[0].get_str().c_str());
origtxid = Parseuint256((char *)params[1].get_str().c_str()); origtxid = Parseuint256((char *)params[1].get_str().c_str());
hex = ChannelStop(0,pubkey2pk(destpub),origtxid); hex = ChannelStop(0,pubkey2pk(destpub),origtxid);
@@ -5154,7 +5176,8 @@ UniValue channelspayment(const UniValue& params, bool fHelp)
throw runtime_error("channelspayment prevtxid origtxid n amount\n"); throw runtime_error("channelspayment prevtxid origtxid n amount\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");
LOCK(cs_main); const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
prevtxid = Parseuint256((char *)params[0].get_str().c_str()); prevtxid = Parseuint256((char *)params[0].get_str().c_str());
origtxid = Parseuint256((char *)params[1].get_str().c_str()); origtxid = Parseuint256((char *)params[1].get_str().c_str());
n = atoi((char *)params[2].get_str().c_str()); n = atoi((char *)params[2].get_str().c_str());
@@ -5176,7 +5199,8 @@ UniValue channelscollect(const UniValue& params, bool fHelp)
throw runtime_error("channelscollect paytxid origtxid n amount\n"); throw runtime_error("channelscollect paytxid origtxid n amount\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");
LOCK(cs_main); const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
paytxid = Parseuint256((char *)params[0].get_str().c_str()); paytxid = Parseuint256((char *)params[0].get_str().c_str());
origtxid = Parseuint256((char *)params[1].get_str().c_str()); origtxid = Parseuint256((char *)params[1].get_str().c_str());
n = atoi((char *)params[2].get_str().c_str()); n = atoi((char *)params[2].get_str().c_str());
@@ -5198,7 +5222,8 @@ UniValue channelsrefund(const UniValue& params, bool fHelp)
throw runtime_error("channelsrefund stoptxid origtxid\n"); throw runtime_error("channelsrefund stoptxid origtxid\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");
LOCK(cs_main); const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
stoptxid = Parseuint256((char *)params[0].get_str().c_str()); stoptxid = Parseuint256((char *)params[0].get_str().c_str());
origtxid = Parseuint256((char *)params[1].get_str().c_str()); origtxid = Parseuint256((char *)params[1].get_str().c_str());
hex = ChannelRefund(0,stoptxid,origtxid); hex = ChannelRefund(0,stoptxid,origtxid);
@@ -5420,6 +5445,8 @@ UniValue gatewaysbind(const UniValue& params, bool fHelp)
throw runtime_error("gatewaysbind tokenid oracletxid coin tokensupply M N pubkey(s)\n"); throw runtime_error("gatewaysbind tokenid oracletxid coin tokensupply M N pubkey(s)\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");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
tokenid = Parseuint256((char *)params[0].get_str().c_str()); tokenid = Parseuint256((char *)params[0].get_str().c_str());
oracletxid = Parseuint256((char *)params[1].get_str().c_str()); oracletxid = Parseuint256((char *)params[1].get_str().c_str());
coin = params[2].get_str(); coin = params[2].get_str();
@@ -5451,6 +5478,8 @@ UniValue gatewaysdeposit(const UniValue& params, bool fHelp)
throw runtime_error("gatewaysdeposit bindtxid height coin cointxid claimvout deposithex proof destpub amount\n"); throw runtime_error("gatewaysdeposit bindtxid height coin cointxid claimvout deposithex proof destpub amount\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");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
bindtxid = Parseuint256((char *)params[0].get_str().c_str()); bindtxid = Parseuint256((char *)params[0].get_str().c_str());
height = atoi((char *)params[1].get_str().c_str()); height = atoi((char *)params[1].get_str().c_str());
coin = params[2].get_str(); coin = params[2].get_str();
@@ -5478,6 +5507,8 @@ UniValue gatewaysclaim(const UniValue& params, bool fHelp)
throw runtime_error("gatewaysclaim bindtxid coin deposittxid destpub amount\n"); throw runtime_error("gatewaysclaim bindtxid coin deposittxid destpub amount\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");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
bindtxid = Parseuint256((char *)params[0].get_str().c_str()); bindtxid = Parseuint256((char *)params[0].get_str().c_str());
coin = params[1].get_str(); coin = params[1].get_str();
deposittxid = Parseuint256((char *)params[2].get_str().c_str()); deposittxid = Parseuint256((char *)params[2].get_str().c_str());
@@ -5499,6 +5530,8 @@ UniValue gatewayswithdraw(const UniValue& params, bool fHelp)
throw runtime_error("gatewayswithdraw bindtxid coin withdrawpub amount\n"); throw runtime_error("gatewayswithdraw bindtxid coin withdrawpub amount\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");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
bindtxid = Parseuint256((char *)params[0].get_str().c_str()); bindtxid = Parseuint256((char *)params[0].get_str().c_str());
coin = params[1].get_str(); coin = params[1].get_str();
withdrawpub = ParseHex(params[2].get_str()); withdrawpub = ParseHex(params[2].get_str());
@@ -5519,6 +5552,8 @@ UniValue gatewaysmarkdone(const UniValue& params, bool fHelp)
throw runtime_error("gatewaysmarkdone withdrawtxid coin cointxid\n"); throw runtime_error("gatewaysmarkdone withdrawtxid coin cointxid\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");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
withdrawtxid = Parseuint256((char *)params[0].get_str().c_str()); withdrawtxid = Parseuint256((char *)params[0].get_str().c_str());
coin = params[1].get_str(); coin = params[1].get_str();
cointxid = Parseuint256((char *)params[2].get_str().c_str()); cointxid = Parseuint256((char *)params[2].get_str().c_str());
@@ -5550,6 +5585,8 @@ UniValue gatewaysmultisig(const UniValue& params, bool fHelp)
throw runtime_error("gatewaysmultisig bindtxid coin withtxid txidaddr\n"); throw runtime_error("gatewaysmultisig bindtxid coin withtxid txidaddr\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");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
bindtxid = Parseuint256((char *)params[0].get_str().c_str()); bindtxid = Parseuint256((char *)params[0].get_str().c_str());
coin = params[1].get_str(); coin = params[1].get_str();
withtxid = Parseuint256((char *)params[2].get_str().c_str()); withtxid = Parseuint256((char *)params[2].get_str().c_str());
@@ -5590,6 +5627,8 @@ UniValue oraclesregister(const UniValue& params, bool fHelp)
throw runtime_error("oraclesregister oracletxid datafee\n"); throw runtime_error("oraclesregister oracletxid datafee\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");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
txid = Parseuint256((char *)params[0].get_str().c_str()); txid = Parseuint256((char *)params[0].get_str().c_str());
datafee = atol((char *)params[1].get_str().c_str()); datafee = atol((char *)params[1].get_str().c_str());
hex = OracleRegister(0,txid,datafee); hex = OracleRegister(0,txid,datafee);
@@ -5608,6 +5647,8 @@ UniValue oraclessubscribe(const UniValue& params, bool fHelp)
throw runtime_error("oraclessubscribe oracletxid publisher amount\n"); throw runtime_error("oraclessubscribe oracletxid publisher amount\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");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
txid = Parseuint256((char *)params[0].get_str().c_str()); txid = Parseuint256((char *)params[0].get_str().c_str());
pubkey = ParseHex(params[1].get_str().c_str()); pubkey = ParseHex(params[1].get_str().c_str());
amount = atof((char *)params[2].get_str().c_str()) * COIN; amount = atof((char *)params[2].get_str().c_str()) * COIN;
@@ -5640,6 +5681,8 @@ UniValue oraclesdata(const UniValue& params, bool fHelp)
throw runtime_error("oraclesdata oracletxid hexstr\n"); throw runtime_error("oraclesdata oracletxid hexstr\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");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
txid = Parseuint256((char *)params[0].get_str().c_str()); txid = Parseuint256((char *)params[0].get_str().c_str());
data = ParseHex(params[1].get_str().c_str()); data = ParseHex(params[1].get_str().c_str());
hex = OracleData(0,txid,data); hex = OracleData(0,txid,data);
@@ -5776,6 +5819,156 @@ UniValue faucetget(const UniValue& params, bool fHelp)
return(result); return(result);
} }
UniValue priceslist(const UniValue& params, bool fHelp)
{
if ( fHelp || params.size() > 0 )
throw runtime_error("priceslist\n");
if ( ensure_CCrequirements() < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
return(PricesList());
}
UniValue pricesinfo(const UniValue& params, bool fHelp)
{
uint256 fundingtxid;
if ( fHelp || params.size() != 1 )
throw runtime_error("pricesinfo fundingtxid\n");
if ( ensure_CCrequirements() < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
fundingtxid = Parseuint256((char *)params[0].get_str().c_str());
return(PricesInfo(fundingtxid));
}
UniValue pricescreate(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); uint64_t mode; int64_t funding; int32_t i,n,margin,maxleverage; std::string hex; uint256 oracletxid,longtoken,shorttoken,bettoken; std::vector<CPubKey> pubkeys; std::vector<uint8_t>pubkey;
if ( fHelp || params.size() < 8 )
throw runtime_error("pricescreate bettoken oracletxid margin mode longtoken shorttoken maxleverage funding N [pubkeys]\n");
if ( ensure_CCrequirements() < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
bettoken = Parseuint256((char *)params[0].get_str().c_str());
oracletxid = Parseuint256((char *)params[1].get_str().c_str());
margin = atof(params[2].get_str().c_str()) * 1000;
mode = atol(params[3].get_str().c_str());
longtoken = Parseuint256((char *)params[4].get_str().c_str());
shorttoken = Parseuint256((char *)params[5].get_str().c_str());
maxleverage = atol(params[6].get_str().c_str());
funding = atof(params[7].get_str().c_str()) * COIN;
n = atoi(params[8].get_str().c_str());
if ( n > 0 )
{
for (i=0; i<n; i++)
{
if ( params.size() < 9+i+1 )
throw runtime_error("not enough parameters for N pubkeys\n");
pubkey = ParseHex(params[9+i].get_str().c_str());
pubkeys.push_back(pubkey2pk(pubkey));
}
}
hex = PricesCreateFunding(0,bettoken,oracletxid,margin,mode,longtoken,shorttoken,maxleverage,funding,pubkeys);
if ( hex.size() > 0 )
{
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", hex));
}
else
{
ERR_RESULT("couldnt create prices funding transaction");
}
return(result);
}
UniValue pricesaddfunding(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); std::string hex; uint256 fundingtxid,bettoken; int64_t amount;
if ( fHelp || params.size() != 3 )
throw runtime_error("pricesaddfunding fundingtxid bettoken amount\n");
if ( ensure_CCrequirements() < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
fundingtxid = Parseuint256((char *)params[0].get_str().c_str());
bettoken = Parseuint256((char *)params[1].get_str().c_str());
amount = atof(params[2].get_str().c_str()) * COIN;
hex = PricesAddFunding(0,bettoken,fundingtxid,amount);
if ( hex.size() > 0 )
{
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", hex));
}
else
{
ERR_RESULT("couldnt create pricesaddfunding transaction");
}
return(result);
}
UniValue pricesbet(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); std::string hex; uint256 fundingtxid,bettoken; int64_t amount; int32_t leverage;
if ( fHelp || params.size() != 4 )
throw runtime_error("pricesbet fundingtxid bettoken amount leverage\n");
if ( ensure_CCrequirements() < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
fundingtxid = Parseuint256((char *)params[0].get_str().c_str());
bettoken = Parseuint256((char *)params[1].get_str().c_str());
amount = atof(params[2].get_str().c_str()) * COIN;
leverage = atoi(params[3].get_str().c_str());
hex = PricesBet(0,bettoken,fundingtxid,amount,leverage);
if ( hex.size() > 0 )
{
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", hex));
}
else
{
ERR_RESULT("couldnt create pricesbet transaction");
}
return(result);
}
UniValue pricesstatus(const UniValue& params, bool fHelp)
{
uint256 fundingtxid,bettxid,bettoken;
if ( fHelp || params.size() != 3 )
throw runtime_error("pricesstatus fundingtxid bettoken bettxid\n");
if ( ensure_CCrequirements() < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
fundingtxid = Parseuint256((char *)params[0].get_str().c_str());
bettoken = Parseuint256((char *)params[1].get_str().c_str());
bettxid = Parseuint256((char *)params[2].get_str().c_str());
return(PricesStatus(0,bettoken,fundingtxid,bettxid));
}
UniValue pricesfinish(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); uint256 fundingtxid,bettxid,bettoken; std::string hex;
if ( fHelp || params.size() != 3 )
throw runtime_error("pricesfinish fundingtxid bettoken bettxid\n");
if ( ensure_CCrequirements() < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
fundingtxid = Parseuint256((char *)params[0].get_str().c_str());
bettoken = Parseuint256((char *)params[1].get_str().c_str());
bettxid = Parseuint256((char *)params[2].get_str().c_str());
hex = PricesFinish(0,bettoken,fundingtxid,bettxid);
if ( hex.size() > 0 )
{
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", hex));
}
else
{
ERR_RESULT("couldnt create pricesfinish transaction");
}
return(result);
}
UniValue dicefund(const UniValue& params, bool fHelp) UniValue dicefund(const UniValue& params, bool fHelp)
{ {
UniValue result(UniValue::VOBJ); int64_t funds,minbet,maxbet,maxodds,timeoutblocks; std::string hex; char *name; UniValue result(UniValue::VOBJ); int64_t funds,minbet,maxbet,maxodds,timeoutblocks; std::string hex; char *name;
@@ -5947,7 +6140,6 @@ UniValue dicestatus(const UniValue& params, bool fHelp)
UniValue dicelist(const UniValue& params, bool fHelp) UniValue dicelist(const UniValue& params, bool fHelp)
{ {
uint256 tokenid;
if ( fHelp || params.size() > 0 ) if ( fHelp || params.size() > 0 )
throw runtime_error("dicelist\n"); throw runtime_error("dicelist\n");
if ( ensure_CCrequirements() < 0 ) if ( ensure_CCrequirements() < 0 )
@@ -6096,6 +6288,42 @@ UniValue tokentransfer(const UniValue& params, bool fHelp)
return(result); return(result);
} }
UniValue tokenconvert(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); std::string hex; int32_t evalcode; int64_t amount; uint256 tokenid;
if ( fHelp || params.size() != 4 )
throw runtime_error("tokenconvert evalcode tokenid pubkey amount\n");
if ( ensure_CCrequirements() < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
evalcode = atoi(params[0].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()));
amount = atol(params[3].get_str().c_str());
if ( tokenid == zeroid )
{
ERR_RESULT("invalid tokenid");
return(result);
}
if ( amount <= 0 )
{
ERR_RESULT("amount must be positive");
return(result);
}
hex = AssetConvert(0,tokenid,pubkey,amount,evalcode);
if (amount > 0) {
if ( hex.size() > 0 )
{
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", hex));
} else ERR_RESULT("couldnt convert tokens");
} else {
ERR_RESULT("amount must be positive");
}
return(result);
}
UniValue tokenbid(const UniValue& params, bool fHelp) UniValue tokenbid(const UniValue& params, bool fHelp)
{ {
UniValue result(UniValue::VOBJ); int64_t bidamount,numtokens; std::string hex; double price; uint256 tokenid; UniValue result(UniValue::VOBJ); int64_t bidamount,numtokens; std::string hex; double price; uint256 tokenid;