Skip to content

Hermez Node

This tutorial describes how to launch a Hermez node. It starts by explaining how to launch a Boot Coordinator in localhost. Next, it describes how to initialize a Proof Server and how to connect it to the Boot Coordinator. The next section describes how to spin up a second Hermez node in synchronizer mode to track the rollup status independently from the Boot Coordinator. This second node will be launched in Rinkeby testnet. The last part of the tutorial includes an explanation on how to add a second Coordinator node to Hermez testnet Rinkeby that bids for the right to forge batches.

  1. Preparing the Environment
  2. Launching the Boot Coordinator
  3. Launching a Proof Server
  4. Launching a Price Updater
  5. Launching a Synchronizer Node
  6. Launching a Second Coordinator

Preparing the Environment

Hermez node requires a PostgreSQL database and connectivity to an Ethereum node. In this part, we describe how you can set this environment up using docker containers.


cd /tmp && go get -u && cd -
  • docker and docker-compose without sudo permission (optional if you want to use the provided PostgreSQL and Geth containers)
  • docker
  • docker-compose
  • aws cli 2 (optional if you want to use the provided Geth container)


  1. Clone hermez-node repository
git clone
  1. Build hermez-node executable
cd hermez-node

The executable can be found in dist/heznode

  1. Deploy PostgreSQL database and Geth node containers. For this step we provide a docker-compose file example. Copy file to docker-compose.sandbox.yaml.

Login to AWS public ECR to be able to download the Geth docker image:

export AWS_REGION=eu-west-3
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin

Ensure that port 5432 is not being used. Otherwise, PostgreSQL docker will fail.

To start start database and Geth node containers:

DEV_PERIOD=3 docker-compose -f docker-compose.sandbox.yaml up -d

This command will start a Geth node mining a block every 3 seconds. Database is available at port 5432. Geth node is available at port 8545.

To stop containers:

docker-compose -f docker-compose.sandbox.yaml down

The Geth container comes with pre-deployed Hermez contracts and with 200 funded accounts. The relevant information about the contract deployment can be found below

 "hermezAuctionProtocolAddress": "0x317113D2593e3efF1FfAE0ba2fF7A61861Df7ae5"
 "hermezAddress": "0x10465b16615ae36F350268eb951d7B0187141D3B"
 "withdrawalDelayeAddress": "0x8EEaea23686c319133a7cC110b840d1591d9AeE0"
 "HEZTokenAddress": "0x5E0816F0f8bC560cB2B9e9C87187BeCac8c2021F"
 "hermezGovernanceIndex": 1
 "hermezGovernanceAddress": "0x8401Eb5ff34cc943f096A32EF3d5113FEbE8D4Eb"
 "emergencyCouncilIndex": 2
 "emergencyCouncilAddress": "0x306469457266CBBe7c0505e8Aad358622235e768"
 "donationIndex": 3
 "donationAddress": "0xd873F6DC68e3057e4B7da74c6b304d0eF0B484C7"
 "bootCoordinatorIndex": 4
 "mnemonic": "explain tackle mirror kit van hammer degree position ginger unfair soup bonus"
 "chainId" : 1337
  1. Customize Hermez Node configuration file. For this example, we can use this configuration file. Just copy this file to cmd/heznode/cfg.sandbox.boot.coordinator.toml

For more information on the parameters in the configuration file, read the configuration parameters description.

  1. Ensure correct permissions are granted to /var/hermez folder
sudo mkdir -p /var/hermez
sudo chown $USER:$USER /var/hermez

Launching the Boot Coordinator

It is recommended to run the Coordinator node in a server with 8+ cores, 16 GB+ of RAM and 250GB of disk (AWS c5a.2xlarge or equivalent).

  1. Import the Coordinator and Fee Ethereum accounts private keys into the keystore.
./dist/heznode importkey --mode coord --cfg ./cmd/heznode/cfg.sandbox.boot-coordinator.toml --privatekey 0x705df2ae707e25fa37ca84461ac6eb83eb4921b653e98fdc594b60bea1bb4e52
./dist/heznode importkey --mode coord --cfg ./cmd/heznode/cfg.sandbox.boot-coordinator.toml --privatekey 0xfdb75ceb9f3e0a6c1721e98b94ae451ecbcb9e8c09f9fc059938cb5ab8cc8a7c

The Coordinator account is used to pay the gas required to forge batches. The Fee account is used to collect the fees paid by users submitting transactions to Hermez Network. You only need to import these keys once.

  1. Start a mock proof server.
cd test/proofserver/cmd
go build -o proof-server
./proof-server -d 15s -a

The hermez-node repository provides a mock proof server that generates proofs every 15 seconds. The mock prover is launched at http://localhost:3000, and it exports two endpoints: - GET /api/status: Queries the prover's status. - POST /api/input: Starts the generation of a new proof.

  1. Wipe SQL database

Before starting the Coordinator node, you may want to wipe the pre-existing SQL database. This command will wipe the pre-existing database if it exists, and it will force the Coordinator to resynchronize the full state.

./dist/heznode wipedbs --mode coord --cfg cmd/heznode/cfg.sandbox.boot-coordinator.toml 
  1. Launch the Hermez Node
./dist/heznode run --mode coord --cfg cmd/heznode/cfg.sandbox.boot-coordinator.toml

Once the Hermez Node is launched, the API can be queried at localhost:8086/v1. You can find more information on the API here

Launching a Proof Server

We will use rapidsnark as the Hermez proof server. rapidsnarks is a zkSnark proof generator written in C++. It is recommended to run the proof server in servers with 48+ cores, 96 GB+ of RAM and 250GB of disk (AWS c5a.12xlarge or equivalent).

rapidsnark requires a host CPU that supports ADX extensions. You can check this with cat /proc/cpuinfo | grep adx


apt install npm
  • npx
npm i -g npx
  • Install gcc, libsodium, gmp, cmake
sudo apt install build-essential
sudo apt-get install libgmp-dev libsodium-dev nasm cmake

Circuit Files

Download circuit and auxiliary files. These files are extremely large (20GB+), so make sure you have enough bandwidth and disk space.

There are two Hermez circuits that have undergone the Trusted Setup Ceremony. - circuit-2048-32-256-64 with 2048 transactions per batch (~2^27 constraints) - circuit-400-32-256-64 with 400 transactions per batch (~2^25 constraints)

For each type of circuit, you will need the following files: - C++ source file (extension .cpp) - Data file (extension .dat) - Verification and Proving Key files (extension .zkey)







More information on Trusted Setup can be found here.


  1. Clone rapidsnark repository
git clone
  1. Compile the prover.

In this example we are building the 400 transactions prover.

cd rapidsnark
npm install
git submodule init
git submodule update
npx task createFieldSources
npx task buildPistche
npx task buildProverServer ../circuit-400-32-256-64.cpp
  1. Launch prover
cd ..
./rapidsnark/build/proverServer circuit-400-32-256-64.dat circuit-400-32-256-64_hez4_final.zkey

Prover is deployed at port 9080.

  1. Check prover status
curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET http://localhost:9080/status

Generate a Prover Input File

  1. Clone circuits repository
git clone
  1. Install dependencies
cd circuits
npm install
cd tools

In this example we are working with circuit-400-32-236-64_hez1.zkey, which corresponds to a circuit with 400 transactions, 32 levels, 256 maxL1Tx and 64 maxFeeTx.

  1. Generate Input file

To generate a new input file with empty transactions:

node build-circuit.js input 400 32 256 64

This command generates a new input file rollup-400-32-256-64/input-400-32-256-64.json

To generate a new input file with random transactions

node generate-input.js 256 144 400 32 256 64

This will create a new input file called inputs-256.json

Generate a New Proof

You can use curl to post any of the inputs generated in the previous step.

curl -X POST -d @inputs-256.json http://localhost:9080/input


curl -X POST -d @input-400-32-256-64.json http://localhost:9080/input

You check the status of the prover by querying the /status endpoint.

curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET http://localhost:9080/status

/status returns if the prover is ready to accept a new input as well as the proof result and input data of the previous iteration. An example is shown below.


Connect Prover to Coordinator Node

Once you have verified the prover is working, you can connect it to the Hermez Coordinator by configuring the cfg.sandbox.boot-coordinator.toml configuration file. You need to substitute sections ServerProofs with the updated URLs where prover is deployed, and the Circuit section where the verifier smart contract is specified.

#TODO: Add Prover URL
#URLs = ["http://localhost:9080"]
MaxTx = 400
NLevels = 32

At this point, you can stop the mock server if it is still running, and re-launch the coordinator as we saw in the previous section. The new prover will be running at http://localhost:9080 (or at the configured URL), and the two endpoints are /status and /input

Launching a Price Updater

Price Updater service is used to consult and updater the tokens and fiat currency used by Hermez Node. Once Hermez Node has been deployed, the Price Updater service can be deployed. Follow these instructions to set up the Price Updater service.

Launching a Synchronizer Node

In synchronizer mode, the node is capable of keeping track of the rollup and consensus smart contracts, storing all the history of events, and keeping the rollup state updated, handling reorgs when they happen. This mode is intended for entities that want to gather all the rollup data by themselves and not rely on third party APIs. For this part of the tutorial, we are going to deploy the syncrhonizer node in testnet on Rinkeby.

  1. Stop Coordinator node launched in localhost in previous steps.

Stop prover, coordinator node and containers from previous phases as you will be working in testnet with a real Boot Coordinator node.

docker-compose -f docker-compose.sandbox.yaml down
  1. Launch PostgreSQL database.

The Hermez node in synchronizer mode needs to run on a separate database

docker run --rm --name hermez-db -p 5432:5432 -e POSTGRES_DB=hermez -e POSTGRES_USER=hermez -e POSTGRES_PASSWORD="yourpasswordhere" -d postgres
  1. Start an Ethereum node in Rinkeby

You will need to run your own Ethreum node on Rinkeby. We recommend using Geth. - Pre-built binaries for all platforms on our downloads page ( - Ubuntu packages in our Launchpad PPA repository ( - OSX packages in our Homebrew Tap repository (

Sync this node with Rinkeby testnet where all of Hermez's smart contracts are deployed.

  1. Get contract addresses

Query Testnet API for the addresses of the Hermez smart contracts. You can use a web browser or the command below.

curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET

At this moment, Hermez Network is deployed in this address:

  1. Copy configuration file to hermez-node/cmd/heznode/cfg.testnet.sync.toml. You will need to edit the following sections:
  2. PostgreSQL Values provided are valid for docker postgreSQL container. You will need to supply the actual values for your database.
  3. Web3 URL of your Rinkeby Ethereum node
  4. SmartContracts Double check that the address provided in the configuration file corresponds to the current Hermez Network contract deployed in Rinkeby

  5. Launch hermez-node in synchronizer mode

./dist/heznode run --mode sync --cfg cmd/heznode/cfg.testnet.sync.toml
  1. Kill and relaunch Price Updater service in testnet Follow instructions to set up the Price Updater service.

Once the Hermez node is launched, the API can be queried at the location specified in the configuration file in API.Address section, as well as at serviced by the Boot Coordinator node.

Launching a Second Coordinator Node

In this part of the tutorial we will start a second Coordinator Node in testnet that will bid for the right to forge batches.


  • node 14+

Start Coordinator in Testnet

  1. Stop Synchronizer node and PostgreSQL container launched in previous steps.

  2. Launch PostgreSQL database

docker run --rm --name hermez-db -p 5432:5432 -e POSTGRES_DB=hermez -e POSTGRES_USER=hermez -e POSTGRES_PASSWORD="yourpasswordhere" -d postgres
  1. Launch Prover as shown here

  2. Create two Ethereum accounts in Rinkeby using Metamask wallet. One account is the forger account (needs to pay for gas to forge batches in Ethereum and for bids in auction in HEZ), and the second is the fee account (receives the HEZ fees). The fees are collected in L2. You can convert from ETH to HEZ in Uniswap

  3. Create a Wallet with fee account Ethereum Private Key.

This wallet is needed to generate a Baby JubJub address where fees will be collected. There is an example code in the SDK that can be used. Simply substitute EXAMPLES_WEB3_URL by your Rinkeby Node URL and EXAMPLES_PRIVATE_KEY1 by fee account private key.

This script will generate a similar output:

  privateKey: <Buffer 3e 12 35 91 e9 99 61 98 24 74 dc 9c 09 70 0a cb d1 a5 c9 6f 34 2f ab 35 ca 44 90 01 31 f4 dc 19>,
  publicKey: [
  publicKeyHex: [
  publicKeyCompressed: '5660923625742030187027289840534366342931920530664475168036204263114974152564',
  publicKeyCompressedHex: '0c83f81f4fce3e2ccc78530099830e29bf69713fa11c546ad152bf5226cfc774',
  publicKeyBase64: 'hez:dMfPJlK_UtFqVByhP3FpvykOg5kAU3jMLD7OTx_4gwzO',
  hermezEthereumAddress: 'hez:0x74d5531A3400f9b9d63729bA9C0E5172Ab0FD0f6'

The Baby JubJub address is publicKeyCompressedHex. In this case, 0x0c83f81f4fce3e2ccc78530099830e29bf69713fa11c546ad152bf5226cfc774.

  1. Copy configuration file to hermez-node/cmd/heznode/cfg.testnet.coord.toml. You will need to edit the following sections:
  2. PostgreSQL Values provided are valid for docker postgreSQL container. You will need to supply the actual values for your database.
  3. Web3 URL of your Rinkeby Ethereum node
  4. SmartContracts Double check that the address provided in the configuration file corresponds to the current Hermez Network contract deployed in Rinkeby
  5. Coordinator.ForgerAddress Ethereum account in Ethereum Rinkeby. This account is used to bid during the slots auction and to pay the gas to forge batches in Ethereum
  6. Coordinator.FeeAccount You need to supply the Fee account in Ethereum Rinkeby and the Baby JubJub address computed in previous step. This account is used to colled the fees paid by transactions.
  7. Coordinator.ServerProofs Provide a valid URL for the proof server.
  8. Coordinator.Circuit Ensure the MaxTx parameters matches with the circuit size configed in the proof server.

  9. Import the forger and fee Ethereum private keys into the keystore.

./dist/heznode importkey --mode coord --cfg cmd/heznode/cfg.coord.toml --privatekey <FORGER ACCOUNT_PRIVATE KEY>
./dist/heznode importkey --mode coord --cfg cmd/heznode/cfg.coord.toml --privatekey <FEE_ACCOUNT PRIVATE KEY>

This private key corresponds to the new Coordinator node

  1. Launch New Coordinator Node
./dist/heznode run --mode coord --cfg cmd/heznode/cfg.testnet.coord.toml

The node will start synchronizing with the Hermez Network in testnet. This may take a while.

  1. Launch new Price Updater service and connect it to the newly launched Hermez node Follow instructions to set up the Price Updater service.

Bidding Process

Once the node is synchronized, you can start bidding for the right to forge a batch.

  1. Install cli-bidding

cli-bidding is a tool that allows to register a Coordinator in Hermez Network and place bids in the auction.

git clone

Once downloaded, follow the installation steps in the README.

NOTE that PRIVATE_KEY_CLI_BIDDING corresponds to the forger private key.

  1. Approve HEZ transfers.

Before the coordinator can start bidding, it needs to approve the use of HEZ tokens. To do this go to HEZ address in Etherscan, select Contract -> Write Contract -> Approve and set spender address to Coordinator address and value to quantity you want to approve. The recommendation is to set this quantity value very high.

  1. Register Forger

Using cli-bidding, you need to register the new Coordinator API URL. In our case, we have the Coordinator node running at

node src/biddingCLI.js register --url

NOTE. In order for the wallet-ui to be able to forward transactions to this coordinator, the API needs to be accessible from a https domain.

  1. Get Current Slot and Minimum Bid in Hermez bid

Take a look at the current slot being bid in Hermez. When bidding, you need to bid at least 2 slots after the curent slot

node src/biddingCLI.js slotinfo

In our case, minimum bidding is set to 11.0 HEZ, and first biddable slot is 4200.

  1. Bidding Process

Send a simple bid of \(11 \times 10^{18}\) HEZ for slot 4200.

node src/biddingCLI.js bid --amount 11 --slot 4200 --bidAmount 11

Parameter amount is the quantity to be transferred to the auction smart contract, and bidAmount is the actual bid amount.

If the bidding process is successful, an Etherscan URL with the transaction id is returned to verify transaction.

You can check the allocated nextForgers using /v1/state endpoint

cli-bidding provides additional mechanisms to bid in multple slots at once. Check the README file