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
|
* 0.3.0
|
||||||
- Implement SQLAlchemy for db backend
|
- Implement SQLAlchemy for db backend
|
||||||
* 0.2.6
|
* 0.2.6
|
||||||
|
@ -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''
|
||||||
|
@ -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:
|
||||||
|
@ -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'))
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
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(
|
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,
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user