Staking Smart Contract

Staking

Nodes are promoted to the role of validator when their operator submits a staking transaction to the Staking smart contract. Through this transaction, the operator locks ("stakes") a specific amount of their own ONE for each node that is to become a validator. A single staking transaction can contain the ONE and all necessary information for staking one or more nodes. Such a transaction includes the following::

  • The number of nodes that the operator is staking for

  • The concatenated list of BLS keys belonging to the individual nodes

  • The stake amount for each individual node, namely the number of nodes × 3000 ONE

  • A gas limit of 6 000 000 gas units × the number of nodes

  • Optionally, a separate address may be specified, to which the rewards should be transferred, instead of the address from which the transaction itself originates. The reward address must be first decoded to bytes from the Bech32 representation, then re-encoded to base16 (hexadecimal).

NOTE

The Every node needs 3000 ONE plus a Validator NFT

For example, if an operator manages two individual nodes with the 96-byte-long BLS keys 45e7131ba....294812f004 and ecf6fdbf5....70f1d251f7, then the staking transaction would be constructed as follows:

StakingTransaction {
    Sender: <account address of the node operator>
    Receiver: erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqXXXXXXXXX
    Value: 3000 ONE
    GasLimit: 12000000
    Data: "stake" +
          "@0002" +
          "@45e7131ba....294812f004" +
          "@67656e65736973"
          "@ecf6fdbf5....70f1d251f7" +
          "@67656e65736973"
          "@optional_reward_address_HEX_ENCODED"
}

For encoding argument details, see the "sc-calls" section.

This transaction, being a call to the Staking smart contract, communicates through the Data field:

  • stake is the name of the smart contract function to be called;

  • 0002 is the number of nodes (unsigned integer, hex-encoded);

  • 45e7131ba....294812f004 is the BLS key of the first node, represented as a 192-character-long hexadecimal string;

  • 67656e65736973 is a reserved placeholder, required after each BLS key;

  • ecf6fdbf5....70f1d251f7 is the BLS key of the second node, represented as a 192-character-long hexadecimal string;

  • 67656e65736973 is the aforementioned reserved placeholder, repeated;

  • optional_reward_address_HEX_ENCODED represents the address of the account set to receive rewards from the staked nodes. This address is converted from its standard Bech32 format into binary, and then encoded again into a hexadecimal string.

Changing the reward address

Changing the Reward Address

Validator nodes generate rewards, which are subsequently deposited into an account. Unless otherwise specified, this account is the one from which the staking transaction originated. During the staking process, node operators have the flexibility to designate a different reward address.

The reward address may be updated following the initial staking transaction by executing a specific transaction with the Staking smart contract. It's crucial to know the exact number of nodes declared in the original staking transaction to accurately calculate the gas limit required for modifying the reward address.

  • An amount of 0 ONE

  • A gas limit of 6 000 000 gas units × the nodes for which the reward address is changed (as specified by the original staking transaction).

  • The new reward address. The reward address must be first decoded into binary from its normal Bech32 representation, then re-encoded to base16 (hexadecimal).

For example, changing the reward address for two nodes requires the following transaction:

ChangeRewardAddressTransaction {
    Sender: <account address of the node operator>
    Receiver: erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqXXXXXXXXX
    Value: 0 ONE
    Data: "changeRewardAddress@reward_address_HEX_ENCODED"
    GasLimit: 12000000
}

Unstaking

A node operator can demote their validator nodes back to observer status by sending an unstaking transaction to the Staking smart contract, which includes the following:

  • An amount of 0 ONE

  • The concatenated list of the BLS keys belonging to the individual nodes which are to be demoted from validator status

  • A gas limit of 6 000 000 gas units × the number of nodes

It's important to note that demotion of nodes does not occur instantly: unstaked nodes will continue to serve as validators until the network formally releases them, a process that is influenced by various factors.

Furthermore, the ONE that was previously locked for staking will not be immediately accessible. It will become available only after a specified number of rounds, at which point the node operator can reclaim the staked amount through a third special transaction (discussed in the subsequent section).

Continuing the example in the previous section, an unstaking transaction for the two nodes contains the following:

UnstakingTransaction {
    Sender: <account address of the node operator>
    Receiver: erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqXXXXXXXXX
    Value: 0 ONE
    GasLimit: 12000000
    Data: "unStake" +
          "@45e7131ba....294812f004" +
          "@ecf6fdbf5....70f1d251f7"
}

Note that:

  • 45e7131ba....294812f004 is the BLS key of the first node, represented as a 192-character-long hexadecimal string;

  • ecf6fdbf5....70f1d251f7 is the BLS key of the second node, represented as a 192-character-long hexadecimal string;

  • no reserved placeholder is needed, as opposed to the staking transaction (see above)

Unbonding

A node operator can reclaim the stake that was previously locked for their validator nodes by sending an unbonding transaction to the Staking smart contract. Before initiating the unbonding process, the node operator needs to have completed an unstaking transaction for some of their validators. Additionally, a specific number of rounds must elapse after the unstaking transaction has been processed.

The unbonding transaction is almost identical to the unstaking transaction, and contains the following:

  • An amount of 0 ONE

  • The concatenated list of the BLS keys belonging to the individual nodes for which the stake is claimed back

  • A gas limit of 6 000 000 gas units × the number of nodes

Following the example in the previous sections, an unbonding transaction for the two nodes contains the following information:

UnbondingTransaction {
    Sender: <account address of the node operator>
    Receiver: erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqXXXXXXXXX
    Value: 0 ONE
    GasLimit: 12000000
    Data: "unBond" +
          "@45e7131ba....294812f004" +
          "@ecf6fdbf5....70f1d251f7"
}

Note that:

  • 45e7131ba....294812f004 is the BLS key of the first node, represented as a 192-character-long hexadecimal string;

  • ecf6fdbf5....70f1d251f7 is the BLS key of the second node, represented as a 192-character-long hexadecimal string;

  • no reserved placeholder is needed, as opposed to the staking transaction (see above)

Unjailing

If a node operator notices that some of their validator nodes have been jailed due to a low rating, they can restore the nodes back to active validators by paying a small fine. This is done using an unjailing transaction, sent to the Staking smart contract, which contains the following:

  • An amount of xxx ONE (the fine) for each jailed node - this value must be correctly calculated; any other amount will result in a rejected unjail transaction

  • The concatenated list of the BLS keys belonging to the individual nodes that are to be unjailed

  • A gas limit of 6 000 000 gas units × the number of nodes

Continuing the example in the previous section, if the nodes 45e7131ba....294812f004 and ecf6fdbf5....70f1d251f7 were placed in jail due to low rating, they can be unjailed with the following transaction:

UnjailTransaction {
    Sender: <account address of the node operator>
    Receiver: erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqXXXXXXXXX
    Value: XXX ONE
    GasLimit: 12000000
    Data: "unJail" +
          "@45e7131ba....294812f004" +
          "@ecf6fdbf5....70f1d251f7"
}

Note that:

  • 45e7131ba....294812f004 is the BLS key of the first node, represented as a 192-character-long hexadecimal string;

  • ecf6fdbf5....70f1d251f7 is the BLS key of the second node, represented as a 192-character-long hexadecimal string;

  • no reserved placeholder is needed, as opposed to the staking transaction (see above)

Claiming unused tokens from Staking

If a node operator has sent a staking transaction containing an amount of ONE higher than the requirement for the nodes listed in the transaction, they can claim back the remainder of the sum with a simple claim transaction, containing:

  • An amount of 0 ONE

  • A gas limit of 6 000 000 gas units

An example of a claim transaction is:

ClaimTransaction {
    Sender: <account address of the node operator>
    Receiver: erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqXXXXXXXXX
    Value: 0 ONE
    Data: "claim"
    GasLimit: 6000000
}

Once this transaction is processed, the Staking smart contract will generate a return transaction to the sender's account, provided that the sender's account has engaged in node staking via a staking transaction previously.

Last updated