stacks 区块链开发指南|如何提示用户签名交易,并将交易广播到 Stacks 区块链

2021-09-02 16:29:39 +08:00
 gitandgit

原英文文档地址:

https://docs.stacks.co/build-apps/guides/transaction-signing

签名交易

提示用户签名交易,并将交易广播到 Stacks 区块链

介绍

本指南解释了如何通过实现 Stacks.js 的连接包来提示用户签署交易并将它们广播到 Stacks 区块链。

交易签名为用户提供了一种方法,让用户执行与应用程序相关的 Clarity 智能合约,然后合理地处理结果.

用户可以签署交易来交换可替代或者不可替代的代币,并提供前期保证,帮助他们保持对数字资产的控制。交易分为三种类型:

  1. STX 传输

  2. 智能合约部署

  3. 智能合约执行

有关此功能在实践中的具体示例,请参阅公共注册教程。

安装依赖项

为了使用 Stacks 钱包的最新交易签名,请使用 @stacks/connect NPM 包的第 5 版。

必须安装以下依赖项:

npm install @stacks/connect@^5

发起会话

用户必须先对应用程序进行身份验证,然后 connect 连接包将提示他们使用身份验证器(如 Stacks 钱包)对交易进行签名并广播到 Stacks 区块链。

在继续集成以下交易签名功能之前,请参阅身份验证指南,以防 userSession .isUserSignedIn() 返回 true 。

获取用户的 Stacks 地址

在您的用户使用他们的 Stacks 钱包进行身份验证后,您可以从他们的 profile 个人资料中获取他们的 Stacks 地址。

const profile = userSession.loadUserData().profile.stxAddress;

const mainnetAddress = stxAddresses.mainnet;
// "SP2K5SJNTB6YP3VCTCBE8G35WZBPVN6TDMDJ96QAH"
const testnetAddress = stxAddresses.testnet;
// "ST2K5SJNTB6YP3VCTCBE8G35WZBPVN6TDMFEVESR6"

提示转移 STX

调用 connect 包所提供的 openSTXTransfer 函数,来触发显示转账 STX 的交易签名提示:

import { openSTXTransfer } from '@stacks/connect';
import { StacksTestnet } from '@stacks/network';

openSTXTransfer({
  recipient: 'ST2EB9WEQNR9P0K28D2DC352TM75YG3K0GT7V13CV',
  amount: '100',
  memo: 'Reimbursement',
  network: new StacksTestnet(), // for mainnet, `new StacksMainnet()`
  appDetails: {
    name: 'My App',
    icon: window.location.origin + '/my-app-logo.svg',
  },
  onFinish: data => {
    console.log('Stacks Transaction:', data.stacksTransaction);
    console.log('Transaction ID:', data.txId);
    console.log('Raw transaction:', data.txRaw);
  },
});

有几个参数可用于调用 openSTXTransfer 。以下是它们的一些接口:

interface STXTransferOptions {
  recipient: string;
  amount: string;
  memo?: string;
  network: StacksNetwork;
  appDetails: {
    name: string;
    icon: string;
  };
  onFinish: (data: FinishedTxData) => void;
}
参数 类型 返回 描述
recipient string true 转账接收者的 STX 地址
amount string true 要传输的 microstacks 数量( 1 STX = 1,000,000 个 microstacks )以字符串形式提供,以防止浮点错误。
appDetails object true 需要应用程序 name 和 icon 的字典
onFinish function true 当交易被签名和广播时由应用程序执行的回调。
memo string false 包含在交易中的可选备忘录
network StacksNetwork false 指定应完成此事务的网络。

提示部署智能合约程序

调用 connect 包提供的 openContractDeploy 函数,触发显示部署智能合约的交易签名提示:

import { openContractDeploy } from '@stacks/connect';

const codeBody = '(begin (print "hello, world"))';

openContractDeploy({
  contractName: 'my-contract-name',
  codeBody,
  appDetails: {
    name: 'My App',
    icon: window.location.origin + '/my-app-logo.svg',
  },
  onFinish: data => {
    console.log('Stacks Transaction:', data.stacksTransaction);
    console.log('Transaction ID:', data.txId);
    console.log('Raw transaction:', data.txRaw);
  },
});

有几个参数可用于调用 openContractDeploy 。这是它们的接口:

interface ContractDeployOptions {
  codeBody: string;
  contractName: string;
  network: StacksNetwork;
  appDetails: {
    name: string;
    icon: string;
  };
  onFinish: (data: FinishedTxData) => void;
}
参数 类型 返回 描述
codeBody string true 合约的 Clarity 源代码
contractName string true 智能合约程序的名称
appDetails object true 需要应用程序 name 和 icon 的字典
onFinish function true 当交易被签名和广播时由应用程序执行的回调。
network StacksNetwork false 指定应完成此事务的网络。

合约将部署到已经经过身份验证的用户的 Stacks 地址。

提示执行智能合约程序

调用 connect 包提供的 openContractCall 函数,触发显示执行合约的交易签名提示。 以这个简单的 Clarity 合约为例:

(define-public
  (my-func
    (arg-uint uint)
    (arg-int int)
    (arg-buff (buff 20))
    (arg-string-ascii (string-ascii 20))
    (arg-string-utf8 (string-utf8 20))
    (arg-principal principal)
    (arg-bool bool)
  )
  (ok u0)
)

要执行此函数,请调用 openContractCall 方法。使用来自 @stacks/transactions 的 ClarityValue 类型来构造格式正确的参数。

import { openContractCall } from '@stacks/connect';
import {
  uintCV,
  intCV,
  bufferCV,
  stringAsciiCV,
  stringUtf8CV,
  standardPrincipalCV,
  trueCV,
} from '@stacks/transactions';

const functionArgs = [
  uintCV(1234),
  intCV(-234),
  bufferCV(Buffer.from('hello, world')),
  stringAsciiCV('hey-ascii'),
  stringUtf8CV('hey-utf8'),
  standardPrincipalCV('STB44HYPYAT2BB2QE513NSP81HTMYWBJP02HPGK6'),
  trueCV(),
];

const options = {
  contractAddress: 'ST22T6ZS7HVWEMZHHFK77H4GTNDTWNPQAX8WZAKHJ',
  contractName: 'my-contract',
  functionName: 'my-func',
  functionArgs,
  appDetails: {
    name: 'My App',
    icon: window.location.origin + '/my-app-logo.svg',
  },
  onFinish: data => {
    console.log('Stacks Transaction:', data.stacksTransaction);
    console.log('Transaction ID:', data.txId);
    console.log('Raw transaction:', data.txRaw);
  },
};

await openContractCall(options);

有几个参数可用于调用 openContractCall 。这是它们的接口:

interface ContractCallOptions {
  contractAddress: string;
  functionName: string;
  contractName: string;
  functionArgs?: ClarityValue[];
  network: StacksNetwork;
  appDetails: {
    name: string;
    icon: string;
  };
  onFinish: (data: FinishedTxData) => void;
}
参数 类型 返回 描述
contractAddress string true 部署合约程序的 STX 地址
contractName string true 签订合约程序的名称
functionName string true 签名 /执行的函数名,必须是公共函数。
functionArgs ClarityValue[] true 调用函数的参数。了解有关构建 clarity 值的更多信息。默认为 []。
appDetails object true 需要应用程序 name 和 icon 的字典
onFinish function true 当交易被签名和广播时由应用程序执行的回调。
network StacksNetwork false 指定应完成此事务的网络。

获取完成后已签名的交易

@stacks/connect 中的每个交易签名方法都允许您指定一个 onFinish 回调。此回调将在用户成功广播其交易后触发。交易将被广播,但它会一直是等待处理的状态,直到它在 Stacks 区块链上被矿工打包数据并出块。您可以通过传递给 onFinish 的参数访问有关此交易的一些信息。您的回调将使用单个参数触发,该参数是具有以下属性的对象:

interface FinishedTxData {
  stacksTransaction: StacksTransaction;
  txRaw: string;
  txId: string;
}

StacksTransaction 类型来自 @stacks/transactions 库。txId 属性可用于提供在资源管理器中查看交易的链接。

const onFinish = data => {
  const explorerTransactionUrl = 'https://explorer.stacks.co/txid/${data.txId}';
  console.log('View transaction in explorer:', explorerTransactionUrl);
};

为转账交易指定网络

此页面中包含的所有方法都接受一个 network 网络选项。默认情况下,Connect 使用 testnet 网络选项。您可以从 @stacks/network 包中导入网络配置。

import { StacksTestnet, StacksMainnet } from '@stacks/network';

const testnet = new StacksTestnet();
const mainnet = new StacksMainnet();

// use this in your transaction signing methods:

openSTXTransfer({
  network: mainnet,
  // other relevant options
});

在 React 应用程序中的使用

从 connect-react 包中导入 useConnect, 使交易签名更无缝地集成到 React 应用程序中。

npm install @stacks/connect-react

每个交易签名方法本身都可以作为 useConnect 返回的函数使用,但为了与 React 操作命名标准保持一致,前缀为 do:

使用具有与上述相同的参数的这些函数。但是,您不必指定 appDetails,因为如果已将 useConnect 用于身份验证,则会自动检测到它们。

import { useConnect } from '@stacks/connect-react';

const MyComponent = () => {
  const { doContractCall } = useConnect();

  const onClick = async () => {
    const options = {
      /** See examples above */
    };
    await doContractCall(options);
  };

  return <span onClick={onClick}>Call my contract</span>;
};

从“水龙头”请求测试网的 STX 代币

在使用 Stacks 测试网开发应用程序时,您可以从 Stacks Explorer 沙盒环境中 请求测试网 STX 代币。

交易请求 /响应负载

在后台,@stacks/connect 将序列化和反序列化您的应用程序和 Stacks 钱包之间的数据。这些有效载荷是符合 JSON Web Token (JWT) 标准的代币,并额外支持比特币和许多其他加密货币使用的 secp256k1 曲线.

交易请求有效负载

当应用程序从 @stacks/connect 触发一个交易时,该交易的选项被序列化为 transactionRequest 有效负载。transactionRequest 类似于用于身份验证的 authRequest 有效负载。除了标准的 JWT 必需字段之外,交易请求有效负载还具有以下架构:

interface TransactionRequest {
  appDetails?: {
    name: string;
    icon: string;
  };
  // 1 = "allow", 2 = "deny".
  postConditionMode?: PostConditionMode; // number
  // Serialized version of post conditions
  postConditions?: string[];
  // JSON serialized version of `StacksNetwork`
  // This allows the app to specify their default desired network.
  // The user may switch networks before broadcasting their transaction.
  network?: {
    coreApiUrl: string;
    chainID: ChainID; // number
  };
  // `AnchorMode` defined in `@stacks/transactions`
  anchorMode?: AnchorMode; // number
  // The desired default stacks address to sign with.
  // There is no guarantee that the transaction is signed with this address;
  stxAddress?: string;
  txType: TransactionDetails; // see below
}

export enum TransactionTypes {
  ContractCall = 'contract_call',
  ContractDeploy = 'smart_contract',
  STXTransfer = 'token_transfer',
}

interface ContractCallPayload extends TransactionRequest {
  contractAddress: string;
  contractName: string;
  functionName: string;
  // Serialized Clarity values to be used as arguments in the contract call
  functionArgs: string[];
  txType: TransactionTypes.ContractCall;
}

interface ContractDeployPayload extends TransactinRequest {
  contractName: string;
  // raw source code for this contract
  codeBody: string;
  txType: TransactionTypes.ContractDeploy;
}

interface StxTransferPayload extends TransactionRequest {
  recipient: string;
  // amount for this transaction, in microstacks
  amount: string;
  memo?: string;
  txType: TransactionTypes.STXTransfer;
}

交易响应负载

在用户签署并广播交易后,transactionResponse 负载将发送回您的应用程序。

interface TransactionResponse {
  txId: string;
  // hex serialized version of this transaction
  txRaw: string;
}

注入 StacksProvider 变量

当用户安装了stacks 钱包浏览器扩展程序时,该扩展程序会将全局 StacksProvider 变量注入到您的 Web 应用程序的 JavaScript 代码中。这允许您的 JavaScript 代码挂钩到扩展程序,并发出身份验证和交易请求。 @stacks/connect 会自动为你检测并使用这个全局变量。

目前,只有stacks 钱包浏览器扩展程序包含 StacksProvider,但是,理想情况下,更多的钱包(和手机钱包)会支持这种格式,这样你的应用程序就可以与任何具有嵌入 Web 应用程序功能的 Stacks 钱包兼容。

在您的 Web 应用程序中,您可以通过检查 window.StacksProvider 的存在来检查用户是否安装了兼容的钱包。下面 StacksProvider 变量的接口。

interface StacksProvider {
  /**
   * Make a transaction request
   *
   * @param payload - a JSON web token representing a transaction request
   */
  transactionRequest(payload: string): Promise<TransactionResponse>;
  /**
   * Make an authentication request
   *
   * @param payload - a JSON web token representing an auth request
   *
   * @returns an authResponse string in the form of a JSON web token
   */
  authenticationRequest(payload: string): Promise<string>;
  getProductInfo:
    | undefined
    | (() => {
        version: string;
        name: string;
        meta?: {
          tag?: string;
          commit?: string;
          [key: string]: any;
        };
        [key: string]: any;
      });
}
653 次点击
所在节点    区块链
0 条回复

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

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

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

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

© 2021 V2EX