solidity0.8.0的应用案例13:数字签名及应用:NFT白名单

以太坊中的数字签名ECDSA,以及如何利用它发放NFT白名单

代码中的ECDSA库由OpenZeppelin的同名库简化而成。

数字签名

如果你用过opensea交易NFT,对签名就不会陌生。下图是小狐狸(metamask)钱包进行签名时弹出的窗口,它可以证明你拥有私钥的同时不需要对外公布私钥。

solidity0.8.0的应用案例13:数字签名及应用:NFT白名单_第1张图片

 

以太坊使用的数字签名算法叫双椭圆曲线数字签名算法(ECDSA),基于双椭圆曲线“私钥-公钥”对的数字签名算法。它主要起到了三个作用:

  1. 身份认证:证明签名方是私钥的持有人。
  2. 不可否认:发送方不能否认发送过这个消息。
  3. 完整性:消息在传输过程中无法被修改。

ECDSA合约

ECDSA标准中包含两个部分:

  1. 签名者利用私钥(隐私的)对消息(公开的)创建签名(公开的)。
  2. 其他人使用消息(公开的)和签名(公开的)恢复签名者的公钥(公开的)并验证签名。 我们将配合ECDSA库讲解这两个部分。本教程所用的私钥公钥消息以太坊签名消息签名如下所示:
私钥: 0x227dbb8586117d55284e26620bc76534dfbd2394be34cf4a09cb775d593b6f2b
公钥: 0xe16C1623c1AA7D919cd2241d8b36d9E79C1Be2A2
消息: 0x1bf2c0ce4546651a1a2feb457b39d891a6b83931cc2454434f39961345ac378c
以太坊签名消息: 0xb42ca4636f721c7a331923e764587e98ec577cea1a185f60dfcc14dbb9bd900b
签名: 0x390d704d7ab732ce034203599ee93dd5d3cb0d4d1d7c600ac11726659489773d559b12d220f99f41d17651b0c1c6a669d346a397f8541760d6b32a5725378b241c

 创建签名

1. 打包消息:

 在以太坊的ECDSA标准中,被签名的消息是一组数据的keccak256哈希,为bytes32类型。我们可以把任何想要签名的内容利用abi.encodePacked()函数打包,然后用keccak256()计算哈希,作为消息。我们例子中的消息是由一个address类型变量和一个uint256类型变量得到的:

    /*
     * 将mint地址(address类型)和tokenId(uint256类型)拼成消息msgHash
     * _account: 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4
     * _tokenId: 0
     * 对应的消息msgHash: 0x1bf2c0ce4546651a1a2feb457b39d891a6b83931cc2454434f39961345ac378c
     */
    function getMessageHash(address _account, uint256 _tokenId) public pure returns(bytes32){
        return keccak256(abi.encodePacked(_account, _tokenId));
    }

 

solidity0.8.0的应用案例13:数字签名及应用:NFT白名单_第2张图片

 2. 计算以太坊签名消息: 

所谓计算以太坊签名消息,本质上是第二次打包消息,只是这次打包是在上一次打包消息的基础上,加上一个字符串作为编码的一部分:"\x19Ethereum Signe

你可能感兴趣的:(区块链)