Initial commit

This commit is contained in:
nolash 2020-08-04 23:41:31 +02:00
commit fafef39943
Signed by: lash
GPG Key ID: 93EC1C676274C889
5 changed files with 151 additions and 0 deletions

5
src/common.py Normal file
View File

@ -0,0 +1,5 @@
def strip_hex_prefix(hx):
if hx[:2] == '0x':
return hx[2:]
return hx

1
src/signer/__init__.py Normal file
View File

@ -0,0 +1 @@
from signer.defaultsigner import ReferenceSigner, Signer

View File

@ -0,0 +1,39 @@
import logging
import sha3
from eth_keys import KeyAPI
from eth_keys.backends import NativeECCBackend
keys = KeyAPI(NativeECCBackend)
logg = logging.getLogger(__name__)
class Signer:
def __init__(self, keyGetter):
self.keyGetter = keyGetter
def signTransaction(self, tx):
raise NotImplementedError
class ReferenceSigner(Signer):
def __init__(self, keyGetter):
super(ReferenceSigner, self).__init__(keyGetter)
def signTransaction(self, tx):
s = tx.serialize()
h = sha3.keccak_256()
h.update(s)
g = h.digest()
k = keys.PrivateKey(self.keyGetter(tx.sender))
z = keys.ecdsa_sign(message_hash=g, private_key=k)
tx.v = (tx.v * 2) + 35 + z[64]
tx.r = z[:32]
tx.s = z[32:64]
return z

42
src/transaction.py Normal file
View File

@ -0,0 +1,42 @@
import logging
import binascii
from rlp import encode as rlp_encode
from common import strip_hex_prefix
logg = logging.getLogger(__name__)
class Transaction:
def __init__(self, tx, nonce, chainId=1):
to = binascii.unhexlify(strip_hex_prefix(tx['to']))
data = binascii.unhexlify(strip_hex_prefix(tx['data']))
self.nonce = nonce
self.gas_price = int(tx['gasPrice'])
self.start_gas = int(tx['gas'])
self.to = to
self.value = int(tx['value'])
self.data = data
self.v = chainId
self.r = 0
self.s = 0
self.sender = tx['from']
def serialize(self):
b = self.nonce.to_bytes(8, byteorder='little')
s = [
self.nonce,
self.gas_price,
self.start_gas,
self.to,
self.value,
self.data,
self.v,
self.r,
self.s,
]
return rlp_encode(s)

64
test/sign.py Normal file
View File

@ -0,0 +1,64 @@
#!/usr/bin/python
import unittest
import logging
from rlp import encode as rlp_encode
from signer import ReferenceSigner
from transaction import Transaction
logging.basicConfig(level=logging.DEBUG)
logg = logging.getLogger()
tx = {
'from': "0xEB014f8c8B418Db6b45774c326A0E64C78914dC0",
'gasPrice': "20000000000",
'gas': "22000",
'to': '0x3535353535353535353535353535353535353535',
'value': "1000",
'data': "deadbeef",
}
class TestSign(unittest.TestCase):
pk = None
nonce = -1
def getPk(self, address):
return self.pk
def getNonce(self):
self.nonce += 1
return self.nonce
def setUp(self):
#self.pk = b'abcdefghijklmnopqrstuvwxyz012345' #random.sample(range(256), k=32)
self.pk = bytes.fromhex('5087503f0a9cc35b38665955eb830c63f778453dd11b8fa5bd04bc41fd2cc6d6')
def tearDown(self):
logg.info('teardown empty')
def test_serialize_transaction(self):
t = Transaction(tx, 0)
self.assertRegex(t.__class__.__name__, "Transaction")
logg.debug('{}'.format(rlp_encode(t.serialize())))
def test_sign_transaction(self):
t = Transaction(tx, 461, 8995)
s = ReferenceSigner(self.getPk)
z = s.signTransaction(t)
logg.debug('{}'.format(z.to_bytes()))
logg.debug('{}'.format(t.serialize().hex()))
if __name__ == '__main__':
unittest.main()