集成 stacks 区块链相关的软件和工具
原英文文档链接: https://doc.stacks.co/build-apps/guides/integrate-stacking
了解如何将 Stacking 质押功能添加到您的钱包或交易所
尝试Stacks 钱包,以代币持有者的身份体验 Stacking(质押)流程。
介绍
在本教程中,您将学习如何通过与相应的智能合约程序交互,以及如何从 Stacks 区块链读取数据来集成 Stacking 。
本教程重点介绍以下功能:
生成 Stacks 帐户
显示质押信息
验证质押资格
添加质押动作
显示质押状态
除了使用 JS 库进行集成,您还可以使用 Rust CLI 或者 JS CLI.
首先,您需要了解质押机制。
您还需要 NodeJS 12.10.0 或更高版本才能完成本教程。您可以通过打开终端,并运行以下命令来验证您已经安装的 NodeJS 版本:
node --version
概述
在本教程中,我们将实现质押指南中所列出的质押流程。
第 1 步:集成库
安装 stacking 、网络、事务库和 bn.js , 为大量处理运算做准备:
npm install --save @stacks/stacking @stacks/network @stacks/transactions bn.js
点击查看更多的stacking 库参考
第 2 步:生成账户并初始化
首先,让我们创建一个新的随机的 Stacks 2.0 帐户:
import { makeRandomPrivKey, privateKeyToString, getAddressFromPrivateKey, TransactionVersion, } from '@stacks/transactions'; import { StackingClient } from '@stacks/stacking'; import { StacksTestnet, StacksMainnet } from '@stacks/network'; import BN from 'bn.js'; // generate random key or use an existing key const privateKey = privateKeyToString(makeRandomPrivKey()); // get Stacks address // for mainnet, remove the TransactionVersion const stxAddress = getAddressFromPrivateKey(privateKey, TransactionVersion.Testnet); // instantiate the Stacker class for testnet // for mainnet, use `new StacksMainnet()` const client = new StackingClient(stxAddress, new StacksTestnet());
你可以通过查看帐户指南以了解更多详细信息
第 3 步:显示质押信息
为了告知用户即将到来的奖励周期,我们可以通过以下方式获取 Stacking 质押信息:通过获取到的 PoX 传输证明信息,你可以向用户展示下一个周期是否已经执行过 Stacking 质押,下一个质押轮次开始的时间,一个质押周期所持续的时间,以及参与质押所需的最小数量的 STX:
// will Stacking be executed in the next cycle? const stackingEnabledNextCycle = await client.isStackingEnabledNextCycle(); // true or false // how long (in seconds) is a Stacking cycle? const cycleDuration = await client.getCycleDuration(); // 120 // how much time is left (in seconds) until the next cycle begins? const secOndsUntilNextCycle= await client.getSecondsUntilNextCycle(); // 600000
请注意:质押周期的持续时间和参与门槛,在主网和测试网的不同环境下,会有所不同。
如果需要,您还可以使用以下方法检索原始的 PoX 传输证明和核心信息:
const poxInfo = await client.getPoxInfo(); // poxInfo: // { // contract_id: 'ST000000000000000000002AMW42H.pox', // first_burnchain_block_height: 0, // min_amount_ustx: 83335083333333, // prepare_cycle_length: 30, // rejection_fraction: 3333333333333333, // reward_cycle_id: 17, // reward_cycle_length: 120, // rejection_votes_left_required: 0, // total_liquid_supply_ustx: 40000840000000000 // } const coreInfo = await client.getCoreInfo(); // coreInfo: // { // peer_version: 385875968, // pox_consensus: 'bb88a6e6e65fa7c974d3f6e91a941d05cc3dff8e', // burn_block_height: 2133, // stable_pox_consensus: '2284451c3e623237def1f8caed1c11fa46b6f0cc', // stable_burn_block_height: 2132, // server_version: 'blockstack-core 0.0.1 => 23.0.0.0 (HEAD:a4deb7a+, release build, linux [x86_64])', // network_id: 2147483648, // parent_network_id: 3669344250, // stacks_tip_height: 1797, // stacks_tip: '016df36c6a154cb6114c469a28cc0ce8b415a7af0527f13f15e66e27aa480f94', // stacks_tip_consensus_hash: 'bb88a6e6e65fa7c974d3f6e91a941d05cc3dff8e', // unanchored_tip: '6b93d2c62fc07cf44302d4928211944d2debf476e5c71fb725fb298a037323cc', // exit_at_block_height: null // } const targetBlocktime = await client.getTargetBlockTime(); // targetBlocktime: // 120
用户需要有足够的 Stacks (STX) 代币才能参与质押。这可以很容易地验证:
const hasMinStxAmount = await client.hasMinimumStx(); // true or false
如果是测试,你可以通过“水龙头”获得测试网络的 STX 代币,用你的 STX 地址代替下面命令行中的<stxAddress>
curl -XPOST "https://stacks-node-api.testnet.stacks.co/extended/v1/faucets/stx?address=<stxAddress>&stacking=true"
您必须等待几分钟才能完成交易。用户可以选择他们想要参与质押的周期数。为了帮助用户更容易做出决定,可以估计解锁质押的时间:
// this would be provided by the user let numberOfCycles = 3; // the projected datetime for the unlocking of tokens const unlockingAt = new Date(new Date().getTime() + secondsUntilNextCycle); unlockingAt.setSeconds(unlockingAt.getSeconds() + cycleDuration * numberOfCycles);
第 4 步:验证质押资格
此时,您的软件会显示质押的详细信息。如果质押将被执行,并且用户有足够的资金,则应要求用户提供要锁定的 microstacks 数量,用户还要输入接收支付奖励的比特币的地址。 有了这个输入和前面步骤的数据,我们可以确定下一个奖励周期的资格:
// user supplied parameters // BTC address must start with "1" or "3". Native Segwit (starts with "bc1") is not supported let btcAddress = '1Xik14zRm29UsyS6DjhYg4iZeZqsDa8D3'; let numberOfCycles = 3; const stackingEligibility = await client.canStack({ poxAddress: btcAddress, cycles: numberOfCycles, }); // stackingEligibility: // { // eligible: false, // reason: 'ERR_STACKING_INVALID_LOCK_PERIOD', // }
请注意,资格检查,假设用户在质押帐户中有可用的余额。
资格检查只是对 PoX 智能合约的只读函数调用,不需要广播交易
如果用户符合条件,则应在界面上启用质押操作。如果没有,则应向用户显示相应的错误消息。
第 5 步:将 STX 代币锁定到 stacks 区块链
接下来,应该执行质押操作。
// set the amount to lock in microstacks const amountMicroStx = new BN(100000000000); // set the burnchain (BTC) block for stacking lock to start // you can find the current burnchain block height from coreInfo above // and adding 3 blocks to provide a buffer for transaction to confirm const burnBlockHeight = 2133 + 3; // execute the stacking action by signing and broadcasting a transaction to the network client .stack({ amountMicroStx, poxAddress: btcAddress, cycles: numberOfCycles, privateKey, burnBlockHeight, }) .then(respOnse=> { // If successful, stackingResults will contain the txid for the Stacking transaction // otherwise an error will be returned if (response.hasOwnProperty('error')) { console.log(response.error); throw new Error('Stacking transaction failed'); } else { console.log(`txid: ${response}`); // txid: f6e9dbf6a26c1b73a14738606cb2232375d1b440246e6bbc14a45b3a66618481 return response; } });
交易完成将需要几分钟时间。每个账户 /地址在任何时候都只有一个质押交易处于活动状态。来自同一帐户的多个 /并发的质押操作将会失败。
第 6 步:确认锁定
新交易不会立即完成。它会在几分钟内保持 pending 挂起状态。我们需要轮询这个状态,直到事务状态变为 success 成功。我们就可以使用 Stacks 区块链 API 客户端库来检查交易状态。
const { TransactionsApi } = require('@stacks/blockchain-api-client'); const tx = new TransactionsApi(apiConfig); const waitForTransactiOnSuccess= txId => new Promise((resolve, reject) => { const pollingInterval = 3000; const intervalID = setInterval(async () => { const resp = await tx.getTransactionById({ txId }); if (resp.tx_status === 'success') { // stop polling clearInterval(intervalID); // update UI to display stacking status return resolve(resp); } }, pollingInterval); }); // note: txId should be defined previously const resp = await waitForTransactionSuccess(txId);
有关交易生命周期的更多详细信息,请参阅交易指南
作为轮询的替代方案,Stacks 区块链 API 客户端库提供了 WebSockets 。WebSockets 可用于订阅特定更新,例如交易状态更改。下面是一个例子:
const client = await connectWebSocketClient('ws://stacks-node-api.blockstack.org/'); // note: txId should be defined previously const sub = await client.subscribeAddressTransactions(txId, event => { console.log(event); // update UI to display stacking status }); await sub.unsubscribe();
步骤 7:显示质押状态
交易完成后,Stacks 代币在锁定期间会被锁定。在此期间,您的应用程序可以显示以下详细信息:解锁时间、锁定的 STX 代币数量和用于奖励的比特币地址。
const stackingStatus = await client.getStatus(); // If stacking is active for the account, you will receive the stacking details // otherwise an error will be thrown // stackingStatus: // { // stacked: true, // details: { // amount_microstx: '80000000000000', // first_reward_cycle: 18, // lock_period: 10, // burnchain_unlock_height: 3020, // pox_address: { // version: '00', // hashbytes: '05cf52a44bf3e6829b4f8c221cc675355bf83b7d' // } // } // }
请注意,pox_address 属性是 PoX 合约程序对奖励 BTC 地址的内部表示。
为了显示解锁时间,你需呀使用 firstRewardCycle 和 lockPeriod 字段
恭喜你!完成此步骤后,您就成功地学会了如何:
生成 Stacks 帐户
显示质押信息
验证质押资格
添加质押动作
显示质押状态
其他:奖励
目前,Stacking 库没有提供获取某固定地址已经支付的奖励的方法。但是,Stacks 区块链 API 公开了端点以便获取更多详细信息。 例如,如果您想获得已经支付给 btcAddress 的奖励数量,您可以使用以下的 API 调用:
# for mainnet, replace `testnet` with `mainnet` curl 'https://stacks-node-api.testnet.stacks.co/extended/v1/burnchain/rewards/<btcAddress>'