mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-03-13 06:01:45 +00:00
Implemented transfer RPC call.
This commit is contained in:
parent
350f6fa953
commit
b39ed3748d
@ -1221,6 +1221,133 @@ UniValue sendmany(const JSONRPCRequest& request)
|
||||
return wtx.GetHash().GetHex();
|
||||
}
|
||||
|
||||
|
||||
static CAmount AmountFromIntegerValue(const UniValue& value)
|
||||
{
|
||||
if (!value.isNum())
|
||||
throw std::runtime_error("Amount is not a number or string");
|
||||
CAmount amount = value.get_int64();
|
||||
if (!MoneyRange(amount))
|
||||
throw std::runtime_error("Amount out of range");
|
||||
return amount;
|
||||
}
|
||||
|
||||
// Cryptnote JSON RPC
|
||||
UniValue transfer(const JSONRPCRequest& request)
|
||||
{
|
||||
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
|
||||
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
if (request.fHelp || request.params.size() < 1 || request.params.size() > 12)
|
||||
throw std::runtime_error(
|
||||
"transfer [{\"address\":amount,...}, ...] \n"
|
||||
"\nSend multiple times. Amounts are in atomic units."
|
||||
+ HelpRequiringPassphrase(pwallet) + "\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"destinations\" (string, required) A json object with addresses and amounts\n"
|
||||
" [{\n"
|
||||
" \"address\":address (string) The kevacoin address\n"
|
||||
" \"amount\":amount (numeric) The numeric amount in atomic unut\n"
|
||||
" ,...\n"
|
||||
" }, ...]\n"
|
||||
"\nResult:\n"
|
||||
"\"txid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n"
|
||||
" the number of addresses.\n"
|
||||
"\nExamples:\n"
|
||||
"\nSend two amounts to two different addresses:\n"
|
||||
+ HelpExampleCli("sendmany", "\"\" \"{\\\"LEr4hNAefWYhBMgxCFP2Po1NPrUeiK8kM2\\\":0.01,\\\"LbhhnrHHVFP1eUjP1tdNIYeEVsNHfN9FCw\\\":0.02}\"") +
|
||||
"\nSend two amounts to two different addresses setting the confirmation and comment:\n"
|
||||
+ HelpExampleCli("sendmany", "\"\" \"{\\\"LEr4hNAefWYhBMgxCFP2Po1NPrUeiK8kM2\\\":0.01,\\\"LbhhnrHHVFP1eUjP1tdNIYeEVsNHfN9FCw\\\":0.02}\" 6 \"testing\"") +
|
||||
"\nSend two amounts to two different addresses, subtract fee from amount:\n"
|
||||
+ HelpExampleCli("sendmany", "\"\" \"{\\\"LEr4hNAefWYhBMgxCFP2Po1NPrUeiK8kM2\\\":0.01,\\\"LbhhnrHHVFP1eUjP1tdNIYeEVsNHfN9FCw\\\":0.02}\" 1 \"\" \"[\\\"LEr4hNAefWYhBMgxCFP2Po1NPrUeiK8kM2\\\",\\\"LbhhnrHHVFP1eUjP1tdNIYeEVsNHfN9FCw\\\"]\"") +
|
||||
"\nAs a json rpc call\n"
|
||||
+ HelpExampleRpc("sendmany", "\"\", {\"LEr4hNAefWYhBMgxCFP2Po1NPrUeiK8kM2\":0.01,\"LbhhnrHHVFP1eUjP1tdNIYeEVsNHfN9FCw\":0.02}, 6, \"testing\"")
|
||||
);
|
||||
|
||||
ObserveSafeMode();
|
||||
|
||||
// Make sure the results are valid at least up to the most recent block
|
||||
// the user could have gotten from another RPC command prior to now
|
||||
pwallet->BlockUntilSyncedToCurrentChain();
|
||||
|
||||
LOCK2(cs_main, pwallet->cs_wallet);
|
||||
|
||||
if (pwallet->GetBroadcastTransactions() && !g_connman) {
|
||||
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
|
||||
}
|
||||
|
||||
UniValue sendToList = request.params[0].get_array();
|
||||
|
||||
CWalletTx wtx;
|
||||
CCoinControl coin_control;
|
||||
std::set<CTxDestination> destinations;
|
||||
std::vector<CRecipient> vecSend;
|
||||
|
||||
CAmount totalAmount = 0;
|
||||
for (unsigned int idx = 0; idx < sendToList.size(); idx++) {
|
||||
const UniValue& sendTo = sendToList[idx].get_obj();
|
||||
const UniValue& addr = find_value(sendTo, "address");
|
||||
if (addr.isNull()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, missing address: "));
|
||||
}
|
||||
std::string addrStr = addr.get_str();
|
||||
CTxDestination dest = DecodeDestination(addrStr);
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Kevacoin address: ") + addrStr);
|
||||
}
|
||||
if (destinations.count(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + addrStr);
|
||||
}
|
||||
destinations.insert(dest);
|
||||
|
||||
CScript scriptPubKey = GetScriptForDestination(dest);
|
||||
const UniValue& amount = find_value(sendTo, "amount");
|
||||
CAmount nAmount = AmountFromIntegerValue(amount);
|
||||
if (nAmount <= 0)
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
|
||||
totalAmount += nAmount;
|
||||
|
||||
CRecipient recipient = {scriptPubKey, nAmount, false};
|
||||
vecSend.push_back(recipient);
|
||||
}
|
||||
|
||||
EnsureWalletIsUnlocked(pwallet);
|
||||
|
||||
// Check funds
|
||||
CAmount nBalance = pwallet->GetLegacyBalance(ISMINE_SPENDABLE, 1, nullptr);
|
||||
if (totalAmount > nBalance)
|
||||
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
|
||||
|
||||
// Send
|
||||
CReserveKey keyChange(pwallet);
|
||||
CAmount nFeeRequired = 0;
|
||||
int nChangePosRet = -1;
|
||||
std::string strFailReason;
|
||||
std::vector<unsigned char> empty;
|
||||
bool fCreated = pwallet->CreateTransaction(vecSend, nullptr, empty, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason, coin_control);
|
||||
if (!fCreated)
|
||||
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
|
||||
CValidationState state;
|
||||
if (!pwallet->CommitTransaction(wtx, keyChange, g_connman.get(), state)) {
|
||||
strFailReason = strprintf("Transaction commit failed:: %s", state.GetRejectReason());
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
|
||||
}
|
||||
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.push_back(Pair("amount", (uint64_t)totalAmount));
|
||||
result.push_back(Pair("fee", (uint64_t)nFeeRequired));
|
||||
result.push_back(Pair("multisig_txset", ""));
|
||||
result.push_back(Pair("tx_blob", ""));
|
||||
result.push_back(Pair("tx_hash", wtx.GetHash().GetHex()));
|
||||
result.push_back(Pair("tx_key", ""));
|
||||
result.push_back(Pair("tx_metadata", ""));
|
||||
result.push_back(Pair("unsigned_txset", ""));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
UniValue addmultisigaddress(const JSONRPCRequest& request)
|
||||
{
|
||||
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
|
||||
@ -3658,6 +3785,7 @@ static const CRPCCommand commands[] =
|
||||
{ "wallet", "walletpassphrase", &walletpassphrase, {"passphrase","timeout"} },
|
||||
{ "wallet", "removeprunedfunds", &removeprunedfunds, {"txid"} },
|
||||
{ "wallet", "rescanblockchain", &rescanblockchain, {"start_height", "stop_height"} },
|
||||
{ "wallet", "transfer", &transfer, {"destinations"} },
|
||||
|
||||
{ "generating", "generate", &generate, {"nblocks","maxtries"} },
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user