Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Set up a dockerized test network for bitcoind with a defined supply of bitcoin
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This notebook demonstrates how the docker Python package can be used to automatically set up a test environment with a defined state. It assumes that\n",
"* you have the docker package installed (if not, run pip install docker)\n",
"* you have a container image called bitcoin-alpine that contains a bitcoind in regtest mode and has exposed port 18332"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"#\n",
"# First we import the package and start two containers - alice and bob\n",
"#\n",
"import docker\n",
"client = docker.client.from_env()\n",
"alice = client.containers.run(\"bitcoin-alpine:latest\", auto_remove=True, detach=True, ports={\"18332\" : \"18332\"})\n",
"bob = client.containers.run(\"bitcoin-alpine:latest\", auto_remove=True, detach=True)\n",
"#\n",
"# Give them some time to come up\n",
"# \n",
"import time\n",
"time.sleep(3)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"#\n",
"# A utility function to get the IP address of a container on the bridge network\n",
"# \n",
"def get_ip(container, network_name=\"bridge\"):\n",
" nw = client.networks.get(network_name)\n",
" ip = [_.attrs['NetworkSettings']['Networks']['bridge']['IPAddress'] for _ in nw.containers if _.id == container.id][0]\n",
" return ip"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'172.17.0.3'"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"bob_ip = get_ip(bob)\n",
"bob_ip"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"ExecResult(exit_code=0, output=b'')"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"#\n",
"# Ask alice to connect to bob\n",
"# \n",
"alice.exec_run(\"bitcoin-cli --rpcuser=user --rpcpassword=password -regtest addnode \" + bob_ip + \" add\")"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"#\n",
"# Now generate a few blocks\n",
"#\n",
"alice.exec_run(\"bitcoin-cli --rpcuser=user --rpcpassword=password -regtest generate 101\");"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"#\n",
"# Set up an account Alice with address mkvAYmgqrEFEsJ9zGBi9Z87gP5rGNAu2mx\n",
"# The private key for this address is (as WIF)\n",
"# cQowgjRpUocje98dhJrondLbHNmgJgAFKdUJjCTtd3VeMfWeaHh7\n",
"#\n",
"alice.exec_run(\"bitcoin-cli --rpcuser=user --rpcpassword=password -regtest importprivkey cQowgjRpUocje98dhJrondLbHNmgJgAFKdUJjCTtd3VeMfWeaHh7\")\n",
"#\n",
"# and verify\n",
"# \n",
"check=alice.exec_run(\"bitcoin-cli --rpcuser=user --rpcpassword=password -regtest dumpprivkey mkvAYmgqrEFEsJ9zGBi9Z87gP5rGNAu2mx\")\n",
"assert(check.output == b'cQowgjRpUocje98dhJrondLbHNmgJgAFKdUJjCTtd3VeMfWeaHh7\\n')"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"#\n",
"# Finally transfer 30 bitcoin to this address\n",
"#\n",
"alice.exec_run(\"bitcoin-cli --rpcuser=user --rpcpassword=password -regtest sendtoaddress mkvAYmgqrEFEsJ9zGBi9Z87gP5rGNAu2mx 30.0\")\n",
"#\n",
"# and mine 6 additional blocks\n",
"# \n",
"alice.exec_run(\"bitcoin-cli --rpcuser=user --rpcpassword=password -regtest generate 6\");\n"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"ExecResult(exit_code=0, output=b'[\\n {\\n \"address\": \"mkvAYmgqrEFEsJ9zGBi9Z87gP5rGNAu2mx\",\\n \"account\": \"\",\\n \"amount\": 30.00000000,\\n \"confirmations\": 6,\\n \"label\": \"\",\\n \"txids\": [\\n \"67981d12268ec0f6503ba8776a0d1724511ded5088c7a7bd2dc917dcebdc5ab4\"\\n ]\\n }\\n]\\n')"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"#\n",
"# Let us check that this worked\n",
"# \n",
"time.sleep(1)\n",
"alice.exec_run(\"bitcoin-cli --rpcuser=user --rpcpassword=password -regtest listreceivedbyaddress\")"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"#\n",
"# Clean up again\n",
"#\n",
"alice.stop()\n",
"bob.stop()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment