# Staking Smart Contract

## **Staking**[​](https://docs.multiversx.com/validators/staking/staking-smart-contract#staking) <a href="#staking" id="staking"></a>

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).

{% hint style="info" %}
NOTE

The Every node needs 3000 ONE plus a Validator NFT
{% endhint %}

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:

```csharp
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.*<br>

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**[​](https://docs.multiversx.com/validators/staking/staking-smart-contract#changing-the-reward-address) <a href="#changing-the-reward-address" id="changing-the-reward-address"></a>

#### 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:

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

### **Unstaking**[​](https://docs.multiversx.com/validators/staking/staking-smart-contract#unstaking) <a href="#unstaking" id="unstaking"></a>

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).&#x20;

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

```csharp
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**[​](https://docs.multiversx.com/validators/staking/staking-smart-contract#unbonding) <a href="#unbonding" id="unbonding"></a>

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:

```csharp
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**[​](https://docs.multiversx.com/validators/staking/staking-smart-contract#unjailing) <a href="#unjailing" id="unjailing"></a>

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:

```csharp
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**[​](https://docs.multiversx.com/validators/staking/staking-smart-contract#claiming-unused-tokens-from-staking) <a href="#claiming-unused-tokens-from-staking" id="claiming-unused-tokens-from-staking"></a>

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:

```csharp
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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.onefinity.network/technology/run-a-onefinity-node/staking-smart-contract.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
