Ethereum autosigning
This commit is contained in:
parent
fe26ea935b
commit
2c97f61ea4
5 changed files with 26 additions and 10 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
13
mmgen/tx.py
13
mmgen/tx.py
|
|
@ -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'
|
||||
|
|
|
|||
5
test/ref/ethereum/BC79AB-ETH[0.123].rawtx
Normal file
5
test/ref/ethereum/BC79AB-ETH[0.123].rawtx
Normal 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'}]
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue