Handle hex inputs for tx create

This commit is contained in:
nolash 2020-10-26 09:02:29 +01:00
parent d46d0620fa
commit b7a35ea181
Signed by: lash
GPG Key ID: 21D2E7BB88C2A746
9 changed files with 131 additions and 27 deletions

View File

@ -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 * 0.3.0
- Implement SQLAlchemy for db backend - Implement SQLAlchemy for db backend
* 0.2.6 * 0.2.6

View File

@ -27,11 +27,35 @@ class EIP155Transaction:
to = binascii.unhexlify(strip_hex_prefix(tx['to'])) to = binascii.unhexlify(strip_hex_prefix(tx['to']))
data = binascii.unhexlify(strip_hex_prefix(tx['data'])) 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.nonce = nonce
self.gas_price = int(tx['gasPrice']) self.gas_price = gas_price
self.start_gas = int(tx['gas']) self.start_gas = start_gas
self.to = to self.to = to
self.value = int(tx['value']) self.value = value
self.data = data self.data = data
self.v = chainId self.v = chainId
self.r = b'' self.r = b''

View File

@ -17,13 +17,8 @@ def create_middleware(ipcpath):
# overrides the original Web3 constructor # overrides the original Web3 constructor
def Web3(blockchain_provider='ws://localhost:8546', ipcpath=None): #def Web3(blockchain_provider='ws://localhost:8546', ipcpath=None):
provider = None def Web3(provider, ipcpath=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 = Web3super(provider)
if ipcpath != None: if ipcpath != None:

View File

@ -38,11 +38,11 @@ class PlatformMiddleware:
# dict input comes as [{}] and fails if not passed on as an array # dict input comes as [{}] and fails if not passed on as an array
@staticmethod @staticmethod
def _translate_params(params): def _translate_params(params):
if params.__class__.__name__ == 'tuple': #if params.__class__.__name__ == 'tuple':
r = [] # r = []
for p in params: # for p in params:
r.append(p) # r.append(p)
return r # return r
if params.__class__.__name__ == 'list' and len(params) > 0: if params.__class__.__name__ == 'list' and len(params) > 0:
return params[0] return params[0]
@ -64,7 +64,7 @@ class PlatformMiddleware:
ipc_provider_workaround = s.connect(self.ipcaddr) ipc_provider_workaround = s.connect(self.ipcaddr)
logg.info('redirecting method {} params {} original params {}'.format(method, params, suspect_params)) 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) j = json.dumps(o)
logg.debug('send {}'.format(j)) logg.debug('send {}'.format(j))
s.send(j.encode('utf-8')) s.send(j.encode('utf-8'))
@ -81,8 +81,8 @@ class PlatformMiddleware:
params = PlatformMiddleware._translate_params(suspect_params) params = PlatformMiddleware._translate_params(suspect_params)
s = socket.socket(family=socket.AF_UNIX, type=socket.SOCK_STREAM, proto=0) s = socket.socket(family=socket.AF_UNIX, type=socket.SOCK_STREAM, proto=0)
ipc_provider_workaround = s.connect(self.ipcaddr) ipc_provider_workaround = s.connect(self.ipcaddr)
logg.info('redirecting method {} params {} original params {}'.format(method, params, suspect_params)) logg.info('redirecting methodd {} params {} original params {}'.format(method, params, suspect_params))
o = jsonrpc_request(method, params) o = jsonrpc_request(method, params[0])
j = json.dumps(o) j = json.dumps(o)
logg.debug('send {}'.format(j)) logg.debug('send {}'.format(j))
s.send(j.encode('utf-8')) s.send(j.encode('utf-8'))

View File

@ -75,6 +75,7 @@ class ReferenceKeystore(Keystore):
}, },
) )
self.db_session.commit() self.db_session.commit()
logg.info('added private key for address {}'.format(address_hex_clean))
return address_hex return address_hex

View File

@ -97,6 +97,7 @@ def personal_new_account(p):
def personal_sign_transaction(p): def personal_sign_transaction(p):
logg.debug('got {} to sign'.format(p[0]))
t = EIP155Transaction(p[0], p[0]['nonce'], 8995) t = EIP155Transaction(p[0], p[0]['nonce'], 8995)
z = signer.signTransaction(t, p[1]) z = signer.signTransaction(t, p[1])
raw_signed_tx = t.rlp_serialize() raw_signed_tx = t.rlp_serialize()
@ -212,7 +213,6 @@ def init():
signer = ReferenceSigner(db) signer = ReferenceSigner(db)
#if __name__ == '__main__':
def main(): def main():
init() init()
arg = None arg = None
@ -226,3 +226,7 @@ def main():
(rpc_id, response) = process_input(arg) (rpc_id, response) = process_input(arg)
r = jsonrpc_ok(rpc_id, response) r = jsonrpc_ok(rpc_id, response)
sys.stdout.write(json.dumps(r)) sys.stdout.write(json.dumps(r))
if __name__ == '__main__':
main()

58
scripts/import.py Normal file
View File

@ -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)

View File

@ -6,7 +6,7 @@ f.close()
setup( setup(
name="crypto-dev-signer", name="crypto-dev-signer",
version="0.3.0", version="0.4.0",
description="A signer and keystore daemon and library for cryptocurrency software development", description="A signer and keystore daemon and library for cryptocurrency software development",
author="Louis Holbrook", author="Louis Holbrook",
author_email="dev@holbrook.no", author_email="dev@holbrook.no",
@ -26,7 +26,7 @@ setup(
'pysha3', 'pysha3',
'rlp', 'rlp',
'json-rpc', 'json-rpc',
'confini==0.2.6', 'confini==0.2.7',
'sqlalchemy==1.3.19', 'sqlalchemy==1.3.19',
], ],
long_description=long_description, long_description=long_description,

View File

@ -12,15 +12,26 @@ logging.basicConfig(level=logging.DEBUG)
logg = logging.getLogger() logg = logging.getLogger()
tx = { tx_ints = {
'nonce': 0,
'from': "0xEB014f8c8B418Db6b45774c326A0E64C78914dC0", 'from': "0xEB014f8c8B418Db6b45774c326A0E64C78914dC0",
'gasPrice': "20000000000", 'gasPrice': "20000000000",
'gas': "22000", 'gas': "21000",
'to': '0x3535353535353535353535353535353535353535', 'to': '0x3535353535353535353535353535353535353535',
'value': "1000", 'value': "1000",
'data': "deadbeef", 'data': "deadbeef",
} }
tx_hexs = {
'nonce': '0x0',
'from': "0xEB014f8c8B418Db6b45774c326A0E64C78914dC0",
'gasPrice': "0x4a817c800",
'gas': "0x5208",
'to': '0x3535353535353535353535353535353535353535',
'value': "0x3e8",
'data': "deadbeef",
}
class pkGetter: class pkGetter:
def __init__(self, pk): def __init__(self, pk):
@ -54,17 +65,24 @@ class TestSign(unittest.TestCase):
# TODO: verify rlp tx output # TODO: verify rlp tx output
def test_serialize_transaction(self): def test_serialize_transaction(self):
t = EIP155Transaction(tx, 0) t = EIP155Transaction(tx_ints, 0)
self.assertRegex(t.__class__.__name__, "Transaction") self.assertRegex(t.__class__.__name__, "Transaction")
s = t.serialize() 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() r = t.rlp_serialize()
self.assertEqual(r.hex(), 'ea808504a817c8008255f09435353535353535353535353535353535353535358203e884deadbeef018080') 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': '0x5208', 'to': '0x3535353535353535353535353535353535353535', 'value': '0x3e8', 'data': '0xdeadbeef', 'v': '0x1', 'r': '', 's': ''}")
r = t.rlp_serialize()
self.assertEqual(r.hex(), 'ea808504a817c8008252089435353535353535353535353535353535353535358203e884deadbeef018080')
def test_sign_transaction(self): def test_sign_transaction(self):
t = EIP155Transaction(tx, 461, 8995) t = EIP155Transaction(tx_ints, 461, 8995)
s = ReferenceSigner(self.pk_getter) s = ReferenceSigner(self.pk_getter)
z = s.signTransaction(t) z = s.signTransaction(t)