From de7a5fb6d732e3dc905815dc5724372675b19b45 Mon Sep 17 00:00:00 2001 From: Duke Date: Fri, 12 Jan 2024 20:47:46 -0500 Subject: [PATCH] remove cc payments and rewards --- src/Makefile.am | 2 - src/cc/CCPayments.h | 46 -- src/cc/CCcustom.cpp | 10 +- src/cc/CCrewards.h | 38 - src/cc/Makefile_rogue | 38 - src/cc/payments.cpp | 1572 -------------------------------------- src/cc/rewards.cpp | 756 ------------------ src/rpc/server.cpp | 21 - src/rpc/server.h | 17 - src/wallet/rpcwallet.cpp | 334 -------- 10 files changed, 4 insertions(+), 2830 deletions(-) delete mode 100644 src/cc/CCPayments.h delete mode 100644 src/cc/CCrewards.h delete mode 100644 src/cc/Makefile_rogue delete mode 100644 src/cc/payments.cpp delete mode 100644 src/cc/rewards.cpp diff --git a/src/Makefile.am b/src/Makefile.am index d376665a5..d08f0d49e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -281,11 +281,9 @@ libbitcoin_server_a_SOURCES = \ cc/CCtokens.cpp \ cc/assets.cpp \ cc/faucet.cpp \ - cc/rewards.cpp \ cc/fsm.cpp \ cc/heir.cpp \ cc/oracles.cpp \ - cc/payments.cpp \ cc/auction.cpp \ cc/betprotocol.cpp \ chain.cpp \ diff --git a/src/cc/CCPayments.h b/src/cc/CCPayments.h deleted file mode 100644 index 246a980d1..000000000 --- a/src/cc/CCPayments.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - - -#ifndef CC_PAYMENTS_H -#define CC_PAYMENTS_H - -#include "CCinclude.h" -#include -#include - -#define PAYMENTS_TXFEE 10000 -#define PAYMENTS_MERGEOFSET 60 // 1H extra. -extern std::vector > vAddressSnapshot; -extern int32_t lastSnapShotHeight; - -bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn); - -// CCcustom -UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr); -UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr); -UniValue PaymentsMerge(struct CCcontract_info *cp,char *jsonstr); -UniValue PaymentsTxidopret(struct CCcontract_info *cp,char *jsonstr); -UniValue PaymentsCreate(struct CCcontract_info *cp,char *jsonstr); -UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr); -UniValue PaymentsAirdropTokens(struct CCcontract_info *cp,char *jsonstr); -UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr); -UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr); - -#endif - diff --git a/src/cc/CCcustom.cpp b/src/cc/CCcustom.cpp index be3dccd17..fb3ff024a 100644 --- a/src/cc/CCcustom.cpp +++ b/src/cc/CCcustom.cpp @@ -20,14 +20,12 @@ #include "CCinclude.h" #include "CCassets.h" #include "CCfaucet.h" -#include "CCrewards.h" #include "CCauction.h" #include "CCfsm.h" #include "CCHeir.h" #include "CCOracles.h" #include "CCPrices.h" #include "CCPegs.h" -#include "CCPayments.h" #include "CCtokens.h" #include "CCImportGateway.h" @@ -314,8 +312,8 @@ struct CCcontract_info *CCinit(struct CCcontract_info *cp, uint8_t evalcode) strcpy(cp->normaladdr,RewardsNormaladdr); strcpy(cp->CChexstr,RewardsCChexstr); memcpy(cp->CCpriv,RewardsCCpriv,32); - cp->validate = RewardsValidate; - cp->ismyvin = IsRewardsInput; + //cp->validate = RewardsValidate; + //cp->ismyvin = IsRewardsInput; break; case EVAL_DICE: strcpy(cp->unspendableCCaddr,DiceCCaddr); @@ -394,8 +392,8 @@ struct CCcontract_info *CCinit(struct CCcontract_info *cp, uint8_t evalcode) strcpy(cp->normaladdr,PaymentsNormaladdr); strcpy(cp->CChexstr,PaymentsCChexstr); memcpy(cp->CCpriv,PaymentsCCpriv,32); - cp->validate = PaymentsValidate; - cp->ismyvin = IsPaymentsInput; + //cp->validate = PaymentsValidate; + //cp->ismyvin = IsPaymentsInput; break; case EVAL_GATEWAYS: strcpy(cp->unspendableCCaddr,GatewaysCCaddr); diff --git a/src/cc/CCrewards.h b/src/cc/CCrewards.h deleted file mode 100644 index e78e20cdd..000000000 --- a/src/cc/CCrewards.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - - -#ifndef CC_REWARDS_H -#define CC_REWARDS_H - -#include "CCinclude.h" -#include - -#define EVAL_REWARDS 0xe5 -#define REWARDSCC_MAXAPR (COIN * 25) - -bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn); -UniValue RewardsInfo(uint256 rewardid); -UniValue RewardsList(); - -std::string RewardsCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t APR,int64_t minseconds,int64_t maxseconds,int64_t mindeposit); -std::string RewardsAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount); -std::string RewardsLock(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount); -std::string RewardsUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 locktxid); - -#endif diff --git a/src/cc/Makefile_rogue b/src/cc/Makefile_rogue deleted file mode 100644 index 3b2f65e00..000000000 --- a/src/cc/Makefile_rogue +++ /dev/null @@ -1,38 +0,0 @@ -SHELL = /bin/sh -CC = gcc -CC_DARWIN = g++-8 -CC_WIN = x86_64-w64-mingw32-gcc-posix -CFLAGS_DARWIN = -DBUILD_ROGUE -std=c++11 -arch x86_64 -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -Wl,-undefined -Wl,dynamic_lookup -Wno-write-strings -shared -dynamiclib -CFLAGS = -Wno-write-strings -DBUILD_ROGUE -std=c++11 -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared -CFLAGS_WIN = -Wno-write-strings -DBUILD_ROGUE -std=c++11 -I./rogue/x86_64-w64-mingw32/include -I./rogue/x86_64-w64-mingw32/include/ncursesw -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared -DEBUGFLAGS = -O0 -D _DEBUG -RELEASEFLAGS = -O2 -D NDEBUG -combine -fwhole-program -$(info $(OS)) -OS := $(shell uname -s) -$(info $(OS)) -TARGET = librogue.so -TARGET_DARWIN = librogue.dylib -TARGET_WIN = librogue.dll -SOURCES = cclib.cpp -#HEADERS = $(shell echo ../cryptoconditions/include/*.h) -I/usr/local/Cellar/gcc\@8/8.3.0/include/c++/8.3.0/ - -all: $(TARGET) - -$(TARGET): $(SOURCES) - $(info Building cclib to src/) -ifeq ($(OS),Darwin) - $(CC_DARWIN) $(CFLAGS_DARWIN) $(DEBUGFLAGS) -o $(TARGET_DARWIN) -c $(SOURCES) - cp $(TARGET_DARWIN) ../libcc.dylib -else ifeq ($(HOST),x86_64-w64-mingw32) - $(info WINDOWS) - $(CC_WIN) $(CFLAGS_WIN) $(DEBUGFLAGS) -o $(TARGET_WIN) -c $(SOURCES) - cp $(TARGET_WIN) ../libcc.dll -#else ifeq ($(WIN_HOST),True) - todo: pass ENV var from build.sh if WIN host -else - $(info LINUX) - $(CC) $(CFLAGS) $(DEBUGFLAGS) -o $(TARGET) -c $(SOURCES) - cp $(TARGET) ../libcc.so -endif - -clean: - rm -rf $(TARGET) diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp deleted file mode 100644 index d212cc387..000000000 --- a/src/cc/payments.cpp +++ /dev/null @@ -1,1572 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include "CCPayments.h" - -/* - 0) txidopret <- allocation, scriptPubKey, opret - 1) create <- locked_blocks, minrelease, list of txidopret - - 2) fund createtxid amount opretflag to global CC address with opret or txidaddr without - - 3) release amount -> vout[i] will be scriptPubKeys[i] and (amount * allocations[i]) / sumallocations[] (only using vins that have been locked for locked_blocks+). - - 4) info txid -> display parameters, funds - 5) list -> all txids - - First step is to create txids with the info needed in their opreturns. this info is the weight, scriptPubKey and opret if needed. To do that txidopret is used: - - ./c is a script that invokes hush-cli with the correct -ac_name - - ./c paymentstxidopret \"[9,%222102d6f13a8f745921cdb811e32237bb98950af1a5952be7b3d429abd9152f8e388dac%22]\" -> rawhex with txid 95d9fc8d8a3ef63693c7427e59ff5e177ef63b7345d5f6d6497ac262699a8def - - ./c paymentstxidopret \"[1,%2221039433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775ac%22]\" -> rawhex txid 00469695a08b975ceaf7258896abbf1455eb0f383e8a98fc650deace4cbf02a1 - - now we have 2 txid with the required info in the opreturn. one of them has a 9 and the other a 1 for a 90%/10% split. - - ./c paymentscreate \"[0,0,%2295d9fc8d8a3ef63693c7427e59ff5e177ef63b7345d5f6d6497ac262699a8def%22,%2200469695a08b975ceaf7258896abbf1455eb0f383e8a98fc650deace4cbf02a1%22]\" -> created txid 318d827cc6d8f25f40517e7fb0982e3f707b4aa749d322483fc336686a87b28a that will be the createtxid that the other rpc calls will use. - - lets see if this appears in the list - - ./c paymentslist -> - { - "result": "success", - "createtxids": [ - "318d827cc6d8f25f40517e7fb0982e3f707b4aa749d322483fc336686a87b28a" - ] - } - - It appeared! now lets get more info on it: - ./c paymentsinfo \"[%22318d827cc6d8f25f40517e7fb0982e3f707b4aa749d322483fc336686a87b28a%22]\" - { - "lockedblocks": 0, - "totalallocations": 10, - "minrelease": 0, - "RWRM36sC8jSctyFZtsu7CyDcHYPdZX7nPZ": 0.00000000, - "REpyKi7avsVduqZ3eimncK4uKqSArLTGGK": 0.00000000, - "totalfunds": 0.00000000, - "result": "success" - } - - There are 2 possible places the funds for this createtxid can be, the first is the special address that is derived from combining the globalCC address with the txidaddr. txidaddr is a non-spendable markeraddress created by converting the txid into a 33 byte pubkey by prefixing 0x02 to the txid. It is a 1of2 address, so it doesnt matter that nobody knows the privkey for this txidaddr. the second address is the global CC address and only utxo to that address with an opreturn containing the createtxid are funds valid for this payments CC createtxid - - next let us add some funds to it. the funds can be to either of the two addresses, controlled by useopret (defaults to 0) - - ./c paymentsfund \"[%22318d827cc6d8f25f40517e7fb0982e3f707b4aa749d322483fc336686a87b28a%22,1,0]\" -> txid 28f69b925bb7a21d2a3ba2327e85eb2031b014e976e43f5c2c6fb8a76767b221, which indeed sent funds to RWRM36sC8jSctyFZtsu7CyDcHYPdZX7nPZ without an opreturn and it appears on the payments info. - - ./c paymentsfund \"[%22318d827cc6d8f25f40517e7fb0982e3f707b4aa749d322483fc336686a87b28a%22,1,1]\" -> txid cc93330b5c951b724b246b3b138d00519c33f2a600a7c938bc9e51aff6e20e32, which indeed sent funds to REpyKi7avsVduqZ3eimncK4uKqSArLTGGK with an opreturn and it appears on the payments info. - - -./c paymentsrelease \"[%22318d827cc6d8f25f40517e7fb0982e3f707b4aa749d322483fc336686a87b28a%22,1.5]\" -> a8d5dbbb8ee94c05e75c4f3c5221091f59dcb86e0e9c4e1e3d2cf69e6fce6b81 - - it used both fund utxos - -*/ - -// start of consensus code - -void mpz_set_lli( mpz_t rop, long long op ) -{ - mpz_import(rop, 1, 1, sizeof(op), 0, 0, &op); -} - -int64_t mpz_get_si2( mpz_t op ) -{ - int64_t ret = 0; - mpz_export(&ret, NULL, 1, sizeof(ret), 0, 0, op); - return ret; -} - -uint64_t mpz_get_ui2( mpz_t op ) -{ - uint64_t ret = 0; - mpz_export(&ret, NULL, 1, sizeof(ret), 0, 0, op); - return ret; -} - -CScript EncodePaymentsTxidOpRet(int64_t allocation,std::vector scriptPubKey,std::vector destopret) -{ - CScript opret; uint8_t evalcode = EVAL_PAYMENTS; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'T' << allocation << scriptPubKey << destopret); - return(opret); -} - -uint8_t DecodePaymentsTxidOpRet(CScript scriptPubKey,int64_t &allocation,std::vector &destscriptPubKey,std::vector &destopret) -{ - std::vector vopret; uint8_t *script,e,f; - GetOpReturnData(scriptPubKey, vopret); - script = (uint8_t *)vopret.data(); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> allocation; ss >> destscriptPubKey; ss >> destopret) != 0 ) - { - if ( e == EVAL_PAYMENTS && f == 'T' ) - return(f); - } - return(0); -} - -CScript EncodePaymentsFundOpRet(uint256 checktxid) -{ - CScript opret; uint8_t evalcode = EVAL_PAYMENTS; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'F' << checktxid); - return(opret); -} - -uint8_t DecodePaymentsFundOpRet(CScript scriptPubKey,uint256 &checktxid) -{ - std::vector vopret; uint8_t *script,e,f; - GetOpReturnData(scriptPubKey, vopret); - script = (uint8_t *)vopret.data(); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> checktxid) != 0 ) - { - if ( e == EVAL_PAYMENTS && f == 'F' ) - return(f); - } - return(0); -} - -CScript EncodePaymentsMergeOpRet(uint256 checktxid) -{ - CScript opret; uint8_t evalcode = EVAL_PAYMENTS; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'M' << checktxid); - return(opret); -} - -uint8_t DecodePaymentsMergeOpRet(CScript scriptPubKey,uint256 &checktxid) -{ - std::vector vopret; uint8_t *script,e,f; - GetOpReturnData(scriptPubKey, vopret); - script = (uint8_t *)vopret.data(); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> checktxid) != 0 ) - { - if ( e == EVAL_PAYMENTS && f == 'M' ) - return(f); - } - return(0); -} - -CScript EncodePaymentsReleaseOpRet(uint256 checktxid, int64_t amountReleased) -{ - CScript opret; uint8_t evalcode = EVAL_PAYMENTS; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'R' << checktxid << amountReleased); - return(opret); -} - -uint8_t DecodePaymentsReleaseOpRet(CScript scriptPubKey,uint256 &checktxid,int64_t &amountReleased) -{ - std::vector vopret; uint8_t *script,e,f; - GetOpReturnData(scriptPubKey, vopret); - script = (uint8_t *)vopret.data(); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> checktxid; ss >> amountReleased) != 0 ) - { - if ( e == EVAL_PAYMENTS && f == 'R' ) - return(f); - } - return(0); -} - -CScript EncodePaymentsOpRet(int32_t lockedblocks,int32_t minrelease,int64_t totalallocations,std::vector txidoprets) -{ - CScript opret; uint8_t evalcode = EVAL_PAYMENTS; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'C' << lockedblocks << minrelease << totalallocations << txidoprets); - return(opret); -} - -uint8_t DecodePaymentsOpRet(CScript scriptPubKey,int32_t &lockedblocks,int32_t &minrelease,int64_t &totalallocations,std::vector &txidoprets) -{ - std::vector vopret; uint8_t *script,e,f; - GetOpReturnData(scriptPubKey, vopret); - script = (uint8_t *)vopret.data(); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> lockedblocks; ss >> minrelease; ss >> totalallocations; ss >> txidoprets) != 0 ) - { - if ( e == EVAL_PAYMENTS && f == 'C' && txidoprets.size() > 1 ) - return(f); - } - return(0); -} - -CScript EncodePaymentsSnapsShotOpRet(int32_t lockedblocks,int32_t minrelease,int32_t minimum,int32_t top,int32_t bottom,int8_t fixedAmount,std::vector> excludeScriptPubKeys) -{ - CScript opret; uint8_t evalcode = EVAL_PAYMENTS; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'S' << lockedblocks << minrelease << minimum << top << bottom << fixedAmount << excludeScriptPubKeys); - return(opret); -} - -uint8_t DecodePaymentsSnapsShotOpRet(CScript scriptPubKey,int32_t &lockedblocks,int32_t &minrelease,int32_t &minimum,int32_t &top,int32_t &bottom,int8_t &fixedAmount,std::vector> &excludeScriptPubKeys) -{ - std::vector vopret; uint8_t *script,e,f; - GetOpReturnData(scriptPubKey, vopret); - script = (uint8_t *)vopret.data(); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> lockedblocks; ss >> minrelease; ss >> minimum; ss >> top; ; ss >> bottom; ss >> fixedAmount; ss >> excludeScriptPubKeys) != 0 ) - { - if ( e == EVAL_PAYMENTS && f == 'S' ) - return(f); - } - return(0); -} - -CScript EncodePaymentsTokensOpRet(int32_t lockedblocks,int32_t minrelease,int32_t minimum,int32_t top,int32_t bottom,int8_t fixedAmount,std::vector> excludeScriptPubKeys,uint256 tokenid) -{ - CScript opret; uint8_t evalcode = EVAL_PAYMENTS; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'O' << lockedblocks << minrelease << minimum << top << bottom << fixedAmount << excludeScriptPubKeys << tokenid); - return(opret); -} - -uint8_t DecodePaymentsTokensOpRet(CScript scriptPubKey,int32_t &lockedblocks,int32_t &minrelease,int32_t &minimum,int32_t &top,int32_t &bottom,int8_t &fixedAmount,std::vector> &excludeScriptPubKeys, uint256 &tokenid) -{ - std::vector vopret; uint8_t *script,e,f; - GetOpReturnData(scriptPubKey, vopret); - script = (uint8_t *)vopret.data(); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> lockedblocks; ss >> minimum; ss >> top; ; ss >> bottom; ss >> fixedAmount; ss >> excludeScriptPubKeys; ss >> tokenid) != 0 ) - { - if ( e == EVAL_PAYMENTS && f == 'O' ) - return(f); - } - return(0); -} - -int64_t IsPaymentsvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v,char *cmpaddr, CScript &ccopret) -{ - char destaddr[64]; - if ( getCCopret(tx.vout[v].scriptPubKey, ccopret) ) - { - if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && (cmpaddr[0] == 0 || strcmp(destaddr,cmpaddr) == 0) ) - return(tx.vout[v].nValue); - } - return(0); -} - -bool payments_game(int32_t &top, int32_t &bottom) -{ - uint64_t x; - uint256 tmphash = chainActive[lastSnapShotHeight]->GetBlockHash(); - memcpy(&x,&tmphash,sizeof(x)); - bottom = ((x & 0xff) % 50); - if ( bottom == 0 ) bottom = 1; - top = (((x>>8) & 0xff) % 100); - if ( top < 50 ) top += 50; - bottom = (vAddressSnapshot.size()*bottom)/100; - top = (vAddressSnapshot.size()*top)/100; - //fprintf(stderr, "bottom.%i top.%i\n",bottom,top); - return true; -} - -bool payments_lockedblocks(uint256 blockhash,int32_t lockedblocks,int32_t &blocksleft) -{ - int32_t ht = chainActive.Height(); - CBlockIndex* pblockindex = hush_blockindex(blockhash); - if ( pblockindex == 0 || pblockindex->GetHeight()+lockedblocks > ht) - { - blocksleft = pblockindex->GetHeight()+lockedblocks - ht; - fprintf(stderr, "not elegible to be spent yet height.%i vs elegible_ht.%i blocksleft.%i\n",ht,(pblockindex!=0?pblockindex->GetHeight():0)+lockedblocks,blocksleft); - return false; - } - return true; -} - -int32_t payments_getallocations(int32_t top, int32_t bottom, const std::vector> &excludeScriptPubKeys, mpz_t &mpzTotalAllocations, std::vector &scriptPubKeys, std::vector &allocations) -{ - mpz_t mpzAllocation; int32_t i =0; - for (int32_t j = bottom; j < vAddressSnapshot.size(); j++) - { - auto &address = vAddressSnapshot[j]; - CScript scriptPubKey = GetScriptForDestination(address.second); - bool skip = false; - // skip excluded addresses. - for ( auto skipkey : excludeScriptPubKeys ) - { - if ( scriptPubKey == CScript(skipkey.begin(), skipkey.end()) ) - skip = true; - } - if ( !skip ) - { - mpz_init(mpzAllocation); - i++; - //fprintf(stderr, "address: %s nValue.%li \n", CBitcoinAddress(address.second).ToString().c_str(), address.first); - scriptPubKeys.push_back(scriptPubKey); - allocations.push_back(address.first); - mpz_set_lli(mpzAllocation,address.first); - mpz_add(mpzTotalAllocations,mpzTotalAllocations,mpzAllocation); - mpz_clear(mpzAllocation); - } - if ( i+bottom == top ) - break; // we reached top amount to pay, it can be less than this, if less address exist on chain, return the number we got. - } - return(i); -} - -int32_t payments_gettokenallocations(int32_t top, int32_t bottom, const std::vector> &excludeScriptPubKeys, uint256 tokenid, mpz_t &mpzTotalAllocations, std::vector &scriptPubKeys, std::vector &allocations) -{ - /* - - check tokenid exists. - - iterate tokenid address and extract all pubkeys, add to map. - - rewind to last notarized height for balances? see main.cpp: line# 660. - - convert balances to mpz_t and add up totalallocations - - sort the map into a vector, then convert to the correct output. - */ - return(0); -} - -bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn) -{ - char temp[128], txidaddr[64]={0}; std::string scriptpubkey; uint256 createtxid, blockhash, tokenid; CTransaction plantx; int8_t funcid=0, fixedAmount=0; - int32_t i,lockedblocks,minrelease,blocksleft,dust = 0, top,bottom=0,minimum=10000; int64_t change,totalallocations,actualtxfee,amountReleased=0; std::vector txidoprets; bool fHasOpret = false,fIsMerge = false; CPubKey txidpk,Paymentspk; - std::vector> excludeScriptPubKeys; bool fFixedAmount = false; CScript ccopret; - mpz_t mpzTotalAllocations,mpzAllocation,mpzCheckamount; - mpz_init(mpzCheckamount); mpz_init(mpzTotalAllocations); - // Check change is in vout[0], and also fetch the ccopret to determine what type of tx this is. txidaddr is unknown, recheck this later. - if ( (change= IsPaymentsvout(cp,tx,0,txidaddr,ccopret)) != 0 && ccopret.size() > 2 ) - { - // get the checktxid and the amount released if doing release tx. - if ( DecodePaymentsMergeOpRet(ccopret,createtxid) == 'M' ) - fIsMerge = true; - else if ( DecodePaymentsReleaseOpRet(ccopret,createtxid,amountReleased) != 'R' ) - return(eval->Invalid("could not decode ccopret")); - if ( tx.vout.back().scriptPubKey.IsOpReturn() ) - fHasOpret = true; - mpz_set_lli(mpzCheckamount,amountReleased); - } else return(eval->Invalid("could not decode ccopret")); - - // use the createtxid to fetch the tx and all of the plans info. - if ( myGetTransaction(createtxid,plantx,blockhash) != 0 && plantx.vout.size() > 0 ) - { - if ( ((funcid= DecodePaymentsOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets)) == 'C' || (funcid= DecodePaymentsSnapsShotOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys)) == 'S' || (funcid= DecodePaymentsTokensOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys,tokenid)) == 'O') ) - { - if ( lockedblocks < 0 || minrelease < 0 || (totalallocations <= 0 && top <= 0 ) ) - return(eval->Invalid("negative values")); - if ( minimum < 10000 ) - return(eval->Invalid("minimum must be over 10000")); - Paymentspk = GetUnspendable(cp,0); - txidpk = CCtxidaddr(txidaddr,createtxid); - GetCCaddress1of2(cp,txidaddr,Paymentspk,txidpk); - //fprintf(stderr, "lockedblocks.%i minrelease.%i totalallocations.%i txidopret1.%s txidopret2.%s\n",lockedblocks, minrelease, totalallocations, txidoprets[0].ToString().c_str(), txidoprets[1].ToString().c_str() ); - if ( !CheckTxFee(tx, PAYMENTS_TXFEE+1, chainActive.LastTip()->GetHeight(), chainActive.LastTip()->nTime, actualtxfee) ) - return eval->Invalid("txfee is too high"); - // Check that the change vout is playing the txid address. - if ( IsPaymentsvout(cp,tx,0,txidaddr,ccopret) == 0 ) - return eval->Invalid("change pays wrong address"); - - if ( !fIsMerge ) - { - if ( amountReleased < minrelease*COIN ) - { - fprintf(stderr, "does not meet minrelease amount.%li minrelease.%li\n",amountReleased, (int64_t)minrelease*COIN); - return(eval->Invalid("amount is too small")); - } - // Get all the script pubkeys and allocations - std::vector allocations; - std::vector scriptPubKeys; - i = 0; - if ( funcid == 'C' ) - { - // normal payment - int64_t checkallocations = 0; - for ( auto txidopret : txidoprets) - { - CTransaction tx0; std::vector scriptPubKey,opret; int64_t allocation; - if ( myGetTransaction(txidopret,tx0,blockhash) != 0 && tx0.vout.size() > 1 && DecodePaymentsTxidOpRet(tx0.vout[tx0.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' ) - { - scriptPubKeys.push_back(CScript(scriptPubKey.begin(), scriptPubKey.end())); - allocations.push_back(allocation); - //fprintf(stderr, "i.%i scriptpubkey.%s allocation.%li\n",i,scriptPubKeys[i].ToString().c_str(),allocation); - checkallocations += allocation; - // if we have an op_return to pay to need to check it exists and is paying the correct opret. - if ( !opret.empty() ) - { - if ( !fHasOpret ) - { - fprintf(stderr, "missing opret.%s in payments release.\n",HexStr(opret.begin(), opret.end()).c_str()); - return(eval->Invalid("missing opret in payments release")); - } - else if ( CScript(opret.begin(),opret.end()) != tx.vout[tx.vout.size()-1].scriptPubKey ) - { - fprintf(stderr, "opret.%s vs opret.%s\n",HexStr(opret.begin(), opret.end()).c_str(), HexStr(tx.vout[tx.vout.size()-1].scriptPubKey.begin(), tx.vout[tx.vout.size()-1].scriptPubKey.end()).c_str()); - return(eval->Invalid("pays incorrect opret")); - } - } - } - i++; - } - //fprintf(stderr, "totalallocations.%li checkallocations.%li\n",totalallocations, checkallocations); - if ( totalallocations != checkallocations ) - return(eval->Invalid("allocation missmatch")); - mpz_set_lli(mpzTotalAllocations,totalallocations); - } - else if ( funcid == 'S' || funcid == 'O' ) - { - // snapshot payment - if ( HUSH_SNAPSHOT_INTERVAL == 0 ) - return(eval->Invalid("snapshots not activated on this chain")); - if ( vAddressSnapshot.size() == 0 ) - return(eval->Invalid("need first snapshot")); - if ( top > 3999 ) - return(eval->Invalid("transaction too big")); - if ( fixedAmount == 7 ) - { - // game setting, randomise bottom and top values - fFixedAmount = payments_game(top,bottom); - } - else if ( fixedAmount != 0 ) - { - fFixedAmount = true; - } - if ( funcid == 'S' ) - payments_getallocations(top, bottom, excludeScriptPubKeys, mpzTotalAllocations, scriptPubKeys, allocations); - else - { - // token snapshot - // payments_gettokenallocations(top, bottom, excludeScriptPubKeys, tokenid, mpzTotalAllocations, scriptPubKeys, allocations); - return(eval->Invalid("tokens not yet implemented")); - } - } - // sanity check to make sure we got all the required info, skip for merge type tx - //fprintf(stderr, " allocations.size().%li scriptPubKeys.size.%li\n",allocations.size(), scriptPubKeys.size()); - if ( (allocations.size() == 0 || scriptPubKeys.size() == 0 || allocations.size() != scriptPubKeys.size()) ) - return(eval->Invalid("missing data cannot validate")); - - // Check vouts go to the right place and pay the right amounts. - int64_t amount = 0; int32_t n = 0; - // We place amount released into ccopret, so that these calcualtion are accurate! - // If you change the amount released in the RPC these calcs will be wrong, and validation will fail. - for (i = 1; i < (fHasOpret ? tx.vout.size()-1 : tx.vout.size()); i++) - { - int64_t test; - if ( scriptPubKeys[n] != tx.vout[i].scriptPubKey ) - { - fprintf(stderr, "pays wrong destination destscriptPubKey.%s voutscriptPubKey.%s\n", HexStr(scriptPubKeys[n].begin(),scriptPubKeys[n].end()).c_str(), HexStr(tx.vout[i].scriptPubKey.begin(),tx.vout[i].scriptPubKey.end()).c_str()); - return(eval->Invalid("pays wrong address")); - } - if ( fFixedAmount ) - { - if ( (top-bottom) > 0 ) - test = amountReleased / (top-bottom); - else - return(eval->Invalid("top/bottom range is illegal")); - } - else - { - mpz_init(mpzAllocation); - mpz_set_lli(mpzAllocation,allocations[n]); - mpz_mul(mpzAllocation,mpzAllocation,mpzCheckamount); - mpz_tdiv_q(mpzAllocation,mpzAllocation,mpzTotalAllocations); - test = mpz_get_si2(mpzAllocation); - mpz_clear(mpzAllocation); - } - //fprintf(stderr, "vout.%i test.%lli vs nVlaue.%lli\n",i, (long long)test, (long long)tx.vout[i].nValue); - if ( test != tx.vout[i].nValue ) - { - fprintf(stderr, "vout.%i test.%lli vs nVlaue.%lli\n",i, (long long)test, (long long)tx.vout[i].nValue); - return(eval->Invalid("amounts do not match")); - } - if ( test < minimum ) - { - // prevent anyone being paid the minimum. - fprintf(stderr, "vout.%i test.%li vs minimum.%i\n",i, test, minimum); - return(eval->Invalid("under minimum size")); - } - amount += tx.vout[i].nValue; - n++; - } - if ( allocations.size() > n ) - { - // need to check that the next allocation was less than minimum, otherwise ppl can truncate the tx at any place not paying all elegible addresses. - mpz_init(mpzAllocation); - mpz_set_lli(mpzAllocation,allocations[n+1]); - mpz_mul(mpzAllocation,mpzAllocation,mpzCheckamount); - mpz_tdiv_q(mpzAllocation,mpzAllocation,mpzTotalAllocations); - int64_t test = mpz_get_si2(mpzAllocation); - //fprintf(stderr, "check next vout pays under min: test.%li > minimuim.%i\n", test, minimum); - if ( test > minimum ) - return(eval->Invalid("next allocation was not under minimum")); - } - mpz_clear(mpzTotalAllocations); mpz_clear(mpzCheckamount); - } - // Check vins - i = 0; - for (auto vin : tx.vin) - { - CTransaction txin; - if ( myGetTransaction(vin.prevout.hash,txin,blockhash) ) - { - // check the vin comes from the CC address's - char fromaddr[64]; int32_t mergeoffset = 0; CScript vinccopret; uint256 checktxid; - Getscriptaddress(fromaddr,txin.vout[vin.prevout.n].scriptPubKey); - if ( fIsMerge && txin.vout[vin.prevout.n].nValue < COIN ) - dust++; - if ( IsPaymentsvout(cp,txin,vin.prevout.n,cp->unspendableCCaddr,vinccopret) != 0 ) - { - // if from global payments address get ccopret to detemine pays correct plan. - uint256 checktxid; - if ( vinccopret.size() < 2 || DecodePaymentsFundOpRet(vinccopret,checktxid) != 'F' || checktxid != createtxid ) - { - fprintf(stderr, "vin.%i is not a payments CC vout: txid.%s vout.%i\n", i, txin.GetHash().ToString().c_str(), vin.prevout.n); - return(eval->Invalid("vin is not paymentsCC type")); - } - } - else if ( IsPaymentsvout(cp,txin,vin.prevout.n,txidaddr,vinccopret) != 0 ) - { - // if in txid address apply merge offset if applicable. - if ( fIsMerge && vinccopret.size() > 2 && DecodePaymentsMergeOpRet(vinccopret,checktxid) == 'M' ) - { - // Apply merge offset to locked blocks, this prevents people spaming payments fund and payments merge to prevent release happening. - mergeoffset = PAYMENTS_MERGEOFSET; - } - } - else // not from global payments plan, or txid address. - return(eval->Invalid("utxo comes from incorrect address")); - // check the chain depth vs locked blocks requirement. - if ( !payments_lockedblocks(blockhash, lockedblocks+mergeoffset, blocksleft) ) - { - fprintf(stderr, "vin.%i is not elegible for.%i blocks \n",i, blocksleft); - return(eval->Invalid("vin not elegible")); - } - i++; - } else return(eval->Invalid("cant get vin transaction")); - } - if ( fIsMerge ) - { - if ( i < 2 ) - return(eval->Invalid("must have at least 2 vins to carry out merge")); - else if ( i == dust+1 ) - return(eval->Invalid("cannot merge only dust")); - } - } else return(eval->Invalid("cannot decode create transaction")); - } else return(eval->Invalid("could not get contract transaction")); - return(true); -} -// end of consensus code - -// helper functions for rpc calls in rpcwallet.cpp -int64_t AddPaymentsInputs(bool fLockedBlocks,int8_t GetBalance,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey txidpk,int64_t total,int32_t maxinputs,uint256 createtxid,int32_t lockedblocks,int64_t minrelease,int32_t &blocksleft) -{ - char coinaddr[64]; CPubKey Paymentspk; int64_t nValue,threshold,price,totalinputs = 0; uint256 txid,checktxid,hashBlock; std::vector origpubkey; CTransaction vintx; int32_t iter,vout,ht,n = 0; - std::vector > unspentOutputs; CScript ccopret; - std::vector > blocksleft_balance; - if ( GetBalance == 0 ) - { - if ( maxinputs > CC_MAXVINS ) - maxinputs = CC_MAXVINS; - if ( maxinputs > 0 ) - threshold = total/maxinputs; - else threshold = total; - } - else threshold = 0; - Paymentspk = GetUnspendable(cp,0); - for (iter=0; iter<2; iter++) - { - if ( GetBalance == 1 && iter == 1 ) - continue; // getbalance of global paymentsCC address. - if ( GetBalance == 2 && iter == 0 ) - continue; // get balance of txidpk address. - if ( iter == 0 ) - GetCCaddress(cp,coinaddr,Paymentspk); - else GetCCaddress1of2(cp,coinaddr,Paymentspk,txidpk); - SetCCunspents(unspentOutputs,coinaddr,true); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - vout = (int32_t)it->first.index; - //fprintf(stderr,"iter.%d %s/v%d %s\n",iter,txid.GetHex().c_str(),vout,coinaddr); - if ( myGetTransaction(txid,vintx,hashBlock) != 0 ) - { - if ( (nValue= IsPaymentsvout(cp,vintx,vout,coinaddr,ccopret)) > PAYMENTS_TXFEE && nValue >= threshold && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 ) - { - int32_t offset = 0; - if ( ccopret.size() > 2 ) - { - if ( iter == 0 && (DecodePaymentsFundOpRet(ccopret,checktxid) != 'F' || checktxid != createtxid) ) - { - // global address but not for this plan. - fprintf(stderr,"bad opret %s vs %s\n",checktxid.GetHex().c_str(),createtxid.GetHex().c_str()); - continue; - } - // increase merge offset, if this is a merge tx, merging merged utxos. - if ( iter == 1 && GetBalance == 4 && DecodePaymentsMergeOpRet(ccopret,checktxid) == 'M' ) - offset = PAYMENTS_MERGEOFSET; - } - int32_t tmpblocksleft = 0; - if ( fLockedBlocks && !payments_lockedblocks(hashBlock, lockedblocks+offset, tmpblocksleft) ) - { - blocksleft_balance.push_back(std::make_pair(tmpblocksleft,nValue)); - continue; - } - if ( (GetBalance == 0 && total != 0 && maxinputs != 0) || GetBalance == 4 ) - mtx.vin.push_back(CTxIn(txid,vout,CScript())); - nValue = it->second.satoshis; - if ( GetBalance == 4 && nValue < COIN ) - blocksleft++; // count dust with unused variable. - if ( GetBalance == 2 || GetBalance == 1 ) - blocksleft++; // count all utxos with unused variable. - totalinputs += nValue; - n++; - //fprintf(stderr,"iter.%d %s/v%d %s %.8f\n",iter,txid.GetHex().c_str(),vout,coinaddr,(double)nValue/COIN); - if ( GetBalance == 0 && ((total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs)) ) - break; // create tx. We have ebnough inputs to make it. - } //else fprintf(stderr,"nValue %.8f vs threshold %.8f\n",(double)nValue/COIN,(double)threshold/COIN); - } - } - } - if ( GetBalance == 3 && totalinputs < minrelease ) // return elegible balance to be spent, and blocks left until min release can be released. - { - int64_t lockedblocks_balance = totalinputs; // inputs that can be spent already. - // sort utxos by blocks until able to be spent, smallest at top. - std::sort(blocksleft_balance.begin(), blocksleft_balance.end()); - // iterate the utxos blocks left vector, to get block height min release is able to be released. - for ( auto utxo : blocksleft_balance ) - { - lockedblocks_balance += utxo.second; - if ( lockedblocks_balance >= minrelease ) - { - blocksleft = utxo.first; - break; - } - } - } - return(totalinputs); -} - -UniValue payments_rawtxresult(UniValue &result,std::string rawtx,int32_t broadcastflag) -{ - CTransaction tx; - if ( rawtx.size() > 0 ) - { - result.push_back(Pair("hex",rawtx)); - if ( DecodeHexTx(tx,rawtx) != 0 ) - { - if ( broadcastflag != 0 && myAddtomempool(tx) != 0 ) - RelayTransaction(tx); - result.push_back(Pair("txid",tx.GetHash().ToString())); - result.push_back(Pair("result","success")); - } else result.push_back(Pair("error","decode hex")); - } else result.push_back(Pair("error","couldnt finalize payments CCtx")); - return(result); -} - -cJSON *payments_reparse(int32_t *nump,char *jsonstr) -{ - cJSON *params=0; char *newstr; int32_t i,j; - *nump = 0; - if ( jsonstr != 0 ) - { - if ( jsonstr[0] == '"' && jsonstr[strlen(jsonstr)-1] == '"' ) - { - jsonstr[strlen(jsonstr)-1] = 0; - jsonstr++; - } - newstr = (char *)malloc(strlen(jsonstr)+1); - for (i=j=0; jsonstr[i]!=0; i++) - { - if ( jsonstr[i] == '%' && jsonstr[i+1] == '2' && jsonstr[i+2] == '2' ) - { - newstr[j++] = '"'; - i += 2; - } - else if ( jsonstr[i] == '\'' ) - newstr[j++] = '"'; - else newstr[j++] = jsonstr[i]; - } - newstr[j] = 0; - params = cJSON_Parse(newstr); - if ( 0 && params != 0 ) - printf("new.(%s) -> %s\n",newstr,jprint(params,0)); - free(newstr); - *nump = cJSON_GetArraySize(params); - } - return(params); -} - -uint256 payments_juint256(cJSON *obj) -{ - uint256 tmp; bits256 t = jbits256(obj,0); - memcpy(&tmp,&t,sizeof(tmp)); - return(revuint256(tmp)); -} - -int32_t payments_parsehexdata(std::vector &hexdata,cJSON *item,int32_t len) -{ - char *hexstr; int32_t val; - if ( (hexstr= jstr(item,0)) != 0 && ((val= is_hexstr(hexstr,0)) == len*2 || (val > 0 && len == 0)) ) - { - val >>= 1; - hexdata.resize(val); - decode_hex(&hexdata[0],val,hexstr); - return(0); - } else return(-1); -} - -UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) -{ - LOCK(cs_main); - CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),hush_nextheight()); UniValue result(UniValue::VOBJ); uint256 createtxid,hashBlock,tokenid; - CTransaction tx,txO; CPubKey mypk,txidpk,Paymentspk; int32_t i,n,m,numoprets=0,lockedblocks,minrelease; int64_t newamount,inputsum,amount,CCchange=0,totalallocations=0,checkallocations=0,allocation; CTxOut vout; CScript onlyopret,ccopret; char txidaddr[64],destaddr[64]; std::vector txidoprets; - int32_t top,bottom=0,blocksleft=0,minimum=10000; std::vector> excludeScriptPubKeys; int8_t funcid,fixedAmount=0,skipminimum=0; bool fFixedAmount = false; - mpz_t mpzTotalAllocations, mpzAllocation; mpz_init(mpzTotalAllocations); - cJSON *params = payments_reparse(&n,jsonstr); - mypk = pubkey2pk(Mypubkey()); - Paymentspk = GetUnspendable(cp,0); - if ( params != 0 && n >= 2 ) - { - createtxid = payments_juint256(jitem(params,0)); - amount = jdouble(jitem(params,1),0) * SATOSHIDEN + 0.0000000049; - if ( n == 3 ) - skipminimum = juint(jitem(params,2),0); - if ( myGetTransaction(createtxid,tx,hashBlock) != 0 && tx.vout.size() > 0 ) - { - if ( ((funcid= DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets)) == 'C' || (funcid= DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys)) == 'S' || (funcid= DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys,tokenid)) == 'O') ) - { - if ( lockedblocks < 0 || minrelease < 0 || (totalallocations <= 0 && top <= 0 ) ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","negative parameter")); - if ( params != 0 ) - free_json(params); - return(result); - } - // set minimum size to 10k sat otherwise the tx will be invalid. - if ( minimum < 10000 ) - minimum = 10000; - if ( amount < minrelease*COIN ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","amount too smal")); - result.push_back(Pair("amount",ValueFromAmount(amount))); - result.push_back(Pair("minrelease",ValueFromAmount(minrelease*COIN))); - if ( params != 0 ) - free_json(params); - return(result); - } - txidpk = CCtxidaddr(txidaddr,createtxid); - ccopret = EncodePaymentsReleaseOpRet(createtxid, amount); - std::vector> vData = std::vector>(); - if ( makeCCopret(ccopret, vData) ) - mtx.vout.push_back(MakeCC1of2vout(EVAL_PAYMENTS,0,Paymentspk,txidpk,&vData)); - //fprintf(stderr, "funcid.%i\n", funcid); - if ( funcid == 'C' ) - { - // normal payments - m = txidoprets.size(); - for (i=0; i scriptPubKey,opret; - vout.nValue = 0; - if ( myGetTransaction(txidoprets[i],txO,hashBlock) != 0 && txO.vout.size() > 1 && DecodePaymentsTxidOpRet(txO.vout[txO.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' ) - { - vout.nValue = allocation; - vout.scriptPubKey.resize(scriptPubKey.size()); - memcpy(&vout.scriptPubKey[0],&scriptPubKey[0],scriptPubKey.size()); - checkallocations += allocation; - if ( opret.size() > 0 ) - { - onlyopret.resize(opret.size()); - memcpy(&onlyopret[0],&opret[0],opret.size()); - numoprets++; - } - } else break; - mtx.vout.push_back(vout); - } - result.push_back(Pair("numoprets",(int64_t)numoprets)); - if ( i != m ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","invalid txidoprets[i]")); - result.push_back(Pair("txi",(int64_t)i)); - if ( params != 0 ) - free_json(params); - return(result); - } - else if ( checkallocations != totalallocations ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","totalallocations mismatch")); - result.push_back(Pair("checkallocations",(int64_t)checkallocations)); - result.push_back(Pair("totalallocations",(int64_t)totalallocations)); - if ( params != 0 ) - free_json(params); - return(result); - } - else if ( numoprets > 1 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","too many oprets")); - if ( params != 0 ) - free_json(params); - return(result); - } - // set totalallocations to a mpz_t bignum, for amounts calculation later. - mpz_set_lli(mpzTotalAllocations,totalallocations); - } - else if ( funcid == 'S' || funcid == 'O' ) - { - // normal snapshot - if ( vAddressSnapshot.size() == 0 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","first snapshot has not happened yet")); - if ( params != 0 ) - free_json(params); - return(result); - } - if ( top > 3999 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","cannot pay more than 3999 addresses")); - if ( params != 0 ) - free_json(params); - return(result); - } - if ( fixedAmount == 7 ) - { - // game setting, randomise bottom and top values - fFixedAmount = payments_game(top,bottom); - } - else if ( fixedAmount != 0 ) - { - fFixedAmount = true; - } - if ( (top-bottom) < 0 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","invalid range top/bottom")); - if ( params != 0 ) - free_json(params); - return(result); - } - - std::vector allocations; - std::vector scriptPubKeys; - if ( funcid == 'S' ) - m = payments_getallocations(top, bottom, excludeScriptPubKeys, mpzTotalAllocations, scriptPubKeys, allocations); - else - { - // token snapshot - // payments_gettokenallocations(top, bottom, excludeScriptPubKeys, tokenid, mpzTotalAllocations, scriptPubKeys, allocations); - } - if ( (allocations.size() == 0 || scriptPubKeys.size() == 0 || allocations.size() != scriptPubKeys.size()) ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","mismatched allocations, scriptpubkeys")); - if ( params != 0 ) - free_json(params); - return(result); - } - i = 0; - for ( auto allocation : allocations ) - { - vout.nValue = allocation; - vout.scriptPubKey = scriptPubKeys[i]; - mtx.vout.push_back(vout); - i++; - } - } - newamount = amount; - int64_t totalamountsent = 0; - mpz_t mpzAmount; mpz_init(mpzAmount); mpz_set_lli(mpzAmount,amount); - for (i=0; i= newamount+2*PAYMENTS_TXFEE ) - { - std::string rawtx; - mtx.vout[0].nValue = inputsum - newamount - PAYMENTS_TXFEE; // only 1 txfee, so the minimum in this vout is a tx fee. - GetCCaddress1of2(cp,destaddr,Paymentspk,txidpk); - CCaddr1of2set(cp,Paymentspk,txidpk,cp->CCpriv,destaddr); - rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,onlyopret); - if ( params != 0 ) - free_json(params); - result.push_back(Pair("amount",ValueFromAmount(amount))); - result.push_back(Pair("newamount",ValueFromAmount(newamount))); - return(payments_rawtxresult(result,rawtx,1)); - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","couldnt find enough locked funds")); - } - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","couldnt find paymentscreate txid")); - } - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","parameters error")); - } - if ( params != 0 ) - free_json(params); - return(result); -} - -UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); UniValue result(UniValue::VOBJ); - CPubKey Paymentspk,mypk,txidpk; uint256 txid,hashBlock; int64_t amount,totalallocations; CScript opret; CTransaction tx; char txidaddr[64]; std::string rawtx; int32_t n,useopret = 0,broadcast=0,lockedblocks,minrelease; std::vector txidoprets; - int32_t top,bottom,minimum=10000; std::vector> excludeScriptPubKeys; // snapshot - uint256 tokenid; int8_t fixedAmount; - cJSON *params = payments_reparse(&n,jsonstr); - mypk = pubkey2pk(Mypubkey()); - Paymentspk = GetUnspendable(cp,0); - if ( params != 0 && n > 1 && n <= 4 ) - { - txid = payments_juint256(jitem(params,0)); - amount = jdouble(jitem(params,1),0) * SATOSHIDEN + 0.0000000049; - if ( n == 3 ) - useopret = jint(jitem(params,2),0) != 0; - if ( n == 4 ) - broadcast = jint(jitem(params,3),0) != 0; - if ( myGetTransaction(txid,tx,hashBlock) == 0 || tx.vout.size() == 1 || (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 0 && DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys) == 0 && DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys,tokenid) == 0) ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","invalid createtxid")); - } - else if ( AddNormalinputs(mtx,mypk,amount+PAYMENTS_TXFEE,60) > 0 ) - { - if ( lockedblocks < 0 || minrelease < 0 || (totalallocations <= 0 && top <= 0 ) ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","negative parameter")); - if ( params != 0 ) - free_json(params); - return(result); - } - if ( useopret == 0 ) - { - txidpk = CCtxidaddr(txidaddr,txid); - mtx.vout.push_back(MakeCC1of2vout(EVAL_PAYMENTS,amount,Paymentspk,txidpk)); - } - else - { - opret = EncodePaymentsFundOpRet(txid); - std::vector> vData = std::vector>(); - if ( makeCCopret(opret, vData) ) - mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,amount,Paymentspk,&vData)); - } - rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,CScript()); - if ( params != 0 ) - free_json(params); - return(payments_rawtxresult(result,rawtx,1)); - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","couldnt find enough funds")); - } - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","parameters error")); - } - if ( params != 0 ) - free_json(params); - return(result); -} - -UniValue PaymentsMerge(struct CCcontract_info *cp,char *jsonstr) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); UniValue result(UniValue::VOBJ); - CPubKey Paymentspk,mypk,txidpk; uint256 createtxid,hashBlock; int64_t inputsum,totalallocations=0; CScript opret; CTransaction tx; char txidaddr[64],destaddr[64]; std::string rawtx; - int32_t n,lockedblocks,minrelease,top,bottom,minimum=10000,blocksleft; std::vector txidoprets; - std::vector> excludeScriptPubKeys; // snapshot - uint256 tokenid; int8_t fixedAmount; - cJSON *params = payments_reparse(&n,jsonstr); - mypk = pubkey2pk(Mypubkey()); - Paymentspk = GetUnspendable(cp,0); - if ( params != 0 && n == 1 ) - { - createtxid = payments_juint256(jitem(params,0)); - txidpk = CCtxidaddr(txidaddr,createtxid); - if ( myGetTransaction(createtxid,tx,hashBlock) == 0 || tx.vout.size() == 1 || (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 0 && DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys) == 0 && DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys,tokenid) == 0) ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","invalid createtxid")); - } - else if ( (inputsum= AddPaymentsInputs(true,4,cp,mtx,txidpk,0,CC_MAXVINS,createtxid,lockedblocks,minrelease,blocksleft)) > 0 && mtx.vin.size() > 1 ) - { - int32_t dust = blocksleft; - if ( mtx.vin.size() == dust+1 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","cannot merge only dust")); - } - else - { - // encode the checktxid into the end of the ccvout, along with 'M' to flag merge type tx. - opret = EncodePaymentsMergeOpRet(createtxid); - std::vector> vData = std::vector>(); - if ( makeCCopret(opret, vData) ) - mtx.vout.push_back(MakeCC1of2vout(EVAL_PAYMENTS,inputsum-PAYMENTS_TXFEE,Paymentspk,txidpk,&vData)); - GetCCaddress1of2(cp,destaddr,Paymentspk,txidpk); - CCaddr1of2set(cp,Paymentspk,txidpk,cp->CCpriv,destaddr); - rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,CScript()); - if ( params != 0 ) - free_json(params); - return(payments_rawtxresult(result,rawtx,1)); - } - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","couldnt find enough funds")); - } - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","parameters error")); - } - if ( params != 0 ) - free_json(params); - return(result); -} - -UniValue PaymentsTxidopret(struct CCcontract_info *cp,char *jsonstr) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); UniValue result(UniValue::VOBJ); CPubKey mypk; std::string rawtx; - std::vector scriptPubKey,opret; int32_t n,retval0,retval1=0; int64_t allocation; CScript test; txnouttype whichType; - cJSON *params = payments_reparse(&n,jsonstr); - mypk = pubkey2pk(Mypubkey()); - if ( params != 0 && n > 1 && n <= 3 ) - { - allocation = (int64_t)jint(jitem(params,0),0); - std::string address; - address.append(jstri(params,1)); - CTxDestination destination = DecodeDestination(address); - if ( IsValidDestination(destination) ) - { - // its an address - test = GetScriptForDestination(destination); - scriptPubKey = std::vector (test.begin(),test.end()); - } - else - { - // its a scriptpubkey - retval0 = payments_parsehexdata(scriptPubKey,jitem(params,1),0); - test = CScript(scriptPubKey.begin(),scriptPubKey.end()); - } - if (!::IsStandard(test, whichType)) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","scriptPubkey is not valid payment.")); - } - else - { - if ( n == 3 ) - retval1 = payments_parsehexdata(opret,jitem(params,2),0); - if ( allocation > 0 && retval0 == 0 && retval1 == 0 && AddNormalinputs(mtx,mypk,PAYMENTS_TXFEE*2,10) > 0 ) - { - rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,EncodePaymentsTxidOpRet(allocation,scriptPubKey,opret)); - if ( params != 0 ) - free_json(params); - return(payments_rawtxresult(result,rawtx,1)); - } - result.push_back(Pair("result","error")); - result.push_back(Pair("error","invalid params or cant find txfee")); - } - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","parameters error")); - result.push_back(Pair("n",(int64_t)n)); - fprintf(stderr,"(%s) %p\n",jsonstr,params); - } - if ( params != 0 ) - free_json(params); - return(result); -} - -UniValue PaymentsCreate(struct CCcontract_info *cp,char *jsonstr) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - UniValue result(UniValue::VOBJ); CTransaction tx; CPubKey Paymentspk,mypk; char markeraddr[64]; std::vector txidoprets; uint256 hashBlock; int32_t i,n,numoprets=0,lockedblocks,minrelease; std::string rawtx; int64_t totalallocations = 0; - cJSON *params = payments_reparse(&n,jsonstr); - if ( params != 0 && n >= 4 ) - { - lockedblocks = juint(jitem(params,0),0); - minrelease = juint(jitem(params,1),0); - if ( lockedblocks < 0 || minrelease < 0 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","negative parameter")); - if ( params != 0 ) - free_json(params); - return(result); - } - for (i=0; i scriptPubKey,opret; int64_t allocation; - //fprintf(stderr, "txid.%s\n",txidoprets[i].GetHex().c_str()); - if ( myGetTransaction(txidoprets[i],tx,hashBlock) != 0 && tx.vout.size() > 1 && DecodePaymentsTxidOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' ) - { - totalallocations += allocation; - if ( opret.size() > 0 ) - numoprets++; - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","invalid txidopret")); - result.push_back(Pair("txid",txidoprets[i].GetHex())); - result.push_back(Pair("txi",(int64_t)i)); - if ( params != 0 ) - free_json(params); - return(result); - } - } - if ( numoprets > 1 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","too many opreturns")); - result.push_back(Pair("numoprets",(int64_t)numoprets)); - if ( params != 0 ) - free_json(params); - return(result); - } - mypk = pubkey2pk(Mypubkey()); - Paymentspk = GetUnspendable(cp,0); - if ( AddNormalinputs(mtx,mypk,2*PAYMENTS_TXFEE,60) > 0 ) - { - mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,PAYMENTS_TXFEE,Paymentspk,Paymentspk)); - rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,EncodePaymentsOpRet(lockedblocks,minrelease,totalallocations,txidoprets)); - if ( params != 0 ) - free_json(params); - return(payments_rawtxresult(result,rawtx,1)); - } - result.push_back(Pair("result","error")); - result.push_back(Pair("error","not enough normal funds")); - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","parameters error")); - } - if ( params != 0 ) - free_json(params); - return(result); -} - -UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - UniValue result(UniValue::VOBJ); - uint256 hashBlock; CTransaction tx; CPubKey Paymentspk,mypk; char markeraddr[64]; std::string rawtx; - int32_t lockedblocks,minrelease,top,bottom,n,i,minimum=10000; std::vector> excludeScriptPubKeys; int8_t fixedAmount; - if ( HUSH_SNAPSHOT_INTERVAL == 0 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","cannot use airdrop wihtout -ac_snapshot set.")); - return(result); - } - cJSON *params = payments_reparse(&n,jsonstr); - if ( params != 0 && n >= 5 ) - { - lockedblocks = juint(jitem(params,0),0); - minrelease = juint(jitem(params,1),0); - minimum = juint(jitem(params,2),0); - if ( minimum < 10000 ) minimum = 10000; - top = juint(jitem(params,3),0); - bottom = juint(jitem(params,4),0); - fixedAmount = juint(jitem(params,5),0); // fixed amount is a flag, set to 7 does game mode, 0 normal snapshot, anything else fixed allocations. - if ( lockedblocks < 0 || minrelease < 0 || top <= 0 || bottom < 0 || minimum < 0 || fixedAmount < 0 || top > 3999 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","negative parameter, or top over 3999")); - if ( params != 0 ) - free_json(params); - return(result); - } - if ( top-bottom < 0 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","invalid range, top/bottom")); - if ( params != 0 ) - free_json(params); - return(result); - } - if ( n > 6 ) - { - for (i=0; i vscriptPubKey; - CScript scriptPubKey = GetScriptForDestination(destination); - vscriptPubKey.assign(scriptPubKey.begin(), scriptPubKey.end()); - excludeScriptPubKeys.push_back(vscriptPubKey); - } - } - mypk = pubkey2pk(Mypubkey()); - Paymentspk = GetUnspendable(cp,0); - if ( AddNormalinputs(mtx,mypk,2*PAYMENTS_TXFEE,60) > 0 ) - { - mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,PAYMENTS_TXFEE,Paymentspk,Paymentspk)); - CScript tempopret = EncodePaymentsSnapsShotOpRet(lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys); - if ( tempopret.size() > 10000 ) // TODO: Check this! - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","op_return is too big, try with less exclude addresses.")); - if ( params != 0 ) - free_json(params); - return(result); - } - rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,tempopret); - if ( params != 0 ) - free_json(params); - return(payments_rawtxresult(result,rawtx,1)); - } - result.push_back(Pair("result","error")); - result.push_back(Pair("error","not enough normal funds")); - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","parameters error")); - } - if ( params != 0 ) - free_json(params); - return(result); -} - -UniValue PaymentsAirdropTokens(struct CCcontract_info *cp,char *jsonstr) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - UniValue result(UniValue::VOBJ); - uint256 hashBlock, tokenid = zeroid; CTransaction tx; CPubKey Paymentspk,mypk; char markeraddr[64]; std::string rawtx; - int32_t lockedblocks,minrelease,top,bottom,n,i,minimum=10000; std::vector> excludeScriptPubKeys; int8_t fixedAmount; - cJSON *params = payments_reparse(&n,jsonstr); - // disable for now. Need token snapshot function. - if ( 0 ) //params != 0 && n >= 6 ) - { - tokenid = payments_juint256(jitem(params,0)); - lockedblocks = juint(jitem(params,1),0); - minrelease = juint(jitem(params,2),0); - minimum = juint(jitem(params,3),0); - if ( minimum < 10000 ) minimum = 10000; - top = juint(jitem(params,4),0); - bottom = juint(jitem(params,5),0); - fixedAmount = juint(jitem(params,6),0); // fixed amount is a flag, set to 7 does game mode, 0 normal snapshot, anything else fixed allocations. - if ( lockedblocks < 0 || minrelease < 0 || top <= 0 || bottom < 0 || minimum < 0 || fixedAmount < 0 || top > 3999 || tokenid == zeroid ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","negative parameter, or top over 3999")); - if ( params != 0 ) - free_json(params); - return(result); - } - // TODO: lookup tokenid and make sure it exists. - if ( n > 7 ) - { - for (i=0; i vscriptPubKey; - CScript scriptPubKey = GetScriptForDestination(destination); - vscriptPubKey.assign(scriptPubKey.begin(), scriptPubKey.end()); - excludeScriptPubKeys.push_back(vscriptPubKey); - } - } - mypk = pubkey2pk(Mypubkey()); - Paymentspk = GetUnspendable(cp,0); - if ( AddNormalinputs(mtx,mypk,2*PAYMENTS_TXFEE,60) > 0 ) - { - mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,PAYMENTS_TXFEE,Paymentspk,Paymentspk)); - CScript tempopret = EncodePaymentsTokensOpRet(lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys,tokenid); - if ( tempopret.size() > 10000 ) // TODO: Check this! - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","op_return is too big, try with less exclude pubkeys.")); - if ( params != 0 ) - free_json(params); - return(result); - } - rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,tempopret); - if ( params != 0 ) - free_json(params); - return(payments_rawtxresult(result,rawtx,0)); - } - result.push_back(Pair("result","error")); - result.push_back(Pair("error","not enough normal funds")); - } - else - { - result.push_back(Pair("result","error")); - //result.push_back(Pair("error","parameters error")); - result.push_back(Pair("error","tokens airdrop not yet impmlemented")); - } - if ( params != 0 ) - free_json(params); - return(result); -} - -UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) -{ - UniValue result(UniValue::VOBJ),a(UniValue::VARR); CTransaction tx,txO; CPubKey Paymentspk,txidpk; int32_t i,j,n,flag=0,numoprets=0,lockedblocks,minrelease,blocksleft=0; std::vector txidoprets; int64_t funds,fundsopret,elegiblefunds,totalallocations=0,allocation; char fundsaddr[64],fundsopretaddr[64],txidaddr[64],*outstr; uint256 createtxid,hashBlock; - int32_t top,bottom,minimum=10000; std::vector> excludeScriptPubKeys; // snapshot - uint256 tokenid; int8_t fixedAmount; CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),hush_nextheight()); - cJSON *params = payments_reparse(&n,jsonstr); - if ( params != 0 && n == 1 ) - { - Paymentspk = GetUnspendable(cp,0); - createtxid = payments_juint256(jitem(params,0)); - if ( myGetTransaction(createtxid,tx,hashBlock) != 0 && tx.vout.size() > 0 ) - { - if ( DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) != 0 ) - { - if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 || txidoprets.size() < 2 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","negative parameter")); - if ( params != 0 ) - free_json(params); - return(result); - } - result.push_back(Pair("plan_type","payments")); - result.push_back(Pair("lockedblocks",(int64_t)lockedblocks)); - result.push_back(Pair("totalallocations",(int64_t)totalallocations)); - result.push_back(Pair("minrelease",(int64_t)minrelease)); - for (i=0; i scriptPubKey,opret; - obj.push_back(Pair("txid",txidoprets[i].GetHex())); - if ( myGetTransaction(txidoprets[i],txO,hashBlock) != 0 && txO.vout.size() > 1 && DecodePaymentsTxidOpRet(txO.vout[txO.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' ) - { - outstr = (char *)malloc(2*(scriptPubKey.size() + opret.size()) + 1); - for (j=0; j 1 ) - { - flag++; - result.push_back(Pair("result","error")); - result.push_back(Pair("error","too many opreturns")); - } else result.push_back(Pair("txidoprets",a)); - } - else if ( DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys) != 0 ) - { - if ( lockedblocks < 0 || minrelease < 0 || top <= 0 || bottom < 0 || fixedAmount < 0 || top > 3999 || minimum < 10000 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","negative parameter")); - if ( params != 0 ) - free_json(params); - return(result); - } - if ( fixedAmount == 7 && payments_game(top,bottom)) - result.push_back(Pair("plan_type","payments_game")); - else - result.push_back(Pair("plan_type","snapshot")); - result.push_back(Pair("lockedblocks",(int64_t)lockedblocks)); - result.push_back(Pair("minrelease",(int64_t)minrelease)); - result.push_back(Pair("minimum",(int64_t)minimum)); - result.push_back(Pair("bottom",(int64_t)bottom)); - result.push_back(Pair("top",(int64_t)top)); - result.push_back(Pair("fixedFlag",(int64_t)fixedAmount)); - for ( auto scriptPubKey : excludeScriptPubKeys ) - { - CTxDestination dest; - if ( ExtractDestination(CScript(scriptPubKey.begin(),scriptPubKey.end()), dest) ) - a.push_back(CBitcoinAddress(dest).ToString()); - } - result.push_back(Pair("excludeAddresses",a)); - } - else if ( DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys,tokenid) != 0 ) - { - if ( lockedblocks < 0 || minrelease < 0 || top <= 0 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","negative parameter")); - if ( params != 0 ) - free_json(params); - return(result); - } - result.push_back(Pair("plan_type","token snapshot")); - result.push_back(Pair("lockedblocks",(int64_t)lockedblocks)); - result.push_back(Pair("minrelease",(int64_t)minrelease)); - result.push_back(Pair("top",(int64_t)top)); - result.push_back(Pair("tokenid",tokenid.ToString())); - // TODO: show pubkeys instead of scriptpubkeys - for ( auto scriptPubKey : excludeScriptPubKeys ) - a.push_back(HexStr(scriptPubKey.begin(),scriptPubKey.end())); - result.push_back(Pair("excludeScriptPubkeys",a)); - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","couldnt decode valid payments create txid opreturn")); - } - if ( flag == 0 ) - { - txidpk = CCtxidaddr(txidaddr,createtxid); - GetCCaddress1of2(cp,fundsaddr,Paymentspk,txidpk); - blocksleft = 0; - funds = AddPaymentsInputs(false,2,cp,mtx,txidpk,0,CC_MAXVINS,createtxid,lockedblocks,minrelease,blocksleft); - result.push_back(Pair(fundsaddr,ValueFromAmount(funds))); - result.push_back(Pair("utxos", (int64_t)blocksleft)); - blocksleft = 0; - GetCCaddress(cp,fundsopretaddr,Paymentspk); - fundsopret = AddPaymentsInputs(false,1,cp,mtx,txidpk,0,CC_MAXVINS,createtxid,lockedblocks,minrelease,blocksleft); - result.push_back(Pair(fundsopretaddr,ValueFromAmount(fundsopret))); - result.push_back(Pair("utxos", (int64_t)blocksleft)); - result.push_back(Pair("totalfunds",ValueFromAmount(funds+fundsopret))); - // Blocks until minrelease can be released. - elegiblefunds = AddPaymentsInputs(true,3,cp,mtx,txidpk,0,CC_MAXVINS,createtxid,lockedblocks,minrelease,blocksleft); - result.push_back(Pair("elegiblefunds",ValueFromAmount(elegiblefunds))); - result.push_back(Pair("min_release_height",chainActive.Height()+blocksleft)); - result.push_back(Pair("result","success")); - } - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","couldnt find valid payments create txid")); - } - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","parameters error")); - } - if ( params != 0 ) - free_json(params); - return(result); -} - -UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr) -{ - std::vector > addressIndex; uint256 txid,hashBlock,tokenid; - UniValue result(UniValue::VOBJ),a(UniValue::VARR); char markeraddr[64],str[65]; CPubKey Paymentspk; CTransaction tx; int32_t lockedblocks,minrelease; std::vector txidoprets; int64_t totalallocations=0; - int32_t top=0,bottom=0,minimum=10000; std::vector> excludeScriptPubKeys; int8_t fixedAmount = 0; - Paymentspk = GetUnspendable(cp,0); - GetCCaddress1of2(cp,markeraddr,Paymentspk,Paymentspk); - SetCCtxids(addressIndex,markeraddr,true); - for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) - { - txid = it->first.txhash; - if ( it->first.index == 0 && myGetTransaction(txid,tx,hashBlock) != 0 ) - { - if ( tx.vout.size() > 0 && (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 'C' || DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys) == 'S' || DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys,tokenid) == 'O') ) - { - if ( lockedblocks < 0 || minrelease < 0 || (totalallocations <= 0 && top <= 0 ) || bottom < 0 || fixedAmount < 0 || minimum < 10000 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","negative parameter")); - return(result); - } - a.push_back(uint256_str(str,txid)); - } - } - } - result.push_back(Pair("result","success")); - result.push_back(Pair("createtxids",a)); - return(result); -} diff --git a/src/cc/rewards.cpp b/src/cc/rewards.cpp deleted file mode 100644 index 3dd6f07ec..000000000 --- a/src/cc/rewards.cpp +++ /dev/null @@ -1,756 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include "CCrewards.h" - -/* - The rewards CC contract is initially for OOT, which needs this functionality. However, many of the attributes can be parameterized to allow different rewards programs to run. Multiple rewards plans could even run on the same blockchain, though the user would need to choose which one to lock funds into. - - At the high level, the user would lock funds for some amount of time and at the end of it, would get all the locked funds back with an additional reward. So there needs to be a lock funds and unlock funds ability. Additionally, the rewards need to come from somewhere, so similar to the faucet, there would be a way to fund the reward. - - Additional requirements are for the user to be able to lock funds via SPV. This requirement in turns forces the creation of a way for anybody to be able to unlock the funds as that operation requires a native daemon running and cant be done over SPV. The idea is to allow anybody to run a script that would unlock all funds that are matured. As far as the user is concerned, he locks his funds via SPV and after some time it comes back with an extra reward. - - In reality, the funds are locked into a CC address that is unspendable, except for some special conditions and it needs to come back to the address that funded the lock. In order to implement this, several things are clear. - - 1) each locked CC utxo needs to be linked to a specific rewards plan - 2) each locked CC utxo needs to know the only address that it can be unlocked into - 3) SPV requirement means the lock transaction needs to be able to be created without any CC signing - - The opreturn will be used to store the name of the rewards plan and all funding and locked funds with the same plan will use the same pool of rewards. plan names will be limited to 8 chars and encoded into a uint64_t. - - The initial funding transaction will have all the parameters for the rewards plan encoded in the vouts. Additional fundings will just increase the available CC utxo for the rewards. - - Locks wont have any CC vins, but will send to the RewardsCCaddress, with the plan stringbits in the opreturn. vout1 will have the unlock address and no other destination is valid. - - Unlock does a CC spend to the vout1 address - - - createfunding - vins.*: normal inputs - vout.0: CC vout for funding - vout.1: normal marker vout for easy searching - vout.2: normal change - vout.n-1: opreturn 'F' sbits APR minseconds maxseconds mindeposit - - addfunding - vins.*: normal inputs - vout.0: CC vout for funding - vout.1: normal change - vout.n-1: opreturn 'A' sbits fundingtxid - - lock - vins.*: normal inputs - vout.0: CC vout for locked funds - vout.1: normal output to unlock address - vout.2: change - vout.n-1: opreturn 'L' sbits fundingtxid - - unlock - vin.0: locked funds CC vout.0 from lock - vin.1+: funding CC vout.0 from 'F' and 'A' and 'U' - vout.0: funding CC change - vout.1: normal output to unlock address - vout.n-1: opreturn 'U' sbits fundingtxid - - */ - -/// the following are compatible with windows -/// mpz_set_lli sets a long long singed int to a big num mpz_t for very large integer math -extern void mpz_set_lli( mpz_t rop, long long op ); -// mpz_get_si2 gets a mpz_t and returns a signed long long int -extern int64_t mpz_get_si2( mpz_t op ); -// mpz_get_ui2 gets a mpz_t and returns a unsigned long long int -extern uint64_t mpz_get_ui2( mpz_t op ); - -uint64_t RewardsCalc(int64_t amount, uint256 txid, int64_t APR, int64_t minseconds, int64_t maxseconds, uint32_t timestamp) -{ - int32_t numblocks; int64_t duration; uint64_t reward = 0; - //fprintf(stderr,"minseconds %llu maxseconds %llu\n",(long long)minseconds,(long long)maxseconds); - if ( (duration= CCduration(numblocks,txid)) < minseconds ) - { - fprintf(stderr,"duration %lli < minseconds %lli\n",(long long)duration,(long long)minseconds); - return(0); - //duration = (uint32_t)time(NULL) - (1532713903 - 3600 * 24); - } else if ( duration > maxseconds ) - duration = maxseconds; - /* if ( 0 ) // amount * APR * duration / COIN * 100 * 365*24*3600 - reward = (((amount * APR) / COIN) * duration) / (365*24*3600LL * 100); - else reward = (((amount * duration) / (365 * 24 * 3600LL)) * (APR / 1000000)) / 10000; - */ - if ( !hush_hardfork_active(timestamp) ) - reward = (((amount * duration) / (365 * 24 * 3600LL)) * (APR / 1000000)) / 10000; - else - { - // declare and init the mpz_t big num variables - mpz_t mpzAmount, mpzDuration, mpzReward, mpzAPR, mpzModifier; - mpz_init(mpzAmount); - mpz_init(mpzDuration); - mpz_init(mpzAPR); - mpz_init(mpzReward); - mpz_init(mpzModifier); - - // set the inputs to big num variables - mpz_set_lli(mpzAmount, amount); - mpz_set_lli(mpzDuration, duration); - mpz_set_lli(mpzAPR, APR); - mpz_set_lli(mpzModifier, COIN*100*365*24*3600LL); - - // (amount * APR * duration) - mpz_mul(mpzReward, mpzAmount, mpzDuration); - mpz_mul(mpzReward, mpzReward, mpzAPR); - - // total_of_above / (COIN * 100 * 365*24*3600LL) - mpz_tdiv_q(mpzReward, mpzReward, mpzModifier); - - // set result to variable we can use and return it. - reward = mpz_get_ui2(mpzReward); - } - if ( reward > amount ) - reward = amount; - fprintf(stderr, "amount.%lli duration.%lli APR.%lli reward.%llu\n", (long long)amount, (long long)duration, (long long)APR, (long long)reward); - //fprintf(stderr,"amount %.8f %.8f %llu -> duration.%llu reward %.8f vals %.8f %.8f\n",(double)amount/COIN,((double)amount * APR)/COIN,(long long)((amount * APR) / (COIN * 365*24*3600)),(long long)duration,(double)reward/COIN,(double)((amount * duration) / (365 * 24 * 3600LL))/COIN,(double)(((amount * duration) / (365 * 24 * 3600LL)) * (APR / 1000000))/COIN); - return(reward); -} - -CScript EncodeRewardsFundingOpRet(uint8_t funcid,uint64_t sbits,uint64_t APR,uint64_t minseconds,uint64_t maxseconds,uint64_t mindeposit) -{ - CScript opret; uint8_t evalcode = EVAL_REWARDS; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'F' << sbits << APR << minseconds << maxseconds << mindeposit); - return(opret); -} - -uint8_t DecodeRewardsFundingOpRet(const CScript &scriptPubKey,uint64_t &sbits,uint64_t &APR,uint64_t &minseconds,uint64_t &maxseconds,uint64_t &mindeposit) -{ - std::vector vopret; uint8_t *script,e,f; - GetOpReturnData(scriptPubKey, vopret); - script = (uint8_t *)vopret.data(); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> sbits; ss >> APR; ss >> minseconds; ss >> maxseconds; ss >> mindeposit) != 0 ) - { - if ( e == EVAL_REWARDS && f == 'F' ) - return(f); - } - return(0); -} - -CScript EncodeRewardsOpRet(uint8_t funcid,uint64_t sbits,uint256 fundingtxid) -{ - CScript opret; uint8_t evalcode = EVAL_REWARDS; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << sbits << fundingtxid); - return(opret); -} - -uint8_t DecodeRewardsOpRet(uint256 txid,const CScript &scriptPubKey,uint64_t &sbits,uint256 &fundingtxid) -{ - std::vector vopret; uint8_t *script,e,f,funcid; uint64_t APR,minseconds,maxseconds,mindeposit; - GetOpReturnData(scriptPubKey, vopret); - if ( vopret.size() > 2 ) - { - script = (uint8_t *)vopret.data(); - if ( script[0] == EVAL_REWARDS ) - { - if ( script[1] == 'F' ) - { - if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> sbits; ss >> APR; ss >> minseconds; ss >> maxseconds; ss >> mindeposit) != 0 ) - { - fundingtxid = txid; - return('F'); - } else fprintf(stderr,"unmarshal error for F\n"); - } - else if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> sbits; ss >> fundingtxid) != 0 ) - { - if ( e == EVAL_REWARDS && (f == 'L' || f == 'U' || f == 'A') ) - return(f); - else fprintf(stderr,"mismatched e.%02x f.(%c)\n",e,f); - } - } else fprintf(stderr,"script[0] %02x != EVAL_REWARDS\n",script[0]); - } else fprintf(stderr,"not enough opret.[%d]\n",(int32_t)vopret.size()); - return(0); -} - -int64_t IsRewardsvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v,uint64_t refsbits,uint256 reffundingtxid) -{ - char destaddr[64]; uint64_t sbits; uint256 fundingtxid,txid; uint8_t funcid; int32_t numvouts; - if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 && (numvouts= (int32_t)tx.vout.size()) > 0 ) - { - txid = tx.GetHash(); - if ( (funcid= DecodeRewardsOpRet(txid,tx.vout[numvouts-1].scriptPubKey,sbits,fundingtxid)) != 0 && sbits == refsbits && (fundingtxid == reffundingtxid || txid == reffundingtxid) ) - { - - if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 ) - return(tx.vout[v].nValue); - } - } - return(0); -} - -bool RewardsExactAmounts(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx,uint64_t txfee,uint64_t refsbits,uint256 reffundingtxid) -{ - static uint256 zerohash; - 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; iismyvin)(tx.vin[i].scriptSig) != 0 ) - { - if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 ) - return eval->Invalid("always should find vin, but didnt"); - else - { - if ( hashBlock == zerohash ) - return eval->Invalid("cant rewards from mempool"); - if ( (assetoshis= IsRewardsvout(cp,vinTx,tx.vin[i].prevout.n,refsbits,reffundingtxid)) != 0 ) - inputs += assetoshis; - } - } - } - for (i=0; iInvalid("mismatched inputs != outputs + txfee"); - } - else return(true); -} - -bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn) -{ - uint256 txid,fundingtxid,hashBlock,vinfundingtxid; uint64_t vinsbits,sbits,APR,minseconds,maxseconds,mindeposit,amount,reward,txfee=10000; int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; uint8_t funcid; CScript scriptPubKey; CTransaction fundingTx,vinTx; - int64_t dummy; - numvins = tx.vin.size(); - numvouts = tx.vout.size(); - preventCCvins = preventCCvouts = -1; - if ( numvouts < 1 ) - return eval->Invalid("no vouts"); - else - { - txid = tx.GetHash(); - if ( (funcid= DecodeRewardsOpRet(txid,tx.vout[numvouts-1].scriptPubKey,sbits,fundingtxid)) != 0 ) - { - if ( eval->GetTxUnconfirmed(fundingtxid,fundingTx,hashBlock) == 0 ) - return eval->Invalid("cant find fundingtxid"); - else if ( fundingTx.vout.size() > 0 && DecodeRewardsFundingOpRet(fundingTx.vout[fundingTx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) != 'F' ) - return eval->Invalid("fundingTx not valid"); - if ( APR > REWARDSCC_MAXAPR ) - return eval->Invalid("excessive APR"); - switch ( funcid ) - { - case 'F': - //vins.*: normal inputs - //vout.0: CC vout for funding - //vout.1: normal marker vout for easy searching - //vout.2: normal change - //vout.n-1: opreturn 'F' sbits APR minseconds maxseconds mindeposit - return eval->Invalid("unexpected RewardsValidate for createfunding"); - break; - case 'A': - //vins.*: normal inputs - //vout.0: CC vout for funding - //vout.1: normal change - //vout.n-1: opreturn 'A' sbits fundingtxid - return eval->Invalid("unexpected RewardsValidate for addfunding"); - break; - case 'L': - //vins.*: normal inputs - //vout.0: CC vout for locked funds - //vout.1: normal output to unlock address - //vout.2: change - //vout.n-1: opreturn 'L' sbits fundingtxid - return eval->Invalid("unexpected RewardsValidate for lock"); - break; - case 'U': - //vin.0: locked funds CC vout.0 from lock - //vin.1+: funding CC vout.0 from 'F' and 'A' and 'U' - //vout.0: funding CC change or recover normal payout - //vout.1: normal output to unlock address - //vout.n-1: opreturn 'U' sbits fundingtxid - if ( fundingtxid == tx.vin[0].prevout.hash ) - return eval->Invalid("cant unlock fundingtxid"); - else if ( eval->GetTxUnconfirmed(tx.vin[0].prevout.hash,vinTx,hashBlock) == 0 ) - return eval->Invalid("always should find vin.0, but didnt"); - else if ( DecodeRewardsOpRet(tx.vin[0].prevout.hash,vinTx.vout[vinTx.vout.size()-1].scriptPubKey,vinsbits,vinfundingtxid) != 'L' ) - return eval->Invalid("can only unlock locktxid"); - else if ( fundingtxid != vinfundingtxid ) - return eval->Invalid("mismatched vinfundingtxid"); - for (i=0; iismyvin)(tx.vin[i].scriptSig) == 0 ) - return eval->Invalid("unexpected normal vin for unlock"); - } - if ( !CheckTxFee(tx, txfee, chainActive.LastTip()->GetHeight(), chainActive.LastTip()->nTime, dummy) ) - return eval->Invalid("txfee is too high"); - amount = vinTx.vout[0].nValue; - reward = RewardsCalc((int64_t)amount,tx.vin[0].prevout.hash,(int64_t)APR,(int64_t)minseconds,(int64_t)maxseconds,GetLatestTimestamp(eval->GetCurrentHeight())); - if ( reward == 0 ) - return eval->Invalid("no eligible rewards"); - if ( numvins == 1 && tx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 ) - { - if ( tx.vout[1].nValue != 10000 ) - return eval->Invalid("wrong marker vout value"); - else if ( tx.vout[1].scriptPubKey != tx.vout[0].scriptPubKey ) - return eval->Invalid("unlock recover tx vout.1 mismatched scriptPubKey"); - else if ( tx.vout[0].scriptPubKey != vinTx.vout[1].scriptPubKey ) - return eval->Invalid("unlock recover tx vout.0 mismatched scriptPubKey"); - else if ( tx.vout[0].nValue > vinTx.vout[0].nValue ) - return eval->Invalid("unlock recover tx vout.0 mismatched amounts"); - else if ( tx.vout[2].nValue > 0 ) - return eval->Invalid("unlock recover tx vout.1 nonz amount"); - else return(true); - } - if ( vinTx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 ) - return eval->Invalid("unlock tx vout.0 is normal output"); - else if ( numvouts != 3 ) - return eval->Invalid("unlock tx wrong number of vouts"); - else if ( tx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 ) - return eval->Invalid("unlock tx vout.0 is normal output"); - else if ( tx.vout[1].scriptPubKey.IsPayToCryptoCondition() != 0 ) - return eval->Invalid("unlock tx vout.1 is CC output"); - else if ( tx.vout[1].scriptPubKey != vinTx.vout[1].scriptPubKey ) - return eval->Invalid("unlock tx vout.1 mismatched scriptPubKey"); - if ( RewardsExactAmounts(cp,eval,tx,txfee+tx.vout[1].nValue,sbits,fundingtxid) == 0 ) - return false; - else if ( tx.vout[1].nValue > amount+reward ) - return eval->Invalid("unlock tx vout.1 isnt amount+reward"); - else if ( tx.vout[2].nValue > 0 ) - return eval->Invalid("unlock tx vout.2 isnt 0"); - preventCCvouts = 1; - break; - default: - fprintf(stderr,"illegal rewards funcid.(%c)\n",funcid); - return eval->Invalid("unexpected rewards funcid"); - break; - } - } else return eval->Invalid("unexpected rewards missing funcid"); - return(PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts)); - } - return(true); -} - -static uint64_t myIs_unlockedtx_inmempool(uint256 &txid,int32_t &vout,uint64_t refsbits,uint256 reffundingtxid,uint64_t needed) -{ - uint8_t funcid; uint64_t sbits,nValue; uint256 fundingtxid; char str[65]; - memset(&txid,0,sizeof(txid)); - vout = -1; - nValue = 0; - BOOST_FOREACH(const CTxMemPoolEntry &e,mempool.mapTx) - { - const CTransaction &tx = e.GetTx(); - if ( tx.vout.size() > 0 && tx.vout[0].nValue >= needed ) - { - const uint256 &hash = tx.GetHash(); - if ( tx.vout[0].scriptPubKey.IsPayToCryptoCondition() != 0 && myIsutxo_spentinmempool(ignoretxid,ignorevin,hash,0) == 0 ) - { - if ( (funcid= DecodeRewardsOpRet(hash,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) == 'U' && sbits == refsbits && fundingtxid == reffundingtxid ) - { - txid = hash; - vout = 0; - nValue = tx.vout[0].nValue; - fprintf(stderr,"found 'U' %s %.8f in unspent in mempool\n",uint256_str(str,txid),(double)nValue/COIN); - return(nValue); - } - } - } - } - return(nValue); -} - -// 'L' vs 'F' and 'A' -int64_t AddRewardsInputs(CScript &scriptPubKey,uint64_t maxseconds,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs,uint64_t refsbits,uint256 reffundingtxid) -{ - char coinaddr[64],str[65]; uint64_t threshold,sbits,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t numblocks,j,vout,n = 0; uint8_t funcid; - std::vector > unspentOutputs; - GetCCaddress(cp,coinaddr,pk); - SetCCunspents(unspentOutputs,coinaddr,true); - if ( maxinputs > CC_MAXVINS ) - maxinputs = CC_MAXVINS; - if ( maxinputs > 0 ) - threshold = total/maxinputs; - else threshold = total; - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - vout = (int32_t)it->first.index; - if ( it->second.satoshis < threshold ) - continue; - //fprintf(stderr,"(%s) %s/v%d %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN); - for (j=0; j 0 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 ) - { - if ( (funcid= DecodeRewardsOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) != 0 ) - { - if ( sbits != refsbits || fundingtxid != reffundingtxid ) - continue; - if ( maxseconds == 0 && funcid != 'F' && funcid != 'A' && funcid != 'U' ) - continue; - else if ( maxseconds != 0 && funcid != 'L' ) - { - if ( CCduration(numblocks,txid) < maxseconds ) - continue; - } - fprintf(stderr,"maxseconds.%d (%c) %.8f %.8f\n",(int32_t)maxseconds,funcid,(double)tx.vout[vout].nValue/COIN,(double)it->second.satoshis/COIN); - if ( total != 0 && maxinputs != 0 ) - { - if ( maxseconds != 0 ) - scriptPubKey = tx.vout[1].scriptPubKey; - mtx.vin.push_back(CTxIn(txid,vout,CScript())); - } - totalinputs += it->second.satoshis; - n++; - if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) - break; - } else fprintf(stderr,"null funcid\n"); - } - } - if ( maxseconds == 0 && totalinputs < total && (maxinputs == 0 || n < maxinputs-1) ) - { - fprintf(stderr,"search mempool for unlocked and unspent CC rewards output for %.8f\n",(double)(total-totalinputs)/COIN); - if ( (nValue= myIs_unlockedtx_inmempool(txid,vout,refsbits,reffundingtxid,total-totalinputs)) > 0 ) - { - mtx.vin.push_back(CTxIn(txid,vout,CScript())); - fprintf(stderr,"added mempool vout for %.8f\n",(double)nValue/COIN); - totalinputs += nValue; - n++; - } - } - return(totalinputs); -} - -int64_t RewardsPlanFunds(uint64_t &lockedfunds,uint64_t refsbits,struct CCcontract_info *cp,CPubKey pk,uint256 reffundingtxid) -{ - char coinaddr[64]; uint64_t sbits; int64_t nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t vout; uint8_t funcid; - std::vector > unspentOutputs; - lockedfunds = 0; - GetCCaddress(cp,coinaddr,pk); - SetCCunspents(unspentOutputs,coinaddr,true); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - vout = (int32_t)it->first.index; - if ( myGetTransaction(txid,tx,hashBlock) != 0 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 ) - { - if ( (funcid= DecodeRewardsOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) == 'F' || funcid == 'A' || funcid == 'U' || funcid == 'L' ) - { - if ( refsbits == sbits && (funcid == 'F' && reffundingtxid == txid) || reffundingtxid == fundingtxid ) - { - if ( (nValue= IsRewardsvout(cp,tx,vout,sbits,fundingtxid)) > 0 ) - { - if ( funcid == 'L' ) - lockedfunds += nValue; - else totalinputs += nValue; - } - else fprintf(stderr,"refsbits.%llx sbits.%llx nValue %.8f\n",(long long)refsbits,(long long)sbits,(double)nValue/COIN); - } //else fprintf(stderr,"else case\n"); - } else fprintf(stderr,"funcid.%d %c skipped %.8f\n",funcid,funcid,(double)tx.vout[vout].nValue/COIN); - } - } - return(totalinputs); -} - -bool RewardsPlanExists(struct CCcontract_info *cp,uint64_t refsbits,CPubKey rewardspk,uint64_t &APR,uint64_t &minseconds,uint64_t &maxseconds,uint64_t &mindeposit) -{ - char CCaddr[64]; uint64_t sbits; uint256 txid,hashBlock; CTransaction tx; - std::vector txids; - GetCCaddress(cp,CCaddr,rewardspk); - SetCCtxids(txids,CCaddr,true,cp->evalcode,zeroid,'F'); - for (std::vector::const_iterator it=txids.begin(); it!=txids.end(); it++) - { - //int height = it->first.blockHeight; - txid = *it; - if ( myGetTransaction(txid,tx,hashBlock) != 0 && tx.vout.size() > 0 && ConstrainVout(tx.vout[0],1,CCaddr,0) != 0 ) - { - //char str[65]; fprintf(stderr,"rewards plan %s\n",uint256_str(str,txid)); - if ( DecodeRewardsFundingOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) == 'F' ) - { - if ( sbits == refsbits ) - return(true); - } - } - } - return(false); -} - -UniValue RewardsInfo(uint256 rewardsid) -{ - UniValue result(UniValue::VOBJ); uint256 hashBlock; CTransaction vintx; uint64_t lockedfunds,APR,minseconds,maxseconds,mindeposit,sbits,funding; CPubKey rewardspk; struct CCcontract_info *cp,C; char str[67],numstr[65]; - if ( myGetTransaction(rewardsid,vintx,hashBlock) == 0 ) - { - fprintf(stderr,"cant find fundingtxid\n"); - result.push_back(Pair("result","error")); - result.push_back(Pair("error","cant find fundingtxid")); - return(result); - } - if ( vintx.vout.size() > 0 && DecodeRewardsFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) == 0 ) - { - fprintf(stderr,"fundingtxid isnt rewards creation txid\n"); - result.push_back(Pair("result","error")); - result.push_back(Pair("error","fundingtxid isnt rewards creation txid")); - return(result); - } - result.push_back(Pair("result","success")); - result.push_back(Pair("fundingtxid",uint256_str(str,rewardsid))); - unstringbits(str,sbits); - result.push_back(Pair("name",str)); - result.push_back(Pair("sbits",sbits)); - sprintf(numstr,"%.8f",(double)APR/COIN); - result.push_back(Pair("APR",numstr)); - result.push_back(Pair("minseconds",minseconds)); - result.push_back(Pair("maxseconds",maxseconds)); - sprintf(numstr,"%.8f",(double)mindeposit/COIN); - result.push_back(Pair("mindeposit",numstr)); - cp = CCinit(&C,EVAL_REWARDS); - rewardspk = GetUnspendable(cp,0); - funding = RewardsPlanFunds(lockedfunds,sbits,cp,rewardspk,rewardsid); - sprintf(numstr,"%.8f",(double)funding/COIN); - result.push_back(Pair("funding",numstr)); - sprintf(numstr,"%.8f",(double)lockedfunds/COIN); - result.push_back(Pair("locked",numstr)); - return(result); -} - -UniValue RewardsList() -{ - UniValue result(UniValue::VARR); std::vector txids; struct CCcontract_info *cp,C; uint256 txid,hashBlock; CTransaction vintx; uint64_t sbits,APR,minseconds,maxseconds,mindeposit; char str[65]; - cp = CCinit(&C,EVAL_REWARDS); - SetCCtxids(txids,cp->normaladdr,false,cp->evalcode,zeroid,'F'); - for (std::vector::const_iterator it=txids.begin(); it!=txids.end(); it++) - { - txid = *it; - if ( myGetTransaction(txid,vintx,hashBlock) != 0 ) - { - if ( vintx.vout.size() > 0 && DecodeRewardsFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) != 0 ) - { - result.push_back(uint256_str(str,txid)); - } - } - } - return(result); -} - -std::string RewardsCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t APR,int64_t minseconds,int64_t maxseconds,int64_t mindeposit) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C; - if ( funds < COIN || mindeposit < 0 || minseconds < 0 || maxseconds < 0 ) - { - fprintf(stderr,"negative parameter error\n"); - return(""); - } - if ( APR > REWARDSCC_MAXAPR ) - { - fprintf(stderr,"25%% APR is maximum\n"); - return(""); - } - cp = CCinit(&C,EVAL_REWARDS); - if ( txfee == 0 ) - txfee = 10000; - mypk = pubkey2pk(Mypubkey()); - rewardspk = GetUnspendable(cp,0); - sbits = stringbits(planstr); - if ( RewardsPlanExists(cp,sbits,rewardspk,a,b,c,d) != 0 ) - { - fprintf(stderr,"Rewards plan (%s) already exists\n",planstr); - return(""); - } - if ( AddNormalinputs(mtx,mypk,funds+2*txfee,64) > 0 ) - { - mtx.vout.push_back(MakeCC1vout(cp->evalcode,funds,rewardspk)); - mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(rewardspk)) << OP_CHECKSIG)); - return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeRewardsFundingOpRet('F',sbits,APR,minseconds,maxseconds,mindeposit))); - } - fprintf(stderr,"cant find enough inputs\n"); - return(""); -} - -std::string RewardsAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C; - if ( amount < 0 ) - { - fprintf(stderr,"negative parameter error\n"); - return(""); - } - cp = CCinit(&C,EVAL_REWARDS); - if ( txfee == 0 ) - txfee = 10000; - mypk = pubkey2pk(Mypubkey()); - rewardspk = GetUnspendable(cp,0); - sbits = stringbits(planstr); - if ( RewardsPlanExists(cp,sbits,rewardspk,a,b,c,d) == 0 ) - { - CCerror = strprintf("Rewards plan %s doesnt exist\n",planstr); - fprintf(stderr,"%s\n",CCerror.c_str()); - return(""); - } - sbits = stringbits(planstr); - if ( AddNormalinputs(mtx,mypk,amount+txfee,64) > 0 ) - { - mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,rewardspk)); - return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeRewardsOpRet('A',sbits,fundingtxid))); - } else { - CCerror = "cant find enough inputs"; - fprintf(stderr,"%s\n", CCerror.c_str()); - } - CCerror = "cant find fundingtxid"; - fprintf(stderr,"%s\n", CCerror.c_str()); - return(""); -} - -std::string RewardsLock(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t deposit) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk,rewardspk; CScript opret; uint64_t lockedfunds,sbits,funding,APR,minseconds,maxseconds,mindeposit; struct CCcontract_info *cp,C; - if ( deposit < txfee ) - { - CCerror = "deposit amount less than txfee"; - fprintf(stderr,"%s\n",CCerror.c_str()); - return(""); - } - cp = CCinit(&C,EVAL_REWARDS); - if ( txfee == 0 ) - txfee = 10000; - mypk = pubkey2pk(Mypubkey()); - rewardspk = GetUnspendable(cp,0); - sbits = stringbits(planstr); - if ( RewardsPlanExists(cp,sbits,rewardspk,APR,minseconds,maxseconds,mindeposit) == 0 ) - { - CCerror = strprintf("Rewards plan %s doesnt exist\n",planstr); - fprintf(stderr,"%s\n",CCerror.c_str()); - return(""); - } - if ( deposit < mindeposit ) - { - CCerror = strprintf("Rewards plan %s deposit %.8f < mindeposit %.8f\n",planstr,(double)deposit/COIN,(double)mindeposit/COIN); - fprintf(stderr,"%s\n",CCerror.c_str()); - return(""); - } - if ( (funding= RewardsPlanFunds(lockedfunds,sbits,cp,rewardspk,fundingtxid)) >= deposit ) // arbitrary cmpval - { - if ( AddNormalinputs(mtx,mypk,deposit+2*txfee,64) > 0 ) - { - mtx.vout.push_back(MakeCC1vout(cp->evalcode,deposit,rewardspk)); - mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeRewardsOpRet('L',sbits,fundingtxid))); - } else { - CCerror = strprintf("cant find enough inputs %.8f not enough for %.8f, make sure you imported privkey for the -pubkey address\n",(double)funding/COIN,(double)deposit/COIN); - fprintf(stderr,"%s\n",CCerror.c_str()); - } - } - fprintf(stderr,"cant find rewards inputs funding %.8f locked %.8f vs deposit %.8f\n",(double)funding/COIN,(double)lockedfunds/COIN,(double)deposit/COIN); - return(""); -} - -std::string RewardsUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 locktxid) -{ - CMutableTransaction firstmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CTransaction tx; char coinaddr[64]; CPubKey mypk,rewardspk; CScript scriptPubKey,ignore; uint256 hashBlock; uint64_t sbits,APR,minseconds,maxseconds,mindeposit; int64_t funding,reward=0,amount=0,inputs,CCchange=0; struct CCcontract_info *cp,C; - cp = CCinit(&C,EVAL_REWARDS); - if ( txfee == 0 ) - txfee = 10000; - rewardspk = GetUnspendable(cp,0); - mypk = pubkey2pk(Mypubkey()); - sbits = stringbits(planstr); - if ( locktxid == fundingtxid ) - { - fprintf(stderr,"Rewards plan cant unlock fundingtxid\n"); - CCerror = "Rewards plan cant unlock fundingtxid"; - return(""); - } - if ( RewardsPlanExists(cp,sbits,rewardspk,APR,minseconds,maxseconds,mindeposit) == 0 ) - { - fprintf(stderr,"Rewards plan %s doesnt exist\n",planstr); - CCerror = "Rewards plan does not exist"; - return(""); - } - fprintf(stderr,"APR %.8f minseconds.%llu maxseconds.%llu mindeposit %.8f\n",(double)APR/COIN,(long long)minseconds,(long long)maxseconds,(double)mindeposit/COIN); - if ( locktxid == zeroid ) - amount = AddRewardsInputs(scriptPubKey,maxseconds,cp,mtx,rewardspk,(1LL << 30),1,sbits,fundingtxid); - else - { - GetCCaddress(cp,coinaddr,rewardspk); - if ( (amount= CCutxovalue(coinaddr,locktxid,0,1)) == 0 ) - { - fprintf(stderr,"%s locktxid/v0 is spent\n",coinaddr); - CCerror = "locktxid/v0 is spent"; - return(""); - } - if ( myGetTransaction(locktxid,tx,hashBlock) != 0 && tx.vout.size() > 0 && tx.vout[1].scriptPubKey.IsPayToCryptoCondition() == 0 ) - { - scriptPubKey = tx.vout[1].scriptPubKey; - mtx.vin.push_back(CTxIn(locktxid,0,CScript())); - } - else - { - fprintf(stderr,"%s no normal vout.1 in locktxid\n",coinaddr); - CCerror = "no normal vout.1 in locktxid"; - return(""); - } - } - if ( amount > txfee ) - { - reward = RewardsCalc((int64_t)amount,mtx.vin[0].prevout.hash,(int64_t)APR,(int64_t)minseconds,(int64_t)maxseconds,hush_chainactive_timestamp()); - if ( scriptPubKey.size() > 0 ) - { - if ( reward > txfee ) - { - firstmtx = mtx; - if ( (inputs= AddRewardsInputs(ignore,0,cp,mtx,rewardspk,reward+txfee,30,sbits,fundingtxid)) >= reward+txfee ) - { - if ( inputs >= (reward + 2*txfee) ) - CCchange = (inputs - (reward + txfee)); - fprintf(stderr,"inputs %.8f CCchange %.8f amount %.8f reward %.8f\n",(double)inputs/COIN,(double)CCchange/COIN,(double)amount/COIN,(double)reward/COIN); - mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,rewardspk)); - mtx.vout.push_back(CTxOut(amount+reward,scriptPubKey)); - return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,EncodeRewardsOpRet('U',sbits,fundingtxid))); - } - else - { - firstmtx.vout.push_back(CTxOut(amount-txfee*2,scriptPubKey)); - fprintf(stderr,"not enough rewards funds to payout %.8f, recover mode tx\n",(double)(reward+txfee)/COIN); - return(FinalizeCCTx(-1LL,cp,firstmtx,mypk,txfee,EncodeRewardsOpRet('U',sbits,fundingtxid))); - } - } - else - { - CCerror = strprintf("reward %.8f is <= the transaction fee", reward); - fprintf(stderr,"%s\n", CCerror.c_str()); - } - } - else - { - CCerror = "invalid scriptPubKey"; - fprintf(stderr,"%s\n", CCerror.c_str()); - } - } - else - { - CCerror = "amount must be more than txfee"; - fprintf(stderr,"%s\n", CCerror.c_str()); - } - fprintf(stderr,"amount %.8f -> reward %.8f\n",(double)amount/COIN,(double)reward/COIN); - return(""); -} diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 1fd035660..bde315159 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -410,15 +410,6 @@ static const CRPCCommand vRPCCommands[] = { "nSPV", "nspv_logout", &nspv_logout, true }, { "nSPV", "nspv_listccmoduleunspent", &nspv_listccmoduleunspent, true }, - // rewards - { "rewards", "rewardslist", &rewardslist, true }, - { "rewards", "rewardsinfo", &rewardsinfo, true }, - { "rewards", "rewardscreatefunding", &rewardscreatefunding, true }, - { "rewards", "rewardsaddfunding", &rewardsaddfunding, true }, - { "rewards", "rewardslock", &rewardslock, true }, - { "rewards", "rewardsunlock", &rewardsunlock, true }, - { "rewards", "rewardsaddress", &rewardsaddress, true }, - // faucet { "faucet", "faucetinfo", &faucetinfo, true }, { "faucet", "faucetfund", &faucetfund, true }, @@ -448,18 +439,6 @@ static const CRPCCommand vRPCCommands[] = { "oracles", "oraclessample", &oraclessample, true }, { "oracles", "oraclessamples", &oraclessamples, true }, - // Payments - { "payments", "paymentsaddress", &paymentsaddress, true }, - { "payments", "paymentstxidopret", &payments_txidopret, true }, - { "payments", "paymentscreate", &payments_create, true }, - { "payments", "paymentsairdrop", &payments_airdrop, true }, - { "payments", "paymentsairdroptokens", &payments_airdroptokens, true }, - { "payments", "paymentslist", &payments_list, true }, - { "payments", "paymentsinfo", &payments_info, true }, - { "payments", "paymentsfund", &payments_fund, true }, - { "payments", "paymentsmerge", &payments_merge, true }, - { "payments", "paymentsrelease", &payments_release, true }, - { "CClib", "cclibaddress", &cclibaddress, true }, { "CClib", "cclibinfo", &cclibinfo, true }, { "CClib", "cclib", &cclib, true }, diff --git a/src/rpc/server.h b/src/rpc/server.h index d805fab63..fc83515c1 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -270,16 +270,6 @@ extern UniValue oraclessubscribe(const UniValue& params, bool fHelp, const CPubK extern UniValue oraclesdata(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue oraclessample(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue oraclessamples(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue paymentsaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue payments_release(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue payments_fund(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue payments_merge(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue payments_txidopret(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue payments_create(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue payments_airdrop(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue payments_airdroptokens(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue payments_info(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue payments_list(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue cclibaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue cclibinfo(const UniValue& params, bool fHelp, const CPubKey& mypk); @@ -296,13 +286,6 @@ extern UniValue faucetfund(const UniValue& params, bool fHelp, const CPubKey& my extern UniValue faucetget(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue faucetaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue faucetinfo(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue rewardsinfo(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue rewardslist(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue rewardsaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue rewardscreatefunding(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue rewardsaddfunding(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue rewardslock(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue rewardsunlock(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue FSMaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue FSMcreate(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue FSMlist(const UniValue& params, bool fHelp, const CPubKey& mypk); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index d725fa7b7..9f0c6beb2 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -6091,13 +6091,11 @@ int32_t hush_notaryvin(CMutableTransaction &txNew,uint8_t *notarypub33, void *pT #include "../cc/CCfaucet.h" #include "../cc/CCassets.h" -#include "../cc/CCrewards.h" #include "../cc/CCfsm.h" #include "../cc/CCauction.h" #include "../cc/CCOracles.h" #include "../cc/CCPrices.h" #include "../cc/CCHeir.h" -#include "../cc/CCPayments.h" int32_t ensure_CCrequirements(uint8_t evalcode) { CCerror = ""; @@ -6326,123 +6324,6 @@ UniValue cclib(const UniValue& params, bool fHelp, const CPubKey& mypk) return(CClib(cp,method,jsonstr)); } -UniValue payments_release(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - struct CCcontract_info *cp,C; - if ( fHelp || params.size() != 1 ) - throw runtime_error("paymentsrelease \"[%22createtxid%22,amount,(skipminimum)]\"\n"); - if ( ensure_CCrequirements(EVAL_PAYMENTS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - const CKeyStore& keystore = *pwalletMain; - LOCK2(cs_main, pwalletMain->cs_wallet); - cp = CCinit(&C,EVAL_PAYMENTS); - return(PaymentsRelease(cp,(char *)params[0].get_str().c_str())); -} - -UniValue payments_fund(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - struct CCcontract_info *cp,C; - if ( fHelp || params.size() != 1 ) - throw runtime_error("paymentsfund \"[%22createtxid%22,amount(,useopret)]\"\n"); - if ( ensure_CCrequirements(EVAL_PAYMENTS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - const CKeyStore& keystore = *pwalletMain; - LOCK2(cs_main, pwalletMain->cs_wallet); - cp = CCinit(&C,EVAL_PAYMENTS); - return(PaymentsFund(cp,(char *)params[0].get_str().c_str())); -} - -UniValue payments_merge(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - struct CCcontract_info *cp,C; - if ( fHelp || params.size() != 1 ) - throw runtime_error("paymentsmerge \"[%22createtxid%22]\"\n"); - if ( ensure_CCrequirements(EVAL_PAYMENTS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - const CKeyStore& keystore = *pwalletMain; - LOCK2(cs_main, pwalletMain->cs_wallet); - cp = CCinit(&C,EVAL_PAYMENTS); - return(PaymentsMerge(cp,(char *)params[0].get_str().c_str())); -} - -UniValue payments_txidopret(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - struct CCcontract_info *cp,C; - if ( fHelp || params.size() != 1 ) - throw runtime_error("paymentstxidopret \"[allocation,%22scriptPubKey%22(,%22destopret%22)]\"\n"); - if ( ensure_CCrequirements(EVAL_PAYMENTS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - const CKeyStore& keystore = *pwalletMain; - LOCK2(cs_main, pwalletMain->cs_wallet); - cp = CCinit(&C,EVAL_PAYMENTS); - return(PaymentsTxidopret(cp,(char *)params[0].get_str().c_str())); -} - -UniValue payments_create(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - struct CCcontract_info *cp,C; - if ( fHelp || params.size() != 1 ) - throw runtime_error("paymentscreate \"[lockedblocks,minamount,%22paytxid0%22,...,%22paytxidN%22]\"\n"); - if ( ensure_CCrequirements(EVAL_PAYMENTS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - const CKeyStore& keystore = *pwalletMain; - LOCK2(cs_main, pwalletMain->cs_wallet); - cp = CCinit(&C,EVAL_PAYMENTS); - return(PaymentsCreate(cp,(char *)params[0].get_str().c_str())); -} - -UniValue payments_airdrop(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - struct CCcontract_info *cp,C; - if ( fHelp || params.size() != 1 ) - throw runtime_error("paymentsairdrop \"[lockedblocks,minamount,mintoaddress,top,bottom,fixedFlag,%22excludeAddress%22,...,%22excludeAddressN%22]\"\n"); - if ( ensure_CCrequirements(EVAL_PAYMENTS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - const CKeyStore& keystore = *pwalletMain; - LOCK2(cs_main, pwalletMain->cs_wallet); - cp = CCinit(&C,EVAL_PAYMENTS); - return(PaymentsAirdrop(cp,(char *)params[0].get_str().c_str())); -} - -UniValue payments_airdroptokens(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - struct CCcontract_info *cp,C; - if ( fHelp || params.size() != 1 ) - throw runtime_error("payments_airdroptokens \"[%22tokenid%22,lockedblocks,minamount,mintoaddress,top,bottom,fixedFlag,%22excludePubKey%22,...,%22excludePubKeyN%22]\"\n"); - if ( ensure_CCrequirements(EVAL_PAYMENTS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - const CKeyStore& keystore = *pwalletMain; - LOCK2(cs_main, pwalletMain->cs_wallet); - cp = CCinit(&C,EVAL_PAYMENTS); - return(PaymentsAirdropTokens(cp,(char *)params[0].get_str().c_str())); -} - -UniValue payments_info(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - struct CCcontract_info *cp,C; - if ( fHelp || params.size() != 1 ) - throw runtime_error("paymentsinfo \"[%22createtxid%22]\"\n"); - if ( ensure_CCrequirements(EVAL_PAYMENTS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - const CKeyStore& keystore = *pwalletMain; - LOCK2(cs_main, pwalletMain->cs_wallet); - cp = CCinit(&C,EVAL_PAYMENTS); - return(PaymentsInfo(cp,(char *)params[0].get_str().c_str())); -} - -UniValue payments_list(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - struct CCcontract_info *cp,C; - if ( fHelp || params.size() != 0 ) - throw runtime_error("paymentslist\n"); - if ( ensure_CCrequirements(EVAL_PAYMENTS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - const CKeyStore& keystore = *pwalletMain; - LOCK2(cs_main, pwalletMain->cs_wallet); - cp = CCinit(&C,EVAL_PAYMENTS); - return(PaymentsList(cp,(char *)"")); -} - UniValue oraclesaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) { struct CCcontract_info *cp,C; std::vector pubkey; @@ -6456,19 +6337,6 @@ UniValue oraclesaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) return(CCaddress(cp,(char *)"Oracles",pubkey)); } -UniValue paymentsaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - struct CCcontract_info *cp,C; std::vector pubkey; - cp = CCinit(&C,EVAL_PAYMENTS); - if ( fHelp || params.size() > 1 ) - throw runtime_error("paymentsaddress [pubkey]\n"); - if ( ensure_CCrequirements(cp->evalcode) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - if ( params.size() == 1 ) - pubkey = ParseHex(params[0].get_str().c_str()); - return(CCaddress(cp,(char *)"Payments",pubkey)); -} - UniValue heiraddress(const UniValue& params, bool fHelp, const CPubKey& mypk) { struct CCcontract_info *cp,C; std::vector pubkey; @@ -6522,19 +6390,6 @@ UniValue faucetaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) return(CCaddress(cp,(char *)"Faucet",pubkey)); } -UniValue rewardsaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - struct CCcontract_info *cp,C; std::vector pubkey; - cp = CCinit(&C,EVAL_REWARDS); - if ( fHelp || params.size() > 1 ) - throw runtime_error("rewardsaddress [pubkey]\n"); - if ( ensure_CCrequirements(cp->evalcode) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - if ( params.size() == 1 ) - pubkey = ParseHex(params[0].get_str().c_str()); - return(CCaddress(cp,(char *)"Rewards",pubkey)); -} - UniValue assetsaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) { struct CCcontract_info *cp, C; std::vector pubkey; @@ -6561,195 +6416,6 @@ UniValue tokenaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) return(CCaddress(cp,(char *)"Tokens", pubkey)); } -UniValue rewardscreatefunding(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); char *name; int64_t funds,APR,minseconds,maxseconds,mindeposit; std::string hex; - if ( fHelp || params.size() > 6 || params.size() < 2 ) - throw runtime_error("rewardscreatefunding name amount APR mindays maxdays mindeposit\n"); - if ( ensure_CCrequirements(EVAL_REWARDS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - const CKeyStore& keystore = *pwalletMain; - LOCK2(cs_main, pwalletMain->cs_wallet); - // default to OOT params - APR = 5 * COIN; - minseconds = maxseconds = 60 * 3600 * 24; - mindeposit = 100 * COIN; - name = (char *)params[0].get_str().c_str(); - funds = atof(params[1].get_str().c_str()) * COIN + 0.00000000499999; - - if (!VALID_PLAN_NAME(name)) { - ERR_RESULT(strprintf("Plan name can be at most %d ASCII characters",PLAN_NAME_MAX)); - return(result); - } - - if ( funds <= 0 ) { - ERR_RESULT("funds must be positive"); - return result; - } - if ( params.size() > 2 ) - { - APR = atof(params[2].get_str().c_str()) * COIN; - if ( APR > REWARDSCC_MAXAPR ) - { - ERR_RESULT("25% APR is maximum"); - return result; - } - if ( params.size() > 3 ) - { - minseconds = atol(params[3].get_str().c_str()) * 3600 * 24; - if ( minseconds < 0 ) { - ERR_RESULT("mindays must be non-negative"); - return result; - } - if ( params.size() > 4 ) - { - maxseconds = atol(params[4].get_str().c_str()) * 3600 * 24; - if ( maxseconds <= 0 ) { - ERR_RESULT("maxdays must be positive"); - return result; - } - if ( maxseconds < minseconds ) { - ERR_RESULT("maxdays must be greater than mindays"); - return result; - } - if ( params.size() > 5 ) - mindeposit = atof(params[5].get_str().c_str()) * COIN + 0.00000000499999; - if ( mindeposit <= 0 ) { - ERR_RESULT("mindeposit must be positive"); - return result; - } - } - } - } - hex = RewardsCreateFunding(0,name,funds,APR,minseconds,maxseconds,mindeposit); - if ( hex.size() > 0 ) - { - result.push_back(Pair("result", "success")); - result.push_back(Pair("hex", hex)); - } else ERR_RESULT("couldnt create rewards funding transaction"); - return(result); -} - -UniValue rewardslock(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); char *name; uint256 fundingtxid; int64_t amount; std::string hex; - if ( fHelp || params.size() != 3 ) - throw runtime_error("rewardslock name fundingtxid amount\n"); - if ( ensure_CCrequirements(EVAL_REWARDS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - const CKeyStore& keystore = *pwalletMain; - LOCK2(cs_main, pwalletMain->cs_wallet); - name = (char *)params[0].get_str().c_str(); - fundingtxid = Parseuint256((char *)params[1].get_str().c_str()); - amount = atof(params[2].get_str().c_str()) * COIN + 0.00000000499999; - hex = RewardsLock(0,name,fundingtxid,amount); - - if (!VALID_PLAN_NAME(name)) { - ERR_RESULT(strprintf("Plan name can be at most %d ASCII characters",PLAN_NAME_MAX)); - return(result); - } - if ( CCerror != "" ){ - ERR_RESULT(CCerror); - } else if ( amount > 0 ) { - if ( hex.size() > 0 ) - { - result.push_back(Pair("result", "success")); - result.push_back(Pair("hex", hex)); - } else ERR_RESULT( "couldnt create rewards lock transaction"); - } else ERR_RESULT("amount must be positive"); - return(result); -} - -UniValue rewardsaddfunding(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); char *name; uint256 fundingtxid; int64_t amount; std::string hex; - if ( fHelp || params.size() != 3 ) - throw runtime_error("rewardsaddfunding name fundingtxid amount\n"); - if ( ensure_CCrequirements(EVAL_REWARDS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - const CKeyStore& keystore = *pwalletMain; - LOCK2(cs_main, pwalletMain->cs_wallet); - name = (char *)params[0].get_str().c_str(); - fundingtxid = Parseuint256((char *)params[1].get_str().c_str()); - amount = atof(params[2].get_str().c_str()) * COIN + 0.00000000499999; - hex = RewardsAddfunding(0,name,fundingtxid,amount); - - if (!VALID_PLAN_NAME(name)) { - ERR_RESULT(strprintf("Plan name can be at most %d ASCII characters",PLAN_NAME_MAX)); - return(result); - } - if (CCerror != "") { - ERR_RESULT(CCerror); - } else if (amount > 0) { - if ( hex.size() > 0 ) - { - result.push_back(Pair("result", "success")); - result.push_back(Pair("hex", hex)); - } else { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "couldnt create rewards addfunding transaction")); - } - } else { - ERR_RESULT("funding amount must be positive"); - } - return(result); -} - -UniValue rewardsunlock(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); std::string hex; char *name; uint256 fundingtxid,txid; - if ( fHelp || params.size() > 3 || params.size() < 2 ) - throw runtime_error("rewardsunlock name fundingtxid [txid]\n"); - if ( ensure_CCrequirements(EVAL_REWARDS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - const CKeyStore& keystore = *pwalletMain; - LOCK2(cs_main, pwalletMain->cs_wallet); - name = (char *)params[0].get_str().c_str(); - fundingtxid = Parseuint256((char *)params[1].get_str().c_str()); - - if (!VALID_PLAN_NAME(name)) { - ERR_RESULT(strprintf("Plan name can be at most %d ASCII characters",PLAN_NAME_MAX)); - return(result); - } - if ( params.size() > 2 ) - txid = Parseuint256((char *)params[2].get_str().c_str()); - else memset(&txid,0,sizeof(txid)); - hex = RewardsUnlock(0,name,fundingtxid,txid); - if (CCerror != "") { - ERR_RESULT(CCerror); - } else if ( hex.size() > 0 ) { - result.push_back(Pair("result", "success")); - result.push_back(Pair("hex", hex)); - } else ERR_RESULT("couldnt create rewards unlock transaction"); - return(result); -} - -UniValue rewardslist(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if ( fHelp || params.size() > 0 ) - throw runtime_error("rewardslist\n"); - if ( ensure_CCrequirements(EVAL_REWARDS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - const CKeyStore& keystore = *pwalletMain; - LOCK2(cs_main, pwalletMain->cs_wallet); - return(RewardsList()); -} - -UniValue rewardsinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - uint256 fundingtxid; - if ( fHelp || params.size() != 1 ) - throw runtime_error("rewardsinfo fundingtxid\n"); - if ( ensure_CCrequirements(EVAL_REWARDS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - const CKeyStore& keystore = *pwalletMain; - LOCK2(cs_main, pwalletMain->cs_wallet); - fundingtxid = Parseuint256((char *)params[0].get_str().c_str()); - return(RewardsInfo(fundingtxid)); -} - - - UniValue oracleslist(const UniValue& params, bool fHelp, const CPubKey& mypk) { if ( fHelp || params.size() > 0 )