diff --git a/src/cc/CCchannels.h b/src/cc/CCchannels.h index 9f84ba753..a1c51204d 100644 --- a/src/cc/CCchannels.h +++ b/src/cc/CCchannels.h @@ -22,6 +22,10 @@ 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,uint64_t amount); +std::string ChannelRefund(uint64_t txfee,uint256 stoptxid,uint256 origtxid); // CCcustom UniValue ChannelsInfo(); diff --git a/src/cc/channels.cpp b/src/cc/channels.cpp index ae446766c..c5991a0ba 100644 --- a/src/cc/channels.cpp +++ b/src/cc/channels.cpp @@ -237,6 +237,74 @@ std::string ChannelOpen(uint64_t txfee,CPubKey destpub,int32_t numpayments,int64 return(""); } +std::string ChannelStop(uint64_t txfee,CPubKey destpub,uint256 origtxid) +{ + CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C; + // verify this is one of our outbound channels + cp = CCinit(&C,EVAL_CHANNELS); + if ( txfee == 0 ) + txfee = 10000; + mypk = pubkey2pk(Mypubkey()); + 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))); + } + return(""); +} + +std::string ChannelPayment(uint64_t txfee,uint256 prevtxid,uint256 origtxid,int32_t numpayments,uint64_t amount) +{ + CMutableTransaction mtx; CPubKey mypk,destpub; 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-depth,amount,secret))); + } + return(""); +} + +std::string ChannelCollect(uint64_t txfee,uint256 paytxid,uint256 origtxid,int32_t n,uint64_t amount) +{ + CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C; + // 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)); + return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('C',senderpub,mypk,prevdepth-depth,amount,paytxid))); + } + return(""); +} + +std::string ChannelRefund(uint64_t txfee,uint256 stoptxid,uint256 origtxid) +{ + CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C; + // verify stoptxid and origtxid match and are mine + cp = CCinit(&C,EVAL_CHANNELS); + if ( txfee == 0 ) + txfee = 10000; + mypk = pubkey2pk(Mypubkey()); + 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('R',mypk,mypk,0,0,stoptxid))); + } + return(""); +} + UniValue ChannelsInfo() { 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; @@ -265,3 +333,4 @@ UniValue ChannelsInfo() return(result); } +// ChannelPayment() diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index eb6aa9b34..8b15a39c8 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -378,6 +378,10 @@ static const CRPCCommand vRPCCommands[] = { "channels", "channelsaddress", &channelsaddress, true }, { "channels", "channelsinfo", &channelsinfo, true }, { "channels", "channelsopen", &channelsopen, true }, + { "channels", "channelspayment", &channelspayment, true }, + { "channels", "channelscollect", &channelscollect, true }, + { "channels", "channelsstop", &channelsstop, true }, + { "channels", "channelsrefund", &channelsrefund, true }, /* Oracles */ { "oracles", "oraclesaddress", &oraclesaddress, true }, diff --git a/src/rpcserver.h b/src/rpcserver.h index 0f3744681..ee7c962c4 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -231,6 +231,10 @@ extern UniValue paymentsaddress(const UniValue& params, bool fHelp); extern UniValue gatewaysaddress(const UniValue& params, bool fHelp); extern UniValue channelsinfo(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 channelsrefund(const UniValue& params, bool fHelp); //extern UniValue tokenswapask(const UniValue& params, bool fHelp); //extern UniValue tokenfillswap(const UniValue& params, bool fHelp); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 945c30dea..0311006c6 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5096,7 +5096,7 @@ UniValue channelsinfo(const UniValue& params, bool fHelp) UniValue channelsopen(const UniValue& params, bool fHelp) { - UniValue result(UniValue::VOBJ); char destaddr[64]; int32_t numpayments; int64_t payment; std::vector destpub; struct CCcontract_info *cp,C; std::string hex; + UniValue result(UniValue::VOBJ); int32_t numpayments; int64_t payment; std::vector destpub; struct CCcontract_info *cp,C; std::string hex; cp = CCinit(&C,EVAL_CHANNELS); if ( fHelp || params.size() != 3 ) throw runtime_error("channelsopen destpubkey numpayments payment\n"); @@ -5115,6 +5115,90 @@ UniValue channelsopen(const UniValue& params, bool fHelp) return(result); } +UniValue channelsstop(const UniValue& params, bool fHelp) +{ + UniValue result(UniValue::VOBJ); std::vector 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"); + LOCK(cs_main); + 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; + cp = CCinit(&C,EVAL_CHANNELS); + if ( fHelp || params.size() != 4 ) + throw runtime_error("channelspayment prevtxid origtxid n 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"); + LOCK(cs_main); + 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,stoptxid,origtxid,n,amount); + if ( hex.size() > 0 ) + { + result.push_back(Pair("result", "success")); + result.push_back(Pair("hex", hex)); + } else ERR_RESULT("couldnt create channelspayment transaction"); + return(result); +} + +UniValue channelscollect(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; + cp = CCinit(&C,EVAL_CHANNELS); + if ( fHelp || params.size() != 4 ) + throw runtime_error("channelscollect prevtxid origtxid n 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"); + LOCK(cs_main); + 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 = ChannelCollect(0,stoptxid,origtxid,n,amount); + if ( hex.size() > 0 ) + { + result.push_back(Pair("result", "success")); + result.push_back(Pair("hex", hex)); + } else ERR_RESULT("couldnt create channelscollect 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; + cp = CCinit(&C,EVAL_CHANNELS); + if ( fHelp || params.size() != 2 ) + throw runtime_error("channelsrefund stoptxid 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"); + LOCK(cs_main); + stoptxid = Parseuint256((char *)params[0].get_str().c_str()); + origtxid = Parseuint256((char *)params[1].get_str().c_str()); + hex = ChannelRefund(0,stoptxid,origtxid); + if ( hex.size() > 0 ) + { + result.push_back(Pair("result", "success")); + result.push_back(Pair("hex", hex)); + } else ERR_RESULT("couldnt create channelsrefund transaction"); + return(result); +} + UniValue rewardscreatefunding(const UniValue& params, bool fHelp) { UniValue result(UniValue::VOBJ); char *name; int64_t funds,APR,minseconds,maxseconds,mindeposit; std::string hex;