Web3 签名验证失败 - ethers.js

Posted

技术标签:

【中文标题】Web3 签名验证失败 - ethers.js【英文标题】:Web3 signature verification is failing - ethers.js 【发布时间】:2020-01-22 10:37:25 【问题描述】:

我正在尝试使用ethers.js 在链外创建签名消息,并使用ecrecover 在链上验证该消息。我正在从我的元掩码钱包中签署正确的消息,并将该签名中的 r、s 和 v 传递到 ecrecover,但没有与我的元掩码钱包匹配。

我的 Solidity 代码应该适用于带前缀或不带前缀的签名。

这是我用来验证签名的合同:

pragma solidity ^0.5.0;
contract SignatureVerifier 
    /// @dev Signature verifier
    function isSigned(address _address, bytes32 messageHash, uint8 v, bytes32 r, bytes32 s) public pure returns (bool) 
        return _isSigned(_address, messageHash, v, r, s) || _isSignedPrefixed(_address, messageHash, v, r, s);
    

    /// @dev Checks unprefixed signatures.
    function _isSigned(address _address, bytes32 messageHash, uint8 v, bytes32 r, bytes32 s)
        internal pure returns (bool)
    
        return ecrecover(messageHash, v, r, s) == _address;
    

    /// @dev Checks prefixed signatures.
    function _isSignedPrefixed(address _address, bytes32 messageHash, uint8 v, bytes32 r, bytes32 s)
        internal pure returns (bool)
    
        bytes memory prefix = "\x19Ethereum Signed Message:\n32";
        return _isSigned(_address, keccak256(abi.encodePacked(prefix, messageHash)), v, r, s);
    
 

来自 ethers,这是我用来生成签名的代码(简化版本),我将其用作 _isSigned 函数调用的参数。

    let provider = new ethers.providers.Web3Provider(window.ethereum)
    let signer = provider.getSigner()
    let dataHash = '0x952d17582514a6a434234b10b8e6b681b6006c8ed225d479fa3db70828b9cd60'
    let signature = await signer.signMessage(dataHash)
    let sigBreakdown = ethers.utils.splitSignature(signature)
    console.log(sigBreakdown)

这提示我在 matamask 中签名,我在其中签署了正确的 dataHash。然后它记录一个 r、s 和 v 值。

在混音中,我调用 isSigned,传递我的元掩码地址、dataHash (0x952...d60) 以及 r、s 和 v 值,期望结果为 true,但它返回 false .我对这里的solidity 代码和javascript 代码相当有信心,但显然我遗漏了一些东西。非常感谢您的帮助!

【问题讨论】:

【参考方案1】:

想通了!原来,我签署的是string dataHash 而不是bytes dataHash 的值。我能够通过添加来获得验证:

let bytesDataHash = ethers.utils.arrayify(dataHash)

并签名bytesDataHash 而不是dataHash :) 像往常一样,Richard Moore 在 github 上回答了一个类似的问题,因为那个人太不可思议了: https://github.com/ethers-io/ethers.js/issues/245#issuecomment-408706606

【讨论】:

以上是关于Web3 签名验证失败 - ethers.js的主要内容,如果未能解决你的问题,请参考以下文章

web3 的身份验证之以太坊签名消息

Web3 系列开发教程——创建你的第一个 NFT使用 Ethers.js 铸造 NFT | 测试用例

接微信支付提示:支付验证签名失败

从 go-ethereum 实现 Ethereum personal_sign (EIP-191) 给出了与 ethers.js 不同的签名

签名验证失败。没有提供安全密钥来验证签名

如何将 ethers.js 与元掩码连接起来?