Receiving ZMQ Notifications#
Overview#
Receiving notifications from Dash Core is important for a variety of use-cases. Although polling RPCs can be useful, in some scenarios it may be more desirable to have publish-subscribe functionality. Dash Core’s built-in ZeroMQ (ZMQ) support provides the ability to subscribe to block, transaction, and governance related messages.
Further information regarding ZMQ support may be found in the ZMQ API Reference.
Enabling Dash Core ZMQ Notifications#
📘
This requires a Dash Core full node or masternode
In the dash.conf
configuration file, add the following ZMQ notifications and assign the address that Dash Core should listen on. The notifications selected here relate to InstantSend and ChainLocks.
# ZMQ
zmqpubhashchainlock=tcp://0.0.0.0:20009
zmqpubhashtx=tcp://0.0.0.0:20009
zmqpubhashtxlock=tcp://0.0.0.0:20009
zmqpubrawchainlock=tcp://0.0.0.0:20009
zmqpubrawtxlock=tcp://0.0.0.0:20009
Restart the Dash Core node once the configuration file has been updated.
JavaScript Example#
Requires an installation of NodeJS
1. Install ZeroMq#
The JavaScript zeromq package is available from npmjs.com and can be installed from the command line by running:
npm install zeromq@5
🚧 ZeroMQ Version
Version 5 of the zeromq package should be used for compatibility reasons.
2. Subscribe to ZeroMQ Messages#
Create a file with the following contents. Then run it by typing node <your-filename.js>
from the command line:
const zmq = require('zeromq');
const sock = zmq.socket('sub');
const zmqPort = 20009;
sock.connect('tcp://127.0.0.1:' + zmqPort);
// Subscribe to transaction notifications
sock.subscribe('hashtx'); // Note: this will subscribe to hashtxlock also
// Subscribe to InstantSend/ChainLock notifications
sock.subscribe('hashchainlock');
sock.subscribe('hashtxlock');
sock.subscribe('rawchainlock'); // Note: this will subscribe to rawchainlocksig also
sock.subscribe('rawtxlock'); // Note: this will subscribe to rawtxlocksig also
console.log('Subscriber connected to port %d', zmqPort);
sock.on('message', function(topic, message) {
console.log(
'Received',
topic.toString().toUpperCase(),
'containing:\n',
message.toString('hex'),
'\n'
);
});
import binascii
import asyncio
import zmq
import zmq.asyncio
import signal
port = 20009
class ZMQHandler():
def __init__(self):
self.loop = asyncio.get_event_loop()
self.zmqContext = zmq.asyncio.Context()
self.zmqSubSocket = self.zmqContext.socket(zmq.SUB)
self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % port)
# Subscribe to transaction notifications
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashtx")
# Subscribe to InstantSend/ChainLock notifications
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashtxlock")
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashchainlock")
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawchainlock")
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawtxlock")
print('Subscriber connected to port {}'.format(port))
@asyncio.coroutine
def handle(self) :
msg = yield from self.zmqSubSocket.recv_multipart()
topic = msg[0]
body = msg[1]
sequence = "Unknown"
print('Received {} containing:\n{}\n'.format(
topic.decode("utf-8"),
binascii.hexlify(body).decode("utf-8")))
# schedule ourselves to receive the next message
asyncio.ensure_future(self.handle())
def start(self):
self.loop.add_signal_handler(signal.SIGINT, self.stop)
self.loop.create_task(self.handle())
self.loop.run_forever()
def stop(self):
self.loop.stop()
self.zmqContext.destroy()
daemon = ZMQHandler()
daemon.start()
Example Response#
The following response demonstrates the notification provided by Dash Core when it receives a transaction and then receives the associated InstantSend lock. The four notifications represent:
The TXID of the transaction is received (
HASHTX
) - at this point the transaction is not lockedThe TXID of a locked transaction is received (
HASHTXLOCK
). Since this is the same value as theHASHTX
already received, we know that the transaction has now received an InstantSend lock.The raw transaction (
RAWTXLOCK
) (this could be decoded using thedecoderawtransaction
RPC for example)A combination of the raw transaction and the InstantSend lock signature (
RAWTXLOCKSIG
)
Received HASHTX containing:
b2e128661e3679c3d00cd081e32fdc9a12f44e486e083e6eab998bdfd6f64a9b
Received HASHTXLOCK containing:
b2e128661e3679c3d00cd081e32fdc9a12f44e486e083e6eab998bdfd6f64a9b
Received RAWTXLOCK containing:
02000000025a4d18da609107e9ea3dc6 ... 5a32ea917a30147d6c9788ac6ea90400
Received RAWTXLOCKSIG containing:
02000000025a4d18da609107e9ea3dc6 ... 9e889cee7ba48981ca002e6962a20236