Handle hex inputs for tx create
This commit is contained in:
parent
d46d0620fa
commit
b7a35ea181
@ -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
|
||||
|
@ -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''
|
||||
|
@ -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:
|
||||
|
@ -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'))
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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()
|
||||
|
58
scripts/import.py
Normal file
58
scripts/import.py
Normal 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)
|
4
setup.py
4
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,
|
||||
|
@ -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': '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')
|
||||
|
||||
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):
|
||||
t = EIP155Transaction(tx, 461, 8995)
|
||||
t = EIP155Transaction(tx_ints, 461, 8995)
|
||||
s = ReferenceSigner(self.pk_getter)
|
||||
z = s.signTransaction(t)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user