首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >web3.py签名消息

web3.py签名消息
EN

Ethereum用户
提问于 2023-02-25 00:41:48
回答 1查看 149关注 0票数 1

我正在尝试使用web3.py创建一个签名,并使用以下内容

代码语言:javascript
复制
private_key = "0x..."
message = "0x..."

w3.eth.account.sign_message(encode_defunct(hexstr=message), private_key=private_key)

SignedMessage(
messageHash=HexBytes('0x0977453c547a8ec8b97e6960c174171c26cc316fe3eb42e9c1f43d906988f2f7'), 
r=3826115209918881089309465947057239465610262098443411688798455982011613167534, 
s=57607373686102894909527198656322533582090341098386235608665690313545458942055, 
v=27, 
signature=HexBytes('0x08758124b2dde0a220b9e86a982343f8daf868c1b3d99eade5c74a72cce3bfae7f5c9e3803b0bef93e2d55c08d0f428976712fbaeee8a40ab1c223b8c67c80671b')
)

但是,我没有得到正确的输出来验证在链上使用erecover。我正在与js版本进行比较,这是正确的:

代码语言:javascript
复制
const signMessage = (types, values, signer) => {
  const message = web3.eth.abi.encodeParameters(types, values);

  const hash = web3.utils.keccak256(message);
  const { r, s, v } = web3.eth.accounts.sign(hash, signer);
  const signature = web3.eth.abi.encodeParameters(
    ["bytes32", "bytes32", "uint8"],
    [r, s, v]
  );

  return { message, signature };
};

{
  message: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000539000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb800000000000000000000000090f79bf6eb2c4f870365e785982e1f101e93b9060000000000000000000000000000000000000000000000000000000063f932b3000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000dba8c9e398042c00000000000000000000000000000000000000000000000000000000000000000',
  hash: '0x2cf410e76a0941e26af6f72a6a8d1cd85dccb68013cb75f79d6953d64df67519',
  signature: '0x822093256039a3f9a7cfeaef298b437a48ce819fbe2595b74f8b00bed01553bc64524f75795487183f0db628859d5dae0c7c80ea2b1b6dd1331f9101052ad705000000000000000000000000000000000000000000000000000000000000001b'
}

我从js端获得的消息和私钥被作为字符串传递,但我没有从js版本获得相同的签名。

我查看了以及文档,但仍然不知道如何做到这一点。

EN

回答 1

Ethereum用户

回答已采纳

发布于 2023-02-27 16:52:38

问题有两个方面,一个是应该传递散列,而不是消息。另一种是签名是打包返回的。

代码语言:javascript
复制
w3.eth.account.sign_message(encode_defunct(hexstr=hash), private_key=private_key)

SignedMessage(
messageHash=HexBytes('0x3418e4d525f194127a8568abe10ce8e85baacfc3a1787c7146b7dc17b3da4d3a'), 
r=84118226279719248546434396845856688871337333924969201322918159090204879128334, 
s=18459783198555716597479201270128233159415607675680227670410186427526995028124, 
v=28, 
signature=HexBytes('0xb9f93a970439f33211fc5761ec7df5065eea37fb99b73ebc2f71d2fda3e8870e28cfddf5cdec9fcb3c6f4b6339258904b639e0975dd511da00e858ba9acca89c1c'))

您可以看到v值是在签名中打包的,这必须是解压缩的。

来自web3.py的打包签名

代码语言:javascript
复制
0xb9f93a970439f33211fc5761ec7df5065eea37fb99b73ebc2f71d2fda3e8870e28cfddf5cdec9fcb3c6f4b6339258904b639e0975dd511da00e858ba9acca89c1c

与未包装的

代码语言:javascript
复制
0xb9f93a970439f33211fc5761ec7df5065eea37fb99b73ebc2f71d2fda3e8870e28cfddf5cdec9fcb3c6f4b6339258904b639e0975dd511da00e858ba9acca89c000000000000000000000000000000000000000000000000000000000000001c

所以,在1c (28)或1b (27)之前,只要把62 0's拍下来。

代码语言:javascript
复制
signed_message = w3.eth.account.sign_message(encode_defunct(hexstr=hash), private_key=private_key)
signature = signed_message.signature.hex()
if signature[130:] == '1c':
    signature = signature[:130] + '000000000000000000000000000000000000000000000000000000000000001c'
else:
    signature = signature[:130] + '000000000000000000000000000000000000000000000000000000000000001b'
return signature
票数 2
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/145514

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档