Ethereum autosigning

This commit is contained in:
The MMGen Project 2018-05-31 19:02:00 +00:00
commit 2c97f61ea4
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
5 changed files with 26 additions and 10 deletions

View file

@ -29,6 +29,8 @@ part_label = u'MMGEN_TX'
wallet_dir = u'/dev/shm/autosign'
key_fn = u'autosign.key'
no_daemon_coins = ('ETH',)
from mmgen.common import *
prog_name = os.path.basename(sys.argv[0])
opts_data = lambda: {
@ -119,6 +121,7 @@ def check_daemons_running():
coins = ['BTC']
for coin in coins:
if coin in no_daemon_coins: continue
g.proto = CoinProtocol(coin,g.testnet)
vmsg('Checking {} daemon'.format(coin))
try:
@ -153,10 +156,11 @@ def do_umount():
def sign_tx_file(txfile):
try:
init_coin(mmgen.tx.MMGenTX(txfile,md_only=True).coin)
init_coin(mmgen.tx.MMGenTX(txfile,coin_sym_only=True).coin)
reload(sys.modules['mmgen.tx'])
tx = mmgen.tx.MMGenTX(txfile)
rpc_init(reinit=True)
if tx.coin not in no_daemon_coins:
rpc_init(reinit=True)
txsign(tx,wfs,None,None)
tx.write_to_file(ask_write=False)
return True

View file

@ -90,6 +90,7 @@ class BitcoinProtocol(MMGenObject):
witness_vernum_hex = '00'
witness_vernum = int(witness_vernum_hex,16)
bech32_hrp = 'bc'
chain_aliases = {}
@classmethod
def is_testnet(cls):
@ -303,6 +304,7 @@ class EthereumProtocol(DummyWIF,BitcoinProtocolAddrgen):
rpc_port = 8545
mmcaps = ('key','addr','rpc')
coin_amt = ETHAmt
chain_aliases = {'mainnet':['foundation'],'testnet':['kovan']}
@classmethod

View file

@ -275,7 +275,7 @@ class MMGenTX(MMGenObject):
cls = EthereumMMGenTX
return MMGenObject.__new__(cls,*args,**kwargs)
def __init__(self,filename=None,md_only=False,caller=None,silent_open=False):
def __init__(self,filename=None,coin_sym_only=False,caller=None,silent_open=False):
self.inputs = self.MMGenTxInputList()
self.outputs = self.MMGenTxOutputList()
self.send_amt = g.proto.coin_amt('0') # total amt minus change
@ -295,8 +295,8 @@ class MMGenTX(MMGenObject):
self.locktime = None
if filename:
self.parse_tx_file(filename,md_only=md_only,silent_open=silent_open)
if md_only: return
self.parse_tx_file(filename,coin_sym_only=coin_sym_only,silent_open=silent_open)
if coin_sym_only: return
self.check_sigs() # marks the tx as signed
# repeat with sign and send, because coin daemon could be restarted
@ -306,6 +306,8 @@ class MMGenTX(MMGenObject):
assert on_fail in ('return','die'),"'{}': invalid value for 'on_fail'".format(on_fail)
m = 'Transaction is for {}, but current chain is {}!'.format(self.chain,g.chain)
bad = self.chain and g.chain and self.chain != g.chain
if bad and g.chain in g.proto.chain_aliases:
bad = self.chain not in g.proto.chain_aliases[g.chain]
if bad:
msg(m) if on_fail == 'return' else die(2,m)
return not bad
@ -1089,7 +1091,7 @@ class MMGenTX(MMGenObject):
def check_tx_hex_data(self):
self.hex = HexStr(self.hex,on_fail='raise')
def parse_tx_file(self,infile,md_only=False,silent_open=False):
def parse_tx_file(self,infile,coin_sym_only=False,silent_open=False):
def eval_io_data(raw_data,desc):
from ast import literal_eval
@ -1147,6 +1149,7 @@ class MMGenTX(MMGenObject):
self.locktime = int(metadata.pop()[3:])
self.coin = metadata.pop(0) if len(metadata) == 6 else 'BTC'
if coin_sym_only: return
if len(metadata) == 5:
t = metadata.pop(0)
@ -1161,7 +1164,7 @@ class MMGenTX(MMGenObject):
self.blockcount = int(blockcount)
desc = 'transaction hex data'
self.check_tx_hex_data()
if md_only: return # the following ops will all fail if g.coin doesn't match self.coin
# the following ops will all fail if g.coin doesn't match self.coin
desc = 'coin type in metadata'
assert self.coin == g.coin,'invalid coin type'
desc = 'inputs data'

View file

@ -0,0 +1,5 @@
59b070
ETH FOUNDATION BC79AB 0.123 20180530_125230 7513928
{"nonce": "0", "chainId": "0x1", "from": "e704b6cfd9f0edb2e6cfbd0c913438d37ede7b35", "to": "62ff8e4dbd251b98102e3fb5e4b14119e24cadde", "amt": "0.123", "gasPrice": "0.000000050"}
[{'confs': 0, 'addr': 'e704b6cfd9f0edb2e6cfbd0c913438d37ede7b35', 'vout': 0, 'txid': '0000000000000000000000000000000000000000000000000000000000000000', 'label': u'', 'amt': '1.234567', 'mmid': '98831F3A:E:1'}]
[{'mmid': '98831F3A:E:31', 'amt': '0.123', 'addr': '62ff8e4dbd251b98102e3fb5e4b14119e24cadde'}]

View file

@ -166,6 +166,7 @@ tn_ext = ('','.testnet')[g.testnet]
coin_sel = g.coin.lower()
# if g.coin == 'B2X': coin_sel = 'btc'
if g.coin == 'ETH': coin_sel = 'btc' # TODO
fork = {'bch':'btc','btc':'btc','ltc':'ltc'}[coin_sel]
tx_fee = {'btc':'0.0001','bch':'0.001','ltc':'0.01'}[coin_sel]
@ -550,6 +551,7 @@ cfgs = {
'bch': '99BE60-BCH[106.6789]{}.rawtx',
'b2x': '6A52BC-B2X[106.6789,tl=1320969600]{}.rawtx',
'ltc': '75F455-LTC[106.6789]{}.rawtx',
'eth': 'BC79AB-ETH[0.123]{}.rawtx',
},
'ic_wallet': u'98831F3A-5482381C-18460FB1[256,1].mmincog',
'ic_wallet_hex': u'98831F3A-1630A9F2-870376A9[256,1].mmincox',
@ -2117,7 +2119,7 @@ class MMGenTestSuite(object):
# Miscellaneous tests
def autosign(self,name): # tests everything except device detection, mount/unmount
if skip_for_win(): return
fdata = (('btc',''),('bch',''),('ltc','litecoin'))
fdata = (('btc',''),('bch',''),('ltc','litecoin'),('eth','ethereum'))
tfns = [cfgs['8']['ref_tx_file'][c].format('') for c,d in fdata]
tfs = [os.path.join(ref_dir,d[1],fn) for d,fn in zip(fdata,tfns)]
try: os.mkdir(os.path.join(cfg['tmpdir'],'tx'))
@ -2127,7 +2129,7 @@ class MMGenTestSuite(object):
# make a bad tx file
with open(os.path.join(cfg['tmpdir'],'tx','bad.rawtx'),'w') as f:
f.write('bad tx data')
opts = ['--mountpoint='+cfg['tmpdir'],'--coins=btc,bch,ltc']
opts = ['--mountpoint='+cfg['tmpdir'],'--coins=btc,bch,ltc,eth']
mn_fn = os.path.join(ref_dir,cfgs['8']['seed_id']+'.mmwords')
mn = read_from_file(mn_fn).strip().split()
@ -2144,7 +2146,7 @@ class MMGenTestSuite(object):
t.ok()
t = MMGenExpect(name,'mmgen-autosign',opts+['wait'],extra_desc='(sign)')
t.expect('3 transactions signed')
t.expect('4 transactions signed')
t.expect('1 transaction failed to sign')
t.expect('Waiting.')
t.kill(2)