This section aims to give a better overview of some concepts currently present in the Proof of Stake (PoS) implementation of the ZChains.
The ZChains Proof of Stake (PoS) implementation is meant to be an alternative to the existing PoA IBFT implementation, giving node operators the ability to easily choose between the two when starting a chain.
The core logic behind the Proof of Stake implementation is situated within the Staking Smart Contract.
This contract is pre-deployed whenever a PoS mechanism Zchains chain is initialized, and is available on the address 0x0000000000000000000000000000000000001001
from block 0
.
Epochs are a concept introduced with the addition of PoS to the Zchains.
Epochs are considered to be a special time frame (in blocks) in which a certain set of validators can produce blocks. Their lengths are modifiable, meaning node operators can configure the length of an epoch during genesis generation.
At the end of each epoch, an epoch block is created, and after that event a new epoch starts. To learn more about epoch blocks, see the Epoch Blocks section.
Validator sets are updated at the end of each epoch. Nodes query the validator set from the Staking Smart Contract during the creation of the epoch block, and save the obtained data to local storage. This query and save cycle is repeated at the end of each epoch.
Essentially, it ensures that the Staking Smart Contract has full control over the addresses in the validator set, and leaves nodes with only 1 responsibility - to query the contract once during an epoch for fetching the latest validator set information. This alleviates the responsibility from individual nodes from taking care of validator sets.
Addresses can stake funds on the Staking Smart Contract by invoking the stake
method, and by specifying a value for the staked amount in the transaction:
By staking funds on the Staking Smart Contract, addresses can enter the validator set and thus be able to participate in the block production process.
:::info Threshold for staking Currently, the minimum threshold for entering the validator set is staking 1 ETH
:::
Addresses that have staked funds can only unstake all of their staked funds at once.
Unstaking can be invoked by calling the unstake
method on the Staking Smart Contract:
After unstaking their funds, addresses are removed from the validator set on the Staking Smart Contract, and will not be considered validators during the next epoch.
Epoch Blocks are a concept introduced in the PoS implementation of IBFT in Zchains.
Essentially, epoch blocks are special blocks that contain no transactions and occur only at the end of an epoch. For example, if the epoch size is set to 50
blocks, epoch blocks would be considered to be blocks 50
, 100
, 150
and so on.
They are used to performing additional logic that shouldn't occur during regular block production.
Most importantly, they are an indication to the node that it needs to fetch the latest validator set information from the Staking Smart Contract.
After updating the validator set at the epoch block, the validator set (either changed or unchanged) is used for the subsequent epochSize - 1
blocks, until it gets updated again by pulling the latest information from the Staking Smart Contract.
Epoch lengths (in blocks) are modifiable when generating the genesis file, by using a special flag --epoch-size
:
The default size of an epoch is 100000
blocks in the Zchains.
The Zchains pre-deploys the Staking Smart Contract during genesis generation to the address 0x0000000000000000000000000000000000001001
.
It does so without a running EVM, by modifying the blockchain state of the Smart Contract directly, using the passed in configuration values to the genesis command.
This guide goes into detail on how to set up a Proof of Stake network with the ZChains, how to stake funds for nodes to become validators and how to unstake funds.
It is highly encouraged to read and go through the Local Setup / Cloud Setup sections, before going along with this PoS guide. These sections outline the steps needed to start a Proof of Stake (PoS) cluster with the ZChains.
Currently, there is no limit to the number of validators that can stake funds on the Staking Smart Contract.
The repo for the Staking Smart Contract is located here.
It holds the necessary testing scripts, ABI files and most importantly the Staking Smart Contract itself.
Setting up a network with the ZChains is covered in the Local Setup / Cloud Setup sections.
The only difference between setting up a PoS and PoA cluster is in the genesis generation part.
When generating the genesis file for a PoS cluster, an additional flag is needed --pos
:
Epochs are covered in detail in the Epoch Blocks section.
To set the size of an epoch for a cluster (in blocks), when generating the genesis file, an additional flag is specified --epoch-size
:
This value specified in the genesis file that the epoch size should be 50
blocks.
The default value for the size of an epoch (in blocks) is 100000
.
:::info Lowering the epoch length As outlined in the Epoch Blocks section, epoch blocks are used to update the validator sets for nodes.
The default epoch length in blocks (100000
) may be a long time to way for validator set updates. Considering that new blocks are added ~2s, it would take ~55.5h for the validator set to possibly change.
Setting a lower value for the epoch length ensures that the validator set is updated more frequently. :::
The Staking Smart Contract repo is a Hardhat project, which requires NPM.
To initialize it correctly, in the main directory run:
Scripts for interacting with the deployed Staking Smart Contract are located on the Staking Smart Contract repo.
Create an .env
file with the following parameters in the Smart Contracts repo location:
Where the parameters are:
JSONRPC_URL - the JSON-RPC endpoint for the running node
PRIVATE_KEYS - private keys of the staker address
STAKING_CONTRACT_ADDRESS - the address of the staking smart contract ( default 0x0000000000000000000000000000000000001001
)
:::info Staking address The Staking Smart Contract is pre-deployed at address 0x0000000000000000000000000000000000001001
.
Any kind of interaction with the staking mechanism is done through the Staking Smart Contract at the specified address.
To learn more about the Staking Smart Contract, please visit the Staking Smart Contract section. :::
In order to become part of the validator set, an address needs to stake a certain amount of funds above a threshold.
Currently, the default threshold for becoming part of the validator set is 1 ETH
.
Staking can be initiated by calling the stake
method of the Staking Smart Contract, and specifying a value >= 1 ETH
.
After the .env
file mentioned in the previous section has been set up, and a chain has been started in PoS mode, staking can be done with the following command in the Staking Smart Contract repo:
The stake
Hardhat script stakes a default amount of 1 ETH
, which can be changed by modifying the scripts/stake.ts
file.
If the funds being staked are >= 1 ETH
, the validator set on the Staking Smart Contract is updated, and the address will be part of the validator set starting from the next epoch.
Addresses that have a stake can only unstake all of their funds at once.
After the .env
file mentioned in the previous section has been set up, and a chain has been started in PoS mode, unstaking can be done with the following command in the Staking Smart Contract repo:
All addresses that stake funds are saved to the Staking Smart Contract.
After the .env
file mentioned in the previous section has been set up, and a chain has been started in PoS mode, fetching the list of validators can be done with the following command in the Staking Smart Contract repo: