Proof of Stake

Overview

This section aims to give a better overview of some concepts currently present in the Proof of Stake (PoS) implementation of the kalychain.
The kalychain 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.

PoS Features

The core logic behind the Proof of Stake implementation is situated within the ValidatorSet Smart Contract.
This contract is pre-deployed whenever a PoS mechanism kalychain chain is initialized, and is available on the address 0x0000000000000000000000000000000000001001 from block 0.

Epochs

Epochs are a concept introduced with the addition of PoS to the kalychain.
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 ValidatorSet 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.

Staking

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:
const ValidatorContractFactory = await ethers.getContractFactory("ValidatorSet");
let validatorContract = await ValidatorContractFactory.attach(VALIDATOR_CONTRACT_ADDRESS) as ValidatorSet;
validatorContract = validatorContract.connect(account);
const tx = await validatorContract.stake(THRESHOLD);
const receipt = await tx.wait();
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 10000000 KLC :::

Unstaking

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:
const ValidatorContractFactory = await ethers.getContractFactory("ValidatorSet");
let validatorContract = await ValidatorContractFactory.attach(VALIDATOR_CONTRACT_ADDRESS) as ValidatorSet;
const tx = await validatorContract.connect(account).unstake();
await tx.wait();
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

Epoch Blocks are a concept introduced in the PoS implementation of IBFT in kalychain.
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:
kalychain genesis --epoch-size 50 ...
The default size of an epoch is 100000 blocks in the kalychain.

Contract pre-deployment

The kalychain pre-deploys the ValidatorSet 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.