Bitcoin basics: Programming with bitcoinjs-lib

Deezy
7 min readJul 23, 2019

--

Bitcoin is programmable digital money built by volunteers, and is open to everyone. The javascript library bitcoinjs-lib is great way to learn the basics of bitcoin programming. This tutorial requires no prior knowledge of bitcoin or programming. Estimated time to complete is 10 minutes.

In this tutorial we will do the following:

  • Generate a key
  • Create an address
  • Receive (testnet) bitcoin
  • Build a transaction
  • Sign it
  • Send it

Part 0: Setup

If you don’t have Node installed on your computer, download NodeJS:

Next we’re going to install the bitcoinjs-lib npm package. Note, you should always audit packages in some way before installing them. If you’re super hardcore, you’d read every line of code, but that’s a bit unrealistic. A good sanity check is to look at the number of weekly downloads. Generally in open source software, more downloads means more eyes on the code, and more eyes is a good thing.

Once you’re convinced that bitcoinjs-lib is not harmful, you’re ready to install it. To do this, open up the application called “Terminal” (on Mac/Linux) or “Command Prompt” (on Windows), and type the following command:

npm i -g bitcoinjs-lib

Once this succeeds, we’re ready to open up our NodeJS session by typing the following command into your terminal:

node

This should open up something that looks like this:

>

This is your NodeJS console, and this is where the rest of the tutorial will take place. Throughout the tutorial, be sure to keep the terminal window open and don’t exit the node session, or you will lose any variables you’re working with.

Ready? Let’s go.

Part 1: Receiving Testnet Bitcoin

First we need to include the package we just installed:

> const bitcoin = require('bitcoinjs-lib')

Now let’s set the network to testnet. Testnet is a clone of the bitcoin network that uses the same rules, except the coins aren’t worth anything. Developers use it to test their code without having to risk real money:

> const network = bitcoin.networks.testnet

Now we’ll generate a key pair. In bitcoin, a key pair consists of a private key and a public key. The private key should always be kept secret, and you use it to cryptographically prove ownership of your coins. The public key is used to create addresses, which you can safely share with others. Let’s create a key pair with:

> const keypair = bitcoin.ECPair.makeRandom({ network })

And let’s grab the public key from the keypair:

> const pubkey = keypair.publicKey

We’re now going to use this public key to create a pay-to-pub-key-hash (p2pkh) address. This is the simplest type of address in bitcoin that people use. Bitcoin addresses can have all types of complex addresses with crazy spending conditions, but this simple p2pkh address means any funds sent to it will be owned by only your private key:

> const addressObject = bitcoin.payments.p2pkh({ pubkey, network })

Now we can print out the address with:

> addressObject.address

That should print out something that starts with an ‘m’ or ’n’, something like this:

'mfs3V2D5h8x4YyZqbow1jKnWYdYiJRbE3C'

Great! Now copy your address (not mine!!) and…

Go to this testnet faucet

Paste your address in there and submit it, and they should send you some testnet bitcoin right away.

Congratulations, you’re now a testnet bitcoin hodler.

Part 2: Sending Bitcoin

First, go to this public testnet block explorer.

Paste your address in the search bar:

Press enter, and it should take you to your address’s info page. Once you’re there, scroll down a little and you’ll see something like this, but with different addresses, transaction ID’s and values:

This is the transaction that the faucet just sent. It’s likely that you’ll see one input (on the left) and two outputs (on the right). One of the outputs will be to your newly generated address. The other output is a change output, which spends bitcoin back to the faucet’s own wallet.

For my transaction, we can see that the output I now own is output #0:

Inspect your transaction, and see which output corresponds to your new address. These testnet faucet transactions generally have only two outputs, so yours should be either #0 or #1.

Let’s go back to your NodeJS console and save your output number. I’m going to set mine to 0, but yours might be 1. Set the your output number accordingly:

> const outputNumber = 0 

Great, now we need to get the txid. My txid is circled below:

Try to find yours on your page, then copy that value, and let’s set the variable in your node console (replace my transaction id with yours):

> const txid = 'a4e407f854ca4c4b387fa137c3716b20386c0cf306997a38d4092bb30d8bd2ed'

Finally we need to make note of the amount. The amount you received is just to the right of your address on the transaction page:

Copy this value and set it in your node console:

> const amount = 0.05485389

Now you have all the data you need to construct a transaction, and spend your testnet bitcoin! We’ll start by creating a TransactionBuilder, which is going to help us create this transaction:

> const txb = new bitcoin.TransactionBuilder()

And make sure we set the network of our builder:

> txb.network = bitcoin.networks.testnet

In bitcoin, an output from one transaction becomes an input to another one. Right now, your address owns one single UTXO (unspent transaction output). We’re going to spend this UTXO by making it an input to a new transaction. To do this, we need to specify the Transaction ID we’re referring to, and the output number that we’re using (remember, we just got those two values from the block explorer: txid and outputNumber). Do the following command:

> txb.addInput(txid, outputNumber)

Great. Now we need to construct the output to our new transaction. First you’ll need to set a destination address. You can send these testnet bitcoin back to the faucet’s testnet donation address, which I’ve entered below:

> const destinationAddress = 'mv4rnyY3Su5gjcDNzbMLKBQkBicCtHUtFB'

And we need to set a miner fee (in satoshis) :

> const minerFee = 10000

***(Note there are 100,000,000 satoshis in 1 bitcoin)***

Now lets calculate the output amount (in satoshis):

> const outputAmount = amount*1e8 - minerFee

Great, now we can add an output to our transaction:

> txb.addOutput(destinationAddress, outputAmount)

Awesome. We’ve now set up our transaction, which has 1 input and 1 output. Now we need to sign it with our key. In bitcoin, every input to a transaction needs to be signed. In our case, we only have 1 input, so we need to sign the “0th” input with our key pair, like so:

> txb.sign(0, keypair)

Excellent! Now we need to build the transaction and serialize it into hexadecimal format:

> txb.build().toHex()

This should print out something that looks like this:

'0200000001edd28b0db32b09d4387a9906f30c6c38206b71c337a17f384b4cca54f807e4a4000000006a47304402207926371c1cb87cc30c213b2c5b43f46c9ec967a0ed9ad553b04ead9aa89d84ba02202ba30df5baf990fbaa218bf15fe0b78f7664e0ddadf0253fbf14239407763202012103375a03fbef2286b3d3b459d5bc80e6eb5880c39ca6ecf64a871272e9c049ce8bffffffff013d8c53000000000017a9144897879a720ab947dcbe3eebe068500fd171a89f8700000000'

Now you should copy your transaction hex (not including the quotes) and:

Go to Blockstream’s Testnet Broadcasting Tool

Paste your transaction hex into the form on that page and click “Broadcast transaction”

That should succeed, and show you your completed transaction! Something like this:

So what just happened? You sent your signed transaction out to a bunch of testnet bitcoin nodes, and since your transaction was valid, these nodes all forwarded it to other nodes. Eventually, a miner will include it in a block.

Congratulations!!

If you’ve enjoyed this tutorial, please give me a shoutout on twitter: @bitcoindeezy

Or even consider donating to me. Donations will be hodl’d then eventually converted into beer: bc1qxa43j39d0yg750e6a66f8epk69d3phajyg6pz9

Did you get stuck or run into trouble? Leave a comment and I can help :)

Hodl and Buidl!!

--

--