BPoS Voting System
BPoS (Bonded Proof of Stake) is the consensus mechanism that selects which validators produce and confirm blocks on the ELA main chain. Community members stake ELA, vote for validators, and earn rewards proportional to their stake. This page covers the technical mechanics.
Validator Lifecycle
Validator Registration
To register as a validator, submit a RegisterProducer transaction (type 0x09):
| Field | Description |
|---|---|
OwnerKey | Producer owner's public key |
NodePublicKey | Node's public key (for DPoS P2P) |
NickName | Display name |
Url | Information URL |
Location | Country code |
NetAddress | Node IP:Port |
StakeUntil | Block height when stake unlocks |
Validators need 80,000+ staking rights to be eligible for block production.
Validator Management Transactions
| Transaction | Code | Purpose |
|---|---|---|
RegisterProducer | 0x09 | Register as a validator |
UpdateProducer | 0x0b | Update profile info |
CancelProducer | 0x0a | Cancel registration |
ActivateProducer | 0x0d | Reactivate after inactivity |
ReturnDepositCoin | 0x0c | Reclaim deposit after cancel |
Vote Weight Calculation
BPoS (After Height 1,405,000)
Vote weight uses a logarithmic time-lock multiplier — longer commitments earn more influence:
weight = log10((LockTime - CurrentBlockHeight) / 7200 * 10)
effectiveVotes = stakedELA * weight
Where 7200 blocks is approximately 10 days at 2-minute block time.
Legacy DPoS v1 (Before Height 1,405,000)
Vote weight equaled the raw ELA amount. No time-locking.
BPoS Staking Transactions
| Transaction | Code | Purpose |
|---|---|---|
ExchangeVotes | 0x62 | Convert ELA to stake votes |
Voting | 0x63 | Cast BPoS votes with lock time |
ReturnVotes | 0x64 | Return staked votes |
VotesRealWithdraw | 0x65 | Execute vote return |
DposV2ClaimReward | 0x60 | Claim voter rewards |
DposV2ClaimRewardRealWithdraw | 0x61 | Execute reward withdrawal |
Validator Selection
Every election round, the validator set is recalculated by ranking all validators by total staking rights:
Configuration:
- ~70 community-elected validators (variable; see nodes.elastos.net)
- 12 Council validators (always active, claimed by council members)
- Backup candidates fill in on failures via
ForceChange()
Block Production Rotation
Validators take turns proposing blocks by rotating a duty index:
- On-duty validator broadcasts a
DPOSProposalwith the block hash - Other validators validate and broadcast
DPOSProposalVote(accept/reject) - When 2/3+1 of active validators vote to accept, a
Confirmis formed - The confirmed block is final — no reorganization is possible
Inactivity Penalties
| Condition | Consequence |
|---|---|
| Missed 1,440+ duty rounds (~2 days) | Producer enters Inactive state |
| Double signing / conflicting proposals | 200 ELA deducted from deposit; can re-register by posting a new deposit |
| Evidence submitted | Permanent on-chain record of misbehavior |
Staking via NFT Tickets
When users stake ELA for BPoS, they receive NFT tickets on ESC via the StakeTicket contract:
- User stakes ELA on the main chain
- User calls
StakeTicket.claim()on ESC with the main chain tx hash - Contract verifies multi-sig via precompiled contract at address
1003 - An ERC-721 NFT is minted representing the stake position
Relevant ESC precompiles:
| Address | Purpose |
|---|---|
1000 | Current active BPoS validators |
1003 | Pledge bill multi-sig verification |
1004 | Main chain tx to NFT token ID mapping |
1005 | Full NFT metadata |
1006 | BPoS NFT payload version |