Display long addresses correctly

This commit is contained in:
The MMGen Project 2018-03-06 07:27:51 +00:00
commit 165f0483e8
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
6 changed files with 24 additions and 24 deletions

View file

@ -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

View file

@ -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 ({})"

View file

@ -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

View file

@ -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 '-'

View file

@ -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),

View file

@ -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 + [