Browse Source

Display long addresses correctly

MMGen 7 years ago
parent
commit
165f0483e8
6 changed files with 24 additions and 24 deletions
  1. 4 3
      mmgen/addr.py
  2. 2 1
      mmgen/obj.py
  3. 4 12
      mmgen/protocol.py
  4. 4 2
      mmgen/tool.py
  5. 4 3
      mmgen/tw.py
  6. 6 3
      mmgen/tx.py

+ 4 - 3
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

+ 2 - 1
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 ({})"

+ 4 - 12
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

+ 4 - 2
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 '-'

+ 4 - 3
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),

+ 6 - 3
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 + [