Part 8: Working with Fullnodes

cryptoskillz
Bitcoin e-commerce development
8 min readOct 16, 2018

Introduction

This guide aims to program a website to accept Bitcoin. In the last section, we refactored a bunch of code and this time we are going to look at full nodes. There is not much code change in this part, instead, we are going to discuss the theory of how to use a full node. The reason being when we first jumped into full nodes (about a month ago) as a simple replacement for block.io’s estimatefee function and found Full nodes are hella cool and can do a whole more than what our original plan was. Never be scared to change your mind kids, it’s a core tenet of programming.

What is a fullnode?

Lifted directly from bitcoin.org. A full node is a program that 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.

Most full nodes also serve lightweight clients by allowing them to transmit their transactions to the network and by notifying them when a transaction affects their wallet. If not enough nodes perform this function, clients won’t be able to connect through the peer-to-peer network — they’ll have to use centralized services instead.

Many people and organizations volunteer to run full nodes using spare computing and bandwidth resources — but more volunteers are needed to allow Bitcoin to continue to grow.

fullnode 101

Disclaimer

There a number of full nodes out there I am going to focus on Bitcoin Core. Also, I use a Mac so all instructions will show how to interact with it on a mac. Please adjust the information accordingly.

Good things to know

Most of the tutorials on setting up / running a full node are pretty old (read out of date) and as a result, you have to do a lot of wrong things to get one up and running and start interacting with it. I have listed factoids below that I found whilst doing my research.

what is Bitcoind?
Bitcoind is a headless daemon. It provides a JSON-RPC and a REST (in beta restricted to local access for now) interface, allowing it to be controlled locally or remotely which makes it useful for integration with other software or in larger payment systems. Various commands are made available by the API.

What is Bitcoin Core?
Bitcoin Core (formerly Bitcoin-Qt) is the third Bitcoin client by Wladimir van der Laan based on the original reference code by Satoshi Nakamoto.

Bitcoin Core can be used as a desktop client for regular payments or as a server utility for merchants and other payment services.

Note, even though BitcoinQT was renamed to Bitcoin Core when you reference it from the terminal it is still called BitcoinQT, nice work devs.

bitcoind is included in Bitcoin Core
You will read lots of tutorials that tell you bitcoind is not in BitcoinQT or it is not the mac version and you will have to download it separately. Although you can download bitcoind separately (recommended for servers) for testing you can use Bitcoin Core.

Bitcoin core comes with an excellent javascript library
As part of the rebranding to Bitcoin Core, I assume the package called bitcoin was retired and replaced with the Bitcoin Core package so if you come across any tutorials referencing the NPM Bitcoin package you can replace it with the Bitcoin Core package (with the appropriate code changes)

What are the accounts?

Think of them as a way to track transactions for “users” just the way banks do. I have used these in this tutorial even though the whole account concept is being deprecated. However, the new functions are only in a pull request so I will continue to use them until the new functions are ready. You can find more about accounts here and the proposed changes here.

Default RPC ports
Bitcoin RPC mainnet runs on port 8332 and testnet runs on 18332

CamelCase

You will see that all of the RPC calls are in lower case but when we use them in the code camel case is excepted. This is more annoying in anything else they should agree on one methodology and use it holistically throughout all aspects of Bitcoin.
Note the docs also show them a third format (shown below) all the mean the same thing.

estimatesmartfee
estimateSmartFee
EstimateSmartFee

Setting up a fullnode

great, now we got the above out the way lets go ahead and set up the Bitcoin Core full node, shall we.

Download Bitcoin Core

You should have already had Bitcoin Core if you have followed any of the tutorials if not you can get it here.

Once you have downloaded it open a terminal type the following command.

cd /Applications/Bitcoin-Qt.app/Contents/MacOS/

Once you in this directory run the command below. This command will launch the Bitcoin Core client in server mode. Let’s take a look at what the arguments are doing.

server: Start in server mode
rpcuser: The username for the RPC server
rpcpassword: The password for the RPC server
rest: The rest server
testnet: Launch in the test network

./Bitcoin-Qt -server -rpcuser=test  -rpcpassword=test -rest -testnet

Once you have run that command you will see Bitcoin Core boot up as shown below.

Connect to rest

Now we can connect via REST by opening a browser and going to this URL and you will see a JSON output (as shown below). Of course, this is a simple GET request with POST etc it is slightly trickier.

You can find a full list of REST commands here you can either interact with this with a Chrome extension called POSTMAN or by opening a new terminal window and running a CURL request as shown below.

curl http://127.0.0.1:18332/rest/chaininfo.json

Some useful CURL examples can be found here.

Connect to RPC

Connecting to RPC using is similar to the REST and is shown below. This is the main we are going to interact with the fullnode as good as REST is it is not nearly as feature rich as the RPC API.

*note: cryptoskillz from the future here the “getinfo” function has been removed from the most recent version of RPC so this command will now produce an error.

curl --user test  --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getinfo", "params": [] }'     -H 'content-type: text/plain;' http://127.0.0.1:18332/

You will be asked to enter the password which you set above (rpcpassword) enter this and you will get a result something like the one below.

{
"result": {
"chain": "test",
"blocks": 1438199,
"headers": 1438199,
"bestblockhash": "00000000000003e2ecbb6d376016a84aa5ab89d299e455c5823d8a90d300d6f5",
"difficulty": 4166899.806567,
"mediantime": 1539596338,
"verificationprogress": 0.99999561714928,
"initialblockdownload": false,
"chainwork": "0000000000000000000000000000000000000000000000c8507d634426736c14",
"size_on_disk": 22923325413,
"pruned": false,
"softforks": [
{
"id": "bip34",
"version": 2,
"reject": {
"status": true
}
},
{
"id": "bip66",
"version": 3,
"reject": {
"status": true
}
},
{
"id": "bip65",
"version": 4,
"reject": {
"status": true
}
}
],
"bip9_softforks": {
"csv": {
"status": "active",
"startTime": 1456790400,
"timeout": 1493596800,
"since": 770112
},
"segwit": {
"status": "active",
"startTime": 1462060800,
"timeout": 1493596800,
"since": 834624
}
},
"warnings": "Warning: unknown new rules activated (versionbit 28)"
},
"error": null,
"id": "curltest"
}

You can find a full list or RPC commands here.

The Code

As I said earlier we are not really going to modify any of the server code as we this is a deep dive of how full nodes work. The branch that has this code is here and the file called rpc.js so let’s take a look at what is happening.

As you can see I am using the Bitcoin core package but we could just as easily use a CURL class or even filgetcontents if we want to get really basic (we do not).

The reason I have used the bitcoin core package as it is coded by the same community who code Bitcoin Core wallet and bitcoind. When I started playing with it quickly became clear that it could do everything that Bitcoinjs (the current package I am using) which to me is very interesting. As I was using Bitcoinjs it frustrated me that it would sign and create transactions but did not have native support for RPC commands. I get they want abstraction from node/wallets but it just feels like a compromise to the library purely for comprise sake.

Also on top of that, we do not have to store the private keys anywhere as we have RPC access to the node that created the address we can simply use the dump private key function for singing etc. This makes perfect sense and as Bitcoin is one of the most secure pieces of software the world has ever seen why to try to replicate this security off chain?

Note, cryptoskillz adding this from the future. It became very clear that BitcoinJs is required when we researched addresses in part 10. It will be back in part 11 to generate the address to improve cold storage functionality.

On to the code.

You will see from the code below we are doing a really simple thing. unlocking the wallet, generating an address and getting the private key. The address I have used in one in the Bitcoin Core that I send funds to in an earlier tutorial.

The address used for the example below.
//load bitcoin core
const Client = require("bitcoin-core");
//open a connection to the RPC client
const client = new Client({
host: "127.0.0.1",
port: 18332,
username: "test",
password: "test"
});
/*
//run this once to encrypt your wallet id you have not already done so.
client.encryptWallet('test').then((res) => {
console.log(res)
});
*/
//unlock the waller for 10 seconds
client.walletPassphrase("test", 10).then(() => {
//create a new address in theaccount account :]
client.getNewAddress("theaccount").then(address => {
//debug
console.log(address);
//get the private key
client.dumpPrivKey(address).then(privkey => {
//debug
console.log("privkey:" + privkey);
//now have the prviate key we can sign transactions etc, basically do whatever we did with BitcooinJS
//do stuff
//lock the wallet
client.walletLock();
});
});
});

You can run the code above by going to the server directory in a terminal window and typing the following command (as usual)

node rpc.js

Conclusion

As you can see we can use the Bitcoin Core (with bitcoind) and the NPM package we have 100% sovereignty over our code and by extension our Bitcoin. See this as a segway to the main tutorial parts and as such, I can see myself coming back and updating this part a lot in the coming weeks and months (cryptoskillz adding this from the future “told ya”)

In the next tutorial, we will either replace all the BitcoinJs code and/or replace the block.io 3rd party calls.

--

--