Staking Transactions
Staking is a fundamental mechanism for participating in and securing the network. By locking up tokens or assets in a stake, users can engage in various network activities. The @ocap/client
provides a suite of helper methods to simplify staking operations, covering the entire lifecycle from creation to revocation and claiming.
These operations are crucial for functionalities like validator participation in an ArcBridge or other scenarios requiring a security deposit. Before diving in, you may want to review the core concepts of Tokens and NFTs.
The typical lifecycle of a stake involves creation, followed by either a successful revocation and claim, or a slash event due to rule violations.
This guide details how to use the client to perform the primary staking transactions: StakeTx
, RevokeStakeTx
, ClaimStakeTx
, and SlashStakeTx
.
Create a Stake#
The client.stake
method creates a new stake, locking specified assets and tokens to a receiver address. The stake itself is a new on-chain entity with its own unique address, derived from the creator, receiver, and a nonce.
This transaction often requires multi-party signatures if the stake's inputs come from multiple owners, but the helper method simplifies this for the common case where one wallet stakes for a receiver.
Parameters
Name | Type | Description |
---|---|---|
|
| The DID address of the account receiving the stake. |
|
| An optional array of asset addresses to be included in the stake. |
|
| An optional array of token objects to be staked. Each object is |
|
| Optional. If |
|
| Optional. A list of DID addresses authorized to slash this stake. Defaults to the receiver's address ( |
|
| Optional. A message or note to attach to the stake. |
|
| Optional. A unique string used to generate the stake address. It is recommended to use a timestamp or a random string. |
|
| The wallet object of the account creating the stake. |
Example
import Client from '@ocap/client';
import { fromTokenToUnit } from '@ocap/util';
const client = new Client('https://beta.abtnetwork.io/api');
const senderWallet = Wallet.fromJSON(senderWalletJson); // The staker's wallet
async function createNewStake() {
try {
const stakeNonce = Date.now().toString();
const receiverAddress = 'z1...'; // The address that will benefit from the stake
const [txHash, stakeAddress] = await client.stake({
to: receiverAddress,
tokens: [{
address: 'z3t...', // Address of the token to stake
value: fromTokenToUnit('100', 18).toString(), // Stake 100 tokens with 18 decimals
}],
message: 'Staking for validator node',
nonce: stakeNonce,
wallet: senderWallet,
});
console.log('Stake creation transaction sent:', txHash);
console.log('New stake address:', stakeAddress);
} catch (error) {
console.error('Error creating stake:', error);
}
}
createNewStake();
Example Response
[
"0x...transaction_hash...",
"z2...stake_address..."
]
This example demonstrates creating a stake with 100 secondary tokens for a specified receiver. The method returns the transaction hash and the newly generated stake address, which is required for subsequent operations like revoking or slashing.
Revoke a Stake#
The client.revokeStake
method initiates the process of withdrawing assets and tokens from a stake. This is typically done by the original staker when the purpose of the stake is fulfilled.
Parameters
Name | Type | Description |
---|---|---|
|
| The address of the stake to be revoked. This is the |
|
| An optional array of asset addresses to be withdrawn from the stake. |
|
| An optional array of token objects to be withdrawn. |
|
| The wallet object of the account initiating the revocation (usually the original staker). |
Example
import Client from '@ocap/client';
import { fromTokenToUnit } from '@ocap/util';
const client = new Client('https://beta.abtnetwork.io/api');
const senderWallet = Wallet.fromJSON(senderWalletJson);
const stakeAddress = 'z2...stake_address...'; // The address from the createStake example
async function revokeExistingStake() {
try {
const txHash = await client.revokeStake({
from: stakeAddress,
tokens: [{
address: 'z3t...', // Address of the token to revoke
value: fromTokenToUnit('100', 18).toString(),
}],
wallet: senderWallet,
});
console.log('Stake revocation transaction sent:', txHash);
// Note: A waiting period might apply before the stake can be claimed.
} catch (error) {
console.error('Error revoking stake:', error);
}
}
revokeExistingStake();
Example Response
"0x...transaction_hash..."
This example creates a RevokeStakeTx
. After this transaction is confirmed and any required waiting period has passed, the staker must send a ClaimStakeTx
to finalize the withdrawal.
Claim a Stake#
The client.claimStake
method finalizes the withdrawal process after a stake has been successfully revoked. It requires evidence of the revocation, which is the hash of the RevokeStakeTx
.
Parameters
Name | Type | Description |
---|---|---|
|
| The address of the stake from which to claim. |
|
| The transaction hash of the successful |
|
| The wallet object of the account claiming the funds (the original staker). |
Example
import Client from '@ocap/client';
const client = new Client('https://beta.abtnetwork.io/api');
const senderWallet = Wallet.fromJSON(senderWalletJson);
const stakeAddress = 'z2...stake_address...';
const revokeTxHash = '0x...revoke_transaction_hash...'; // The hash from the revokeStake example
async function claimRevokedStake() {
try {
const txHash = await client.claimStake({
from: stakeAddress,
evidence: revokeTxHash,
wallet: senderWallet,
});
console.log('Stake claim transaction sent:', txHash);
} catch (error) {
console.error('Error claiming stake:', error);
}
}
claimRevokedStake();
Example Response
"0x...transaction_hash..."
Once this transaction is confirmed, the specified assets and tokens are returned to the original staker's account.
Slash a Stake#
The client.slashStake
method is used to penalize a stake, typically for violating network rules. This action can only be performed by an address designated as a slasher
during the stake's creation.
Parameters
Name | Type | Description |
---|---|---|
|
| The address of the stake to be slashed. |
|
| A mandatory message explaining the reason for the slash. |
|
| An optional array of asset addresses to be slashed. |
|
| An optional array of token objects to be slashed. |
|
| The wallet of the authorized |
Example
import Client from '@ocap/client';
import { fromTokenToUnit } from '@ocap/util';
const client = new Client('https://beta.abtnetwork.io/api');
const slasherWallet = Wallet.fromJSON(slasherWalletJson); // Wallet of an authorized slasher
const stakeAddress = 'z2...stake_address...';
async function slashOffendingStake() {
try {
const txHash = await client.slashStake({
from: stakeAddress,
reason: 'Validator missed too many blocks.',
tokens: [{
address: 'z3t...',
value: fromTokenToUnit('10', 18).toString(), // Slash 10 tokens
}],
wallet: slasherWallet,
});
console.log('Slash stake transaction sent:', txHash);
} catch (error) {
console.error('Error slashing stake:', error);
}
}
slashOffendingStake();
Example Response
"0x...transaction_hash..."
This example slashes 10 tokens from the specified stake. The slashed funds are typically sent to a pre-configured vault address on the chain.
These methods provide the complete toolkit for managing staking on the blockchain. You can build complex systems that rely on staking for security and governance.
Next, you can explore transactions related to ArcBridge, which often utilize staking for validator management.
Next Steps: ArcBridge Transactions