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

发布时间:2026/9/21 16:39:11

Diem Swiss Knife 实战指南:BCS 序列化交易生成、签名与验证命令行工具 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),仅供参考
延伸阅读

更多相关文章

2026/9/21 16:34:10

【热力学】基于FEM的二维热传导与对流边界附Matlab代码和报告

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、算法改进、程序设计科研仿真。🍎 往期回顾关注个人主页:完整代码获取 定制创新 论文复现私信🍊个人信条:做科研&#xff0c…

2026/9/21 17:39:16

android 11正式发布后实战项目避坑指南

android 11正式发布后实战项目避坑指南 刚把网上抄的 Android 11 适配代码粘进工程,编译报错,运行闪退。那种“复制来的代码跑不通不知道怎么调”的绝望感,每个做安卓的老兵都经历过。别慌,这不是你的错,是 Android…

2026/9/21 17:39:16

生产制造管理系统避坑:搞定电子证书与年审的5个高频面试题

生产制造管理系统避坑:搞定电子证书与年审的5个高频面试题 官方文档厚达三百页,翻半天找不到证书查询接口在哪?别慌,这不仅是文档的问题,更是很多后端开发在构建 生产制造管理系统 时最容易踩的深坑。我见过太多项目上线后,因为没处理好 电子证书…

2026/9/21 17:39:16

2026最新ladyboy69版本升级API全变?3招搞定底层逻辑

2026最新ladyboy69版本升级API全变?3招搞定底层逻辑 昨晚还在跑通顺的脚本,今早一启动,满屏的 AttributeError 。那种感觉就像你熟练地掏出一把旧钥匙,却发现门锁已经被厂家偷偷换成了指纹锁。这就是 版本升级后…

2026/9/21 17:39:16

点线面构成图性能优化:新手避坑指南,告别卡顿

点线面构成图性能优化:新手避坑指南,告别卡顿 配置环境就卡半天,代码一跑就崩,这是很多刚接触图形渲染或地理信息开发的新手最真实的写照。在公路工程或测绘项目中,处理【点线面构成图】时,数据量稍大,浏览器或客户端直接卡死,内存飙升,用户体验极差…

2026/9/21 17:39:16

3分钟搞定孩子身高预测工具:保姆级教程

3分钟搞定孩子身高预测工具:保姆级教程 是不是刚把GitHub上的项目复制下来,双击运行就报错?或者在本地跑通了,换个电脑又炸了?这种“复制来的代码跑不通不知道怎么调”的噩梦,每个初学者都经历过。别急,今天这篇保姆级教程,不讲虚的,直接带你…

2026/9/21 3:28:31

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/21 3:33:19

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/21 0:02:23

OpenResearch:构建可复现的开放式研究工作流

第一次看到“OpenResearch”这个名字,我脑子里冒出的不是某个具体软件,而更像一种研究方式的宣言:开放、可复现、可验证。这三件事放在一起,其实比大多数人想象中难得多。过去几年我一直在折腾自己的研究工作流,从纯纸…

2026/9/20 4:54:47

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/20 5:01:23

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/21 10:29:02

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码