如何正确使用ECDSA.sol模块?

how to use the ECDSA.sol module correctly?

我有这个使用 ECDSA 库的合约。

import "./ECDSA.sol";
struct Signature {
        uint8 v;
        bytes32 r;
        bytes32 s;
    }
function make(Signature memory sign) public returns(bool)

我试图理解在这种情况下我必须使用的参数。我能看到它是一个元组类型值,但我无法弄清楚 v、r、s 是什么样子。从我的地址哪里可以得到这些值?

vrs 参数是使用私钥对消息进行签名的结果。签名有65个字节,分为3个部分:

65 byte array (of type bytes in Solidity) arranged the following way: [[v (1)], [r (32)], [s (32)]].

来源:OpenZeppelin


链下签名(因为您使用的是私钥)。

注意评论中的地址,我们稍后会在链上进行验证。

const signature = await web3.eth.accounts.sign(
    'Hello world',
    // below is private key to the address `0x0647EcF0D64F65AdA7991A44cF5E7361fd131643`
    '02ed07b6d5f2e29907962d2bfde8f46f03c46e79d5f2ded0b1e0c27fa82f1384'
);

console.log(signature);

输出

{
    message: 'Hello world',
    messageHash: '0x8144a6fa26be252b86456491fbcd43c1de7e022241845ffea1c3df066f7cfede',
    v: '0x1c',
    r: '0x285e6fbb504b57dca3ceacc851a7bfa37743c79b5c53fb184f4cc0b10ebff6ad',
    s: '0x245f558fa13540029f0ee2dc0bd73264cf04f28ba9c2520ad63ddb1f2e7e9b24',
    signature: '0x285e6fbb504b57dca3ceacc851a7bfa37743c79b5c53fb184f4cc0b10ebff6ad245f558fa13540029f0ee2dc0bd73264cf04f28ba9c2520ad63ddb1f2e7e9b241c'
}

注意vsignature的最后一个字节,r是前半部分,s是后半部分(不包括最后一个字节)。


链上验证

pragma solidity ^0.8;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol";

contract MyContract {
    function foo() external pure returns (bool) {
        address recovered = ECDSA.recover(
            0x8144a6fa26be252b86456491fbcd43c1de7e022241845ffea1c3df066f7cfede, // messageHash
            0x1c, // v
            0x285e6fbb504b57dca3ceacc851a7bfa37743c79b5c53fb184f4cc0b10ebff6ad, // r
            0x245f558fa13540029f0ee2dc0bd73264cf04f28ba9c2520ad63ddb1f2e7e9b24 // s
        );
        
        return recovered == address(0x0647EcF0D64F65AdA7991A44cF5E7361fd131643);
    }
}