commit b7a35ea18136744eff521e2fa023e83d2779a7be
parent d46d0620fae4ed8515807974a348bb81a5c57dbd
Author: nolash <dev@holbrook.no>
Date: Mon, 26 Oct 2020 09:02:29 +0100
Handle hex inputs for tx create
Diffstat:
9 files changed, 131 insertions(+), 27 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
@@ -1,3 +1,7 @@
+* 0.4.0
+ - Handle hex inputs for int values in transaction dict
+ - Change signature for Web3 constructor to take provider instead of url
+ - Add script for importing private key from hex
* 0.3.0
- Implement SQLAlchemy for db backend
* 0.2.6
diff --git a/crypto_dev_signer/eth/transaction.py b/crypto_dev_signer/eth/transaction.py
@@ -27,11 +27,35 @@ class EIP155Transaction:
to = binascii.unhexlify(strip_hex_prefix(tx['to']))
data = binascii.unhexlify(strip_hex_prefix(tx['data']))
+ gas_price = None
+ start_gas = None
+ value = None
+
+ try:
+ gas_price = int(tx['gasPrice'])
+ except ValueError:
+ gas_price = int(tx['gasPrice'], 16)
+
+ try:
+ start_gas = int(tx['gas'])
+ except ValueError:
+ start_gas = int(tx['gas'], 16)
+
+ try:
+ value = int(tx['value'])
+ except ValueError:
+ value = int(tx['value'], 16)
+
+ try:
+ nonce = int(nonce)
+ except ValueError:
+ nonce = int(nonce, 16)
+
self.nonce = nonce
- self.gas_price = int(tx['gasPrice'])
- self.start_gas = int(tx['gas'])
+ self.gas_price = gas_price
+ self.start_gas = start_gas
self.to = to
- self.value = int(tx['value'])
+ self.value = value
self.data = data
self.v = chainId
self.r = b''
diff --git a/crypto_dev_signer/eth/web3ext/__init__.py b/crypto_dev_signer/eth/web3ext/__init__.py
@@ -17,13 +17,8 @@ def create_middleware(ipcpath):
# overrides the original Web3 constructor
-def Web3(blockchain_provider='ws://localhost:8546', ipcpath=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)
-
+#def Web3(blockchain_provider='ws://localhost:8546', ipcpath=None):
+def Web3(provider, ipcpath=None):
w3 = Web3super(provider)
if ipcpath != None:
diff --git a/crypto_dev_signer/eth/web3ext/middleware.py b/crypto_dev_signer/eth/web3ext/middleware.py
@@ -38,11 +38,11 @@ class PlatformMiddleware:
# 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__ == 'tuple':
+ # r = []
+ # for p in params:
+ # r.append(p)
+ # return r
if params.__class__.__name__ == 'list' and len(params) > 0:
return params[0]
@@ -64,7 +64,7 @@ class PlatformMiddleware:
ipc_provider_workaround = s.connect(self.ipcaddr)
logg.info('redirecting method {} params {} original params {}'.format(method, params, suspect_params))
- o = jsonrpc_request(method, params)
+ o = jsonrpc_request(method, params[0])
j = json.dumps(o)
logg.debug('send {}'.format(j))
s.send(j.encode('utf-8'))
@@ -81,8 +81,8 @@ class PlatformMiddleware:
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)
+ logg.info('redirecting methodd {} params {} original params {}'.format(method, params, suspect_params))
+ o = jsonrpc_request(method, params[0])
j = json.dumps(o)
logg.debug('send {}'.format(j))
s.send(j.encode('utf-8'))
diff --git a/crypto_dev_signer/keystore/postgres.py b/crypto_dev_signer/keystore/postgres.py
@@ -75,6 +75,7 @@ class ReferenceKeystore(Keystore):
},
)
self.db_session.commit()
+ logg.info('added private key for address {}'.format(address_hex_clean))
return address_hex
diff --git a/crypto_dev_signer/runnable/signer.py b/crypto_dev_signer/runnable/signer.py
@@ -97,6 +97,7 @@ def personal_new_account(p):
def personal_sign_transaction(p):
+ logg.debug('got {} to sign'.format(p[0]))
t = EIP155Transaction(p[0], p[0]['nonce'], 8995)
z = signer.signTransaction(t, p[1])
raw_signed_tx = t.rlp_serialize()
@@ -212,7 +213,6 @@ def init():
signer = ReferenceSigner(db)
-#if __name__ == '__main__':
def main():
init()
arg = None
@@ -226,3 +226,7 @@ def main():
(rpc_id, response) = process_input(arg)
r = jsonrpc_ok(rpc_id, response)
sys.stdout.write(json.dumps(r))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/scripts/import.py b/scripts/import.py
@@ -0,0 +1,58 @@
+# standard imports
+import os
+import sys
+import logging
+import argparse
+
+# third-party imports
+import confini
+
+# local imports
+from crypto_dev_signer.keystore import ReferenceKeystore
+
+logging.basicConfig(level=logging.WARNING)
+logg = logging.getLogger()
+
+config_dir = os.path.join('/usr/local/etc/cic-eth')
+
+db = None
+
+
+argparser = argparse.ArgumentParser()
+argparser.add_argument('-c', type=str, default=config_dir, help='config file')
+argparser.add_argument('--env-prefix', default=os.environ.get('CONFINI_ENV_PREFIX'), dest='env_prefix', type=str, help='environment prefix for variables to overwrite configuration')
+argparser.add_argument('-v', action='store_true', help='be verbose')
+argparser.add_argument('-vv', action='store_true', help='be more verbose')
+argparser.add_argument('private_key', type=str, help='private key to add, 0x hex format')
+args = argparser.parse_args()
+
+if args.vv:
+ logging.getLogger().setLevel(logging.DEBUG)
+elif args.v:
+ logging.getLogger().setLevel(logging.INFO)
+
+config = confini.Config(args.c, args.env_prefix)
+config.process()
+config.censor('PASSWORD', 'DATABASE')
+config.censor('SECRET', 'SIGNER')
+logg.debug('config loaded from {}:\n{}'.format(config_dir, config))
+
+# connect to database
+dsn = 'postgresql://{}:{}@{}:{}/{}'.format(
+ config.get('DATABASE_USER'),
+ config.get('DATABASE_PASSWORD'),
+ config.get('DATABASE_HOST'),
+ config.get('DATABASE_PORT'),
+ config.get('DATABASE_NAME'),
+ )
+
+logg.info('using dsn {}'.format(dsn))
+
+
+if __name__ == '__main__':
+ kw = {
+ 'symmetric_key': bytes.fromhex(config.get('SIGNER_SECRET')),
+ }
+ r = ReferenceKeystore(dsn, **kw)
+ private_key_bytes = bytes.fromhex(args.private_key)
+ r.import_raw_key(private_key_bytes)
diff --git a/setup.py b/setup.py
@@ -6,7 +6,7 @@ f.close()
setup(
name="crypto-dev-signer",
- version="0.3.0",
+ version="0.4.0",
description="A signer and keystore daemon and library for cryptocurrency software development",
author="Louis Holbrook",
author_email="dev@holbrook.no",
@@ -26,7 +26,7 @@ setup(
'pysha3',
'rlp',
'json-rpc',
- 'confini==0.2.6',
+ 'confini==0.2.7',
'sqlalchemy==1.3.19',
],
long_description=long_description,
diff --git a/test/test_sign.py b/test/test_sign.py
@@ -12,15 +12,26 @@ logging.basicConfig(level=logging.DEBUG)
logg = logging.getLogger()
-tx = {
+tx_ints = {
+ 'nonce': 0,
'from': "0xEB014f8c8B418Db6b45774c326A0E64C78914dC0",
'gasPrice': "20000000000",
- 'gas': "22000",
+ 'gas': "21000",
'to': '0x3535353535353535353535353535353535353535',
'value': "1000",
'data': "deadbeef",
}
+tx_hexs = {
+ 'nonce': '0x0',
+ 'from': "0xEB014f8c8B418Db6b45774c326A0E64C78914dC0",
+ 'gasPrice': "0x4a817c800",
+ 'gas': "0x5208",
+ 'to': '0x3535353535353535353535353535353535353535',
+ 'value': "0x3e8",
+ 'data': "deadbeef",
+}
+
class pkGetter:
def __init__(self, pk):
@@ -54,17 +65,24 @@ class TestSign(unittest.TestCase):
# TODO: verify rlp tx output
def test_serialize_transaction(self):
- t = EIP155Transaction(tx, 0)
+ t = EIP155Transaction(tx_ints, 0)
+ self.assertRegex(t.__class__.__name__, "Transaction")
+ s = t.serialize()
+ self.assertEqual('{}'.format(s), "{'nonce': '0x0', 'gasPrice': '0x4a817c800', 'gas': '0x5208', 'to': '0x3535353535353535353535353535353535353535', 'value': '0x3e8', 'data': '0xdeadbeef', 'v': '0x1', 'r': '', 's': ''}")
+ r = t.rlp_serialize()
+ self.assertEqual(r.hex(), 'ea808504a817c8008252089435353535353535353535353535353535353535358203e884deadbeef018080')
+
+ t = EIP155Transaction(tx_hexs, 0)
self.assertRegex(t.__class__.__name__, "Transaction")
s = t.serialize()
- self.assertEqual('{}'.format(s), "{'nonce': '0x0', 'gasPrice': '0x4a817c800', 'gas': '0x55f0', 'to': '0x3535353535353535353535353535353535353535', 'value': '0x3e8', 'data': '0xdeadbeef', 'v': '0x1', 'r': '', 's': ''}")
+ self.assertEqual('{}'.format(s), "{'nonce': '0x0', 'gasPrice': '0x4a817c800', 'gas': '0x5208', 'to': '0x3535353535353535353535353535353535353535', 'value': '0x3e8', 'data': '0xdeadbeef', 'v': '0x1', 'r': '', 's': ''}")
r = t.rlp_serialize()
- self.assertEqual(r.hex(), 'ea808504a817c8008255f09435353535353535353535353535353535353535358203e884deadbeef018080')
+ self.assertEqual(r.hex(), 'ea808504a817c8008252089435353535353535353535353535353535353535358203e884deadbeef018080')
def test_sign_transaction(self):
- t = EIP155Transaction(tx, 461, 8995)
+ t = EIP155Transaction(tx_ints, 461, 8995)
s = ReferenceSigner(self.pk_getter)
z = s.signTransaction(t)