我正在尝试使用web3.py创建一个签名,并使用以下内容
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版本进行比较,这是正确的:
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版本获得相同的签名。
发布于 2023-02-27 16:52:38
问题有两个方面,一个是应该传递散列,而不是消息。另一种是签名是打包返回的。
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的打包签名
0xb9f93a970439f33211fc5761ec7df5065eea37fb99b73ebc2f71d2fda3e8870e28cfddf5cdec9fcb3c6f4b6339258904b639e0975dd511da00e858ba9acca89c1c与未包装的
0xb9f93a970439f33211fc5761ec7df5065eea37fb99b73ebc2f71d2fda3e8870e28cfddf5cdec9fcb3c6f4b6339258904b639e0975dd511da00e858ba9acca89c000000000000000000000000000000000000000000000000000000000000001c所以,在1c (28)或1b (27)之前,只要把62 0's拍下来。
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 signaturehttps://ethereum.stackexchange.com/questions/145514
复制相似问题