Solidity

如何使用 nonce 來防止簽名複製?

  • September 23, 2022

我想驗證消息是由某個地址發送的,並且要獲取簽名者地址,我使用以下函式:

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;
}

但是為了防止簽名的複制,我想使用隨機數。如何將 nonce 集成到我的邏輯中?如果這些方面可能需要任何管理,我的應用程序中也有前端和後端。

你可以看看ERC20中permit函式是如何實現的:https ://github.com/fractional-company/contracts/blob/master/src/OpenZeppelin/drafts/ERC20Permit.sol#L57-L60

基本上你需要mapping (address => uint256) public nonces;在你的契約中有一個,它為每個簽名者保存最後使用的隨機數。

簽名者必須對包含目前隨機數的消息進行簽名,因此您必須在nonces[msg.sender]裡面添加abi.encodePacked(prefix, _hashedMessage). 我正在使用msg.sender,但是當然,如果您要檢查另一個使用者,則需要傳遞其地址。

把它們放在一起:

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,
       nonces[msg.sender],
       _hashedMessage
   ));
   address signer = ecrecover(prefixedHashMessage, _v, _r, _s);

   require(msg.sender == signer);
   nonces[msg.sender] += 1;

   return signer;
}

引用自:https://ethereum.stackexchange.com/questions/136224