Skip to content

Python Query Example

Eric Voskuil edited this page Jan 3, 2018 · 12 revisions

In the interest of simplicity this example does not handle ZeroMQ exceptions. The example also assumes that BX is installed.

import zmq
import struct
from subprocess import call
from binascii import hexlify, unhexlify

# The default unsecured mainnet community server address.
# https://github.com/libbitcoin/libbitcoin-server/wiki/Community-Servers
server_url = "tcp://mainnet.libbitcoin.net:9091"

# This query returns a confirmed transaction (without witness) by its hash.
# https://github.com/libbitcoin/libbitcoin-server/wiki/Query-Service#blockchainfetch_transaction
request_command = b'blockchain.fetch_transaction'

# The arbitrary message id is for client response correlation.
request_id = struct.pack('I', 42)

# All integer and hash values are encoded in little-endian byte order.
request_hash = unhexlify('60e030aba2f593caf913a7d96880ff227143bfc370d03dbaee37d582801ebd83')[::-1]

# Connect to the server with 5 second timeouts.
context = zmq.Context()
socket = context.socket(zmq.DEALER)
socket.setsockopt(zmq.RCVTIMEO, 5000)
socket.setsockopt(zmq.SNDTIMEO, 5000)
socket.connect(server_url)
    
# Make the request in parts.
socket.send(request_command, zmq.SNDMORE)
socket.send(request_id, zmq.SNDMORE)
socket.send(request_hash)

# Collect the response in parts.
response_command = socket.recv()
response_id = socket.recv()
response_body = socket.recv()

# These values allow the response to be correlated to the request.
# print(response_command.decode('ascii') + ":" + str(struct.unpack('<I', response_id)[0]))

# Decode message payload according to blockchain.fetch_transaction specification.
ec = struct.unpack('<I', response_body[0:4])[0]
tx = hexlify(response_body[4:]).decode('ascii')

if ec == 3:
    # https://github.com/libbitcoin/libbitcoin/blob/master/include/bitcoin/bitcoin/error.hpp
    print("Transaction not found on server.")
elif ec != 0:
    # In the case of an error the remainder of the response may be missing and should be ignored.
    print("Error getting transaction from server: " + str(ec))    
else:
    # Bitcoin objects (headers, blocks and transactions) are encoded in canonical serialization.
    assert call(["bx", "tx-decode", tx]) == 0
transaction
{
    hash 60e030aba2f593caf913a7d96880ff227143bfc370d03dbaee37d582801ebd83
    inputs
    {
        input
        {
            address_hash b4dc57e35f93de9ec155872c1ad0136134fb08b1
            previous_output
            {
                hash 4afe720d05336385a3589f218ef37e53e9804094f4de03e0d189b903446ed081
                index 8
            }
            script "[3045022100943e28772ef850587034b447a76c1eb918d63c82a4619a01a34cf32dee13807a02204cbe75c49f8ced0ebc373a6d8e7cb7ecab31369861d8997873b94bac13c379b301] [04dbfb10dd8a498b3431f4c7041bbba82aa33146d40b7def4315e9e6df7424d527e762042f9fcc5450cbfc5f849bd3dace5cc9d9b3be8fadc3de92f96e303cf599]"
            sequence 4294967295
        }
    }
    lock_time 0
    outputs
    {
        output
        {
            address_hash b4dc57e35f93de9ec155872c1ad0136134fb08b1
            script "dup hash160 [b4dc57e35f93de9ec155872c1ad0136134fb08b1] equalverify checksig"
            value 1249448
        }
        output
        {
            address_hash 61ec8bf07c6a3a04a08d1251d70178c1b3d273cc
            script "hash160 [61ec8bf07c6a3a04a08d1251d70178c1b3d273cc] equal"
            value 3401403
        }
    }
    version 1
}
Clone this wiki locally