原英文文档地址:
https://docs.stacks.co/build-apps/guides/transaction-signing
签名交易
提示用户签名交易,并将交易广播到 Stacks 区块链
介绍
本指南解释了如何通过实现 Stacks.js 的连接包来提示用户签署交易并将它们广播到 Stacks 区块链。
交易签名为用户提供了一种方法,让用户执行与应用程序相关的 Clarity 智能合约,然后合理地处理结果.
用户可以签署交易来交换可替代或者不可替代的代币,并提供前期保证,帮助他们保持对数字资产的控制。交易分为三种类型:
STX 传输
智能合约部署
智能合约执行
有关此功能在实践中的具体示例,请参阅公共注册教程。
安装依赖项
为了使用 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;
});
}