Under the Hood¶
The intent of this section is to document what goes on under the hood of
transactions
.
We’ll use three main “pillars” to organize and present the information:
One additional section will be used to present some key aspects of the
libraries that transactions
rely on, especially the two bitcoin libraries:
pycoin
and pybitcointools
.
Bitcoin Network¶
There are multiple ways that one may connect to the bitcoin network. For the sake of simplicity, let’s say that they are two main ways:
- via a daemon
- that is communicating directly with a node located at a specific host and port
- via a blockchain explorer
- that is communicating with the bitcoin network via the public API of the blockchain explorer service such as blockr.io
Different Modes of the Bitcoin Network¶
The bitcoin daemon and other bitcoin core programs can be run in three different “network modes”:
- mainnet
- The original and main network for Bitcoin transactions, where satoshis have real economic value. [1]
- testnet
- A global testing environment in which developers can obtain and spend satoshis that have no real-world value on a network that is very similar to the Bitcoin. [2]
- regtest
- A local testing environment in which developers can almost instantly generate blocks on demand for testing events, and can create private satoshis with no real-world value. [3]
Running a bitcoin node in regtest mode¶
bitcoin json rpc¶
ref: https://en.bitcoin.it/wiki/API_reference_%28JSON-RPC%29
- via curl
- via python with python-bitcoinrpc
- via python with requests
- via transactions
curl¶
$ curl --user user --data-binary \
'{"jsonrpc": "1.0", "id":"dummy", "method": "getinfo", "params": [] }' \
-H 'content-type: text/plain;' http://127.0.0.1:18332/
docker¶
host - container¶
Runnign bitcoind in container and making rpc calls to it from the host machine, (sender_ip)
given the following bitcoin.conf
:
dnsseed=0
rpcuser=a
rpcallowip=<sender_ip>
docker run --rm --name btc -v ~/.bitcoin-docker:/root/.bitcoin -p <sender_ip>:58332:18332 btc5 bitcoind -regtest -printtoconsole
curl --user a:b --data-binary '{"jsonrpc": "1.0", "id":"", "method": "getinfo", "params": [] }' -H 'content-type: text/plain;' http://<sender_ip>:58332
container-container¶
Making rpc calls from a container to the bitcoind running in another container.
Connecting to the Bitcoin Network with transactions
¶
When using transactions
, one can interact with the bitcoin network
via a daemon or via a blockchain explorer. When connecting via a daemon it is
possible to connect to the three networks: mainnet, testnet, or regtest,
whereas when connecting via a blockchain explorer one may connect to the
mainnet or testnet.
The supported blockchain explorer is blockr.io
Todo
show code examples
Bitcoin Addresses¶
Todo
Show how a bitcoin address is created.
Bitcoin Transactions¶
Todo
Show the different steps required to publish a transaction in the bitcoin network.
Lifecycle of a transaction: creation, signing, publishing, confirmation
- Using
create
to fetch a transaction - Using
sign
to fetch a transaction - Using
push
to publish a transaction - Using
get
to fetch a transaction
Elements of the payload of a transaction
Blocks¶
Transactions are assembled into blocks.
credits:
Example:
$ curl https://blockexplorer.com/api/block/0000000000000000e067a478024addfecdc93628978aa52d91fabd4292982a50 | python -m json.tool
Or in python:
import json
import requests
BLOCKEXPLORER_API_URL = 'https://blockexplorer.com/api'
BLOCKHASH = '0000000000000000e067a478024addfecdc93628978aa52d91fabd4292982a50q'
url = '{}/block/{}'.format(BLOCKEXPLORER_API_URL, blockhash)
response = requests.get(url)
block = json.loads(response.content)
block
{u'bits': u'19015f53',
u'chainwork': u'000000000000000000000000000000000000000000001a6eca45b2459ce9eed8',
u'confirmations': 120187,
u'difficulty': 3129573174.5222874,
u'hash': u'0000000000000000e067a478024addfecdc93628978aa52d91fabd4292982a50',
u'height': 286819,
u'isMainChain': True,
u'merkleroot': u'871714dcbae6c8193a2bb9b2a69fe1c0440399f38d94b3a0f1b447275a29978a',
u'nextblockhash': u'0000000000000000b0f08ec6a3d1e84994498ecf993a9981f57982cfdb66c443',
u'nonce': 856192328,
u'poolInfo': {u'poolName': u'ghash.io', u'url': u'https://ghash.io/'},
u'previousblockhash': u'000000000000000117c80378b8da0e33559b5997f2ad55e2f7d18ec1975b9717',
u'reward': 25,
u'size': 152509,
u'time': 1392872245,
u'tx': [u'00baf6626abc2df808da36a518c69f09b0d2ed0a79421ccfde4f559d2e42128b',
u'91c5e9f288437262f218c60f986e8bc10fb35ab3b9f6de477ff0eb554da89dea',
u'46685c94b82b84fa05b6a0f36de6ff46475520113d5cb8c6fb060e043a0dbc5c',
u'ba7ed2544c78ad793ef5bb0ebe0b1c62e8eb9404691165ffcb08662d1733d7a8',
u'b8dc1b7b7ed847c3595e7b02dbd7372aa221756b718c5f2943c75654faf48589',
...]
u'version': 2}
'merkleroot': u'871714dcbae6c8193a2bb9b2a69fe1c0440399f38d94b3a0f1b447275a29978a',
The merkle root corresponds to the cummulative hashing of the transactions hashes.
That is, each transaction is hashed. Each hash is a leaf of a binary tree.
A binary tree is built by pairing leaves, concatenating the pair, and computing the hash of the concatenated pair. The same process is repeated for the parent, recursively all the way to the root, resulting in the merkle root.
At each level of the tree, if the number of hashes is odd, then the last hash is included twice.
Progammatically, this means:
def merkleroot(hashes);
if len(hashes) == 1:
return hashes[0]
if len(hashes) % 2 == 1;
hashes.append(hashes[-1])
parent_hashes = []
for i in range(0, len(hashes), 2);
h = sec_hash_algo(hashes[i] + hashes[i+1])
parent_hashes.append(h)
return merkle_root(parent_hashes)
Libraries used by transactions
¶
Todo
Present libraries used; requests
, pycoin
, pybitcointools
Dive into the details of how pycoin and pybitcointools are used and work under the hood.