mirror of
https://github.com/ChristopherA/Learning-Bitcoin-from-the-Command-Line.git
synced 2025-06-08 16:36:32 +00:00
Create 15_3_Receiving_Bitcoind_Notifications_with_C.md
This commit is contained in:
parent
5da470fa20
commit
e2c42668ae
196
15_3_Receiving_Bitcoind_Notifications_with_C.md
Normal file
196
15_3_Receiving_Bitcoind_Notifications_with_C.md
Normal file
@ -0,0 +1,196 @@
|
||||
# 15.3 Receiving Bitcoind Notifications with C
|
||||
|
||||
> **NOTE:** This is a draft in progress, so that I can get some feedback from early reviewers. It is not yet ready for learning.
|
||||
|
||||
[§15.3](15_3_Receiving_Bitcoind_Notifications_with_C.md) In this chapter we will show how to create a simple listener for bitcoin blockchain to receive notifications using ZMQ-based (http://zeromq.org/) notification interface, which is a highly scalable networking library written in C that acts like a concurrency framework. Bitcoin allows connection points where clients can subscribe to get notified about blockchain events like raw transactions or raw blocks.
|
||||
|
||||
## Install ZMQ
|
||||
|
||||
To create a blockchain listener in C you need to install ZMQ following this steps.
|
||||
|
||||
1. Install ZMQ
|
||||
2. Create C program.
|
||||
3. Compile C program.
|
||||
4. Configure bitcoind to allow ZMQ notifications
|
||||
5. Execute listener.
|
||||
|
||||
### 1. Install ZMQ
|
||||
|
||||
```
|
||||
sudo apt-get install libzmq3-dev
|
||||
```
|
||||
Output
|
||||
|
||||
```
|
||||
Reading package lists... Done
|
||||
Building dependency tree
|
||||
Reading state information... Done
|
||||
The following NEW packages will be installed:
|
||||
libzmq3-dev
|
||||
0 upgraded, 1 newly installed, 0 to remove and 18 not upgraded.
|
||||
Need to get 400 kB of archives.
|
||||
After this operation, 2.227 kB of additional disk space will be used.
|
||||
Get:1 http://es.archive.ubuntu.com/ubuntu bionic-updates/universe amd64 libzmq3-dev amd64 4.2.5-1ubuntu0.2 [400 kB]
|
||||
Fetched 400 kB in 0s (1.114 kB/s)
|
||||
Selecting previously unselected package libzmq3-dev:amd64.
|
||||
(Reading database ... 313982 files and directories currently installed.)
|
||||
Preparing to unpack .../libzmq3-dev_4.2.5-1ubuntu0.2_amd64.deb ...
|
||||
Unpacking libzmq3-dev:amd64 (4.2.5-1ubuntu0.2) ...
|
||||
Setting up libzmq3-dev:amd64 (4.2.5-1ubuntu0.2) ...
|
||||
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
|
||||
```
|
||||
Then
|
||||
|
||||
```
|
||||
sudo apt-get install libczmq-dev
|
||||
```
|
||||
Output:
|
||||
|
||||
```
|
||||
Reading package lists... Done
|
||||
Building dependency tree
|
||||
Reading state information... Done
|
||||
The following additional packages will be installed:
|
||||
libczmq4
|
||||
The following NEW packages will be installed:
|
||||
libczmq-dev libczmq4
|
||||
0 upgraded, 2 newly installed, 0 to remove and 18 not upgraded.
|
||||
Need to get 496 kB of archives.
|
||||
After this operation, 2.148 kB of additional disk space will be used.
|
||||
Do you want to continue? [Y/n] y
|
||||
Get:1 http://es.archive.ubuntu.com/ubuntu bionic/universe amd64 libczmq4 amd64 4.1.0-2 [145 kB]
|
||||
Get:2 http://es.archive.ubuntu.com/ubuntu bionic/universe amd64 libczmq-dev amd64 4.1.0-2 [351 kB]
|
||||
Fetched 496 kB in 0s (1.287 kB/s)
|
||||
Selecting previously unselected package libczmq4:amd64.
|
||||
(Reading database ... 314055 files and directories currently installed.)
|
||||
Preparing to unpack .../libczmq4_4.1.0-2_amd64.deb ...
|
||||
Unpacking libczmq4:amd64 (4.1.0-2) ...
|
||||
Selecting previously unselected package libczmq-dev:amd64.
|
||||
Preparing to unpack .../libczmq-dev_4.1.0-2_amd64.deb ...
|
||||
Unpacking libczmq-dev:amd64 (4.1.0-2) ...
|
||||
Setting up libczmq4:amd64 (4.1.0-2) ...
|
||||
Setting up libczmq-dev:amd64 (4.1.0-2) ...
|
||||
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
|
||||
Processing triggers for libc-bin (2.27-3ubuntu1) ...
|
||||
```
|
||||
|
||||
### 2. Create C Program
|
||||
|
||||
Now we've installed ZMQ and we can compile our C program using it's notifications.
|
||||
The program use czmq.h library and receives two parameters as follows, first param is the point exposed by bitcoind and second the topic about we'll listen.
|
||||
|
||||
``` c
|
||||
#include <czmq.h>
|
||||
int main(int argc, char ** argv) {
|
||||
|
||||
char *zmqserver;
|
||||
char *topic;
|
||||
|
||||
if (argc < 3) {
|
||||
printf("\nUSAGE:\nchainlistener <tcp://localhost:port> <topic>\n\n");
|
||||
return 0;
|
||||
} else {
|
||||
zmqserver = argv[1];
|
||||
topic = argv[2];
|
||||
}
|
||||
|
||||
zsock_t *socket = zsock_new_sub(zmqserver, topic);
|
||||
assert(socket);
|
||||
|
||||
while(1) {
|
||||
zmsg_t *msg;
|
||||
int rc = zsock_recv(socket, "m", &msg);
|
||||
assert(rc == 0);
|
||||
|
||||
char *header = zmsg_popstr(msg);
|
||||
zframe_t *zdata = zmsg_pop(msg);
|
||||
unsigned int *no = (unsigned int*)zmsg_popstr(msg);
|
||||
|
||||
char *data = zframe_strhex(zdata);
|
||||
int len = zframe_size(zdata);
|
||||
printf("Size: %d\n", len);
|
||||
printf("Data: %s", data);
|
||||
printf("\nNo: %d\n", *no);
|
||||
|
||||
free(header);
|
||||
free(data);
|
||||
free(no);
|
||||
free(zdata);
|
||||
zmsg_destroy(&msg);
|
||||
sleep(1);
|
||||
}
|
||||
zsock_destroy(&socket);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Compile C program
|
||||
|
||||
To compile this C program you have to do it with clang or gcc compiler and test zmq and czmq libraries.
|
||||
|
||||
```
|
||||
gcc -o chainlistener chainlistener.c -I/usr/local/include -L/usr/local/lib -lzmq -lczmq
|
||||
```
|
||||
|
||||
### 4. Configure ZMQ on bitcoind
|
||||
|
||||
Add this lines to bitcoin.conf file and restart daemon.
|
||||
|
||||
```
|
||||
zmqpubrawblock=tcp://127.0.0.1:28332
|
||||
zmqpubrawtx=tcp://127.0.0.1:28333
|
||||
```
|
||||
Then test it's working using this command
|
||||
|
||||
```
|
||||
$ bitcoin-cli --testnet getzmqnotifications
|
||||
```
|
||||
Output:
|
||||
```
|
||||
[
|
||||
{
|
||||
"type": "pubrawblock",
|
||||
"address": "tcp://127.0.0.1:28332",
|
||||
"hwm": 1000
|
||||
},
|
||||
{
|
||||
"type": "pubrawtx",
|
||||
"address": "tcp://127.0.0.1:28333",
|
||||
"hwm": 1000
|
||||
}
|
||||
]
|
||||
```
|
||||
### 5. Execute listener:
|
||||
|
||||
```
|
||||
$ ./chainlistener tcp://127.0.0.1:28333 rawtx
|
||||
Size: 250
|
||||
Data: 02000000000101F5BD2032E5A9E6650D4E411AD272E391F26AFC3C9102B7C0C7444F8F74AE86010000000017160014AE9D51ADEEE8F46ED2017F41CD631D210F2ED9C5FEFFFFFF0203A732000000000017A9147231060F1CDF34B522E9DB650F44EDC6C0714E4C8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100AE316D5F21657E3525271DE39EB285D8A0E89A20AB6413824E88CE47DCD0EFE702202F61E10C2A8F4A7125D5EB63AEF883D8E3584A0ECED0D349283AABB6CA5E066D0121035A77FE575A9005E3D3FF0682E189E753E82FA8BFF0A20F8C45F06DC6EBE3421079111B00
|
||||
No: 67
|
||||
Size: 249
|
||||
Data: 0200000000010165C986992F7DAD22BBCE3FCF0BF546EDBC3C599618B04CFA22D9E64EF0CE4C030000000017160014B58E0A5CD68B249F1C407E9AAE9CD0332AAA3067FEFFFFFF02637932000000000017A914CCC47261489036CB6B9AA610857793FF5752E5378710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC0247304402206CCC3F3B4BE01D4E532A01C2DC6BC3B53E4FFB6B494C8B87DD603EFC648A159902201653841E8B16A814DC375129189BB7CF01CFF7D269E91178645B6A97F5C7F4F10121030E20F3D2F172281B8DC747F007DF24B352248AC09E48CA64016942A8F01D317079111B00
|
||||
No: 68
|
||||
Size: 250
|
||||
Data: 02000000000101E889CFC1FFE127BA49F6C1011388606A194109AE1EDAAB9BEE215E123C14A7920000000017160014577B0B3C2BF91B33B5BD70AE9E8BD8144F4B87E7FEFFFFFF02C34B32000000000017A914A9F1440402B46235822639C4FD2F78A31E8D269E8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100B46318F53E1DCE63E7109DB4FA54AF40AADFC2FEB0E08263756BC3B7A6A744CB02200851982AF87DBABDC3DFC3362016ECE96AECFF50E24D9DCF264AE8966A5646FE0121039C90FCB46AEA1530E5667F8FF15CB36169D2AD81247472F236E3A3022F39917079111B00
|
||||
No: 69
|
||||
Size: 250
|
||||
Data: 0200000000010137527957C9AD6CFF0C9A74597E6EFCD7E1EBD53E942AB2FA34A831046CA11488000000001716001429BFF05B3CD79E9CCEFDB5AE82139F72EB3E9DB0FEFFFFFF0210270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC231E32000000000017A9146C8D5FE29BFDDABCED0D6F4D8E82DCBFD9D34A8B8702483045022100F259846BAE29EB2C7A4AD711A3BC6109DE69AE91E35B14CA2742157894DD9760022021464E09C00ABA486AEAA0C49FEE12D2850DC03F57F04A1A9E2CC4D0F4F1459C012102899F24A9D60132F4DD1A5BA6DCD1E4E4B6C728927BA482C2C4E511679F60CA5779111B00
|
||||
No: 70
|
||||
.......
|
||||
```
|
||||
|
||||
|
||||
### For More Information
|
||||
|
||||
In this repository you can browse find more details about ZMQ notifications and others kind of messages. (https://github.com/Actinium-project/ChainTools/blob/master/docs/chainlistener.md)
|
||||
|
||||
### Summary Receiving Bitcoind Notifications with C.md
|
||||
|
||||
By using ZMQ framework, you can easily receive notifications by subscribing to a connection point exposed by bitcoind changing configuration file.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user