技术:如何在 Solidity 中验证签名消息

  • 时间:
  • 浏览:112
  • 来源:区块链技术网

介绍

这是一个使用MetaMask签名消息,然后在链上进行验证的实用教程。

这里有一个demo:https://leon-do.github.io/ecrecover/

签名

Sign Message

  async function signMessage() {
    if (!window.ethereum) return alert("Please Install Metamask");

    // connect and get metamask account
    const accounts = await ethereum.request({ method: "eth_requestAccounts" });

    // message to sign
    const message = "hello";
    console.log({ message });

    // hash message
    const hashedMessage = Web3.utils.sha3(message);
    console.log({ hashedMessage });

    // sign hashed message
    const signature = await ethereum.request({
      method: "personal_sign",
      params: [hashedMessage, accounts[0]],
    });
    console.log({ signature });

    // split signature
    const r = signature.slice(0, 66);
    const s = "0x" + signature.slice(66, 130);
    const v = parseInt(signature.slice(130, 132), 16);
    console.log({ r, s, v });
  }

需注意:

  • 这是使用personal_sign方法来防止意外的交易支出。这将与智能合约(以下)中发现的\x19Ethereum Signed Message:\n32前缀相关。
  • 这是对散列消息进行签名。

签字

下面是验证签名所需的信息。可在智能合约中使用它。

hashedMessage = 0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8
r = 0xb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d
s = 0x2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9
v = 28

智能合约

创建Solidity合约。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Verify {

    function VerifyMessage(bytes32 _hashedMessage, uint8 _v, bytes32 _r, bytes32 _s) public pure returns (address) {
        bytes memory prefix = "\x19Ethereum Signed Message:\n32";
        bytes32 prefixedHashMessage = keccak256(abi.encodePacked(prefix, _hashedMessage));
        address signer = ecrecover(prefixedHashMessage, _v, _r, _s);
        return signer;
    }

}

需注意:

  • 注意前缀,\x19Ethereum Signed Message:\n32是验证签名消息所必需的。
  • 前缀随消息散列。
  • Ecrecover应返回签名者的地址。

在solidity中验证

输入散列消息和签名(r, s, v)来验证地址。

用例:Unity Gaming

  • 游戏开发者创建一个游戏、服务器和智能合约,如果玩家获胜,则该合约会发放奖品。
  • 赢家告诉游戏开发者他们赢了。
  • 游戏服务器为玩家提供一个签名(上面解释过),允许用户认领。把它当作优惠券。
  • 然后,玩家与合约互动,提交签名(优惠券)来领取奖品。

游戏开发者部署智能合约的例子:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// game developer depoloys contract
contract Verify {

    // game developer's account
    address public owner = 0xdD4c825203f97984e7867F11eeCc813A036089D1;

    // player claims price
    function claimPrize(bytes32 _hashedMessage, uint8 _v, bytes32 _r, bytes32 _s) public view returns (bool) {
        bytes memory prefix = "\x19Ethereum Signed Message:\n32";
        bytes32 prefixedHashMessage = keccak256(abi.encodePacked(prefix, _hashedMessage));
        address signer = ecrecover(prefixedHashMessage, _v, _r, _s);

        // if the signature is signed by the owner
        if (signer == owner) {
            // give player (msg.sender) a prize
            return true;
        }

        return false;
    }
}

获胜后,玩家会从游戏服务器获得一张签名(优惠券)来领取奖品。

0xb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c91c

玩家在Unity中解析签名:

string signature = "0xb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c91c";
string r = signature.Substring(0, 66);
string s = "0x" + signature.Substring(66, 64);
int v = int.Parse(signature.Substring(130, 2), System.Globalization.NumberStyles.HexNumber);

然后,玩家可以与智能合约进行交互,领取奖品。

Source:https://www.web3.university/article/how-to-verify-a-signed-message-in-solidity

关于

ChinaDeFi - ChinaDeFi.com 是一个研究驱动的DeFi创新组织,同时我们也是区块链开发团队。每天从全球超过500个优质信息源的近900篇内容中,寻找思考更具深度、梳理更为系统的内容,以最快的速度同步到中国市场提供决策辅助材料。

本文首发于:https://mp.weixin.qq.com/s/cS90RBgcmj8ZrxkBLo0GLg

猜你喜欢

使用 SNARKs 批处理 ECDSA 签名

我们带来了circom-batch-ECDSA,一个基于circom-ECDSA(由0xPARC社区中其他人之前完成的工作)之上的概念验证实现,其灵感来自halo2-batch

2022-11-06

如何成为资深 solidity 智能合约工程师

如何成为资深solidity智能合约工程师#如何成为资深solidity智能合约工程师##Solidity+Hardhat+Ethers熟悉[Solidity](https:/

2022-11-06

Solidity自学笔记

Solidity自学笔记我在GitHub上写了一个Solidity自学笔记,会持续更新希望大家感兴趣的可以关注一下,感兴趣的给个star,就再好不过了前期由于javascrip

2022-11-06

在BSN武汉链上部署solidity智能合约

BSN简介区块链服务网络(Blockchain-basedServiceNetwork)是一个跨云服务、跨门户、跨底层框架,用于部署和运行各类区块链应用的基础设施网络,2020

2022-11-06

Solidity 字节码和操作码基础知识

在本文中,简单地解释一些EVM基础知识。随着我们深入编写智能合约,我们会遇到诸如“PUSH1”、“SSTORE”、“CALLVALUE”等术语。它们是什么,我们甚至应该关心它们

2022-11-06