【问题标题】:how to use the ECDSA.sol module correctly?如何正确使用 ECDSA.sol 模块?
【发布时间】:2021-08-24 15:04:58
【问题描述】:

我有这份使用 ECDSA 库的合同。

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

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

【问题讨论】:

    标签: solidity ecdsa


    【解决方案1】:

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

    65 字节数组(Solidity 中的 bytes 类型)按以下方式排列:[[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);
        }
    }
    

    【讨论】:

    • 谢谢,所以在这种情况下,为了填充签名的元组(sign 参数)。我必须提前签名才能获得 v,r,s 的值。我说的对吗?
    • 没错。 vrs 实际上是签名的一部分。
    猜你喜欢
    • 2014-09-17
    • 1970-01-01
    • 1970-01-01
    • 2021-03-13
    • 2021-12-03
    • 2019-08-08
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多