@@ -490,8 +490,61 @@ Now we can make the payment based on the hashvalue revealed at a specified depth
|
||||
|
||||
Payments at the speed of the mempool, protected by dPoW!
|
||||
|
||||
<details of rpc calls, vin/vout allocations, etc>
|
||||
RPC calls
|
||||
channelsopen:
|
||||
Used to open channel between two pub keys (sender and receiver). Parameters: destination_pubkey, total_number_of_payments, payment_denomination.
|
||||
Example - channelsopen 03a8fe537de2ace0d9c210b0ff945085c9192c9abf56ea22f22ce7998f289bb7bb 10 10000000
|
||||
channelspayment:
|
||||
Sending payment to receiver. Condition is that the channel open tx is confirmed/notarised. Parameters: open_tx_id, payment_amount, [secret] (optional, used when receiver needs to make a payment which secret has already been revealed by sender).
|
||||
Example - channelspayment b9c141facc8cb71306d0de8e525b3de1450e93e17fc8799c8fda5ed52fd14440 20000000
|
||||
channelsclose:
|
||||
Marking channel as closed. This RPC only creates a tx which says that the channel is closed and will be used in refund RPC to withdraw funds from closed channel. This also notifies receiver that channel fund could be withdrawn, but the payment RPC is still available until all funds are withdrawn. Parameters: open_tx_id.
|
||||
Example - channelsclose b9c141facc8cb71306d0de8e525b3de1450e93e17fc8799c8fda5ed52fd14440
|
||||
channelsrefund:
|
||||
Withdrawing funds back to senders address. Refund can be issued only when channel close tx is confirmed/notarised. Parameters: open_tx_id, close_tx_id
|
||||
Example - channelsrefund b9c141facc8cb71306d0de8e525b3de1450e93e17fc8799c8fda5ed52fd14440 bb0ea34f846247642684c7c541c435b06ee79e47893640e5d2e51023841677fd
|
||||
channelsinfo:
|
||||
Getting info about channels in which the issuer is involved, either as sender or receiver. Call without parameters give the list of available channels. Parameters: [open_tx_id] (optional - used to get info about specific channel)
|
||||
|
||||
VIN/VOUT allocation
|
||||
Open:
|
||||
vin.0: normal input
|
||||
vout.0: CC vout for channel funding on CC1of2 pubkey
|
||||
vout.1: CC vout marker to senders pubKey
|
||||
vout.2: CC vout marker to receiver pubkey
|
||||
vout.n-2: normal change
|
||||
vout.n-1: opreturn - 'O' zerotxid senderspubkey receiverspubkey totalnumberofpayments paymentamount hashchain
|
||||
|
||||
Payment
|
||||
vin.0: normal input
|
||||
vin.1: CC input from channel funding
|
||||
vin.2: CC input from src marker
|
||||
vout.0: CC vout change to channel funding on CC1of2 pubkey
|
||||
vout.1: CC vout marker to senders pubKey
|
||||
vout.2: CC vout marker to receiver pubkey
|
||||
vout.3: normal output of payment amount to receiver pubkey
|
||||
vout.n-2: normal change
|
||||
vout.n-1: opreturn - 'P' opentxid senderspubkey receiverspubkey depth numpayments secret
|
||||
|
||||
Close:
|
||||
vin.0: normal input
|
||||
vin.1: CC input from channel funding
|
||||
vin.2: CC input from src marker
|
||||
vout.0: CC vout for channel funding
|
||||
vout.1: CC vout marker to senders pubKey
|
||||
vout.2: CC vout marker to receiver pubkey
|
||||
vout.n-2: normal change
|
||||
vout.n-1: opreturn - 'C' opentxid senderspubkey receiverspubkey 0 0 0
|
||||
|
||||
Refund:
|
||||
vin.0: normal input
|
||||
vin.1: CC input from channel funding
|
||||
vin.2: CC input from src marker
|
||||
vout.0: CC vout marker to senders pubKey
|
||||
vout.1: CC vout marker to receiver pubKey
|
||||
vout.2: normal output of CC input to senders pubkey
|
||||
vout.n-2: normal change
|
||||
vout.n-1: opreturn - 'R' opentxid senderspubkey receiverspubkey numpayments payment closetxid
|
||||
|
||||
Chapter 11 - oracles example
|
||||
Oracles CC is an example where it ended up being simpler than I first expected, but at the same time a lot more powerful. It is one of the smaller CC, but it enables creation of an arbitrary number of data markets, in a performant way.
|
||||
|
||||
@@ -22,12 +22,11 @@
|
||||
|
||||
bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||
std::string ChannelOpen(uint64_t txfee,CPubKey destpub,int32_t numpayments,int64_t payment);
|
||||
std::string ChannelStop(uint64_t txfee,CPubKey destpub,uint256 origtxid);
|
||||
std::string ChannelPayment(uint64_t txfee,uint256 prevtxid,uint256 origtxid,int32_t n,int64_t amount);
|
||||
std::string ChannelCollect(uint64_t txfee,uint256 paytxid,uint256 origtxid,int32_t n,int64_t amount);
|
||||
std::string ChannelRefund(uint64_t txfee,uint256 stoptxid,uint256 origtxid);
|
||||
std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint256 secret);
|
||||
std::string ChannelClose(uint64_t txfee,uint256 opentxid);
|
||||
std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid);
|
||||
|
||||
// CCcustom
|
||||
UniValue ChannelsInfo();
|
||||
UniValue ChannelsInfo(uint256 opentxid);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -214,7 +214,7 @@ uint8_t PaymentsCCpriv[32] = { 0x03, 0xc9, 0x73, 0xc2, 0xb8, 0x30, 0x3d, 0xbd, 0
|
||||
#define FUNCNAME IsGatewaysInput
|
||||
#define EVALCODE EVAL_GATEWAYS
|
||||
const char *GatewaysCCaddr = "RKWpoK6vTRtq5b9qrRBodLkCzeURHeEk33";
|
||||
const char *GatewaysNormaladdr = "RGJKV97ZN1wBfunuMt1tebiiHENNEq73Yh";
|
||||
const char *GatewaysNormaladdr = "RGJKV97ZN1wBfunuMt1tebiiHENNEq73Yh"; // wif UxJFYqEvLAjWPPRvn8NN1fRWscBxQZXZB5BBgc3HiapKVQBYNcmo
|
||||
char GatewaysCChexstr[67] = { "03ea9c062b9652d8eff34879b504eda0717895d27597aaeb60347d65eed96ccb40" };
|
||||
uint8_t GatewaysCCpriv[32] = { 0xf7, 0x4b, 0x5b, 0xa2, 0x7a, 0x5e, 0x9c, 0xda, 0x89, 0xb1, 0xcb, 0xb9, 0xe6, 0x9c, 0x2c, 0x70, 0x85, 0x37, 0xdd, 0x00, 0x7a, 0x67, 0xff, 0x7c, 0x62, 0x1b, 0xe2, 0xfb, 0x04, 0x8f, 0x85, 0xbf };
|
||||
#include "CCcustom.inc"
|
||||
|
||||
@@ -54,6 +54,7 @@ extern uint32_t ASSETCHAINS_CC;
|
||||
extern std::string CCerror;
|
||||
|
||||
#define SMALLVAL 0.000000000000001
|
||||
#define MIN_NOTARIZATION_CONFIRMS 2
|
||||
union _bits256 { uint8_t bytes[32]; uint16_t ushorts[16]; uint32_t uints[8]; uint64_t ulongs[4]; uint64_t txid; };
|
||||
typedef union _bits256 bits256;
|
||||
|
||||
@@ -125,6 +126,7 @@ uint256 DiceHashEntropy(uint256 &entropy,uint256 _txidpriv);
|
||||
CTxOut MakeCC1vout(uint8_t evalcode,CAmount nValue,CPubKey pk);
|
||||
CTxOut MakeCC1of2vout(uint8_t evalcode,CAmount nValue,CPubKey pk,CPubKey pk2);
|
||||
CC *MakeCCcond1(uint8_t evalcode,CPubKey pk);
|
||||
CC *MakeCCcond1of2(uint8_t evalcode,CPubKey pk1,CPubKey pk2);
|
||||
CC* GetCryptoCondition(CScript const& scriptSig);
|
||||
void CCaddr2set(struct CCcontract_info *cp,uint8_t evalcode,CPubKey pk,uint8_t *priv,char *coinaddr);
|
||||
void CCaddr3set(struct CCcontract_info *cp,uint8_t evalcode,CPubKey pk,uint8_t *priv,char *coinaddr);
|
||||
@@ -148,7 +150,7 @@ bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey);
|
||||
std::vector<uint8_t> Mypubkey();
|
||||
bool Myprivkey(uint8_t myprivkey[]);
|
||||
int64_t CCduration(int32_t &numblocks,uint256 txid);
|
||||
|
||||
bool isCCTxNotarizedConfirmed(uint256 txid);
|
||||
// CCtx
|
||||
std::string FinalizeCCTx(uint64_t skipmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret);
|
||||
void SetCCunspents(std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs,char *coinaddr);
|
||||
|
||||
@@ -111,7 +111,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
|
||||
{
|
||||
privkey = myprivkey;
|
||||
cond = mycond;
|
||||
//fprintf(stderr,"my CC addr.(%s)\n",myaddr);
|
||||
|
||||
}
|
||||
else if ( strcmp(destaddr,unspendable) == 0 )
|
||||
{
|
||||
@@ -119,12 +119,14 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
|
||||
cond = othercond;
|
||||
//fprintf(stderr,"unspendable CC addr.(%s)\n",unspendable);
|
||||
}
|
||||
else if ( strcmp(destaddr,cp->unspendableaddr2) == 0 )
|
||||
else if ( strcmp(destaddr,cp->unspendableaddr2) == 0)
|
||||
{
|
||||
//fprintf(stderr,"matched %s unspendable2!\n",cp->unspendableaddr2);
|
||||
privkey = cp->unspendablepriv2;
|
||||
if ( othercond2 == 0 )
|
||||
if ( othercond2 == 0 && cp->evalcode != EVAL_CHANNELS)
|
||||
othercond2 = MakeCCcond1(cp->evalcode2,cp->unspendablepk2);
|
||||
else if ( othercond2 == 0 && cp->evalcode == EVAL_CHANNELS)
|
||||
othercond2 = MakeCCcond1of2(cp->evalcode2,cp->unspendablepk2,cp->unspendablepk3);
|
||||
cond = othercond2;
|
||||
}
|
||||
else if ( strcmp(destaddr,cp->unspendableaddr3) == 0 )
|
||||
@@ -137,7 +139,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"vini.%d has unknown CC address.(%s)\n",i,destaddr);
|
||||
fprintf(stderr,"CC signing error: vini.%d has unknown CC address.(%s)\n",i,destaddr);
|
||||
continue;
|
||||
}
|
||||
uint256 sighash = SignatureHash(CCPubKey(cond), mtx, i, SIGHASH_ALL, utxovalues[i],consensusBranchId, &txdata);
|
||||
|
||||
@@ -63,7 +63,6 @@ CTxOut MakeCC1of2vout(uint8_t evalcode,CAmount nValue,CPubKey pk1,CPubKey pk2)
|
||||
CTxOut vout;
|
||||
CC *payoutCond = MakeCCcond1of2(evalcode,pk1,pk2);
|
||||
vout = CTxOut(nValue,CCPubKey(payoutCond));
|
||||
fprintf(stderr,"payoutCond: %s\n",cc_conditionToJSONString(payoutCond));
|
||||
cc_free(payoutCond);
|
||||
return(vout);
|
||||
}
|
||||
@@ -406,7 +405,16 @@ int64_t CCduration(int32_t &numblocks,uint256 txid)
|
||||
}
|
||||
numblocks = (pindex->nHeight - txheight);
|
||||
duration = (pindex->nTime - txtime);
|
||||
fprintf(stderr,"duration %d (%u - %u) numblocks %d (%d - %d)\n",(int32_t)duration,(uint32_t)pindex->nTime,txtime,numblocks,pindex->nHeight,txheight);
|
||||
//fprintf(stderr,"duration %d (%u - %u) numblocks %d (%d - %d)\n",(int32_t)duration,(uint32_t)pindex->nTime,txtime,numblocks,pindex->nHeight,txheight);
|
||||
return(duration);
|
||||
}
|
||||
|
||||
bool isCCTxNotarizedConfirmed(uint256 txid)
|
||||
{
|
||||
int32_t confirms;
|
||||
|
||||
CCduration(confirms,txid);
|
||||
if (confirms >= MIN_NOTARIZATION_CONFIRMS)
|
||||
return (true);
|
||||
return (false);
|
||||
}
|
||||
|
||||
@@ -62,46 +62,86 @@ Possible third iteration:
|
||||
|
||||
// start of consensus code
|
||||
|
||||
int64_t IsChannelsvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
|
||||
int64_t IsChannelsvout(struct CCcontract_info *cp,const CTransaction& tx,CPubKey srcpub, CPubKey destpub,int32_t v)
|
||||
{
|
||||
char destaddr[64];
|
||||
char destaddr[64],channeladdr[64];
|
||||
|
||||
GetCCaddress1of2(cp,channeladdr,srcpub,destpub);
|
||||
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||
{
|
||||
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 )
|
||||
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,channeladdr) == 0 )
|
||||
return(tx.vout[v].nValue);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int64_t IsChannelsMarkervout(struct CCcontract_info *cp,const CTransaction& tx,CPubKey srcpub,int32_t v)
|
||||
{
|
||||
char destaddr[64],ccaddr[64];
|
||||
|
||||
GetCCaddress(cp,ccaddr,srcpub);
|
||||
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||
{
|
||||
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,ccaddr) == 0 )
|
||||
return(tx.vout[v].nValue);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
CScript EncodeChannelsOpRet(uint8_t funcid,uint256 opentxid,CPubKey srcpub,CPubKey destpub,int32_t numpayments,int64_t payment,uint256 hashchain)
|
||||
{
|
||||
CScript opret; uint8_t evalcode = EVAL_CHANNELS;
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << opentxid << srcpub << destpub << numpayments << payment << hashchain);
|
||||
return(opret);
|
||||
}
|
||||
|
||||
uint8_t DecodeChannelsOpRet(const CScript &scriptPubKey,uint256 &opentxid, CPubKey &srcpub,CPubKey &destpub,int32_t &numpayments,int64_t &payment,uint256 &hashchain)
|
||||
{
|
||||
std::vector<uint8_t> vopret; uint8_t *script,e,f;
|
||||
GetOpReturnData(scriptPubKey, vopret);
|
||||
if ( vopret.size() > 2 )
|
||||
{
|
||||
script = (uint8_t *)vopret.data();
|
||||
if ( script[0] == EVAL_CHANNELS )
|
||||
{
|
||||
if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> opentxid; ss >> srcpub; ss >> destpub; ss >> numpayments; ss >> payment; ss >> hashchain) != 0 )
|
||||
{
|
||||
return(f);
|
||||
}
|
||||
} else fprintf(stderr,"script[0] %02x != EVAL_CHANNELS\n",script[0]);
|
||||
} else fprintf(stderr,"not enough opret.[%d]\n",(int32_t)vopret.size());
|
||||
return(0);
|
||||
}
|
||||
|
||||
bool ChannelsExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
|
||||
{
|
||||
static uint256 zerohash;
|
||||
CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis;
|
||||
uint256 txid,param3;
|
||||
CPubKey srcpub,destpub;
|
||||
int32_t param1; int64_t param2; uint8_t funcid;
|
||||
CTransaction vinTx; uint256 hashBlock; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis;
|
||||
numvins = tx.vin.size();
|
||||
numvouts = tx.vout.size();
|
||||
for (i=0; i<numvins; i++)
|
||||
|
||||
if ((numvouts=tx.vout.size()) > 0 && DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey, txid, srcpub, destpub, param1, param2, param3)!=0)
|
||||
{
|
||||
//fprintf(stderr,"vini.%d\n",i);
|
||||
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) != 0 )
|
||||
for (i=0; i<numvins; i++)
|
||||
{
|
||||
//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 Channels from mempool");
|
||||
if ( (assetoshis= IsChannelsvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
|
||||
inputs += assetoshis;
|
||||
inputs += vinTx.vout[tx.vin[i].prevout.n].nValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return eval->Invalid("invalid op_return data");
|
||||
}
|
||||
for (i=0; i<numvouts; i++)
|
||||
{
|
||||
//fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts);
|
||||
if ( (assetoshis= IsChannelsvout(cp,tx,i)) != 0 )
|
||||
outputs += assetoshis;
|
||||
outputs += tx.vout[i].nValue;
|
||||
}
|
||||
if ( inputs != outputs+txfee )
|
||||
{
|
||||
@@ -113,25 +153,22 @@ bool ChannelsExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransacti
|
||||
|
||||
bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
|
||||
{
|
||||
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks; bool retval; uint256 txid; uint8_t hash[32]; char str[65],destaddr[64];
|
||||
return(false);
|
||||
std::vector<std::pair<CAddressIndexKey, CAmount> > txids;
|
||||
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numpayments,p1,param1; bool retval;
|
||||
uint256 txid,hashblock,p3,param3,opentxid,tmp_txid,genhashchain,hashchain;
|
||||
uint8_t funcid,hash[32],hashdest[32];
|
||||
int64_t p2,param2,payment;
|
||||
CPubKey srcpub, destpub;
|
||||
CTransaction channelOpenTx,channelCloseTx,prevTx;
|
||||
|
||||
numvins = tx.vin.size();
|
||||
numvouts = tx.vout.size();
|
||||
preventCCvins = preventCCvouts = -1;
|
||||
fprintf(stderr,"validateCC\n");
|
||||
if ( numvouts < 1 )
|
||||
return eval->Invalid("no vouts");
|
||||
else
|
||||
{
|
||||
for (i=0; i<numvins; i++)
|
||||
{
|
||||
if ( IsCCInput(tx.vin[0].scriptSig) == 0 )
|
||||
{
|
||||
return eval->Invalid("illegal normal vini");
|
||||
}
|
||||
}
|
||||
//fprintf(stderr,"check amounts\n");
|
||||
if ( ChannelsExactAmounts(cp,eval,tx,1,10000) == false )
|
||||
if (ChannelsExactAmounts(cp,eval,tx,1,10000) == false )
|
||||
{
|
||||
fprintf(stderr,"Channelsget invalid amount\n");
|
||||
return false;
|
||||
@@ -140,6 +177,180 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
|
||||
{
|
||||
txid = tx.GetHash();
|
||||
memcpy(hash,&txid,sizeof(hash));
|
||||
|
||||
if ( (funcid = DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey, opentxid, srcpub, destpub, param1, param2, param3)) != 0)
|
||||
{
|
||||
switch ( funcid )
|
||||
{
|
||||
case 'O':
|
||||
//vin.0: normal input
|
||||
//vout.0: CC vout for channel funding on CC1of2 pubkey
|
||||
//vout.1: CC vout marker to senders pubKey
|
||||
//vout.2: CC vout marker to receiver pubkey
|
||||
//vout.n-2: normal change
|
||||
//vout.n-1: opreturn - 'O' zerotxid senderspubkey receiverspubkey totalnumberofpayments paymentamount hashchain
|
||||
return eval->Invalid("unexpected ChannelsValidate for channelsopen!");
|
||||
case 'P':
|
||||
//vin.0: normal input
|
||||
//vin.1: CC input from channel funding
|
||||
//vin.2: CC input from src marker
|
||||
//vout.0: CC vout change to CC1of2 pubkey
|
||||
//vout.1: CC vout marker to senders pubKey
|
||||
//vout.2: CC vout marker to receiver pubkey
|
||||
//vout.3: normal output of payment amount to receiver pubkey
|
||||
//vout.n-2: normal change
|
||||
//vout.n-1: opreturn - 'P' opentxid senderspubkey receiverspubkey depth numpayments secret
|
||||
if (isCCTxNotarizedConfirmed(opentxid) == 0)
|
||||
return eval->Invalid("channelOpen is not yet confirmed(notarised)!");
|
||||
else if ( IsCCInput(tx.vin[0].scriptSig) != 0 )
|
||||
return eval->Invalid("vin.0 is normal for channelPayment!");
|
||||
else if ( IsCCInput(tx.vin[1].scriptSig) == 0 )
|
||||
return eval->Invalid("vin.1 is CC for channelPayment!");
|
||||
else if ( IsCCInput(tx.vin[2].scriptSig) == 0 )
|
||||
return eval->Invalid("vin.1 is CC for channelPayment!");
|
||||
else if ( tx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 )
|
||||
return eval->Invalid("vout.0 is CC for channelPayment!");
|
||||
else if ( tx.vout[1].scriptPubKey.IsPayToCryptoCondition() == 0 )
|
||||
return eval->Invalid("vout.1 is CC for channelPayment (marker to srcPub)!");
|
||||
else if ( tx.vout[2].scriptPubKey.IsPayToCryptoCondition() == 0 )
|
||||
return eval->Invalid("vout.1 is CC for channelPayment (marker to dstPub)!");
|
||||
else if ( tx.vout[3].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||
return eval->Invalid("vout.1 is normal for channelPayment!");
|
||||
else if ( tx.vout[3].scriptPubKey!=CScript() << ParseHex(HexStr(destpub)) << OP_CHECKSIG)
|
||||
return eval->Invalid("payment funds do not go to receiver!");
|
||||
else if ( param1 > CHANNELS_MAXPAYMENTS)
|
||||
return eval->Invalid("too many payment increments!");
|
||||
else
|
||||
{
|
||||
if (myGetTransaction(opentxid,channelOpenTx,hashblock) != 0)
|
||||
{
|
||||
if ((numvouts=channelOpenTx.vout.size()) > 0 && (funcid=DecodeChannelsOpRet(channelOpenTx.vout[numvouts-1].scriptPubKey, tmp_txid, srcpub, destpub, numpayments, payment, hashchain)) != 0 && funcid!='O')
|
||||
return eval->Invalid("invalid channelopen OP_RETURN data!");
|
||||
endiancpy(hash, (uint8_t * ) & param3, 32);
|
||||
for (i = 0; i < numpayments-param1; i++)
|
||||
{
|
||||
vcalc_sha256(0, hashdest, hash, 32);
|
||||
memcpy(hash, hashdest, 32);
|
||||
}
|
||||
endiancpy((uint8_t*)&genhashchain,hashdest,32);
|
||||
if (hashchain!=genhashchain)
|
||||
return eval->Invalid("invalid secret for payment, does not reach final hashchain!");
|
||||
else if (tx.vout[3].nValue != param2*payment)
|
||||
return eval->Invalid("vout amount does not match number_of_payments*payment!");
|
||||
}
|
||||
if (myGetTransaction(tx.vin[1].prevout.hash,prevTx,hashblock) != 0)
|
||||
{
|
||||
if ((numvouts=prevTx.vout.size()) > 0 && DecodeChannelsOpRet(prevTx.vout[numvouts-1].scriptPubKey, tmp_txid, srcpub, destpub, p1, p2, p3) == 0)
|
||||
return eval->Invalid("invalid previous tx OP_RETURN data!");
|
||||
else if (tx.vout[1].scriptPubKey != prevTx.vout[1].scriptPubKey)
|
||||
return eval->Invalid("invalid destination for sender marker!");
|
||||
else if (tx.vout[2].scriptPubKey != prevTx.vout[2].scriptPubKey)
|
||||
return eval->Invalid("invalid destination for receiver marker!");
|
||||
else if (param1+param2!=p1)
|
||||
return eval->Invalid("invalid payment depth!");
|
||||
else if (tx.vout[3].nValue > prevTx.vout[0].nValue)
|
||||
return eval->Invalid("not enough funds in channel for that amount!");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'C':
|
||||
//vin.0: normal input
|
||||
//vin.1: CC input from channel funding
|
||||
//vin.2: CC input from src marker
|
||||
//vout.0: CC vout for channel funding
|
||||
//vout.1: CC vout marker to senders pubKey
|
||||
//vout.2: CC vout marker to receiver pubkey
|
||||
//vout.n-2: normal change
|
||||
//vout.n-1: opreturn - 'C' opentxid senderspubkey receiverspubkey 0 0 0
|
||||
if (isCCTxNotarizedConfirmed(opentxid) == 0)
|
||||
return eval->Invalid("channelOpen is not yet confirmed(notarised)!");
|
||||
else if ( IsCCInput(tx.vin[0].scriptSig) != 0 )
|
||||
return eval->Invalid("vin.0 is normal for channelClose!");
|
||||
else if ( IsCCInput(tx.vin[1].scriptSig) == 0 )
|
||||
return eval->Invalid("vin.1 is CC for channelClose!");
|
||||
else if ( IsCCInput(tx.vin[2].scriptSig) == 0 )
|
||||
return eval->Invalid("vin.2 is CC for channelClose!");
|
||||
else if ( tx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 )
|
||||
return eval->Invalid("vout.0 is CC for channelClose!");
|
||||
else if ( tx.vout[1].scriptPubKey.IsPayToCryptoCondition() == 0 )
|
||||
return eval->Invalid("vout.1 is CC for channelClose (marker to srcPub)!");
|
||||
else if ( tx.vout[2].scriptPubKey.IsPayToCryptoCondition() == 0 )
|
||||
return eval->Invalid("vout.2 is CC for channelClose (marker to dstPub)!");
|
||||
else if ( param1 > CHANNELS_MAXPAYMENTS)
|
||||
return eval->Invalid("too many payment increments!");
|
||||
else if (myGetTransaction(opentxid,channelOpenTx,hashblock) == 0)
|
||||
return eval->Invalid("invalid open txid!");
|
||||
else if ((numvouts=channelOpenTx.vout.size()) > 0 && DecodeChannelsOpRet(channelOpenTx.vout[numvouts-1].scriptPubKey, tmp_txid, srcpub, destpub, numpayments, payment, hashchain) != 'O')
|
||||
return eval->Invalid("invalid channelopen OP_RETURN data!");
|
||||
else if (tx.vout[0].nValue != param1*payment)
|
||||
return eval->Invalid("vout amount does not match number_of_payments*payment!");
|
||||
else if (myGetTransaction(tx.vin[1].prevout.hash,prevTx,hashblock) != 0)
|
||||
{
|
||||
if ((numvouts=prevTx.vout.size()) > 0 && DecodeChannelsOpRet(prevTx.vout[numvouts-1].scriptPubKey, tmp_txid, srcpub, destpub, p1, p2, p3) == 0)
|
||||
return eval->Invalid("invalid previous tx OP_RETURN data!");
|
||||
else if (tx.vout[1].scriptPubKey != prevTx.vout[1].scriptPubKey)
|
||||
return eval->Invalid("invalid destination for sender marker!");
|
||||
else if (tx.vout[2].scriptPubKey != prevTx.vout[2].scriptPubKey)
|
||||
return eval->Invalid("invalid destination for receiver marker!");
|
||||
else if (tx.vout[0].nValue != prevTx.vout[0].nValue)
|
||||
return eval->Invalid("invalid CC amount, amount must match funds in channel");
|
||||
}
|
||||
break;
|
||||
case 'R':
|
||||
//vin.0: normal input
|
||||
//vin.1: CC input from channel funding
|
||||
//vin.2: CC input from src marker
|
||||
//vout.0: CC vout marker to senders pubKey
|
||||
//vout.1: CC vout marker to receiver pubKey
|
||||
//vout.2: normal output of CC input to senders pubkey
|
||||
//vout.n-2: normal change
|
||||
//vout.n-1: opreturn - 'R' opentxid senderspubkey receiverspubkey numpayments payment closetxid
|
||||
if (isCCTxNotarizedConfirmed(opentxid) == 0)
|
||||
return eval->Invalid("channelOpen is not yet confirmed(notarised)!");
|
||||
else if (isCCTxNotarizedConfirmed(param3) == 0)
|
||||
return eval->Invalid("channelClose is not yet confirmed(notarised)!");
|
||||
else if ( IsCCInput(tx.vin[0].scriptSig) != 0 )
|
||||
return eval->Invalid("vin.0 is normal for channelRefund!");
|
||||
else if ( IsCCInput(tx.vin[1].scriptSig) == 0 )
|
||||
return eval->Invalid("vin.1 is CC for channelRefund!");
|
||||
else if ( IsCCInput(tx.vin[2].scriptSig) == 0 )
|
||||
return eval->Invalid("vin.2 is CC for channelRefund!");
|
||||
else if ( tx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 )
|
||||
return eval->Invalid("vout.0 is CC for channelRefund (marker to srcPub)!");
|
||||
else if ( tx.vout[1].scriptPubKey.IsPayToCryptoCondition() == 0 )
|
||||
return eval->Invalid("vout.1 is CC for channelRefund (marker to dstPub)!");
|
||||
else if ( tx.vout[2].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||
return eval->Invalid("vout.2 is normal for channelRefund!");
|
||||
else if ( tx.vout[2].scriptPubKey!=CScript() << ParseHex(HexStr(srcpub)) << OP_CHECKSIG)
|
||||
return eval->Invalid("payment funds do not go to sender!");
|
||||
else if ( param1 > CHANNELS_MAXPAYMENTS)
|
||||
return eval->Invalid("too many payment increments!");
|
||||
else if (myGetTransaction(opentxid,channelOpenTx,hashblock) == 0)
|
||||
return eval->Invalid("invalid open txid!");
|
||||
else if ((numvouts=channelOpenTx.vout.size()) > 0 && DecodeChannelsOpRet(channelOpenTx.vout[numvouts-1].scriptPubKey, tmp_txid, srcpub, destpub, numpayments, payment, hashchain) != 'O')
|
||||
return eval->Invalid("invalid channelopen OP_RETURN data!");
|
||||
else if (myGetTransaction(param3,channelCloseTx,hashblock) == 0)
|
||||
return eval->Invalid("invalid close txid!");
|
||||
else if ((numvouts=channelCloseTx.vout.size()) > 0 && DecodeChannelsOpRet(channelCloseTx.vout[numvouts-1].scriptPubKey, tmp_txid, srcpub, destpub, param1, param2, param3) != 'C')
|
||||
return eval->Invalid("invalid channelclose OP_RETURN data!");
|
||||
else if (tmp_txid!=opentxid)
|
||||
return eval->Invalid("invalid close tx, opentxid do not match on close and refund!");
|
||||
else if (tx.vout[2].nValue != param1*payment)
|
||||
return eval->Invalid("vout amount does not match number_of_payments*payment!");
|
||||
else if (myGetTransaction(tx.vin[1].prevout.hash,prevTx,hashblock) != 0)
|
||||
{
|
||||
if ((numvouts=prevTx.vout.size()) > 0 && DecodeChannelsOpRet(prevTx.vout[numvouts-1].scriptPubKey, tmp_txid, srcpub, destpub, p1, p2, p3) == 0)
|
||||
return eval->Invalid("invalid previous tx OP_RETURN data!");
|
||||
else if (tx.vout[0].scriptPubKey != prevTx.vout[1].scriptPubKey)
|
||||
return eval->Invalid("invalid destination for sender marker!");
|
||||
else if (tx.vout[1].scriptPubKey != prevTx.vout[2].scriptPubKey)
|
||||
return eval->Invalid("invalid destination for receiver marker!");
|
||||
else if (tx.vout[2].nValue != prevTx.vout[0].nValue)
|
||||
return eval->Invalid("invalid amount, refund amount and funds in channel must match!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
|
||||
if ( retval != 0 )
|
||||
fprintf(stderr,"Channelsget validated\n");
|
||||
@@ -152,57 +363,67 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
|
||||
|
||||
// helper functions for rpc calls in rpcwallet.cpp
|
||||
|
||||
CScript EncodeChannelsOpRet(uint8_t funcid,CPubKey srcpub,CPubKey destpub,int32_t numpayments,int64_t payment,uint256 hashchain)
|
||||
int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, CTransaction openTx, uint256 &prevtxid)
|
||||
{
|
||||
CScript opret; uint8_t evalcode = EVAL_CHANNELS;
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << srcpub << destpub << numpayments << payment << hashchain);
|
||||
return(opret);
|
||||
}
|
||||
|
||||
uint8_t DecodeChannelsOpRet(uint256 txid,const CScript &scriptPubKey,CPubKey &srcpub,CPubKey &destpub,int32_t &numpayments,int64_t &payment,uint256 &hashchain)
|
||||
{
|
||||
std::vector<uint8_t> vopret; uint8_t *script,e,f,funcid;
|
||||
GetOpReturnData(scriptPubKey, vopret);
|
||||
if ( vopret.size() > 2 )
|
||||
{
|
||||
script = (uint8_t *)vopret.data();
|
||||
if ( script[0] == EVAL_CHANNELS )
|
||||
{
|
||||
if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> srcpub; ss >> destpub; ss >> numpayments; ss >> payment; ss >> hashchain) != 0 )
|
||||
{
|
||||
return(f);
|
||||
}
|
||||
} else fprintf(stderr,"script[0] %02x != EVAL_CHANNELS\n",script[0]);
|
||||
} else fprintf(stderr,"not enough opret.[%d]\n",(int32_t)vopret.size());
|
||||
return(0);
|
||||
}
|
||||
|
||||
int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,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]; int64_t param2,totalinputs = 0,numvouts; uint256 txid=zeroid,tmp_txid,hashBlock,param3; CTransaction tx; int32_t param1;
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
GetCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
CPubKey srcpub,destpub;
|
||||
uint8_t myprivkey[32];
|
||||
|
||||
if ((numvouts=openTx.vout.size()) > 0 && DecodeChannelsOpRet(openTx.vout[numvouts-1].scriptPubKey,tmp_txid,srcpub,destpub,param1,param2,param3)=='O')
|
||||
{
|
||||
GetCCaddress1of2(cp,coinaddr,srcpub,destpub);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"invalid open txid\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
vout = (int32_t)it->first.index;
|
||||
// no need to prevent dup
|
||||
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
|
||||
if ( (int32_t)it->first.index==0 && GetTransaction(it->first.txhash,tx,hashBlock,false) != 0 && (numvouts=tx.vout.size()) > 0)
|
||||
{
|
||||
if ( (nValue= IsChannelsvout(cp,vintx,vout)) > 0 && myIsutxo_spentinmempool(txid,vout) == 0 )
|
||||
if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,tmp_txid,srcpub,destpub,param1,param2,param3)!=0 &&
|
||||
(tmp_txid==openTx.GetHash() || tx.GetHash()==openTx.GetHash()) &&
|
||||
(totalinputs=IsChannelsvout(cp,tx,srcpub,destpub,0)+IsChannelsMarkervout(cp,tx,srcpub,1))>0)
|
||||
{
|
||||
if ( total != 0 && maxinputs != 0 )
|
||||
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
||||
nValue = it->second.satoshis;
|
||||
totalinputs += nValue;
|
||||
n++;
|
||||
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
|
||||
break;
|
||||
txid = it->first.txhash;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(totalinputs);
|
||||
if (txid!=zeroid && myIsutxo_spentinmempool(txid,0) != 0)
|
||||
{
|
||||
fprintf(stderr,"spent in mempool\n");
|
||||
txid=zeroid;
|
||||
int32_t mindepth=CHANNELS_MAXPAYMENTS;
|
||||
BOOST_FOREACH(const CTxMemPoolEntry &e, mempool.mapTx)
|
||||
{
|
||||
const CTransaction &txmempool = e.GetTx();
|
||||
const uint256 &hash = txmempool.GetHash();
|
||||
|
||||
if ((numvouts=txmempool.vout.size()) > 0 && DecodeChannelsOpRet(txmempool.vout[numvouts-1].scriptPubKey,tmp_txid,srcpub,destpub,param1,param2,param3) != 0 &&
|
||||
tmp_txid==openTx.GetHash() && param1 < mindepth)
|
||||
{
|
||||
txid=hash;
|
||||
totalinputs=txmempool.vout[0].nValue+txmempool.vout[1].nValue;
|
||||
mindepth=param1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (txid != zeroid)
|
||||
{
|
||||
prevtxid=txid;
|
||||
mtx.vin.push_back(CTxIn(txid,0,CScript()));
|
||||
mtx.vin.push_back(CTxIn(txid,1,CScript()));
|
||||
Myprivkey(myprivkey);
|
||||
CCaddr2set(cp,EVAL_CHANNELS,srcpub,myprivkey,coinaddr);
|
||||
CCaddr3set(cp,EVAL_CHANNELS,destpub,myprivkey,coinaddr);
|
||||
return totalinputs;
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
|
||||
std::string ChannelOpen(uint64_t txfee,CPubKey destpub,int32_t numpayments,int64_t payment)
|
||||
@@ -210,7 +431,7 @@ std::string ChannelOpen(uint64_t txfee,CPubKey destpub,int32_t numpayments,int64
|
||||
CMutableTransaction mtx; uint8_t hash[32],hashdest[32]; uint64_t funds; int32_t i; uint256 hashchain,entropy,hentropy; CPubKey mypk; struct CCcontract_info *cp,C;
|
||||
if ( numpayments <= 0 || payment <= 0 || numpayments > CHANNELS_MAXPAYMENTS )
|
||||
{
|
||||
CCerror = strprintf("invalid ChannelsFund param numpayments.%d max.%d payment.%lld\n",numpayments,CHANNELS_MAXPAYMENTS,(long long)payment);
|
||||
CCerror = strprintf("invalid ChannelOpen param numpayments.%d max.%d payment.%lld\n",numpayments,CHANNELS_MAXPAYMENTS,(long long)payment);
|
||||
fprintf(stderr,"%s\n",CCerror.c_str());
|
||||
return("");
|
||||
}
|
||||
@@ -232,106 +453,310 @@ std::string ChannelOpen(uint64_t txfee,CPubKey destpub,int32_t numpayments,int64
|
||||
mtx.vout.push_back(MakeCC1of2vout(EVAL_CHANNELS,funds,mypk,destpub));
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,mypk));
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,destpub));
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('O',mypk,destpub,numpayments,payment,hashchain)));
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('O',zeroid,mypk,destpub,numpayments,payment,hashchain)));
|
||||
}
|
||||
return("");
|
||||
}
|
||||
|
||||
std::string ChannelStop(uint64_t txfee,CPubKey destpub,uint256 origtxid)
|
||||
std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint256 secret)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx; CPubKey mypk,srcpub,destpub; uint256 txid,hashchain,gensecret,hashblock,entropy,hentropy,prevtxid,param3;
|
||||
struct CCcontract_info *cp,C; int32_t i,funcid,prevdepth,numvouts,numpayments,totalnumpayments;
|
||||
int64_t payment,change,funds,param2;
|
||||
uint8_t hash[32],hashdest[32];
|
||||
CTransaction channelOpenTx,prevTx;
|
||||
|
||||
cp = CCinit(&C,EVAL_CHANNELS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if (GetTransaction(opentxid,channelOpenTx,hashblock,false) == 0)
|
||||
{
|
||||
fprintf(stderr, "invalid channel open txid\n");
|
||||
return ("");
|
||||
}
|
||||
if (AddNormalinputs(mtx,mypk,2*txfee,1) > 0)
|
||||
{
|
||||
if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid)) !=0 && (change=funds-amount-txfee)>=0)
|
||||
{
|
||||
if ((numvouts=channelOpenTx.vout.size()) > 0 && DecodeChannelsOpRet(channelOpenTx.vout[numvouts-1].scriptPubKey, txid, srcpub, destpub, totalnumpayments, payment, hashchain)=='O')
|
||||
{
|
||||
|
||||
if (mypk != srcpub && mypk != destpub)
|
||||
{
|
||||
fprintf(stderr,"this is not our channel\n");
|
||||
return("");
|
||||
}
|
||||
else if (amount % payment != 0)
|
||||
{
|
||||
fprintf(stderr,"invalid amount, not a magnitude of payment size\n");
|
||||
return ("");
|
||||
}
|
||||
numpayments=amount/payment;
|
||||
if (GetTransaction(prevtxid,prevTx,hashblock,false) != 0 && (numvouts=prevTx.vout.size()) > 0 &&
|
||||
((funcid = DecodeChannelsOpRet(prevTx.vout[numvouts-1].scriptPubKey, txid, srcpub, destpub, prevdepth, param2, param3)) != 0) &&
|
||||
(funcid == 'P' || funcid=='O'))
|
||||
{
|
||||
if (secret!=zeroid)
|
||||
{
|
||||
endiancpy(hash, (uint8_t * ) & secret, 32);
|
||||
for (i = 0; i < totalnumpayments-(prevdepth-numpayments); i++)
|
||||
{
|
||||
vcalc_sha256(0, hashdest, hash, 32);
|
||||
memcpy(hash, hashdest, 32);
|
||||
}
|
||||
endiancpy((uint8_t * ) & gensecret, hashdest, 32);
|
||||
if (gensecret!=hashchain)
|
||||
{
|
||||
fprintf(stderr,"invalid secret supplied\n");
|
||||
return("");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hentropy = DiceHashEntropy(entropy, channelOpenTx.vin[0].prevout.hash);
|
||||
if (prevdepth-numpayments)
|
||||
{
|
||||
endiancpy(hash, (uint8_t * ) & hentropy, 32);
|
||||
for (i = 0; i < prevdepth-numpayments; i++)
|
||||
{
|
||||
vcalc_sha256(0, hashdest, hash, 32);
|
||||
memcpy(hash, hashdest, 32);
|
||||
}
|
||||
endiancpy((uint8_t * ) & secret, hashdest, 32);
|
||||
}
|
||||
else endiancpy((uint8_t * ) & secret, (uint8_t * ) & hentropy, 32);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"invalid previous tx\n");
|
||||
return("");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "invalid channel open tx\n");
|
||||
return ("");
|
||||
}
|
||||
mtx.vout.push_back(MakeCC1of2vout(EVAL_CHANNELS, change, mypk, destpub));
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,mypk));
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,destpub));
|
||||
mtx.vout.push_back(CTxOut(amount, CScript() << ParseHex(HexStr(destpub)) << OP_CHECKSIG));
|
||||
return (FinalizeCCTx(0, cp, mtx, mypk, txfee, EncodeChannelsOpRet('P', opentxid, mypk, destpub, prevdepth-numpayments, numpayments, secret)));
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"error adding CC inputs\n");
|
||||
return("");
|
||||
}
|
||||
}
|
||||
fprintf(stderr,"error adding normal inputs\n");
|
||||
return("");
|
||||
}
|
||||
|
||||
std::string ChannelClose(uint64_t txfee,uint256 opentxid)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,srcpub,destpub; struct CCcontract_info *cp,C;
|
||||
CTransaction channelOpenTx;
|
||||
uint256 hashblock,tmp_txid,prevtxid,hashchain;
|
||||
int32_t numvouts,numpayments;
|
||||
int64_t payment,funds;
|
||||
|
||||
// verify this is one of our outbound channels
|
||||
cp = CCinit(&C,EVAL_CHANNELS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if (GetTransaction(opentxid,channelOpenTx,hashblock,false) == 0)
|
||||
{
|
||||
fprintf(stderr, "invalid channel open txid\n");
|
||||
return ("");
|
||||
}
|
||||
if ((numvouts=channelOpenTx.vout.size()) < 1 || DecodeChannelsOpRet(channelOpenTx.vout[numvouts-1].scriptPubKey,tmp_txid,srcpub,destpub,numpayments,payment,hashchain)!='O')
|
||||
{
|
||||
fprintf(stderr, "invalid channel open tx\n");
|
||||
return ("");
|
||||
}
|
||||
if (mypk != srcpub)
|
||||
{
|
||||
fprintf(stderr,"this channel is not in our ownership\n");
|
||||
return("");
|
||||
}
|
||||
if ( AddNormalinputs(mtx,mypk,2*txfee,1) > 0 )
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,mypk));
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('S',mypk,destpub,0,0,zeroid)));
|
||||
if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid)) !=0 && funds-txfee>0)
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1of2vout(EVAL_CHANNELS, funds-txfee, mypk, destpub));
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,mypk));
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,destpub));
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('C',opentxid,mypk,destpub,funds/payment,payment,zeroid)));
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"error adding CC inputs\n");
|
||||
return("");
|
||||
}
|
||||
}
|
||||
fprintf(stderr,"error adding normal inputs\n");
|
||||
return("");
|
||||
}
|
||||
|
||||
std::string ChannelPayment(uint64_t txfee,uint256 prevtxid,uint256 origtxid,int32_t n,int64_t amount)
|
||||
std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,destpub; uint256 secret; struct CCcontract_info *cp,C; int32_t prevdepth;
|
||||
// verify lasttxid and origtxid match and src is me
|
||||
// also verify hashchain depth and amount, set prevdepth
|
||||
cp = CCinit(&C,EVAL_CHANNELS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if ( AddNormalinputs(mtx,mypk,2*txfee,1) > 0 )
|
||||
{
|
||||
// add locked funds inputs
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,mypk));
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('P',mypk,destpub,prevdepth-n,amount,secret)));
|
||||
}
|
||||
return("");
|
||||
}
|
||||
CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C; int64_t funds,payment,param2;
|
||||
int32_t i,numpayments,numvouts,param1;
|
||||
uint256 hashchain,hashblock,txid,prevtxid,param3,entropy,hentropy,secret;
|
||||
CTransaction channelOpenTx,channelCloseTx,prevTx;
|
||||
CPubKey srcpub,destpub;
|
||||
uint8_t funcid,hash[32],hashdest[32];;
|
||||
|
||||
std::string ChannelCollect(uint64_t txfee,uint256 paytxid,uint256 origtxid,int32_t n,int64_t amount)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,senderpub; struct CCcontract_info *cp,C; int32_t prevdepth;
|
||||
// verify paytxid and origtxid match and dest is me
|
||||
// also verify hashchain depth and amount
|
||||
cp = CCinit(&C,EVAL_CHANNELS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if ( AddNormalinputs(mtx,mypk,2*txfee,1) > 0 )
|
||||
{
|
||||
// add locked funds inputs
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,mypk));
|
||||
mtx.vout.push_back(CTxOut(amount,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('C',senderpub,mypk,prevdepth-n,amount,paytxid)));
|
||||
}
|
||||
return("");
|
||||
}
|
||||
|
||||
std::string ChannelRefund(uint64_t txfee,uint256 stoptxid,uint256 origtxid)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C; int64_t amount;
|
||||
// verify stoptxid and origtxid match and are mine
|
||||
cp = CCinit(&C,EVAL_CHANNELS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if (GetTransaction(closetxid,channelCloseTx,hashblock,false) == 0)
|
||||
{
|
||||
fprintf(stderr, "invalid channel close txid\n");
|
||||
return ("");
|
||||
}
|
||||
if ((numvouts=channelCloseTx.vout.size()) < 1 || DecodeChannelsOpRet(channelCloseTx.vout[numvouts-1].scriptPubKey,txid,srcpub,destpub,param1,param2,param3)!='C')
|
||||
{
|
||||
fprintf(stderr, "invalid channel close tx\n");
|
||||
return ("");
|
||||
}
|
||||
if (txid!=opentxid)
|
||||
{
|
||||
fprintf(stderr,"%s - %s\n",txid.ToString().c_str(),opentxid.ToString().c_str());
|
||||
fprintf(stderr, "open and close txid are not from same channel\n");
|
||||
return ("");
|
||||
}
|
||||
if (GetTransaction(opentxid,channelOpenTx,hashblock,false) == 0)
|
||||
{
|
||||
fprintf(stderr, "invalid channel open txid\n");
|
||||
return ("");
|
||||
}
|
||||
if ((numvouts=channelOpenTx.vout.size()) < 1 || DecodeChannelsOpRet(channelOpenTx.vout[numvouts-1].scriptPubKey,txid,srcpub,destpub,numpayments,payment,hashchain)!='O')
|
||||
{
|
||||
fprintf(stderr, "invalid channel open tx\n");
|
||||
return ("");
|
||||
}
|
||||
if (mypk != srcpub)
|
||||
{
|
||||
fprintf(stderr,"this channel is not in our ownership\n");
|
||||
return("");
|
||||
}
|
||||
if ( AddNormalinputs(mtx,mypk,2*txfee,1) > 0 )
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,mypk));
|
||||
mtx.vout.push_back(CTxOut(amount,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('R',mypk,mypk,0,0,stoptxid)));
|
||||
if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid)) !=0 && funds-txfee>0)
|
||||
{
|
||||
if ((GetTransaction(prevtxid,prevTx,hashblock,false) != 0) && (numvouts=prevTx.vout.size()) > 0 && DecodeChannelsOpRet(prevTx.vout[numvouts-1].scriptPubKey, txid, srcpub, destpub, param1, param2, param3) != 0)
|
||||
{
|
||||
hentropy = DiceHashEntropy(entropy, channelOpenTx.vin[0].prevout.hash);
|
||||
endiancpy(hash, (uint8_t * ) & hentropy, 32);
|
||||
for (i = 0; i < param1; i++)
|
||||
{
|
||||
vcalc_sha256(0, hashdest, hash, 32);
|
||||
memcpy(hash, hashdest, 32);
|
||||
}
|
||||
endiancpy((uint8_t * ) & secret, hashdest, 32);
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,mypk));
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,destpub));
|
||||
mtx.vout.push_back(CTxOut(funds-txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('R',opentxid,mypk,destpub,param1,payment,closetxid)));
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"previous tx is invalid\n");
|
||||
return("");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"error adding CC inputs\n");
|
||||
return("");
|
||||
}
|
||||
}
|
||||
return("");
|
||||
}
|
||||
|
||||
UniValue ChannelsInfo()
|
||||
UniValue ChannelsInfo(uint256 channeltxid)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); CTransaction tx; uint256 txid,hashBlock,hashchain; struct CCcontract_info *cp,C; uint8_t funcid; char myCCaddr[64]; int32_t vout,numvouts,numpayments; int64_t nValue,payment; CPubKey srcpub,destpub,mypk;
|
||||
UniValue result(UniValue::VOBJ); CTransaction tx,opentx; uint256 txid,tmp_txid,hashBlock,param3,opentxid,hashchain,prevtxid;
|
||||
struct CCcontract_info *cp,C; char myCCaddr[64],addr[64],str1[256],str2[64]; int32_t vout,numvouts,param1,numpayments;
|
||||
int64_t nValue,param2,payment; CPubKey srcpub,destpub,mypk;
|
||||
std::vector<std::pair<CAddressIndexKey, CAmount> > txids;
|
||||
|
||||
result.push_back(Pair("result","success"));
|
||||
result.push_back(Pair("name","Channels"));
|
||||
cp = CCinit(&C,EVAL_CHANNELS);
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
GetCCaddress(cp,myCCaddr,mypk);
|
||||
SetCCtxids(txids,myCCaddr);
|
||||
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=txids.begin(); it!=txids.end(); it++)
|
||||
if (channeltxid==zeroid)
|
||||
{
|
||||
//int height = it->first.blockHeight;
|
||||
txid = it->first.txhash;
|
||||
vout = (int32_t)it->first.index;
|
||||
nValue = (int64_t)it->second;
|
||||
if ( (vout == 1 || vout == 2) && nValue == 10000 && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 )
|
||||
result.push_back(Pair("name","Channels Info"));
|
||||
GetCCaddress(cp,myCCaddr,mypk);
|
||||
SetCCtxids(txids,myCCaddr);
|
||||
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=txids.begin(); it!=txids.end(); it++)
|
||||
{
|
||||
if ( DecodeChannelsOpRet(txid,tx.vout[numvouts-1].scriptPubKey,srcpub,destpub,numpayments,payment,hashchain) == 'O' || funcid == 'P' )
|
||||
//int height = it->first.blockHeight;
|
||||
txid = it->first.txhash;
|
||||
vout = (int32_t)it->first.index;
|
||||
nValue = (int64_t)it->second;
|
||||
if ( (vout == 1 || vout == 2) && nValue == 10000 && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 )
|
||||
{
|
||||
char str[67],str2[67];
|
||||
fprintf(stderr,"%s func.%c %s -> %s %.8f num.%d of %.8f\n",mypk == srcpub ? "send" : "recv",funcid,pubkey33_str(str,(uint8_t *)&srcpub),pubkey33_str(str2,(uint8_t *)&destpub),(double)tx.vout[0].nValue/COIN,numpayments,(double)payment/COIN);
|
||||
if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,tmp_txid,srcpub,destpub,param1,param2,param3) == 'O')
|
||||
{
|
||||
GetCCaddress1of2(cp,addr,srcpub,destpub);
|
||||
sprintf(str1,"%s - %lld payments of %lld satoshi - %s",addr,(long long)param1,(long long)param2,tx.GetHash().ToString().c_str());
|
||||
result.push_back(Pair("Channel", str1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetTransaction(channeltxid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 &&
|
||||
(DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,opentxid,srcpub,destpub,param1,param2,param3) == 'O'))
|
||||
{
|
||||
GetCCaddress1of2(cp,addr,srcpub,destpub);
|
||||
sprintf(str1,"Channel %s",addr);
|
||||
result.push_back(Pair("name",str1));
|
||||
SetCCtxids(txids,addr);
|
||||
prevtxid=zeroid;
|
||||
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=txids.begin(); it!=txids.end(); it++)
|
||||
{
|
||||
|
||||
txid = it->first.txhash;
|
||||
if (txid!=prevtxid && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 )
|
||||
{
|
||||
if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,tmp_txid,srcpub,destpub,param1,param2,param3) == 'O' && tx.GetHash()==channeltxid)
|
||||
{
|
||||
sprintf(str1,"%lld payments of %lld satoshi",(long long)param1,(long long)param2);
|
||||
result.push_back(Pair("Open", str1));
|
||||
}
|
||||
else if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,opentxid,srcpub,destpub,param1,param2,param3) == 'P' && opentxid==channeltxid)
|
||||
{
|
||||
if (GetTransaction(opentxid,opentx,hashBlock,false) != 0 && (numvouts=opentx.vout.size()) > 0 && DecodeChannelsOpRet(opentx.vout[numvouts-1].scriptPubKey,tmp_txid,srcpub,destpub,numpayments,payment,hashchain) == 'O')
|
||||
{
|
||||
Getscriptaddress(str2,tx.vout[3].scriptPubKey);
|
||||
sprintf(str1,"%lld satoshi to %s, %lld payments left",(long long)(param2*payment),str2,(long long)param1);
|
||||
result.push_back(Pair("Payment",str1));
|
||||
}
|
||||
}
|
||||
else if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,opentxid,srcpub,destpub,param1,param2,param3) == 'C' && opentxid==channeltxid)
|
||||
{
|
||||
result.push_back(Pair("Close","channel"));
|
||||
}
|
||||
else if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,opentxid,srcpub,destpub,param1,param2,param3) == 'R' && opentxid==channeltxid)
|
||||
{
|
||||
Getscriptaddress(str2,tx.vout[2].scriptPubKey);
|
||||
sprintf(str1,"%lld satoshi back to %s",(long long)(param1*param2),str2);
|
||||
result.push_back(Pair("Refund",str1));
|
||||
}
|
||||
}
|
||||
prevtxid=txid;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -464,10 +464,10 @@ int32_t get_coinheader(char *refcoin,char *acname,bits256 *blockhashp,bits256 *m
|
||||
return(0);
|
||||
}
|
||||
|
||||
cJSON *get_gatewayspending(char *refcoin,char *acname,char *oraclestxidstr)
|
||||
cJSON *get_gatewayspending(char *refcoin,char *acname,char *bindtxidstr)
|
||||
{
|
||||
cJSON *retjson; char *retstr;
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"gatewayspending",oraclestxidstr,refcoin,"","")) != 0 )
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"gatewayspending",bindtxidstr,refcoin,"","")) != 0 )
|
||||
{
|
||||
//printf("pending.(%s)\n",jprint(retjson,0));
|
||||
return(retjson);
|
||||
|
||||
@@ -311,14 +311,14 @@ int64_t AddGatewaysInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP
|
||||
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
|
||||
{
|
||||
Getscriptaddress(destaddr,vintx.vout[vout].scriptPubKey);
|
||||
//fprintf(stderr,"%s vout.%d %.8f %.8f\n",destaddr,vout,(double)vintx.vout[vout].nValue/COIN,(double)it->second.satoshis/COIN);
|
||||
fprintf(stderr,"check %s vout.%d %.8f %.8f\n",destaddr,vout,(double)vintx.vout[vout].nValue/COIN,(double)it->second.satoshis/COIN);
|
||||
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);
|
||||
//char str[65],str2[65]; fprintf(stderr,"vout.%d %d:%d (%c) check for refassetid.%s vs %s %.8f\n",vout,evalcode,cp->evalcode,funcid,uint256_str(str,refassetid),uint256_str(str2,assetid),(double)vintx.vout[vout].nValue/COIN);
|
||||
char str[65],str2[65]; fprintf(stderr,"vout.%d %d:%d (%c) check for refassetid.%s vs %s %.8f\n",vout,evalcode,cp->evalcode,funcid,uint256_str(str,refassetid),uint256_str(str2,assetid),(double)vintx.vout[vout].nValue/COIN);
|
||||
if ( assetid == refassetid && funcid == 't' && (nValue= vintx.vout[vout].nValue) > 0 && myIsutxo_spentinmempool(txid,vout) == 0 )
|
||||
{
|
||||
//fprintf(stderr,"total %llu maxinputs.%d %.8f\n",(long long)total,maxinputs,(double)it->second.satoshis/COIN);
|
||||
@@ -426,7 +426,7 @@ UniValue GatewaysInfo(uint256 bindtxid)
|
||||
result.push_back(Pair("tokenid",uint256_str(str,tokenid)));
|
||||
sprintf(numstr,"%.8f",(double)totalsupply/COIN);
|
||||
result.push_back(Pair("totalsupply",numstr));
|
||||
remaining = CCaddress_balance(gatewaysassets);
|
||||
remaining = CCtoken_balance(gatewaysassets,tokenid);
|
||||
sprintf(numstr,"%.8f",(double)remaining/COIN);
|
||||
result.push_back(Pair("remaining",numstr));
|
||||
sprintf(numstr,"%.8f",(double)(totalsupply - remaining)/COIN);
|
||||
@@ -704,7 +704,7 @@ std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std::
|
||||
}
|
||||
if ( AddNormalinputs(mtx,mypk,3*txfee,60) > 0 )
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,mypk));
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,destpub));
|
||||
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(CCtxidaddr(txidaddr,cointxid))) << OP_CHECKSIG));
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeGatewaysOpRet('D',coin,bindtxid,publishers,txids,height,cointxid,deposithex,proof,destpub,amount)));
|
||||
}
|
||||
@@ -714,7 +714,7 @@ 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)
|
||||
{
|
||||
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];
|
||||
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],destaddr[64];
|
||||
cp = CCinit(&C,EVAL_GATEWAYS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -747,6 +747,8 @@ std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,ui
|
||||
{
|
||||
if ( inputs > amount )
|
||||
CCchange = (inputs - amount);
|
||||
_GetCCaddress(destaddr,EVAL_GATEWAYS,mypk);
|
||||
printf("expecting deposittxid/v0 to be to %s\n",destaddr);
|
||||
mtx.vin.push_back(CTxIn(deposittxid,0,CScript())); // triggers EVAL_GATEWAYS validation
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,amount,mypk)); // transfer back to normal token
|
||||
if ( CCchange != 0 )
|
||||
|
||||
@@ -666,6 +666,7 @@ int64_t AddOracleInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
GetCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
fprintf(stderr,"addoracleinputs from (%s)\n",coinaddr);
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
@@ -804,7 +805,7 @@ std::string OracleData(int64_t txfee,uint256 oracletxid,std::vector <uint8_t> da
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,batonpk));
|
||||
mtx.vout.push_back(CTxOut(datafee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeOraclesData('D',oracletxid,batontxid,mypk,data)));
|
||||
} else fprintf(stderr,"couldnt find enough oracle inputs, limit 1 per utxo\n");
|
||||
} else fprintf(stderr,"couldnt find enough oracle inputs %s, limit 1 per utxo\n",coinaddr);
|
||||
} else fprintf(stderr,"couldnt add normal inputs\n");
|
||||
return("");
|
||||
}
|
||||
|
||||
@@ -55,6 +55,8 @@
|
||||
|
||||
exposure address, funds address
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// start of consensus code
|
||||
@@ -138,7 +140,7 @@ int64_t AddTokensInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,char
|
||||
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 && vout < vintx.vout.size() )
|
||||
{
|
||||
// need to verify assetid
|
||||
if ( (nValue= vintx.vout[vout].nValue) > 10000 && myIsutxo_spentinmempool(txid,vout) == 0 )
|
||||
if ( (nValue= vintx.vout[vout].nValue) >= 10000 && myIsutxo_spentinmempool(txid,vout) == 0 )
|
||||
{
|
||||
if ( total != 0 && maxinputs != 0 )
|
||||
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
||||
@@ -179,7 +181,7 @@ UniValue PricesList()
|
||||
// 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; 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;
|
||||
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;
|
||||
if ( funding < 100*COIN || maxleverage <= 0 || maxleverage > 10000 )
|
||||
{
|
||||
CCerror = "invalid parameter error";
|
||||
@@ -187,7 +189,6 @@ std::string PricesCreateFunding(uint64_t txfee,uint256 bettoken,uint256 oracletx
|
||||
return("");
|
||||
}
|
||||
cp = CCinit(&C,EVAL_PRICES);
|
||||
assetscp = CCinit(&C2,EVAL_ASSETS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
@@ -243,9 +244,8 @@ std::string PricesCreateFunding(uint64_t txfee,uint256 bettoken,uint256 oracletx
|
||||
|
||||
UniValue PricesInfo(uint256 fundingtxid)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
cp = CCinit(&C,EVAL_PRICES);
|
||||
assetscp = CCinit(&C2,EVAL_ASSETS);
|
||||
pricespk = GetUnspendable(cp,0);
|
||||
if ( GetTransaction(fundingtxid,vintx,hashBlock,false) == 0 )
|
||||
{
|
||||
@@ -266,8 +266,8 @@ UniValue PricesInfo(uint256 fundingtxid)
|
||||
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
|
||||
GetCCaddress1of2(cp,houseaddr,pricespk,planpk);
|
||||
GetCCaddress1of2(cp,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)));
|
||||
@@ -292,7 +292,7 @@ UniValue PricesInfo(uint256 fundingtxid)
|
||||
|
||||
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;
|
||||
CMutableTransaction mtx; struct CCcontract_info *cp,C; 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";
|
||||
@@ -300,12 +300,11 @@ std::string PricesAddFunding(uint64_t txfee,uint256 refbettoken,uint256 fundingt
|
||||
return("");
|
||||
}
|
||||
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);
|
||||
GetCCaddress(cp,myaddr,mypk);
|
||||
if ( GetTransaction(fundingtxid,tx,hashBlock,false) == 0 )
|
||||
{
|
||||
fprintf(stderr,"cant find fundingtxid\n");
|
||||
@@ -313,16 +312,16 @@ std::string PricesAddFunding(uint64_t txfee,uint256 refbettoken,uint256 fundingt
|
||||
}
|
||||
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 )
|
||||
{
|
||||
GetCCaddress1of2(assetscp,houseaddr,pricespk,planpk);
|
||||
GetCCaddress1of2(cp,houseaddr,pricespk,planpk);
|
||||
if ( AddNormalinputs(mtx,mypk,2*txfee,3) > 0 )
|
||||
{
|
||||
if ( (inputs= AddTokensInputs(assetscp,mtx,myaddr,bettoken,amount,60)) >= amount )
|
||||
if ( (inputs= AddTokensInputs(cp,mtx,myaddr,bettoken,amount,60)) >= amount )
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1of2vout(assetscp->evalcode,amount,pricespk,planpk));
|
||||
mtx.vout.push_back(MakeCC1of2vout(cp->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));
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,mypk));
|
||||
// add addr2
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetOpRet('t',bettoken,zeroid,0,Mypubkey())));
|
||||
}
|
||||
@@ -343,19 +342,18 @@ std::string PricesAddFunding(uint64_t txfee,uint256 refbettoken,uint256 fundingt
|
||||
|
||||
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;
|
||||
CMutableTransaction mtx; struct CCcontract_info *cp,C; 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);
|
||||
GetCCaddress(cp,myaddr,mypk);
|
||||
if ( GetTransaction(fundingtxid,tx,hashBlock,false) == 0 )
|
||||
{
|
||||
fprintf(stderr,"cant find fundingtxid\n");
|
||||
@@ -368,8 +366,8 @@ std::string PricesBet(uint64_t txfee,uint256 refbettoken,uint256 fundingtxid,int
|
||||
fprintf(stderr,"illegal leverage\n");
|
||||
return("");
|
||||
}
|
||||
GetCCaddress1of2(assetscp,houseaddr,pricespk,planpk);
|
||||
GetCCaddress1of2(assetscp,exposureaddr,pricespk,pricespk);
|
||||
GetCCaddress1of2(cp,houseaddr,pricespk,planpk);
|
||||
GetCCaddress1of2(cp,exposureaddr,pricespk,pricespk);
|
||||
if ( dir < 0 )
|
||||
tokenid = shorttoken;
|
||||
else tokenid = longtoken;
|
||||
@@ -387,22 +385,22 @@ std::string PricesBet(uint64_t txfee,uint256 refbettoken,uint256 fundingtxid,int
|
||||
}
|
||||
if ( AddNormalinputs(mtx,mypk,txfee,3) > 0 )
|
||||
{
|
||||
if ( (inputs= AddTokensInputs(assetscp,mtx,houseaddr,tokenid,exposure,30)) >= exposure )
|
||||
if ( (inputs= AddTokensInputs(cp,mtx,houseaddr,tokenid,exposure,30)) >= exposure )
|
||||
{
|
||||
if ( (inputs2= AddTokensInputs(assetscp,mtx,myaddr,bettoken,amount,30)) >= amount )
|
||||
if ( (inputs2= AddTokensInputs(cp,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));
|
||||
mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,amount,pricespk,planpk));
|
||||
mtx.vout.push_back(MakeCC1of2vout(cp->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));
|
||||
mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,CCchange,pricespk,planpk));
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange2,mypk));
|
||||
// add addr2 and addr3
|
||||
//return(FinalizeCCTx(0,assetscp,mtx,mypk,txfee,EncodePricesExtra('T',tokenid,bettoken,zeroid,dir*leverage)));
|
||||
//return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodePricesExtra('T',tokenid,bettoken,zeroid,dir*leverage)));
|
||||
CScript opret;
|
||||
return(FinalizeCCTx(0,assetscp,mtx,mypk,txfee,opret));
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1284,7 +1284,7 @@ uint32_t komodo_stake(int32_t validateflag,arith_uint256 bnTarget,int32_t nHeigh
|
||||
|
||||
arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc)
|
||||
{
|
||||
int32_t oldflag = 0;
|
||||
int32_t oldflag = 0,dispflag = 0;
|
||||
CBlockIndex *pindex; arith_uint256 easydiff,bnTarget,hashval,sum,ave; bool fNegative,fOverflow; int32_t i,n,m,ht,percPoS,diff,val;
|
||||
*percPoSp = percPoS = 0;
|
||||
if ( height <= 10 || (ASSETCHAINS_STAKED == 100 && height <= 100) )
|
||||
@@ -1303,23 +1303,23 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he
|
||||
{
|
||||
n++;
|
||||
percPoS++;
|
||||
if ( ASSETCHAINS_STAKED < 100 )
|
||||
if ( dispflag != 0 && ASSETCHAINS_STAKED < 100 )
|
||||
fprintf(stderr,"0");
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ASSETCHAINS_STAKED < 100 )
|
||||
if ( dispflag != 0 && ASSETCHAINS_STAKED < 100 )
|
||||
fprintf(stderr,"1");
|
||||
sum += UintToArith256(pindex->GetBlockHash());
|
||||
m++;
|
||||
}
|
||||
}
|
||||
if ( ASSETCHAINS_STAKED < 100 && (i % 10) == 9 )
|
||||
if ( dispflag != 0 && ASSETCHAINS_STAKED < 100 && (i % 10) == 9 )
|
||||
fprintf(stderr," %d, ",percPoS);
|
||||
}
|
||||
if ( m+n < 100 )
|
||||
percPoS = ((percPoS * n) + (goalperc * (100-n))) / 100;
|
||||
if ( ASSETCHAINS_STAKED < 100 )
|
||||
if ( dispflag != 0 && ASSETCHAINS_STAKED < 100 )
|
||||
fprintf(stderr," -> %d%% percPoS vs goalperc.%d ht.%d\n",percPoS,goalperc,height);
|
||||
*percPoSp = percPoS;
|
||||
if ( m > 0 )
|
||||
@@ -1332,12 +1332,10 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he
|
||||
percPoS = 1;
|
||||
if ( percPoS < goalperc ) // increase PoW diff -> lower bnTarget
|
||||
{
|
||||
//if ( oldflag != 0 )
|
||||
// bnTarget = (ave * arith_uint256(percPoS * percPoS)) / arith_uint256(goalperc * goalperc * goalperc);
|
||||
if ( oldflag != 0 )
|
||||
bnTarget = (ave / arith_uint256(goalperc * goalperc * goalperc)) * arith_uint256(percPoS * percPoS);
|
||||
else bnTarget = (ave / arith_uint256(goalperc * goalperc * goalperc * goalperc)) * arith_uint256(percPoS * percPoS);
|
||||
if ( ASSETCHAINS_STAKED < 100 )
|
||||
if ( dispflag != 0 && ASSETCHAINS_STAKED < 100 )
|
||||
{
|
||||
for (i=31; i>=24; i--)
|
||||
fprintf(stderr,"%02x",((uint8_t *)&ave)[i]);
|
||||
@@ -1355,7 +1353,6 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he
|
||||
if ( oldflag != 0 )
|
||||
{
|
||||
bnTarget = ((ave * arith_uint256(goalperc)) + (easydiff * arith_uint256(percPoS))) / arith_uint256(percPoS + goalperc);
|
||||
//bnTarget = (bnTarget * arith_uint256(percPoS * percPoS * percPoS)) / arith_uint256(goalperc * goalperc);
|
||||
bnTarget = (bnTarget / arith_uint256(goalperc * goalperc)) * arith_uint256(percPoS * percPoS * percPoS);
|
||||
}
|
||||
else bnTarget = (ave / arith_uint256(goalperc * goalperc)) * arith_uint256(percPoS * percPoS * percPoS);
|
||||
@@ -1367,7 +1364,7 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he
|
||||
if ( bnTarget < ave )
|
||||
bnTarget = ave;
|
||||
}
|
||||
if ( 1 )
|
||||
if ( dispflag != 0 )
|
||||
{
|
||||
for (i=31; i>=24; i--)
|
||||
fprintf(stderr,"%02x",((uint8_t *)&ave)[i]);
|
||||
|
||||
@@ -1877,9 +1877,11 @@ CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
|
||||
{
|
||||
if ( nHeight == 1 )
|
||||
return(100000000 * COIN); // ICO allocation
|
||||
else if ( nHeight < KOMODO_ENDOFERA ) //komodo_moneysupply(nHeight) < MAX_MONEY )
|
||||
else if ( nHeight < KOMODO_ENDOFERA )
|
||||
return(3 * COIN);
|
||||
else return(0);
|
||||
else if ( nHeight < 2*KOMODO_ENDOFERA )
|
||||
return(2 * COIN);
|
||||
else return(COIN);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -477,7 +477,7 @@ int32_t gettxout_scriptPubKey(uint8_t *scriptPubKey,int32_t maxsize,uint256 txid
|
||||
uint256 hashBlock;
|
||||
if ( GetTransaction(txid,tx,hashBlock,false) == 0 )
|
||||
return(-1);
|
||||
else if ( n <= tx.vout.size() ) // vout.size() seems off by 1
|
||||
else if ( n < tx.vout.size() )
|
||||
{
|
||||
ptr = (uint8_t *)tx.vout[n].scriptPubKey.data();
|
||||
m = tx.vout[n].scriptPubKey.size();
|
||||
|
||||
@@ -383,8 +383,7 @@ static const CRPCCommand vRPCCommands[] =
|
||||
{ "channels", "channelsinfo", &channelsinfo, true },
|
||||
{ "channels", "channelsopen", &channelsopen, true },
|
||||
{ "channels", "channelspayment", &channelspayment, true },
|
||||
{ "channels", "channelscollect", &channelscollect, true },
|
||||
{ "channels", "channelsstop", &channelsstop, true },
|
||||
{ "channels", "channelsclose", &channelsclose, true },
|
||||
{ "channels", "channelsrefund", &channelsrefund, true },
|
||||
|
||||
/* Oracles */
|
||||
|
||||
@@ -254,11 +254,9 @@ extern UniValue gatewayspending(const UniValue& params, bool fHelp);
|
||||
extern UniValue gatewaysmarkdone(const UniValue& params, bool fHelp);
|
||||
extern UniValue gatewaysmultisig(const UniValue& params, bool fHelp);
|
||||
extern UniValue channelsinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue channelsbind(const UniValue& params, bool fHelp);
|
||||
extern UniValue channelsopen(const UniValue& params, bool fHelp);
|
||||
extern UniValue channelspayment(const UniValue& params, bool fHelp);
|
||||
extern UniValue channelscollect(const UniValue& params, bool fHelp);
|
||||
extern UniValue channelsstop(const UniValue& params, bool fHelp);
|
||||
extern UniValue channelsclose(const UniValue& params, bool fHelp);
|
||||
extern UniValue channelsrefund(const UniValue& params, bool fHelp);
|
||||
|
||||
//extern UniValue tokenswapask(const UniValue& params, bool fHelp);
|
||||
|
||||
@@ -5147,11 +5147,15 @@ UniValue tokenaddress(const UniValue& params, bool fHelp)
|
||||
|
||||
UniValue channelsinfo(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if ( fHelp || params.size() != 0 )
|
||||
throw runtime_error("channelsinfo\n");
|
||||
uint256 opentxid;
|
||||
if ( fHelp || params.size() > 1 )
|
||||
throw runtime_error("channelsinfo [opentxid]\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(ChannelsInfo());
|
||||
opentxid=zeroid;
|
||||
if (params.size() > 0 && !params[0].isNull() && !params[0].get_str().empty())
|
||||
opentxid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
return(ChannelsInfo(opentxid));
|
||||
}
|
||||
|
||||
UniValue channelsopen(const UniValue& params, bool fHelp)
|
||||
@@ -5176,42 +5180,23 @@ UniValue channelsopen(const UniValue& params, bool fHelp)
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue channelsstop(const UniValue& params, bool fHelp)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); std::vector<unsigned char> destpub; struct CCcontract_info *cp,C; std::string hex; uint256 origtxid;
|
||||
cp = CCinit(&C,EVAL_CHANNELS);
|
||||
if ( fHelp || params.size() != 2 )
|
||||
throw runtime_error("channelsstop destpubkey origtxid\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);
|
||||
destpub = ParseHex(params[0].get_str().c_str());
|
||||
origtxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
hex = ChannelStop(0,pubkey2pk(destpub),origtxid);
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
result.push_back(Pair("hex", hex));
|
||||
} else ERR_RESULT("couldnt create channelsstop transaction");
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue channelspayment(const UniValue& params, bool fHelp)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); struct CCcontract_info *cp,C; std::string hex; uint256 origtxid,prevtxid; int32_t n; int64_t amount;
|
||||
UniValue result(UniValue::VOBJ); struct CCcontract_info *cp,C; std::string hex; uint256 opentxid,secret=zeroid; int32_t n; int64_t amount;
|
||||
cp = CCinit(&C,EVAL_CHANNELS);
|
||||
if ( fHelp || params.size() != 4 )
|
||||
throw runtime_error("channelspayment prevtxid origtxid n amount\n");
|
||||
if ( fHelp || params.size() != 2 )
|
||||
throw runtime_error("channelspayment opentxid amount [secret]\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);
|
||||
prevtxid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
origtxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
n = atoi((char *)params[2].get_str().c_str());
|
||||
amount = atoi((char *)params[3].get_str().c_str());
|
||||
hex = ChannelPayment(0,prevtxid,origtxid,n,amount);
|
||||
opentxid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
amount = atoi((char *)params[1].get_str().c_str());
|
||||
if (params.size() > 2 && !params[2].isNull() && !params[2].get_str().empty())
|
||||
{
|
||||
secret = Parseuint256((char *)params[2].get_str().c_str());
|
||||
}
|
||||
hex = ChannelPayment(0,opentxid,amount,secret);
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
@@ -5220,42 +5205,39 @@ UniValue channelspayment(const UniValue& params, bool fHelp)
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue channelscollect(const UniValue& params, bool fHelp)
|
||||
UniValue channelsclose(const UniValue& params, bool fHelp)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); struct CCcontract_info *cp,C; std::string hex; uint256 origtxid,paytxid; int32_t n; int64_t amount;
|
||||
UniValue result(UniValue::VOBJ); struct CCcontract_info *cp,C; std::string hex; uint256 opentxid;
|
||||
cp = CCinit(&C,EVAL_CHANNELS);
|
||||
if ( fHelp || params.size() != 4 )
|
||||
throw runtime_error("channelscollect paytxid origtxid n amount\n");
|
||||
if ( fHelp || params.size() != 1 )
|
||||
throw runtime_error("channelsclose opentxid\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);
|
||||
paytxid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
origtxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
n = atoi((char *)params[2].get_str().c_str());
|
||||
amount = atoi((char *)params[3].get_str().c_str());
|
||||
hex = ChannelCollect(0,paytxid,origtxid,n,amount);
|
||||
opentxid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
hex = ChannelClose(0,opentxid);
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
result.push_back(Pair("hex", hex));
|
||||
} else ERR_RESULT("couldnt create channelscollect transaction");
|
||||
} else ERR_RESULT("couldnt create channelsclose transaction");
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue channelsrefund(const UniValue& params, bool fHelp)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); struct CCcontract_info *cp,C; std::string hex; uint256 origtxid,stoptxid;
|
||||
UniValue result(UniValue::VOBJ); struct CCcontract_info *cp,C; std::string hex; uint256 opentxid,closetxid;
|
||||
cp = CCinit(&C,EVAL_CHANNELS);
|
||||
if ( fHelp || params.size() != 2 )
|
||||
throw runtime_error("channelsrefund stoptxid origtxid\n");
|
||||
throw runtime_error("channelsrefund opentxid closetxid\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);
|
||||
stoptxid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
origtxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
hex = ChannelRefund(0,stoptxid,origtxid);
|
||||
opentxid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
closetxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
hex = ChannelRefund(0,opentxid,closetxid);
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
@@ -5577,7 +5559,7 @@ UniValue gatewayswithdraw(const UniValue& params, bool fHelp)
|
||||
UniValue gatewaysmarkdone(const UniValue& params, bool fHelp)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); uint256 withdrawtxid,cointxid; std::string hex,coin;
|
||||
if ( fHelp || params.size() != 1 )
|
||||
if ( fHelp || params.size() != 3 )
|
||||
throw runtime_error("gatewaysmarkdone withdrawtxid coin cointxid\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");
|
||||
|
||||
Reference in New Issue
Block a user