diff --git a/transactions_101/index.md b/transactions_101/index.md new file mode 100644 index 0000000..dd9b138 --- /dev/null +++ b/transactions_101/index.md @@ -0,0 +1,25 @@ +# Bitcoin transactions 101 + +## Introduction + +A transaction is a transfer of Bitcoin value that is broadcast to the network and collected into blocks. A transaction typically references previous transaction outputs as new transaction inputs and dedicates all input Bitcoin values to new outputs. Transactions are not encrypted, so it is possible to browse and view every transaction ever collected into a block. Once transactions are buried under enough confirmations they can be considered irreversible. + +Standard transaction outputs nominate addresses, and the redemption of any future inputs requires a relevant signature. + +All transactions are visible in the block chain, and can be viewed with a hex editor. A block chain browser is a site where every transaction included within the block chain can be viewed in human-readable terms. This is useful for seeing the technical details of transactions in action and for verifying payments. + +## Background + +Provide some background as to what problem will be addressed or what motivated writing this tutorial. + +## Let's get started + +Here is a free flow of task oriented information which runs through the steps required. + +## Conclusion + +In conclusion, we review the goals and purpose of the tutorial. + +## Reference + +Provide any references related to this tutorial. diff --git a/zmq/index.md b/zmq/index.md new file mode 100644 index 0000000..c0c1f77 --- /dev/null +++ b/zmq/index.md @@ -0,0 +1,481 @@ +# Accessing Bitcoin's ZeroMQ interface + +## Introduction + +In this tutorial, we will be taking a closer look at bitcoin's ZeroMQ messaging interface. This interface is useful for developing applications which might require data related to `block` and `transaction` events from a Bitcoin core node. Some applications which include block explorers, wallets and reporting dash boards to name just a few. + +## Background + + +[ZeroMQ](http://zeromq.org/) is a high-performance asynchronous messaging library, aimed at use in distributed or concurrent applications. It provides a message queue, but unlike message-oriented middleware, a ZeroMQ system can run without a dedicated message broker. + +The Bitcoin Core daemon can be configured to act as a trusted "border router", implementing the [bitcoin wire protocol](/bitcoin wire protocol/) and relay, making consensus decisions, maintaining the local blockchain database, broadcasting locally generated transactions into the network, and providing a queryable RPC interface to interact on a polled basis for requesting blockchain related data. However, there exists only a limited service to notify external software of events like the arrival of new blocks or transactions. + +The ZeroMQ facility implements a notification interface through a set of specific notifiers. Currently there are notifiers that publish blocks and transactions. This read-only facility requires only the connection of a corresponding ZeroMQ subscriber port in receiving software; it is not authenticated nor is there any two-way protocol involvement. Therefore, subscribers should validate the received data since it may be out of date, incomplete or even invalid. + +ZeroMQ sockets are self-connecting and self-healing; that is, connections made between two endpoints will be automatically restored after an outage, and either end may be freely started or stopped in any order. + +Because ZeroMQ is message oriented, subscribers receive transactions and blocks all-at-once and do not need to implement any sort of buffering or reassembly. + + +## What you'll need + +You will need access to a bitcoin node. We suggest executed against a node configured in `regtest` mode so that we can have the freedom of playing with various scenarios without having to loose real money. You can however execute these against either the `testnet` or `mainnet` configurations. + +> **Note:** +> If you don't currently have access to a bitcoin development environment set up, dont' worry, we have your back! We've setup a web based mechanism which provisions your very own private session that includes these tools and comes preconfigured with a bitcoin node in `regtest` mode. https://bitcoindev.network/bitcoin-cli-sandbox/ +> Alternatively, we have also provided a simple docker container configured in `regtest` mode that you can install for testing purposes. +> ```console +> gr0kchain:~ $ docker volume create --name=bitcoind-data +> gr0kchain:~ $ docker run -v bitcoind-data:/bitcoin --name=bitcoind-node -d \ +> -p 18444:18444 \ +> -p 127.0.0.1:18332:18332 \ +> bitcoindevelopernetwork/bitcoind-regtest +> ``` + +By default, the ZeroMQ feature is automatically compiled in if the necessary prerequisites are found. To disable, use --disable-zmq during the *configure* step of building bitcoind: + +```console +gr0kchain bitcoindev $ ./configure --disable-zmq .... +``` + +## Let's get started + +Before we dive into things, let's have a brief taste of what we can expect to learn from this tutorial. + + + +In the use case demonstrated above, we have executed a script which listens for one of four configurable events from our Bitcoin Core node. The script prints out the transaction identifiers as they are received by our node. + +Bitcoin's ZMQ uses a publish/subscribe ([pubsub](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern)) design pattern, where the publisher in our case is our bitcoin node which published messages based on events. The subscriber on the other hand, includes any application looking to utilise it by subscribing to these events. There are currently 4 different publish (PUB) notification topics we can expose via `bitcoind` which notify us when ever a new block or transaction is validated by the node. + +* zmqpubhashtx : Publishes transaction hashes +* zmqpubhashblock : Publishes block hashes +* zmqpubrawblock : Publishes raw block information +* zmqpubrawtx : Publishes raw transaction information + + +### Enabling zmq + +To enable these features, you will need to update your `bitcoin.conf` file. We will start by reviewing the `--help` flag from our `bitcoind` command. + +```console +bitcoind --help | grep zmq -A3 + -zmqpubhashblock=
+ Enable publish hash block in + + -zmqpubhashtx= + Enable publish hash transaction in + + -zmqpubrawblock= + Enable publish raw block in + + -zmqpubrawtx= + Enable publish raw transaction in + +Debugging/Testing options: +-- + mempool, http, bench, zmq, db, rpc, estimatefee, addrman, + selectcoins, reindex, cmpctblock, rand, prune, proxy, mempoolrej, + libevent, coindb, qt, leveldb. + +``` + +Here we can see the four message types together with information on how to enable debugging for various components including `zmq`. + +> **Note:** +> When developing, it is useful to always keep `debug` configured to `1` in your `bitcoin.conf` file. + +Each of our PUB topics can be configured using an tcp socket on the configured address. This address is where Bitcoin Core will be publishing messages to the various topics a subscribed might be interested in. + +We can call the `getzmqnotifications` remote procedure call (RPC) method to see if any of the `zmq` services are currently running. + +```console +gr0kchain@bitcoindev $ bitcoin-cli getzmqnotifications +[ +] +``` + +If you receive an empty array as shown above, you will need to update your `bitcoin.conf` by adding the following: + +```console +zmqpubrawblock=tcp://127.0.0.1:29000 +zmqpubrawtx=tcp://127.0.0.1:29000 +zmqpubhashtx=tcp://127.0.0.1:29000 +zmqpubhashblock=tcp://127.0.0.1:29000 +``` + +Next up, we will need to restart `bitcoind` for the changes to take effect. + +```console +gr0kchain@bitcoindev $ bitcoin-cli stop +Bitcoin server stopping +gr0kchain@bitcoindev $ bitcoind +Bitcoin server starting +gr0kchain@bitcoindev $ bitcoin-cli getzmqnotifications +[ + { + "type": "pubhashblock", + "address": "tcp://127.0.0.1:29000" + }, + { + "type": "pubhashtx", + "address": "tcp://127.0.0.1:29000" + }, + { + "type": "pubrawblock", + "address": "tcp://127.0.0.1:29000" + }, + { + "type": "pubrawtx", + "address": "tcp://127.0.0.1:29000" + } +] +``` + +We are now ready to start playing around with these services. + +### Writing our client + +There are many ways in which you can write clients that can connect to `zmq` servers. For simplicity, we will be using javascript, but feel free to search for libraries related to your language of choice. + +Let's start by creating a directory for our project. + +```console +gr0kchain@bitcoindev $ mkdir ./bitcoin-zmq/ && cd ./bitcoin-zmq/ +``` + +We will be using the [zmq](https://www.npmjs.com/package/zmq) node package which you can install as follows. + +```console +gr0kchain@bitcoindev $ npm install zmq +``` + +Create a file called `index.js` and include the `zmq` package as follows. + +```console +var zmq = require('zmq') + , sock = zmq.socket('sub') +``` + +Next, add a line for connecting to the `zmq` address we had previously configured in our `bitcoind.conf` file. + +```console +sock.connect('tcp://127.0.0.1:29000'); +``` + +Now add an event handled for the event `message`. This event will be triggered every time we receive any event from the `zmq` service. + +```console +sock.on('message', function(topic, message) { + console.log(topic, message) +}) +``` + +Connecting to the interface does not yield much unless we subscribe to one of the 4 topics we had mentioned earlier. You can do this by calling the `subscribe` method to our `sock` instance. + +```console +sock.subscribe('hashtx') +``` + +Here we are notifying the Bitcoin Core ZMQ server that we are interested in getting updates on transactions identifiers whenever it learns of new ones. Now let's test our new script. + +```console +gr0kchain@bitcoindev $ node ./index.js + +``` + +Running this should result in what appears to be a terminal in a waiting state. Our script is waiting to be notified of incoming transactions. Since we're using a node configured in `regtest` mode, we need to manually generate some blocks in a separate terminal session. + +```console +gr0kchain@bitcoindev $ bitcoin-cli generate 1 +[ + "7a5865e307d49d4be5ff5a902cadca33a88b34b5acc2603c1b7eb2fae904d09e" +] +``` + +After generating a block, you should have output being printed from the terminal where our script is running. + +```console +gr0kchain@bitcoindev $ node ./test.js +