2020-08-04 23:41:31 +02:00
|
|
|
import logging
|
|
|
|
import sha3
|
|
|
|
|
|
|
|
from eth_keys import KeyAPI
|
|
|
|
from eth_keys.backends import NativeECCBackend
|
|
|
|
|
|
|
|
keys = KeyAPI(NativeECCBackend)
|
|
|
|
logg = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
class Signer:
|
|
|
|
|
2020-08-05 18:14:25 +02:00
|
|
|
|
2020-08-04 23:41:31 +02:00
|
|
|
def __init__(self, keyGetter):
|
|
|
|
self.keyGetter = keyGetter
|
|
|
|
|
2020-08-05 18:14:25 +02:00
|
|
|
|
2020-08-06 11:07:18 +02:00
|
|
|
def signTransaction(self, tx, password=None):
|
2020-08-04 23:41:31 +02:00
|
|
|
raise NotImplementedError
|
|
|
|
|
|
|
|
|
2020-08-05 18:14:25 +02:00
|
|
|
|
2020-08-04 23:41:31 +02:00
|
|
|
class ReferenceSigner(Signer):
|
2020-08-05 18:14:25 +02:00
|
|
|
|
|
|
|
|
2020-08-04 23:41:31 +02:00
|
|
|
def __init__(self, keyGetter):
|
|
|
|
super(ReferenceSigner, self).__init__(keyGetter)
|
|
|
|
|
|
|
|
|
2020-08-05 21:30:08 +02:00
|
|
|
def signTransaction(self, tx, password=None):
|
2020-08-05 22:00:23 +02:00
|
|
|
s = tx.rlp_serialize()
|
2020-08-04 23:41:31 +02:00
|
|
|
h = sha3.keccak_256()
|
|
|
|
h.update(s)
|
|
|
|
g = h.digest()
|
2020-08-06 11:07:18 +02:00
|
|
|
k = keys.PrivateKey(self.keyGetter.get(tx.sender, password))
|
2020-08-04 23:41:31 +02:00
|
|
|
z = keys.ecdsa_sign(message_hash=g, private_key=k)
|
2021-01-12 14:50:52 +01:00
|
|
|
vnum = int.from_bytes(tx.v, 'big')
|
|
|
|
v = (vnum * 2) + 35 + z[64]
|
|
|
|
byts = ((v.bit_length()-1)/8)+1
|
|
|
|
tx.v = v.to_bytes(int(byts), 'big')
|
2020-08-04 23:41:31 +02:00
|
|
|
tx.r = z[:32]
|
|
|
|
tx.s = z[32:64]
|
2021-02-07 11:55:40 +01:00
|
|
|
if tx.r[0] == 0:
|
|
|
|
tx.r = tx.r[1:]
|
|
|
|
if tx.s[0] == 0:
|
2021-02-07 16:23:15 +01:00
|
|
|
tx.s = tx.s[1:]
|
2020-08-04 23:41:31 +02:00
|
|
|
return z
|
2020-12-19 08:47:21 +01:00
|
|
|
|
|
|
|
|
|
|
|
def signEthereumMessage(self, address, message, password=None):
|
|
|
|
#msg = b'\x19Ethereum Signed Message:\n{}{}'.format(len(message), message)
|
|
|
|
k = keys.PrivateKey(self.keyGetter.get(address, password))
|
|
|
|
#z = keys.ecdsa_sign(message_hash=g, private_key=k)
|
2020-12-25 12:34:05 +01:00
|
|
|
z = None
|
|
|
|
if type(message).__name__ == 'str':
|
2020-12-25 12:53:16 +01:00
|
|
|
logg.debug('signing message in "str" format: {}'.format(message))
|
2021-01-09 20:25:47 +01:00
|
|
|
z = k.sign_msg(bytes.fromhex(message))
|
2020-12-25 12:34:05 +01:00
|
|
|
elif type(message).__name__ == 'bytes':
|
2020-12-25 12:53:16 +01:00
|
|
|
logg.debug('signing message in "bytes" format: {}'.format(message.hex()))
|
2020-12-25 12:34:05 +01:00
|
|
|
z = k.sign_msg(message)
|
|
|
|
else:
|
|
|
|
raise ValueError('message must be type str or bytes, received {}'.format(type(message).__name__))
|
2020-12-19 08:47:21 +01:00
|
|
|
return z
|
|
|
|
|