1) The bitcoin-cli command can be used to send bitcoin to any recipient address. For testing purpose, the regtest network is used.
bitcoin-cli -regtest getaccountaddress "" - get the address from default account
bitcoin-cli -regtest sendtoaddress mjSTBVs....... {amount} <comment> - this returns transaction id
2) In this analysis, the source code that handles sendtoaddress RPC will be walked through.
httprpc.cpp
In HTTPReq_JSONRPC(HTTPRequest *req, const std::string &)
call jreq.parse(valRequest) - parse the request
call tableRPC.execute(jreq) - execute the RPC comamnd
rpc/server.cpp
In CRPCTable::execute(const JSONRPCRequest &request)
initialise pcmd
CRPCCommand *pcmd = tableRPC[request.strMethod]
The tableRPC array is filled in init.cpp
init.cpp
In AppInitParameterInteraction()
call RegisterAllCoreRPCCommands(tableRPC)
and RegisterWalletRPCCommands(tableRPC)
rpc/register.h
define the function RegisterAllCoreRPCCommands(CRPCTable &t), which calls
RegisterBlockchainRPCCommands(t)
RegisterMiscRPCCommands(t)
RegisterMiningRPCCommands(t)
RegisterRawTransactionRPCCommands(t)
rpc/blockchain.cpp
define RegisterBlockchainRPCCommands(CRPCTable &t)
rpc/net.cpp
define RegisterNetRPCCommands(CRPCTable &t)
rpc/mining.cpp
define RegisterMiningRPCCommands(CRPCTable &t)
rpc/rawtransaction.cpp
define RegisterRawTransactionRPCCommands(CRPCTable &t)
Last but not least, RegisterWalletRPCCommands is defined in
wallet/rpcwallet.cpp
The RegisterWalletRPCCommands(CRPCTable &t) fill up the CRPCCommand array. In the CRPCComamnd structure, actor function pointer, sendtoaddress function is assigned to that field.
The function
UniValue sendtoaddress(const JSONRPCRequest & request)
Firstly, the address is gotten from parameter 0. Then, the amount is gotten from parameter 1. The it calls the SendMoney() function, and returns the hash value of the transaction.
The function
static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CAmount value, bool fSubtractFeeFromAmount, CWalletTx & wtxNew)
Firstly, it gets the balance from the wallet, parse the bitcoin address, find out the recipient.
Then, it declares std::vector<CRecipient> vecSend
and append the recipient to the array vecSend
Then, it calls CWallet function CreateTransaction and CommitTransaction.
wallet/wallet.cpp
In the CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, const CCoinControl* coinControl, bool sign)
Firstly, it checks the recipient amount , which must be >= 0. Then, it sets the lockTime to the next block to discourage fee sniping. The CTxOut txout object is constructed. The txout is appended to CMutableTransaction txNew vout vector. Then, it chooses the Bitcoin to use for transaction. If input value is greater than selected value, it creates a CTxOut and insert it to same CMutableTransaction vout at position nChangePosInOut.
After that, it creates CTxIn and appends the CTxIn to vin vector. It calculate the minimum fee needed. If the fee needed is less than min relay fee, the transaction is dropped. Then the min fee inclusive of necessary fee is calculated.
If transaction requires signature, a signature is produced (via ProduceSignature function). UpdateTransaction() is called to update with signature data.
Then, the CMutableTransaction txNew is embedded in CWalletTx wtxNew object. If wtxNew size is bigger than mempool's chain limit, transaction will be dropped.
In the bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman, CValidationState& state)
It calls AddToWallet(wtxNew) and coin.BindWallet(this) to notify old coins are spent.
It then broadcast transaction if wtxNew is accepted to mempool
bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose)
It creates the walletdb. It creates the std:pair object from mapWallet.insert(std::make_pair(hash, wtxIn)). From the std::pair object, it creates another CWalletTx wtx object. If it is new transaction, it gets the order position from walletdb, and adds the hash. If it is not new, the code merges the hash block. Finally, it writes to disk with walletdb.WriteTx(wtx).
mapWallet is declared in wallet/wallet.h as
std::map<uint256, CWalletTx> mapWallet;
Man I need more blogs from you.
ReplyDeleteAlso post your email id. I want to contact you.
ReplyDelete