|
12 | 12 | #include "main.h" |
13 | 13 | #include "net.h" |
14 | 14 | #include "primitives/transaction.h" |
| 15 | +#include "primitives/deterministicmint.h" |
15 | 16 | #include "rpc/server.h" |
16 | 17 | #include "script/script.h" |
17 | 18 | #include "script/script_error.h" |
@@ -912,3 +913,74 @@ UniValue getspentzerocoinamount(const UniValue& params, bool fHelp) |
912 | 913 | CAmount nValue = libzerocoin::ZerocoinDenominationToAmount(spend.getDenomination()); |
913 | 914 | return FormatMoney(nValue); |
914 | 915 | } |
| 916 | + |
| 917 | +#ifdef ENABLE_WALLET |
| 918 | +UniValue createrawzerocoinstake(const UniValue& params, bool fHelp) |
| 919 | +{ |
| 920 | + if (fHelp || params.size() != 1) |
| 921 | + throw runtime_error( |
| 922 | + "createrawzerocoinstake mint_input \n" |
| 923 | + "\nCreates raw zPIV coinstakes (without MN output).\n" + |
| 924 | + HelpRequiringPassphrase() + "\n" |
| 925 | + |
| 926 | + "\nArguments:\n" |
| 927 | + "1. mint_input (hex string, required) serial hash of the mint used as input\n" |
| 928 | + |
| 929 | + "\nResult:\n" |
| 930 | + "\"transaction\" (string) hex string of the transaction\n" |
| 931 | + |
| 932 | + "\nExamples\n" + |
| 933 | + HelpExampleCli("createrawzerocoinstake", "0d8c16eee7737e3cc1e4e70dc006634182b175e039700931283b202715a0818f") + |
| 934 | + HelpExampleRpc("createrawzerocoinstake", "0d8c16eee7737e3cc1e4e70dc006634182b175e039700931283b202715a0818f")); |
| 935 | + |
| 936 | + |
| 937 | + assert(pwalletMain != NULL); |
| 938 | + LOCK2(cs_main, pwalletMain->cs_wallet); |
| 939 | + |
| 940 | + if(GetAdjustedTime() > GetSporkValue(SPORK_16_ZEROCOIN_MAINTENANCE_MODE)) |
| 941 | + throw JSONRPCError(RPC_WALLET_ERROR, "zPIV is currently disabled due to maintenance."); |
| 942 | + |
| 943 | + std::string serial_hash = params[0].get_str(); |
| 944 | + if (!IsHex(serial_hash)) |
| 945 | + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex serial hash"); |
| 946 | + |
| 947 | + EnsureWalletIsUnlocked(); |
| 948 | + |
| 949 | + uint256 hashSerial(serial_hash); |
| 950 | + CZerocoinMint input_mint; |
| 951 | + if (!pwalletMain->GetMint(hashSerial, input_mint)) { |
| 952 | + std::string strErr = "Failed to fetch mint associated with serial hash " + serial_hash; |
| 953 | + throw JSONRPCError(RPC_WALLET_ERROR, strErr); |
| 954 | + } |
| 955 | + |
| 956 | + CMutableTransaction coinstake_tx; |
| 957 | + |
| 958 | + // create the zerocoinmint output (one spent denom + three 1-zPIV denom) |
| 959 | + libzerocoin::CoinDenomination staked_denom = input_mint.GetDenomination(); |
| 960 | + std::vector<CTxOut> vOutMint(4); |
| 961 | + CDeterministicMint dMint; |
| 962 | + if (!pwalletMain->CreateZPIVOutPut(staked_denom, vOutMint[0], dMint)) |
| 963 | + throw JSONRPCError(RPC_WALLET_ERROR, "failed to create new zpiv output"); |
| 964 | + |
| 965 | + for (int i=1; i<4; i++) { |
| 966 | + if (!pwalletMain->CreateZPIVOutPut(libzerocoin::ZQ_ONE, vOutMint[i], dMint)) |
| 967 | + throw JSONRPCError(RPC_WALLET_ERROR, "failed to create new zpiv output"); |
| 968 | + } |
| 969 | + coinstake_tx.vout = vOutMint; |
| 970 | + |
| 971 | + //hash with only the output info in it to be used in Signature of Knowledge |
| 972 | + uint256 hashTxOut = coinstake_tx.GetHash(); |
| 973 | + CZerocoinSpendReceipt receipt; |
| 974 | + |
| 975 | + // create the zerocoinspend input |
| 976 | + CTxIn newTxIn; |
| 977 | + // !TODO: mint checks |
| 978 | + if (!pwalletMain->MintToTxIn(input_mint, 100, hashTxOut, newTxIn, receipt, libzerocoin::SpendType::SPEND)) |
| 979 | + throw JSONRPCError(RPC_WALLET_ERROR, "failed to create zc-spend stake input"); |
| 980 | + |
| 981 | + coinstake_tx.vin.push_back(newTxIn); |
| 982 | + |
| 983 | + return EncodeHexTx(coinstake_tx); |
| 984 | + |
| 985 | +} |
| 986 | +#endif |
0 commit comments