Bitcoin core Testnet
Ritu Sharma
I Promise Small businesses to book 50+ appointments/month for High-Value Services with a 100% guarantee through Website Development, Mobile App Development and Digital Marketing.
For Basics, I have covered in previous Newsletter article. So please check previous articles also for basics. Now giving brief.
In this in-depth tutorial, we will cover the?basics?of?blockchain, why you would want a bitcoin full-node, how to?setup a bitcoin full-node?on linux using the?testnet chain?and how to interact with your node and the blockchain using the?cli?and the?json rpc, where we will create wallets and addresses and sending?tbtc?to your accounts.
Blockchain Basics
Before we start setting up our bitcoin full-node, we first need to get through some blockchain basics, if you already aware of it, you can skip the the setup section of this post.
Block
Transaction data is permanently recorded into files called blocks. You can think of it as a transaction ledger. Blocks are organised into a linear sequence over time.
New transactions are constantly being processed by miners into new blocks which are added to the end of the chain. As blocks are buried deeper and deeper into the blockchain they become harder and harder to change or remove, this gives rise of?Bitcoin’s Irreversible Transactions.
The first block added to the blockchain is referred to as the?genesis block
Blockchain
A blockchain is a transaction database shared by all nodes participating in a system based on the bitcoin protocol. A?full copy?of a currency’s blockchain contains?every?transaction?ever?executed in the currency. With this information, one can find out how much value belonged to each address at any point in history.
Every block contains a hash of the previous block. This has the effect of creating a chain of blocks from the?genesis block?to the current block. Each block is guaranteed to come after the previous block chronologically because the previous block’s hash would otherwise not be known. Each block is also computationally impractical to modify once it has been in the chain for a while because every block after it would also have to be regenerated. These properties are what make?bitcoins transactions irreversible.?The blockchain is the main innovation of Bitcoin.
Mining
Mining is the process of?adding transaction records to bitcoin’s public ledger?of past transactions. The term “mining rig” is referred to where as a single computer system that performs the necessary computations for “mining”.
The blockchain serves to confirm transactions to the rest of the network as having taken place. Bitcoin nodes use the blockchain to distinguish legitimate Bitcoin transactions from attempts to re-spend coins that have already been spent elsewhere.
Node
Any computer that?connects?to the?bitcoin network?is called a?node. Nodes that fully verify all of the rules of bitcoin are called full nodes. The most popular software implementation of full nodes is called bitcoin-core, its releases can be found on their?github page
What is a Full Node
A full node is a node (computer system with bitcoin-core running on it) which downloads?every block?and transaction and?check?them against bitcoin’s?consensus rules. which fully validates transactions and blocks. Almost all full nodes also help the network by accepting transactions and blocks from other full nodes,?validating?those transactions and blocks, and then relaying them to further full nodes.
Some?examples?of?consensus rules:
At?minimum, a full node?must?download?every?transaction that has ever taken place, all new transactions, and all block headers. Additionally, full nodes must store information about every unspent transaction output until it is spent.
By default full nodes are inefficient in that they download each new transaction at least twice, and they store the entire block chain (more than 165 GB as of 20180214) forever, even though only the unspent transaction outputs (<2 GB) are required. Performance can improved by enabling?-blocksonly?mode and enabling?pruning
Archival Nodes
A subset of full nodes also accept incoming connections and upload old blocks to other peers on the network. This happens if the software is run with `-listen=1` as is default.
Contrary to some popular misconceptions, being an archival node is not necessary to being a full node. If a user’s bandwidth is constrained then they can use `-listen=0`, if their disk space is constrained they can use pruning, all the while still being a fully-validating node that enforces bitcoin’s consensus rules and contributing to bitcoin’s overall security.
Most information was referenced from?this?wiki.
Setup Bitcoin Core
Now for the fun part, to setup bitcoin-core on linux, in my case I am using a fresh Ubuntu 20.04 instance and the following commands will be executed as a non-root user.
Environment Variables
Set the following environment variables, the latest version for `BITCOIN_VERSION` can be retrieved at:?https://bitcoincore.org/bin/, execute the following:
$ export ARCH=x86_64
$ export BITCOIN_VERSION=0.21.1
$ export BITCOIN_URL=https://bitcoincore.org/bin/bitcoin-core-${BITCOIN_VERSION}/bitcoin-${BITCOIN_VERSION}-${ARCH}-linux-gnu.tar.gz
$ export BITCOIN_DATA_DIR=/blockchain/bitcoin/data
Installation
Create the user and group for bitcoin:
$ sudo groupadd -r bitcoin
$ sudo useradd -r -m -g bitcoin -s /bin/bash bitcoin
Update the package manager and install the dependencies:
$ sudo apt update
$ sudo apt install ca-certificates gnupg gpg wget jq --no-install-recommends -y
Download bitcoin-core and verify that the package matches the sha hash:
$ cd /tmp
$ wget https://bitcoincore.org/bin/bitcoin-core-${BITCOIN_VERSION}/SHA256SUMS.asc
$ wget -qO bitcoin-${BITCOIN_VERSION}-${ARCH}-linux-gnu.tar.gz “${BITCOIN_URL}”
$ cat SHA256SUMS.asc | grep bitcoin-${BITCOIN_VERSION}-${ARCH}-linux-gnu.tar.gz | awk ‘{ print $1 }’
Extract the package to `/opt/bitcoin/${BITCOIN_VERSION}` and exclude any graphical user interfacing binaries, create the home directory and set the ownership:
$ sudo mkdir -p /opt/bitcoin/${BITCOIN_VERSION}
$ sudo mkdir -p ${BITCOIN_DATA_DIR}
$ sudo tar -xzvf bitcoin-${BITCOIN_VERSION}-${ARCH}-linux-gnu.tar.gz -C /opt/bitcoin/${BITCOIN_VERSION} — strip-components=1 — exclude=*-qt
$ sudo ln -s /opt/bitcoin/${BITCOIN_VERSION} /opt/bitcoin/current
$ sudo rm -rf /tmp/*
$ sudo chown -R bitcoin:bitcoin ${BITCOIN_DATA_DIR}
When you have to upgrade the software version of bitcoin-core in the future you can remove the symlink with `sudo rm -rf /usr/local/bitcoin/current` and symlink to the newer version as shown above.
Configuration
Create the bitcoin configuration, here you see I am using the testnet chain and due to storage restrictions for my use-case I am setting `pruning` mode to 1GB, and if you don’t set `BITCOIN_RPC_USER` it will use the user `bitcoin` and if you don’t set `BITCOIN_RPC_PASSWORD` it will generate a password for the json-rpc interface:
$ cat > bitcoin.conf.tmp << EOF
datadir=${BITCOIN_DATA_DIR}
printtoconsole=1
rpcallowip=127.0.0.1
rpcuser=${BITCOIN_RPC_USER:-bitcoin}
rpcpassword=${BITCOIN_RPC_PASSWORD:-$(openssl rand -hex 24)}
testnet=1
prune=1000
[test]
rpcbind=127.0.0.1
rpcport=18332
EOF
Create the systemd unit-file for bitcoind:
$ cat > bitcoind.service << EOF
[Unit]
Description=Bitcoin Core Testnet
After=network.target
[Service]
User=bitcoin
Group=bitcoin
WorkingDirectory=${BITCOIN_DATA_DIR}
Type=simple
ExecStart=/usr/local/bitcoin/current/bin/bitcoind -conf=$BITCOIN_DATA_DIR/bitcoin.conf
[Install]
WantedBy=multi-user.target
EOF
Now move the temporary config files, change the ownership and symlink the bitcoin home directory to the path that we created earlier:
$ sudo mv bitcoin.conf.tmp $BITCOIN_DATA_DIR/bitcoin.conf
$ sudo chown bitcoin:bitcoin $BITCOIN_DATA_DIR/bitcoin.conf
$ sudo chown -R bitcoin $BITCOIN_DATA_DIR
$ sudo ln -sfn $BITCOIN_DATA_DIR /home/bitcoin/.bitcoin
$ sudo chown -h bitcoin:bitcoin /home/bitcoin
$ sudo chown -R bitcoin:bitcoin /home/bitcoin
Move the systemd unit file in place, then reload systemd and start bitcoind:
$ sudo mv bitcoind.service /etc/systemd/system/bitcoind.service
$ sudo systemctl daemon-reload
$ sudo systemctl enable bitcoind
$ sudo systemctl start bitcoind
Switch to the `bitcoin` user:
$ sudo su — bitcoin
And append the bitcoin path to the `~/.profile` file so that your user know where to find the bitcoin binaries:
$ export PATH=$PATH:/opt/bitcoin/current/bin
Initial Block Download
Once bitcoind process has started, the initial block download will start and you can get the progress as the bitcoin user using the cli:
$ bitcoin-cli -getinfo
Or as the root user you can view the progress using `journalctl`:
$ sudo journalctl -fu bitcoind
Sep 03 08:44:23 rpi-01 bitcoind[532]: 2021–09–03T06:44:23Z UpdateTip: new best=x height=2091205 version=0x20c00000 log2_work=74.461678 tx=60938712 date=’2021–09–03T06:44:13Z’ progress=1.000000 cache=1.7MiB(13673txo)
Troubleshooting
If you run into any issues you can see the status of bitcoind using:
$ sudo systemctl status bitcoind
Or check the logs:
$ sudo journalctl -fu bitcoind
CLI Usage
To get the current block count:
$ bitcoin-cli getblockcount
2091215
To get some basic info about the first block ever created on the bitcoin blockchain. As the genesis block, it has the index value 0. We can use `getblockhas` to get the hash value for the first block ever created:
$ bitcoin-cli getblockhash 0
000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943
We can now use `getblock` with the hash value to retrieve details about the block:
$ bitcoin-cli getblock 000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943
{
“hash”: “000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943”,
“confirmations”: 2004218,
“strippedsize”: 285,
“size”: 285,
“weight”: 1140,
“height”: 0,
“version”: 1,
“versionHex”: “00000001”,
“merkleroot”: “4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b”,
“tx”: [
“4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b”
],
“time”: 1296688602,
“mediantime”: 1296688602,
“nonce”: 414098458,
“bits”: “1d00ffff”,
“difficulty”: 1,
“chainwork”: “0000000000000000000000000000000000000000000000000000000100010001”,
“nTx”: 1,
“nextblockhash”: “00000000b873e79784647a6c82962c70d228557d24a747ea4d1b8bbe878e1206”
}
We can use the `nextblockhash` to retrieve information about block 1:
$ bitcoin-cli getblock 00000000b873e79784647a6c82962c70d228557d24a747ea4d1b8bbe878e1206
{
“hash”: “00000000b873e79784647a6c82962c70d228557d24a747ea4d1b8bbe878e1206”,
“confirmations”: 2004217,
“strippedsize”: 190,
“size”: 190,
“weight”: 760,
“height”: 1,
“version”: 1,
“versionHex”: “00000001”,
“merkleroot”: “f0315ffc38709d70ad5647e22048358dd3745f3ce3874223c80a7c92fab0c8ba”,
“tx”: [
“f0315ffc38709d70ad5647e22048358dd3745f3ce3874223c80a7c92fab0c8ba”
],
“time”: 1296688928,
“mediantime”: 1296688928,
“nonce”: 1924588547,
“bits”: “1d00ffff”,
“difficulty”: 1,
“chainwork”: “0000000000000000000000000000000000000000000000000000000200020002”,
“nTx”: 1,
“previousblockhash”: “000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943”,
“nextblockhash”: “000000006c02c8ea6e4ff69651f7fcde348fb9d557a06e6957b65552002a7820”
}
We can use `-getinfo` to get information show as the verification progress and balances in our wallets, should they exist:
$ bitcoin-cli -getinfo
{
“version”: 210100,
“blocks”: 2091215,
“headers”: 2091215,
“verificationprogress”: 0.9999993040419591,
“timeoffset”: 0,
“connections”: {
“in”: 0,
“out”: 10,
“total”: 10
},
“proxy”: “”,
“difficulty”: 16777216,
“chain”: “test”,
“relayfee”: 0.00001000,
“warnings”: “Warning: unknown new rules activated (versionbit 28)”,
“balances”: {
}
}
For more examples view?chainquery
JSON RPC Usage
First get the jsonrpc user and password:
$ cat ~/.bitcoin/bitcoin.conf | grep -E ‘(rpcuser|rpcpassword)’
rpcuser=bitcoin
rpcpassword=xxxxxxxxxxxxxx
Because this is a test environment, we can set the username and password as an environment variable:
# the user and password might differ on your setup
$ export bitcoinauth=”bitcoin:xxxxxxxxxxxxxx”
Wallet Interaction
Create a wallet:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “createwallet”, “params”: [“wallet”]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/
{“result”:{“name”:”wallet”,”warning”:””},”error”:null,”id”:”curltest”}
List wallets:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “tutorial”, “method”: “listwallets”, “params”: []}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/
{“result”:[“wallet”],”error”:null,”id”:”tutorial”}
If we inspect the `bitcoin.conf` we will notice that we don’t have the wallet loaded in our config:
$ cat ~/.bitcoin/bitcoin.conf | grep -c ‘wallet=’
0
But since we created the wallet, we can see the `wallet.dat` in our data directory:
$ find /blockchain/ -type f -name wallet.dat
/blockchain/bitcoin/data/testnet3/wallets/wallet/wallet.dat
Let’s restart the `bitcoind` service and see if we can still list our wallet, first restart the service:
$ sudo systemctl restart bitcoind
Then wait a couple of seconds and list the wallets:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “tutorial”, “method”: “listwallets”, “params”: []}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/
{“result”:[],”error”:null,”id”:”tutorial”}
As you can see it’s not loaded, due to it not being in the config. Let’s update our config `~/.bitcoin/bitcoin.conf`, and restart the service:
# more wallets can be referenced by using another wallet= config
[test]
wallet=wallet
# which corresponds to datadir + walletdir
# /blockchain/bitcoin/data/testnet3/wallets/wallet/wallet.dat
# /blockchain/bitcoin/data/testnet3/wallets/wallet/db.log
When I restarted the `bitcoind` service, I checked the logs with `journalctl -fu bitcoind`, and I could see the wallet has been loaded:
Jun 10 13:16:23 ip-172–31–82–15 bitcoind[41053]: 2021–06–10T13:16:23Z init message: Loading wallet…
Jun 10 13:16:23 ip-172–31–82–15 bitcoind[41053]: 2021–06–10T13:16:23Z BerkeleyEnvironment::Open: LogDir=/blockchain/bitcoin/data/testnet3/wallets/wallet/database ErrorFile=/blockchain/bitcoin/data/testnet3/wallets/wallet//db.log
Jun 10 13:16:23 ip-172–31–82–15 bitcoind[41053]: 2021–06–10T13:16:23Z txindex thread start
Jun 10 13:16:23 ip-172–31–82–15 bitcoind[41053]: 2021–06–10T13:16:23Z txindex is enabled at height 2004267
Jun 10 13:16:23 ip-172–31–82–15 bitcoind[41053]: 2021–06–10T13:16:23Z txindex thread exit
Jun 10 13:16:23 ip-172–31–82–15 bitcoind[41053]: 2021–06–10T13:16:23Z [wallet] Wallet File Version = 169900
Jun 10 13:16:23 ip-172–31–82–15 bitcoind[41053]: 2021–06–10T13:16:23Z [wallet] Keys: 2001 plaintext, 0 encrypted, 2001 w/ metadata, 2001 total. Unknown wallet records: 0
Jun 10 13:16:23 ip-172–31–82–15 bitcoind[41053]: 2021–06–10T13:16:23Z [wallet] Wallet completed loading in 39ms
Jun 10 13:16:23 ip-172–31–82–15 bitcoind[41053]: 2021–06–10T13:16:23Z init message: Rescanning…
Jun 10 13:16:23 ip-172–31–82–15 bitcoind[41053]: 2021–06–10T13:16:23Z [wallet] Rescanning last 2 blocks (from block 2004265)…
Jun 10 13:16:23 ip-172–31–82–15 bitcoind[41053]: 2021–06–10T13:16:23Z [wallet] Rescan started from block 000000000000001f778a8e2b68cf05490ae000e653b925bb0552c1b79ef4fe70…
Jun 10 13:16:23 ip-172–31–82–15 bitcoind[41053]: 2021–06–10T13:16:23Z [wallet] Rescan completed in 2ms
Jun 10 13:16:23 ip-172–31–82–15 bitcoind[41053]: 2021–06–10T13:16:23Z [wallet] setKeyPool.size() = 2000
Jun 10 13:16:23 ip-172–31–82–15 bitcoind[41053]: 2021–06–10T13:16:23Z [wallet] mapWallet.size() = 0
Jun 10 13:16:23 ip-172–31–82–15 bitcoind[41053]: 2021–06–10T13:16:23Z [wallet] m_address_book.size() = 0
When I list the wallets again:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “tutorial”, “method”: “listwallets”, “params”: []}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/
{“result”:[“wallet”],”error”:null,”id”:”tutorial”}
Now that the wallet has been loaded, we can get wallet info:
$ curl -s -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “tutorial”, “method”: “getwalletinfo”, “params”: []}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/ | jq .
{
“result”: {
“walletname”: “wallet”,
“walletversion”: 169900,
“format”: “bdb”,
“balance”: 0,
“unconfirmed_balance”: 0,
“immature_balance”: 0,
“txcount”: 0,
“keypoololdest”: 1623329789,
“keypoolsize”: 1000,
“hdseedid”: “x”,
“keypoolsize_hd_internal”: 1000,
“paytxfee”: 0,
“private_keys_enabled”: true,
“avoid_reuse”: false,
“scanning”: false,
“descriptors”: false
},
“error”: null,
“id”: “tutorial”
}
Create another wallet, named `test-wallet`:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “createwallet”, “params”: [“test-wallet”]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/
{“result”:{“name”:”test-wallet”,”warning”:””},”error”:null,”id”:”curltest”}
After we created our wallet, list the wallets again:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “listwallets”, “params”: []}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/
{“result”:[“wallet”,”test-wallet”],”error”:null,”id”:”curltest”}
Now that we have 2 wallets, we need to specify the wallet name, when we want to do a `getwalletinfo` method for a specific wallet, `test-wallet` in this case:
$ curl -s -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “getwalletinfo”, “params”: []}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet | jq .
{
“result”: {
“walletname”: “test-wallet”,
“walletversion”: 169900,
“format”: “bdb”,
“balance”: 0,
“unconfirmed_balance”: 0,
“immature_balance”: 0,
“txcount”: 0,
“keypoololdest”: 1623333495,
“keypoolsize”: 1000,
“hdseedid”: “x”,
“keypoolsize_hd_internal”: 1000,
“paytxfee”: 0,
“private_keys_enabled”: true,
“avoid_reuse”: false,
“scanning”: false,
“descriptors”: false
},
“error”: null,
“id”: “curltest”
}
In order to understand where the data resides for our `test-wallet`, we can use `find`:
$ find /blockchain/ -type f -name wallet.dat | grep test-wallet
/blockchain/bitcoin/data/testnet3/wallets/test-wallet/wallet.dat
$ find /blockchain/ -type f -name db.log | grep test-wallet
/blockchain/bitcoin/data/testnet3/wallets/test-wallet/db.log
Include the wallet name in the config located at `~/.bitcoin/bitcoin.conf`:
[test]
wallet=wallet
wallet=test-wallet
Then restart bitcoind:
$ sudo systemctl restart bitcoind
Now list our wallets again, and you should see they are being read from config and the wallets will persist if your node restarts:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “listwallets”, “params”: []}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/
{“result”:[“wallet”,”test-wallet”],”error”:null,”id”:”curltest”}
To backup a wallet, the `test-wallet` in this case:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “backupwallet”, “params”: [“test-wallet_bak.dat”]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet
{“result”:null,”error”:null,”id”:”curltest”}
To check where the file was backed up:
$ find /blockchain/ -name test-wallet_bak.dat
/blockchain/bitcoin/data/test-wallet_bak.dat
Addresses
At this moment we have wallets, but we don’t have any addresses associated to those wallets, we can verify this by listing wallet addresses using the `getaddressesbylabel` and passing a empty label as new addresses gets no labels assigned by default.
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “getaddressesbylabel”, “params”: [“”]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet
{“result”:{“”:{“purpose”:”receive”}},”error”:null,”id”:”curltest”}
Let’s generate a new address for our `test-wallet`:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “getnewaddress”, “params”: []}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet
{“result”:”tb1qr66hw59k958xrz008n679p8r9n2y7mjfr3tsjc”,”error”:null,”id”:”curltest”}
As you can see our address for `test-wallet` is `tb1qr66hw59k958xrz008n679p8r9n2y7mjfr3tsjc`, note that you can have multiple addresses per wallet.
To get address information for the wallet by using the `getaddressinfo` method and passing the wallet address as the parameter:
$ curl -s -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “getaddressinfo”, “params”: [“tb1qr66hw59k958xrz008n679p8r9n2y7mjfr3tsjc”]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet | jq .
{
“result”: {
“address”: “tb1qr66hw59k958xrz008n679p8r9n2y7mjfr3tsjc”,
“scriptPubKey”: “x”,
“ismine”: true,
“solvable”: true,
“desc”: “wpkh([05c34822/0'/0'/0']x)#x3x5vu3t”,
“iswatchonly”: false,
“isscript”: false,
“iswitness”: true,
“witness_version”: 0,
“witness_program”: “1eb57750b62dxe284e32cd44f6e49”,
“pubkey”: “023a1250c0d44751b604656x649357b5e530b9f8500f03ab5b”,
“ischange”: false,
“timestamp”: 1623333494,
“hdkeypath”: “m/0'/0'/0'”,
“hdseedid”: “x”,
“hdmasterfingerprint”: “x”,
“labels”: [
“”
]
},
“error”: null,
“id”: “curltest”
}
As before, we can view the address by label, to view the address for your wallet, we will now see our address:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “getaddressesbylabel”, “params”: [“”]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet
{“result”:{“tb1qr66hw59k958xrz008n679p8r9n2y7mjfr3tsjc”:{“purpose”:”receive”}},”error”:null,”id”:”curltest”}
Get available wallet balance with at least 6 confirmations,:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “getbalance”, “params”: [“*”, 6]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet
{“result”:0.00000000,”error”:null,”id”:”curltest”}
Get balances (all balances) for the `test-wallet` wallet:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “getbalances”, “params”: []}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet
{“result”:{“mine”:{“trusted”:0.00000000,”untrusted_pending”:0.00000000,”immature”:0.00000000}},”error”:null,”id”:”curltest”}
Create a new address:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “getnewaddress”, “params”: []}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet
{“result”:”tb1qa7e0mmgsul6pnxhzx7rw49y9qf35enqqra47hh”,”error”:null,”id”:”curltest”}
List all addresses for the wallet:
# by default new addresses has no labels, therefore it returns both
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “getaddressesbylabel”, “params”: [“”]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet
{“result”:{“tb1qr66hw59k958xrz008n679p8r9n2y7mjfr3tsjc”:{“purpose”:”receive”},”tb1qa7e0mmgsul6pnxhzx7rw49y9qf35enqqra47hh”:{“purpose”:”receive”}},”error”:null,”id”:”curltest”}
Labelling Addresses
Now we can label addresses on wallets, to label the first address as “green”:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “setlabel”, “params”: [“tb1qr66hw59k958xrz008n679p8r9n2y7mjfr3tsjc”, “green”]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet
{“result”:null,”error”:null,”id”:”curltest”}
Label the new address as “blue”:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “setlabel”, “params”: [“tb1qa7e0mmgsul6pnxhzx7rw49y9qf35enqqra47hh”, “blue”]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet
{“result”:null,”error”:null,”id”:”curltest”}
Now we can list addresses for our wallet by the label, “blue” in this example:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “getaddressesbylabel”, “params”: [“blue”]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet
{“result”:{“tb1qa7e0mmgsul6pnxhzx7rw49y9qf35enqqra47hh”:{“purpose”:”receive”}},”error”:null,”id”:”curltest”}
List addresses for our wallet by the label “green”:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “getaddressesbylabel”, “params”: [“green”]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet
{“result”:{“tb1qr66hw59k958xrz008n679p8r9n2y7mjfr3tsjc”:{“purpose”:”receive”}},”error”:null,”id”:”curltest”}
Create another address for our test-walet:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “getnewaddress”, “params”: []}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet
{“result”:”tb1qunk223dztk2j2zqswleyenwu3chfqt642vrp8z”,”error”:null,”id”:”curltest”}
Set the new address to the green label:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “setlabel”, “params”: [“tb1qunk223dztk2j2zqswleyenwu3chfqt642vrp8z”, “green”]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet
{“result”:null,”error”:null,”id”:”curltest”}
List addresses by green label:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “getaddressesbylabel”, “params”: [“green”]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet
{“result”:{“tb1qr66hw59k958xrz008n679p8r9n2y7mjfr3tsjc”:{“purpose”:”receive”},”tb1qunk223dztk2j2zqswleyenwu3chfqt642vrp8z”:{“purpose”:”receive”}},”error”:null,”id”:”curltest”}
Receive tBTC
You can?receive free test btc, by using any of these testnet faucet websites to receive tBTC over testnet:
The transaction details for sending 0.001 tbtc to my `tb1qr66hw59k958xrz008n679p8r9n2y7mjfr3tsjc` address, we will receive the following information:
Then to list transactions:
$ curl -s -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “listtransactions”, “params”: [“*”]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet | jq .
{
“result”: [
{
“address”: “tb1qr66hw59k958xrz008n679p8r9n2y7mjfr3tsjc”,
“category”: “receive”,
“amount”: 0.001,
“label”: “green”,
“vout”: 1,
“confirmations”: 0,
“trusted”: false,
“txid”: “637ea98aca23411059ad79aca7ea36ae30b68a173d89e6644703a06a1a846c25”,
“walletconflicts”: [],
“time”: 1623337058,
“timereceived”: 1623337058,
“bip125-replaceable”: “no”
}
],
“error”: null,
“id”: “curltest”
}
As you can see at the time, there were 0 confirmations, we can see the same txid as well as other info. With the testnet, we require at least 1 confirmation before a transaction is confirmed, where the mainnet requires 6.
To get balances for our wallet:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “getbalances”, “params”: []}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet
{“result”:{“mine”:{“trusted”:0.00000000,”untrusted_pending”:0.00100000,”immature”:0.00000000}},”error”:null,”id”:”curltest”}
As you can see as we don’t have any confirmations yet, so therefore the trusted value is still 0.
Listing the transactions over time:
$ curl -s -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “listtransactions”, “params”: [“*”]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet | jq .
{
“result”: [
{
“address”: “tb1qr66hw59k958xrz008n679p8r9n2y7mjfr3tsjc”,
“category”: “receive”,
“amount”: 0.001,
“label”: “green”,
“vout”: 1,
“confirmations”: 0,
“trusted”: false,
“txid”: “637ea98aca23411059ad79aca7ea36ae30b68a173d89e6644703a06a1a846c25”,
“walletconflicts”: [],
“time”: 1623337058,
“timereceived”: 1623337058,
“bip125-replaceable”: “no”
}
],
“error”: null,
“id”: “curltest”
}
After a couple of minutes:
$ curl -s -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “listtransactions”, “params”: [“*”]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet | jq .
{
“result”: [
{
“address”: “tb1qr66hw59k958xrz008n679p8r9n2y7mjfr3tsjc”,
“category”: “receive”,
“amount”: 0.001,
“label”: “green”,
“vout”: 1,
“confirmations”: 2,
“blockhash”: “0000000000000000ba226ad21b51fe3998180dc354ec433ad7a4c4897e04d805”,
“blockheight”: 2004280,
“blockindex”: 107,
“blocktime”: 1623337883,
“txid”: “637ea98aca23411059ad79aca7ea36ae30b68a173d89e6644703a06a1a846c25”,
“walletconflicts”: [],
“time”: 1623337058,
“timereceived”: 1623337058,
“bip125-replaceable”: “no”
}
],
“error”: null,
“id”: “curltest”
}
Testnet Block Explorer
We can also use a blockchain explorer, head over to a testnet blockchain explorer, such as:
And provide the txid, in my case it was this one:
This transaction was done a while ago, so the confirmations will be much more than from the output above, but you can see the confirmations, addresses involved and?tbtc?amount.
To only get the?trusted?balance, using the?getbalance?method and with at least 6 confirmations(note: testnet only requires 1 confirmation to mark a transaction confirmed):
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “getbalance”, “params”: [“*”, 6]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet
{“result”:0.00100000,”error”:null,”id”:”curltest”}
Let’s send another transaction, the list the transactions using the?listtransactions?method:
$ curl -s -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “listtransactions”, “params”: [“*”]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet | jq .
{
“result”: [
{
“address”: “tb1qr66hw59k958xrz008n679p8r9n2y7mjfr3tsjc”,
“category”: “receive”,
“amount”: 0.001,
“label”: “green”,
“vout”: 1,
“confirmations”: 4,
“blockhash”: “0000000000000000ba226ad21b51fe3998180dc354ec433ad7a4c4897e04d805”,
“blockheight”: 2004280,
“blockindex”: 107,
“blocktime”: 1623337883,
“txid”: “637ea98aca23411059ad79aca7ea36ae30b68a173d89e6644703a06a1a846c25”,
“walletconflicts”: [],
“time”: 1623337058,
“timereceived”: 1623337058,
“bip125-replaceable”: “no”
},
{
“address”: “tb1qr66hw59k958xrz008n679p8r9n2y7mjfr3tsjc”,
“category”: “receive”,
“amount”: 0.0111048,
“label”: “green”,
“vout”: 0,
“confirmations”: 1,
“blockhash”: “000000000000002912e2da87e6e752c38965fc21e108aab439fcdcd82ba6e37a”,
“blockheight”: 2004283,
“blockindex”: 4,
“blocktime”: 1623338496,
“txid”: “3cac023b088a2ddb2d601538edfc72cd1bff1bd2e1a1531518500c5b7a52e473”,
“walletconflicts”: [],
“time”: 1623338453,
“timereceived”: 1623338453,
“bip125-replaceable”: “no”
}
],
“error”: null,
“id”: “curltest”
}
After?12 hours, we can see that we have?102 confirmations?for our first transaction and?99 transactions?for the second transaction:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “listtransactions”, “params”: [“*”]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet | jq .
{
“result”: [
{
“address”: “tb1qr66hw59k958xrz008n679p8r9n2y7mjfr3tsjc”,
“category”: “receive”,
“amount”: 0.001,
“label”: “green”,
“vout”: 1,
“confirmations”: 102,
“blockhash”: “0000000000000000ba226ad21b51fe3998180dc354ec433ad7a4c4897e04d805”,
“blockheight”: 2004280,
“blockindex”: 107,
“blocktime”: 1623337883,
“txid”: “637ea98aca23411059ad79aca7ea36ae30b68a173d89e6644703a06a1a846c25”,
“walletconflicts”: [],
“time”: 1623337058,
“timereceived”: 1623337058,
“bip125-replaceable”: “no”
},
{
“address”: “tb1qr66hw59k958xrz008n679p8r9n2y7mjfr3tsjc”,
“category”: “receive”,
“amount”: 0.0111048,
“label”: “green”,
“vout”: 0,
“confirmations”: 99,
“blockhash”: “000000000000002912e2da87e6e752c38965fc21e108aab439fcdcd82ba6e37a”,
“blockheight”: 2004283,
“blockindex”: 4,
“blocktime”: 1623338496,
“txid”: “3cac023b088a2ddb2d601538edfc72cd1bff1bd2e1a1531518500c5b7a52e473”,
“walletconflicts”: [],
“time”: 1623338453,
“timereceived”: 1623338453,
“bip125-replaceable”: “no”
},
{
“address”: “tb1qr66hw59k958xrz008n679p8r9n2y7mjfr3tsjc”,
“category”: “receive”,
“amount”: 0.03521065,
“label”: “green”,
“vout”: 5,
“confirmations”: 27,
“blockhash”: “000000000000004255a9d5af67b4649ff3f4d6a2f0c334261ca822cd9fbd00a9”,
“blockheight”: 2004355,
“blockindex”: 43,
“blocktime”: 1623383177,
“txid”: “eb43868bd2c5abd97d4f5f11450952837bc3edc149478248e9453fdfb05c5187”,
“walletconflicts”: [],
“time”: 1623382990,
“timereceived”: 1623382990,
“bip125-replaceable”: “no”
}
],
“error”: null,
“id”: “curltest”
}
After 3 transactions, view the balance in the test wallet using the `getbalance` method:
$ curl -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curltest”, “method”: “getbalance”, “params”: [“*”, 6]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet
{“result”:0.04731545,”error”:null,”id”:”curltest”}
Sending a Transaction
To send a transaction is by using the?sendtoaddress?method?and the source wallet will be in the request url, ie: `/wallet/wallet-name`
First we look if we have a address for our account that we are?sending from, if not then we can create a wallet and a address, for this example, I have a address for the `wallet` wallet:
$ curl -s -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curl”, “method”: “getaddressesbylabel”, “params”: [“”]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/wallet
{“result”:{“tb1qks4tyrz52vvdh35kcx0ypvnj3fjdkl692pzfyc”:{“purpose”:”receive”}},”error”:null,”id”:”curl”}
Ensure that our source wallet has funds in it:
$ curl -s -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curl”, “method”: “getbalance”, “params”: []}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/wallet | python -m json.tool
{
“error”: null,
“id”: “curl”,
“result”: 0.01811929
}
We have enough funds to send, so we now have the source wallet name and we need to get the wallet address, where we want to send the funds to, which in this case is the address in `test-wallet` as the destination:
$ curl -s -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curl”, “method”: “getaddressesbylabel”, “params”: [“”]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet
{“result”:{“tb1qzxmefmcpq98z42v67a80gvug2fe979r5h768yv”:{“purpose”:”receive”}},”error”:null,”id”:”curl”}
Just to double check our current funds in the wallet that will receive funds:
$ curl -s -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curl”, “method”: “getbalance”, “params”: []}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/test-wallet | python -m json.tool
{
“error”: null,
“id”: “curl”,
“result”: 0.35572584
}
Now we will use the?sendtoaddress?method, with the recipient address and the amount to send as the parameters. To summarize:
Sending the amount:
$ curl -s -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”:”0", “method”: “sendtoaddress”, “params”:[“tb1qzxmefmcpq98z42v67a80gvug2fe979r5h768yv”, 0.01]}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/wallet
{“result”:”df087095ac79d678f9d98c8bf8ebface2ac62a20546d85e07a852feb2c3bea50",”error”:null,”id”:”0"}
We will receive a?transaction id?in the response, and if we list for transactions for our source wallet, we will see the transaction:
$ curl -s -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curl”, “method”: “listtransactions”, “params”: []}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/wallet | python -m json.tool
{
“error”: null,
“id”: “curl”,
“result”: [
{
“address”: “tb1qks4tyrz52vvdh35kcx0ypvnj3fjdkl692pzfyc”,
“amount”: 0.01811929,
“bip125-replaceable”: “no”,
“blockhash”: “000000000000003c0ac4978ba815ff8f0d7f55da98923c686118c75461fb579e”,
“blockheight”: 2091275,
“blockindex”: 1,
“blocktime”: 1630677226,
“category”: “receive”,
“confirmations”: 1,
“label”: “”,
“time”: 1630677177,
“timereceived”: 1630677177,
“txid”: “e44b45a309284e8044a15dca8c0a895a5c7072741882281038fb185cc0c1a0d9”,
“vout”: 0,
“walletconflicts”: []
},
{
“abandoned”: false,
“address”: “tb1qzxmefmcpq98z42v67a80gvug2fe979r5h768yv”,
“amount”: -0.01,
“bip125-replaceable”: “no”,
“category”: “send”,
“confirmations”: 0,
“fee”: -1.41e-06,
“time”: 1630677743,
“timereceived”: 1630677743,
“trusted”: true,
“txid”: “df087095ac79d678f9d98c8bf8ebface2ac62a20546d85e07a852feb2c3bea50”,
“vout”: 0,
“walletconflicts”: []
}
]
}
So when we look at the sender wallet, we will see the funds was deducted:
$ curl -s -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curl”, “method”: “getbalance”, “params”: []}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/wallet | python -m json.tool
{
“error”: null,
“id”: “curl”,
“result”: 0.00811788
}
And when we look at the receiver wallet, we can see that the account was received:
$ curl -s -u “$bitcoinauth” -d ‘{“jsonrpc”: “1.0”, “id”: “curl”, “method”: “getbalance”, “params”: []}’ -H ‘content-type: text/plain;’ https://127.0.0.1:18332/wallet/rpi01-main | python -m json.tool
{
“error”: null,
“id”: “curl”,
“result”: 0.36572584
}
Thank You
For more details Please message me.