Connecting to the Bitcoin Network

With a wallet and a place to store the blockchain data, we can now connect to the actual Bitcoin network. A Bitcoin node connects to the Bitcoin network by connecting to several semirandom peer nodes. Here is the code that fires up a connection to several peers:

First we create a PeerGroup object O that manages these connections. Next, we choose some random peers to connect to. We do this by adding a peer discovery algorithm to the PeerGroup 0. The DnsDiscovery class basically uses the URLs of some well-established and trusted nodes as a starting point to discover peers that are willing to accept new connections. Then we add our wallet to the PeerGroup object ®.

Now we're finally ready to inject the app into the Bitcoin network! We do this by calling PeerGroup.start 0, which will find and connect to some nodes and perform the appropriate handshake operations via network sockets. And, like any Bitcoin node, we request that the peers send us the blockchain so we can become a fully functional node 0. As mentioned previously, this step will take a while to run, but only the first time we run the program.

Listening for New Money

One last feature we need to add to the hello-money program is a hook to detect when money has arrived:

The bitcoinJ wallet object has an addEventListener member function, and we can create an anonymous class of type EventListener, which intercepts and listens to different events that might happen to a wallet O. In our app, we're interested in the onCoinsReceived function 0, which will be called every time money is received by this wallet. Let's explore in more detail exactly what this means.

Because the program lives directly in the Bitcoin network, it can listen to the bitcoin firehose, a stream of data that contains every Bitcoin transaction happening anywhere in the world in close to real time. Each transaction is examined to see whether it involves receiving money into any Bitcoin address contained in our wallet. In our app, the wallet contains only one address. As soon as this transaction arrives (even before it has been incorporated into a mined block), our function onCoinsReceved will be called.

In the hello-money program, we won't worry about capturing confirmation events on the money received; we'll only listen for the transmission of new, unconfirmed transactions. However, if we were interested in confirmations, we could capture them via the onTransactionConfidenceChanged function. Because we're running a full Bitcoin client, we can do what we want, whereas in Appendix A we were forced to look only at confirmed transactions due to the limitations of the JSON-RPC interface.

The onCoinsReceived function has four parameters passed into it 0: the wallet object, a transaction object, the previous balance in the wallet, and the new balance. The bitcoinJ library uses the Java Biglnteger class to encode Bitcoin balances, because this numerical type can handle very large integers precisely. If you've written financial software before, you'll know why the Biglnteger class is used (or you may recall how the bank heist was done in the movie Office Space). The fact is that it's very easy to botch a financial transaction due to rounding errors, and using big, precise integers prevents this problem. Hence, bitcoinJ performs all Bitcoin math using satoshis, the smallest unit of bitcoins, which are worth one one-hundred-millionth of a bitcoin.

Because we added the event listener after we downloaded the initial blockchain, the onCoinsReceived function will be called only when new transactions appear as the program is running. If we had declared it before downloading the initial blockchain, the design of bitcoinJ is such that onCoinsReceived would also have been called on relevant historical transactions.

Finally, we put the program into an infinite loop, so the program continues running as we wait for money to arrive:

< Prev   CONTENTS   Next >