Fix setup.py to include all modules

This commit is contained in:
nolash
2020-08-08 11:33:15 +02:00
parent 4df619f072
commit 646dbf5f79
18 changed files with 181 additions and 171 deletions

View File

View File

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

View File

@@ -0,0 +1,40 @@
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, password=None):
raise NotImplementedError
class ReferenceSigner(Signer):
def __init__(self, keyGetter):
super(ReferenceSigner, self).__init__(keyGetter)
def signTransaction(self, tx, password=None):
s = tx.rlp_serialize()
h = sha3.keccak_256()
h.update(s)
g = h.digest()
k = keys.PrivateKey(self.keyGetter.get(tx.sender, password))
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

View File

@@ -0,0 +1,68 @@
# standard imports
import logging
import binascii
# third-party imports
from rlp import encode as rlp_encode
# local imports
from crypto_dev_signer.common import strip_hex_prefix, add_hex_prefix
logg = logging.getLogger(__name__)
class Transaction:
def rlp_serialize(self):
raise NotImplementedError
def serialize(self):
raise NotImplementedError
class EIP155Transaction:
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 = b''
self.s = b''
self.sender = strip_hex_prefix(tx['from'])
def rlp_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)
def serialize(self):
return {
'nonce': add_hex_prefix(hex(self.nonce)),
'gasPrice': add_hex_prefix(hex(self.gas_price)),
'gas': add_hex_prefix(hex(self.start_gas)),
'to': add_hex_prefix(self.to.hex()),
'value': add_hex_prefix(hex(self.value)),
'data': add_hex_prefix(self.data.hex()),
'v': add_hex_prefix(hex(self.v)),
'r': add_hex_prefix(self.r.hex()),
's': add_hex_prefix(self.s.hex()),
}

View File

@@ -0,0 +1,29 @@
import re
from web3 import Web3 as Web3super
from web3 import WebsocketProvider, HTTPProvider
from .middleware import PlatformMiddleware
re_websocket = re.compile('^wss?://')
re_http = re.compile('^https?://')
#def create_middleware(ipcaddr='/var/run/cic-platform/cic.ipc'):
def create_middleware(ipcaddr='/tmp/foo.ipc'):
PlatformMiddleware.ipcaddr = ipcaddr
return PlatformMiddleware
# overrides the original Web3 constructor
def Web3(blockchain_provider='ws://localhost:8546', ipcaddr=None):
provider = None
if re.match(re_websocket, blockchain_provider) != None:
provider = WebsocketProvider(blockchain_provider)
elif re.match(re_http, blockchain_provider) != None:
provider = HTTPProvider(blockchain_provider)
w3 = Web3super(provider)
w3.middleware_onion.add(create_middleware())
w3.eth.personal = w3.geth.personal
return w3

View File

@@ -0,0 +1,96 @@
# standard imports
import logging
import re
import socket
import uuid
import json
logg = logging.getLogger(__file__)
def jsonrpc_request(method, params):
uu = uuid.uuid4()
return {
"jsonrpc": "2.0",
"id": str(uu),
"method": method,
"params": params,
}
class PlatformMiddleware:
# id for the request is not available, meaning we cannot easily short-circuit
# hack workaround
id_seq = -1
re_personal = re.compile('^personal_.*')
ipcaddr = '/tmp/foo.ipc'
def __init__(self, make_request, w3):
self.w3 = w3
self.make_request = make_request
# TODO: understand what format input params come in
# single entry input gives a tuple on params, wtf...
# dict input comes as [{}] and fails if not passed on as an array
@staticmethod
def _translate_params(params):
if params.__class__.__name__ == 'tuple':
r = []
for p in params:
r.append(p)
return r
if params.__class__.__name__ == 'list' and len(params) > 0:
return params[0]
return params
def __call__(self, method, suspect_params):
self.id_seq += 1
logg.debug('in middleware method {} params {}'.format(method, suspect_params))
if self.re_personal.match(method) != None:
params = PlatformMiddleware._translate_params(suspect_params)
# multiple providers is broken in web3.py 5.12.0
# https://github.com/ethereum/web3.py/issues/1701
# hack workaround
s = socket.socket(family=socket.AF_UNIX, type=socket.SOCK_STREAM, proto=0)
ipc_provider_workaround = s.connect(self.ipcaddr)
logg.info('redirecting method {} params {} original params {}'.format(method, params, suspect_params))
o = jsonrpc_request(method, params)
j = json.dumps(o)
logg.debug('send {}'.format(j))
s.send(j.encode('utf-8'))
r = s.recv(4096)
s.close()
logg.debug('got recv {}'.format(str(r)))
jr = json.loads(r)
jr['id'] = self.id_seq
#return str(json.dumps(jr))
return jr
elif method == 'eth_signTransaction':
params = PlatformMiddleware._translate_params(suspect_params)
s = socket.socket(family=socket.AF_UNIX, type=socket.SOCK_STREAM, proto=0)
ipc_provider_workaround = s.connect(self.ipcaddr)
logg.info('redirecting method {} params {} original params {}'.format(method, params, suspect_params))
o = jsonrpc_request(method, params)
j = json.dumps(o)
logg.debug('send {}'.format(j))
s.send(j.encode('utf-8'))
r = s.recv(4096)
s.close()
logg.debug('got recv {}'.format(str(r)))
jr = json.loads(r)
jr['id'] = self.id_seq
#return str(json.dumps(jr))
return jr
r = self.make_request(method, suspect_params)
return r