diff --git a/mmgen/addr.py b/mmgen/addr.py index 07e52976..3ac66a7d 100755 --- a/mmgen/addr.py +++ b/mmgen/addr.py @@ -90,6 +90,8 @@ class AddrGeneratorEthereum(AddrGenerator): # github.com/FiloSottile/zcash-mini/zcash/address.go class AddrGeneratorZcashZ(AddrGenerator): + addr_width = 95 + def zhash256(self,s,t): s = map(ord,s+'\0'*32) s[0] |= 0xc0 @@ -106,7 +108,7 @@ class AddrGeneratorZcashZ(AddrGenerator): p2 = crypto_scalarmult_base(self.zhash256(key,1)) from mmgen.protocol import _b58chk_encode ret = _b58chk_encode(g.proto.addr_ver_num['zcash_z'][0] + hexlify(self.zhash256(key,0)+p2)) - assert len(ret) == g.proto.addr_width,'Invalid Zcash z-address length' + assert len(ret) == self.addr_width,'Invalid Zcash z-address length' return CoinAddr(ret) def to_viewkey(self,pubhex): # pubhex is really privhex @@ -118,7 +120,7 @@ class AddrGeneratorZcashZ(AddrGenerator): vk[63] |= 0x40 from mmgen.protocol import _b58chk_encode ret = _b58chk_encode(g.proto.addr_ver_num['viewkey'][0] + hexlify(''.join(map(chr,vk)))) - assert len(ret) == g.proto.addr_width,'Invalid Zcash view key length' + assert len(ret) == self.addr_width,'Invalid Zcash view key length' return ZcashViewKey(ret) def to_segwit_redeem_script(self,pubhex): @@ -194,7 +196,6 @@ class KeyGenerator(MMGenObject): msg('Using (slow) native Python ECDSA library for address generation') return super(cls,cls).__new__(KeyGeneratorPython) elif pubkey_type in ('zcash_z','monero'): - g.proto.addr_width = 95 me = super(cls,cls).__new__(KeyGeneratorDummy) me.desc = 'mmgen-'+pubkey_type return me diff --git a/mmgen/obj.py b/mmgen/obj.py index e5978c9d..84fada25 100755 --- a/mmgen/obj.py +++ b/mmgen/obj.py @@ -355,6 +355,8 @@ class LTCAmt(BTCAmt): max_amt = 84000000 class CoinAddr(str,Hilite,InitErrors,MMGenObject): color = 'cyan' hex_width = 40 + width = 1 + trunc_ok = False def __new__(cls,s,on_fail='die'): if type(s) == cls: return s cls.arg_chk(cls,on_fail) @@ -366,7 +368,6 @@ class CoinAddr(str,Hilite,InitErrors,MMGenObject): assert va,'failed verification' me.addr_fmt = va['format'] me.hex = va['hex'] - cls.width = va['width'] return me except Exception as e: m = "{!r}: value cannot be converted to {} address ({})" diff --git a/mmgen/protocol.py b/mmgen/protocol.py index 7107ec50..daa64ec6 100755 --- a/mmgen/protocol.py +++ b/mmgen/protocol.py @@ -87,12 +87,10 @@ class BitcoinProtocol(MMGenObject): caps = ('rbf','segwit') mmcaps = ('key','addr','rpc','tx') base_coin = 'BTC' - addr_width = 34 # From BIP173: witness version 'n' is stored as 'OP_n'. OP_0 is encoded as 0x00, # but OP_1 through OP_16 are encoded as 0x51 though 0x60 (81 to 96 in decimal). witness_vernum_hex = '00' witness_vernum = int(witness_vernum_hex,16) - bech32_addr_width = 40 bech32_hrp = 'bc' @staticmethod @@ -140,8 +138,7 @@ class BitcoinProtocol(MMGenObject): elif ret[1]: return { 'hex': ''.join([chr(b) for b in ret[1]]).encode('hex'), - 'format': 'bech32', - 'width': cls.bech32_addr_width, + 'format': 'bech32' } if return_dict else True return False @@ -161,8 +158,7 @@ class BitcoinProtocol(MMGenObject): return { 'hex': addr_hex[len(ver_num):-8], 'format': {'p2pkh':'p2pkh','p2sh':'p2sh','p2sh2':'p2sh', - 'zcash_z':'zcash_z','viewkey':'viewkey'}[addr_fmt], - 'width': cls.addr_width + 'zcash_z':'zcash_z','viewkey':'viewkey'}[addr_fmt] } if return_dict else True else: if g.debug: Msg('Invalid checksum in address') @@ -200,7 +196,6 @@ class BitcoinTestnetProtocol(BitcoinProtocol): data_subdir = 'testnet' daemon_data_subdir = 'testnet3' rpc_port = 18332 - addr_width = 35 bech32_hrp = 'tb' bech32_hrp_rt = 'bcrt' @@ -230,7 +225,6 @@ class BitcoinCashTestnetProtocol(BitcoinCashProtocol): wif_ver_num = { 'std': 'ef' } data_subdir = 'testnet' daemon_data_subdir = 'testnet3' - addr_width = 35 class B2XProtocol(BitcoinProtocol): daemon_name = 'bitcoind-2x' @@ -249,7 +243,6 @@ class B2XTestnetProtocol(B2XProtocol): data_subdir = 'testnet' daemon_data_subdir = 'testnet5' rpc_port = 18338 - addr_width = 35 class LitecoinProtocol(BitcoinProtocol): block0 = '12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2' @@ -273,7 +266,6 @@ class LitecoinTestnetProtocol(LitecoinProtocol): data_subdir = 'testnet' daemon_data_subdir = 'testnet4' rpc_port = 19332 - addr_width = 35 class BitcoinProtocolAddrgen(BitcoinProtocol): mmcaps = ('key','addr') class BitcoinTestnetProtocolAddrgen(BitcoinTestnetProtocol): mmcaps = ('key','addr') @@ -304,7 +296,7 @@ class EthereumProtocol(DummyWIF,BitcoinProtocolAddrgen): def verify_addr(cls,addr,hex_width,return_dict=False): from mmgen.util import is_hex_str_lc if is_hex_str_lc(addr) and len(addr) == cls.addr_width: - return { 'hex': addr, 'format': 'ethereum', 'width': cls.addr_width } if return_dict else True + return { 'hex': addr, 'format': 'ethereum' } if return_dict else True if g.debug: Msg("Invalid address '{}'".format(addr)) return False @@ -395,7 +387,7 @@ class MoneroProtocol(DummyWIF,BitcoinProtocolAddrgen): chk = sha3.keccak_256(ret.decode('hex')[:-4]).hexdigest()[:8] assert chk == ret[-8:],'Incorrect checksum' - return { 'hex': ret, 'format': 'monero', 'width': cls.addr_width } if return_dict else True + return { 'hex': ret, 'format': 'monero' } if return_dict else True class MoneroTestnetProtocol(MoneroProtocol): addr_ver_num = { 'monero': ('35','4'), 'monero_sub': ('3f','8') } # 53,63 diff --git a/mmgen/tool.py b/mmgen/tool.py index 2b7a054e..a6b3caac 100755 --- a/mmgen/tool.py +++ b/mmgen/tool.py @@ -725,12 +725,14 @@ def Listaddresses(addrs='',minconf=1, mmaddrs = [k for k in addrs.keys() if k.type == 'mmgen'] max_mmid_len = max(len(k) for k in mmaddrs) + 2 if mmaddrs else 10 max_cmt_len = max(max(len(v['lbl'].comment) for v in addrs.values()),7) + addr_width = max(len(addrs[mmid]['addr']) for mmid in addrs) + # pmsg([a.split('.')[1] for a in [str(v['amt']) for v in addrs.values()] if '.' in a]) # fp: fractional part max_fp_len = max([len(a.split('.')[1]) for a in [str(v['amt']) for v in addrs.values()] if '.' in a] or [1]) out += [fs.format( mid=MMGenID.fmtc('MMGenID',width=max_mmid_len), - addr=CoinAddr.fmtc('ADDRESS'), + addr=CoinAddr.fmtc('ADDRESS',width=addr_width), cmt=TwComment.fmtc('COMMENT',width=max_cmt_len+1), amt='BALANCE'.ljust(max_fp_len+4), age=('CONFS','DAYS')[show_days], @@ -761,7 +763,7 @@ def Listaddresses(addrs='',minconf=1, e = addrs[mmid] out.append(fs.format( mid=MMGenID.fmtc(mmid_disp,width=max_mmid_len,color=True), - addr=(e['addr'].fmt(color=True) if showbtcaddrs else None), + addr=(e['addr'].fmt(color=True,width=addr_width) if showbtcaddrs else None), cmt=e['lbl'].comment.fmt(width=max_cmt_len,color=True,nullrepl='-'), amt=e['amt'].fmt('4.{}'.format(max(max_fp_len,3)),color=True), age=mmid.confs / (1,confs_per_day)[show_days] if hasattr(mmid,'confs') else '-' diff --git a/mmgen/tw.py b/mmgen/tw.py index 81002211..a5d0a845 100755 --- a/mmgen/tw.py +++ b/mmgen/tw.py @@ -142,7 +142,7 @@ watch-only wallet using '{}-addrimport' and then re-run this program. col1_w = max(3,len(str(len(unsp)))+1) # num + ')' mmid_w = max(len(('',i.twmmid)[i.twmmid.type=='mmgen']) for i in unsp) or 12 # DEADBEEF:S:1 max_acct_w = max(len(i.label) for i in unsp) + mmid_w + 1 - addr_w = min(g.proto.addr_width+(0,1+max_acct_w)[self.show_mmid],self.cols-45) + addr_w = min(max(len(i.addr) for i in unsp)+(0,1+max_acct_w)[self.show_mmid],self.cols-45) acct_w = min(max_acct_w, max(24,int(addr_w-10))) btaddr_w = addr_w - acct_w - 1 label_w = acct_w - mmid_w - 1 @@ -195,10 +195,11 @@ watch-only wallet using '{}-addrimport' and then re-run this program. def format_for_printing(self,color=False): + addr_w = max(len(i.addr) for i in self.unspent) mmid_w = max(len(('',i.twmmid)[i.twmmid.type=='mmgen']) for i in self.unspent) or 12 # DEADBEEF:S:1 fs = ' {:4} {:67} {} {} {:12} {:<8} {:<6} {}' out = [fs.format('Num','Tx ID,Vout', - 'Address'.ljust(g.proto.addr_width), + 'Address'.ljust(addr_w), 'MMGen ID'.ljust(mmid_w+1), 'Amount({})'.format(g.coin), 'Confs','Age(d)', @@ -206,7 +207,7 @@ watch-only wallet using '{}-addrimport' and then re-run this program. max_lbl_len = max([len(i.label) for i in self.unspent if i.label] or [1]) for n,i in enumerate(self.unspent): - addr = '|'+'.' * g.proto.addr_width if i.skip == 'addr' and self.group else i.addr.fmt(color=color) + addr = '|'+'.' * addr_w if i.skip == 'addr' and self.group else i.addr.fmt(color=color,width=addr_w) tx = '|'+'.' * 63 if i.skip == 'txid' and self.group else str(i.txid) out.append( fs.format(str(n+1)+')', tx+','+str(i.vout), diff --git a/mmgen/tx.py b/mmgen/tx.py index 5125dbfe..6b5b56ad 100755 --- a/mmgen/tx.py +++ b/mmgen/tx.py @@ -919,8 +919,9 @@ class MMGenTX(MMGenObject): max_mmwid = max(get_max_mmwid(self.inputs),get_max_mmwid(self.outputs)) def format_io(io): - ip = io == self.inputs + ip = io is self.inputs io_out = '' + addr_w = max(len(e.addr) for e in io) confs_per_day = 60*60*24 / g.proto.secs_per_block for n,e in enumerate(sorted(io,key=lambda o: o.mmid.sort_key if o.mmid else o.addr)): if ip and blockcount != None: @@ -932,10 +933,12 @@ class MMGenTX(MMGenObject): else: mmid_fmt = MMGenID.fmtc(nonmm_str,width=max_mmwid) if terse: - io_out += '{:3} {} {} {} {}\n'.format(n+1,e.addr.fmt(color=True),mmid_fmt,e.amt.hl(),g.coin) + io_out += '{:3} {} {} {} {}\n'.format(n+1, + e.addr.fmt(color=True,width=addr_w), + mmid_fmt,e.amt.hl(),g.coin) else: icommon = [ - ((n+1,'')[ip],'address:',e.addr.fmt(color=True) + ' '+mmid_fmt), + ((n+1,'')[ip],'address:',e.addr.fmt(color=True,width=addr_w) + ' '+mmid_fmt), ('','comment:',e.label.hl() if e.label else ''), ('','amount:','{} {}'.format(e.amt.hl(),g.coin))] items = [(n+1, 'tx,vout:','{},{}'.format(e.txid,e.vout))] + icommon + [