IB-Anchor-Stake

Gabrielle Lv5

什么是质押?

将我们的 SOL 或者其他 TOKNES 进行锁定,并赚取收益

为什么要质押

对用户来说

  • 赚取收益
  • 参与共识网络

对平台来说

  • PoS(Proof of Stake)网络中 validators 负责交易确认和区块制作,他们的权重由质押决定。这样有助于创建更安全的共识网络(详见:https://solanabeach.io/validators)
  • 类似于央行,平台通过控制质押收益控制 TOKEN 流动性,从而控制价值

质押的方式

  • 网络级别的质押(Staking for Network Security)
    • Native Staking on Solana
      • Stake account
      • Validator
    • Liquid Staking: Stake Pools
      • 验证节点列表(Validator list account)
      • 质押池(Stake Pool)
        • Mint Account
          • liquidity token 是质押的凭证
        • Reserve stake account 用于持有未授权的质押
  • 应用级别的质押(Application-Level Staking)

Native Staking

ID

Stake11111111111111111111111111111111111111

文档

https://solana.com/docs/references/staking

https://docs.solanalabs.com/cli/examples/delegate-stake

角色

  • User Wallet: 用户通过质押账户进行质押
  • Validator:validator 通过 vote account 接收质押

图1

质押的收益

收益模型

图2

从哪里寻找 Validator

如何实现 native staking

Method 1 - 使用钱包

Phantom and Solflare 都原生支持质押

Method 2 - 使用 Solana CLI

Step-01: 启动本地测试验证器

1
solana-test-validator

Step-02: 创建质押账户

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 生成新的密钥对(存储在 stake-account.json)
solana-keygen new --no-passphrase -s -o stake-account.json

# 创建质押账户(使用 stake-account.json 密钥对文件),并质押 100 SOL
# /// 如果不执行 solana-keygen new 命令,会自动生成新的密钥对 stake-account.json,并用其创建质押账户
solana create-stake-account stake-account.json 100
# 指定连接的 Solana 集群(localhost 为本地测试验证器)
# --url localhost

# 设置质押操作权限,默认为新质押账户自身
# --stake-authority wallet.json \

# 设置资金提取权限,默认为新质押账户自身
# --withdraw-authority wallet.json \

# 提供「创建质押账户所需的资金(质押金额 + 质押账户本身存在的存储费用)」的账户,默认为当前默认钱包
# --from wallet.json \

# 支付「交易本身的网络手续费」的账户,默认为当前默认钱包
# --fee-payer wallet.json \

# 查看质押账户状态
solana stake-account stake-account.json
  • --stake-authority: 有委托质押、拆分、合并质押账户权限的 key pair
  • --withdraw-authority: 有提现权限的 key pair

Step-03: 进行委托(delegate)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 查询连接到「​​本地测试验证器​」的所有验证节点信息,关注 Vote Account
solana validators -u localhost

# 将质押账户委托给指定的验证节点​(Vote Account)
solana delegate-stake stake-account.json <VOTE_ACCOUNT>
# --url localhost
# --stake-authority wallet.json \
# --withdraw-authority wallet.json \
# --fee-payer wallet.json \

# 添加交易备注,并存储到区块链上
# --with-memo "Delegating stake test."

solana stake-account stake-account.json

Step-04: 取消质押

1
2
3
4
5
6
solana deactivate-stake stake-account.json
# --url localhost \
# --stake-authority wallet.json \
# --fee-payer wallet.json \

solana stake-account stake-account.json

Step-05: 提现(withdraw)

1
2
3
4
5
6
7
solana withdraw-stake stake-account.json <DESTINATION> <AMOUNT>
# --url localhost \
# --withdraw-authority wallet.json \
# --fee-payer wallet.json \

# 全部提现后 stake account 即被销毁
solana stake-account stake-account.json

Method 3 - Staking SOL with Solana’s JavaScript API

Step-01: 创建质押账户

1
2
3
4
5
6
const transaction = StakeProgram.createAccount({
fromPubkey: wallet.publicKey,
stakePubkey: stakeAccount.publicKey,
authorized: new Authorized(wallet.publicKey, wallet.publicKey),
lamports: 10 * LAMPORTS_PER_SOL
});

Step-02: 进行委托

1
2
3
4
5
6
7
const validatorVoteAccount = new PublicKey("YOUR_VALIDATOR_VOTE_ACCOUNT");

const transaction = StakeProgram.delegate({
stakePubkey: stakeAccount.publicKey,
authorizedPubkey: wallet.publicKey,
votePubkey: validatorVoteAccount
});

Native Staking 拓展

流动性质押(Liquid Staking)

  1. 在 native stake 中,质押了 SOL 之后,这部分 SOL 就被冻结无法参与交易
  2. 流动性质押中,质押了 SOL 之后,staker 将获得 proxy token (liquid stake pool token)。这些 token 我们可以用来 swap、trade、transfer

收益

假设质押池初始时 1sol=1token,经过一定的 epoch 后 1sol=0.5token,此时 1token=2sol

h:400

流动性质押(Liquid Staking)

Solana Stake Pool Program

Solana Stake Pool 是一个标准质押池,实现了 validator 分配策略、费用、从池中委托/提取资金的指令

ID

SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy

官方文档:Solana Stake Pool Program Documentation

角色

  • Pool Manager:质押池的管理员及相关角色
  • User Wallet:用户通过质押账户质押或者直接质押 SOL
  • Validator List:验证节点列表,validator 通过 vote account 接收质押

图3

Solana Stake Pool Program

热门流动性质押池

NameToken
MarinademSOL
LidostSOL
JitojitoSOL
JpooljSOL
Blaze StakebSOL
SoceanscnSOL

从哪里可以找到质押池

【管理员】如何创建质押池

用户费用(管理员收益)

质押池程序允许管理者为质押池配置多种类型的费用:

费用类型说明
SOL Deposit用户向质押池存入 SOL 时收取的百分比费用
Stake Deposit用户将质押账户委托给质押池时收取的百分比费用
SOL Withdrawal用户从质押池提取 SOL 时收取的百分比费用
Stake Withdrawal用户向已激活的质押账户提取 SOL 时收取的百分比费用
Epoch (Stake Reward)每个纪元(Epoch)结束时,从质押池收益中收取的百分比费用
Referral (推荐佣金)分配给合作伙伴应用或钱包的存款费百分比

【管理员】如何创建质押池

使用 spl-stake-pool

Step-01: 启动本地环境

1
2
3
4
5
6
7
8
9
solana-test-validator \
--clone-upgradeable-program SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy \
--clone-upgradeable-program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s \
--url mainnet-beta \
--slots-per-epoch 32 \
--quiet --reset

solana config set --url http://127.0.0.1:8899
solana config set --commitment confirmed
  • 克隆两个可升级程序(SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy 和 metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s)
  • 指定使用主网(mainnet-beta)的配置
  • 设置每个 epoch 的槽数为 32
  • 以安静模式运行
  • 在启动前重置

Step-02: 创建质押池

1
2
3
4
5
6
7
8
9
spl-stake-pool create-pool \
--epoch-fee-denominator 100 \
--epoch-fee-numerator 2 \
--max-validators 10 \
--withdrawal-fee-denominator 1000 \
--withdrawal-fee-numerator 1 \
--deposit-fee-numerator 3 \
--deposit-fee-denominator 1000 \
--referral-fee 0

必填参数

  • --epoch-fee-denominator: 管理手续费的分母。如果设置成 100,所有费用都是百分数
  • --epoch-fee-numerator: 管理手续费的分子。如果 validator 收 8%,stake pool 收 2%,对于 100SOL 的奖励,用户到手 90.16 SOL
  • --max-validators: stake pool 中最大的 validator 数量

其他参数

  • --withdrawal-fee-[denominator|numerator]: 提现的手续费
  • --deposit-fee-[denominator|numerator]: 质押的手续费
  • --referral-fee:介绍费
  • --manager <KEYPAIR>: stake pool 的管理员 [default: cli config keypair]

所有的账户地址我们都可以指定,不指定的话会创建新的地址

  • --pool-keypair <PATH>: stake pool
  • --validator-list-keypair <PATH>: validator list
  • --mint-keypair <PATH>: mint 账户使用的 keypair [default: new keypair]
  • --reserve-keypair <PATH>: pool reserve stake account

查看质押池

1
spl-stake-pool list -v <YOUR_STAKE_POOL_ADDRESS>
  • Stake Pool Account: 质押池
  • Validator List Account: 验证节点列表
  • Reserve Stake Account: 持有还没有质押的 sol,可以通过 rebalance 的方式质押给 validator
  • Pool Token Mint Account: SPL token 的 mint account,代表着流动性质押置换的 token
  • Pool Fee Collection Account: 为 manager 持有交易费

图4

图5

【管理员】如何修改质押池

修改 manager

1
spl-stake-pool set-manager [FLAGS] [OPTIONS] <POOL_ADDRESS> <--new-manager <KEYPAIR>|--new-fee-receiver <ADDRESS>>

修改费用

1
spl-stake-pool set-fee [FLAGS] [OPTIONS] <POOL_ADDRESS> <FEE_TYPE> <NUMERATOR> <DENOMINATOR>

修改 staker

1
spl-stake-pool set-staker [FLAGS] [OPTIONS] <POOL_ADDRESS> [ADDRESS]

添加 validator

1
2
3
4
5
solana validators -u localhost

spl-stake-pool add-validator <YOUR_STAKE_POOL_ADDRESS> <VOTE_ACCOUNT_ADDRESS>

spl-stake-pool list -v <YOUR_STAKE_POOL_ADDRESS>

流动性质押的全流程

​【​用户】存款(Deposit)​​

用户向质押池存入 SOL

​​关键费用​​:扣除存款费(示例:3/1000)

sequenceDiagram
  User->>+Deposit Authority: 提交存款请求
  Deposit Authority->>Token Program: 铸造流动性质押代币
  Token Program->>User Wallet: 发放质押代币(如 stSOL)
  Deposit Authority->>Reserve Stake Account: 存入 SOL

【管理员】​​资金分配(Allocation)​​

管理者(Manager)将资金分配到验证节点

​​容量控制​​:验证者数量 ≤ max-validators(10)

sequenceDiagram
  Manager->>Staker: 分配指令
  Staker->>Stake Program: 创建质押账户
  Reserve Stake Account->>Validator Stake Account: 转移 SOL
  Stake Program->>Vote Program: 委托给验证节点

​【管理员】​收益生成(Rewards)​​

验证节点产生质押奖励

sequenceDiagram
  Validator Node->>Validator Stake Account: 累积奖励
  Stake Program->>Fee Account: 扣除 epoch-fee(2%)

​​【用户】提取(Withdrawal)​​

用户销毁质押代币提取 SOL

sequenceDiagram
  User->>Withdraw Authority: 提现请求
  Withdraw Authority->>Token Program: 销毁质押代币
  Withdraw Authority->>User Wallet: 支付 SOL
  Withdraw Authority->>Fee Account: 扣除 withdrawal-fee(0.1%)

【管理员】​​资金调配(Rebalance)​​

根据需求调整质押分布:

  • 新存款 → Reserve → 新增验证节点
  • 大额提现 → 解质押 → Reserve → 支付用户

如何进行流动性质押

Method 1 - web 界面

Method 2 - 使用 Solana CLI

【用户】使用质押账户质押

切换下身份

1
2
3
4
5
solana config set -k ./user.json

solana address -k user.json

solana airdrop 100 <ADDRESS>

使用新身份进行质押质押 stake account

1
2
3
4
5
solana create-stake-account stake-account.json 100 

solana delegate-stake stake-account.json <VOTE_ACCOUNT>

spl-stake-pool deposit-stake <POOL_ADDRESS> <STAKE_ACCOUNT_ADDRESS> [ADDRESS]

质押后的效果

  • SOL Balance Change

    • user account ⬇️
    • reverse account SOL ⬆️
  • Token Balance Change

    • user token ⬆️
    • manager token ⬆️ (3/1000)

【用户】使用质押账户提现

1
2
3
spl-stake-pool withdraw-stake <POOL_ADDRESS> <AMOUNT>
# --stake-receiver <STAKE_ACCOUNT_ADDRESS> # 要接收的 stake account,不指定的话会创建新的
# --vote-account <VOTE_ACCOUNT_ADDRESS> # 默认会从最多余额的 validator 中提现

提现后的效果

  • SOL Balance Change

    • user account ⬇️
    • reverse account SOL ⬆️
  • Token Balance Change

    • user token ⬆️
    • manager token ⬆️(3/1000)

【用户】直接质押 SOL

切换下身份

1
2
3
4
5
6
7
solana-keygen new --no-passphrase -s -o user.json 

solana config set -k ./user.json

solana address -k user.json

solana airdrop 100 <ADDRESS>

使用新身份进行质押 SOL

1
spl-stake-pool deposit-sol <YOUR_STAKE_POOL_ADDRESS>  20

质押后的效果

  • SOL Balance Change

    • user account ⬇️
    • reverse account SOL ⬆️
  • Token Balance Change

    • user token ⬆️
    • manager token ⬆️ (3/1000)

【管理员】rebalance

1
2
3
4
5
solana config set -k ~/.config/solana/id.json

spl-stake-pool increase-validator-stake <YOUR_STAKE_POOL_ADDRESS> <VOTE_ACCOUNT_ADDRESS> [AMOUNT]

spl-stake-pool list -v <YOUR_STAKE_POOL_ADDRESS>

spl 会在下一个 epoch 进行质押

许多操作都会触发 update 的操作,如果没有触发可以手动触发

1
2
3
4
5
6
7
solana epoch-info

spl-stake-pool list -v <YOUR_STAKE_POOL_ADDRESS>

spl-stake-pool update <YOUR_STAKE_POOL_ADDRESS>

spl-stake-pool list -v <YOUR_STAKE_POOL_ADDRESS>

【用户】直接提现 SOL

1
spl-stake-pool withdraw-sol <YOUR_STAKE_POOL_ADDRESS> ./user.json <AMOUNT>

spl-stake-pool

manager 的工作

  • spl-stake-pool create-pool 创建质押池
  • spl-stake-pool create-token-metadata 设置 token 的 metadata(symbol、name)
  • spl-stake-pool set-xx 修改质押池
  • spl-stake-pool add-validator 添加 validator
  • spl-stake-pool update 定时更新质押池
  • spl-stake-pool increase-validator-stake/decrease-validator-stake 调整各 validator 的质押金额

user 的工作

  • spl-stake-pool deposit-sol 质押 sol
  • spl-stake-pool withdraw-sol 提现 sol
  • spl-stake-pool deposit-stake 质押到质押账户
  • spl-stake-pool withdraw-stake 提现到质押账户

Stake Pool 的实现原理

应用级别质押

图6

参考资料

  • Title: IB-Anchor-Stake
  • Author: Gabrielle
  • Created at : 2025-07-20 18:54:17
  • Updated at : 2025-07-31 22:36:43
  • Link: https://zoella-w.github.io/2025/07/20/96-IB-Anchor-Stake/
  • License: This work is licensed under CC BY-NC-SA 4.0.
On this page
IB-Anchor-Stake