Getting Started with BitGoD

Three weeks ago I started working at BitGo as a software developer on the Platform/API team, and I got to get my hands dirty with one of BitGo’s open-source software tools, bitgod. I hadn’t used it prior to joining the company, so I quickly headed over to the BitGoD Github page to checkout the README and any documentation. Although the Summary section in the README is clear and concise, it took me longer than I thought it would to understand BitGoD to the point where I could make and test code changes. I spent a large chunk of that time learning exactly where bitgod sits in a blockchain developer’s stack, and what it should be used for. In response to this confusion, I wrote this article to help get you up to speed with bitgod as fast as possible.

The Road Plan

I’ll start by explaining why bitgod exists, then follow with an installation guide. Finally, I’ll go over the some common commands, and end by explaining how one can use bitgod as a proxy to bitcoind to eliminate single points of failure in the unlikely event that BitGo’s service is interrupted.

There are several assumptions I’m making when writing this post.

  • You are familiar with using a bitcoind
  • You’ve created an account on either BitGo’s test network or its production network
  • You’ve created a wallet which we’ll refer to as <your_wallet>
  • You’ve created a second wallet which we’ll refer to as <your_other_wallet>
  • You want to run bitgod on a Linux machine

For Mac and Windows users, all of these commands should be the same except for installing bitcoind. If you’re unfamiliar with running bitcoind, then you should use BitGo Express, as it accomplishes a very similar goal to bitgod, but is for users whose systems are not already built to work with bitcoind. If you don’t have a BitGo account and wallet, head over to BitGo’s production page or testnet page to set up your free account. With that all done, let’s dive in!

What is BitGoD and Why Use it?

Straight from the BitGoD’s Github page:

BitGoD is a drop-in replacement for bitcoind JSON-RPC which proxies to the BitGo API

bitcoind interacts with the blockchain, and even knows about multi-sig addresses, but it knows nothing about the wallets and services made available through BitGo. Imagine you are an admin of a BitGo wallet and you want to unlock the wallet so you can spend its bitcoins. bitcoind can’t do this for you, because it doesn’t know anything about BitGo! By replacing bitcoind with bitgod, you’ll have the ability to communicate with the Bitcoin blockchain as you did previously with bitcoind, and talk to BitGo’s backend for all your BitGo wallet-related needs.

In the description above it says bitgod uses the BitGo API. This refers to BitGoJS, BitGo’s Javascript library which all of BitGo’s software uses to interact with BitGo’s backend servers. This is powerful, because with bitgod you can continue to use most of the CLI (command line interface) functionality accepted by bitcoind while at the same time get access to BitGoJS’s functionality. On the other hand, it introduces a single point-of-failure into your system by relying on BitGo’s servers for wallet and blockchain information. But don’t worry! After the upcoming installation guide and a brief look at what we can do with a standalone bitgod instance, we’ll see how we can use bitgod and bitcoind together to reduce the dependence on BitGo.

Setting Up BitGoD

Installing and running bitgod

bitgod is a NodeJS application written in Javascript, so you can install it using the node package manager npm.

npm install -g bitgod

where we use the “-g” flag to specify that we want to download bitgod to the system-wide node_modules directory, so we aren’t restricted to running it within one particular directory. If you don’t have npm installed, you can install nodejs which has npm bundled with it:

sudo apt-get install nodejs

Now we can run bitgod. We can connect it to either BitGo’s testnet or the main bitcoin blockchain. Because this is our first time running bitgod and we want to minimize the risk of losing valuable BTC, we’ll have bitgod connect to the testnet. Make sure you’ve set up an account and created a wallet at test.bitgo.com/signup (remember your wallet passphrase!) then run

nohup bitgod -rpcport 19332 &

The “nohup” command makes sure bitgod won’t stop running when you close your terminal screen, the “&” makes the bitgod process run in the background, and the “-rpcport 19332” assures bitgod will connect to the BitGo’s testnet (not passing any -rpcport option, or passing “-rpcport 9332” will connect you to the main blockchain network). If you want to stop the bitgod process, enter the following command:

kill -15 `ps aux | grep bitgod | grep -v grep| awk '{print $2}'`

which issues a SIGTERM shutdown signal to the PID of the bitgod process.

Installing bitcoin-cli

Since bitgod acts as server, you need a client to interact with it. That client will be bitcoin-cli, the same CLI we use to talk with the regular bitcoind process. If you’ve already installed bitcoind, great! You already have bitcoin-cli and can skip ahead to the section about downloading bitgo-cli. If you need to install bitcoind run the following command:

sudo apt-get install bitcoind

To check if it downloaded correctly, run the command below:

bitcoind -testnet -daemon

and you should see a single-line message about bitcoind starting up.

Tokens and Authentication

OK, so far we’ve installed and run bitgod, and installed the bitcoin CLI which we’ll use to send calls to it. Now we need to authenticate ourselves with BitGo so we can actually use bitgod. We could keep creating one-time-use tokens everytime we use bitgod, but the easiest way in the long run is to create a long-lived access token, and have all future calls to bitgod authenticated by this token.

Creating this token is pretty easy. Log onto your testnet BitGo account here. Once you’re logged in, click on your email address in the top-right corner and click on “Account Settings” in the dropdown that appears. On the following page click the “API Access” navbar option and click “Add Access Bar Token”. Give yourself whichever permissions you’d like, and you can leave the “IP Addresses Allowed” field empty so you can use the token from any network you want (if this were a production wallet you would have to supply a IP whitelist). Once you generate the token, add the following line to your ~/.bashrc or /etc/profile file so that your token can be accessed with “$TEST_ACCESS_TOKEN” in any of your future shells.

export TEST_ACCESS_TOKEN="7a41d49f5...eab9b96e"

and then run the following command in your terminal:

source ~/.bashrc && source /etc/profile

If you need help understanding why you’re adding the export line to either your .bashrc or .profile file, check out this explanation.

Now we’re ready to authenticate with BitGo. Run the following command:

bitcoin-cli -rpcport=19332 settoken $TEST_ACCESS_TOKEN
Authenticated as BitGo user: myusername@gmail.com

Finally we’ve created a session with BitGo! Now we’ll move on to seeing a couple use cases.

Getting our Hands Dirty with BitGoD

bitgod is designed to be used on a per-wallet basis. One token, one session, one wallet. Assuming you want to send wallet-based calls to BitGo (that’s why you’re using bitgod in the first place, right?) you need to set which wallet you want to use:

bitcoin-cli -rpcport=19332 setwallet <your_wallet>
Set wallet: 2NA72xxRjST...hoXPQqHgr4

Now with a wallet set, lets check information about our session:

bitcoin-cli -rpcport=19332 session
{
"id" : "55d1719056d432af54baf72a330d41b0",
"client" : "bitgo",
"user" : "55d17075313261c0121a9166ef04db3e",
"scope" : [
"user_manage",
"openid",
"profile",
"wallet_create",
"wallet_manage_all",
"wallet_approve_all",
"wallet_spend_all",
"wallet_edit_all",
"wallet_view_all"
],
"created" : "2015-08-17T05:30:56.411Z",
"expires" : "2015-08-17T06:30:56.212Z",
"origin" : "test.bitgo.com"
}

Here we see the types of policies set for our wallet, and more information about our session with BitGo.

Let’s try to send some bitcoin through bitgod. First you’ll need to acquire some testnet coins. Head over to this testnet bitcoin faucet and enter in <your_wallet> to recieve some free testnet bitcoins. You should see those show up in the wallet in around 10 minutes, and you can verify by running:

bitcoin-cli -rpcport=19332 getbalance

Once you’ve received the testnet faucet bitcoins, we’ll send some bitcoins to the second wallet. First you need to unlock your current wallet to send transactions:

bitcoin-cli -rpcport=19332 unlock 0000000
Unlocked

where here we passed the testnet otp “0000000”. Then you need to decrypt your wallet so you can sign the transaction with your private key:

bitcoin-cli -rpcport=19332 walletpassphrase <your_wallet_password> <your_wallet> 4000

where here the <your_wallet_password> is the wallet’s password (which should be your account password unless you chose to enter a wallet-specific passphrase), and the “4000” is the time in seconds to keep the passphrase in memory.

Now we can send some bitcoins! Enter the following command:

bitcoin-cli -rpcport=19332 sendtoaddress <my_other>wallet> 0.01 "my first bitgod transaction"

where here you use the address of the second wallet you created. I chose to send only 0.01 BTC, but you can send as much as you’re able to. That last argument is just an optional comment you can attach to a transaction. Now, wait for the next block to be mined which should take about 10 minutes, run the following command to set the current wallet to <your_other_wallet>:

bitcoin-cli -rpcport=19332 setwallet <your_other_wallet>

and then run:

bitcoin-cli -rpcport=19332 getbalance

and you should see the bitcoin has arrived!

So far we’ve seen several commands for working with your BitGoD wallets. Now let’s look at a more advanced way to use bitgod and bitcoind in tandem.

Using bitgod as a proxy to bitcoind

bitgod is great for using BitGo’s services through the bitcoin-cli interface many are accustomed to. However, the way which we’ve been using it so far implicitly requires us to trust that BitGo is returning the proper data to us. Were BitGo’s service to go down, or worse were BitGo to be hacked and controlled by a malicious entity, the data received from bitgod could wreak havoc with a user’s system. For instance it could return false information about transactions on the blockchain.

BitGo’s primary concern is the security of your bitcoins, and so to mitigate this problem they’ve made it possible to proxy non-wallet commands to your own instance of bitcoind. So, assuming you have an instance of bitcoind connected the the testnet (port 18332) with the rpcusername bitcoinrpc and the rpcpassword mypassword run the following command to run bitgod as a proxy:

nohup bitgod -rpcport 19332 -proxyhost localhost -proxy true -proxyport 18332 -proxyuser bitcoinrpc -proxypassword mypassword &

To check if this is now proxying correctly, issue the following command to get information about the network:

bitcoin-cli -rpcport=19332 getinfo
{
"bitgod" : true,
"version" : "0.2.14",
"testnet" : true,
"token" : false,
"wallet" : false,
"keychain" : false,
"paytxfee" : 0.00010000,
"proxy" : {
"version" : 100100,
"protocolversion" : 70002,
"blocks" : 205641,
"timeoffset" : -201,
"connections" : 8,
"proxy" : "",
"difficulty" : 1,
"testnet" : true,
"relayfee" : 0.00001000,
"errors" : ""
}
}

Compare this to the result of issuing the same command to a un-proxied bitgod:

bitcoin-cli -rpcport 19332 getinfo      # running un-proxied
{
"bitgod" : true,
"version" : "0.2.14",
"testnet" : true,
"token" : false,
"wallet" : false,
"keychain" : false,
"paytxfee" : 0.00010000
}

Here we see the response includes both information obtained from BitGo’s servers, and information from the bitcoind server.

Where this really comes in handy is validating transactions we get from BitGo. This solves the problem I mentioned before where if BitGo is compromised and you’re running un-proxied, you have no way to validate if the transactions you’re seeing are the transactions the rest of the network is seeing. Imagine you’re running a payment processing system using bitgod. You accept BTC deposits from your customers, and then credit customers’ wallets with USD once the initial deposit transaction reaches 6+ confirmations. If BitGo is compromised, you might see transactions which don’t actually exist on the real blockchain, and then erroneously credit your customers’ wallets for deposits they never made!

Running bitgod in a proxied manner aims to prevent these types of scenarios. Currently (as of bitgod v0.2.14) this validation only covers the listtransactions command, but it will be extended in the future.

To test this validation, kill bitgod, and make sure you’re running your bitcoind instance with the “-txindex” option which causes bitcoind to index all of the transactions for fast lookup. This may require you to kill your bitcoind instance and rerun it with the command

bitcoind -testnet -daemon -reindex

which may take as long as a day or two to reindex based on your network speed. Once your bitcoind reindexes, run the following command to have bitgod validate the transactions it receives with bitcoind

nohup bitgod -rpcport 19332 -validate=loose -proxyhost localhost -proxy true -proxyport 18332 -proxyuser bitcoinrpc -proxypassword mypassword &

Now you can be sure that you are independently verifying the information received from BitGo directly against your own node’s version of the blockchain.

Recap

And there you have it! We’ve looked at what problems BitGoD solves, how to install the necessary tools to use it, and several commands in both its un-proxied and proxy form. Thank you for taking the time to read through this article; I hope you now have a much clearer idea of how you can use BitGoD to help with your own venture. As this is open-source software, you can always peruse the Javascript code yourself on Github, and make a pull request if you add your own features you’d like to share. Thanks again, and please comment below if you run into any trouble.