Merge pull request #1622 from DeckerSU/patch-createrawtransaction

createrawtransaction enchancement
This commit is contained in:
jl777
2019-07-17 19:03:35 -11:00
committed by GitHub
4 changed files with 421 additions and 32 deletions

338
src/ac.json Normal file
View File

@@ -0,0 +1,338 @@
{
"REVS": {
"ac_supply": "1300000"
}
,
"SUPERNET": {
"ac_supply": "816061"
}
,
"DEX": {
"ac_supply": "999999"
}
,
"PANGEA": {
"ac_supply": "999999"
}
,
"JUMBLR": {
"ac_supply": "999999"
}
,
"BET": {
"ac_supply": "999999"
}
,
"CRYPTO": {
"ac_supply": "999999"
}
,
"HODL": {
"ac_supply": "9999999"
}
,
"MSHARK": {
"ac_supply": "1400000"
}
,
"BOTS": {
"ac_supply": "999999"
}
,
"MGW": {
"ac_supply": "999999"
}
,
"COQUICASH": {
"ac_supply": "72000000",
"ac_reward": "7200000000",
"ac_staked": "50",
"ac_halving": "420000",
"ac_cc": "2",
"ac_ccenable": "227,235,236,241",
"addnode": [
"78.47.108.168"
]
}
,
"WLC": {
"ac_supply": "210000000"
}
,
"KV": {
"ac_supply": "1000000"
}
,
"CEAL": {
"ac_supply": "366666666"
}
,
"MESH": {
"ac_supply": "1000007"
}
,
"AXO": {
"ac_supply": "200000000",
"ac_ccactivate": "130000"
}
,
"ETOMIC": {
"ac_supply": "100000000"
}
,
"BTCH": {
"ac_supply": "20998641"
}
,
"PIZZA": {
"ac_supply": "100000000"
}
,
"BEER": {
"ac_supply": "100000000"
}
,
"NINJA": {
"ac_supply": "100000000"
}
,
"OOT": {
"ac_supply": "216000000",
"ac_sapling": "5000000"
}
,
"BNTN": {
"ac_supply": "500000000"
}
,
"CHAIN": {
"ac_supply": "999999"
}
,
"PRLPAY": {
"ac_supply": "500000000"
}
,
"DSEC": {
"ac_supply": "7000000"
}
,
"GLXT": {
"ac_supply": "10000000000"
}
,
"EQL": {
"ac_supply": "500000000",
"ac_ccactivate": "205000"
}
,
"ZILLA": {
"ac_supply": "11000000",
"ac_sapling": "5000000",
"addnode": [
"51.68.215.104"
]
}
,
"RFOX": {
"ac_supply": "1000000000",
"ac_reward": "100000000"
}
,
"SEC": {
"ac_supply": "1000000000",
"ac_cc": "333"
}
,
"CCL": {
"ac_supply": "200000000",
"ac_end": "1",
"ac_cc": "2",
"addressindex": "1",
"spentindex": "1",
"addnode": [
"142.93.136.89",
"195.201.22.89"
]
}
,
"PIRATE": {
"ac_supply": "0",
"ac_reward": "25600000000",
"ac_halving": "77777",
"ac_private": "1",
"addnode": [
"136.243.102.225"
]
}
,
"PGT": {
"ac_supply": "10000000",
"ac_end": "1",
"addnode": [
"190.114.254.104"
]
}
,
"DION": {
"ac_supply": "3900000000",
"ac_reward": "22260000000",
"ac_staked": "100",
"ac_cc": "1",
"ac_end": "4300000000",
"addnode": [
"51.75.124.34"
]
}
,
"KMDICE": {
"ac_supply": "10500000",
"ac_reward": "2500000000",
"ac_halving": "210000",
"ac_cc": "2",
"addressindex": "1",
"spentindex": "1",
"addnode": [
"144.76.217.232"
]
}
,
"KSB": {
"ac_supply": "1000000000",
"ac_end": "1",
"ac_public": "1",
"addnode": [
"37.187.225.231"
]
}
,
"OUR": {
"ac_reward": "1478310502",
"ac_halving": "525600",
"ac_cc": "42",
"ac_supply": "100000000",
"ac_perc": "77700",
"ac_staked": "93",
"ac_pubkey": "02652a3f3e00b3a1875a918314f0bac838d6dd189a346fa623f5efe9541ac0b98c",
"ac_public": "1",
"addnode": [
"51.255.195.65",
"217.182.129.38",
"37.187.225.231"
]
}
,
"ILN": {
"ac_supply": "10000000000",
"ac_cc": "2",
"addnode": ["51.75.122.83"]
}
,
"RICK": {
"ac_supply": "90000000000",
"ac_reward": "100000000",
"ac_cc": "3",
"addnode": ["138.201.136.145"]
}
,
"MORTY": {
"ac_supply": "90000000000",
"ac_reward": "100000000",
"ac_cc": "3",
"addnode": ["138.201.136.145"]
}
,
"KOIN": {
"ac_supply": "125000000",
"addnode": ["3.0.32.10"]
}
,
"ZEXO": {
"ac_reward": "1478310502",
"ac_halving": "525600",
"ac_cc": "42",
"ac_ccenable": "236",
"ac_supply": "100000000",
"ac_perc": "77700",
"ac_staked": "93",
"ac_pubkey": "02713bd85e054db923694b6b7a85306264edf4d6bd6d331814f2b40af444b3ebbc",
"ac_public": "1",
"addnode": [
"195.201.20.230",
"80.240.17.222"
]
}
,
"K64": {
"ac_reward": "0",
"ac_supply": "64000777",
"ac_staked": "10",
"addnode": ["18.197.20.21"]
}
,
"HUSH3": {
"ac_sapling": "1",
"ac_founders": "1",
"ac_reward": "0,1125000000,562500000",
"ac_end": "128,340000,5422111",
"ac_blocktime": "150",
"ac_supply": "6178674",
"ac_halving": "129,340000,840000",
"ac_cc": "2",
"ac_cclib": "hush3",
"ac_ccenable": "228,234,235,236,241",
"ac_perc": "11111111",
"ac_eras": "3",
"ac_script": "76a9145eb10cf64f2bab1b457f1f25e658526155928fac88ac",
"clientname": "GoldenSandtrout",
"addnode": [
"188.165.212.101",
"136.243.227.142",
"5.9.224.250"
]
}
}

View File

@@ -44,9 +44,16 @@
"ac_supply": "999999" "ac_supply": "999999"
}, },
{ {
"ac_name": "COQUI", "ac_name": "COQUICASH",
"ac_supply": "72000000", "ac_supply": "72000000",
"ac_ccactivate": "200000" "ac_reward": "7200000000",
"ac_staked": "50",
"ac_halving": "420000",
"ac_cc": "2",
"ac_ccenable": "227,235,236,241",
"addnode": [
"78.47.108.168"
]
}, },
{ {
"ac_name": "WLC", "ac_name": "WLC",
@@ -235,12 +242,6 @@
"ac_cc": "3", "ac_cc": "3",
"addnode": ["138.201.136.145"] "addnode": ["138.201.136.145"]
}, },
{
"ac_name": "VOTE2019",
"ac_supply": "123651638",
"ac_public": "1",
"addnode": ["95.213.238.98"]
},
{ {
"ac_name": "KOIN", "ac_name": "KOIN",
"ac_supply": "125000000", "ac_supply": "125000000",

View File

@@ -1908,13 +1908,15 @@ void komodo_args(char *argv0)
} }
if ( ASSETCHAINS_CC != 0 ) if ( ASSETCHAINS_CC != 0 )
{ {
uint8_t prevCCi = 0;
ASSETCHAINS_CCLIB = GetArg("-ac_cclib",""); ASSETCHAINS_CCLIB = GetArg("-ac_cclib","");
Split(GetArg("-ac_ccenable",""), sizeof(ccenables)/sizeof(*ccenables), ccenables, 0); Split(GetArg("-ac_ccenable",""), sizeof(ccenables)/sizeof(*ccenables), ccenables, 0);
for (i=nonz=0; i<0x100; i++) for (i=nonz=0; i<0x100; i++)
{ {
if ( ccenables[i] != 0 ) if ( ccenables[i] != prevCCi && ccenables[i] != 0 )
{ {
nonz++; nonz++;
prevCCi = ccenables[i];
fprintf(stderr,"%d ",(uint8_t)(ccenables[i] & 0xff)); fprintf(stderr,"%d ",(uint8_t)(ccenables[i] & 0xff));
} }
} }
@@ -1926,11 +1928,12 @@ void komodo_args(char *argv0)
ASSETCHAINS_CCDISABLES[i] = 1; ASSETCHAINS_CCDISABLES[i] = 1;
SETBIT(disablebits,i); SETBIT(disablebits,i);
} }
for (i=0; i<256; i++) for (i=0; i<nonz; i++)
{ {
CLEARBIT(disablebits,(ccenables[i] & 0xff)); CLEARBIT(disablebits,(ccenables[i] & 0xff));
ASSETCHAINS_CCDISABLES[ccenables[i] & 0xff] = 0; ASSETCHAINS_CCDISABLES[ccenables[i] & 0xff] = 0;
} }
CLEARBIT(disablebits,0);
} }
/*if ( ASSETCHAINS_CCLIB.size() > 0 ) /*if ( ASSETCHAINS_CCLIB.size() > 0 )
{ {

View File

@@ -727,27 +727,31 @@ UniValue verifytxoutproof(const UniValue& params, bool fHelp)
UniValue createrawtransaction(const UniValue& params, bool fHelp) UniValue createrawtransaction(const UniValue& params, bool fHelp)
{ {
string examplescriptPubKey = "21021ce1eac70455c3e6c52d67c133549b8aed4a588fba594372e8048e65c4f0fcb6ac";
if (fHelp || params.size() < 2 || params.size() > 4) if (fHelp || params.size() < 2 || params.size() > 4)
throw runtime_error( throw runtime_error(
"createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,...} ( locktime ) ( expiryheight )\n" "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,...} ( locktime ) ( expiryheight )\n"
"\nCreate a transaction spending the given inputs and sending to the given addresses.\n" "\nCreate a transaction spending the given inputs and creating new outputs.\n"
"Outputs can be addresses or standart scripts (in hex) or data.\n"
"Returns hex-encoded raw transaction.\n" "Returns hex-encoded raw transaction.\n"
"Note that the transaction's inputs are not signed, and\n" "Note that the transaction's inputs are not signed, and\n"
"it is not stored in the wallet or transmitted to the network.\n" "it is not stored in the wallet or transmitted to the network.\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"transactions\" (string, required) A json array of json objects\n" "1. \"inputs\" (array, required) A json array of json objects\n"
" [\n" " [\n"
" {\n" " {\n"
" \"txid\":\"id\", (string, required) The transaction id\n" " \"txid\":\"id\", (string, required) The transaction id\n"
" \"vout\":n (numeric, required) The output number\n" " \"vout\":n, (numeric, required) The output number\n"
" \"sequence\":n (numeric, optional) The sequence number\n" " \"sequence\":n (numeric, optional) The sequence number\n"
" }\n" " } \n"
" ,...\n" " ,...\n"
" ]\n" " ]\n"
"2. \"addresses\" (string, required) a json object with addresses as keys and amounts as values\n" "2. \"outputs\" (object, required) a json object with outputs\n"
" {\n" " {\n"
" \"address\": x.xxx (numeric, required) The key is the Komodo address, the value is the " + CURRENCY_UNIT + " amount\n" " \"address\": x.xxx, (numeric or string, required) The key is the komodo address or script (in hex), the numeric value (can be string) is the " + CURRENCY_UNIT + " amount\n"
" \"data\": \"hex\" (string, required) The key is \"data\", the value is hex encoded data\n"
" ,...\n" " ,...\n"
" }\n" " }\n"
"3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n" "3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n"
@@ -757,7 +761,11 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp)
"\nExamples\n" "\nExamples\n"
+ HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"") + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"")
+ HelpExampleRpc("createrawtransaction", "[{\"txid\":\"myid\",\"vout\":0}], {\"address\":0.01}") + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\""+examplescriptPubKey+"\\\":0.01}\"")
+ HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"data\\\":\\\"00010203\\\"}\"")
+ HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"")
+ HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\""+examplescriptPubKey+"\\\":0.01}\"")
+ HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"data\\\":\\\"00010203\\\"}\"")
); );
LOCK(cs_main); LOCK(cs_main);
@@ -817,22 +825,61 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp)
} }
std::set<CTxDestination> destinations; std::set<CTxDestination> destinations;
//std::set<std::string> destinations;
vector<string> addrList = sendTo.getKeys(); vector<string> addrList = sendTo.getKeys();
for (const std::string& name_ : addrList) {
CTxDestination destination = DecodeDestination(name_); if (addrList.size() != sendTo.size()) {
if (!IsValidDestination(destination)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid outputs")); // for checking edge case, should never happened ...
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Komodo address: ") + name_); }
//for (const std::string& name_ : addrList) {
for (size_t idx = 0; idx < sendTo.size(); idx++) {
const std::string& name_ = addrList[idx];
CScript scriptPubKey;
CTxDestination destination;
if (name_ == "data") {
std::vector<unsigned char> data = ParseHexV(sendTo[name_].getValStr(),"Data");
CTxOut out(0, CScript() << OP_RETURN << data);
rawTx.vout.push_back(out);
} else {
destination = DecodeDestination(name_);
if (IsValidDestination(destination)) {
scriptPubKey = GetScriptForDestination(destination);
} else if (IsHex(name_)) {
std::vector<unsigned char> data(ParseHex(name_));
scriptPubKey = CScript(data.begin(), data.end());
// destination is not valid, but we should convert it to valid anyway, to be able to check duplicates,
// so we need to get destination from existing scriptPubKey via ExtractDestination
if (!(ExtractDestination(scriptPubKey, destination) &&
(scriptPubKey.IsPayToPublicKeyHash() || scriptPubKey.IsPayToPublicKey() || scriptPubKey.IsPayToScriptHash())
)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid script: ") + name_ + std::string(" (only P2PKH, P2PK and P2SH scripts are allowed)"));
}
}
else {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Komodo address or script: ") + name_);
}
if (!(fExperimentalMode && IS_KOMODO_NOTARY)) {
// support of sending duplicates in createrawtransaction requires experimental features enabled and
// notary flag, to prevent common users to get messed up with duplicates
//if (!destinations.insert(EncodeDestination(destination)).second) {
if (!destinations.insert(destination).second) {
throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated destination: ") + name_);
}
}
// CAmount nAmount = AmountFromValue(sendTo[name_]); // operator[](const std::string& key) const;
CAmount nAmount = AmountFromValue(sendTo[idx]); // operator[](size_t index) const;
CTxOut out(nAmount, scriptPubKey);
rawTx.vout.push_back(out);
} }
if (!destinations.insert(destination).second) {
throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + name_);
}
CScript scriptPubKey = GetScriptForDestination(destination);
CAmount nAmount = AmountFromValue(sendTo[name_]);
CTxOut out(nAmount, scriptPubKey);
rawTx.vout.push_back(out);
} }
return EncodeHexTx(rawTx); return EncodeHexTx(rawTx);