V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
gitandgit
V2EX  ›  区块链

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

  •  
  •   gitandgit · 2021-08-28 15:03:50 +08:00 · 671 次点击
    这是一个创建于 1217 天前的主题,其中的信息可能已经有所发展或是发生改变。

    集成 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>'
    
    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2812 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 06:50 · PVG 14:50 · LAX 22:50 · JFK 01:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.