Stake Account
https://solana.com/docs/economics/staking/stake-accounts
Solana 上的质押账户可用于将代币委托给网络上的验证者,从而可能为质押账户的所有者赚取奖励。质押账户的创建和管理方式与传统钱包地址(称为system account)不同。
system account只能从网络上的其他账户发送和接收 SOL,而 stake account 支持管理代币委托所需的更复杂的操作。
Solana 上的质押账户的工作方式也与您可能熟悉的其他权益证明区块链网络不同。
本文档介绍了 Solana 质押账户的高级结构和功能。
/// An account and a stake state deserialized from the account.
/// Generic type T enforces type-safety so that StakeAccount<Delegation> can
/// only wrap a stake-state which is a Delegation; whereas StakeAccount<()>
/// wraps any account with stake state.
#[derive(Clone, Debug, Default)]
pub struct StakeAccount<T> {
account: AccountSharedData,
stake_state: StakeStateV2,
_phantom: PhantomData<T>,
}
pub enum StakeStateV2 {
#[default]
Uninitialized,
Initialized(Meta),
Stake(Meta, Stake, StakeFlags),
RewardsPool,
}
pub struct Meta {
pub rent_exempt_reserve: u64,
pub authorized: Authorized,
pub lockup: Lockup,
}
pub struct Stake {
pub delegation: Delegation,
/// credits observed is credits from vote account state when delegated or redeemed
pub credits_observed: u64,
}
pub struct StakeFlags {
bits: u8,
}
pub struct Delegation {
/// to whom the stake is delegated
pub voter_pubkey: Pubkey,
/// activated stake amount, set at delegate() time
pub stake: u64,
/// epoch at which this stake was activated, std::Epoch::MAX if is a bootstrap stake
pub activation_epoch: Epoch,
/// epoch the stake was deactivated, std::Epoch::MAX if not deactivated
pub deactivation_epoch: Epoch,
/// how much stake we can activate per-epoch as a fraction of currently effective stake
#[deprecated(
since = "1.16.7",
note = "Please use `solana_sdk::stake::state::warmup_cooldown_rate()` instead"
)]
pub warmup_cooldown_rate: f64,
}
账户地址
每个 stake account 都有一个唯一的地址,可用于在命令行或任何网络浏览器工具中查找账户信息。但是,与钱包地址(地址的密钥对持有者控制钱包)不同,与 stake account 地址关联的密钥对不一定对账户有任何控制权。事实上, stake account 地址甚至可能不存在密钥对或私钥。
stake account 地址唯一具有密钥对文件的情况是 使用命令行工具创建质押账户时。首先会创建一个新的密钥对文件,以确保 stake account 地址是新的且唯一的。
理解account authority#
某些类型的账户可能具有与给定账户关联的一个或多个 signing authorities 。account authority用于为其控制的账户签署某些交易。这与其他一些区块链网络不同,在这些网络中,与账户地址关联的密钥对的持有者控制着账户的所有活动。
每个 stake account 都有两个由各自地址指定的signing authorities,每个签名权限都被授权对 stake account 执行某些操作。
pub struct Authorized {
pub staker: Pubkey,
pub withdrawer: Pubkey,
}
pub enum StakeAuthorize {
Staker,
Withdrawer,
}
stake authority 用于签署以下操作的交易:
- 委托股权- Delegating stake
- 停用权益委托 - Deactivating the stake delegation
- 拆分质押账户,用第一个账户中的部分资金创建一个新的质押账户- Splitting the stake account, creating a new stake account with a portion of the funds in the first account
- 将两个权益账户合并为一个- Merging two stake accounts into one
- 设定新的权益权限- Setting a new stake authority
withdraw authority 机构签署以下交易:
- 将未委托的质押提现到钱包地址 - Withdrawing un-delegated stake into a wallet address
- 设置新的提现权限 - Setting a new withdraw authority
- 设定新的权益权限 - Setting a new stake authority
stake authority 和 withdraw authority 在创建 stake account 时设置,可随时修改以授权新的签名地址,stake authority 和 withdraw authority 可以是同一个地址,也可以是两个不同的地址。
The withdraw authority keypair 对账户拥有更多的控制权,因为需要用它清算质押账户中的代币,并且如果 stake authority keypair 丢失或被泄露,可以用它来重置 stake authority。
在管理 stake account 时,确保 withdraw authority 免遭丢失或盗窃是至关重要的。
Multiple Delegations #
每个stake account 一次只能用于委托给一个validator。账户中的所有代币要么已委托 (delegated),要么未委托(un-delegated),要么正在委托或未委托(in the process of becoming delegated or un-delegated.)。要将部分代币委托给验证者,或委托给多个验证者,您必须创建多个质押账户。
这可以通过从包含一些代币的钱包地址创建多个 stake accounts 来实现,或者通过创建单个 large stake account 并使用 stake authority 将该账户拆分为多个具有您选择的代币余额的账户来实现。
相同的 stake and withdraw authorities 可以分配给多个 stake accounts。
Merge stake accounts
两个具有相同 authorities 和 lockup 的 stake account 可以合并为一个 stake account。以下状态下的两个 stake account 可以合并,无需任何附加条件:
- two deactivated stakes
- an inactive stake into an activating stake during its activation epoch
对于以下情况,观察到的投票者公钥和投票信用必须匹配:
- 两个激活的stake - two activated stakes
- 在激活时期,两个共享激活时期的激活账户 - two activating accounts that share an activation epoch, during the activation epoch
所有其他stake状态组合都将无法合并,包括所有"瞬时(transient)"状态,其中stake通过非零有效stake 激活或停用。
Delegation Warmup and Cooldown
当 stake account 被 delegated 或委托被停用(a delegation is deactivated)时,该操作不会立即生效。
委托或停用需要几个epochs 才能完成,在包含指令的交易提交给集群后,每个时期边界上的一部分委托将变为活动或非活动状态。
单个时期内委托或停用的总stake也有限制,以防止整个网络的stake突然发生大幅度变化。由于warmup和cooldown取决于其他网络参与者的行为,因此很难预测它们的确切持续时间。有关预热和冷却时间的详细信息,请点击 此处。
Lockups
Stake accounts可以锁定,以防止在特定日期或时期之前提取其持有的代币。
锁定期间,stake account 仍可委托、取消委托或拆分,其stake authority可正常更改。仅不允许提取到另一个钱包或更新提取权限。
stake account 余额在指定时间之前不可提取。锁定被指定为一个epoch height,即除非交易也由指定的custodian签署,否则网络在stake account余额可提取之前必须达到的最小epoch heigth。
锁仓仅可在首次创建质押账户时添加,但稍后可由 lockup authority 或 托管人(custodian) 进行修改,其地址也是在创建账户时设置的。
pub struct Lockup {
/// UnixTimestamp at which this stake will allow withdrawal, unless the
/// transaction is signed by the custodian
pub unix_timestamp: UnixTimestamp,
/// epoch height at which this stake will allow withdrawal, unless the
/// transaction is signed by the custodian
pub epoch: Epoch,
/// custodian signature on a transaction exempts the operation from
/// lockup constraints
pub custodian: Pubkey,
}
销毁stake account #
与 Solana 网络上的其他accounts类型一样,余额为 0 SOL 的 stake account 将不再被跟踪。
如果stake account未被委托,且其中包含的所有代币都被提取到钱包地址,则该地址的帐户实际上已被销毁,需要手动重新创建才能再次使用该地址。
查看stake accounts #
通过将帐户地址复制并粘贴到搜索栏中,您可以在Solana Explorer上查看质押帐户的详细信息 。