From e4e500811e36e01ffbff85effb23e6b74d824bea Mon Sep 17 00:00:00 2001 From: capi Date: Tue, 11 Jun 2024 14:48:08 +0800 Subject: [PATCH 1/5] Docs: stake pool --- docs/SolanaProgramLibrary/stake-pool/cli.md | 599 ++++++++++++++++++ docs/SolanaProgramLibrary/stake-pool/fees.md | 79 +++ .../stake-pool/operation.md | 126 ++++ .../stake-pool/quickstart.md | 156 +++++ 4 files changed, 960 insertions(+) create mode 100644 docs/SolanaProgramLibrary/stake-pool/cli.md create mode 100644 docs/SolanaProgramLibrary/stake-pool/fees.md create mode 100644 docs/SolanaProgramLibrary/stake-pool/operation.md create mode 100644 docs/SolanaProgramLibrary/stake-pool/quickstart.md diff --git a/docs/SolanaProgramLibrary/stake-pool/cli.md b/docs/SolanaProgramLibrary/stake-pool/cli.md new file mode 100644 index 0000000..a4fcb32 --- /dev/null +++ b/docs/SolanaProgramLibrary/stake-pool/cli.md @@ -0,0 +1,599 @@ +# 命令行界面 +以下是使用命令行工具的Stake Pool程序中可用的指令,以及示例。 + +## 安装 +`spl-stake-pool`命令行工具可用于试验SPL代币。一旦你安装了[Rust](https://rustup.rs/),请运行: +``` +$ cargo install spl-stake-pool-cli +``` +运行 `spl-stake-pool --help` 以获取所有可用命令的完整描述。 + +## 配置 +`spl-stake-pool`配置与`solana`命令行工具共享。 + +### 当前配置 +``` +$ solana config get +Config File: ${HOME}/.config/solana/cli/config.yml +RPC URL: https://api.mainnet-beta.solana.com +WebSocket URL: wss://api.mainnet-beta.solana.com/ (computed) +Keypair Path: ${HOME}/.config/solana/id.json +``` +集群RPC URL +查看[Solana集群](https://docs.solana.com/clusters)以获取特定于集群的RPC URL + +``` +$ solana config set --url https://api.devnet.solana.com +``` +### 默认密钥对 +有关如何设置[密钥对](https://docs.solana.com/cli/conventions#keypair-conventions)的信息,请参见密钥对约定,如果你还没有密钥对。 + +密钥对文件 +``` +$ solana config set --keypair ${HOME}/new-keypair.json +``` +硬件钱包URL(见[URL规范](https://docs.solana.com/wallet-guide/hardware-wallets#specify-a-keypair-url)) + +$ solana config set --keypair usb://ledger/ +### 本地运行 +如果你想在不等待质押激活和停用的情况下本地测试质押池,你可以使用`solana-test-validator`工具运行质押池,缩短纪元,并从devnet拉取当前程序。 + +``` +$ solana-test-validator -c SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy -c EmiU8AQkB2sswTxVB6aCmsAJftoowZGGDXuytm6X65R3 --url devnet --slots-per-epoch 32 +$ solana config set --url http://127.0.0.1:8899 +``` +## 质押池管理者示例 +### 创建质押池 +质押池管理者从高层控制质押池,并作为交换以SPL代币的形式收取费用。管理者在创建时设置费用。让我们创建一个带有3%费用和最多1000个验证者质押账户的池: + +```$ spl-stake-pool create-pool --epoch-fee-numerator 3 --epoch-fee-denominator 100 --max-validators 1000 +$ spl-stake-pool create-pool --epoch-fee-numerator 3 --epoch-fee-denominator 100 --max-validators 1000 +Creating reserve stake DVwDn4LTRztuai4QeenM6fyzgiwUGpVXVNZ1mgKE1Pyc +Creating mint BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB +Creating associated token account DgyZrAq88bnG1TNRxpgDQzWXpzEurCvfY2ukKFWBvADQ to receive stake pool tokens of mint BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB, owned by 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn +Creating pool fee collection account DgyZrAq88bnG1TNRxpgDQzWXpzEurCvfY2ukKFWBvADQ +Signature: qQwqahLuC24wPwVdgVXtd7v5htSSPDAH3JxFNmXCv9aDwjjqygQ64VMg3WdPCiNzc4Bn8vtS3qcnUVHVP5MbKgL +Creating stake pool Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR +Signature: 5z6uH3EuPcujeWGpAjBtciSUR3TxtMBgWYU4ULagUso4QGzE9JenhYHwYthJ4b3rS57ByUNEXTr2BFyF5PjWC42Y +``` +质押池的唯一标识符是 `Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR。` + +质押池的SPL代币铸造标识符是 `BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB`。质押池对铸造有完全控制权。 + +池创建者的费用账户标识符是 `DgyZrAq88bnG1TNRxpgDQzWXpzEurCvfY2ukKFWBvADQ`。在每个纪元里,当质押池中的质押账户获得奖励时,程序会将相当于该纪元收益3%的SPL池代币铸造到这个账户。如果没有观察到收益,就什么都不会存入。 + +储备质押账户标识符是 `J5XB7mWpeaUZxZ6ogXT57qSCobczx27vLZYSgfSbZoBB`。此账户持有在验证者之间重新平衡时使用的额外质押。 + +对于有1000个验证者的质押池,创建质押池的成本不到0.5 SOL。 + +`create-pool`命令允许设置所有账户和密钥对为预先生成的值,包括: + +- 质押池,通过 `--pool-keypair` 标志 +- 验证者列表,通过 `--validator-list-keypair` 标志 +- 池子代币铸造,通过 `--mint-keypair` 标志 +- 池子储备质押账户,通过 `--reserve-keypair` 标志 + +否则,这些将默认为新生成的密钥对。 + +你可以随时运行 `spl-stake-pool create-pool -h` 来查看可用的选项。 + +### 创建受限质押池 +如果管理者希望将质押(质押和SOL)存款限制为特定的一个密钥,他们可以在创建时设置存款权限: + +``` +$ spl-stake-pool create-pool --epoch-fee-numerator 3 --epoch-fee-denominator 100 --max-validators 1000 --deposit-authority authority_keypair.json +Creating reserve stake DVwDn4LTRztuai4QeenM6fyzgiwUGpVXVNZ1mgKE1Pyc +Creating mint BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB +Creating associated token account DgyZrAq88bnG1TNRxpgDQzWXpzEurCvfY2ukKFWBvADQ to receive stake pool tokens of mint BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB, owned by 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn +Creating pool fee collection account DgyZrAq88bnG1TNRxpgDQzWXpzEurCvfY2ukKFWBvADQ +Signature: qQwqahLuC24wPwVdgVXtd7v5htSSPDAH3JxFNmXCv9aDwjjqygQ64VMg3WdPCiNzc4Bn8vtS3qcnUVHVP5MbKgL +Creating stake pool Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR +Deposits will be restricted to 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn only, this can be changed using the set-funding-authority command. +Signature: 5z6uH3EuPcujeWGpAjBtciSUR3TxtMBgWYU4ULagUso4QGzE9JenhYHwYthJ4b3rS57ByUNEXTr2BFyF5PjWC42Y +``` + +正如输出所说,`set-funding-authority` 可以用来修改或删除存款权威。 + +只要设置了存款权威,SOL和质押存款必须由 `4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn` 签名,所以没有其他人可以参与池。如前所述,这个特性不禁止提款,所以任何有池子代币的人仍然可以从池中提款。 + +### 设置管理者 +质押池管理者可以将他们的管理员权限传递给另一个账户。 + +``` +$ spl-stake-pool set-manager Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR --new-manager 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn +Signature: 39N5gkaqXuWm6JPEUWfenKXeG4nSa71p7iHb9zurvdZcsWmbjdmSXwLVYfhAVHWucTY77sJ8SkUNpVpVAhe4eZ53 +``` + +同时,他们还可以更改每个纪元接收费用的SPL代币账户。所提供代币账户的铸造必须是SPL代币铸造,在我们的例子中是 `BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB`。 +``` +$ spl-stake-pool set-manager Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR --new-fee-receiver HoCsh97wRxRXVjtG7dyfsXSwH9VxdDzC7GvAsBE1eqJz +Signature: 4aK8yzYvPBkP4PyuXTcCm529kjEH6tTt4ixc5D5ZyCrHwc4pvxAHj6wcr4cpAE1e3LddE87J1GLD466aiifcXoAY +``` + +### 设置费用 +质押池管理者可以更新与质押池相关的任何费用,需要传入构成费用比例的分子和分母。 + +对于10%的纪元费用,他们可以执行以下操作: +``` +$ spl-stake-pool set-fee Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR epoch 10 100 +Signature: 5yPXfVj5cbKBfZiEVi2UR5bXzVDuc2c3ruBwSjkAqpvxPHigwGHiS1mXQVE4qwok5moMWT5RNYAMvkE9bnfQ1i93 +``` + +为了保护质押池存款人免受恶意管理者的侵害,程序在跨越两个纪元的界限后才应用新的费用,提供了至少一个完整纪元的等待时间。 + +例如,如果在第100个纪元费用是1%,管理者将其设置为10%,管理者仍然会因为在第100和101个纪元赚取的奖励而获得1%的费用。从第102个纪元开始,管理者将获得10%的费用。 + +此外,为了防止恶意管理者立即将提款费用设置得非常高,从而使用户实际上无法提款,质押池程序目前每两个纪元界限强制执行最多增加1.5倍的限制。 + +例如,如果当前的提款费用是2.5%,可设置的最高费用是3.75%,将在两个纪元界限后生效。 + +费用类型可能的选项有`纪元费用`、`SOL提款费`、`质押提款费`、`SOL存款费`和`质押存款费`。 + +### 设置推荐费 +质押池管理者可以随时更新存款上的推荐费,传入一个百分比金额。 + +要设置80%的质押存款推荐费,他们可以执行以下操作: +``` +$ spl-stake-pool set-referral-fee Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR stake 80 +Signature: 4vhaBEDhuKkVwMxy7TpyfHEk3Z5kGZKerD1AgajQBdiMRQLZuNZKVR3KQaqbUYZM7UyfRXgkZNdAeP1NfvmwKdqb +``` +对于80%的推荐费,这意味着质押存款费用的20%归管理者所有,而80%归推荐人所有。 + +### 设置质押者 +为了管理质押账户,质押池管理者或质押者可以设置质押池管理账户的质押者权限。 + +``` +$ spl-stake-pool set-staker Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn +Signature: 39N5gkaqXuWm6JPEUWfenKXeG4nSa71p7iHb9zurvdZcsWmbjdmSXwLVYfhAVHWucTY77sJ8SkUNpVpVAhe4eZ53 +``` +现在,新的质押者可以执行任何正常的质押池操作,包括添加和移除验证者以及重新平衡质押。 + +重要的安全提示:质押池程序仅向质押池质押者授予质押权限,并始终保留提款权限。因此,恶意的质押池质押者无法从质押池中窃取资金。 + +注意:为了避免“打扰管理者”,质押者也可以重新分配他们的质押权限。 + +### 设置资金权限 +为了限制谁可以与池子交互,质押池管理者可能需要在质押存款、SOL存款或SOL提款上要求特定的签名。这并不会使得池子变得私有,因为所有信息都是在链上公开的,但它限制了谁可以使用池子。 + +例如,假设一个池子想要限制所有的SOL提款。 + +``` +$ spl-stake-pool set-funding-authority Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR sol-withdraw AZ1PgxWSxw4ezX8gvpNgGsr39jJHCwtkaXr1mNMwWWeK +Signature: 3gx7ckGNSL7gUUyxh4CU3RH3Lyt88hiCvYQ4QRKtnmrZHvAS93ebP6bf39WYGTeKDMVSJUuwBEmk9VFSaWtXsHVV +``` + +执行此命令后,`AZ1PgxWSxw4ezX8gvpNgGsr39jJHCwtkaXr1mNMwWWeK` 必须对所有的SOL提款进行签名,否则操作将失败。 + +过了一段时间后,如果管理者希望启用SOL提款,他们可以移除这个限制: +``` +$ spl-stake-pool set-funding-authority Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR sol-withdraw --unset +Signature: 5kWeBqoxyvANMHCP4ydsZRf8QU4hMotLnKkFbTEdvqEVywo4F3MpZtay7D57FbjJZpdp72fc3vrbxJi9qDLfLCnD +``` + +现在,只要储备中还有足够的SOL,任何人都可以从质押池中提取SOL。 + +资金权威选项有`sol-提款`、`sol-存款`和`质押存款`。 + +注意:限制质押提款是不可能的。这将为恶意池管理者提供机会,实际上锁定用户资金。 +## 质押池质押者示例 +### 向池中添加验证者 +为了适应大量用户向质押池存款,质押池只为每个验证者管理一个质押账户。要向质押池添加新的验证者,质押者必须使用`add-validator`命令。 + +用于向池中添加验证者的SOL来自质押池的储备账户。如果储备中的SOL不足,命令将失败。请确保使用`deposit-sol`命令将一些SOL转移到池中。 + +假设质押池中有10 SOL,让我们向质押池添加一些随机验证者。 + +``` +$ spl-stake-pool add-validator Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk +Adding stake account F8e8Ympp4MkDSPZdvRxdQUZXRkMBDdyqgHa363GShAPt, delegated to 38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk +Signature: 5tdpsx64mVcSHBK8vMbBzFDHnEZB6GUmVpqSXXE5hezMAzPYwZbJCBtAHakDAiuWNcrMongGrmwDaeywhVz4i8pi +``` +为了最大程度地提高审查抵抗能力,我们希望将我们的SOL分散到尽可能多的验证者那里,因此让我们再添加一些。 +``` +$ spl-stake-pool add-validator Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H +Adding stake account 5AaobwjccyHnXhFCd24uiX6VqPjXE3Ry4o92fJjqqjAr, delegated to J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H +Signature: 4xeve6gWuiffqBLAMcqa8s7dCMvBmSVdKbDu5WQhigLiXHdCjSNEwoZRexTZji786qgEjXg3nrUh4HcTt3RauZV5 +$ spl-stake-pool add-validator Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ +Adding stake account 3k7Nwu9jUSc6SNG11wzufKYoZXRFgxWamheGLYWp5Rvx, delegated to EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ +Signature: 4VJYHpPmWkP99TdgYUTgLYixmhqmqsEkWtg4j7zvGZFjYbnLgryu48aV6ub8bqDyULzKckUhb6tvcmZmMX5AFf5G +``` +我们可以使用Solana命令行工具查看质押账户的状态。 +``` +$ solana stake-account 5AaobwjccyHnXhFCd24uiX6VqPjXE3Ry4o92fJjqqjAr +Balance: 1.00228288 SOL +Rent Exempt Reserve: 0.00228288 SOL +Delegated Stake: 1 SOL +Active Stake: 0 SOL +Activating Stake: 1 SOL +Stake activates starting from epoch: 5 +Delegated Vote Account Address: J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H +Stake Authority: DS3AyFN9dF1ruNBcSeo8XXQR8UyVMhcCPcnjU5GnY18S +Withdraw Authority: DS3AyFN9dF1ruNBcSeo8XXQR8UyVMhcCPcnjU5GnY18S +``` +质押池创建了这些特殊的质押账户,其中1 SOL是所需的最低委托金额。质押和提款权限属于质押池提款权限,即从质押池地址派生的程序地址。 + +我们还可以看到质押池的状态。 +``` +$ spl-stake-pool list Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR +Stake Pool: Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR +Pool Token Mint: BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB +Epoch Fee: 3/100 of epoch rewards +Withdrawal Fee: none +Stake Deposit Fee: none +SOL Deposit Fee: none +SOL Deposit Referral Fee: none +Stake Deposit Referral Fee: none +Reserve Account: EN4px2h4gFkYtsQUi4yeCYBrdRM4DoRxCVJyavMXEAm5 Available Balance: ◎6.99315136 +Vote Account: EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ Balance: ◎1.002282880 Last Update Epoch: 4 +Vote Account: J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H Balance: ◎1.002282880 Last Update Epoch: 4 +Vote Account: 38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk Balance: ◎1.002282880 Last Update Epoch: 4 +Total Pool Stake: ◎10.000000000 +Total Pool Tokens: 10.00000000 +Current Number of Validators: 3 +Max Number of Validators: 1000 +``` +为了便于阅读,该工具不会显示质押池无法触及的余额。储备质押账户 `EN4px2h4gFkYtsQUi4yeCYBrdRM4DoRxCVJyavMXEAm5` 实际上还有额外的0.002282881 SOL余额,但由于这是最低要求金额,所以CLI不会显示。 + +### 移除验证者质押账户 +如果质押池的质押者想要停止向某个投票账户委托,他们可以完全从质押池中移除该验证者的质押账户。 + +和添加验证者一样,要移除的验证者质押账户必须恰好有1.00228288 SOL(1 SOL用于委托,0.00228288 SOL用于租金豁免)。 + +如果情况不是这样,质押者必须先将质押金额减少到这个最小数额。假设委托给`J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H`的验证者质押账户总共委托了7.5 SOL。为了减少这个数额,质押者可以执行以下操作: + +``` +$ spl-stake-pool decrease-validator-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H 6.5 +Signature: ZpQGwT85rJ8Y9afdkXhKo3TVv4xgTz741mmZj2vW7mihYseAkFsazWxza2y8eNGY4HDJm15c1cStwyiQzaM3RpH +``` + +好的,让我们尝试移除验证者`J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H`,其对应的质押账户是`5AaobwjccyHnXhFCd24uiX6VqPjXE3Ry4o92fJjqqjAr`。 +``` +$ spl-stake-pool remove-validator Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H +Removing stake account 5AaobwjccyHnXhFCd24uiX6VqPjXE3Ry4o92fJjqqjAr, delegated to J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H +Creating account to receive stake nHEEyey8KkgHuVRAUDzkH5Q4PkA4veSHuTxgG6C8L2G +Signature: 4XprnR768Ch6LUvqUVLTjMCiqdYvtjNfECh4izErqwbsASTGjUBz7NtLZHAiraTqhs7b9PoSAazetdsgXa6J4wVu +``` +与普通提款不同,验证者的质押账户将被停用,并在下一个纪元与储备账户合并。 + +我们可以检查正在停用的质押账户: +``` +$ solana stake-account nHEEyey8KkgHuVRAUDzkH5Q4PkA4veSHuTxgG6C8L2G +Balance: 1.002282880 SOL +Rent Exempt Reserve: 0.00228288 SOL +Delegated Stake: 1.000000000 SOL +Active Stake: 1.000000000 SOL +Stake deactivates starting from epoch: 10 +Delegated Vote Account Address: J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H +Stake Authority: 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn +Withdraw Authority: 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn +``` + +### 重新平衡质押池 +随着时间的推移,用户将向质押池管理的所有质押账户存款和提款,质押池的质押者可能希望重新平衡这些质押。 + +例如,假设质押者希望对池中的每个验证者进行相同数量的委托。当他们查看池的状态时,他们看到: +``` +$ spl-stake-pool list Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR +Stake Pool: Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR +Pool Token Mint: BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB +Epoch Fee: 3/100 of epoch rewards +Withdrawal Fee: none +Stake Deposit Fee: none +SOL Deposit Fee: none +SOL Deposit Referral Fee: none +Stake Deposit Referral Fee: none +Reserve Account: EN4px2h4gFkYtsQUi4yeCYBrdRM4DoRxCVJyavMXEAm5 Available Balance: ◎10.006848640 +Vote Account: EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ Balance: ◎100.000000000 Last Update Epoch: 4 +Vote Account: J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H Balance: ◎10.000000000 Last Update Epoch: 4 +Vote Account: 38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk Balance: ◎10.000000000 Last Update Epoch: 4 +Total Pool Stake: ◎130.006848640 +Total Pool Tokens: 130.00684864 +Current Number of Validators: 3 +Max Number of Validators: 1000 +``` +这可不太好!第一个质押账户,`EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ`,分配得太多了。根据他们的策略,质押者希望`100`SOL能够均匀分配,也就是每个账户`40`SOL。他们需要将`30`SOL移动到`J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H`和`38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk`。 + +#### 减少验证者质押 +首先,他们需要减少委托给`EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ`的质押账户`3k7Nwu9jUSc6SNG11wzufKYoZXRFgxWamheGLYWp5Rvx`上的金额,总共减少`60`SOL。 + +他们减少那部分SOL的操作如下: +``` +$ spl-stake-pool decrease-validator-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ 60 +Signature: ZpQGwT85rJ8Y9afdkXhKo3TVv4xgTz741mmZj2vW7mihYseAkFsazWxza2y8eNGY4HDJm15c1cStwyiQzaM3RpH +``` +在内部,该指令将来自验证者质押账户`3k7Nwu9jUSc6SNG11wzufKYoZXRFgxWamheGLYWp5Rvx`的60 SOL分割并停用,转入一个临时质押账户,该账户完全由质押池拥有和管理。 + +一旦在下一个纪元质押被停用,`update`命令将自动将临时质押账户合并到一个储备质押账户中,该账户也完全由质押池拥有和管理。 + +#### 增加验证者质押 +现在储备质押账户有足够的资金来执行重新平衡,质押者可以增加其他两个验证者`J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H`和`38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk`的质押。 + +他们向`J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H`增加了30 SOL: +``` +$ spl-stake-pool increase-validator-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H 30 +Signature: 3GJACzjUGLPjcd9RLUW86AfBLWKapZRkxnEMc2yHT6erYtcKBgCapzyrVH6VN8Utxj7e2mtvzcigwLm6ZafXyTMw +``` + +并且他们增加了 30 SOL 到38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk: +``` +$ spl-stake-pool increase-validator-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk 30 +Signature: 4zaKYu3MQ3as8reLbuHKaXN8FNaHvpHuiZtsJeARo67UKMo6wUUoWE88Fy8N4EYQYicuwULTNffcUD3a9jY88PoU +``` + +在内部,该指令也使用临时质押账户。这一次,质押池从储备质押中分割,进入临时质押账户,然后将其激活到适当的验证者。 + +一到两个纪元后,一旦临时质押激活,更新命令会自动将临时质押合并到验证者质押账户中,留下一个完全重新平衡的质押池: +``` +$ spl-stake-pool list Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR +Stake Pool: Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR +Pool Token Mint: BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB +Preferred Deposit Validator: 38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk +Epoch Fee: 3/100 of epoch rewards +Withdrawal Fee: none +Stake Deposit Fee: none +SOL Deposit Fee: none +SOL Deposit Referral Fee: none +Stake Deposit Referral Fee: none +Reserve Account: EN4px2h4gFkYtsQUi4yeCYBrdRM4DoRxCVJyavMXEAm5 Available Balance: ◎10.006848640 +Vote Account: EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ Balance: ◎40.000000000 Last Update Epoch: 8 +Vote Account: J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H Balance: ◎40.000000000 Last Update Epoch: 8 +Vote Account: 38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk Balance: ◎40.000000000 Last Update Epoch: 8 +Total Pool Stake: ◎130.006848640 +Total Pool Tokens: 130.00684864 +Current Number of Validators: 3 +Max Number of Validators: 1000 +``` + +由于在重新平衡过程中累积的质押奖励,池子可能无法达到完美的平衡。这是完全正常的。 + +### 设置首选的存款/提款验证者 +由于质押池可以接受对其任何质押账户的存款,并且允许从任何质押账户提款,它可能被恶意套利者利用,这些套利者希望每个时代都能最大化收益。 + +例如,如果一个质押池有1000个验证者,套利者可以向这些验证者中的任何一个质押。在时代的末尾,他们可以检查哪个验证者表现最佳,存入他们的质押,然后立即从表现最好的验证者那里提款。一旦奖励发放,他们可以取出他们宝贵的质押,并以高于原来数量的金额重新存入。 + +为了减轻这种套利行为,质押池的质押者可以设置首选的提款或存款验证者。任何存款或提款都必须进入相应的质押账户,这使得在没有大量资金的情况下进行这种攻击变得不可能。 + +让我们设置一个首选的存款验证者质押账户: + +``` +$ spl-stake-pool set-preferred-validator Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR deposit --vote-account EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ +Signature: j6fbTqGJ8ehgKnSPns1adaSeFwg5M3wP1a32qYwZsQjymYoSejFUXLNGwvHSouJcFm4C78HUoC8xd7cvb5iActL +``` + +然后让我们将首选的提款验证者质押账户设置为同一个。 + +``` +$ spl-stake-pool set-preferred-validator Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR withdraw --vote-account EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ +Signature: 4MKdYLyFqU6H3311YZDeLtsoeGZMzswBHyBCRjHfkzuN1rB4LXJbPfkgUGLKkdbsxJvPRub7SqB1zNPTqDdwti2w +``` +在任何时候,他们也可以选择取消设置首选验证者: +``` +$ spl-stake-pool set-preferred-validator Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR withdraw --unset +Signature: 5Qh9FA3EXtJ7nKw7UyxmMWXnTMLRKQqcpvfEsEyBtxSPqzPAXp2vFXnPg1Pw8f37JFdvyzYay65CtA8Z1ewzVkvF +``` + +在`list`命令中会标记出首选验证者: +``` +$ spl-stake-pool list Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR +Stake Pool: Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR +Pool Token Mint: BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB +Preferred Deposit Validator: EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ +Preferred Withdraw Validator: EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ +``` + +## 用户示例 +### 列出验证者质押账户 +为了向质押池存款,用户首先必须向与质押池相关联的验证者质押账户之一委托一些质押。命令行实用工具有一个特殊的指令来查找哪些投票账户已经与质押池关联。 + +``` +$ spl-stake-pool list Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR +Stake Pool: Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR +Pool Token Mint: BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB +Preferred Deposit Validator: 38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk +Epoch Fee: 3/100 of epoch rewards +Withdrawal Fee: none +Stake Deposit Fee: none +SOL Deposit Fee: none +SOL Deposit Referral Fee: none +Stake Deposit Referral Fee: none +Reserve Account: EN4px2h4gFkYtsQUi4yeCYBrdRM4DoRxCVJyavMXEAm5 Available Balance: ◎10.006848640 +Vote Account: EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ Balance: ◎35.000000000 Last Update Epoch: 8 +Vote Account: J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H Balance: ◎35.000000000 Last Update Epoch: 8 +Vote Account: 38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk Balance: ◎35.000000000 Last Update Epoch: 8 +Total Pool Stake: ◎115.006848640 +Total Pool Tokens: 115.00684864 +Current Number of Validators: 3 +Max Number of Validators: 1000 +``` + +### 存款SOL +质押池直接从常规SOL钱包账户接受SOL存款,并作为交换铸造相应数量的池代币。 + +``` +$ spl-stake-pool deposit-sol Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 100 +Using existing associated token account DgyZrAq88bnG1TNRxpgDQzWXpzEurCvfY2ukKFWBvADQ to receive stake pool tokens of mint BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB, owned by 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn +Signature: 23CptpZaq33njCpJPAvk8XS53xXwpfqF1sGxChk3VDB5mzz7XPKQqwsreun3iwZ6b51AyHqGBaUyc6tx9fqvF9JK +``` + +作为回报,质押池为我们铸造了新的池代币,代表我们在池中的所有权份额。我们可以使用SPL代币命令行工具再次检查我们的质押池账户。 + +``` +$ spl-token balance BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB +100.00000000 +``` + +### 提款SOL +质押池允许直接从储备中提取SOL到常规SOL钱包账户,作为交换,会燃烧提供的池代币。 + +``` +$ spl-stake-pool withdraw-sol Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 7VXPpSxneL6JLj18Naw2gkukXtjBZfbmPh18cnoUCMD8 2 +Signature: 4bqZKUUrjVspqTGqGqX4zxnHnJB67WbeukKUZRmxJ2yFmr275CtHPjZNzQJD9Pe7Q6mSxnUpcVv9FUdAbGP9RyBc +``` + +质押池已经燃烧了2个池代币,作为交换,向地址`7VXPpSxneL6JLj18Naw2gkukXtjBZfbmPh18cnoUCMD8`发送了SOL。 + +你可以检查池代币已经被燃烧的情况: +``` +$ spl-token balance BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB +98.00000000 +``` + +并且你可以确认收款方已经被记入了信用: +``` +$ solana balance 7VXPpSxneL6JLj18Naw2gkukXtjBZfbmPh18cnoUCMD8 +2 SOL +``` + +### 质押存款 +质押池也接受来自活跃质押账户的存款,因此我们必须首先创建质押账户,并将它们委托给质押池管理的其中一个验证者。使用前一节中的`list`命令,我们看到`38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk`是一个有效的投票账户,因此让我们创建一个质押账户,并将我们的质押委托到那里。 +``` +$ solana-keygen new --no-passphrase -o stake-account.json +Generating a new keypair +Wrote new keypair to stake-account.json +============================================================================ +pubkey: 97wBBiLVA7fUViEew8yV8R6tTdKithZDVz8LHLfF9sTJ +============================================================================ +Save this seed phrase to recover your new keypair: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +============================================================================ +$ solana create-stake-account stake-account.json 10 +Signature: 5Y9r6MNoqJzVX8TWryAJbdp8i2DvintfxbYWoY6VcLEPgphK2tdydhtJTd3o3dF7QdM2Pg8sBFDZuyNcMag3nPvj +$ solana delegate-stake 97wBBiLVA7fUViEew8yV8R6tTdKithZDVz8LHLfF9sTJ 38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk +Signature: 2cDjHXSHjuadGQf1NQpPi43A8R19aCifsY16yTcictKPHcSAXN5TvXZ58nDJwkYs12tuZfTh5WVgAMSvptfrKdPP +``` + +两个纪元之后,当质押完全激活并且已经收到一个纪元奖励时,我们可以将质押存入质押池。 +``` +$ spl-stake-pool deposit-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 97wBBiLVA7fUViEew8yV8R6tTdKithZDVz8LHLfF9sTJ +Depositing stake 97wBBiLVA7fUViEew8yV8R6tTdKithZDVz8LHLfF9sTJ into stake pool account F8e8Ympp4MkDSPZdvRxdQUZXRkMBDdyqgHa363GShAPt +Using existing associated token account DgyZrAq88bnG1TNRxpgDQzWXpzEurCvfY2ukKFWBvADQ to receive stake pool tokens of mint BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB, owned by 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn +Signature: 45x2UtA1b49eBPtRHdkvA3k8JneZzfwjptNN1kKQZaPABYiJ4hSA8qwi7qLNN5b3Fr4Z6vXhJprrTCpkk3f8UqgD +``` +命令行界面(CLI)默认使用费用支付者的[关联代币账户](https://spl.solana.com/associated-token-account)来处理质押池代币,以及作为存入质押账户的提款权限。 + +或者,您可以自己创建一个SPL代币账户,并将其作为命令的`token-receiver`传递,并使用`withdraw-authority`标志指定质押账户上的提款权限。 + +``` +$ spl-stake-pool deposit-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 97wBBiLVA7fUViEew8yV8R6tTdKithZDVz8LHLfF9sTJ --token-receiver 34XMHa3JUPv46ftU4dGHvemZ9oKVjnciRePYMcX3rjEF --withdraw-authority authority.json +Depositing stake 97wBBiLVA7fUViEew8yV8R6tTdKithZDVz8LHLfF9sTJ into stake pool account F8e8Ympp4MkDSPZdvRxdQUZXRkMBDdyqgHa363GShAPt +Signature: 4AESGZzqBVfj5xQnMiPWAwzJnAtQDRFK1Ha6jqKKTs46Zm5fw3LqgU1mRAT6CKTywVfFMHZCLm1hcQNScSMwVvjQ +``` +作为回报,质押池为我们铸造了新的池代币,这些代币代表了我们在池中的所有权份额。我们可以使用SPL代币命令行工具来再次检查我们的质押池账户。 +``` +$ spl-token balance BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB +10.00000000 +``` + +##### 关于质押存款费用的说明 +质押池对于质押和SOL有各自的费用标准,因此从质押账户存款的总费用是根据租金豁免储备按SOL计算,以及委托部分按质押计算的。 + +例如,如果质押池的质押存款费用是1%,SOL存款费用是5%,您存入的质押账户中有10 SOL的质押金和0.00228288 SOL的租金豁免,那么收取的总费用是: +``` +total_fee = stake_delegation * stake_deposit_fee + rent_exemption * sol_deposit_fee +total_fee = 10 * 1% + .00228288 * 5% +total_fee = 0.100114144 +``` + +#### 更新 +每个纪元,网络都会向质押池管理的质押账户支付奖励,这增加了存款时铸造的池代币的价值。为了计算这些质押池代币的正确价值,我们必须每个纪元更新质押池管理的总价值。 +``` +$ spl-stake-pool update Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR +Signature: 2rtPNGKFSSnXFCb6MKG5wHp34dkB5hJWNhro8EU2oGh1USafAgzu98EgoRnPLi7ojQfmTpvXk4S7DWXYGu5t85Ka +Signature: 5V2oCNvZCNJfC6QXHmR2UHGxVMip6nfZixYkVjFQBTyTf2Z9s9GJ9BjkxSFGvUsvW6zc2cCRv9Lqucu1cgHMFcVU +``` + +如果另一个用户已经为当前时代更新了质押池余额,我们将看到不同的输出。 +``` +$ spl-stake-pool update Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR +Update not required +``` + +如果当前纪元没有人更新质押池,包括存款和提款在内的所有指令都将失败。更新指令是无需许可的,因此任何用户都可以在与质押池交互之前运行它。为了方便起见,命令行界面(CLI)在执行质押池的任何指令之前都会尝试进行更新。 + +如果质押池的临时质押处于非预期状态,且合并操作无法进行,有一个选项可以仅更新质押池余额而不执行合并,即使用`--no-merge`标志。 +``` +$ spl-stake-pool update Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR --no-merge +Signature: 5cjdZG727uzwnEEG3vJ1vskA9WsXibaEHh7imXSb2S1cwEYK4Q3btr2GEeAV8EffK4CEQ2WM6PQxawkJAHoZ4jsQ +Signature: EBHbSRstJ3HxKwYKak8vEwVMKr1UBxdbqs5KuX3XYt4ppPjhaziGEtvL2TJCm1HLokbrtMeTEv57Ef4xhByJtJP +``` +稍后,每当临时质押准备合并时,可以使用`--force`标志在同一时期强制进行另一次更新 + +``` +$ spl-stake-pool update Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR --force +Signature: 5RneEBwJkFytBJaJdkvCTHFrG3QzE3SGf9vdBm9gteCcHV4HwaHzj3mjX1hZg4yCREQSgmo3H9bPF6auMmMFTSTo +Signature: 1215wJUY7vj82TQoGCacQ2VJZ157HnCTvfsUXkYph3nZzJNmeDaGmy1nCD7hkhFfxnQYYxVtec5TkDFGGB4e7EvG +``` +#### 提取质押 +无论何时用户想要回收他们的SOL代币以及累积的奖励,他们都可以提供他们的池代币以换取一个激活的质押账户。 + +让我们用5个池代币来兑换活跃的质押SOL。 +``` +$ spl-stake-pool withdraw-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 5 +Withdrawing ◎5.000000000, or 5 pool tokens, from stake account 3k7Nwu9jUSc6SNG11wzufKYoZXRFgxWamheGLYWp5Rvx, delegated to EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ +Creating account to receive stake 5GuAyPAt6577HoGhSVRNBv6aHohVtjQ8q7q5i3X1p4tB +Signature: 5fzaKt5MU8bLjJRgNZyEktKsgweSQzFRpubCGKPeuk9shNQb4CtTkbgZ2X5MmC1VRDZ3YcCTPdtL9sFpXYfoqaeV +``` + +质押池收取了5个池代币,作为交换,用户收到了一个完全激活的质押账户,该账户已委托给地址 `EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ`。让我们再次检查质押账户的状态: +``` +$ solana stake-account 5GuAyPAt6577HoGhSVRNBv6aHohVtjQ8q7q5i3X1p4tB +Balance: 5.00228288 SOL +Rent Exempt Reserve: 0.00228288 SOL +Delegated Stake: 5 SOL +Active Stake: 5 SOL +Delegated Vote Account Address: EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ +Stake Authority: 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn +Withdraw Authority: 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn +``` + +注意:这个操作花费了用户一些资金,因为他们需要创建一个新的质押账户,并支付最低的租金免除费用,以便接收资金。这允许用户提取任何数量的质押池代币,即使这些代币不足以支付质押账户的租金免除。 + +另外,用户可以通过使用`--stake-receiver`参数来指定一个现有的未初始化的质押账户,以接收他们的质押。 +``` +$ spl-stake-pool withdraw-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR --amount 0.02 --vote-account EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ --stake-receiver CZF2z3JJoDmJRcVjtsrz1BKUUGNL3VPW5FPFqge1bzmQ +Withdrawing ◎5.000000000, or 5 pool tokens, from stake account 3k7Nwu9jUSc6SNG11wzufKYoZXRFgxWamheGLYWp5Rvx, delegated to EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ +Signature: 2xBPVPJ749AE4hHNCNYdjuHv1EdMvxm9uvvraWfTA7Urrvecwh9w64URCyLLroLQ2RKDGE2QELM2ZHd8qRkjavJM +``` + +默认情况下,withdraw命令会使用`代币持有者`关联的代币账户来获取池代币。可以使用`--pool-account`标志来指定SPL代币账户。 + +``` +$ spl-stake-pool withdraw-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 5 --pool-account 34XMHa3JUPv46ftU4dGHvemZ9oKVjnciRePYMcX3rjEF +Withdrawing ◎5.000000000, or 5 pool tokens, from stake account 3k7Nwu9jUSc6SNG11wzufKYoZXRFgxWamheGLYWp5Rvx, delegated to EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ +Creating account to receive stake CZF2z3JJoDmJRcVjtsrz1BKUUGNL3VPW5FPFqge1bzmQ +Signature: 2xBPVPJ749AE4hHNCNYdjuHv1EdMvxm9uvvraWfTA7Urrvecwh9w64URCyLLroLQ2RKDGE2QELM2ZHd8qRkjavJM +``` +默认情况下,withdraw命令会从池中最大的验证者质押账户中提取资金。也可以使用`--vote-account`标志来指定特定的投票账户进行提取。 + +``` +$ spl-stake-pool withdraw-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR --amount 5 --vote-account EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ +Withdrawing ◎5.000000000, or 5 pool tokens, from stake account 3k7Nwu9jUSc6SNG11wzufKYoZXRFgxWamheGLYWp5Rvx, delegated to EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ +Creating account to receive stake CZF2z3JJoDmJRcVjtsrz1BKUUGNL3VPW5FPFqge1bzmQ +Signature: 2xBPVPJ749AE4hHNCNYdjuHv1EdMvxm9uvvraWfTA7Urrvecwh9w64URCyLLroLQ2RKDGE2QELM2ZHd8qRkjavJM +``` + +请注意,关联的验证者质押账户必须有足够的lamports来满足请求的池代币数量。 + +##### 特殊情况:退出有拖欠者的池子 +使用储备质押,一个拖欠或恶意的质押者可以通过`decrease-validator-stake`操作将所有质押转移到储备中,这样池代币将不会获得奖励,而质押池用户也将无法提取他们的资金。 + +为了解决这种情况,也可以从质押池的储备中提取资金,但前提是所有的验证者质押账户都必须至少有`1 SOL + 质押账户的租金免除金额`。 + +``` +$ spl-stake-pool withdraw-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 5 --use-reserve +Withdrawing ◎5.000000000, or 5 pool tokens, from stake account J5XB7mWpeaUZxZ6ogXT57qSCobczx27vLZYSgfSbZoBB +Creating account to receive stake 51XdXiBSsVzeuY79xJwWAGZgeKzzgFKWajkwvWyrRiNE +Signature: yQH9n7Go6iCMEYXqWef38ZYBPwXDmbwKAJFJ4EHD6TusBpusKsfNuT3TV9TL8FmxR2N9ExZTZwbD9Njc3rMvUcf +``` + +##### 特殊情况:从池中移除验证者 +由于用于将验证者添加到池中的资金来自外部存款,因此拖欠或恶意的质押者可能会使用户无法通过将所有资金保持在最低金额来回收他们的SOL。 + +为了解决这种情况,也可以从质押池中移除验证者,但前提是所有的验证者质押账户都必须至少有`1 SOL + 质押账户的租金免除金额`。这意味着,如果验证者的质押账户中有足够的资金来覆盖租金免除,用户就可以从池中移除验证者,即使质押者试图通过保持最低金额来阻止用户回收资金。这样的机制可以保护用户的利益,确保他们能够从质押池中提取自己的份额。 + +``` +$ spl-stake-pool withdraw-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 1.00228288 SOL +Withdrawing ◎1.00228288 or 1.00228288 pool tokens, from stake account J5XB7mWpeaUZxZ6ogXT57qSCobczx27vLZYSgfSbZoBB +Creating account to receive stake 51XdXiBSsVzeuY79xJwWAGZgeKzzgFKWajkwvWyrRiNE +Signature: yQH9n7Go6iCMEYXqWef38ZYBPwXDmbwKAJFJ4EHD6TusBpusKsfNuT3TV9TL8FmxR2N9ExZTZwbD9Njc3rMvUcf +``` diff --git a/docs/SolanaProgramLibrary/stake-pool/fees.md b/docs/SolanaProgramLibrary/stake-pool/fees.md new file mode 100644 index 0000000..ed6fb8c --- /dev/null +++ b/docs/SolanaProgramLibrary/stake-pool/fees.md @@ -0,0 +1,79 @@ +# 费用 +质押池的运营商应该花时间理解每种费用的目的,并仔细考虑它们,以确保质押池不会被滥用。 + +有五种不同的费用来源。 + +### 纪元费用 +每个纪元(大约2天),池中的质押账户会获得通胀奖励,因此质押池会按获得奖励的比例,将池代币铸造到管理者的费用账户中。 + +例如,如果池子获得了10 SOL的奖励,并且费用设置为2%,管理者将获得价值0.2 SOL的池代币。 + +请注意,纪元费用是在正常验证者佣金评估后收取的。例如,如果一个验证者收取8%的佣金,质押池收取2%,而池中的质押在佣金前赚取了100 SOL,那么这个质押实际上会为池增加90.16 SOL。该验证者的总奖励将减少约9.84%。 + +当纪元费用更新时,变更仅在两个纪元边界后生效。例如,如果在100纪元更新纪元费用,新的费用将仅从102纪元开始使用。 + +### SOL提款费 +将所需提款金额的一部分发送给管理者。 + +例如,如果用户希望提款100池代币,费用设置为3%,3池代币将归管理者所有,剩余的97代币将转换为SOL并发送给用户。 + +当SOL提款费更新时,变更仅在两个纪元边界后生效。例如,如果在100纪元更新费用,新的费用将仅从102纪元开始使用。 + +此外,费用增加限制为当前费用的1.5倍。例如,如果当前费用为2.5%,则可设置的最高费用为3.75%,这将在两个纪元边界后生效。 + +### 质押提款费 +在为用户创建新的质押之前,将所需提款金额的一部分发送给管理者。 + +例如,如果用户希望提款100池代币,费用设置为0.5%,0.5池代币将归管理者所有,剩余的99.5代币将转换为SOL然后作为已激活的质押账户发送给用户。 + +当质押提款费更新时,变更仅在两个纪元边界后生效。例如,如果在100纪元更新费用,新的费用将仅从102纪元开始使用。 + +此外,费用增加限制为当前费用的1.5倍。例如,如果当前费用为2.5%,则可设置的最高费用为3.75%,这将在两个纪元边界后生效。 + +### SOL存款费 +将整个SOL存款转换为池代币,然后将池代币的一部分发送给管理者,其余部分发送给用户。 + +例如,如果用户存入100 SOL,转换为90池代币,费用为1%,那么用户将收到89.1池代币,管理者将收到0.9池代币。 + +### 质押存款费 +将质押账户的委托加上租金豁免转换为池代币,将其中一部分发送给管理者,其余部分发送给用户。质押账户的租金豁免部分按照SOL存款率转换,而质押按照质押存款率转换。 + +例如,假设池代币与SOL的汇率为1:1,SOL存款率为10%,质押存款率为5%。如果用户存入一个质押账户,其中质押了100 SOL和0.00228288 SOL用于租金豁免。来自质押的费用价值5池代币,来自租金豁免的费用价值0.000228288池代币,因此用户收到95.002054592池代币,管理者收到5.000228288池代币。 + +## 推荐费 +对于合作伙伴应用程序,管理者可以在存款上设置推荐费。在SOL或质押存款期间,质押池将池代币费用的百分比重新分配给另一个地址作为推荐费。 + +这个选项对钱包提供商特别有吸引力。当钱包集成质押池时,钱包开发者将有机会在用户存入质押池时赚取额外的代币。质押池管理者可以利用这个功能建立战略合作伙伴关系,并吸引更多人使用质押池! + +## 最佳实践 +除了货币化之外,费用是避免对质押池进行经济攻击并保持其运行的关键工具。为此,质押池CLI将防止管理者创建没有费用的池,除非他们还提供`--yolo`标志。 + +### 纪元 +如果一个有1000个验证者的质押池每个纪元运行一次重新平衡脚本,质押者需要发送大约200笔交易来更新质押池余额,然后多达1000笔交易来增加或减少每个验证者的质押。 + +在撰写本文时,当前交易费用为每个签名 5,000 lampor,因此这1200笔交易的最低成本为 6,000,000 lampor,或0.006 SOL。为了收支平衡,质押池管理者每个纪元必须赚取0.006 SOL的费用。 + +例如,假设我们有一个质押了10,000 SOL的质押池,其质押赚取6% APY / ~3.3基点每个纪元的收益,每个纪元大约产生3.3 SOL的奖励。这个质押池的最低收支平衡纪元费用为0.18%。 + +### 质押存款/提款 +如果质押池没有存款或提款费,恶意的池代币持有者可以轻易地从质押池中吸取价值。 + +在最简单的攻击中,每个纪元的末尾,恶意的池代币持有者找到池中表现最好的验证者,提取相当于他们所有池代币的活跃质押,等待纪元滚动,赚取最大的质押奖励,然后立即重新存入质押池。 + +实际上,恶意存款人总是委托给质押池中表现最好的验证者,而从未真正向该验证者承诺质押。除此之外,恶意存款人绕过了任何纪元费用。 + +为了使这种攻击不可行,质押池管理者可以设置存款或提款费。如果质押池的整体表现为6% APY / ~3.3基点每个纪元,而最佳验证者的表现为6.15% APY / ~3.37基点每个纪元,那么最低的质押存款/提款费将是0.07基点。 + +为了完全安全,如果池中的一个违约验证者降低了性能,管理者可能希望提高更多。 + +### SOL存款/提款 +如果质押池的SOL存款/提款费为0,则恶意的SOL持有者可以执行类似的攻击,从池中提取更多价值。 + +如果他们将SOL存入质押池,提取池中顶级验证者的质押账户,等待纪元滚动,然后将该质押重新存入池中,然后提取SOL,他们基本上在没有任何时间承诺的情况下免费赚取了即时奖励。与此同时,质押池的性能下降了,因为存入的流动SOL没有赚取奖励。 + +例如,如果质押池中表现最好的验证者赚取6.15% APY / ~3.37基点每个纪元,那么最低的SOL存款/提款费应该是3.37基点。 + +### 最后的想法 +前几节中概述的攻击是任何人都可以轻易执行的最简单的攻击,只需几次运行几个脚本即可。对于零费用或非常低费用的质押池,可能有更复杂的攻击,因此请确保用费用保护您的存款人! + + diff --git a/docs/SolanaProgramLibrary/stake-pool/operation.md b/docs/SolanaProgramLibrary/stake-pool/operation.md new file mode 100644 index 0000000..426853c --- /dev/null +++ b/docs/SolanaProgramLibrary/stake-pool/operation.md @@ -0,0 +1,126 @@ +# 操作 +质押池是赚取质押奖励的另一种方法。这个链上程序将SOL汇集在一起,由质押者进行质押,允许SOL持有者质押并赚取奖励,而无需管理质押。 + +## 质押 +SOL代币持有者可以通过将代币质押给一个或多个验证者来赚取奖励并帮助保护网络。质押代币的奖励基于当前的通胀率、网络上质押的SOL总数以及个别验证者的在线时间和佣金(费用)。 + +有关质押和质押编程的更多信息,请访问: +- https://solana.com/staking +- https://docs.solana.com/staking/stake-programming + +## 背景 +Solana的编程模型和本文档中使用的Solana术语的定义,请访问: +- https://docs.solana.com/apps +- https://docs.solana.com/terminology + +## 动机 +本文档旨在为质押池系统的主要参与者提供信息: + +- 管理者:创建和管理质押池,赚取费用,可以更新费用、质押者和管理者 +- 质押者:向池中添加和移除验证者,重新平衡验证者之间的质押,可以更新质押者 +- 用户:向现有的质押池提供流动或质押SOL + +在当前的迭代中,质押池接受活跃的质押或SOL,因此存款可能来自活跃的质押或SOL钱包。提款可以返回质押池账户中的一个完全活跃的质押账户,或者来自储备的SOL。 + +这意味着质押池管理者和质押者必须熟悉创建和委托质押,这比发送和接收SPL代币和SOL更为高级的操作。有关质押操作的更多信息,请访问: + +- https://docs.solana.com/cli/delegate-stake +- https://docs.solana.com/cli/manage-stake-accounts + +为了吸引更多的用户,鼓励质押池管理者通过[Token Swap](https://spl.solana.com/token-swap)等AMM为他们池子的代币提供市场。 + +或者,质押池管理者可以与钱包和质押账户提供商合作,进行直接的SOL存款。 + +## 操作 +一个质押池管理者创建了一个质押池。此时,用户可以立即通过`deposit-sol`指令参与,将资金转移到储备中以换取池代币。 + +使用这些SOL存款,质押者通过使用`add-validator`将“验证者质押账户”添加到池子中,从而包括将从池子中接收委托的验证者。在这个命令中,质押池使用储备资金创建一个新的质押账户并将其委托给所需的验证者。 + +此时,用户也可以将质押账户存入池子中。为此,他们必须将质押账户委托给质押池中的一个验证者。如果质押池有一个首选的存款验证者,用户必须将他们的质押委托给该验证者的投票账户。 + +一旦质押在下一个纪元界限(最多2天)激活,用户就可以使用`deposit-stake`指令将他们的质押存入池中。 + +作为他们存款(SOL或质押)的交换,用户收到代表他们在池中的分数所有权的SPL代币。池中赚取的奖励的一部分作为一个纪元费用归池管理者所有。 + +随着时间的推移,随着池中的质押累积奖励,用户的分数所有权将比他们最初的存款更有价值。 + +当他们希望退出池时,用户可以使用`withdraw-sol`指令从质押池的储备中以质押池代币换取SOL。请注意,如果质押池的储备中没有足够的SOL,此操作将失败,这很正常,如果质押池管理者将池中的所有SOL都进行了质押。 + +或者,他们可以使用`withdraw-stake`指令以他们的SPL池代币换取已激活的质押账户。用户将立即得到一个SOL质押账户。在任何情况下,始终可以提取质押。 + +注意:当提取质押时,如果用户想要提取质押账户中的SOL,他们必须首先停用质押账户并等待到下一个纪元界限(最多2天)。一旦质押不活跃,他们可以自由提取SOL。 + +质押池质押者可以添加和移除验证者,或通过降低对验证者质押的份额,等待一个纪元将其移动到质押池的储备账户中,然后在另一个验证者上增加质押,来重新平衡池。 + +质押者添加新验证者的操作需要1.00228288 SOL来在验证者上创建质押账户,因此质押池储备需要流动性。 + +### 资金限制 +为了给管理者更多的控制权,质押池允许通过三种不同的“资金授权”对进入池中的资金进行存款和提款限制: + +SOL存款 +质押存款 +SOL提款 + +如果设置了该字段,则该授权必须签署相关指令。 + +例如,如果管理者设置了一个质押存款授权,那么该地址必须签署每个质押存款指令。 + +这在几种情况下也很有用: +- 控制谁可以向质押池存款 +- 禁止某种形式的存款。例如,管理者只希望有SOL存款,因此他们设置了一个质押存款授权,使得只有在该授权签署交易的情况下才能存入质押账户。 +- 维护模式。如果池需要时间来重置费用或以其他方式,管理者可以通过设置存款授权暂时限制新存款。 + +注意:为了确保用户资金的安全,总是允许质押提款。 + +## 资金安全 +质押池程序的主要目标之一是始终允许池代币持有者随时提取他们的资金。 + +为此,让我们来看看质押池系统中的三种类别的质押账户: +- 验证者质押:活跃的质押账户,池中每个验证者一个 +- 临时质押:正在激活或停用的质押账户,在停用后合并到储备中,或在激活后合并到验证者质押中,每个验证者一个 +- 储备质押:不活跃的质押,被质押者用于重新平衡 +此外,质押者可能会设定一个“首选提取账户”,强制用户从特定的质押账户提款。这是为了防止恶意存款者将质押池作为验证者之间的免费转换。 + +- 在处理提款时,优先顺序如下: +- 首选提款的验证者质押账户(如果设定) +- 验证者质押账户 +- 临时质押账户 +- 储备质押账户 +- 完全移除验证者质押账户 + +如果有首选提款验证者,并且该验证者质押账户有任何SOL,用户必须从该账户提款。 + +如果该账户为空,或者没有设置首选提款验证者质押账户,那么用户必须从任何验证者质押账户中提款。 + +如果所有验证者质押账户都为空,这可能会发生如果质押池质押者一次性减少所有验证者上的质押,那么用户必须从任何临时质押账户中提款。 + +如果所有临时质押账户都为空,那么用户必须从储备中提款或完全移除验证者质押账户。 + +通过这种方式,用户的资金永远不会处于风险中,始终可以赎回。 + +## 附录 +### 活跃质押 +如前所述,质押池使用活跃质押来维持质押池代币的可互换性。完全激活的质押与不活跃的、正在激活的或正在停用的质押不同,因为质押的时间成本。 + +### 临时质押账户 +每个验证者都会得到一个临时质押账户,因此质押者一次只能对验证者执行一个动作。不可能同时增加和减少对验证者的质押。质押者必须等到现有的临时质押账户在一个`update`指令中合并后才能执行新动作。 + +### 储备质押账户 +每个质押池都初始化了一个未委托的储备质押账户,用于在重新平衡过程中持有未委托的质押。当质押者减少对验证者的质押时,并在经历一个纪元后,更新操作会将减少的质押合并到储备中。相反,每当质押者增加对验证者的质押时,就会从储备质押账户中提取lamports。 + +### 验证者列表账户 +每个质押池都包含两个数据账户:质押池和验证者列表。 + +质押池包含有关池子的总体信息,包括费用、池代币铸造、管理金额等。 + +验证者列表包含有关池中每个验证者质押账户的特定信息。这些信息包括池在验证者上质押的SOL金额,以及在验证者上激活/停用的SOL金额。 + +每个质押池都必须有自己的验证者列表账户,否则初始化时会失败。 + +### 交易大小 +Solana交易处理器有两个重要的限制: + +- 整体交易的大小,限制在大约 1 MTU /数据包 +- 每个指令的计算预算 + +一个质押池可能管理数百个质押账户,因此不可能在一条指令中更新质押池的总价值。幸运的是,命令行工具将会拆分交易,以避免大型池子遇到这个问题。 diff --git a/docs/SolanaProgramLibrary/stake-pool/quickstart.md b/docs/SolanaProgramLibrary/stake-pool/quickstart.md new file mode 100644 index 0000000..21e8331 --- /dev/null +++ b/docs/SolanaProgramLibrary/stake-pool/quickstart.md @@ -0,0 +1,156 @@ +# 快速开始指南 +本指南适用于希望立即开始运行质押池的管理人员。 + +## 前提条件 +本指南需要 Solana CLI 工具套件和 Stake Pool CLI 工具。 +- [安装 Solana 工具](https://docs.solana.com/cli/install-solana-cli-tools) +- [安装 Stake Pool CLI](https://spl.solana.com/stake-pool/cli) + +你还必须拥有一个包含 SOL 的账户。假设你使用的是通过 `solana-keygen new` 在默认位置创建的默认密钥对。请注意,如果需要,可以在每个命令中覆盖默认密钥对。 + +如果你在本地使用 `solana-test-validator`,默认密钥对会自动启动并拥有 500,000,000 SOL。 + +如果你在 开发网 或 测试网 上运行,可以使用 `solana airdrop 1` 来空投资金。 + +如果你在 主网beta版 上运行,则必须通过其他方式(如从交易所或朋友处等)购买资金。 + +## 示例脚本 +本指南使用 [GitHub 上的示例脚本](https://github.com/solana-labs/solana-program-library/tree/master/stake-pool/cli/scripts) 来快速轻松地运行所有内容。 + +你将看到以下脚本: + +- `setup-test-validator.sh`:设置带有验证者投票账户的本地测试验证者 +- `setup-stake-pool.sh`:创建具有硬编码参数的新质押池 +- `add-validators.sh`:向质押池添加验证者 +- `deposit.sh`:进行质押和 SOL 存款 +- `rebalance.sh`:重新平衡质押池 +- `withdraw.sh`:进行一些提款 + +本指南将使用大多数这些脚本在本地网络上设置质押池。 + +## (可选)步骤 0:设置本地网络以进行测试 +所有这些脚本都可以在 开发网、测试网 或 主网beta版 上运行,但为了进行更多实验,我们将使用 `setup-test-validator.sh` 设置一个带有一些验证者投票账户的本地验证者。 + +该脚本接受要创建的投票账户数量和输出验证者投票账户的文件路径,例如: +``` +$ ./setup-test-validator.sh 10 local_validators.txt +``` +这大约需要 10 秒钟,最终会输出一个包含 base58 编码公钥列表的文件。这些代表本地网络上的验证者投票账户,例如: +``` +EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ +J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H +38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk +7q371UZcYJTMmFPeijUJ6RBr6jHE9t4mDd2gnDs7wpje +7ffftyketRJrmCcczhSnWatxB32SzAG3dhDpnyRdm91d +HtqJXQNWr4E1qxftAxxqNnHbpSYnokayHSxurzS9vKKF +4e6EmSSmExdRM6tF1osYiAq9HxXN5oVvDqS78FcT6F4P +DrT6VGqqJT1GRVaZmuEjNim4ie7ecmNixjiycd67jyJy +71vNo5HBuAtejbcQYp9CdBeT7npVdbJqjmuWbXbNeudq +7FMebvnWnWN45KF5Fa3Y7kAJZReKU6WLzribtWDJybax +``` + +注意:如果另一个 `solana-test-validator` 已经在运行,这将会失败。 + +*本地网络的重要注意事项* + +如果你使用的是 32 个槽位的纪元,那么在使用某个质押池命令时,则很有可能在使用其中一个质押池命令时传递一个纪元,导致其失败并显示:`Custom program error: 0x11`。这是完全正常的,并且在其他网络上不会发生。你只需重新运行命令。 + +由于测试验证者网络上没有投票活动,你需要在使用 `solana delegate-stake` 时使用 `--force` 标志,例如: + +``` +$ solana delegate-stake --force stake.json CzDy6uxLTko5Jjcdm46AozMmrARY6R2aDBagdemiBuiT +``` + +## 步骤 1:创建质押池 +我们的下一个脚本是 `setup-stake-pool.sh`。在其中,你会看到一个很大的区域可以在其中修改你的质押池参数。这些参数用于创建新的质押池,并包括: +- 纪元(epoch)费用,以两个不同的标志表示,分子和分母 +- 提款费用,以两个不同的标志表示,分子和分母 +- 存款费用,以两个不同的标志表示,分子和分母 +- 推荐费用,以 0 到 100 之间的数字表示(包括 0 和 100) +- 最大验证者数量(目前最高可能是 2,950) +- (可选)存款授权,用于受限池 + +虽然费用在此时似乎不太有趣或有欺骗性,但请考虑运行质押池的成本,以及如果没有费用,可能会有恶意行为者滥用你的池子。 + +这些参数中的每一个在池子创建后都是可修改的,因此不必担心被锁定在任何选择中。 + +修改参数以满足你的需求。费用尤其重要,以避免滥用,因此请花时间审查和计算最适合你的池子的费用。 + +仔细阅读[费用](https://spl.solana.com/stake-pool/fees)以获取有关费用和最佳实践的更多信息。 + +在我们的示例中,我们将使用 0.3% 的费用、50% 的推荐费用,选择不设置存款授权,并拥有最大数量的验证 +``` +$ ./setup-stake-pool.sh 15 +Creating pool ++ spl-stake-pool create-pool --epoch-fee-numerator 3 --epoch-fee-denominator 1000 --withdrawal-fee-numerator 3 --withdrawal-fee-denominator 1000 --deposit-fee-numerator 3 --deposit-fee-denominator 1000 --referral-fee 50 --max-validators 2350 --pool-keypair keys/stake-pool.json --validator-list-keypair keys/validator-list.json --mint-keypair keys/mint.json --reserve-keypair keys/reserve.json +Creating reserve stake 4tvTkLB4X7ahUYZ2NaTohkG3mud4UBBvu9ZEGD4Wk9mt +Creating mint BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB +Creating associated token account DgyZrAq88bnG1TNRxpgDQzWXpzEurCvfY2ukKFWBvADQ to receive stake pool tokens of mint BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB, owned by 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn +Creating pool fee collection account DgyZrAq88bnG1TNRxpgDQzWXpzEurCvfY2ukKFWBvADQ +Signature: 51yf2J6dSGAx42KPs2oTMTV4ufEm1ncAHyLPQ6PNf4sbeMHGqno7BGn2tHkUnrd7PRXiWBbGzCWpJNevYjmoLgn2 +Creating stake pool Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR with validator list 86VZZCuqiz7sDJpFKjQy9c9dZQN9vwDKbYgY8pcwHuaF +Signature: 47QHcWMEa5Syg13C3SQRA4n88Y8iLx1f39wJXQAStRUxpt2VD5t6pYgAdruNRHUQt1ZBY8QwbvEC1LX9j3nPrAzn +Depositing SOL into stake pool +Update not required +Using existing associated token account DgyZrAq88bnG1TNRxpgDQzWXpzEurCvfY2ukKFWBvADQ to receive stake pool tokens of mint BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB, owned by 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn +Signature: 4jnS368HcofZ1rUpsGZtmSK9kVxFzJRndSX5VS7eMV3kVgzyg9efA4mcgd2C6BoSNksTmTonRGXTVM1WMywFpiKq +``` +你的质押池现在已经存在了!对于最大数量的验证者,此阶段的成本约为 2.02 SOL,加上存入池中的 15 SOL 以换取池代币。 + +## 步骤 2:向池中存入 SOL +现在池子已经存在,让我们存入一些 SOL 以换取一些池代币。 + +SOL 可能是最具吸引力的存款形式,因为它对每个人来说都是最容易使用的。通常,这可能通过 DeFi 应用或钱包完成,但在我们的示例中,我们将直接从命令行进行操作。 + +在创建池子时,我们已经存入了 15 SOL,但现在让我们再向池中存入 10 SOL: +``` +$ spl-stake-pool deposit-sol Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 10 +Using existing associated token account DgyZrAq88bnG1TNRxpgDQzWXpzEurCvfY2ukKFWBvADQ to receive stake pool tokens of mint BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB, owned by 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn +Signature: 4AJv6hSznYoMGnaQvjWXSBjKqtjYpjBx2MLezmRRjWRDa8vUaBLQfPNGd3kamZNs1JeWSvnzczwtzsMD5WkgKamA +``` + +## 步骤 3:向池中添加验证者 +现在池中已经有了一些 SOL,我们需要向其中添加验证者。 + +使用 `add-validators.sh` 脚本,我们将把在步骤 0 中创建的每个验证者添加到质押池中。如果你在其他网络上运行,可以创建一个包含验证者投票账户的文件。 + +``` +$ ./add-validators.sh keys/stake-pool.json local_validators.txt +Adding validator stake accounts to the pool +Adding stake account 3k7Nwu9jUSc6SNG11wzufKYoZXRFgxWamheGLYWp5Rvx, delegated to EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ +Signature: 5Vm2n3umPXFzQgDiaib1B42k7GqsNYHZWrauoe4DUyFszczB7Hjv9r1DKWKrypc8KDiUccdWmJhHBqM1fdP6WiCm +Signature: 3XtmYu9msqnMeKJs9BopYjn5QTc5hENMXXiBwvEw6HYzU5w6z1HUkGwNW24io4Vu9WRKFFN6SAtrfkZBLK4fYjv4 +... (something similar repeated 9 more times) +``` +此操作将从储备中移动 1.00228288 SOL 到给定验证者的质押账户。这意味着您要添加的每个验证者都需要超过 1 个 SOL。 + +## 步骤 4:向池中存入质押 +现在你的池中已有验证者,它可以接受质押账户供您管理。存款有两种可能来源:SOL 或质押账户。在步骤 2 中,我们直接存入了 SOL,所以现在我们将存入质押账户。 + +此选项对已经拥有质押账户的用户特别有吸引力,他们可能希望换取质押池代币,或者希望进一步分散他们的质押。 +`deposit.sh` 脚本展示了如何使用 CLI 来实现这一点。 + +创建新的质押,将给定数量的资金存入池中的每个质押账户,使用质押池和验证者文件。 +``` +$ ./deposit.sh keys/stake-pool.json local_validators.txt 10 +``` + +## 步骤 5:重新平衡池中的质押 +随着时间的推移,当人们将 SOL 存入储备时,或者随着验证者性能的变化,你可能需要重新分配质押。最佳方式是通过一个自动化系统来收集关于质押池和网络的信息,并决定分配给每个验证者的质押数量。 + +Solana 基金会为其委托计划维护了一个开源机器人,可以为你的质押池进行适配。源码是 [stake-o-matic GitHub仓库](https://github.com/solana-labs/stake-o-matic/tree/master/bot) 的一部分。 + +此外,还有一个正在开发中的 Python 质押池机器人,可以在 [stake-pool-py on GitHub](https://github.com/solana-labs/solana-program-library/tree/master/stake-pool/py) 中找到。 + +在我们的示例中,我们将运行一个简单的池重新平衡器,它会按给定数量增加列表中每个验证者的质押。没有任何检查或逻辑来确保这是有效的。 +``` +$ ./rebalance.sh keys/stake-pool.json local_validators.txt 100 +``` + +## 步骤 6:从质押池中提款 +最后,如果用户想从质押池中提款,他们可以选择从储备中提取 SOL(如果储备中有足够的 SOL),或者从池中的某个质押账户中提取。 + +`withdraw.sh` 脚本根据质押池、验证者文件和金额,从池中的每个质押账户中移除质押和 SOL。 +``` +$ ./withdraw.sh keys/stake-pool.json local_validators.txt 100 +``` From 07a76c9f4921de12230e9a1e87f9c9b2053daa65 Mon Sep 17 00:00:00 2001 From: RuoMinggX <117256259+Patrickming@users.noreply.github.com> Date: Sun, 21 Jul 2024 10:44:36 +0800 Subject: [PATCH 2/5] review cli.md --- docs/SolanaProgramLibrary/stake-pool/cli.md | 269 +++++++++++++------- 1 file changed, 178 insertions(+), 91 deletions(-) diff --git a/docs/SolanaProgramLibrary/stake-pool/cli.md b/docs/SolanaProgramLibrary/stake-pool/cli.md index a4fcb32..6cc6463 100644 --- a/docs/SolanaProgramLibrary/stake-pool/cli.md +++ b/docs/SolanaProgramLibrary/stake-pool/cli.md @@ -1,52 +1,71 @@ # 命令行界面 -以下是使用命令行工具的Stake Pool程序中可用的指令,以及示例。 + +以下是命令行工具的Stake Pool程序中可用的指令,以及使用示例。 ## 安装 -`spl-stake-pool`命令行工具可用于试验SPL代币。一旦你安装了[Rust](https://rustup.rs/),请运行: -``` + +`spl-stake-pool`命令行工具可用于试验SPL代币。首先确保你安装了[Rust](https://rustup.rs/),然后运行: + +```bash $ cargo install spl-stake-pool-cli ``` -运行 `spl-stake-pool --help` 以获取所有可用命令的完整描述。 + +运行 `spl-stake-pool --help` 查看所有可用命令的完整描述。 ## 配置 + `spl-stake-pool`配置与`solana`命令行工具共享。 ### 当前配置 -``` + +```bash $ solana config get Config File: ${HOME}/.config/solana/cli/config.yml RPC URL: https://api.mainnet-beta.solana.com WebSocket URL: wss://api.mainnet-beta.solana.com/ (computed) Keypair Path: ${HOME}/.config/solana/id.json ``` -集群RPC URL -查看[Solana集群](https://docs.solana.com/clusters)以获取特定于集群的RPC URL -``` +### 集群RPC URL + +参考[Solana集群](https://docs.solana.com/clusters)以获取特定于集群的RPC URL + +```bash $ solana config set --url https://api.devnet.solana.com ``` + ### 默认密钥对 -有关如何设置[密钥对](https://docs.solana.com/cli/conventions#keypair-conventions)的信息,请参见密钥对约定,如果你还没有密钥对。 + +有关如何设置密钥对(如果还没有密钥对)的信息,请参阅[密钥对规定](https://docs.solana.com/cli/conventions#keypair-conventions)。 密钥对文件 -``` + +```bash $ solana config set --keypair ${HOME}/new-keypair.json ``` -硬件钱包URL(见[URL规范](https://docs.solana.com/wallet-guide/hardware-wallets#specify-a-keypair-url)) +参考[URL规范](https://docs.solana.com/wallet-guide/hardware-wallets#specify-a-keypair-url)设置硬件钱包URL。 + +```bash $ solana config set --keypair usb://ledger/ +``` + ### 本地运行 -如果你想在不等待质押激活和停用的情况下本地测试质押池,你可以使用`solana-test-validator`工具运行质押池,缩短纪元,并从devnet拉取当前程序。 -``` +如果你想在不等待质押激活和停用的情况下,来本地测试质押池,你可以使用`solana-test-validator`工具运行质押池,缩短纪元(epochs)的时间,并从开发网拉取当前程序。 + +```bash $ solana-test-validator -c SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy -c EmiU8AQkB2sswTxVB6aCmsAJftoowZGGDXuytm6X65R3 --url devnet --slots-per-epoch 32 $ solana config set --url http://127.0.0.1:8899 ``` -## 质押池管理者示例 + +## 质押池管理器示例 + ### 创建质押池 -质押池管理者从高层控制质押池,并作为交换以SPL代币的形式收取费用。管理者在创建时设置费用。让我们创建一个带有3%费用和最多1000个验证者质押账户的池: -```$ spl-stake-pool create-pool --epoch-fee-numerator 3 --epoch-fee-denominator 100 --max-validators 1000 +质押池管理器(Stake Pool Manager)以高级别控制质押池,并以SPL代币形式收取费用。管理器在创建时设置费用。例如,创建一个3%费用和最多1000个验证者质押的池: + +```bash $ spl-stake-pool create-pool --epoch-fee-numerator 3 --epoch-fee-denominator 100 --max-validators 1000 Creating reserve stake DVwDn4LTRztuai4QeenM6fyzgiwUGpVXVNZ1mgKE1Pyc Creating mint BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB @@ -56,11 +75,12 @@ Signature: qQwqahLuC24wPwVdgVXtd7v5htSSPDAH3JxFNmXCv9aDwjjqygQ64VMg3WdPCiNzc4Bn8 Creating stake pool Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR Signature: 5z6uH3EuPcujeWGpAjBtciSUR3TxtMBgWYU4ULagUso4QGzE9JenhYHwYthJ4b3rS57ByUNEXTr2BFyF5PjWC42Y ``` + 质押池的唯一标识符是 `Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR。` 质押池的SPL代币铸造标识符是 `BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB`。质押池对铸造有完全控制权。 -池创建者的费用账户标识符是 `DgyZrAq88bnG1TNRxpgDQzWXpzEurCvfY2ukKFWBvADQ`。在每个纪元里,当质押池中的质押账户获得奖励时,程序会将相当于该纪元收益3%的SPL池代币铸造到这个账户。如果没有观察到收益,就什么都不会存入。 +质押池创建者的费用账户标识符是 `DgyZrAq88bnG1TNRxpgDQzWXpzEurCvfY2ukKFWBvADQ`。在每个纪元里,当质押池中的质押账户获得奖励时,程序会将相当于该纪元收益3%的SPL池代币铸造到这个账户。如果没有观察到收益,就什么都不会存入。 储备质押账户标识符是 `J5XB7mWpeaUZxZ6ogXT57qSCobczx27vLZYSgfSbZoBB`。此账户持有在验证者之间重新平衡时使用的额外质押。 @@ -68,19 +88,20 @@ Signature: 5z6uH3EuPcujeWGpAjBtciSUR3TxtMBgWYU4ULagUso4QGzE9JenhYHwYthJ4b3rS57By `create-pool`命令允许设置所有账户和密钥对为预先生成的值,包括: -- 质押池,通过 `--pool-keypair` 标志 -- 验证者列表,通过 `--validator-list-keypair` 标志 -- 池子代币铸造,通过 `--mint-keypair` 标志 -- 池子储备质押账户,通过 `--reserve-keypair` 标志 +- 质押池,通过 `--pool-keypair` 标识 +- 验证者列表,通过 `--validator-list-keypair` 标识 +- 池子代币铸造厂,通过 `--mint-keypair` 标识 +- 池子储备质押账户,通过 `--reserve-keypair` 标识 否则,这些将默认为新生成的密钥对。 你可以随时运行 `spl-stake-pool create-pool -h` 来查看可用的选项。 -### 创建受限质押池 +### 创建限制性质押池 + 如果管理者希望将质押(质押和SOL)存款限制为特定的一个密钥,他们可以在创建时设置存款权限: -``` +```bash $ spl-stake-pool create-pool --epoch-fee-numerator 3 --epoch-fee-denominator 100 --max-validators 1000 --deposit-authority authority_keypair.json Creating reserve stake DVwDn4LTRztuai4QeenM6fyzgiwUGpVXVNZ1mgKE1Pyc Creating mint BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB @@ -92,29 +113,33 @@ Deposits will be restricted to 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn only Signature: 5z6uH3EuPcujeWGpAjBtciSUR3TxtMBgWYU4ULagUso4QGzE9JenhYHwYthJ4b3rS57ByUNEXTr2BFyF5PjWC42Y ``` -正如输出所说,`set-funding-authority` 可以用来修改或删除存款权威。 +正如输出所示,`set-funding-authority` 可以用来修改或删除存款权限。 -只要设置了存款权威,SOL和质押存款必须由 `4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn` 签名,所以没有其他人可以参与池。如前所述,这个特性不禁止提款,所以任何有池子代币的人仍然可以从池中提款。 +只要设置了存款权限,SOL和质押存款必须由 `4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn` 签名,因此其他人不能参与。如前所述,这个功能不禁止提款,所以任何有池子代币的人仍然可以从池中提款。 ### 设置管理者 + 质押池管理者可以将他们的管理员权限传递给另一个账户。 -``` +```bash $ spl-stake-pool set-manager Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR --new-manager 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn Signature: 39N5gkaqXuWm6JPEUWfenKXeG4nSa71p7iHb9zurvdZcsWmbjdmSXwLVYfhAVHWucTY77sJ8SkUNpVpVAhe4eZ53 ``` -同时,他们还可以更改每个纪元接收费用的SPL代币账户。所提供代币账户的铸造必须是SPL代币铸造,在我们的例子中是 `BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB`。 -``` +同时,他们还可以更改每个纪元接收费用的SPL代币账户。所提供代币账户的铸造厂必须是SPL代币铸造厂,在我们的例子中是 `BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB`。 + +```bash $ spl-stake-pool set-manager Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR --new-fee-receiver HoCsh97wRxRXVjtG7dyfsXSwH9VxdDzC7GvAsBE1eqJz Signature: 4aK8yzYvPBkP4PyuXTcCm529kjEH6tTt4ixc5D5ZyCrHwc4pvxAHj6wcr4cpAE1e3LddE87J1GLD466aiifcXoAY ``` ### 设置费用 + 质押池管理者可以更新与质押池相关的任何费用,需要传入构成费用比例的分子和分母。 对于10%的纪元费用,他们可以执行以下操作: -``` + +```bash $ spl-stake-pool set-fee Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR epoch 10 100 Signature: 5yPXfVj5cbKBfZiEVi2UR5bXzVDuc2c3ruBwSjkAqpvxPHigwGHiS1mXQVE4qwok5moMWT5RNYAMvkE9bnfQ1i93 ``` @@ -127,25 +152,30 @@ Signature: 5yPXfVj5cbKBfZiEVi2UR5bXzVDuc2c3ruBwSjkAqpvxPHigwGHiS1mXQVE4qwok5moMW 例如,如果当前的提款费用是2.5%,可设置的最高费用是3.75%,将在两个纪元界限后生效。 -费用类型可能的选项有`纪元费用`、`SOL提款费`、`质押提款费`、`SOL存款费`和`质押存款费`。 +费用类型可能的选项有`纪元费用`、`SOL提款`、`质押提款`、`SOL存款`和`质押存款`(epoch` 、 `sol-withdrawal` 、 `stake-withdrawal` 、 `sol-deposit 和 stake-deposit)。 + +### 设置推荐费用 -### 设置推荐费 质押池管理者可以随时更新存款上的推荐费,传入一个百分比金额。 要设置80%的质押存款推荐费,他们可以执行以下操作: -``` + +```bash $ spl-stake-pool set-referral-fee Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR stake 80 Signature: 4vhaBEDhuKkVwMxy7TpyfHEk3Z5kGZKerD1AgajQBdiMRQLZuNZKVR3KQaqbUYZM7UyfRXgkZNdAeP1NfvmwKdqb ``` + 对于80%的推荐费,这意味着质押存款费用的20%归管理者所有,而80%归推荐人所有。 ### 设置质押者 + 为了管理质押账户,质押池管理者或质押者可以设置质押池管理账户的质押者权限。 ``` $ spl-stake-pool set-staker Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn Signature: 39N5gkaqXuWm6JPEUWfenKXeG4nSa71p7iHb9zurvdZcsWmbjdmSXwLVYfhAVHWucTY77sJ8SkUNpVpVAhe4eZ53 ``` + 现在,新的质押者可以执行任何正常的质押池操作,包括添加和移除验证者以及重新平衡质押。 重要的安全提示:质押池程序仅向质押池质押者授予质押权限,并始终保留提款权限。因此,恶意的质押池质押者无法从质押池中窃取资金。 @@ -153,11 +183,12 @@ Signature: 39N5gkaqXuWm6JPEUWfenKXeG4nSa71p7iHb9zurvdZcsWmbjdmSXwLVYfhAVHWucTY77 注意:为了避免“打扰管理者”,质押者也可以重新分配他们的质押权限。 ### 设置资金权限 + 为了限制谁可以与池子交互,质押池管理者可能需要在质押存款、SOL存款或SOL提款上要求特定的签名。这并不会使得池子变得私有,因为所有信息都是在链上公开的,但它限制了谁可以使用池子。 例如,假设一个池子想要限制所有的SOL提款。 -``` +```bash $ spl-stake-pool set-funding-authority Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR sol-withdraw AZ1PgxWSxw4ezX8gvpNgGsr39jJHCwtkaXr1mNMwWWeK Signature: 3gx7ckGNSL7gUUyxh4CU3RH3Lyt88hiCvYQ4QRKtnmrZHvAS93ebP6bf39WYGTeKDMVSJUuwBEmk9VFSaWtXsHVV ``` @@ -165,31 +196,37 @@ Signature: 3gx7ckGNSL7gUUyxh4CU3RH3Lyt88hiCvYQ4QRKtnmrZHvAS93ebP6bf39WYGTeKDMVSJ 执行此命令后,`AZ1PgxWSxw4ezX8gvpNgGsr39jJHCwtkaXr1mNMwWWeK` 必须对所有的SOL提款进行签名,否则操作将失败。 过了一段时间后,如果管理者希望启用SOL提款,他们可以移除这个限制: -``` + +```bash $ spl-stake-pool set-funding-authority Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR sol-withdraw --unset Signature: 5kWeBqoxyvANMHCP4ydsZRf8QU4hMotLnKkFbTEdvqEVywo4F3MpZtay7D57FbjJZpdp72fc3vrbxJi9qDLfLCnD ``` 现在,只要储备中还有足够的SOL,任何人都可以从质押池中提取SOL。 -资金权威选项有`sol-提款`、`sol-存款`和`质押存款`。 +资金权限相关选项有`sol-提款`、`sol-存款`和`质押存款`( `sol-withdraw`, `sol-deposit`, and `stake-deposit`)。 注意:限制质押提款是不可能的。这将为恶意池管理者提供机会,实际上锁定用户资金。 + ## 质押池质押者示例 + ### 向池中添加验证者 + 为了适应大量用户向质押池存款,质押池只为每个验证者管理一个质押账户。要向质押池添加新的验证者,质押者必须使用`add-validator`命令。 用于向池中添加验证者的SOL来自质押池的储备账户。如果储备中的SOL不足,命令将失败。请确保使用`deposit-sol`命令将一些SOL转移到池中。 假设质押池中有10 SOL,让我们向质押池添加一些随机验证者。 -``` +```bash $ spl-stake-pool add-validator Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk Adding stake account F8e8Ympp4MkDSPZdvRxdQUZXRkMBDdyqgHa363GShAPt, delegated to 38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk Signature: 5tdpsx64mVcSHBK8vMbBzFDHnEZB6GUmVpqSXXE5hezMAzPYwZbJCBtAHakDAiuWNcrMongGrmwDaeywhVz4i8pi ``` + 为了最大程度地提高审查抵抗能力,我们希望将我们的SOL分散到尽可能多的验证者那里,因此让我们再添加一些。 -``` + +```bash $ spl-stake-pool add-validator Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H Adding stake account 5AaobwjccyHnXhFCd24uiX6VqPjXE3Ry4o92fJjqqjAr, delegated to J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H Signature: 4xeve6gWuiffqBLAMcqa8s7dCMvBmSVdKbDu5WQhigLiXHdCjSNEwoZRexTZji786qgEjXg3nrUh4HcTt3RauZV5 @@ -197,8 +234,10 @@ $ spl-stake-pool add-validator Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR EhRbK Adding stake account 3k7Nwu9jUSc6SNG11wzufKYoZXRFgxWamheGLYWp5Rvx, delegated to EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ Signature: 4VJYHpPmWkP99TdgYUTgLYixmhqmqsEkWtg4j7zvGZFjYbnLgryu48aV6ub8bqDyULzKckUhb6tvcmZmMX5AFf5G ``` + 我们可以使用Solana命令行工具查看质押账户的状态。 -``` + +```bash $ solana stake-account 5AaobwjccyHnXhFCd24uiX6VqPjXE3Ry4o92fJjqqjAr Balance: 1.00228288 SOL Rent Exempt Reserve: 0.00228288 SOL @@ -210,10 +249,12 @@ Delegated Vote Account Address: J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H Stake Authority: DS3AyFN9dF1ruNBcSeo8XXQR8UyVMhcCPcnjU5GnY18S Withdraw Authority: DS3AyFN9dF1ruNBcSeo8XXQR8UyVMhcCPcnjU5GnY18S ``` + 质押池创建了这些特殊的质押账户,其中1 SOL是所需的最低委托金额。质押和提款权限属于质押池提款权限,即从质押池地址派生的程序地址。 我们还可以看到质押池的状态。 -``` + +```bash $ spl-stake-pool list Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR Stake Pool: Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR Pool Token Mint: BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB @@ -232,31 +273,36 @@ Total Pool Tokens: 10.00000000 Current Number of Validators: 3 Max Number of Validators: 1000 ``` -为了便于阅读,该工具不会显示质押池无法触及的余额。储备质押账户 `EN4px2h4gFkYtsQUi4yeCYBrdRM4DoRxCVJyavMXEAm5` 实际上还有额外的0.002282881 SOL余额,但由于这是最低要求金额,所以CLI不会显示。 + +为了便于阅读,该工具不会显示质押池无法触及的余额。储备质押账户 `EN4px2h4gFkYtsQUi4yeCYBrdRM4DoRxCVJyavMXEAm5` 实际上还有额外的0.002282881 SOL余额,但由于这是最低要求金额,所以命令行不会显示。 ### 移除验证者质押账户 -如果质押池的质押者想要停止向某个投票账户委托,他们可以完全从质押池中移除该验证者的质押账户。 + +如果质押池质押者希望停止委托给投票账户,他们可以完全从质押池中移除该验证者的质押账户。 和添加验证者一样,要移除的验证者质押账户必须恰好有1.00228288 SOL(1 SOL用于委托,0.00228288 SOL用于租金豁免)。 如果情况不是这样,质押者必须先将质押金额减少到这个最小数额。假设委托给`J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H`的验证者质押账户总共委托了7.5 SOL。为了减少这个数额,质押者可以执行以下操作: -``` +```bash $ spl-stake-pool decrease-validator-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H 6.5 Signature: ZpQGwT85rJ8Y9afdkXhKo3TVv4xgTz741mmZj2vW7mihYseAkFsazWxza2y8eNGY4HDJm15c1cStwyiQzaM3RpH ``` 好的,让我们尝试移除验证者`J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H`,其对应的质押账户是`5AaobwjccyHnXhFCd24uiX6VqPjXE3Ry4o92fJjqqjAr`。 -``` + +```bash $ spl-stake-pool remove-validator Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H Removing stake account 5AaobwjccyHnXhFCd24uiX6VqPjXE3Ry4o92fJjqqjAr, delegated to J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H Creating account to receive stake nHEEyey8KkgHuVRAUDzkH5Q4PkA4veSHuTxgG6C8L2G Signature: 4XprnR768Ch6LUvqUVLTjMCiqdYvtjNfECh4izErqwbsASTGjUBz7NtLZHAiraTqhs7b9PoSAazetdsgXa6J4wVu ``` + 与普通提款不同,验证者的质押账户将被停用,并在下一个纪元与储备账户合并。 我们可以检查正在停用的质押账户: -``` + +```bash $ solana stake-account nHEEyey8KkgHuVRAUDzkH5Q4PkA4veSHuTxgG6C8L2G Balance: 1.002282880 SOL Rent Exempt Reserve: 0.00228288 SOL @@ -269,10 +315,12 @@ Withdraw Authority: 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn ``` ### 重新平衡质押池 + 随着时间的推移,用户将向质押池管理的所有质押账户存款和提款,质押池的质押者可能希望重新平衡这些质押。 例如,假设质押者希望对池中的每个验证者进行相同数量的委托。当他们查看池的状态时,他们看到: -``` + +```bash $ spl-stake-pool list Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR Stake Pool: Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR Pool Token Mint: BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB @@ -291,39 +339,47 @@ Total Pool Tokens: 130.00684864 Current Number of Validators: 3 Max Number of Validators: 1000 ``` + 这可不太好!第一个质押账户,`EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ`,分配得太多了。根据他们的策略,质押者希望`100`SOL能够均匀分配,也就是每个账户`40`SOL。他们需要将`30`SOL移动到`J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H`和`38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk`。 #### 减少验证者质押 + 首先,他们需要减少委托给`EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ`的质押账户`3k7Nwu9jUSc6SNG11wzufKYoZXRFgxWamheGLYWp5Rvx`上的金额,总共减少`60`SOL。 他们减少那部分SOL的操作如下: -``` + +```bash $ spl-stake-pool decrease-validator-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ 60 Signature: ZpQGwT85rJ8Y9afdkXhKo3TVv4xgTz741mmZj2vW7mihYseAkFsazWxza2y8eNGY4HDJm15c1cStwyiQzaM3RpH ``` -在内部,该指令将来自验证者质押账户`3k7Nwu9jUSc6SNG11wzufKYoZXRFgxWamheGLYWp5Rvx`的60 SOL分割并停用,转入一个临时质押账户,该账户完全由质押池拥有和管理。 + +在内部,该指令将来自验证者质押账户`3k7Nwu9jUSc6SNG11wzufKYoZXRFgxWamheGLYWp5Rvx`的60 SOL拆分并停用,转入一个临时质押账户,该账户完全由质押池拥有和管理。 一旦在下一个纪元质押被停用,`update`命令将自动将临时质押账户合并到一个储备质押账户中,该账户也完全由质押池拥有和管理。 #### 增加验证者质押 + 现在储备质押账户有足够的资金来执行重新平衡,质押者可以增加其他两个验证者`J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H`和`38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk`的质押。 他们向`J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H`增加了30 SOL: -``` + +```bash $ spl-stake-pool increase-validator-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H 30 Signature: 3GJACzjUGLPjcd9RLUW86AfBLWKapZRkxnEMc2yHT6erYtcKBgCapzyrVH6VN8Utxj7e2mtvzcigwLm6ZafXyTMw ``` -并且他们增加了 30 SOL 到38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk: -``` +并且他们增加了 30 SOL 到`38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk`: + +```bash $ spl-stake-pool increase-validator-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk 30 Signature: 4zaKYu3MQ3as8reLbuHKaXN8FNaHvpHuiZtsJeARo67UKMo6wUUoWE88Fy8N4EYQYicuwULTNffcUD3a9jY88PoU ``` -在内部,该指令也使用临时质押账户。这一次,质押池从储备质押中分割,进入临时质押账户,然后将其激活到适当的验证者。 +在内部,该指令也使用临时质押账户。这一次,质押池从储备质押中拆分为临时质押账户,然后将其激活到相应的验证者。 -一到两个纪元后,一旦临时质押激活,更新命令会自动将临时质押合并到验证者质押账户中,留下一个完全重新平衡的质押池: -``` +一到两个纪元后,一旦临时质押激活,update命令会自动将临时质押合并到验证者质押账户中,留下一个完全重新平衡的质押池: + +```bash $ spl-stake-pool list Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR Stake Pool: Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR Pool Token Mint: BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB @@ -347,7 +403,8 @@ Max Number of Validators: 1000 由于在重新平衡过程中累积的质押奖励,池子可能无法达到完美的平衡。这是完全正常的。 ### 设置首选的存款/提款验证者 -由于质押池可以接受对其任何质押账户的存款,并且允许从任何质押账户提款,它可能被恶意套利者利用,这些套利者希望每个时代都能最大化收益。 + +由于质押池可以接受对其任何质押账户的存款,并且允许从任何质押账户提款,它可能被恶意套利者利用,这些套利者希望每个纪元都能最大化收益。 例如,如果一个质押池有1000个验证者,套利者可以向这些验证者中的任何一个质押。在时代的末尾,他们可以检查哪个验证者表现最佳,存入他们的质押,然后立即从表现最好的验证者那里提款。一旦奖励发放,他们可以取出他们宝贵的质押,并以高于原来数量的金额重新存入。 @@ -355,25 +412,28 @@ Max Number of Validators: 1000 让我们设置一个首选的存款验证者质押账户: -``` +```bash $ spl-stake-pool set-preferred-validator Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR deposit --vote-account EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ Signature: j6fbTqGJ8ehgKnSPns1adaSeFwg5M3wP1a32qYwZsQjymYoSejFUXLNGwvHSouJcFm4C78HUoC8xd7cvb5iActL ``` 然后让我们将首选的提款验证者质押账户设置为同一个。 -``` +```bash $ spl-stake-pool set-preferred-validator Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR withdraw --vote-account EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ Signature: 4MKdYLyFqU6H3311YZDeLtsoeGZMzswBHyBCRjHfkzuN1rB4LXJbPfkgUGLKkdbsxJvPRub7SqB1zNPTqDdwti2w ``` + 在任何时候,他们也可以选择取消设置首选验证者: -``` + +```bash $ spl-stake-pool set-preferred-validator Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR withdraw --unset Signature: 5Qh9FA3EXtJ7nKw7UyxmMWXnTMLRKQqcpvfEsEyBtxSPqzPAXp2vFXnPg1Pw8f37JFdvyzYay65CtA8Z1ewzVkvF ``` 在`list`命令中会标记出首选验证者: -``` + +```bash $ spl-stake-pool list Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR Stake Pool: Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR Pool Token Mint: BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB @@ -382,10 +442,12 @@ Preferred Withdraw Validator: EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ ``` ## 用户示例 + ### 列出验证者质押账户 -为了向质押池存款,用户首先必须向与质押池相关联的验证者质押账户之一委托一些质押。命令行实用工具有一个特殊的指令来查找哪些投票账户已经与质押池关联。 -``` +为了向质押池存款,用户首先必须向与质押池相关联的验证者质押账户之一委托一些质押。命令行实用工具有一个特殊的指令,来查找哪些投票账户已经与质押池关联。 + +```bash $ spl-stake-pool list Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR Stake Pool: Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR Pool Token Mint: BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB @@ -407,9 +469,10 @@ Max Number of Validators: 1000 ``` ### 存款SOL + 质押池直接从常规SOL钱包账户接受SOL存款,并作为交换铸造相应数量的池代币。 -``` +```bash $ spl-stake-pool deposit-sol Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 100 Using existing associated token account DgyZrAq88bnG1TNRxpgDQzWXpzEurCvfY2ukKFWBvADQ to receive stake pool tokens of mint BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB, owned by 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn Signature: 23CptpZaq33njCpJPAvk8XS53xXwpfqF1sGxChk3VDB5mzz7XPKQqwsreun3iwZ6b51AyHqGBaUyc6tx9fqvF9JK @@ -417,15 +480,16 @@ Signature: 23CptpZaq33njCpJPAvk8XS53xXwpfqF1sGxChk3VDB5mzz7XPKQqwsreun3iwZ6b51Ay 作为回报,质押池为我们铸造了新的池代币,代表我们在池中的所有权份额。我们可以使用SPL代币命令行工具再次检查我们的质押池账户。 -``` +```bash $ spl-token balance BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB 100.00000000 ``` ### 提款SOL + 质押池允许直接从储备中提取SOL到常规SOL钱包账户,作为交换,会燃烧提供的池代币。 -``` +```bash $ spl-stake-pool withdraw-sol Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 7VXPpSxneL6JLj18Naw2gkukXtjBZfbmPh18cnoUCMD8 2 Signature: 4bqZKUUrjVspqTGqGqX4zxnHnJB67WbeukKUZRmxJ2yFmr275CtHPjZNzQJD9Pe7Q6mSxnUpcVv9FUdAbGP9RyBc ``` @@ -433,20 +497,24 @@ Signature: 4bqZKUUrjVspqTGqGqX4zxnHnJB67WbeukKUZRmxJ2yFmr275CtHPjZNzQJD9Pe7Q6mSx 质押池已经燃烧了2个池代币,作为交换,向地址`7VXPpSxneL6JLj18Naw2gkukXtjBZfbmPh18cnoUCMD8`发送了SOL。 你可以检查池代币已经被燃烧的情况: -``` + +```bash $ spl-token balance BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB 98.00000000 ``` -并且你可以确认收款方已经被记入了信用: -``` +并且你可以确认收款方已经被记入: + +```bash $ solana balance 7VXPpSxneL6JLj18Naw2gkukXtjBZfbmPh18cnoUCMD8 2 SOL ``` ### 质押存款 + 质押池也接受来自活跃质押账户的存款,因此我们必须首先创建质押账户,并将它们委托给质押池管理的其中一个验证者。使用前一节中的`list`命令,我们看到`38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk`是一个有效的投票账户,因此让我们创建一个质押账户,并将我们的质押委托到那里。 -``` + +```bash $ solana-keygen new --no-passphrase -o stake-account.json Generating a new keypair Wrote new keypair to stake-account.json @@ -463,71 +531,85 @@ Signature: 2cDjHXSHjuadGQf1NQpPi43A8R19aCifsY16yTcictKPHcSAXN5TvXZ58nDJwkYs12tuZ ``` 两个纪元之后,当质押完全激活并且已经收到一个纪元奖励时,我们可以将质押存入质押池。 -``` + +```bash $ spl-stake-pool deposit-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 97wBBiLVA7fUViEew8yV8R6tTdKithZDVz8LHLfF9sTJ Depositing stake 97wBBiLVA7fUViEew8yV8R6tTdKithZDVz8LHLfF9sTJ into stake pool account F8e8Ympp4MkDSPZdvRxdQUZXRkMBDdyqgHa363GShAPt Using existing associated token account DgyZrAq88bnG1TNRxpgDQzWXpzEurCvfY2ukKFWBvADQ to receive stake pool tokens of mint BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB, owned by 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn Signature: 45x2UtA1b49eBPtRHdkvA3k8JneZzfwjptNN1kKQZaPABYiJ4hSA8qwi7qLNN5b3Fr4Z6vXhJprrTCpkk3f8UqgD ``` -命令行界面(CLI)默认使用费用支付者的[关联代币账户](https://spl.solana.com/associated-token-account)来处理质押池代币,以及作为存入质押账户的提款权限。 + +命令行工具(CLI)默认使用费用支付者的[关联代币账户](https://spl.solana.com/associated-token-account)来处理质押池代币,以及作为存入质押账户的提款权限。 或者,您可以自己创建一个SPL代币账户,并将其作为命令的`token-receiver`传递,并使用`withdraw-authority`标志指定质押账户上的提款权限。 -``` +```bash $ spl-stake-pool deposit-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 97wBBiLVA7fUViEew8yV8R6tTdKithZDVz8LHLfF9sTJ --token-receiver 34XMHa3JUPv46ftU4dGHvemZ9oKVjnciRePYMcX3rjEF --withdraw-authority authority.json Depositing stake 97wBBiLVA7fUViEew8yV8R6tTdKithZDVz8LHLfF9sTJ into stake pool account F8e8Ympp4MkDSPZdvRxdQUZXRkMBDdyqgHa363GShAPt Signature: 4AESGZzqBVfj5xQnMiPWAwzJnAtQDRFK1Ha6jqKKTs46Zm5fw3LqgU1mRAT6CKTywVfFMHZCLm1hcQNScSMwVvjQ ``` + 作为回报,质押池为我们铸造了新的池代币,这些代币代表了我们在池中的所有权份额。我们可以使用SPL代币命令行工具来再次检查我们的质押池账户。 -``` + +```bash $ spl-token balance BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB 10.00000000 ``` -##### 关于质押存款费用的说明 +#### 关于质押存款费用的说明 + 质押池对于质押和SOL有各自的费用标准,因此从质押账户存款的总费用是根据租金豁免储备按SOL计算,以及委托部分按质押计算的。 例如,如果质押池的质押存款费用是1%,SOL存款费用是5%,您存入的质押账户中有10 SOL的质押金和0.00228288 SOL的租金豁免,那么收取的总费用是: -``` + +```tex total_fee = stake_delegation * stake_deposit_fee + rent_exemption * sol_deposit_fee total_fee = 10 * 1% + .00228288 * 5% total_fee = 0.100114144 ``` -#### 更新 +### 更新 + 每个纪元,网络都会向质押池管理的质押账户支付奖励,这增加了存款时铸造的池代币的价值。为了计算这些质押池代币的正确价值,我们必须每个纪元更新质押池管理的总价值。 -``` + +```bash $ spl-stake-pool update Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR Signature: 2rtPNGKFSSnXFCb6MKG5wHp34dkB5hJWNhro8EU2oGh1USafAgzu98EgoRnPLi7ojQfmTpvXk4S7DWXYGu5t85Ka Signature: 5V2oCNvZCNJfC6QXHmR2UHGxVMip6nfZixYkVjFQBTyTf2Z9s9GJ9BjkxSFGvUsvW6zc2cCRv9Lqucu1cgHMFcVU ``` 如果另一个用户已经为当前时代更新了质押池余额,我们将看到不同的输出。 -``` + +```bash $ spl-stake-pool update Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR Update not required ``` -如果当前纪元没有人更新质押池,包括存款和提款在内的所有指令都将失败。更新指令是无需许可的,因此任何用户都可以在与质押池交互之前运行它。为了方便起见,命令行界面(CLI)在执行质押池的任何指令之前都会尝试进行更新。 +如果当前纪元没有人更新质押池,包括存款和提款在内的所有指令都将失败。更新指令是无需许可的,因此任何用户都可以在与质押池交互之前运行它。为了方便起见,命令行工具(CLI)在执行质押池的任何指令之前都会尝试进行更新。 如果质押池的临时质押处于非预期状态,且合并操作无法进行,有一个选项可以仅更新质押池余额而不执行合并,即使用`--no-merge`标志。 -``` + +```bash $ spl-stake-pool update Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR --no-merge Signature: 5cjdZG727uzwnEEG3vJ1vskA9WsXibaEHh7imXSb2S1cwEYK4Q3btr2GEeAV8EffK4CEQ2WM6PQxawkJAHoZ4jsQ Signature: EBHbSRstJ3HxKwYKak8vEwVMKr1UBxdbqs5KuX3XYt4ppPjhaziGEtvL2TJCm1HLokbrtMeTEv57Ef4xhByJtJP ``` -稍后,每当临时质押准备合并时,可以使用`--force`标志在同一时期强制进行另一次更新 -``` +紧接着,每当临时质押准备合并时,可以使用`--force`标志在同一时期强制进行另一次更新 + +```bash $ spl-stake-pool update Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR --force Signature: 5RneEBwJkFytBJaJdkvCTHFrG3QzE3SGf9vdBm9gteCcHV4HwaHzj3mjX1hZg4yCREQSgmo3H9bPF6auMmMFTSTo Signature: 1215wJUY7vj82TQoGCacQ2VJZ157HnCTvfsUXkYph3nZzJNmeDaGmy1nCD7hkhFfxnQYYxVtec5TkDFGGB4e7EvG ``` -#### 提取质押 + +### 提取质押 + 无论何时用户想要回收他们的SOL代币以及累积的奖励,他们都可以提供他们的池代币以换取一个激活的质押账户。 让我们用5个池代币来兑换活跃的质押SOL。 -``` + +```bash $ spl-stake-pool withdraw-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 5 Withdrawing ◎5.000000000, or 5 pool tokens, from stake account 3k7Nwu9jUSc6SNG11wzufKYoZXRFgxWamheGLYWp5Rvx, delegated to EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ Creating account to receive stake 5GuAyPAt6577HoGhSVRNBv6aHohVtjQ8q7q5i3X1p4tB @@ -535,7 +617,8 @@ Signature: 5fzaKt5MU8bLjJRgNZyEktKsgweSQzFRpubCGKPeuk9shNQb4CtTkbgZ2X5MmC1VRDZ3Y ``` 质押池收取了5个池代币,作为交换,用户收到了一个完全激活的质押账户,该账户已委托给地址 `EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ`。让我们再次检查质押账户的状态: -``` + +```bash $ solana stake-account 5GuAyPAt6577HoGhSVRNBv6aHohVtjQ8q7q5i3X1p4tB Balance: 5.00228288 SOL Rent Exempt Reserve: 0.00228288 SOL @@ -549,23 +632,25 @@ Withdraw Authority: 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn 注意:这个操作花费了用户一些资金,因为他们需要创建一个新的质押账户,并支付最低的租金免除费用,以便接收资金。这允许用户提取任何数量的质押池代币,即使这些代币不足以支付质押账户的租金免除。 另外,用户可以通过使用`--stake-receiver`参数来指定一个现有的未初始化的质押账户,以接收他们的质押。 -``` + +```bash $ spl-stake-pool withdraw-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR --amount 0.02 --vote-account EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ --stake-receiver CZF2z3JJoDmJRcVjtsrz1BKUUGNL3VPW5FPFqge1bzmQ Withdrawing ◎5.000000000, or 5 pool tokens, from stake account 3k7Nwu9jUSc6SNG11wzufKYoZXRFgxWamheGLYWp5Rvx, delegated to EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ Signature: 2xBPVPJ749AE4hHNCNYdjuHv1EdMvxm9uvvraWfTA7Urrvecwh9w64URCyLLroLQ2RKDGE2QELM2ZHd8qRkjavJM ``` -默认情况下,withdraw命令会使用`代币持有者`关联的代币账户来获取池代币。可以使用`--pool-account`标志来指定SPL代币账户。 +默认情况下,withdraw命令会使用`代币持有者`(token-owner)关联的代币账户来获取池代币。可以使用`--pool-account`标志来指定SPL代币账户。 -``` +```bash $ spl-stake-pool withdraw-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 5 --pool-account 34XMHa3JUPv46ftU4dGHvemZ9oKVjnciRePYMcX3rjEF Withdrawing ◎5.000000000, or 5 pool tokens, from stake account 3k7Nwu9jUSc6SNG11wzufKYoZXRFgxWamheGLYWp5Rvx, delegated to EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ Creating account to receive stake CZF2z3JJoDmJRcVjtsrz1BKUUGNL3VPW5FPFqge1bzmQ Signature: 2xBPVPJ749AE4hHNCNYdjuHv1EdMvxm9uvvraWfTA7Urrvecwh9w64URCyLLroLQ2RKDGE2QELM2ZHd8qRkjavJM ``` + 默认情况下,withdraw命令会从池中最大的验证者质押账户中提取资金。也可以使用`--vote-account`标志来指定特定的投票账户进行提取。 -``` +```bash $ spl-stake-pool withdraw-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR --amount 5 --vote-account EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ Withdrawing ◎5.000000000, or 5 pool tokens, from stake account 3k7Nwu9jUSc6SNG11wzufKYoZXRFgxWamheGLYWp5Rvx, delegated to EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ Creating account to receive stake CZF2z3JJoDmJRcVjtsrz1BKUUGNL3VPW5FPFqge1bzmQ @@ -574,24 +659,26 @@ Signature: 2xBPVPJ749AE4hHNCNYdjuHv1EdMvxm9uvvraWfTA7Urrvecwh9w64URCyLLroLQ2RKDG 请注意,关联的验证者质押账户必须有足够的lamports来满足请求的池代币数量。 -##### 特殊情况:退出有拖欠者的池子 +#### 特殊情况:退出有拖欠者的池子 + 使用储备质押,一个拖欠或恶意的质押者可以通过`decrease-validator-stake`操作将所有质押转移到储备中,这样池代币将不会获得奖励,而质押池用户也将无法提取他们的资金。 为了解决这种情况,也可以从质押池的储备中提取资金,但前提是所有的验证者质押账户都必须至少有`1 SOL + 质押账户的租金免除金额`。 -``` +```bash $ spl-stake-pool withdraw-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 5 --use-reserve Withdrawing ◎5.000000000, or 5 pool tokens, from stake account J5XB7mWpeaUZxZ6ogXT57qSCobczx27vLZYSgfSbZoBB Creating account to receive stake 51XdXiBSsVzeuY79xJwWAGZgeKzzgFKWajkwvWyrRiNE Signature: yQH9n7Go6iCMEYXqWef38ZYBPwXDmbwKAJFJ4EHD6TusBpusKsfNuT3TV9TL8FmxR2N9ExZTZwbD9Njc3rMvUcf ``` -##### 特殊情况:从池中移除验证者 +#### 特殊情况:从池中移除验证者 + 由于用于将验证者添加到池中的资金来自外部存款,因此拖欠或恶意的质押者可能会使用户无法通过将所有资金保持在最低金额来回收他们的SOL。 为了解决这种情况,也可以从质押池中移除验证者,但前提是所有的验证者质押账户都必须至少有`1 SOL + 质押账户的租金免除金额`。这意味着,如果验证者的质押账户中有足够的资金来覆盖租金免除,用户就可以从池中移除验证者,即使质押者试图通过保持最低金额来阻止用户回收资金。这样的机制可以保护用户的利益,确保他们能够从质押池中提取自己的份额。 -``` +```bash $ spl-stake-pool withdraw-stake Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 1.00228288 SOL Withdrawing ◎1.00228288 or 1.00228288 pool tokens, from stake account J5XB7mWpeaUZxZ6ogXT57qSCobczx27vLZYSgfSbZoBB Creating account to receive stake 51XdXiBSsVzeuY79xJwWAGZgeKzzgFKWajkwvWyrRiNE From f552b58925f58b3ac6872166f39f1cd451253158 Mon Sep 17 00:00:00 2001 From: RuoMinggX <117256259+Patrickming@users.noreply.github.com> Date: Sun, 21 Jul 2024 10:51:12 +0800 Subject: [PATCH 3/5] review fees.md --- docs/SolanaProgramLibrary/stake-pool/fees.md | 42 ++++++++++++-------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/docs/SolanaProgramLibrary/stake-pool/fees.md b/docs/SolanaProgramLibrary/stake-pool/fees.md index ed6fb8c..87ac59a 100644 --- a/docs/SolanaProgramLibrary/stake-pool/fees.md +++ b/docs/SolanaProgramLibrary/stake-pool/fees.md @@ -1,64 +1,74 @@ # 费用 + 质押池的运营商应该花时间理解每种费用的目的,并仔细考虑它们,以确保质押池不会被滥用。 有五种不同的费用来源。 ### 纪元费用 -每个纪元(大约2天),池中的质押账户会获得通胀奖励,因此质押池会按获得奖励的比例,将池代币铸造到管理者的费用账户中。 -例如,如果池子获得了10 SOL的奖励,并且费用设置为2%,管理者将获得价值0.2 SOL的池代币。 +每个纪元(大约2天),池中的质押账户会获得通胀奖励,因此质押池会按获得奖励的比例,将池子代币铸造到管理者的费用账户中。 + +例如,如果池子获得了10 SOL的奖励,并且费用设置为2%,管理者将获得价值0.2 SOL的池子代币。 请注意,纪元费用是在正常验证者佣金评估后收取的。例如,如果一个验证者收取8%的佣金,质押池收取2%,而池中的质押在佣金前赚取了100 SOL,那么这个质押实际上会为池增加90.16 SOL。该验证者的总奖励将减少约9.84%。 当纪元费用更新时,变更仅在两个纪元边界后生效。例如,如果在100纪元更新纪元费用,新的费用将仅从102纪元开始使用。 ### SOL提款费 + 将所需提款金额的一部分发送给管理者。 -例如,如果用户希望提款100池代币,费用设置为3%,3池代币将归管理者所有,剩余的97代币将转换为SOL并发送给用户。 +例如,如果用户希望提款100池子代币,费用设置为3%,3池子代币将归管理者所有,剩余的97代币将转换为SOL并发送给用户。 当SOL提款费更新时,变更仅在两个纪元边界后生效。例如,如果在100纪元更新费用,新的费用将仅从102纪元开始使用。 此外,费用增加限制为当前费用的1.5倍。例如,如果当前费用为2.5%,则可设置的最高费用为3.75%,这将在两个纪元边界后生效。 ### 质押提款费 + 在为用户创建新的质押之前,将所需提款金额的一部分发送给管理者。 -例如,如果用户希望提款100池代币,费用设置为0.5%,0.5池代币将归管理者所有,剩余的99.5代币将转换为SOL然后作为已激活的质押账户发送给用户。 +例如,如果用户希望提款100池子代币,费用设置为0.5%,0.5池子代币将归管理者所有,剩余的99.5代币将转换为SOL然后作为已激活的质押账户发送给用户。 当质押提款费更新时,变更仅在两个纪元边界后生效。例如,如果在100纪元更新费用,新的费用将仅从102纪元开始使用。 此外,费用增加限制为当前费用的1.5倍。例如,如果当前费用为2.5%,则可设置的最高费用为3.75%,这将在两个纪元边界后生效。 ### SOL存款费 -将整个SOL存款转换为池代币,然后将池代币的一部分发送给管理者,其余部分发送给用户。 -例如,如果用户存入100 SOL,转换为90池代币,费用为1%,那么用户将收到89.1池代币,管理者将收到0.9池代币。 +将整个SOL存款转换为池子代币,然后将池子代币的一部分发送给管理者,其余部分发送给用户。 + +例如,如果用户存入100 SOL,转换为90池子代币,费用为1%,那么用户将收到89.1池子代币,管理者将收到0.9池子代币。 ### 质押存款费 -将质押账户的委托加上租金豁免转换为池代币,将其中一部分发送给管理者,其余部分发送给用户。质押账户的租金豁免部分按照SOL存款率转换,而质押按照质押存款率转换。 -例如,假设池代币与SOL的汇率为1:1,SOL存款率为10%,质押存款率为5%。如果用户存入一个质押账户,其中质押了100 SOL和0.00228288 SOL用于租金豁免。来自质押的费用价值5池代币,来自租金豁免的费用价值0.000228288池代币,因此用户收到95.002054592池代币,管理者收到5.000228288池代币。 +将质押账户的委托加上租金豁免转换为池子代币,将其中一部分发送给管理者,其余部分发送给用户。质押账户的租金豁免部分按照SOL存款率转换,而质押按照质押存款率转换。 + +例如,假设池子代币与SOL的汇率为1:1,SOL存款率为10%,质押存款率为5%。如果用户存入一个质押账户,其中质押了100 SOL和0.00228288 SOL用于租金豁免。来自质押的费用价值5池子代币,来自租金豁免的费用价值0.000228288池子代币,因此用户收到95.002054592池子代币,管理者收到5.000228288池子代币。 -## 推荐费 -对于合作伙伴应用程序,管理者可以在存款上设置推荐费。在SOL或质押存款期间,质押池将池代币费用的百分比重新分配给另一个地址作为推荐费。 +## 推荐费(佣金) + +对于合作伙伴应用程序,管理者可以在存款上设置推荐费。在SOL或质押存款期间,质押池将池子代币费用的百分比重新分配给另一个地址作为推荐费。 这个选项对钱包提供商特别有吸引力。当钱包集成质押池时,钱包开发者将有机会在用户存入质押池时赚取额外的代币。质押池管理者可以利用这个功能建立战略合作伙伴关系,并吸引更多人使用质押池! ## 最佳实践 + 除了货币化之外,费用是避免对质押池进行经济攻击并保持其运行的关键工具。为此,质押池CLI将防止管理者创建没有费用的池,除非他们还提供`--yolo`标志。 ### 纪元 + 如果一个有1000个验证者的质押池每个纪元运行一次重新平衡脚本,质押者需要发送大约200笔交易来更新质押池余额,然后多达1000笔交易来增加或减少每个验证者的质押。 -在撰写本文时,当前交易费用为每个签名 5,000 lampor,因此这1200笔交易的最低成本为 6,000,000 lampor,或0.006 SOL。为了收支平衡,质押池管理者每个纪元必须赚取0.006 SOL的费用。 +在撰写本文时,当前交易费用为每个签名 5,000 lamports ,因此这1200笔交易的最低成本为 6,000,000 lamports ,或0.006 SOL。为了收支平衡,质押池管理者每个纪元必须赚取0.006 SOL的费用。 例如,假设我们有一个质押了10,000 SOL的质押池,其质押赚取6% APY / ~3.3基点每个纪元的收益,每个纪元大约产生3.3 SOL的奖励。这个质押池的最低收支平衡纪元费用为0.18%。 ### 质押存款/提款 -如果质押池没有存款或提款费,恶意的池代币持有者可以轻易地从质押池中吸取价值。 -在最简单的攻击中,每个纪元的末尾,恶意的池代币持有者找到池中表现最好的验证者,提取相当于他们所有池代币的活跃质押,等待纪元滚动,赚取最大的质押奖励,然后立即重新存入质押池。 +如果质押池没有存款或提款费,恶意的池子代币持有者可以轻易地从质押池中窃取价值。 + +在最简单的攻击中,每个纪元的末尾,恶意的池子代币持有者找到池中表现最好的验证者,提取相当于他们所有池子代币的活跃质押,等待纪元滚动,赚取最大的质押奖励,然后立即重新存入质押池。 实际上,恶意存款人总是委托给质押池中表现最好的验证者,而从未真正向该验证者承诺质押。除此之外,恶意存款人绕过了任何纪元费用。 @@ -67,13 +77,13 @@ 为了完全安全,如果池中的一个违约验证者降低了性能,管理者可能希望提高更多。 ### SOL存款/提款 + 如果质押池的SOL存款/提款费为0,则恶意的SOL持有者可以执行类似的攻击,从池中提取更多价值。 如果他们将SOL存入质押池,提取池中顶级验证者的质押账户,等待纪元滚动,然后将该质押重新存入池中,然后提取SOL,他们基本上在没有任何时间承诺的情况下免费赚取了即时奖励。与此同时,质押池的性能下降了,因为存入的流动SOL没有赚取奖励。 例如,如果质押池中表现最好的验证者赚取6.15% APY / ~3.37基点每个纪元,那么最低的SOL存款/提款费应该是3.37基点。 -### 最后的想法 -前几节中概述的攻击是任何人都可以轻易执行的最简单的攻击,只需几次运行几个脚本即可。对于零费用或非常低费用的质押池,可能有更复杂的攻击,因此请确保用费用保护您的存款人! - +### 最后的思考 +前几节中概述的攻击是任何人都可以轻易执行的最简单的攻击,只需通过每个 epoch 运行几次几个个脚本即可。对于零费用或非常低费用的质押池,可能有更复杂的攻击,因此请确保用费用保护您的存款人! From 71a849f2e2ce73fcf7e5933cf72c965afd05eb19 Mon Sep 17 00:00:00 2001 From: RuoMinggX <117256259+Patrickming@users.noreply.github.com> Date: Sun, 21 Jul 2024 10:58:09 +0800 Subject: [PATCH 4/5] review operation.md --- .../stake-pool/operation.md | 52 +++++++++++++------ 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/docs/SolanaProgramLibrary/stake-pool/operation.md b/docs/SolanaProgramLibrary/stake-pool/operation.md index 426853c..090695d 100644 --- a/docs/SolanaProgramLibrary/stake-pool/operation.md +++ b/docs/SolanaProgramLibrary/stake-pool/operation.md @@ -1,19 +1,25 @@ # 操作 + 质押池是赚取质押奖励的另一种方法。这个链上程序将SOL汇集在一起,由质押者进行质押,允许SOL持有者质押并赚取奖励,而无需管理质押。 ## 质押 + SOL代币持有者可以通过将代币质押给一个或多个验证者来赚取奖励并帮助保护网络。质押代币的奖励基于当前的通胀率、网络上质押的SOL总数以及个别验证者的在线时间和佣金(费用)。 有关质押和质押编程的更多信息,请访问: + - https://solana.com/staking - https://docs.solana.com/staking/stake-programming ## 背景 + Solana的编程模型和本文档中使用的Solana术语的定义,请访问: + - https://docs.solana.com/apps - https://docs.solana.com/terminology -## 动机 +## 激励机制 + 本文档旨在为质押池系统的主要参与者提供信息: - 管理者:创建和管理质押池,赚取费用,可以更新费用、质押者和管理者 @@ -32,57 +38,64 @@ Solana的编程模型和本文档中使用的Solana术语的定义,请访问 或者,质押池管理者可以与钱包和质押账户提供商合作,进行直接的SOL存款。 ## 操作 -一个质押池管理者创建了一个质押池。此时,用户可以立即通过`deposit-sol`指令参与,将资金转移到储备中以换取池代币。 + +一个质押池管理者创建了一个质押池。此时,用户可以立即通过`deposit-sol`指令参与,将资金转移到储备中以换取池子代币。 使用这些SOL存款,质押者通过使用`add-validator`将“验证者质押账户”添加到池子中,从而包括将从池子中接收委托的验证者。在这个命令中,质押池使用储备资金创建一个新的质押账户并将其委托给所需的验证者。 此时,用户也可以将质押账户存入池子中。为此,他们必须将质押账户委托给质押池中的一个验证者。如果质押池有一个首选的存款验证者,用户必须将他们的质押委托给该验证者的投票账户。 -一旦质押在下一个纪元界限(最多2天)激活,用户就可以使用`deposit-stake`指令将他们的质押存入池中。 +一旦质押在下一个纪元边界(最多2天)激活,用户就可以使用`deposit-stake`指令将他们的质押存入池中。 作为他们存款(SOL或质押)的交换,用户收到代表他们在池中的分数所有权的SPL代币。池中赚取的奖励的一部分作为一个纪元费用归池管理者所有。 随着时间的推移,随着池中的质押累积奖励,用户的分数所有权将比他们最初的存款更有价值。 -当他们希望退出池时,用户可以使用`withdraw-sol`指令从质押池的储备中以质押池代币换取SOL。请注意,如果质押池的储备中没有足够的SOL,此操作将失败,这很正常,如果质押池管理者将池中的所有SOL都进行了质押。 +当他们希望退出池时,用户可以使用`withdraw-sol`指令从质押池的储备中以质押池子代币换取SOL。请注意,如果质押池的储备中没有足够的SOL,此操作将失败,这很正常,如果质押池管理者将池中的所有SOL都进行了质押。 -或者,他们可以使用`withdraw-stake`指令以他们的SPL池代币换取已激活的质押账户。用户将立即得到一个SOL质押账户。在任何情况下,始终可以提取质押。 +或者,他们可以使用`withdraw-stake`指令以他们的SPL池子代币换取已激活的质押账户。用户将立即得到一个SOL质押账户。在任何情况下,始终可以提取质押。 -注意:当提取质押时,如果用户想要提取质押账户中的SOL,他们必须首先停用质押账户并等待到下一个纪元界限(最多2天)。一旦质押不活跃,他们可以自由提取SOL。 +注意:当提取质押时,如果用户想要提取质押账户中的SOL,他们必须首先停用质押账户并等待到下一个纪元边界(最多2天)。一旦质押不活跃,他们可以自由提取SOL。 质押池质押者可以添加和移除验证者,或通过降低对验证者质押的份额,等待一个纪元将其移动到质押池的储备账户中,然后在另一个验证者上增加质押,来重新平衡池。 质押者添加新验证者的操作需要1.00228288 SOL来在验证者上创建质押账户,因此质押池储备需要流动性。 ### 资金限制 + 为了给管理者更多的控制权,质押池允许通过三种不同的“资金授权”对进入池中的资金进行存款和提款限制: -SOL存款 -质押存款 -SOL提款 +- SOL存款 +- 质押存款 +- SOL提款 -如果设置了该字段,则该授权必须签署相关指令。 +如果设置了这些属性,则该权限账户(authority)必须对关联的指令进行签名。。 例如,如果管理者设置了一个质押存款授权,那么该地址必须签署每个质押存款指令。 这在几种情况下也很有用: + - 控制谁可以向质押池存款 - 禁止某种形式的存款。例如,管理者只希望有SOL存款,因此他们设置了一个质押存款授权,使得只有在该授权签署交易的情况下才能存入质押账户。 - 维护模式。如果池需要时间来重置费用或以其他方式,管理者可以通过设置存款授权暂时限制新存款。 -注意:为了确保用户资金的安全,总是允许质押提款。 +注意:为了确保用户资金的安全,始终允许提款。 ## 资金安全 -质押池程序的主要目标之一是始终允许池代币持有者随时提取他们的资金。 + +质押池程序的主要目标之一是始终允许池子代币持有者随时提取他们的资金。 为此,让我们来看看质押池系统中的三种类别的质押账户: + - 验证者质押:活跃的质押账户,池中每个验证者一个 - 临时质押:正在激活或停用的质押账户,在停用后合并到储备中,或在激活后合并到验证者质押中,每个验证者一个 - 储备质押:不活跃的质押,被质押者用于重新平衡 + 此外,质押者可能会设定一个“首选提取账户”,强制用户从特定的质押账户提款。这是为了防止恶意存款者将质押池作为验证者之间的免费转换。 -- 在处理提款时,优先顺序如下: -- 首选提款的验证者质押账户(如果设定) +在处理提款时,优先顺序如下: + +- 首选提款的验证者质押账户(如果设置) - 验证者质押账户 - 临时质押账户 - 储备质押账户 @@ -99,28 +112,35 @@ SOL提款 通过这种方式,用户的资金永远不会处于风险中,始终可以赎回。 ## 附录 + ### 活跃质押 -如前所述,质押池使用活跃质押来维持质押池代币的可互换性。完全激活的质押与不活跃的、正在激活的或正在停用的质押不同,因为质押的时间成本。 + +如前所述,质押池与活跃质押配合使用,以保持质押池代币的可替代性。由于质押的时间成本,完全激活的质押并不等同于非活动、激活或停用的质押。 ### 临时质押账户 + 每个验证者都会得到一个临时质押账户,因此质押者一次只能对验证者执行一个动作。不可能同时增加和减少对验证者的质押。质押者必须等到现有的临时质押账户在一个`update`指令中合并后才能执行新动作。 ### 储备质押账户 + 每个质押池都初始化了一个未委托的储备质押账户,用于在重新平衡过程中持有未委托的质押。当质押者减少对验证者的质押时,并在经历一个纪元后,更新操作会将减少的质押合并到储备中。相反,每当质押者增加对验证者的质押时,就会从储备质押账户中提取lamports。 ### 验证者列表账户 + 每个质押池都包含两个数据账户:质押池和验证者列表。 -质押池包含有关池子的总体信息,包括费用、池代币铸造、管理金额等。 +质押池包含有关池子的总体信息,包括费用、池子代币铸造、管理金额等。 验证者列表包含有关池中每个验证者质押账户的特定信息。这些信息包括池在验证者上质押的SOL金额,以及在验证者上激活/停用的SOL金额。 每个质押池都必须有自己的验证者列表账户,否则初始化时会失败。 ### 交易大小 + Solana交易处理器有两个重要的限制: - 整体交易的大小,限制在大约 1 MTU /数据包 - 每个指令的计算预算 一个质押池可能管理数百个质押账户,因此不可能在一条指令中更新质押池的总价值。幸运的是,命令行工具将会拆分交易,以避免大型池子遇到这个问题。 + From c6b6bf91c7f27461d0679213467359eac5687f82 Mon Sep 17 00:00:00 2001 From: RuoMinggX <117256259+Patrickming@users.noreply.github.com> Date: Sun, 21 Jul 2024 11:04:09 +0800 Subject: [PATCH 5/5] review quickstart.md --- .../stake-pool/quickstart.md | 54 +++++++++++++------ 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/docs/SolanaProgramLibrary/stake-pool/quickstart.md b/docs/SolanaProgramLibrary/stake-pool/quickstart.md index 21e8331..9188e7c 100644 --- a/docs/SolanaProgramLibrary/stake-pool/quickstart.md +++ b/docs/SolanaProgramLibrary/stake-pool/quickstart.md @@ -1,8 +1,11 @@ # 快速开始指南 -本指南适用于希望立即开始运行质押池的管理人员。 + +本指南适用于希望立即开始运行质押池的管理者。 ## 前提条件 + 本指南需要 Solana CLI 工具套件和 Stake Pool CLI 工具。 + - [安装 Solana 工具](https://docs.solana.com/cli/install-solana-cli-tools) - [安装 Stake Pool CLI](https://spl.solana.com/stake-pool/cli) @@ -12,9 +15,10 @@ 如果你在 开发网 或 测试网 上运行,可以使用 `solana airdrop 1` 来空投资金。 -如果你在 主网beta版 上运行,则必须通过其他方式(如从交易所或朋友处等)购买资金。 +如果你在 主网beta版 上运行,则必须通过其他方式(如从交易所或朋友等处)购买资金。 ## 示例脚本 + 本指南使用 [GitHub 上的示例脚本](https://github.com/solana-labs/solana-program-library/tree/master/stake-pool/cli/scripts) 来快速轻松地运行所有内容。 你将看到以下脚本: @@ -29,14 +33,18 @@ 本指南将使用大多数这些脚本在本地网络上设置质押池。 ## (可选)步骤 0:设置本地网络以进行测试 + 所有这些脚本都可以在 开发网、测试网 或 主网beta版 上运行,但为了进行更多实验,我们将使用 `setup-test-validator.sh` 设置一个带有一些验证者投票账户的本地验证者。 该脚本接受要创建的投票账户数量和输出验证者投票账户的文件路径,例如: -``` + +```bash $ ./setup-test-validator.sh 10 local_validators.txt ``` + 这大约需要 10 秒钟,最终会输出一个包含 base58 编码公钥列表的文件。这些代表本地网络上的验证者投票账户,例如: -``` + +```bash EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ J3xu64PWShcMen99kU3igxtwbke2Nwfo8pkZNRgrq66H 38DYMkwYCvsj8TC6cNaEvFHHVDYeWDp1qUgMgyjNqZXk @@ -51,26 +59,28 @@ DrT6VGqqJT1GRVaZmuEjNim4ie7ecmNixjiycd67jyJy 注意:如果另一个 `solana-test-validator` 已经在运行,这将会失败。 -*本地网络的重要注意事项* +### 本地网络的重要注意事项 如果你使用的是 32 个槽位的纪元,那么在使用某个质押池命令时,则很有可能在使用其中一个质押池命令时传递一个纪元,导致其失败并显示:`Custom program error: 0x11`。这是完全正常的,并且在其他网络上不会发生。你只需重新运行命令。 由于测试验证者网络上没有投票活动,你需要在使用 `solana delegate-stake` 时使用 `--force` 标志,例如: -``` +```bash $ solana delegate-stake --force stake.json CzDy6uxLTko5Jjcdm46AozMmrARY6R2aDBagdemiBuiT ``` ## 步骤 1:创建质押池 + 我们的下一个脚本是 `setup-stake-pool.sh`。在其中,你会看到一个很大的区域可以在其中修改你的质押池参数。这些参数用于创建新的质押池,并包括: + - 纪元(epoch)费用,以两个不同的标志表示,分子和分母 - 提款费用,以两个不同的标志表示,分子和分母 - 存款费用,以两个不同的标志表示,分子和分母 -- 推荐费用,以 0 到 100 之间的数字表示(包括 0 和 100) +- 推荐费用(佣金),以 0 到 100 之间的数字表示(包括 0 和 100) - 最大验证者数量(目前最高可能是 2,950) -- (可选)存款授权,用于受限池 +- (可选)存款授权,用于受限制的池 -虽然费用在此时似乎不太有趣或有欺骗性,但请考虑运行质押池的成本,以及如果没有费用,可能会有恶意行为者滥用你的池子。 +虽然费用在此时似乎不太有趣或有欺骗性,但请考虑运行质押池的成本,以及潜在的恶意行为者,如果您的权益池没有费用,他们可能会滥用您的权益池。 这些参数中的每一个在池子创建后都是可修改的,因此不必担心被锁定在任何选择中。 @@ -79,7 +89,8 @@ $ solana delegate-stake --force stake.json CzDy6uxLTko5Jjcdm46AozMmrARY6R2aDBagd 仔细阅读[费用](https://spl.solana.com/stake-pool/fees)以获取有关费用和最佳实践的更多信息。 在我们的示例中,我们将使用 0.3% 的费用、50% 的推荐费用,选择不设置存款授权,并拥有最大数量的验证 -``` + +```bash $ ./setup-stake-pool.sh 15 Creating pool + spl-stake-pool create-pool --epoch-fee-numerator 3 --epoch-fee-denominator 1000 --withdrawal-fee-numerator 3 --withdrawal-fee-denominator 1000 --deposit-fee-numerator 3 --deposit-fee-denominator 1000 --referral-fee 50 --max-validators 2350 --pool-keypair keys/stake-pool.json --validator-list-keypair keys/validator-list.json --mint-keypair keys/mint.json --reserve-keypair keys/reserve.json @@ -95,26 +106,30 @@ Update not required Using existing associated token account DgyZrAq88bnG1TNRxpgDQzWXpzEurCvfY2ukKFWBvADQ to receive stake pool tokens of mint BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB, owned by 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn Signature: 4jnS368HcofZ1rUpsGZtmSK9kVxFzJRndSX5VS7eMV3kVgzyg9efA4mcgd2C6BoSNksTmTonRGXTVM1WMywFpiKq ``` + 你的质押池现在已经存在了!对于最大数量的验证者,此阶段的成本约为 2.02 SOL,加上存入池中的 15 SOL 以换取池代币。 ## 步骤 2:向池中存入 SOL + 现在池子已经存在,让我们存入一些 SOL 以换取一些池代币。 SOL 可能是最具吸引力的存款形式,因为它对每个人来说都是最容易使用的。通常,这可能通过 DeFi 应用或钱包完成,但在我们的示例中,我们将直接从命令行进行操作。 在创建池子时,我们已经存入了 15 SOL,但现在让我们再向池中存入 10 SOL: -``` + +```bash $ spl-stake-pool deposit-sol Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR 10 Using existing associated token account DgyZrAq88bnG1TNRxpgDQzWXpzEurCvfY2ukKFWBvADQ to receive stake pool tokens of mint BoNneHKDrX9BHjjvSpPfnQyRjsnc9WFH71v8wrgCd7LB, owned by 4SnSuUtJGKvk2GYpBwmEsWG53zTurVM8yXGsoiZQyMJn Signature: 4AJv6hSznYoMGnaQvjWXSBjKqtjYpjBx2MLezmRRjWRDa8vUaBLQfPNGd3kamZNs1JeWSvnzczwtzsMD5WkgKamA ``` ## 步骤 3:向池中添加验证者 + 现在池中已经有了一些 SOL,我们需要向其中添加验证者。 使用 `add-validators.sh` 脚本,我们将把在步骤 0 中创建的每个验证者添加到质押池中。如果你在其他网络上运行,可以创建一个包含验证者投票账户的文件。 -``` +```bash $ ./add-validators.sh keys/stake-pool.json local_validators.txt Adding validator stake accounts to the pool Adding stake account 3k7Nwu9jUSc6SNG11wzufKYoZXRFgxWamheGLYWp5Rvx, delegated to EhRbKi4Vhm1oUCGWHiLEMYZqDrHwEd7Jgzgi26QJKvfQ @@ -122,20 +137,24 @@ Signature: 5Vm2n3umPXFzQgDiaib1B42k7GqsNYHZWrauoe4DUyFszczB7Hjv9r1DKWKrypc8KDiUc Signature: 3XtmYu9msqnMeKJs9BopYjn5QTc5hENMXXiBwvEw6HYzU5w6z1HUkGwNW24io4Vu9WRKFFN6SAtrfkZBLK4fYjv4 ... (something similar repeated 9 more times) ``` + 此操作将从储备中移动 1.00228288 SOL 到给定验证者的质押账户。这意味着您要添加的每个验证者都需要超过 1 个 SOL。 -## 步骤 4:向池中存入质押 +## 步骤 4:向池中质押 + 现在你的池中已有验证者,它可以接受质押账户供您管理。存款有两种可能来源:SOL 或质押账户。在步骤 2 中,我们直接存入了 SOL,所以现在我们将存入质押账户。 此选项对已经拥有质押账户的用户特别有吸引力,他们可能希望换取质押池代币,或者希望进一步分散他们的质押。 `deposit.sh` 脚本展示了如何使用 CLI 来实现这一点。 创建新的质押,将给定数量的资金存入池中的每个质押账户,使用质押池和验证者文件。 -``` + +```bash $ ./deposit.sh keys/stake-pool.json local_validators.txt 10 ``` ## 步骤 5:重新平衡池中的质押 + 随着时间的推移,当人们将 SOL 存入储备时,或者随着验证者性能的变化,你可能需要重新分配质押。最佳方式是通过一个自动化系统来收集关于质押池和网络的信息,并决定分配给每个验证者的质押数量。 Solana 基金会为其委托计划维护了一个开源机器人,可以为你的质押池进行适配。源码是 [stake-o-matic GitHub仓库](https://github.com/solana-labs/stake-o-matic/tree/master/bot) 的一部分。 @@ -143,14 +162,17 @@ Solana 基金会为其委托计划维护了一个开源机器人,可以为你 此外,还有一个正在开发中的 Python 质押池机器人,可以在 [stake-pool-py on GitHub](https://github.com/solana-labs/solana-program-library/tree/master/stake-pool/py) 中找到。 在我们的示例中,我们将运行一个简单的池重新平衡器,它会按给定数量增加列表中每个验证者的质押。没有任何检查或逻辑来确保这是有效的。 -``` + +```bash $ ./rebalance.sh keys/stake-pool.json local_validators.txt 100 ``` ## 步骤 6:从质押池中提款 + 最后,如果用户想从质押池中提款,他们可以选择从储备中提取 SOL(如果储备中有足够的 SOL),或者从池中的某个质押账户中提取。 `withdraw.sh` 脚本根据质押池、验证者文件和金额,从池中的每个质押账户中移除质押和 SOL。 -``` + +```bash $ ./withdraw.sh keys/stake-pool.json local_validators.txt 100 ```