集成 stacks 区块链相关的软件和工具
原英文文档链接: https://docs.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>'