mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-20 23:29:12 +01:00
sendmany RPC command, to send to multiple recipients in one transaction.
This commit is contained in:
73
rpc.cpp
73
rpc.cpp
@@ -768,6 +768,69 @@ Value sendfrom(const Array& params, bool fHelp)
|
||||
return wtx.GetHash().GetHex();
|
||||
}
|
||||
|
||||
Value sendmany(const Array& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() < 2 || params.size() > 4)
|
||||
throw runtime_error(
|
||||
"sendmany <fromaccount> {address:amount,...} [minconf=1] [comment]\n"
|
||||
"amounts are double-precision floating point numbers");
|
||||
|
||||
string strAccount = AccountFromValue(params[0]);
|
||||
Object sendTo = params[1].get_obj();
|
||||
int nMinDepth = 1;
|
||||
if (params.size() > 2)
|
||||
nMinDepth = params[2].get_int();
|
||||
|
||||
CWalletTx wtx;
|
||||
wtx.strFromAccount = strAccount;
|
||||
if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty())
|
||||
wtx.mapValue["comment"] = params[3].get_str();
|
||||
|
||||
set<string> setAddress;
|
||||
vector<pair<CScript, int64> > vecSend;
|
||||
|
||||
int64 totalAmount = 0;
|
||||
foreach(const Pair& s, sendTo)
|
||||
{
|
||||
uint160 hash160;
|
||||
string strAddress = s.name_;
|
||||
|
||||
if (setAddress.count(strAddress))
|
||||
throw JSONRPCError(-8, string("Invalid parameter, duplicated address: ")+strAddress);
|
||||
setAddress.insert(strAddress);
|
||||
|
||||
CScript scriptPubKey;
|
||||
if (!scriptPubKey.SetBitcoinAddress(strAddress))
|
||||
throw JSONRPCError(-5, string("Invalid bitcoin address:")+strAddress);
|
||||
int64 nAmount = AmountFromValue(s.value_);
|
||||
totalAmount += nAmount;
|
||||
|
||||
vecSend.push_back(make_pair(scriptPubKey, nAmount));
|
||||
}
|
||||
|
||||
CRITICAL_BLOCK(cs_mapWallet)
|
||||
{
|
||||
// Check funds
|
||||
int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
|
||||
if (totalAmount > nBalance)
|
||||
throw JSONRPCError(-6, "Account has insufficient funds");
|
||||
|
||||
// Send
|
||||
CReserveKey keyChange;
|
||||
int64 nFeeRequired = 0;
|
||||
bool fCreated = CreateTransaction(vecSend, wtx, keyChange, nFeeRequired);
|
||||
if (!fCreated)
|
||||
{
|
||||
if (totalAmount + nFeeRequired > GetBalance())
|
||||
throw JSONRPCError(-6, "Insufficient funds");
|
||||
throw JSONRPCError(-4, "Transaction creation failed");
|
||||
}
|
||||
if (!CommitTransaction(wtx, keyChange))
|
||||
throw JSONRPCError(-4, "Transaction commit failed");
|
||||
}
|
||||
|
||||
return wtx.GetHash().GetHex();
|
||||
}
|
||||
|
||||
|
||||
struct tallyitem
|
||||
@@ -1344,6 +1407,7 @@ pair<string, rpcfn_type> pCallTable[] =
|
||||
make_pair("getbalance", &getbalance),
|
||||
make_pair("move", &movecmd),
|
||||
make_pair("sendfrom", &sendfrom),
|
||||
make_pair("sendmany", &sendmany),
|
||||
make_pair("gettransaction", &gettransaction),
|
||||
make_pair("listtransactions", &listtransactions),
|
||||
make_pair("getwork", &getwork),
|
||||
@@ -1995,6 +2059,15 @@ int CommandLineRPC(int argc, char *argv[])
|
||||
if (strMethod == "sendfrom" && n > 3) ConvertTo<boost::int64_t>(params[3]);
|
||||
if (strMethod == "listtransactions" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||
if (strMethod == "listaccounts" && n > 0) ConvertTo<boost::int64_t>(params[0]);
|
||||
if (strMethod == "sendmany" && n > 1)
|
||||
{
|
||||
string s = params[1].get_str();
|
||||
Value v;
|
||||
if (!read_string(s, v) || v.type() != obj_type)
|
||||
throw runtime_error("type mismatch");
|
||||
params[1] = v.get_obj();
|
||||
}
|
||||
if (strMethod == "sendmany" && n > 2) ConvertTo<boost::int64_t>(params[2]);
|
||||
|
||||
// Execute
|
||||
Object reply = CallRPC(strMethod, params);
|
||||
|
||||
Reference in New Issue
Block a user