How to Stake with Locked FLOW
This document outlines the steps a token holder (TH) can take to stake and manage
a Flow node using the LockedTokens
contract. This is the original way that users
who bought tokens from the Flow community sale had to stake their tokens,
but now there is a better way to manage staking, the Staking Collection.
It is highly recommended that you use the staking collection paradigm instead,
as it has more flexibility and features than these original paradigms.
This guide only covers staking with locked FLOW tokens.
Setup
Prerequisites
The token holder must configure their account to hold locked FLOW
before they are able to complete the steps below. After this is complete,
the LockedTokens.TokenHolder
can be used to perform staking operations from the account.
Register a New Staked Node
To register as a node, the token holder can use the Register Node (TH.06) transaction with the following arguments:
Argument | Type | Description |
---|---|---|
id | String | The ID of the new node. It must be a 32 byte String . The operator is free to choose this value, but it must be unique across all nodes. A recommended process to generate this is to hash the staking public key. |
role | UInt8 | The role of the new node. (1: collection, 2: consensus, 3: execution, 4: verification, 5: access) |
networkingAddress | String | The IP address of the new node. |
networkingKey | String | The networking public key as a hex-encoded string. |
stakingKey | String | The staking public key as a hex-encoded string. |
amount | UFix64 | The number of FLOW tokens to stake. |
This transaction registers the account as a node with the specified node information
and attaches a NodeStakerProxy
capability to the TokenHolder
resource.
This capability can later be used to perform staking actions.
Once an account has registered as a node, they cannot register any additional nodes. For more information, see Stake Multiple Nodes from the Same Account below. This feature will be added in the future.
An account can use this transaction to register a different node that replaces the old node, but only if they have withdrawn ALL tokens for their node from their record in the staking contract. If there are any tokens remaining, the re-registration will fail. This is because the registration overwrites the old one, which would revoke access to their tokens.
Once the token holder has registered their node, their tokens and node information are committed to the central staking contract for the next epoch.
At this point, the token holder now has access to various staking operations that they can perform, assuming they have the correct number of tokens to perform the action.
Stake New Tokens
The token holder can stake additional tokens at any time.
Note: this transaction stakes additional tokens to the same node that was registered in the setup phase. It is currently not possible to stake to multiple nodes from the same account.
To stake new tokens via the NodeStakerProxy
,
the token holder can use the Stake New Locked FLOW (TH.08)
transaction with the following arguments:
Argument | Type | Description |
---|---|---|
amount | UFix64 | The number of FLOW tokens to stake. |
This transaction commits tokens to stake from the token holder's locked token account.
Re-stake Unstaked Tokens
After tokens become unstaked, the token holder can choose to re-stake the unstaked tokens to the same node.
To staked unstaked tokens via the NodeStakerProxy
,
the token holder can use the Re-stake Unstaked FLOW (TH.09)
transaction with the following arguments:
Argument | Type | Description |
---|---|---|
amount | UFix64 | The number of unstaked FLOW tokens to stake. |
Re-stake Rewarded Tokens
After earning rewards from staking, the token holder can choose to re-stake the rewarded tokens to the same node.
To staked rewarded tokens via the NodeStakerProxy
,
the token holder can use the Re-stake Rewarded FLOW (TH.10)
transaction with the following arguments:
Argument | Type | Description |
---|---|---|
amount | UFix64 | The number of rewarded FLOW tokens to stake. |
Since rewarded tokens are considered to be unlocked for the purposes of the vesting schedule,
and staked tokens are considered locked, staking rewarded tokens marks the staked tokens as locked
and marks an equal amount of tokens in the token holder's LockedTokens.LockedTokenManager
as unlocked.
Unstake Tokens
The token holder can submit a request to unstake their tokens at any time. If the tokens aren't staked yet, they will be uncommitted and available to withdraw.
To unstake staked tokens via the NodeStakerProxy
, the token holder can use
the Unstake FLOW (TH.11) transaction.
This transaction requires no arguments.
Warning: this will unstake all of the user's staked tokens.
Note: unstaked tokens will be held by the central staking contract until the end of the following epoch. Once the tokens are released (unstaked), they can be claimed via the Withdraw Unstaked Tokens action below.
Withdraw Unstaked Tokens
After tokens become unstaked, the token holder can withdraw them from the central staking contract.
To withdraw unstaked tokens via the NodeStakerProxy
,
the token holder can use the Withdraw Unstaked FLOW (TH.13)
transaction with the following arguments:
Argument | Type | Description |
---|---|---|
amount | UFix64 | The number of unstaked FLOW tokens to withdraw. |
This transaction moves the unstaked tokens back into the LockedTokens.TokenManager
owned by the token holder.
Withdraw Rewarded Tokens
After earning rewards from staking, the token holder can withdraw them from the central staking contract.
To withdraw rewarded tokens via the NodeStakerProxy
,
the token holder can use the Withdraw Rewarded FLOW (TH.14)
transaction with the following arguments:
Argument | Type | Description |
---|---|---|
amount | UFix64 | The number of rewarded FLOW tokens to withdraw. |
This transaction moves the rewarded tokens back into the LockedTokens.TokenManager
owned by the token holder.
However, unlike unstaked tokens, rewards are unlocked FLOW and can be immediately withdrawn from the locked account.
Update A Node's Networking Address
A user may update their node's networking address if it has become inconsistent with the protocol state.
This operation can only be performed in the staking auction phase of an epoch.
Note: Currently, if a node updates its networking address and the new address does not match what is stored in the protocol state for the node, the node will not be able to participate in the upcoming epoch Only update your networking address if you have already confirmed with the Flow team that you can. This restriction will be removed once fully automated epochs are completely implemented
The owner of a Staking Collection can use the Update Networking Address (TH.25) transaction with the following arguments:
Argument | Type | Description |
---|---|---|
nodeID | String | The nodeID of the node to update. |
newAddress | String | The new networking address |
Query a Staker Record
To return a struct with all the information associated with a node, anyone can use the Get Node Info (TH.06) script with the following arguments:
Argument | Type | Description |
---|---|---|
nodeID | String | The 32 byte ID of the node |
This script returns a FlowIDTableStaking.NodeInfo
struct.
Stake Multiple Nodes from the Same Account
Currently, the LockedTokens
contract only supports token holders staking to a single node.
If a token holder wants to create a second staking relationship, they must create a new account and transfer their locked tokens to the new account by requesting authorization from the token admin.
We plan on adding functionality in the future to allow accounts to stake to multiple nodes.
Delegate from the Same Account
An account that registers a node with locked FLOW can also register as a delegator from the same account. See the Locked Delegation Guide for how to register a delegator.
Delegate
Setup
Prerequisites
The token holder must configure their account to hold locked FLOW
before they are able to complete the steps below. After this is complete,
the LockedTokens.TokenHolder
can be used to perform staking operations from the account.
Register as a Delegator
To register as a delegator, the token holder can use the Register Delegator (TH.17) transaction with the following arguments:
Argument | Type | Description |
---|---|---|
id | String | The ID of the node to delegate to. |
amount | UFix64 | The number of FLOW tokens to delegate. |
This transaction registers the account as a delegator to the node ID they specified
and attaches a NodeDelegatorProxy
capability to the TokenHolder
resource.
This capability can later be used to perform delegation actions.
Once an account has registered as a delegator with one node, they cannot register with any others. For more information, see Delegate to Multiple Nodes from the Same Account below. This feature will be added in the future.
An account can use this transaction to register a different delegator that replaces the old delegator, but only if they have withdrawn ALL tokens for their old delegator from their record in the staking contract. If there are any tokens remaining, the re-registration will fail. This is because the registration overwrites the old one, which would revoke access to the tokens.
Delegate New Tokens
The token holder can delegate additional tokens after registering as a delegator.
Note: this transaction delegates additional tokens to the same node that was registered in the setup phase. It is currently not possible to delegate to multiple nodes from the same account.
To delegate new tokens via the NodeDelegatorProxy
,
the token holder can use the Delegate New Locked FLOW (TH.19)
transaction with the following arguments:
Argument | Type | Description |
---|---|---|
amount | UFix64 | The number of FLOW tokens to delegate. |
Re-delegate Unstaked Tokens
After delegated tokens become unstaked, the token holder can choose to re-delegate the unstaked tokens to the same node.
To delegate unstaked tokens via the NodeDelegatorProxy
,
the token holder can use the Re-delegate Unstaked FLOW (TH.20)
transaction with the following arguments:
Argument | Type | Description |
---|---|---|
amount | UFix64 | The number of unstaked FLOW tokens to delegate. |
Re-delegate Rewarded Tokens
After earning rewards from delegation, the token holder can choose to re-delegate the rewarded tokens to the same node.
To delegate rewarded tokens via the NodeDelegatorProxy
,
the token holder can use the Re-delegate Rewarded FLOW (TH.21)
transaction with the following arguments:
Argument | Type | Description |
---|---|---|
amount | UFix64 | The number of rewarded FLOW tokens to delegate. |
Unstake Delegated Tokens
The token holder can submit a request to unstake their delegated tokens at any time. If the tokens aren't staked yet, they will be uncommitted and available to withdraw.
To unstake delegated tokens via the NodeDelegatorProxy
,
the token holder can use the Unstake Delegated FOW (TH.22)
transaction with the following arguments:
Argument | Type | Description |
---|---|---|
amount | UFix64 | The number of FLOW tokens to unstake. |
Note: unstaked delegated tokens will be held by the central staking contract for a period of time (the rest of the current epoch plus all of the next epoch) before they are released to the token holder. Once the tokens are released (unstaked), they can be claimed via the Withdraw Unstaked Tokens action below.
Withdraw Unstaked Tokens
After delegated tokens become unstaked, the token holder can withdraw them from the central staking contract.
To withdraw unstaked tokens via the NodeDelegatorProxy
,
the token holder can use the Withdraw Unstaked FLOW (TH.23)
transaction with the following arguments:
Argument | Type | Description |
---|---|---|
amount | UFix64 | The number of unstaked FLOW tokens to withdraw. |
This transaction moves the unstaked tokens back into the LockedTokens.TokenManager
owned by the token holder.
Withdraw Rewarded Tokens
After earning rewards from delegation, the token holder can withdraw them from the central staking contract.
To withdraw rewarded tokens via the NodeDelegatorProxy
,
the token holder can use the Withdraw Rewarded FLOW (TH.24)
transaction with the following arguments:
Argument | Type | Description |
---|---|---|
amount | UFix64 | The number of rewarded FLOW tokens to withdraw. |
This transaction moves the rewarded tokens back into the LockedTokens.TokenManager
owned by the token holder.
However, unlike unstaked tokens, rewards are unlocked FLOW and can be immediately withdrawn from the lockbox.
Query a Delegator Record
To return a struct with all the information associated with a delegator, anyone can use the Get Delegator Info (TH.21) script with the following arguments:
Argument | Type | Description |
---|---|---|
nodeID | String | The 32 byte ID of the node of the delegator |
nodeID | UInt8 | The ID of the delegator |
This script returns a FlowIDTableStaking.DelegatorInfo
struct.
Delegate to Multiple Nodes from the Same Account
Currently, the LockedTokens
contract only supports token holders delegating to a single node.
If a token holder wants to create a second delegation relationship, they must create a new account and transfer their locked tokens to the new account by requesting authorization from the token admin.
We plan on adding functionality in the future to allow accounts to delegate to multiple nodes.