Running a Zcashd Regtest Node with Docker
Docker is a server "containerization" tool that lets users run their
own servers as isolated containers from custom or pre-build images.
Regtest is a mode where we can run a zcash node to build our own blockchain
and test scenarios with "real blocks" but controlling the events of the blockchain.
Installing tools we will need
Installing Docker
We will use docker to run our zcashd container locally in our computer.
check https://www.docker.com/ for installation instructions for your operating system.
Installing an RPC Client. Curl
Curl is a tool to internet transfers. We will use it to communicate with our zcashd container
Check it our here https://everything.curl.dev/get
Running Electric Coin Co's Zcashd docker image
You will find the generic instructions here
For this tutorial we will use a slightly different approach.
Setting up the customized configuration
Docker containers don't have a "hard drive" of their own. If we want to store information
between launches we will have to attach a volume to the container. That volume will point
to a folder in your computer
I'm using the current setup:
- root-folder|----> zcash-data-dir|----> zcash-params-dir
Note: for this tutorial we will use relative paths from the root folder. The terminal commands
should be launched from this folder for it to work.
$ mkdir root-folder$ cd root-folder$ mkdir zcash-data-dir$ mkdir zcash-params-dir
we will use zcash-data-dir to store the regtest blocks and the custom zcash.conf file.
The zcash-params-dir will hold trusted setup parameter files so they are not re-downloaded
again between launches.
The zcash.conf file
regtest=1txindex=1insightexplorer=1experimentalfeatures=1rpcuser=<your_user>rpcpassword=<your_password>rpcport=8232rpcallowip=172.17.0.0/16## NUPARAMSnuparams=5ba81b19:1 # Overwinternuparams=76b809bb:1 # Saplingnuparams=2bb40e60:1 # Blossomnuparams=f5b9230b:1 # Heartwoodnuparams=e9ff75a6:1 # Canopynuparams=c2d6d0b4:1 # NU5
Key takeaways
regtest=1 this sets Zcashd in regtest mode
rpcport=8232 the port we are going to use for communicate through RPC you can set this to whatever you want as long as it matches your docker run setup.
rpcuser and rpcpassword credentials to use on RPC communications.
rpcallowip=172.17.0.0/16 this is specifically for Docker's default network settings. If you have another setup then you'll need to adjust this.
launching the Zcashd container
To launch the container we will use the following command:
docker run -p 8323:8323 --platform linux/amd64 -d --name my_zcashd \ -v $(pwd)/zcash-data-dir:/srv/zcashd/.zcash \ -v $(pwd)/zcash-params-dir:/srv/zcashd/.zcash-params \ electriccoinco/zcashd
It's really important to run this from root-folder
Key Takeaways
-p 8323:8323 the port mapping to access the container from your terminal
--platform linux/amd64 this is needed if your computer does not build zcashd natively like mine. Specify the platform to avoid weird warnings.
--name my_zcashd the name of your container. you can set this to whatever you like
-v $(pwd)/zcash-data-dir:/srv/zcashd/.zcash the data dir of your container mapped to the directory.
-v $(pwd)/zcash-params-dir:/srv/zcashd/.zcash-params the params dir mapped to the directory on your computer.
electriccoinco/zcashd the zcashd docker image we will be using.
Interacting with the Zcash container
We will use curl to contact our zcashd container through port 8232.
We will tell curl to use jsonrpc. and send the method getblockchaininfo to get the
blockchain info.
first you have to check that your container has finished initializing with
$ docker logs my_zcashd
You should see this message:
INFO Init: main: init message: Done loading
If your container is still starting up it won't reply with other thing than an empty message.
Once it's started we can start interacting with our node.
get blockchain info
Lets send an RPC to the node and see the blockchain status.
$ curl --verbose --user 'your_user:your_password' --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getblockchaininfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:8232/
You should see something like this:
{ "result": { "chain": "regtest", "blocks": 0, "initial_block_download_complete": false, "headers": 0, "bestblockhash": "029f11d80ef9765602235e1bc9727e3eb6ba20839319f761fee920d63401e327", "difficulty": 1, "verificationprogress": 1, "chainwork": "0000000000000000000000000000000000000000000000000000000000000011", "pruned": false, "size_on_disk": 780, "estimatedheight": 5270450, "commitments": 0, "chainSupply": { "monitored": true, "chainValue": 0.00000000, "chainValueZat": 0 }, "valuePools": [ { "id": "transparent", "monitored": true, "chainValue": 0.00000000, "chainValueZat": 0 }, { "id": "sprout", "monitored": true, "chainValue": 0.00000000, "chainValueZat": 0 }, { "id": "sapling", "monitored": true, "chainValue": 0.00000000, "chainValueZat": 0 }, { "id": "orchard", "monitored": true, "chainValue": 0.00000000, "chainValueZat": 0 } ], "softforks": [ { "id": "bip34", "version": 2, "enforce": { "status": false, "found": 1, "required": 750, "window": 1000 }, "reject": { "status": false, "found": 1, "required": 950, "window": 1000 } }, { "id": "bip66", "version": 3, "enforce": { "status": false, "found": 1, "required": 750, "window": 1000 }, "reject": { "status": false, "found": 1, "required": 950, "window": 1000 } }, { "id": "bip65", "version": 4, "enforce": { "status": false, "found": 1, "required": 750, "window": 1000 }, "reject": { "status": false, "found": 1, "required": 950, "window": 1000 } } ], "upgrades": { "5ba81b19": { "name": "Overwinter", "activationheight": 1, "status": "pending", "info": "See https://z.cash/upgrade/overwinter/ for details." }, "76b809bb": { "name": "Sapling", "activationheight": 1, "status": "pending", "info": "See https://z.cash/upgrade/sapling/ for details." }, "2bb40e60": { "name": "Blossom", "activationheight": 1, "status": "pending", "info": "See https://z.cash/upgrade/blossom/ for details." }, "f5b9230b": { "name": "Heartwood", "activationheight": 1, "status": "pending", "info": "See https://z.cash/upgrade/heartwood/ for details." }, "e9ff75a6": { "name": "Canopy", "activationheight": 1, "status": "pending", "info": "See https://z.cash/upgrade/canopy/ for details." }, "c2d6d0b4": { "name": "NU5", "activationheight": 1, "status": "pending", "info": "See https://z.cash/upgrade/nu5/ for details." } }, "consensus": { "chaintip": "00000000", "nextblock": "c2d6d0b4" }, "fullyNotified": true }, "error": null, "id": "curltest"}
note:
If you see "server responded with empty message" you have to check your ports matching.
generate a new block
let's mine a block in our regtest blockchain
curl --verbose --user 'your_user:your_password' --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "generate", "params": [1] }' -H 'content-type: text/plain;' http://127.0.0.1:8232/
* Trying 127.0.0.1:8232...* Connected to 127.0.0.1 (127.0.0.1) port 8232 (#0)* Server auth using Basic with user 'your_user'> POST / HTTP/1.1> Host: 127.0.0.1:8232> Authorization: Basic cGFjdTpwYWN1> User-Agent: curl/7.88.1> Accept: */*> content-type: text/plain;> Content-Length: 73> < HTTP/1.1 200 OK< Content-Type: application/json< Date: Mon, 14 Aug 2023 01:11:39 GMT< Content-Length: 109< {"result":["0bab1c8c2329a2efd292af774f54e4f3504f52528301c78dc99129b76db2fb2a"],"error":null,"id":"curltest"}* Connection #0 to host 127.0.0.1 left intact
Now let's see the blockchain info again
{ "result": { "chain": "regtest", "blocks": 1, "initial_block_download_complete": true, "headers": 1, "bestblockhash": "0bab1c8c2329a2efd292af774f54e4f3504f52528301c78dc99129b76db2fb2a", "difficulty": 1, "verificationprogress": 1, "chainwork": "0000000000000000000000000000000000000000000000000000000000000022", "pruned": false, "size_on_disk": 1146, "estimatedheight": 1, "commitments": 0, "chainSupply": { "monitored": true, "chainValue": 6.25000000, "chainValueZat": 625000000 }, "valuePools": [ { "id": "transparent", "monitored": true, "chainValue": 6.25000000, "chainValueZat": 625000000 }, { "id": "sprout", "monitored": true, "chainValue": 0.00000000, "chainValueZat": 0 }, { "id": "sapling", "monitored": true, "chainValue": 0.00000000, "chainValueZat": 0 }, { "id": "orchard", "monitored": true, "chainValue": 0.00000000, "chainValueZat": 0 } ], "softforks": [ { "id": "bip34", "version": 2, "enforce": { "status": false, "found": 2, "required": 750, "window": 1000 }, "reject": { "status": false, "found": 2, "required": 950, "window": 1000 } }, { "id": "bip66", "version": 3, "enforce": { "status": false, "found": 2, "required": 750, "window": 1000 }, "reject": { "status": false, "found": 2, "required": 950, "window": 1000 } }, { "id": "bip65", "version": 4, "enforce": { "status": false, "found": 2, "required": 750, "window": 1000 }, "reject": { "status": false, "found": 2, "required": 950, "window": 1000 } } ], "upgrades": { "5ba81b19": { "name": "Overwinter", "activationheight": 1, "status": "active", "info": "See https://z.cash/upgrade/overwinter/ for details." }, "76b809bb": { "name": "Sapling", "activationheight": 1, "status": "active", "info": "See https://z.cash/upgrade/sapling/ for details." }, "2bb40e60": { "name": "Blossom", "activationheight": 1, "status": "active", "info": "See https://z.cash/upgrade/blossom/ for details." }, "f5b9230b": { "name": "Heartwood", "activationheight": 1, "status": "active", "info": "See https://z.cash/upgrade/heartwood/ for details." }, "e9ff75a6": { "name": "Canopy", "activationheight": 1, "status": "active", "info": "See https://z.cash/upgrade/canopy/ for details." }, "c2d6d0b4": { "name": "NU5", "activationheight": 1, "status": "active", "info": "See https://z.cash/upgrade/nu5/ for details." } }, "consensus": { "chaintip": "c2d6d0b4", "nextblock": "c2d6d0b4" }, "fullyNotified": true }, "error": null, "id": "curltest"}
you can see that the node has "mined" a block to the node's wallet.
"chainSupply": { "monitored": true, "chainValue": 6.25000000, "chainValueZat": 625000000 }, "valuePools": [ { "id": "transparent", "monitored": true, "chainValue": 6.25000000, "chainValueZat": 625000000 }
You can see all the available RPC of your node here in the zcash docs
