You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用prepareContcmd输出发送区块链续期交易并解决pactCode报错?

解决Pact续期交易签名与发送问题

错误原因分析

你遇到的TypeError: pactCode must be a string: undefined错误,本质是请求格式不符合Pact API要求:

  • 续期交易不需要手动添加pactCode字段,prepareContCmd生成的cmd已经包含所有必要的交易编码信息
  • 你的签名结构不完整,缺少publicKey字段,导致API解析请求时触发异常提示

正确的续期交易流程与代码修正

核心步骤

  1. 生成续期命令框架:用prepareContCmd构造包含续期逻辑的待签名命令
  2. 签名命令:对cmd字段进行签名,确保签名结构包含publicKey和sig
  3. 发送交易:将带签名的完整命令直接传递给local(测试)或send(上链)端点

修正后的完整代码

const Pact = require('pact-lang-api');
const NETWORK_ID = "mainnet01";
const CHAIN_ID = "8";
const API_HOST = `https://api.chainweb.com/chainweb/0.0/${NETWORK_ID}/chain/${CHAIN_ID}/pact`;

// 交易参数
const keyPairs = {
    publicKey: '4aab9f08f1bd86c3ce007a9a87225ef061c09e7062efa622e2fd704c24514cfa',
    secretKey: 'secret-key'
};
const step = 1;
const rollback = false;
const envData = null;
const seller = "k:79464b986676c7b39f2202b09fcbbaf324c677c43122c62de76edaf9f0ca10bd";
const buyer = "k:4aab9f08f1bd86c3ce007a9a87225ef061c09e7062efa622e2fd704c24514cfa";
const amount = 1.0;
const price = 1000.0;
const pactId = "FdFn_GVF4f5IEOcsx8gvmWbQghMbY65rpwcfSdStgag";
const saleId = "n7Erm5Gcij3ITgOF3vXUww8j6MZgIGRSSeU0uCYcmKg";
const sender = "k:4aab9f08f1bd86c3ce007a9a87225ef061c09e7062efa622e2fd704c24514cfa";
const chainId = "8";
const gasPrice = 0.0000001;
const gasLimit = 10000;
const creationTime = Math.floor(new Date().getTime() / 1000);
const ttl = 28800;
const meta = Pact.lang.mkMeta(sender, chainId, gasPrice, gasLimit, creationTime, ttl);

// 获取SPV证明(仅跨链续期需要,同链可省略或传null)
async function getProof() {
    const cmd1 = {
        requestKey: pactId,
        targetChainId: CHAIN_ID,
    };
    return Pact.fetch.spv(cmd1, API_HOST);
}

async function main() {
    // 若为同链续期,可直接将proof设为null
    const proof = await getProof();

    // 构造续期命令
    const contCommand = Pact.api.prepareContCmd(
        {
            publicKey: keyPairs.publicKey,
            clist: [
                {
                    name: "marmalade.ledger.BUY",
                    args: [
                        "t:KNl_38B4fqeJd2ijPghc_ihD-5viRvqLcV10MZEIwsA",
                        buyer,
                        seller,
                        amount,
                        { int: 99999999 },
                        saleId,
                    ],
                },
                {
                    name: "coin.TRANSFER",
                    args: [buyer, seller, price],
                },
                { name: "coin.GAS", args: [] }
            ]
        },
        new Date().toISOString(),
        proof, // 传入SPV证明,同链传null
        pactId,
        rollback,
        step,
        envData,
        meta,
        NETWORK_ID
    );

    // 签名命令:确保签名包含publicKey和sig
    const signedCmd = Pact.crypto.sign(contCommand.cmd, keyPairs);
    contCommand.sigs = [
        {
            publicKey: keyPairs.publicKey,
            sig: signedCmd.sig
        }
    ];

    // 发送到local端点测试,如需上链改用Pact.fetch.send
    try {
        const response = await Pact.fetch.local(contCommand, API_HOST);
        console.log("交易响应:", response);
    } catch (error) {
        console.error("发送交易失败:", error);
    }
}

main();

关键修正点

  1. 完整签名结构:签名后的sigs数组必须包含publicKey和sig两个字段,这是Pact API的强制要求
  2. SPV证明传递:如果是跨链续期,必须将获取到的SPV证明传入prepareContCmd的第3个参数;同链续期可传null
  3. 移除多余的pactCode字段:续期交易不需要手动添加pactCode,prepareContCmd生成的cmd已经是完整的编码交易内容

切换到send端点上链

若要将交易发送到主链,只需将Pact.fetch.local替换为Pact.fetch.send,两者接受的参数格式完全一致:

const response = await Pact.fetch.send(contCommand, API_HOST);

内容的提问来源于stack exchange,提问作者Nexion21

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 00:32:18