查看原文
其他

波卡的交易构建与签名操作指南

PolkaWorld 2023-03-03

The following article is from Polkadot生态研究院 Author Polkadot Labs


波卡知识图谱是我们针对波卡从零到一的入门级文章,我们尝试从波卡最基础的部分讲起,为大家提供全方位了解波卡的内容,当然这是一项巨大的工程,也充满了挑战,然而我们希望通过这样的努力让大家能够正确认知波卡,也让不了解波卡的人方便快速掌握波卡相关知识,今天是该栏目的第84期,波卡的交易架构是比较新颖的设计,开发者需要细致地理解波卡的交易是如何构建的,以及相关的签名是如何操作的。
本文将讨论波卡中的交易格式以及如何创建、签署和广播交易。本文演示了一些可用的工具,集成时请始终参考每个工具的文档



交易格式


波卡有一些所有交易通用的基本交易信息。
  • Address:发送账户的SS58编码地址。
  • Block Hash:检查点区块的哈希。
  • Block Number:检查点块的编号。
  • Genesis Hash:链的创世哈希。
  • Metadata:提交时Runtime的SCALE编码元数据。
  • Nonce:本次交易的随机数。
  • Spec Version:运行时的当前规范版本。
  • Transaction Version:交易格式的当前版本。
  • Tip:可选,增加交易优先级的提示。
  • Era Period:可选,交易有效的检查点之后的区块数。如果为零,则交易是永久的(immortal)。


警告:使交易变成永久的(immortal)存在一些风险。如果一个账户被收回并且用户重新为该账户注资,那么他们可以重播一个永久的交易。始终默认使用非永久的(mortal)外源。


从System模块查询的随机数(nonce)不考虑待处理的交易(pending transactions)。如果你想同时提交多个有效交易,你必须手动跟踪和增加随机数。


每个交易都有自己的(或没有)要添加的参数。例如,Balances pallet中的transferKeepAlive函数将采用:
  • dest: 目的地地址
  • #[compact] value:通证数(紧凑编码compact encoding)



1

序列化交易格式


使用该--chain 选项选择链。可以是polkadot、kusama、westend、 rococo或自定义链规范。默认情况下,客户端将启动Polkadot。观看视频,学习单个代码库如何为四个不同的区块链提供支持, 以了解有关链的选择的内部工作原理的更多信息。相关视频内容:


在提交之前,交易会被序列化。序列化交易是十六进制编码的SCALE编码字节。波卡的Runtime是可升级的,因此任何接口都可能发生变化,元数据允许开发人员相应地构建任何外源(extrinsics)或存储条目。话虽这么说,序列化格式可以描述如下:
  • 紧随其后的SCALE编码字节的紧凑编码数。
  • 1 位:如果没有签名则为0,如果有则为1。
  • 7 位:外部版本,它等于十进制的4。
  • 4 个字节:Runtime的规范版本。
  • 4 个字节:Runtime的交易版本。
  • 32 字节:链的创世哈希。
  • 32 字节:作为era参考的区块哈希。如果交易是永久的,那么这将是创世哈希。


如果有一个签名是:
  • 一个用sp_runtime::MultiAddress::Id指示交易的签名者的编码的SCALE。
  • 一个用sp_runtime::MultiSignature::{SigningScheme}签名(波卡支持sr25519、ed25519和ECDSA作为签名方案)的编码的SCALE。


一个用sp_runtime::generic::Era指示该交易的有效期的编码的SCALE:
  • 如果交易是永久的,那么Era就是0。
  • 否则,它将是一个Vec[u64, u64]包括时期和阶段的时期。
  • 用随机数紧凑编码的u32。
  • 用支付给区块生产者的小费(tip)进行紧凑编码的u128。
  • 一个用sp_runtime::traits::SignedExtension>与此交易相关的附加数据和逻辑编码的SCALE 。


具体交易参数或调用数据,包括:
  • 1 个字节:交易调用的pallet索引。
  • 1 个字节:交易正在调用的pallet中的函数。
  • 变量:被调用函数所需的SCALE编码参数。


元数据为您提供了解如何构建特定于您的交易的序列化调用数据所需的所有信息。您可以在Substrate文档中阅读有关元数据、其格式以及如何获取它的更多信息 。相关内容:
https://docs.substrate.io/reference/command-line-tools/subxt/#metadata


2

总结


获得所有必要信息后,您将需要:
  • 构造一个未签名的交易。
  • 创建签名的有效载荷(payload)。
  • 签署有效载荷。
  • 将签名的有效载荷序列化为交易。
  • 提交序列化交易。
  • Parity提供以下工具来帮助执行这些步骤。




Polkadot-JS Tools



Polkadot-JS Tools包含一组用于与Substrate客户端交互的命令行工具,包括一个名为“Signer CLI”的工具,用于创建、签名和广播交易。


此示例将使用signer submit命令,该命令将创建并提交交易。signer sendOffline命令具有完全相同的API,但不会广播交易。submit并且sendOffline必须连接到节点以获取当前元数据并构建有效交易。他们的API具有以下格式:
yarn run:signer <submit|sendOffline> --account <from-account-ss58> --ws <endpoint> <module.method> [param1] [...] [paramX]


签名:
yarn run:signer sign --account <from-account-ss58> --seed <seed> --type <sr25519|ed25519> <payload>


从121X5bEgTZcGQx5NZjwuTjqqKoiG8B2wEAvrUFjuw24ZGZf2发送0.5T到15vrtLsCQFG3qRYUcaEeeEih4JwepocNJHkpsrqojqnZPc2y:
yarn run:signer sign --account 121X5bEgTZcGQx5NZjwuTjqqKoiG8B2wEAvrUFjuw24ZGZf2 --seed "pulp gaze fuel ... mercy inherit equal" --type sr25519 0x040300ff4a83f1...a8239139ff3ff7c3f6


这将返回要签名的有效载荷和等待签名的输入。获取此有效载荷并使用您的正常签名环境(例如air gapped机器、VM等)。签署有效载荷:
yarn run:signer sign --account 121X5bEgTZcGQx5NZjwuTjqqKoiG8B2wEAvrUFjuw24ZGZf2 --seed "pulp gaze fuel ... mercy inherit equal" --type sr25519 0x040300ff4a83f1...a8239139ff3ff7c3f6


保存输出并将其带到您将广播的机器上,将其输入到submit的签名字段中,然后发送交易(或者如果使用sendOffline则返回序列化交易)。



Tx Wrappers



如果您不想使用CLI进行签名操作,Parity提供了一个名为TxWrapper Core的SDK来离线生成和签署交易。对于波卡、Kusama和选择平行链,请使用该txwrapper-polkadot包。其他基于Substrate的链将有自己的txwrapper-{chain}实现,请参阅示例以获取指南。TxWrapperCore相关内容:https://github.com/paritytech/txwrapper-core其余txwrapper-{chain}实例相关内容:https://github.com/paritytech/txwrapper-core/blob/main/packages/txwrapper-examples/README.md



1

导入私钥


import { importPrivateKey } from '@substrate/txwrapper-polkadot';
const keypair = importPrivateKey(“pulp gaze fuel ... mercy inherit equal”);
客户端将启动Polkadot。观看视频,学习单个代码库如何为四个不同的区块链提供支持, 以了解有关链的选择的内部工作原理的更多信息。相关视频内容:



2

从公钥导出地址


import { deriveAddress } from '@substrate/txwrapper-polkadot';

// Public key, can be either hex string, or Uint8Arrayconst publicKey = “0x2ca17d26ca376087dc30ed52deb74bf0f64aca96fe78b05ec3e720a72adb1235”;const address = deriveAddress(publicKey);



3

离线构建一笔交易

归档节点不会删减任何区块或状态数据。使用--pruning archive标注。某些类型的节点(如验证者)必须以归档模式运行。

import { methods } from "@substrate/txwrapper-polkadot";

const unsigned = methods.balances.transferKeepAlive( { dest: "15vrtLsCQFG3qRYUcaEeeEih4JwepocNJHkpsrqojqnZPc2y", value: 5000000000, }, { address: "121X5bEgTZcGQx5NZjwuTjqqKoiG8B2wEAvrUFjuw24ZGZf2", blockHash: "0x1fc7493f3c1e9ac758a183839906475f8363aafb1b1d3e910fe16fab4ae1b582", blockNumber: 4302222, genesisHash: "0xe3777fa922cafbff200cadeaea1a76bd7898ad5b89f7848999058b50e715f636", metadataRpc, // must import from client RPC call state_getMetadata nonce: 2, specVersion: 1019, tip: 0, eraPeriod: 64, // number of blocks from checkpoint that transaction is valid transactionVersion: 1, }, { metadataRpc, registry, // Type registry });


4

构建签名有效载荷


import { methods, createSigningPayload } from '@substrate/txwrapper-polkadot';

// See "Construct a transaction offline" for "{...}"const unsigned = methods.balances.transferKeepAlive({...}, {...}, {...});const signingPayload = createSigningPayload(unsigned, { registry });



5

序列化已签名的交易

Parity Polkadot客户端实现了一个Polkadot主机和一个本地Runtime。Runtime必须编译为WebAssembly并存储在链上。如果客户端的Runtime规范与存储在链上的Runtime规范相同,则客户端将使用客户端二进制文件执行区块。

import { createSignedTx } from "@substrate/txwrapper-polkadot";

// Example code, replace `signWithAlice` with actual remote signer.// An example is given here:// https://github.com/paritytech/txwrapper-core/blob/b213cabf50f18f0fe710817072a81596e1a53cae/packages/txwrapper-core/src/test-helpers/signWithAlice.tsconst signature = await signWithAlice(signingPayload);const signedTx = createSignedTx(unsigned, signature, { metadataRpc, registry });



6

解码有效载荷类型


您可能希望在提交之前解码有效载荷(payload)以验证其内容。

import { decode } from "@substrate/txwrapper-polkadot";

// Decode an unsigned txconst txInfo = decode(unsigned, { metadataRpc, registry });

// Decode a signing payloadconst txInfo = decode(signingPayload, { metadataRpc, registry });

// Decode a signed txconst txInfo = decode(signedTx, { metadataRpc, registry });



7

检查交易的哈希


import { getTxHash } from ‘@substrate/txwrapper-polkadot’;const txHash = getTxHash(signedTx);


否则,客户端将从链上执行Wasm Runtime。因此,在同步链时,客户端将使用其关联的Wasm二进制文件执行过去运行时的区块。此功能还允许无硬分叉升级:客户端可以在不更新客户端的情况下执行新的Runtime。




提交已签名的有效荷载



有几种方法可以提交签名的有效载荷:
  • 签名者CLI(yarn run:signer submit --tx  --ws )
  • Substrate API Sidecar
  • 带有author_submitExtrinsic或author_submitAndWatchExtrinsic的RPC,后者将使您订阅事件event,以便在交易得到验证并包含在链中时得到通知。




备注



示例中使用的一些地址。请参阅子项文档:
https://docs.substrate.io/reference/command-line-tools/subkey/
$ subkey --network polkadot generateSecret phrase `pulp gaze fuel ... mercy inherit equal` is account: Secret seed: 0x57450b3e09ba4598 ... ... ... ... ... ... ... .. 219756eeba80bb16 Public key (hex): 0x2ca17d26ca376087dc30ed52deb74bf0f64aca96fe78b05ec3e720a72adb1235 Account ID: 0x2ca17d26ca376087dc30ed52deb74bf0f64aca96fe78b05ec3e720a72adb1235 SS58 Address: 121X5bEgTZcGQx5NZjwuTjqqKoiG8B2wEAvrUFjuw24ZGZf2

$ subkey --network polkadot generateSecret phrase `exercise auction soft ... obey control easily` is account: Secret seed: 0x5f4bbb9fbb69261a ... ... ... ... ... ... ... .. 4691ed7d1130fbbd Public key (hex): 0xda04de6cd781c98acf0693dfb97c11011938ad22fcc476ed0089ac5aec3fe243 Account ID: 0xda04de6cd781c98acf0693dfb97c11011938ad22fcc476ed0089ac5aec3fe243 SS58 Address: 15vrtLsCQFG3qRYUcaEeeEih4JwepocNJHkpsrqojqnZPc2y


如果需要更好的查看代码,请参见原文,相关地址:

https://wiki.polkadot.network/docs/build-transaction-construction#tx-wrapper





波卡网络蓬勃发展,生态项目层出不穷,波卡生态研究院聚焦波卡生态动向,把握当前趋势。回复【日报】,获取波卡生态每日最新消息汇总







欢迎大家加入我们Polkadot生态研究院的电报:

https://t.me/polkadot_eri

欢迎大家访问波卡生态研究院的Mirror地址:
https://mirror.xyz/0x9A259b3a2316281Cc948cE2Cf1Ac610a79844f05




精选文章


智能合约 | 经济模型 | Slash | 通货膨胀 | NPoS | Web3基金
Staking
 | Gavin Wood | 跨链 | 平行链 | 国库 | Parity
KSM | Web3.0 | Kusama | Grant指南
Statemint | 区块链 SBP计划 | NFT
XCVM | BEEFY | XCM
Wasm



 

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存