EON 1.4 – Version Changes and Update Instructions
Overview
This document will outline the various changes that were introduced with the 1.4 update. It will provide a list of areas you should be aware of and also instructions on how to update your forger with new capabilities.
In version 1.4, we’ve improved the usability of the staking system at the protocol level by automating the reward distribution among the forger hosting provider and the ZEN holders who stake their ZEN to the forger node. Forgers are now able to designate a smart contract that will allow delegators to claim rewards. The percentage of the forger’s incomes redirected to the smart contract will be declared by each forger when first registering.
Horizen will provide a factory contract that can be used to distribute rewards to forgers, although any contract can be used. The smart contract provided will distribute rewards proportionally to delegators according to the amount they stake.
Version 1.4 also introduces a minimum staking requirement (10 ZEN) to forgers for security best practices.
It’s important to note that no changes need to be made by existing forger nodes, 100% of the forger incomes will continue being sent to the reward address specified by the forger as it does currently. Otherwise, you can designate a smart contract for reward distribution (instructions provided within this document).
The EON 1.4 hardfork will happen on Thursday, June 27th at Epoch 1593 (16:55pm UTC)
- EON 1.4 mainnet release tag https://github.com/HorizenOfficial/eon/releases/tag/1.4.0 :
- Docker Compose Updates: https://github.com/HorizenOfficial/compose-evm-simplified/releases/tag/1.4.0
- Horizen Reward Factory Contract Address: https://eon-explorer.horizenlabs.io/address/0x8604Bb903B7D54F666bA1e75f98045345C63132a
- (instructions for interacting with the factory contract noted below)
Changes in Stakes Management
Please review the following information to understand the changes that occurred with this update. This is important for those of you running forger nodes as some functionality has changed.
A new native smart contract will be available to manage stake-related operations. It will be available at the address 0x0000000000000000000022222222222222222333. Full documentation of its interface can be found here.
The old smart contract exposed at address 0x0000000000000000000022222222222222222222 will be deprecated and all its methods will error if called after the 1.4 hardfork.
The below table summarizes the most important differences.
Detail: Changes Before <> After
Operation |
EON < 1.4 |
EON 1.4 |
Declare a new forger |
Not needed |
New Endpoint /transaction/registerForger |
Add stake (via smart contract call) |
delegate method on old stake contract. Stake owner (the address that can unstake it) can be any address |
delegate method on new stake contract |
Add stake (via http endpoints) |
Not available |
|
Withdraw stake (via smart contract call) |
withdraw on old stake contract StakeId and additional signature needed Partial withdraw not possible |
withdraw on new stake contract No stakeId and no additional signature needed Partial withdraw possible |
Withdraw stake (via http endpoints) |
Not available |
|
Stakes belonging to a delegator address |
getPagedForgersStakesByUser on old stake contract (in the return list 1 element for each stakeId) |
getPagedForgersStakesByDelegator on new stake contract (in the return list 1 element for each forger, with the sum of the stakes) |
Stakes owned or delegated to a specific forger |
Not available |
getPagedForgersStakesByForger on the new stake contract |
Total amount staked |
stakeOf on the old stake contract: Returns only the current value and only by delegator |
stakeTotal on new stake contract. Possible to query historical data for previous epochs, and filter by delegator and/or forger |
Stake lottery |
Forger will participate at the lottery with any amount |
Forger will participate at the lottery only if owned+delegated stake >= 10 ZEN |
List of registered forgers |
Not available |
getPagedForgers on new stake contract |
Explorer Changes
EON Explorer will be updated to a new version on Tuesday, June 25.
Breaking changes
- Current API will be deprecated on the current URL. Please update the API URL to https://eon-explorer-api.horizenlabs.io/api.
Alternatively, the V2 API can be used. See specifications in the V2 API docs: https://eon-explorer.horizenlabs.io/api-docs
New features
- Display ABI for Forger Stake V2 contract
- Display a list of “Mainchain Rewards Distribution” from 0x0000000000000000000033333333333333333333
- V2 API docs: https://eon-explorer.horizenlabs.io/api-docs
- New APIs for forward transfers and fee payments:
- /blocks/{block_number_or_hash}/forward-transfers
- /blocks/{block_number_or_hash}/fee-payments
- /addresses/{address_hash}/forward-transfers
- /addresses/{address_hash}/fee-payments
- /forward-transfers
- /fee-payments
Deploying the Factory Contract to EON for Distribution
Horizen provides a default implementation of a smart contract handling the redistribution of rewards between forger’s delegators.
If you want to deploy one for your forger:
-
- Go to the factory contract available on the explorer: https://eon-explorer.horizenlabs.io/address/0x8604Bb903B7D54F666bA1e75f98045345C63132a
- Select the Contract tab.
- Select the Write Contract tab.
- Connect your wallet.
- Use the method deployDelegatedStakingReferenceImplementation of the factory:
- The required parameters that identify your forger are:
- signPubKey
- vrfKey
- Note that this is split in between two parameters: one for the first 32 bytes and another for the last btye. This is because the vrfkey is 33 bytes of data.
- The required parameters that identify your forger are:
- Once the parameters are entered click the Write button. The method execution will trigger the deployment of the smart contract instance.
- Take note of its address: you will need it in the forger registration step.
For further info, you can read the full tutorial on how to setup a forger node here: https://docs.horizen.io/horizen_eon/tutorials/forger_node_setup_guide
If you want to look at the code of the delegated staking contract, it is available at this address: https://github.com/HorizenOfficial/eon-delegated-staking
This factory contract was audited by Halborn for security best practices.
Forger Registration and Setting Smart Contract for Distribution of Rewards
The instructions below are all steps required when setting up a new forger node. If you already have a node, you only need to (optionally) follow Step 2 to assign an EON smart contract for reward distribution.
Step 1: Registration of Forgers
Each forger must now register before being able to participate in the lottery and receive stake delegations. This is an additional step compared to the actual flow (so far, was enough to create an initial stake).
The registration can be performed by calling a new http endpoint on the forger node:
The method will accept the following parameters:
- signPubKey
- vrfPubKey
- rewardShare
- smartContractAddress
- stakedAmount
(see above link for further info)
Please note that rewardShare and smartContractAddress once set are considered immutable and can’t be changed later (to use different values a forger would have to register new keys, and ask the delegators to unstake+stake to the new key).
Step 2: Update of a Forger Already Present Before EON 1.4
Forgers already present before EON 1.4 will not require an explicit registration described in Step 1: they will be automatically migrated and registered.
But please note that if they own a total stake (own + delegated) < 10 ZEN they will no longer be able to forge any block after the 1.4 hardfork activation, and you will need to increase the stake to 10 ZEN or more.
All migrated forgers will have the fields rewardShare = 0 and smartContractAddress = none, meaning they will not redirect any percentage of the reward to an additional smart contract (the same behavior happens in old EON versions).
A method to update these fields is available in the http endpoints:
The method will accept the following parameters:
- signPubKey
- vrfPubKey
- rewardShare
- rewardAddress
(see above link for further info)
Please note this method can be called only once and only if their value is equal to: (rewardShare=0, smartContractAddress=null). In other words, rewardShare and smartContractAddress once set are considered immutable and can’t be changed (to use different values a forger would have to register new keys, and ask the delegators to unstake+stake to the new key).
Important: for security reasons the updateForger operation will be doable only starting from two consensus epochs after the hard fork activation (25 hours).
Step 3: Collect Stakes
Similar to the actual smart contract, the new native smart contract will expose methods to delegate stake to a forger and withdraw them.
delegate(bytes32 signPubKey, bytes32 vrf1, bytes1 vrf2)
The method will fail if the forger was not previously registered (remember forgers existing before the hard fork activation will be considered registered by default).
withdraw(bytes32 signPubKey, bytes32 vrf1, bytes1 vrf2, uint256 amount)
The owner of the stake must be the one sending the tx.
Enough stake must exist, but now will be possible also to partially withdraw the stake.
Amount unstaked will be sent back to the sender balance.
Please note that with the new system the stake handling is simplified, since:
- There is no more the concept of “stakeId”. A stake is now just an amount associated with a specific forger and delegator address, that can be incremented or decremented over-time with multiple delegate and withdrawal operations.
- No additional signatures other than the standard Ethereum-like transaction signature will be required to call delegate and withdraw methods: this allows them to be called easily also from hardware wallets like Ledger.
Step 4: Reward Calculation
The same algorithm will be applied at the end of each withdrawal epoch to reward forgers, but the amount previously sent to the forger address will be split in two parts if the rewardShare specified by the forger is > 0.
An additional change has been also implemented in the:
- Endpoints /block/getFeePayments
- RPC endpoint zen_getFeePayments
Their result will keep the same format as now, but will also include the reward paid to the address of the smart contracts (if defined).
We will also detail the amount coming from the mainchain redistribution: to be retrocompatible they will be into additional fields valueFromMainchain and valueFromFees:
Step 5: Claim of Delegators Rewards
The amounts directed to the smart contract will have to be redistributed among delegators through the contract. Distribution is the responsibility of the contract implementation. Horizen’s contract provides a fair distribution based on the amount staked and epoch of staking. The default smart contract implementation provided by Horizen exposes a claim method to do it:
claimReward(address owner)
Note that anyone could call the claim method on behalf of the owner (no restrictions on the sender of the transaction).
Documentation on the factory contract is located here: https://github.com/HorizenOfficial/eon/blob/development/doc/howto/delegatedstakingcontract.md
Any forger is free to deploy its own smart contract. Please read the native smart contract documentation for useful methods that could be used inside the smart contract logic.
Reward from Mainchain – New Rules
The maximum ZEN amount redistributed to forgers from the special address 0x000000000000000000003333333333333333333 in a single withdrawal epoch is now limited to a maximum value expressed by the following formula:
-
MAX_VALUE_REDISTRIBUTED = sum [10% of Mainchain’s block-reward Coinbase of each mainchain block reference included in the withdrawal epoch]
-
Funds over the limit will stay in the address balance and will be redistributed in the following epochs.
For example:
Current Mainchain block reward: 6.25 ZEN
Number of mainchain block-reference in a withdrawal epoch: 100
MAX_VALUE_REDISTRIBUTED = 10%(6.25) * 100 = 62.5 ZEN
Release Notes
Additional info on other changes introduced in EON 1.4 can be found in the release notes for EON 1.4 and SDK respectfully: