[stacks 区块链中文开发文档] 了解如何将 Stacking 质押功能添加到您的钱包或交易所

2021-08-28 15:03:50 +08:00
 gitandgit

集成 stacks 区块链相关的软件和工具

原英文文档链接: https://docs.stacks.co/build-apps/guides/integrate-stacking

了解如何将 Stacking 质押功能添加到您的钱包或交易所

尝试Stacks 钱包,以代币持有者的身份体验 Stacking(质押)流程。

介绍

在本教程中,您将学习如何通过与相应的智能合约程序交互,以及如何从 Stacks 区块链读取数据来集成 Stacking 。

本教程重点介绍以下功能:

除了使用 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 字段

恭喜你!完成此步骤后,您就成功地学会了如何:

其他:奖励

目前,Stacking 库没有提供获取某固定地址已经支付的奖励的方法。但是,Stacks 区块链 API 公开了端点以便获取更多详细信息。 例如,如果您想获得已经支付给 btcAddress 的奖励数量,您可以使用以下的 API 调用:

# for mainnet, replace `testnet` with `mainnet`
curl 'https://stacks-node-api.testnet.stacks.co/extended/v1/burnchain/rewards/<btcAddress>'
648 次点击
所在节点    区块链
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/798509

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX