Bitcoin
We can check the transaction and balance at explore website such as BlockCypher.
I want to make Android Bitcoin wallet without SPV node. I have to fetch balance, transactions and send BTC by JSON-RPC API with someone's full node. The other solution is using third-party API such as blockchain.com, BlockCypher and Coinbase.
Get balance
One possible solution is use JSON-RPC API to get all transactions, then keep the relative transactions with user address. Finally calculating its UXTO
to get the final balance. But using third-party API to get the balance is easier.
blockchain.com
Get https://blockchain.info/rawaddr/$address // response { "hash160":"660d4ef3a743e3e696ad990364e555c271ad504b", "address":"1AJbsFZ64EpEfS5UAjAfcUG8pH8Jn3rn1F", "n_tx":17, "n_unredeemed":2, "total_received":1031350000, "total_sent":931250000, "final_balance":100100000, "txs":[--Array of Transactions--] }
Get transactions
The gettransaction
JSON-RPC API can get the transaction only for the wallet in host node. So we have to use getrawtransaction
API. And second parameter should be true so that we can get the JSON response.
{
"jsonrpc":"2.0",
"method":"getrawtransaction",
"params":["301e88f1bf7d261c63d063e3a1707a505ca6dcb9014f12247bb461188d20614c", true], // Testnet
"id": 1
}
{
"result": {
"txid": "301e88f1bf7d261c63d063e3a1707a505ca6dcb9014f12247bb461188d20614c",
"hash": "4def7a882946d7c9cc09aae49517fe8fe71ac6d7b231f65d225193a7e33d458a",
"version": 2,
"size": 245,
"vsize": 164,
"weight": 653,
"locktime": 1541608,
"vin": [
{
"txid": "7a5b07fcfccc0aa546db265638102ad11a5558dbf1008c6de2877079f1b2713b",
"vout": 36,
"scriptSig": {
"asm": "0014e03fc8188a85321a909eb8f5d3ed5f53573e0594",
"hex": "160014e03fc8188a85321a909eb8f5d3ed5f53573e0594"
},
"txinwitness": [
"304402200478d8e61405a250a84b5717a1c330fc270a8ce69056032b897b84788ce462cb02205df2b6425083d046e4f8f8df5f93795045f7818425235588575293c79f07b7d901",
"027f712362142b9709ef29caff6f520dbf600e041bb94ccc23e1941164f313667f"
],
"sequence": 4294967294
}
],
"vout": [
{
"value": 0.01,
"n": 0,
"scriptPubKey": {
"asm": "0 682b103184441f62bc82b60478196bb862ca1d70",
"hex": "0014682b103184441f62bc82b60478196bb862ca1d70",
"reqSigs": 1,
"type": "witness_v0_keyhash",
"addresses": [
"tb1qdq43qvvygs0k90yzkcz8sxtthp3v58ts599yfv"
]
}
},
{
"value": 0.01099672,
"n": 1,
"scriptPubKey": {
"asm": "0 44525400c97bd32550ccc68952db4321d1b2799d",
"hex": "001444525400c97bd32550ccc68952db4321d1b2799d",
"reqSigs": 1,
"type": "witness_v0_keyhash",
"addresses": [
"tb1qg3f9gqxf00fj25xvc6y49k6ry8gmy7vatznqs0"
]
}
}
],
"hex": "020000000001013b71b2f1797087e26d8c00f1db58551ad12a10385626db46a50accfcfc075b7a2400000017160014e03fc8188a85321a909eb8f5d3ed5f53573e0594feffffff0240420f0000000000160014682b103184441f62bc82b60478196bb862ca1d7098c710000000000016001444525400c97bd32550ccc68952db4321d1b2799d0247304402200478d8e61405a250a84b5717a1c330fc270a8ce69056032b897b84788ce462cb02205df2b6425083d046e4f8f8df5f93795045f7818425235588575293c79f07b7d90121027f712362142b9709ef29caff6f520dbf600e041bb94ccc23e1941164f313667fe8851700",
"blockhash": "000000000000015bec9f6aa9e2cdc6e402f1657804f718710b553bf059fb298d",
"confirmations": 661,
"time": 1560155793,
"blocktime": 1560155793
},
"error": null,
"id": 1
}
Send transaction
We can use sendrawtransaction
JSON-RPC API to send BTC. But first we have to create transaction and sign it.
Address myTBdQRS6h5DFSQ8o5nR7wgUwoqgRj2U7t
received BTC from faucet in transaction b4e09a90d5e0054b2e08ba8d6f7e2a80962baef528d1b91353639aa778a80610
.
- from address
myTBdQRS6h5DFSQ8o5nR7wgUwoqgRj2U7t
has 0.07508694 BTC - to address
n1wMf2JJxFNdQ6DWaaMzPg5ZZXwA6UkRTv
has no balance
First step is call createrawtransaction
.
{
"jsonrpc":"2.0",
"method":"createrawtransaction",
"params":[
[{
"txid":"b4e09a90d5e0054b2e08ba8d6f7e2a80962baef528d1b91353639aa778a80610",
"vout": 1
}],
[{
"n1wMf2JJxFNdQ6DWaaMzPg5ZZXwA6UkRTv": 0.00123
}]
],
"id": 1
}
{
"result": "02000000011006a878a79a635313b9d128f5ae2b96802a7e6f8dba082e4b05e0d5909ae0b40100000000ffffffff0178e00100000000001976a914dfffffff373af20b31bf975abe3e2ae55fefa69488ac00000000",
"error": null,
"id": 1
}
Then call signrawtransactionwithkey
with our private key.
{
"jsonrpc":"2.0",
"method":"signrawtransactionwithkey",
"params":[
"02000000011006a878a79a635313b9d128f5ae2b96802a7e6f8dba082e4b05e0d5909ae0b40100000000ffffffff0178e00100000000001976a914dfffffff373af20b31bf975abe3e2ae55fefa69488ac00000000",
["936L4d7HsoXVRpbPrYXZP4YbuwxqDoBt6anRnNeUvcvPaP2DLEm"]
],
"id": 1
}
{
"result": {
"hex": "02000000011006a878a79a635313b9d128f5ae2b96802a7e6f8dba082e4b05e0d5909ae0b4010000008a47304402203a247421f93aa99bb2e82777cab859d55c6d68ed163a0b2228843f4655df9bd202203afa00dc76fdc824a85a43b9c3833164b587fa1072595855230800dcaf681b4e014104a0ad9f0f9b0ae8bd9bae13e81cae8fda00bbc791f29f0f8daa8cffb4aaaeb3e1595d2c938f77af1e0db4e6db25880c66c73f5d55d3ed59032e574d6bedfcb07affffffff0178e00100000000001976a914dfffffff373af20b31bf975abe3e2ae55fefa69488ac00000000",
"complete": true
},
"error": null,
"id": 1
}
Finally, call sendrawtransaction
.
{
"jsonrpc":"2.0",
"method":"sendrawtransaction",
"params":["02000000011006a878a79a635313b9d128f5ae2b96802a7e6f8dba082e4b05e0d5909ae0b4010000008a47304402203a247421f93aa99bb2e82777cab859d55c6d68ed163a0b2228843f4655df9bd202203afa00dc76fdc824a85a43b9c3833164b587fa1072595855230800dcaf681b4e014104a0ad9f0f9b0ae8bd9bae13e81cae8fda00bbc791f29f0f8daa8cffb4aaaeb3e1595d2c938f77af1e0db4e6db25880c66c73f5d55d3ed59032e574d6bedfcb07affffffff0178e00100000000001976a914dfffffff373af20b31bf975abe3e2ae55fefa69488ac00000000"],
"id": 1
}
{
"result": "c544bf3b622c3d8e6e967c2d6e103bb26ba86d850001ae2bfa0f924210c6e94b",
"error": null,
"id": 1
}
Now, address n1wMf2JJxFNdQ6DWaaMzPg5ZZXwA6UkRTv
has 0.00123 BTC.
Input not found or already spent error
When I call createrawtransaction
with zero vout
, I got error of sendrawtransaction
.
{
"jsonrpc":"2.0",
"method":"createrawtransaction",
"params":[
[{
"txid":"b4e09a90d5e0054b2e08ba8d6f7e2a80962baef528d1b91353639aa778a80610",
"vout": 0
}],
[{
"n1wMf2JJxFNdQ6DWaaMzPg5ZZXwA6UkRTv":"0.00123"
}]
],
"id": 1
}
{
"jsonrpc":"2.0",
"method":"signrawtransactionwithkey",
"params":[
"02000000011006a878a79a635313b9d128f5ae2b96802a7e6f8dba082e4b05e0d5909ae0b40000000000ffffffff0178e00100000000001976a914dfffffff373af20b31bf975abe3e2ae55fefa69488ac00000000",
["936L4d7HsoXVRpbPrYXZP4YbuwxqDoBt6anRnNeUvcvPaP2DLEm"]
],
"id": 1
}
{
"result": {
"hex": "02000000011006a878a79a635313b9d128f5ae2b96802a7e6f8dba082e4b05e0d5909ae0b40000000000ffffffff0178e00100000000001976a914dfffffff373af20b31bf975abe3e2ae55fefa69488ac00000000",
"complete": false,
"errors": [
{
"txid": "b4e09a90d5e0054b2e08ba8d6f7e2a80962baef528d1b91353639aa778a80610",
"vout": 0,
"witness": [],
"scriptSig": "",
"sequence": 4294967295,
"error": "Input not found or already spent"
}
]
},
"error": null,
"id": 1
}
I change vout
to be 1 to fix it.