Aleo Staking & Delegation
1. Overview
All staking, delegation, and credit transfer operations on Aleo are handled by the credits.aleo system program. This skill covers the complete function reference, staking mechanics, and operational workflows.
Version & Canonical Syntax
- Target: Leo compiler >= 3.5.0 and current
credits.aleointerface on active Aleo networks - Canonical syntax: CLI examples assume
leo execute credits.aleo <function> ... --broadcastcommand forms - Amount formatting: Credit amounts are expressed in microcredits as
u64literals - When docs conflict: Prefer current network docs and
leo execute credits.aleo --helpoutput
2. Key Concepts & Glossary
- Validator: A node that participates in consensus. Must self-bond a minimum of 100 credits and attract 10,000,000 total delegated credits to join the committee.
- Delegator/Staker: A user who bonds credits to a validator. Minimum 10,000 credits per delegation.
- Committee: The set of validators actively participating in consensus.
- Commission: A percentage of rewards taken by the validator. Set once when first bonding and immutable thereafter.
- Withdrawal Address: The address authorized to unbond/withdraw credits. Can be different from the staking address.
- Unbonding Period: 360 blocks (~1 hour) between requesting unbond and claiming credits.
- credits.aleo: The system program that manages all credit operations.
3. Staking Parameters
| Parameter | Value |
|---|---|
| Minimum validator self-bond | 100 credits |
| Minimum total delegation to join committee | 10,000,000 credits |
| Minimum delegation per delegator | 10,000 credits |
| Maximum delegators per validator | 100,000 |
| Unbonding period | 360 blocks (~1 hour) |
| Commission rate | Set once, immutable |
4. credits.aleo Function Reference
Credit Transfer Functions
| Function | Description | Example CLI |
|---|---|---|
transfer_public | Transfer public credits between addresses | leo execute credits.aleo transfer_public "aleo1receiver..." "1000000u64" |
transfer_private | Transfer private credits (record-to-record) | leo execute credits.aleo transfer_private <record> "aleo1receiver..." "1000000u64" |
transfer_public_to_private | Convert public to private credits (shielding) | leo execute credits.aleo transfer_public_to_private "aleo1receiver..." "1000000u64" |
transfer_private_to_public | Convert private to public credits (unshielding) | leo execute credits.aleo transfer_private_to_public <record> "aleo1receiver..." "1000000u64" |
join | Combine two credit records into one | leo execute credits.aleo join <record1> <record2> |
split | Split one credit record into two | leo execute credits.aleo split <record> "500000u64" |
Fee Functions
| Function | Description |
|---|---|
fee_public | Pay transaction fee from public balance |
fee_private | Pay transaction fee from a private credit record |
Staking Functions
| Function | Description |
|---|---|
bond_validator | Validator self-bond (min 100 credits) |
bond_public | Delegate credits to a validator (min 10,000 credits) |
unbond_public | Request unbonding (starts 360-block timer) |
claim_unbond_public | Claim credits after unbonding period |
set_validator_state | Toggle validator open/closed to delegators |
5. Delegation Workflow
Step 1: Bond (Delegate) Credits
bash
# Delegate 10,000 credits to a validator
leo execute credits.aleo bond_public \
"aleo1validator_address..." \
"aleo1your_withdrawal_address..." \
"10000000000u64" \
--broadcast
# Note: amount is in microcredits (10,000 credits = 10,000,000,000 microcredits)
Step 2: Check Delegation Status
bash
# Query the bonded mapping
leo query program credits.aleo --mapping-value bonded "aleo1your_address..."
Step 3: Unbond Credits
bash
# Request unbonding (starts 360-block timer)
leo execute credits.aleo unbond_public "10000000000u64" --broadcast
Step 4: Wait for Unbonding Period
bash
# Check unbonding status
leo query program credits.aleo --mapping-value unbonding "aleo1your_address..."
# Check current block height
leo query block --latest
Step 5: Claim After Unbonding
bash
# Claim unbonded credits (only after 360 blocks have passed)
leo execute credits.aleo claim_unbond_public --broadcast
6. Validator Setup Workflow
bash
# 1. Self-bond as a validator (minimum 100 credits)
leo execute credits.aleo bond_validator \
"aleo1your_withdrawal_address..." \
"100000000u64" \
10u8 \
--broadcast
# 10u8 = 10% commission rate (immutable after this call!)
# 2. Open for delegations
leo execute credits.aleo set_validator_state true --broadcast
# 3. Check committee membership
leo query program credits.aleo --mapping-value committee "aleo1your_address..."
7. On-Chain Mappings for Monitoring
| Mapping | Key | Value | Description |
|---|---|---|---|
committee | validator address | committee info | Active validators |
delegated | validator address | total delegated | Total credits delegated to validator |
bonded | staker address | bond info | Individual bond amounts |
unbonding | staker address | unbond info | Pending unbond requests |
withdraw | staker address | withdrawal address | Withdrawal address mapping |
metadata | validator address | metadata | Validator metadata |
Query example:
bash
leo query program credits.aleo --mapping-value committee "aleo1validator..."
leo query program credits.aleo --mapping-value bonded "aleo1staker..."
leo query program credits.aleo --mapping-value unbonding "aleo1staker..."
8. Common Errors and Fixes
| Error | Cause | Fix |
|---|---|---|
| Bonding less than 10,000 credits | Transaction rejected | Bond at least 10,000 credits (10,000,000,000 microcredits) |
| Using credits instead of microcredits | Wrong amount (1Mx too small) | 1 credit = 1,000,000 microcredits |
| Claiming before 360 blocks | Transaction rejected | Wait for unbonding period to complete |
| Wrong withdrawal address | Cannot unbond | Ensure withdrawal address matches when bonding |
| Changing commission rate | Impossible | Commission is immutable after bond_validator |
| Delegating to closed validator | Transaction rejected | Check set_validator_state first |
9. Security Notes
- Staking is public — all delegation amounts and validators are visible on-chain
- Withdrawal address controls unbonding — protect this key carefully
- Commission rate is permanent — choose carefully on first
bond_validator - Monitor validator uptime — poor performance may affect rewards
- Never share private keys used for staking
10. Performance Notes
- Batch status checks using scheduled polling intervals instead of per-block manual queries
- Cache validator metadata and only refresh committee/delegated mappings when new blocks arrive
- Keep delegation workflows idempotent in automation so retries do not emit duplicate transactions
- Prefer explicit unbond tracking keyed by height to avoid unnecessary failed
claim_unbond_publiccalls
- Credit transfers and fees: see
aleo_smart_contractsforcredits.aleointernals - Backend SDK for staking: see
aleo_backend - Deploy staking dashboards: see
aleo_frontend - Complete recipes: see
aleo_cookbook
12. Agent SOP: Staking Workflow
- Normalize units first: convert user-facing credits into
u64microcredits before building any command - Validate prerequisites: ensure validator state and withdrawal address assumptions are correct
- Execute one staking action at a time and record transaction IDs for auditability
- Query on-chain mappings after each step to confirm state transitions
- Enforce unbond timing by checking block height before any claim attempt
- On failure: map to the error matrix above and retry only after the underlying cause is resolved