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

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

  •  
  •   gitandgit · 2021-09-02 16:29:39 +08:00 · 520 次点击
    这是一个创建于 967 天前的主题,其中的信息可能已经有所发展或是发生改变。

    原英文文档地址:

    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:

    • openContractCall 等同 doContractCall

    • openSTXTransfer 等同 doSTXTransfer

    • openContractDeploy 等同 doContractDeploy

    使用具有与上述相同的参数的这些函数。但是,您不必指定 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;
          });
    }
    
    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5144 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 09:37 · PVG 17:37 · LAX 02:37 · JFK 05:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.