Skip to content

Instantly share code, notes, and snippets.

@alexisrobert
Last active February 11, 2024 18:15
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save alexisrobert/9facb3d21d4f04946f3a41b5a3c0a9a1 to your computer and use it in GitHub Desktop.
Save alexisrobert/9facb3d21d4f04946f3a41b5a3c0a9a1 to your computer and use it in GitHub Desktop.
Python script that signs EIP712 structs that can be validated by EVM smart contracts
# Python script that signs EIP712 structs that can be validated
# by EVM smart contracts.
#
# Copyright (c) 2021 Alexis Robert <github@me.ale6.net>
#
# Dependencies:
# coincurve==15.0.1
# eip712-structs==1.1.0
import os
import sha3
from eip712_structs import EIP712Struct, Address, String, Uint
from eip712_structs import make_domain
from eth_utils import big_endian_to_int
from coincurve import PrivateKey, PublicKey
keccak_hash = lambda x : sha3.keccak_256(x).digest()
# Configuration of the EIP712 domain
my_domain = make_domain(name='TestContract',
version='0.1',
chainId=80001,
verifyingContract='0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')
# Configuration of the EIP712 message struct
class Mail(EIP712Struct):
to = Address()
contents = String()
# Instanciation of a new EIP712 message
msg = Mail()
msg['to'] = '0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'
msg['contents'] = "Hello world!"
# Converting it to signable bytes
signable_bytes = msg.signable_bytes(my_domain)
# Now ... sign it :)
pk = PrivateKey.from_hex(os.getenv('PRIVATE_KEY'))
signature = pk.sign_recoverable(signable_bytes, hasher=keccak_hash)
v = signature[64] + 27
r = big_endian_to_int(signature[0:32])
s = big_endian_to_int(signature[32:64])
final_sig = r.to_bytes(32, 'big') + s.to_bytes(32, 'big') + v.to_bytes(1, 'big')
print("Signature:",final_sig.hex())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment