Title: Why the receiver doesn't get any bitcoin on the balance if sendtoaddress or send
Post by: srgbnd on November 20, 2021, 11:49:26 AM
I want to do a transaction (sendtoaddress), but I see that the receiver doesn't get the amount sent. Stackoverflow question https://bitcoin.stackexchange.com/questions/110858/why-the-receiver-doesnt-get-any-bitcoin-on-the-balance-if-sendtoaddress-or-send The regtest node started bitcoind -rpcuser=test -rpcpassword=test -regtest -rpcport=16591 -fallbackfee=0.000045
My service class to interact with bitcoind API const httpClient = require('axios');
const bitcoindConfig = { url: 'http://localhost:16591', headers: { 'content-type': 'text-plain' }, auth: { username: 'test', password: 'test' }, };
class BitcoinService { _bitcoindRpcCall({ reqMethod = 'POST', walletName, method, params = [] } = {}) { const options = { url: walletName ? bitcoindConfig.url + `/wallet/${walletName}` : bitcoindConfig.url, method: reqMethod, data: JSON.stringify({'jsonrpc': '1.0', 'id': 'curltext', 'method': method, 'params': params}), headers: bitcoindConfig.headers, auth: bitcoindConfig.auth }; return httpClient(options); }
listWallets() { return this._bitcoindRpcCall({ method: 'listwallets' }); }
createWallet({ walletName }) { return this._bitcoindRpcCall({ method: 'createwallet', params: [walletName] }); }
getNewAddress({ walletName }) { return this._bitcoindRpcCall({ method: 'getnewaddress', walletName }); }
getBalance({ walletName }) { return this._bitcoindRpcCall({ method: 'getbalance', walletName }); }
listUnspent({ walletName }) { return this._bitcoindRpcCall({ method: 'listunspent', walletName }); }
dumpPrivKey({ address, walletName }) { return this._bitcoindRpcCall({ method: 'dumpprivkey', params: [address], walletName }); }
listTransactions({ walletName }) { return this._bitcoindRpcCall({ method: 'listtransactions', walletName }); }
generateToAddress({ address, nBlocks, walletName }) { return this._bitcoindRpcCall({ method: 'generatetoaddress', params: [nBlocks, address], walletName }); }
getTransaction({ txId, walletName }) { return this._bitcoindRpcCall({ method: 'gettransaction', params: [txId], walletName }); }
getRawTransaction({ txId, walletName }) { return this._bitcoindRpcCall({ method: 'getrawtransaction', params: [txId], walletName }); }
decodeRawTransaction({ hexString }) { return this._bitcoindRpcCall({ method: 'decoderawtransaction', params: [hexString] }); }
// https://bitcoincore.org/en/doc/0.17.0/rpc/wallet/sendtoaddress/ async sendToAddress({ walletName, amount, toAddress, comment = '', commentTo = '', subtractFeeFromAmount = true } = {}) { return this._bitcoindRpcCall({ method: 'sendtoaddress', params: [toAddress, amount, comment, commentTo, subtractFeeFromAmount], walletName }); }
// https://bitcoincore.org/en/doc/0.17.0/rpc/rawtransactions/createrawtransaction/ async createRawTransaction({ walletName, amount, toAddress }) { const { data: { result: txs } } = await this.listUnspent({ walletName }); const inputs = []; let n = amount; let i = 0; while (n > 0 && i < txs.length) { const tx = txs[i++]; inputs.push({ txid: tx.txid, vout: tx.vout }); n -= tx.amount; } const outputs = [ { [toAddress]: amount } ]; console.log('inputs, outputs', inputs, outputs);
return this._bitcoindRpcCall({ method: 'createrawtransaction', params: [inputs, outputs] }); }
// https://chainquery.com/bitcoin-cli/signrawtransactionwithwallet signRawTransactionWithWallet({ hexString, walletName }) { return this._bitcoindRpcCall({ method: 'signrawtransactionwithwallet', params: [hexString], walletName }); }
// https://bitcoincore.org/en/doc/0.17.0/rpc/rawtransactions/sendrawtransaction/ sendRawTransaction({ hexString, allowHighFees = true } = {}) { return this._bitcoindRpcCall({ method: 'sendrawtransaction', params: [hexString] }); }
async rawTransaction({ walletName, amount, toAddress }) { let res = await this.createRawTransaction({ walletName, amount, toAddress }); res = await this.signRawTransactionWithWallet({ hexString: res.data.result, walletName }); return this.sendRawTransaction({ hexString: res.data.result.hex }); } }
Two wallets created: alice and bob const btc = new BitcoinService();
res = await btc.createWallet({ walletName: 'bob' }); console.log('create bob wallet', res.data); // { result: { name: 'bob', warning: '' }, error: null, id: 'curltext' } res = await btc.createWallet({ walletName: 'alice' }); console.log('create alice wallet', res.data); // { result: { name: 'alice', warning: '' }, error: null, id: 'curltext' }
Check whether the wallets exist res = await btc.listWallets(); console.log('listwallets', res.data); // { result: [ 'bob', 'alice' ], error: null, id: 'curltext' }
Create addresses for the wallets let aliceAddr; let bobAddr;
res = await btc.getNewAddress({ walletName: 'alice' }); aliceAddr = res.data.result; console.log('alice addr', aliceAddr); // bcrt1qn4w4futa4j0mrt6frqn9u9zg9n5s9dvaeh2mrl
res = await btc.getNewAddress({ walletName: 'bob' }); bobAddr = res.data.result; console.log('bob addr', bobAddr); // bcrt1qecashk27r403nkeq09gvpfnr7dgfeet9xk97m5
Generate bitcoin for alice for (let i = 0; i < 5; i++) { res = await btc.generateToAddress({ address: aliceAddr, nBlocks: 101 }); console.log('generate bitcon for alice', res.data); // hashes in the output }
Check balance // Get balance res = await btc.getBalance({ walletName: 'alice' }); console.log('alice balance', res.data); // { result: 126.85546875, error: null, id: 'curltext' }
res = await btc.getBalance({ walletName: 'bob' }); console.log('bob balance', res.data); // { result: 0, error: null, id: 'curltext' }
Send bitcoin from alice to bob res = await btc.sendToAddress({ walletName: 'alice', toAddress: bobAddr, amount: 0.1 }); console.log('alice sends to bob', res.data); // { // result: '0ae84b140e3be5d4933daa4f25e3d1cd5c02b9485ede54ad4c24a91e7d0d28f2', // error: null, // id: 'curltext' // }
Checking the balance again res = await btc.getBalance({ walletName: 'alice' }); console.log('alice balance', res.data); // { result: 126.75546875, error: null, id: 'curltext' }
res = await btc.getBalance({ walletName: 'bob' }); console.log('bob balance', res.data); // { result: 0, error: null, id: 'curltext' }
The alice balance was decreased by 0.1 as expected. Why is there no amount on the bob balance?Also, I tried the sendrawtransaction, same result, bob got no bitcoin on the balance. res = await btc.rawTransaction({ walletName: 'alice', toAddress: bobAddr, amount: 0.1 }) console.log('alice sends raw transaction', res.data); // { // result: 'e1fc8cc8bbe38bdd793ff1f87ca59a52d90c9fa1523d93d166f6a53209bc5e56', // error: null, // id: 'curltext' // }
But I can list the transaction that bob received res = await btc.listTransactions({ walletName: 'bob' }); console.log('bob transactions', res.data);
bob transactions { result: [ { address: 'bcrt1qyrjp4kcar7c60842zmd38wnwjxlgjhj6550nev', category: 'receive', amount: 0.1, label: '', vout: 0, confirmations: 0, trusted: false, txid: 'e1fc8cc8bbe38bdd793ff1f87ca59a52d90c9fa1523d93d166f6a53209bc5e56', walletconflicts: [], time: 1637406810, timereceived: 1637406810, 'bip125-replaceable': 'no' }, { address: 'bcrt1qyrjp4kcar7c60842zmd38wnwjxlgjhj6550nev', category: 'receive', amount: 0.1, label: '', vout: 0, confirmations: 0, trusted: false, txid: 'd4de85ff41b0386808b60a8ec0028923c42a2bc1667e5b8a7b865cacf21abd5d', walletconflicts: [], time: 1637407520, timereceived: 1637407520, 'bip125-replaceable': 'no' }, { address: 'bcrt1qyrjp4kcar7c60842zmd38wnwjxlgjhj6550nev', category: 'receive', amount: 0.1, label: '', vout: 0, confirmations: 0, trusted: false, txid: '573d8ef6b72fa3e029f3207ddc8b5f03a248e88b4ae643bc66be38ae84ffa01f', walletconflicts: [], time: 1637407554, timereceived: 1637407554, 'bip125-replaceable': 'no' }, { address: 'bcrt1qyrjp4kcar7c60842zmd38wnwjxlgjhj6550nev', category: 'receive', amount: 0.1, label: '', vout: 0, confirmations: 0, trusted: false, txid: '4fa4efff12348f0916cec1b39e47cf19ceb1aa91b7236f7c67905b2eef34433a', walletconflicts: [], time: 1637407824, timereceived: 1637407824, 'bip125-replaceable': 'no' } ], error: null, id: 'curltext' }
Title: Re: Why the receiver doesn't get any bitcoin on the balance if sendtoaddress or send
Post by: nc50lc on November 20, 2021, 12:33:57 PM
The transaction needs to have at least 1 confirmation for it to be included to the getBalance command's result.
Title: Re: Why the receiver doesn't get any bitcoin on the balance if sendtoaddress or send
Post by: TheArchaeologist on November 21, 2021, 08:41:26 AM
I've written a post on using regtest last year, you could check it out here: https://bitcointalk.org/index.php?topic=5268794.0 (https://bitcointalk.org/index.php?topic=5268794.0). From this guide: Confirmation neededSo whenever you do one or more transactions in your regtest environment they will be unconfirmed as long as you don't mine at least an extra block. Since there are no active miners on your private regtest chain you have to take care of that yourself. The good news is that means you also don't have to wait for an average of 10 minutes for a block to get mined. So just like nc50lc mentions the transaction isn't included in any block yet, that's the reason the balance is not updated. You can verify this by checking if the txid is in the mempool of you regtest environment: bitcoin-cli -regtest getrawmempool
You should see the txid (0ae84b140e3be5d4933daa4f25e3d1cd5c02b9485ede54ad4c24a91e7d0d28f2) listed. To get the transaction included in a block you need to mine at least 1 block, you can do this by using generatetoaddress: bitcoin-cli -regtest generatetoaddress <numBlocks> <address>
Where <numBlocks> is an integer value of the number of blocks we want to mine and <address> is the address the mining reward should go to. After mining the balance should be adjusted as you expected.
|