Skip to content

Commit

Permalink
2024.10.16
Browse files Browse the repository at this point in the history
  • Loading branch information
shenzhimeng authored Oct 16, 2024
1 parent 9aba661 commit f9dbe7c
Showing 1 changed file with 79 additions and 0 deletions.
79 changes: 79 additions & 0 deletions ruoshui.md
Original file line number Diff line number Diff line change
Expand Up @@ -3633,4 +3633,83 @@ contract ERC4626 is ERC20, IERC4626 {
}
}
```
### 2024.10.16
[EIP712 类型化数据签名](https://eips.ethereum.org/EIPS/eip-712)[EIP191 签名标准(personal sign)](https://eips.ethereum.org/EIPS/eip-191) 要高级安全一些,会展示签名消息的原始数据,用户可以在验证数据符合预期之后签名。

签名验证

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
contract EIP712Storage {
using ECDSA for bytes32;
bytes32 private constant EIP712DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
bytes32 private constant STORAGE_TYPEHASH = keccak256("Storage(address spender,uint256 number)");
bytes32 private DOMAIN_SEPARATOR;
uint256 number;
address owner;
constructor(){
DOMAIN_SEPARATOR = keccak256(abi.encode(
EIP712DOMAIN_TYPEHASH, // type hash
keccak256(bytes("EIP712Storage")), // name
keccak256(bytes("1")), // version
block.chainid, // chain id
address(this) // contract address
));
owner = msg.sender;
}
/**
* @dev Store value in variable
*/
function permitStore(uint256 _num, bytes memory _signature) public {
// 检查签名长度,65是标准r,s,v签名的长度
require(_signature.length == 65, "invalid signature length");
bytes32 r;
bytes32 s;
uint8 v;
// 目前只能用assembly (内联汇编)来从签名中获得r,s,v的值
assembly {
/*
前32 bytes存储签名的长度 (动态数组存储规则)
add(sig, 32) = sig的指针 + 32
等效为略过signature的前32 bytes
mload(p) 载入从内存地址p起始的接下来32 bytes数据
*/
// 读取长度数据后的32 bytes
r := mload(add(_signature, 0x20))
// 读取之后的32 bytes
s := mload(add(_signature, 0x40))
// 读取最后一个byte
v := byte(0, mload(add(_signature, 0x60)))
}
// 获取签名消息hash
bytes32 digest = keccak256(abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR,
keccak256(abi.encode(STORAGE_TYPEHASH, msg.sender, _num))
));
address signer = digest.recover(v, r, s); // 恢复签名者
require(signer == owner, "EIP712Storage: Invalid signature"); // 检查签名
// 修改状态变量
number = _num;
}
/**
* @dev Return value
* @return value of 'number'
*/
function retrieve() public view returns (uint256){
return number;
}
}
```
<!-- Content_END -->

0 comments on commit f9dbe7c

Please sign in to comment.