如何向智能合约外部函数传递Signature(r,s,v)结构体参数?
调用合约时签名的msg设置规则
你要签名的
msg不能是随便的文本,必须是合约业务逻辑需要验证的关键数据的标准化哈希值——简单说,就是你调用合约函数时,除了Signature参数之外的其他核心业务参数(比如转账金额、接收地址、订单ID等),按照合约里签名验证的参数顺序和类型,生成的Keccak256哈希。具体操作步骤:
- 先明确合约函数的业务参数:比如你调用的合约函数是用来授权转账,那参数可能是
uint256 amount和address recipient; - 用Web3工具生成这些参数的结构化哈希:
// 示例:针对amount和recipient生成哈希 const targetAmount = 100; const targetRecipient = "0x1234567890abcdef1234567890abcdef12345678"; const msgHash = web3.utils.soliditySha3( { type: 'uint256', value: targetAmount }, { type: 'address', value: targetRecipient } ); - 用这个
msgHash作为web3.eth.sign的第二个参数(不需要再转hex字符串,因为soliditySha3已经返回十六进制哈希); - 签名后拆分得到v、r、s:
把这三个值组装成const signature = web3.eth.sign(addr, msgHash); const r = signature.slice(0, 66); const s = '0x' + signature.slice(66, 130); const v = web3.utils.hexToNumber('0x' + signature.slice(130, 132));Signature结构体,就能传给合约函数了。
- 先明确合约函数的业务参数:比如你调用的合约函数是用来授权转账,那参数可能是
注意点:
web3.eth.sign会自动给原始哈希加上\x19Ethereum Signed Message:\n32的前缀再做签名,所以合约里的验证逻辑必须对应这个前缀——比如合约里要用keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", msgHash))来计算哈希,再用ecrecover还原签名地址。- 如果合约用的是EIP-712结构化签名规范(更安全,适合复杂数据),那就要按照EIP-712的规则构造签名数据,而不是简单的参数哈希。
内容的提问来源于stack exchange,提问作者pochimen
相关产品推荐
相关产品推荐

