exchange.IO("signTypedData", ...)
按照EIP-712标准对结构化数据进行签名,一次调用即可完成类型哈希、域分隔符、结构体哈希和摘要的计算并签名,适用于ERC-20 Permit、Permit2、UniswapX、CoW、1inch限价单等场景。
exchange.IO(k, typedData)
exchange.IO(k, typedData, key)
exchange.IO(k, domain, types, message)
exchange.IO(k, domain, types, message, key)示例
对以太坊主网USDC的Permit进行签名,并通过exchange.IO("call", ...)由USDC合约验证签名。
javascript
function main() {
var USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" // 以太坊主网 USDC
var spender = "0x1111111254EEB25477B68fb85Ed929f73A960582" // 被授权方,按实际填写
var owner = exchange.IO("address")
var deadline = Math.floor(Date.now() / 1000) + 3600
// nonce 必须等于合约里的 nonces(owner):钱包用过一次 permit 后就不再是 0
exchange.IO("abi", USDC, JSON.stringify([{ type: "function", name: "nonces",
stateMutability: "view",
inputs: [{ type: "address" }], outputs: [{ type: "uint256" }] }]))
var nonce = exchange.IO("api", USDC, "nonces", owner)
// ethers 写法:domain、types(不含 EIP712Domain)、message,主类型自动推断
var domain = { name: "USD Coin", version: "2", chainId: 1, verifyingContract: USDC }
var types = {
Permit: [
{ name: "owner", type: "address" }, { name: "spender", type: "address" },
{ name: "value", type: "uint256" }, { name: "nonce", type: "uint256" },
{ name: "deadline", type: "uint256" }
]
}
var message = { owner: owner, spender: spender, value: "1000000", nonce: nonce,
deadline: deadline }
var sig = exchange.IO("signTypedData", domain, types, message)
Log("digest:", sig.digest, "v:", sig.v, "r:", sig.r, "s:", sig.s)
// 单对象写法(MetaMask eth_signTypedData_v4 的格式)结果相同
var sig2 = exchange.IO("signTypedData", { domain: domain, types: types, primaryType: "Permit",
message: message })
Log("两种写法一致:", sig.signature === sig2.signature)
// 用 eth_call 模拟 USDC 的 permit,由合约验证签名(不发送交易)
var calldata = "0x" + String(exchange.IO("hash", "keccak256", "raw", "hex",
"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)")).replace(/^0x/, "").slice(0, 8) +
exchange.IO("encode", "address,address,uint256,uint256,uint8,bytes32,bytes32",
owner, spender, "1000000", deadline, sig.v, sig.r, sig.s)
Log("permit 模拟:", exchange.IO("call", USDC, calldata) !== null ? "签名有效" : GetLastError())
}返回值
| 类型 | 描述 |
object | 返回签名对象,字段与 |
参数
| 名称 | 类型 | 必填 | 描述 |
k | string | 是 | 固定为 |
typedData | object / string | 否 | 包含 |
domain | object | 否 | EIP-712域,例如 |
types | object | 否 | 类型定义,例如 |
message | object | 否 | 待签名的数据。大整数可以以字符串形式传入。 |
key | string | 否 | 签名所使用的私钥,不传该参数时使用 |
参考
备注
message中缺少类型定义中的字段时会报错,不会将缺失字段补零后签名。
私钥仅在交易所对象内部使用,策略代码无法获取私钥。