commit 5af30d5955be0ae8be0ddbcc5a1d0043a45f6dc5
Author: lash <dev@holbrook.no>
Date: Tue, 28 Mar 2023 10:15:02 +0100
Initial commit
Diffstat:
A | solidity/Example.sol | | | 109 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 109 insertions(+), 0 deletions(-)
diff --git a/solidity/Example.sol b/solidity/Example.sol
@@ -0,0 +1,109 @@
+pragma solidity ^0.4.24;
+
+// This file was copied from https://eips.ethereum.org/assets/eip-712/Example.sol
+// SPDX-License-Identifier: CC0-1.0
+
+contract Example {
+
+ struct EIP712Domain {
+ string name;
+ string version;
+ uint256 chainId;
+ address verifyingContract;
+ }
+
+ struct Person {
+ string name;
+ address wallet;
+ }
+
+ struct Mail {
+ Person from;
+ Person to;
+ string contents;
+ }
+
+ bytes32 constant EIP712DOMAIN_TYPEHASH = keccak256(
+ "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
+ );
+
+ bytes32 constant PERSON_TYPEHASH = keccak256(
+ "Person(string name,address wallet)"
+ );
+
+ bytes32 constant MAIL_TYPEHASH = keccak256(
+ "Mail(Person from,Person to,string contents)Person(string name,address wallet)"
+ );
+
+ bytes32 DOMAIN_SEPARATOR;
+
+ constructor () public {
+ DOMAIN_SEPARATOR = hash(EIP712Domain({
+ name: "Ether Mail",
+ version: '1',
+ chainId: 1,
+ // verifyingContract: this
+ verifyingContract: 0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC
+ }));
+ }
+
+ function hash(EIP712Domain eip712Domain) internal pure returns (bytes32) {
+ return keccak256(abi.encode(
+ EIP712DOMAIN_TYPEHASH,
+ keccak256(bytes(eip712Domain.name)),
+ keccak256(bytes(eip712Domain.version)),
+ eip712Domain.chainId,
+ eip712Domain.verifyingContract
+ ));
+ }
+
+ function hash(Person person) internal pure returns (bytes32) {
+ return keccak256(abi.encode(
+ PERSON_TYPEHASH,
+ keccak256(bytes(person.name)),
+ person.wallet
+ ));
+ }
+
+ function hash(Mail mail) internal pure returns (bytes32) {
+ return keccak256(abi.encode(
+ MAIL_TYPEHASH,
+ hash(mail.from),
+ hash(mail.to),
+ keccak256(bytes(mail.contents))
+ ));
+ }
+
+ function verify(Mail mail, uint8 v, bytes32 r, bytes32 s) internal view returns (bool) {
+ // Note: we need to use `encodePacked` here instead of `encode`.
+ bytes32 digest = keccak256(abi.encodePacked(
+ "\x19\x01",
+ DOMAIN_SEPARATOR,
+ hash(mail)
+ ));
+ return ecrecover(digest, v, r, s) == mail.from.wallet;
+ }
+
+ function test() public view returns (bool) {
+ // Example signed message
+ Mail memory mail = Mail({
+ from: Person({
+ name: "Cow",
+ wallet: 0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826
+ }),
+ to: Person({
+ name: "Bob",
+ wallet: 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB
+ }),
+ contents: "Hello, Bob!"
+ });
+ uint8 v = 28;
+ bytes32 r = 0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d;
+ bytes32 s = 0x07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b91562;
+
+ assert(DOMAIN_SEPARATOR == 0xf2cee375fa42b42143804025fc449deafd50cc031ca257e0b194a650a912090f);
+ assert(hash(mail) == 0xc52c0ee5d84264471806290a3f2c4cecfc5490626bf912d01f240d7a274b371e);
+ assert(verify(mail, v, r, s));
+ return true;
+ }
+}