diff --git a/mmgen/altcoin.py b/mmgen/altcoin.py index aed8e638..9181675c 100755 --- a/mmgen/altcoin.py +++ b/mmgen/altcoin.py @@ -756,7 +756,7 @@ def create_altcoin_protos(data): (mainnet,), { 'base_coin': e.symbol, - 'addr_ver_bytes': dict( + 'addr_ver_info': dict( [( num2hexstr(e.p2pkh_info[0]), 'p2pkh' )] + ([( num2hexstr(e.p2sh_info[0]), 'p2sh' )] if e.p2sh_info else []) ), diff --git a/mmgen/proto/bch.py b/mmgen/proto/bch.py index abd12641..5eff8bfa 100755 --- a/mmgen/proto/bch.py +++ b/mmgen/proto/bch.py @@ -30,7 +30,7 @@ class mainnet(mainnet): def pubhash2segwitaddr(self,pubkey): raise NotImplementedError class testnet(mainnet): - addr_ver_bytes = { '6f': 'p2pkh', 'c4': 'p2sh' } + addr_ver_info = { '6f': 'p2pkh', 'c4': 'p2sh' } wif_ver_num = { 'std': 'ef' } class regtest(testnet): diff --git a/mmgen/proto/btc.py b/mmgen/proto/btc.py index d80d1141..65e5782f 100755 --- a/mmgen/proto/btc.py +++ b/mmgen/proto/btc.py @@ -21,7 +21,7 @@ class mainnet(CoinProtocol.Secp256k1): # chainparams.cpp """ mod_clsname = 'Bitcoin' network_names = _nw('mainnet','testnet','regtest') - addr_ver_bytes = { '00': 'p2pkh', '05': 'p2sh' } + addr_ver_info = { '00': 'p2pkh', '05': 'p2sh' } addr_len = 20 wif_ver_num = { 'std': '80' } mmtypes = ('L','C','S','B') @@ -123,7 +123,7 @@ class mainnet(CoinProtocol.Secp256k1): # chainparams.cpp data = [self.witness_vernum] + bech32.convertbits(list(pubhash),8,5) ) class testnet(mainnet): - addr_ver_bytes = { '6f': 'p2pkh', 'c4': 'p2sh' } + addr_ver_info = { '6f': 'p2pkh', 'c4': 'p2sh' } wif_ver_num = { 'std': 'ef' } bech32_hrp = 'tb' diff --git a/mmgen/proto/ltc.py b/mmgen/proto/ltc.py index b6b23ce3..90f28a59 100755 --- a/mmgen/proto/ltc.py +++ b/mmgen/proto/ltc.py @@ -16,7 +16,7 @@ from .btc import mainnet class mainnet(mainnet): block0 = '12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2' - addr_ver_bytes = { '30': 'p2pkh', '05': 'p2sh', '32': 'p2sh' } # new p2sh ver 0x32 must come last + addr_ver_info = { '30': 'p2pkh', '05': 'p2sh', '32': 'p2sh' } # new p2sh ver 0x32 must come last wif_ver_num = { 'std': 'b0' } mmtypes = ('L','C','S','B') coin_amt = 'LTCAmt' @@ -30,7 +30,7 @@ class mainnet(mainnet): class testnet(mainnet): # addr ver nums same as Bitcoin testnet, except for 'p2sh' - addr_ver_bytes = { '6f':'p2pkh', 'c4':'p2sh', '3a':'p2sh' } + addr_ver_info = { '6f':'p2pkh', 'c4':'p2sh', '3a':'p2sh' } wif_ver_num = { 'std': 'ef' } # same as Bitcoin testnet bech32_hrp = 'tltc' diff --git a/mmgen/proto/xmr.py b/mmgen/proto/xmr.py index d6f90481..48e3c8a1 100755 --- a/mmgen/proto/xmr.py +++ b/mmgen/proto/xmr.py @@ -24,7 +24,7 @@ class mainnet(CoinProtocol.DummyWIF,CoinProtocol.Base): network_names = _nw('mainnet','stagenet',None) base_coin = 'XMR' base_proto = 'Monero' - addr_ver_bytes = { '12': 'monero', '2a': 'monero_sub', '13': 'monero_integrated' } + addr_ver_info = { '12': 'monero', '2a': 'monero_sub', '13': 'monero_integrated' } wif_ver_num = {} pubkey_types = ('monero',) mmtypes = ('M',) @@ -77,4 +77,4 @@ class mainnet(CoinProtocol.DummyWIF,CoinProtocol.Base): raise NotImplementedError('Monero addresses do not support pubhash2addr()') class testnet(mainnet): # use stagenet for testnet - addr_ver_bytes = { '18': 'monero', '24': 'monero_sub', '19': 'monero_integrated' } # testnet is {'35','3f','36'} + addr_ver_info = { '18': 'monero', '24': 'monero_sub', '19': 'monero_integrated' } # testnet is {'35','3f','36'} diff --git a/mmgen/proto/zec.py b/mmgen/proto/zec.py index de707ef8..11a5efd1 100755 --- a/mmgen/proto/zec.py +++ b/mmgen/proto/zec.py @@ -13,10 +13,11 @@ Zcash protocol """ from .btc import mainnet +from ..protocol import decoded_addr class mainnet(mainnet): base_coin = 'ZEC' - addr_ver_bytes = { '1cb8': 'p2pkh', '1cbd': 'p2sh', '169a': 'zcash_z', 'a8abd3': 'viewkey' } + addr_ver_info = { '1cb8': 'p2pkh', '1cbd': 'p2sh', '169a': 'zcash_z', 'a8abd3': 'viewkey' } wif_ver_num = { 'std': '80', 'zcash_z': 'ab36' } pubkey_types = ('std','zcash_z') mmtypes = ('L','C','Z') @@ -32,6 +33,18 @@ class mainnet(mainnet): def get_addr_len(self,addr_fmt): return (20,64)[addr_fmt in ('zcash_z','viewkey')] + def decode_addr_bytes(self,addr_bytes): + """ + vlen must be set dynamically since Zcash has variable length ver_bytes + """ + for ver_bytes,addr_fmt in self.addr_ver_bytes.items(): + vlen = len(ver_bytes) + if addr_bytes[:vlen] == ver_bytes: + if len(addr_bytes[vlen:]) == self.get_addr_len(addr_fmt): + return decoded_addr( addr_bytes[vlen:], ver_bytes, addr_fmt ) + + return False + def preprocess_key(self,sec,pubkey_type): if pubkey_type == 'zcash_z': # zero the first four bits return bytes([sec[0] & 0x0f]) + sec[1:] @@ -49,4 +62,4 @@ class mainnet(mainnet): class testnet(mainnet): wif_ver_num = { 'std': 'ef', 'zcash_z': 'ac08' } - addr_ver_bytes = { '1d25': 'p2pkh', '1cba': 'p2sh', '16b6': 'zcash_z', 'a8ac0c': 'viewkey' } + addr_ver_info = { '1d25': 'p2pkh', '1cba': 'p2sh', '16b6': 'zcash_z', 'a8ac0c': 'viewkey' } diff --git a/mmgen/protocol.py b/mmgen/protocol.py index 4f64ba8f..c0d2c595 100755 --- a/mmgen/protocol.py +++ b/mmgen/protocol.py @@ -68,8 +68,10 @@ class CoinProtocol(MMGenObject): 'regtest': '_rt', }[network] - if hasattr(self,'addr_ver_bytes'): - self.addr_fmt_to_ver_bytes = {v:bytes.fromhex(k) for k,v in self.addr_ver_bytes.items()} + if hasattr(self,'addr_ver_info'): + self.addr_ver_bytes = {bytes.fromhex(k):v for k,v in self.addr_ver_info.items()} + self.addr_fmt_to_ver_bytes = {v:k for k,v in self.addr_ver_bytes.items()} + self.addr_ver_bytes_len = len(list(self.addr_ver_bytes)[0]) if 'tx' not in self.mmcaps and g.is_txprog: from .util import die @@ -139,14 +141,11 @@ class CoinProtocol(MMGenObject): return self.addr_len def decode_addr_bytes(self,addr_bytes): - for ver_hex,addr_fmt in self.addr_ver_bytes.items(): - ver_bytes = bytes.fromhex(ver_hex) - vlen = len(ver_bytes) - if addr_bytes[:vlen] == ver_bytes: - if len(addr_bytes[vlen:]) == self.get_addr_len(addr_fmt): - return decoded_addr( addr_bytes[vlen:], ver_bytes, addr_fmt ) - - return False + vlen = self.addr_ver_bytes_len + return decoded_addr( + addr_bytes[vlen:], + addr_bytes[:vlen], + self.addr_ver_bytes[addr_bytes[:vlen]] ) def coin_addr(self,addr): from .addr import CoinAddr