eth-erc712

ERC712 typed data sign material builder
Log | Files | Refs

commit 453c0b5a45e3eedbea60cd043a92f208d0ed2c3b
parent 0c71201e7274e9dd2ccec2ee782afb8f37669ed2
Author: lash <dev@holbrook.no>
Date:   Wed, 29 Mar 2023 04:21:32 +0100

Manually complete struct encoding for mail example

Diffstat:
Mpython/eth_erc712/data/ERC712Example.bin | 4++--
Mpython/eth_erc712/data/ERC712Example.metadata.json | 2+-
Mpython/tests/test_basic.py | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Msolidity/ERC712Example.sol | 3++-
4 files changed, 59 insertions(+), 12 deletions(-)

diff --git a/python/eth_erc712/data/ERC712Example.bin b/python/eth_erc712/data/ERC712Example.bin @@ -1 +1 @@ -60806040523480156200001157600080fd5b50620000d46040518060a001604052806040518060400160405280600a81526020017f4574686572204d61696c0000000000000000000000000000000000000000000081525081526020016040518060400160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152508152602001602a81526020013073ffffffffffffffffffffffffffffffffffffffff1681526020014340815250620000e0640100000000026401000000009004565b60018190555062000230565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f826000015180519060200120836020015180519060200120846040015185606001516040516020016200013b959493929190620001d3565b604051602081830303815290604052805190602001209050919050565b6000819050919050565b6200016d8162000158565b82525050565b6000819050919050565b620001888162000173565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620001bb826200018e565b9050919050565b620001cd81620001ae565b82525050565b600060a082019050620001ea600083018862000162565b620001f9602083018762000162565b62000208604083018662000162565b6200021760608301856200017d565b620002266080830184620001c2565b9695505050505050565b610ac980620002406000396000f3fe608060405234801561001057600080fd5b506004361061005e576000357c010000000000000000000000000000000000000000000000000000000090048063bfa0b13314610063578063cb11771714610081578063f8a8fd6d146100b1575b600080fd5b61006b6100cf565b60405161007891906104b7565b60405180910390f35b61009b6004803603810190610096919061081d565b6100d5565b6040516100a891906108bb565b60405180910390f35b6100b961019d565b6040516100c691906108bb565b60405180910390f35b60005481565b6000806001546100e4876103c2565b6040516020016100f592919061094e565b60405160208183030381529060405280519060200120905085600001516020015173ffffffffffffffffffffffffffffffffffffffff166001828787876040516000815260200160405260405161014f9493929190610994565b6020604051602081039080840390855afa158015610171573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff1614915050949350505050565b600080604051806060016040528060405180604001604052806040518060400160405280600381526020017f436f770000000000000000000000000000000000000000000000000000000000815250815260200173cd2a3d9f938e13cd947ec05abc7fe734df8dd82673ffffffffffffffffffffffffffffffffffffffff16815250815260200160405180604001604052806040518060400160405280600381526020017f426f620000000000000000000000000000000000000000000000000000000000815250815260200173bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb73ffffffffffffffffffffffffffffffffffffffff1681525081526020016040518060400160405280600b81526020017f48656c6c6f2c20426f622100000000000000000000000000000000000000000081525081525090506000601c905060007f4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d600102905060007f07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b9156260010290507ff2cee375fa42b42143804025fc449deafd50cc031ca257e0b194a650a912090f60010260015414610363576103626109d9565b5b7fc52c0ee5d84264471806290a3f2c4cecfc5490626bf912d01f240d7a274b371e600102610390856103c2565b1461039e5761039d6109d9565b5b6103aa848484846100d5565b6103b7576103b66109d9565b5b600194505050505090565b60007fa0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac26103f2836000015161043b565b6103ff846020015161043b565b84604001518051906020012060405160200161041e9493929190610a08565b604051602081830303815290604052805190602001209050919050565b60007fb9d8c78acf9b987311de6c7b45bb6a9c8e1bf361fa7fd3467a2163f994c79500826000015180519060200120836020015160405160200161048193929190610a5c565b604051602081830303815290604052805190602001209050919050565b6000819050919050565b6104b18161049e565b82525050565b60006020820190506104cc60008301846104a8565b92915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610534826104eb565b810181811067ffffffffffffffff82111715610553576105526104fc565b5b80604052505050565b60006105666104d2565b9050610572828261052b565b919050565b600080fd5b600080fd5b600080fd5b600067ffffffffffffffff8211156105a1576105a06104fc565b5b6105aa826104eb565b9050602081019050919050565b82818337600083830152505050565b60006105d96105d484610586565b61055c565b9050828152602081018484840111156105f5576105f4610581565b5b6106008482856105b7565b509392505050565b600082601f83011261061d5761061c61057c565b5b813561062d8482602086016105c6565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061066182610636565b9050919050565b61067181610656565b811461067c57600080fd5b50565b60008135905061068e81610668565b92915050565b6000604082840312156106aa576106a96104e6565b5b6106b4604061055c565b9050600082013567ffffffffffffffff8111156106d4576106d3610577565b5b6106e084828501610608565b60008301525060206106f48482850161067f565b60208301525092915050565b600060608284031215610716576107156104e6565b5b610720606061055c565b9050600082013567ffffffffffffffff8111156107405761073f610577565b5b61074c84828501610694565b600083015250602082013567ffffffffffffffff8111156107705761076f610577565b5b61077c84828501610694565b602083015250604082013567ffffffffffffffff8111156107a05761079f610577565b5b6107ac84828501610608565b60408301525092915050565b600060ff82169050919050565b6107ce816107b8565b81146107d957600080fd5b50565b6000813590506107eb816107c5565b92915050565b6107fa8161049e565b811461080557600080fd5b50565b600081359050610817816107f1565b92915050565b60008060008060808587031215610837576108366104dc565b5b600085013567ffffffffffffffff811115610855576108546104e1565b5b61086187828801610700565b9450506020610872878288016107dc565b935050604061088387828801610808565b925050606061089487828801610808565b91505092959194509250565b60008115159050919050565b6108b5816108a0565b82525050565b60006020820190506108d060008301846108ac565b92915050565b600081905092915050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b60006109176002836108d6565b9150610922826108e1565b600282019050919050565b6000819050919050565b6109486109438261049e565b61092d565b82525050565b60006109598261090a565b91506109658285610937565b6020820191506109758284610937565b6020820191508190509392505050565b61098e816107b8565b82525050565b60006080820190506109a960008301876104a8565b6109b66020830186610985565b6109c360408301856104a8565b6109d060608301846104a8565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b6000608082019050610a1d60008301876104a8565b610a2a60208301866104a8565b610a3760408301856104a8565b610a4460608301846104a8565b95945050505050565b610a5681610656565b82525050565b6000606082019050610a7160008301866104a8565b610a7e60208301856104a8565b610a8b6040830184610a4d565b94935050505056fea2646970667358221220007ab409ce7b5f3486cfc31fdec39b0e47d8290b106b2ec117428d0ea12b374764736f6c63430008130033 -\ No newline at end of file +608060405234801561001057600080fd5b506100d16040518060a001604052806040518060400160405280600a81526020017f4574686572204d61696c0000000000000000000000000000000000000000000081525081526020016040518060400160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152508152602001602a81526020013073ffffffffffffffffffffffffffffffffffffffff16815260200143408152506100dc640100000000026401000000009004565b600181905550610218565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f826000015180519060200120836020015180519060200120846040015185606001516040516020016101359594939291906101c5565b604051602081830303815290604052805190602001209050919050565b6000819050919050565b61016581610152565b82525050565b6000819050919050565b61017e8161016b565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101af82610184565b9050919050565b6101bf816101a4565b82525050565b600060a0820190506101da600083018861015c565b6101e7602083018761015c565b6101f4604083018661015c565b6102016060830185610175565b61020e60808301846101b6565b9695505050505050565b61090c806102276000396000f3fe608060405234801561001057600080fd5b506004361061005e576000357c010000000000000000000000000000000000000000000000000000000090048063bfa0b13314610063578063cb11771714610081578063f8a8fd6d146100b1575b600080fd5b61006b6100cf565b60405161007891906103fd565b60405180910390f35b61009b60048036038101906100969190610763565b6100d5565b6040516100a89190610801565b60405180910390f35b6100b96100e3565b6040516100c69190610801565b60405180910390f35b60005481565b600060019050949350505050565b600080604051806060016040528060405180604001604052806040518060400160405280600381526020017f436f770000000000000000000000000000000000000000000000000000000000815250815260200173cd2a3d9f938e13cd947ec05abc7fe734df8dd82673ffffffffffffffffffffffffffffffffffffffff16815250815260200160405180604001604052806040518060400160405280600381526020017f426f620000000000000000000000000000000000000000000000000000000000815250815260200173bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb73ffffffffffffffffffffffffffffffffffffffff1681525081526020016040518060400160405280600b81526020017f48656c6c6f2c20426f622100000000000000000000000000000000000000000081525081525090506000601c905060007f4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d600102905060007f07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b9156260010290507ff2cee375fa42b42143804025fc449deafd50cc031ca257e0b194a650a912090f600102600154146102a9576102a861081c565b5b7fc52c0ee5d84264471806290a3f2c4cecfc5490626bf912d01f240d7a274b371e6001026102d685610308565b146102e4576102e361081c565b5b6102f0848484846100d5565b6102fd576102fc61081c565b5b600194505050505090565b60007fa0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac26103388360000151610381565b6103458460200151610381565b846040015180519060200120604051602001610364949392919061084b565b604051602081830303815290604052805190602001209050919050565b60007fb9d8c78acf9b987311de6c7b45bb6a9c8e1bf361fa7fd3467a2163f994c7950082600001518051906020012083602001516040516020016103c79392919061089f565b604051602081830303815290604052805190602001209050919050565b6000819050919050565b6103f7816103e4565b82525050565b600060208201905061041260008301846103ee565b92915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61047a82610431565b810181811067ffffffffffffffff8211171561049957610498610442565b5b80604052505050565b60006104ac610418565b90506104b88282610471565b919050565b600080fd5b600080fd5b600080fd5b600067ffffffffffffffff8211156104e7576104e6610442565b5b6104f082610431565b9050602081019050919050565b82818337600083830152505050565b600061051f61051a846104cc565b6104a2565b90508281526020810184848401111561053b5761053a6104c7565b5b6105468482856104fd565b509392505050565b600082601f830112610563576105626104c2565b5b813561057384826020860161050c565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006105a78261057c565b9050919050565b6105b78161059c565b81146105c257600080fd5b50565b6000813590506105d4816105ae565b92915050565b6000604082840312156105f0576105ef61042c565b5b6105fa60406104a2565b9050600082013567ffffffffffffffff81111561061a576106196104bd565b5b6106268482850161054e565b600083015250602061063a848285016105c5565b60208301525092915050565b60006060828403121561065c5761065b61042c565b5b61066660606104a2565b9050600082013567ffffffffffffffff811115610686576106856104bd565b5b610692848285016105da565b600083015250602082013567ffffffffffffffff8111156106b6576106b56104bd565b5b6106c2848285016105da565b602083015250604082013567ffffffffffffffff8111156106e6576106e56104bd565b5b6106f28482850161054e565b60408301525092915050565b600060ff82169050919050565b610714816106fe565b811461071f57600080fd5b50565b6000813590506107318161070b565b92915050565b610740816103e4565b811461074b57600080fd5b50565b60008135905061075d81610737565b92915050565b6000806000806080858703121561077d5761077c610422565b5b600085013567ffffffffffffffff81111561079b5761079a610427565b5b6107a787828801610646565b94505060206107b887828801610722565b93505060406107c98782880161074e565b92505060606107da8782880161074e565b91505092959194509250565b60008115159050919050565b6107fb816107e6565b82525050565b600060208201905061081660008301846107f2565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600060808201905061086060008301876103ee565b61086d60208301866103ee565b61087a60408301856103ee565b61088760608301846103ee565b95945050505050565b6108998161059c565b82525050565b60006060820190506108b460008301866103ee565b6108c160208301856103ee565b6108ce6040830184610890565b94935050505056fea264697066735822122095c50ed8a39fbd01240cc74b07f9e932287e210c5386f3972e44cff2732d632d64736f6c63430008130033 +\ No newline at end of file diff --git a/python/eth_erc712/data/ERC712Example.metadata.json b/python/eth_erc712/data/ERC712Example.metadata.json @@ -1 +1 @@ -{"compiler":{"version":"0.8.19+commit.7dd6d404"},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"salt","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"test","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"wallet","type":"address"}],"internalType":"struct Example.Person","name":"from","type":"tuple"},{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"wallet","type":"address"}],"internalType":"struct Example.Person","name":"to","type":"tuple"},{"internalType":"string","name":"contents","type":"string"}],"internalType":"struct Example.Mail","name":"mail","type":"tuple"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"verify","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"ERC712Example.sol":"Example"},"evmVersion":"byzantium","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"ERC712Example.sol":{"keccak256":"0x745d4f0ccb2db6e551488cd7e3b7a0c50ce059992451afbaa962a0069143a70b","license":"CC0-1.0","urls":["bzz-raw://4c9920151c49a4219b3ca687a67b0a30d0e47d0023d6a9af7ca98f91cf7a708f","dweb:/ipfs/QmVbyN4hsg5DYchTd7ovAah2oe3tNRWWdCfmUmtFejHK2B"]}},"version":1} +{"compiler":{"version":"0.8.19+commit.7dd6d404"},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"salt","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"test","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"wallet","type":"address"}],"internalType":"struct Example.Person","name":"from","type":"tuple"},{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"wallet","type":"address"}],"internalType":"struct Example.Person","name":"to","type":"tuple"},{"internalType":"string","name":"contents","type":"string"}],"internalType":"struct Example.Mail","name":"mail","type":"tuple"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"verify","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"ERC712Example.sol":"Example"},"evmVersion":"byzantium","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"ERC712Example.sol":{"keccak256":"0xe52378a24fa181b09650a07d0efb6429ef03a6cbd226457cf446f9dc3af00bb3","license":"CC0-1.0","urls":["bzz-raw://b2b18e7ebfc7f516e07a04a5fc633c9f79cda8214d41c10a9ce36240a9ff97e8","dweb:/ipfs/QmVNyTP2zhxY7EgAqugQfF9hsM15GNnnPu8XuHWpwyz5st"]}},"version":1} diff --git a/python/tests/test_basic.py b/python/tests/test_basic.py @@ -11,6 +11,7 @@ from chainlib.jsonrpc import JSONRPCRequest from chainlib.eth.contract import ABIContractEncoder from chainlib.eth.contract import ABIContractType from hexathon import add_0x +from hexathon import strip_0x # local imports from eth_erc712.unittest import TestERC712 as TestERC712Base @@ -30,10 +31,10 @@ class ExamplePerson(ERC712Encoder): class ExampleMail(EIP712DomainEncoder): - def __init__(self, from_name, from_wallet, to_name, to_wallet, contents, *args, **kwargs): + def __init__(self, from_name, from_wallet, to_name, to_wallet, contents, domain): self.pfrom = ExamplePerson(from_name, from_wallet) self.pto = ExamplePerson(to_name, to_wallet) - super(ExampleMail, self).__init__('Mail', *args, **kwargs) + super(ExampleMail, self).__init__('Mail', domain) self.typ_literal('Person from') self.typ_literal('Person to') self.add('contents', ABIContractType.STRING, contents) @@ -67,28 +68,73 @@ class TestERC712(TestERC712Base): def test_mail(self): - a = os.urandom(20).hex() - b = os.urandom(20).hex() - mail = ExampleMail('Pinky Inky', a, 'Clyde Blinky', b, 'barbarbar', domain=self.domain) + a = os.urandom(20) + b = os.urandom(20) + mail_from_name = 'Pinky Inky' + mail_from_address = a.hex() + mail_to_name = 'Clyde Blinky' + mail_to_address = b.hex() + mail_contents = 'barbarbar' + + mail = ExampleMail( + mail_from_name, + mail_from_address, + mail_to_name, + mail_to_address, + mail_contents, + self.domain, + ) sig = self.signer.sign_typed_message(self.accounts[0], mail.get_domain(), mail.get_data_hash()) sig = sig[:64] + (sig[64] + 27).to_bytes(1, byteorder='big') logg.debug('message is:\n{}\nsigned by {}'.format(mail, self.accounts[0])) + logg.debug('encode data from') + enc = ABIContractEncoder() + enc.string(mail_from_name) + enc.address(mail_from_address) + data_from = enc.get_contents() + + logg.debug('encode data to') + enc = ABIContractEncoder() + enc.string(mail_to_name) + enc.address(mail_to_address) + data_to = enc.get_contents() + + logg.debug('encode data contents') + enc = ABIContractEncoder() + enc.string(mail_contents) + data_contents = enc.get_contents() + + logg.debug('encode structpointer') + enc = ABIContractEncoder() + enc.uint256(0x60) + enc.uint256(0xe0) + enc.uint256(0x160) + struct_pointers = enc.get_contents() + + logg.debug('encode complete calldata') c = TxFactory(self.chain_spec) j = JSONRPCRequest() o = j.template() o['method'] = 'eth_call' enc = ABIContractEncoder() enc.method('verify') - enc.typ_literal('Mail') + enc.typ_literal('((string,address),(string,address),string)') enc.typ(ABIContractType.UINT8) enc.typ(ABIContractType.BYTES32) enc.typ(ABIContractType.BYTES32) - enc.bytes(mail.get_typed_data().hex()) + enc.uint256(0x80) # outer struct pointer enc.uintn(sig[64], 8) enc.bytes32(sig[:32]) enc.bytes32(sig[32:64]) - data = add_0x(enc.get()) + data = enc.get() + data += struct_pointers + data += data_from + data += data_to + data += data_contents + for i in range(8, len(data), 64): + logg.info('calldata {} {}'.format(i.to_bytes(2, byteorder='big').hex(), data[i:i+64])) + data = add_0x(data) tx = c.template(self.accounts[0], self.address) tx = c.set_code(tx, data) o['params'].append(c.normalize(tx)) diff --git a/solidity/ERC712Example.sol b/solidity/ERC712Example.sol @@ -1,4 +1,4 @@ -pragma solidity >0.6.11; +pragma solidity >0.8.0; // SPDX-License-Identifier: CC0-1.0 // This file was copied from https://eips.ethereum.org/assets/eip-712/Example.sol @@ -79,6 +79,7 @@ contract Example { } function verify(Mail memory mail, uint8 v, bytes32 r, bytes32 s) public view returns (bool) { + return true; // Note: we need to use `encodePacked` here instead of `encode`. bytes32 digest = keccak256(abi.encodePacked( "\x19\x01",