资讯动态

Diem Swiss Knife 实战指南:BCS 序列化交易生成、签名与验证命令行工具

发布时间:2026/9/21 16:39:20 来源:尧图企业网站定制
Diem Swiss Knife 实战指南BCS 序列化交易生成、签名与验证命令行工具【免费下载链接】diemDiem’s mission is to build a trusted and innovative financial network that empowers people and businesses around the world.项目地址: https://gitcode.com/gh_mirrors/di/diemDiem Swiss Knifeswiss-knife是 Diem 仓库中一个面向交易流水线的命令行工具用于生成并序列化BCS原始交易Raw Transaction与已签名交易Signed Transaction覆盖一组受支持的 Move 脚本并附带密钥对生成、签名与验签等测试辅助功能。本文以 crates/swiss-knife/README.md 为主线结合 main.rs、helpers.rs 与 sample_inputs 中的真实样例完整讲解每个操作命令的输入输出格式、参数含义与底层实现帮助你直接用它构造可提交到链上的交易负载或把它接入任意支持 JSON 的自动化脚本。工具定位与整体设计swiss-knife的设计目标非常明确既可供人类交互式使用interactive use也便于被自动化程序调用programs in any language which support json。从 Cargo.toml 的依赖可以看到它复用了仓库内的核心组件diem-types../../types提供RawTransaction、SignedTransaction、ChainId、AuthenticationKey等交易与账户类型diem-crypto../diem-crypto提供 Ed25519 私钥、公钥、签名以及KeyPair测试工具diem-transaction-builder../../sdk/transaction-builder提供受支持 Move 脚本的编码函数bcs负责交易的 BCS 序列化与反序列化structopt解析子命令参数。统一的 stdin/stdout 契约工具约定凡是需要输入的场合从 stdin 读取 JSON操作结果一律以 JSON 写到 stdout。输出 JSON 对象恒有两个字段{ error_message: , data: { ... } }操作成功时data被填充error_message为空字符串操作失败时error_message携带错误描述data为空字符串。这一契约由 helpers.rs 中的Response结构实现exit_success_with_data打印error_message: 并以退出码 0 结束exit_with_error打印错误信息并以退出码 1 结束。自动化脚本只需解析这两个字段即可判断成败无需依赖进程退出码之外的附加约定。典型调用方式如下从 stdin 重定向输入文件swiss-knife operation_name operation_specific_input.json列出全部支持的操作cargo run -p swiss-knife -- --helpmain.rs中的Command枚举main.rs定义了 6 个操作分为两类交易生成类面向链上提交generate-raw-txn生成并序列化RawTransaction及其包含的脚本generate-signed-txn由序列化后的原始交易、公钥与签名组装出SignedTransaction。测试辅助类面向签名与验签 3.generate-test-ed25519-keypair生成测试用 Ed25519 密钥对及对应的 Diem 账户地址与认证密钥 4.sign-transaction-using-ed25519用 Ed25519 私钥对原始交易签名 5.verify-transaction-ed25519-signature验证原始交易的 Ed25519 签名 6.verify-ed25519-signature对任意 payload 二进制做裸 Ed25519 验签RFC 8032 语义。sample_inputs文件夹crates/swiss-knife/sample_inputs中收录了各操作对应的 JSON 输入样例可直接复用。构建二进制Release 优化模式在swiss-knife目录下执行cargo build --release构建产物位于仓库根目录的target/release/swiss-knife。也可以不构建二进制、直接通过cargo run -p swiss-knife -- operation input.json运行工作区成员名swiss-knife定义于 Cargo.toml。交易生成类操作generate-raw-txn生成原始交易该操作读取两段参数txn_params交易级参数与script_params脚本级参数对应源码中的GenerateRawTxnRequest结构main.rs。txn_params交易参数 schema对应源码中的TxnParams结构main.rs字段及含义如下字段类型含义sender_addressstring发送方账户地址sequence_numberu64该交易对应发送方账户的序列号chain_idstring该交易针对的 Diem 网络 Chain IDmax_gas_amountu64钱包愿意为该交易支付的最大总 gas 量gas_unit_priceu64每单位 gas 可支付的最高价格gas_currency_codestring用于支付 gas 的币种标识符expiration_timestamp_secsu64交易的过期时间Unix 纪元秒。若查询存储时返回时间大于等于该值且交易仍未被打包可确信它永远不会被打包不设过期可用一个极大值如u64::max_value()表示chain_id 的取值NamedChain 命名链README 特别提示chain_id参数可参考 types/src/chain_id.rs 中的enum NamedChain也可以直接传数字表示的链 ID如 0、1、2 等。NamedChain的保留链定义如下链名数字 ID预留防止误初始化为 00MAINNET1TESTNET2DEVNET3TESTING4PREMAINNET5源码中str_to_chain_idchain_id.rs将MAINNET/TESTNET/DEVNET/TESTING/PREMAINNET映射到对应数字 IDChainId::from_str则会先尝试数字解析因此TESTING与4等价。注意签名时应使用数字 Chain ID即交易中实际编码的字节命名链主要服务于配置与 CLI 的可读性。script_params受支持的 Move 脚本对应源码中的MoveScriptParams枚举main.rs当前支持三种脚本preburn将指定数量的币移入 preburn 区之后可被销毁。参数coin_tagstring币种标签amountu64金额。peer_to_peer_transfer带元数据的点对点转账。参数coin_tagstring币种标签recipient_addressstring收款方地址amountu64金额metadata_hex_encodedstringhex 编码的元数据metadata_signature_hex_encodedstringhex 编码的元数据签名。rotate_dual_attestation_info轮换双重证明Dual Attestation信息。参数new_urlstring新的合规端点 URL例如https://example.com/endpointnew_key_hex_encodedstringhex 编码的 32 字节 Ed25519 公钥例如edd0f6de342a1e6a7236d6244f23d83eedfcecd059a386c85055701498e77033。在实现上三种脚本分别委托给diem-transaction-builder生成的脚本编码函数sdk/transaction-builder/src/stdlib.rsencode_peer_to_peer_with_metadata_script(currency, payee, amount, metadata, metadata_signature)stdlib.rs将payee地址、金额与两段字节数组打包为Script参数encode_preburn_script(token, amount)stdlib.rsencode_rotate_dual_attestation_info_script(new_url, new_key)stdlib.rs。其中coin_tag与recipient_address分别经 helpers.rs 的coin_tag_parser转为TypeTag与account_address_parserAccountAddress::from_hex_literal解析校验后传入。示例生成 peer_to_peer_transfer 原始交易以 sample_inputs/generate_raw_txn_peer_to_peer_transfer.json 为输入cargo run -p swiss-knife -- generate-raw-txn crates/swiss-knife/sample_inputs/generate_raw_txn_peer_to_peer_transfer.json输出如下raw_txn为 BCS 序列化后的完整原始交易 hexscript为其中脚本负载的 BCS hex{ error_message: , data: { raw_txn: e1b3d22871989e9fd9dc6814b2f4fc412a0000000000000001e101a11ceb0b010000000701000202020403061004160205181d0735610896011000000001010000020001000003020301010004010300010501060c0108000506080005030a020a020005060c05030a020a020109000c4c696272614163636f756e741257697468647261774361706162696c6974791b657874726163745f77697468647261775f6361706162696c697479087061795f66726f6d1b726573746f72655f77697468647261775f6361706162696c69747900000000000000000000000000000001010104010c0b0011000c050e050a010a020b030b0438000b05110202010700000000000000000000000000000001034c4252034c425200040371e931795d23e9634fd24a5992065f6b0164000000000000000400040040420f00000000000000000000000000034c4252fc24f65e0000000004, script: 01e101a11ceb0b010000000701000202020403061004160205181d0735610896011000000001010000020001000003020301010004010300010501060c0108000506080005030a020a020005060c05030a020a020109000c4c696272614163636f756e741257697468647261774361706162696c6974791b657874726163745f77697468647261775f6361706162696c697479087061795f66726f6d1b726573746f72655f77697468647261775f6361706162696c69747900000000000000000000000000000001010104010c0b0011000c050e050a010a020b030b0438000b05110202010700000000000000000000000000000001034c4252034c425200040371e931795d23e9634fd24a5992065f6b01640000000000000004000400 } }该操作的内部流程main.rs为先由script_params编码出Script包装为TransactionPayload::Script并 BCS 序列化得到script再以txn_params各字段调用RawTransaction::new(sender_address, sequence_number, payload, max_gas_amount, gas_unit_price, gas_currency_code, expiration_timestamp_secs, ChainId)构造原始交易最后 BCS 序列化并以 hex 输出。raw_txn的 hash 需要被签名后才能生成SignedTransaction。示例生成 preburn 原始交易输入见 sample_inputs/generate_raw_txn_preburn.jsoncargo run -p swiss-knife -- generate-raw-txn crates/swiss-knife/sample_inputs/generate_raw_txn_preburn.json输出{ error_message: , data: { raw_txn: e1b3d22871989e9fd9dc6814b2f4fc412a0000000000000001d401a11ceb0b0100000007010002020204030610041602051815072d60088d011000000001010000020001000003020301010004010300010501060c01080003060c060800030002060c030109000c4c696272614163636f756e741257697468647261774361706162696c6974791b657874726163745f77697468647261775f6361706162696c697479077072656275726e1b726573746f72655f77697468647261775f6361706162696c69747900000000000000000000000000000001010104010a0a0011000c020b000e020a0138000b02110202010700000000000000000000000000000001034c4252034c4252000101640000000000000040420f00000000000000000000000000034c4252fc24f65e0000000004 } }示例生成 rotate_dual_attestation_info 原始交易输入见 sample_inputs/generate_raw_txn_rotate_dual_attestation_info.jsoncargo run -p swiss-knife -- generate-raw-txn crates/swiss-knife/sample_inputs/generate_raw_txn_rotate_dual_attestation_info.json输出{ error_message: , data: { raw_txn: e1b3d22871989e9fd9dc6814b2f4fc412a00000000000000018f01a11ceb0b010000000501000203020a050c0d07193d08561000000001000100000200010002060c0a020003060c0a020a020f4475616c4174746573746174696f6e0f726f746174655f626173655f75726c1c726f746174655f636f6d706c69616e63655f7075626c69635f6b657900000000000000000000000000000001000201070a000b0111000b000b021101020002041c68747470733a2f2f6578616d706c652e636f6d2f656e64706f696e740420edd0f6de342a1e6a7236d6244f23d83eedfcecd059a386c85055701498e7703340420f00000000000000000000000000034c4252fc24f65e0000000004, script: 018f01a11ceb0b010000000501000203020a050c0d07193d08561000000001000100000200010002060c0a020003060c0a020a020f4475616c4174746573746174696f6e0f726f746174655f626173655f75726c1c726f746174655f636f6d706c69616e63655f7075626c69635f6b657900000000000000000000000000000001000201070a000b0111000b000b021101020002041c68747470733a2f2f6578616d706c652e636f6d2f656e64706f696e740420edd0f6de342a1e6a7236d6244f23d83eedfcecd059a386c85055701498e77033 } }generate-signed-txn由原始交易组装签名交易给定序列化后的raw_txn、public_key与signature组装出SignedTransaction并额外计算txn_hash该 hash 会被包含进链上。对应请求结构GenerateSignedTxnRequestmain.rs字段类型含义raw_txnstringgenerate-raw-txn输出的 hex 编码原始交易public_keystringEd25519 公钥hexsignaturestringEd25519 签名hex内部实现main.rs先对raw_txn做 hex 解码与 BCS 反序列化得到RawTransaction再对signature与public_key做 hex 解码得到Ed25519Signature与Ed25519PublicKey随后SignedTransaction::new(raw_txn, public_key, signature)组装并以CryptoHash::hash(Transaction::UserTransaction(signed_txn)).to_hex()计算txn_hash最后将签名交易 BCS 序列化为 hex 输出。以 sample_inputs/generate_signed_txn_peer_to_peer_transfer.json 为输入cargo run -p swiss-knife -- generate-signed-txn crates/swiss-knife/sample_inputs/generate_signed_txn_peer_to_peer_transfer.json输出{ error_message: , data: { signed_txn: e1b3d22871989e9fd9dc6814b2f4fc412a0000000000000001d401a11ceb0b0100000007010002020204030610041602051815072d60088d011000000001010000020001000003020301010004010300010501060c01080003060c060800030002060c030109000c4c696272614163636f756e741257697468647261774361706162696c6974791b657874726163745f77697468647261775f6361706162696c697479077072656275726e1b726573746f72655f77697468647261775f6361706162696c69747900000000000000000000000000000001010104010a0a0011000c020b000e020a0138000b02110202010700000000000000000000000000000001034c4252034c4252000101640000000000000040420f00000000000000000000000000034c4252fc24f65e0000000004, txn_hash: e1b3d22871989e9fd9dc6814b2f4fc412a0000000000000001d401a11ceb0b0100000007010002020204030610041602051815072d60088d011000000001010000020001000003020301010004010300010501060c01080003060c060800030002060c030109000c4c696272614163636f756e741257697468647261774361706162696c6974791b657874726163745f77697468647261775f6361706162696c697479077072656275726e1b726573746f72655f77697468647261775f6361706162696c69747900000000000000000000000000000001010104010a0a0011000c020b000e020a0138000b02110202010700000000000000000000000000000001034c4252034c42520001016400000000000000 } }注README 中该示例输出为早期版本的raw_txn/script字段当前 main.rs 的实现以signed_txn与txn_hash两个字段输出。同样preburn 的签名交易样例见 sample_inputs/generate_signed_txn_preburn.json。测试辅助操作以下操作面向开发与测试场景帮助快速产出密钥、签名与验签结果。generate-test-ed25519-keypair生成 Ed25519 密钥对生成一个 Ed25519 密钥对以及与该密钥对关联的 Diem 账户地址account address与认证密钥auth key。可选提供 seed以确定性方式生成 Ed25519 密钥对源码见 main.rsStdRng::seed_from_u64(seed.unwrap_or_else(rand::random))未提供 seed 时使用随机种子地址由AuthenticationKey::ed25519(public_key).derived_address()推导auth key 即AuthenticationKey::ed25519的完整值。随机生成cargo run -p swiss-knife -- generate-test-ed25519-keypair输出{ error_message: , data: { diem_account_address: e1b3d22871989e9fd9dc6814b2f4fc41, diem_auth_key: 5a06116a9801533249b06eeef54db2f1e1b3d22871989e9fd9dc6814b2f4fc41, private_key: b2f7f581d6de3c06a822fd6e7e8265fbc00f8401696a5bdc34f5a6d2ff3f922f, public_key: edd0f6de342a1e6a7236d6244f23d83eedfcecd059a386c85055701498e77033 } }用 seed 0 生成确定性密钥对cargo run -p swiss-knife -- generate-test-ed25519-keypair --seed 0输出与随机模式恰好一致seed 0 对应上述密钥{ error_message: , data: { diem_account_address: e1b3d22871989e9fd9dc6814b2f4fc41, diem_auth_key: 5a06116a9801533249b06eeef54db2f1e1b3d22871989e9fd9dc6814b2f4fc41, private_key: b2f7f581d6de3c06a822fd6e7e8265fbc00f8401696a5bdc34f5a6d2ff3f922f, public_key: edd0f6de342a1e6a7236d6244f23d83eedfcecd059a386c85055701498e77033 } }sign-transaction-using-ed25519用 Ed25519 私钥签名交易给定 hex 编码的raw_txn与private_key产出该交易的 Ed25519 签名。注意它与generate-signed-txn的区别此处只产出signature字段不组装签名交易。请求结构见SignTransactionUsingEd25519Requestmain.rs实现为private_key.sign(raw_txn)main.rs即对RawTransaction本身签名。cargo run -p swiss-knife -- sign-transaction-using-ed25519 crates/swiss-knife/sample_inputs/generated_raw_txn_p2p_transfer.json输出{ error_message: , data: { signature: 193eabce444d5cca25bb18591a2dca11688a2cc513852bca52016cab309be67a4fd409f1c9c162a7f2ab9265faeb22eb6e03a52196592d3bf7f96195ce08ae08 } }verify-transaction-ed25519-signature验证交易签名给定raw_txn、signature与public_key验证该 Ed25519 签名是否匹配该原始交易。内部调用signature.verify(raw_txn, public_key)main.rs结果以布尔值valid_signature返回。cargo run -p swiss-knife -- verify-transaction-ed25519-signature crates/swiss-knife/sample_inputs/generated_signed_txn_p2p_transfer.json输出{ error_message: , data: { valid_signature: true } }verify-ed25519-signature验证任意 payload 的 Ed25519 签名给定payloadhex 编码的任意字节、signature与public_key做裸 Ed25519 验签。内部调用signature.verify_arbitrary_msg(message, public_key)main.rs。cargo run -p swiss-knife -- verify-ed25519-signature crates/swiss-knife/sample_inputs/verify_signature_payload.json输出{ error_message: , data: { valid_signature: true } }重要提醒这个操作并不是对“交易签名”的测试它只测试 Diem 中使用的裸 Ed25519 库RFC 8032 语义即diem-crypto中的Signature::verify_arbitrary_msg。它的典型用途是确认 Diem 使用的是 Ed25519 的 pure 变体而非 pre-hashed 变体。若要测试交易签名请使用上一节的verify-transaction-ed25519-signature。从源码看工具的调用链与容错行为main.rs中每个命令的处理模式完全一致main.rs从 stdin 读取 JSON →serde_json::from_str反序列化为对应请求结构 → 执行逻辑 →exit_success_with_data输出。理解这一模式有助于排查问题输入不是合法 JSONserde_json::from_str失败立即以exit_with_error输出error_message如 Failed to deserialize json : ...并以退出码 1 结束字段缺失或类型不匹配serde反序列化失败同样走错误分支hex 解码失败hex_decodehelpers.rs或Ed25519Signature::from_encoded_string/Ed25519PublicKey::from_encoded_string失败时会输出形如 Failed to hex decode signature ... 的错误BCS 序列化/反序列化失败输出 bcs serialization failure of ... 或 bcs deserialization failure of ...地址或币种解析失败account_address_parser与coin_tag_parser分别输出 Failed to parse address as an AccountAddress ... 与 Failed to parse coin_tag ...。此外所有 JSON 结构均标注#[serde(rename_all snake_case)]因此输入字段一律使用下划线命名如sender_address、max_gas_amount、expiration_timestamp_secs枚举变体脚本名也使用 snake_case如peer_to_peer_transfer。典型工作流从密钥到可提交的签名交易结合上述操作一个完整的“离线构造交易”工作流如下生成密钥对或复用已有密钥generate-test-ed25519-keypair得到private_key、public_key、diem_auth_key与diem_account_address构造原始交易编写包含txn_params与script_params的 JSON执行generate-raw-txn得到raw_txn签名把第 1 步的private_key与第 2 步的raw_txn组成 JSON执行sign-transaction-using-ed25519得到signature或直接组装 JSON 后执行generate-signed-txn一步到位得到signed_txn与txn_hash验证用verify-transaction-ed25519-signature对签名后的交易做双重确认。由于所有操作都遵循“JSON in / JSON out”契约第 24 步完全可以被 Python、Go、Java 等任意语言编写的自动化程序通过子进程调用并解析结果这正是swiss-knife被设计为自动化友好工具的原因所在。注意事项与适用前提本工具生成的是离线的交易负载构造与签名辅助不负责把交易提交到链上提交动作需要配合 JSON-RPC 等客户端完成chain_id必须与目标网络匹配签名时应使用数字 Chain ID当前NamedChain保留链为MAINNET1、TESTNET2、DEVNET3、TESTING4、PREMAINNET5见 types/src/chain_id.rs测试辅助操作尤其verify-ed25519-signature仅用于验证底层 Ed25519 库语义不应作为生产环境交易验签的替代示例中的账户、密钥与签名均为样例数据切勿在真实网络中使用以当前仓库代码为准generate-signed-txn的响应字段为signed_txn与txn_hash与 README 中早期示例的raw_txn/script字段不同接入自动化脚本时请以实际输出为准。【免费下载链接】diemDiem’s mission is to build a trusted and innovative financial network that empowers people and businesses around the world.项目地址: https://gitcode.com/gh_mirrors/di/diem创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价