funga

Signer and keystore daemon and library for cryptocurrency software development
Log | Files | Refs | README | LICENSE

commit 472e2f04fc106523b24b65f99aa572cc6df453fa
parent 34440ece7e43527e95d4293476a59ac8436147c1
Author: nolash <dev@holbrook.no>
Date:   Fri,  7 Aug 2020 23:01:49 +0200

Add eth_signTransaction workaround for missing personal_signTransaction

Diffstat:
Mscripts/server.py | 16+++++++++++++---
Msrc/common.py | 6++++++
Msrc/transaction.py | 20++++++++++----------
Msrc/web3ext/__init__.py | 2+-
Msrc/web3ext/middleware.py | 18++++++++++++++++++
5 files changed, 48 insertions(+), 14 deletions(-)

diff --git a/scripts/server.py b/scripts/server.py @@ -8,7 +8,7 @@ from jsonrpc.exceptions import * from signer import ReferenceSigner from keystore import ReferenceKeystore -from transaction import Transaction +from transaction import EIP155Transaction logging.basicConfig(level=logging.DEBUG) logg = logging.getLogger() @@ -38,18 +38,28 @@ def personal_new_account(p): def personal_sign_transaction(p): - t = Transaction(p[0], 0, 8995) + t = EIP155Transaction(p[0], 0, 8995) z = signer.signTransaction(t, p[1]) raw_signed_tx = t.rlp_serialize() - return { + o = { 'raw': '0x' + raw_signed_tx.hex(), 'tx': t.serialize(), } + return o + + +# TODO: temporary workaround for platform, since personal_signTransaction is missing from web3.py +def eth_signTransaction(tx): + password = tx['password'] + del tx['password'] + tx_signed = personal_sign_transaction([tx, password]) + return tx_signed methods = { 'personal_newAccount': personal_new_account, 'personal_signTransaction': personal_sign_transaction, + 'eth_signTransaction': eth_signTransaction, } diff --git a/src/common.py b/src/common.py @@ -3,3 +3,9 @@ def strip_hex_prefix(hx): return hx[2:] return hx +def add_hex_prefix(hx): + if len(hx) < 2: + return hx + if hx[:2] != '0x': + return '0x' + hx + return hx diff --git a/src/transaction.py b/src/transaction.py @@ -3,7 +3,7 @@ import binascii from rlp import encode as rlp_encode -from common import strip_hex_prefix +from common import strip_hex_prefix, add_hex_prefix logg = logging.getLogger(__name__) @@ -52,13 +52,13 @@ class EIP155Transaction: def serialize(self): return { - 'nonce': '0x' + hex(self.nonce), - 'gasPrice': '0x' + hex(self.gas_price), - 'gas': '0x' + hex(self.start_gas), - 'to': '0x' + self.to.hex(), - 'value': '0x' + hex(self.value), - 'data': '0x' + self.data.hex(), - 'v': '0x' + hex(self.v), - 'r': '0x' + self.r.hex(), - 's': '0x' + self.s.hex(), + '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()), } diff --git a/src/web3ext/__init__.py b/src/web3ext/__init__.py @@ -19,7 +19,7 @@ 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_providers[0]) != None: + elif re.match(re_http, blockchain_provider) != None: provider = HTTPProvider(blockchain_provider) w3 = Web3super(provider) diff --git a/src/web3ext/middleware.py b/src/web3ext/middleware.py @@ -73,5 +73,23 @@ class PlatformMiddleware: #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