You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用0x.js API签名订单时遇Invalid signature问题求助(Ropsten测试网)

排查ZeroEx订单签名Invalid Signature错误的思路

我来帮你梳理这个签名失败的问题,结合你用的Ropsten测试网、ZeroEx API和@0xproject/connect工具,Invalid Signature错误基本都和订单格式、签名方法、网络配置这几个核心环节有关,咱们一步步排查:

1. 先检查订单对象的完整性与格式

ZeroEx的订单有严格的字段规范,缺字段或者格式不对会直接导致签名无效:

  • 你给出的代码里makerTokenAmount的BigNumber没写完,要确认所有数值字段都是代币最小单位的准确值(比如ERC20代币通常是18位小数,1个代币对应1e18
  • 必须包含所有必填字段,不能遗漏:
    • salt:随机数,用来防止订单重复,建议用new BigNumber(Math.floor(Math.random() * 1e18))生成
    • exchangeAddress:Ropsten网络对应的ZeroEx交易所地址(不同版本地址不同,比如v3版本是0x4f833a24e1f95d70f028921e27040ca56e09ab0b,要和你用的API版本匹配)
    • expirationTimeSeconds:订单过期时间戳,必须是未来的有效时间
    • feeRecipientAddressmakerFeetakerFee:如果没有手续费需求,可设为0地址和0值

示例完整的订单结构:

const order = {
  maker: web3.eth.accounts[0],
  taker: "0x0000000000000000000000000000000000000000",
  makerTokenAddress: "0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d",
  takerTokenAddress: "0xc778417e063141139fce010982780140aa0cd5ab",
  makerTokenAmount: new BigNumber("1000000000000000000"), // 1个代币(假设18位小数)
  takerTokenAmount: new BigNumber("2000000000000000000"),
  salt: new BigNumber(Math.floor(Math.random() * 1e18)),
  exchangeAddress: "0x4f833a24e1f95d70f028921e27040ca56e09ab0b",
  expirationTimeSeconds: new BigNumber(Math.floor(Date.now() / 1000) + 86400), // 24小时后过期
  feeRecipientAddress: "0x0000000000000000000000000000000000000000",
  makerFee: new BigNumber(0),
  takerFee: new BigNumber(0)
};

2. 确认签名方法的正确性

ZeroEx的签名是基于EIP-712规范的,绝对不要手动构造签名数据,一定要用官方工具生成:

  • 初始化ZeroEx合约包装器时,必须指定Ropsten的networkId(3):
    import { ZeroEx } from '@0x/contract-wrappers';
    const zeroEx = new ZeroEx(web3.currentProvider, { networkId: 3 }); // 3对应Ropsten
    
  • 用官方方法签名订单,比如通过钱包连接器:
    const signedOrder = await zeroEx.signOrderAsync(order, web3.eth.accounts[0]);
    
  • 如果用MetaMask等钱包签名,要确保当前钱包连接的是Ropsten网络,且活跃地址就是订单里的maker地址。

3. 检查网络与合约地址的匹配性

  • 确认exchangeAddress是Ropsten网络的正确地址,不同ZeroEx版本(v2/v3/v4)的交易所地址不同,错用主网地址会直接导致签名无效
  • 确保你的API调用目标https://api.openrelay.xyz/v0对应的是Ropsten网络(OpenRelay的v0 API确实支持Ropsten,但要确认没有配置错误)

4. 用调试工具定位具体问题

ZeroEx提供了验证方法,可以帮你找出更具体的错误:

// 验证订单可填充性,会抛出详细错误信息
try {
  await zeroEx.validateOrderFillabilityOrThrowAsync(signedOrder);
} catch (err) {
  console.error('订单验证失败:', err.message);
}

另外可以打印出完整的signedOrder对象,检查signature字段是否是带0x前缀的合法十六进制字符串,长度是否符合要求。

5. 钱包与地址权限检查

  • 确认web3.eth.accounts[0]确实是你要签名的maker地址,且该地址在Ropsten网络上(如果用本地私钥签名,要确保私钥没有写错)
  • 如果用MetaMask,要确保钱包已解锁,且授权了你的应用访问地址

如果还是解决不了,可以把完整的订单对象和签名代码贴出来(注意不要泄露私钥),这样能更精准定位问题。

内容的提问来源于stack exchange,提问作者Md. Mahbubul Haque

火山引擎 最新活动