BCH cashaddr: full support
- BCH addresses are now displayed in cashaddr format by default. This may be
overridden on the command line with --cashaddr=0, or in the config file by
setting `bch_cashaddr` to false
- In tracking wallet views, the ‘h’ key toggles between legacy and cashaddr
address display
- Transaction views display BCH addresses in both formats simultaneously
- The --usecashaddr=0 daemon option is no longer required and should be omitted
Testing:
$ test/unit_tests.py -v cashaddr bip_hd.multicoin
$ test/gentest.py --coin=bch -v --type=C 1 test/ref/bitcoin_cash/bchwallet.dump
$ test/cmdtest.py -e bch_txview_cashaddr1 bch_txview_cashaddr2
$ test/cmdtest.py --coin=bch -e txsend regtest.view autosign_automount
$ test/cmdtest.py --coin=bch -n ref3_addr
This commit is contained in:
parent
15b94038a4
commit
8edc7da5a2
29 changed files with 397 additions and 25 deletions
|
|
@ -157,9 +157,14 @@ class CoinAddr(HiliteStr, InitErrors, MMGenObject):
|
|||
try:
|
||||
ap = proto.decode_addr(addr)
|
||||
assert ap, f'coin address {addr!r} could not be parsed'
|
||||
me = str.__new__(cls, addr)
|
||||
me.views = [addr]
|
||||
me.view_pref = 0
|
||||
if hasattr(ap, 'addr'):
|
||||
me = str.__new__(cls, ap.addr)
|
||||
me.views = ap.views
|
||||
me.view_pref = ap.view_pref
|
||||
else:
|
||||
me = str.__new__(cls, addr)
|
||||
me.views = [addr]
|
||||
me.view_pref = 0
|
||||
me.addr_fmt = ap.fmt
|
||||
me.bytes = ap.bytes
|
||||
me.ver_bytes = ap.ver_bytes
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ class AddrFile(MMGenObject):
|
|||
coin = proto.coin
|
||||
mmtype = self.parent.al_id.mmtype
|
||||
lbl_p2 = ':'.join(
|
||||
([] if coin in ('BTC', 'BCH') else [coin])
|
||||
([] if coin == 'BTC' or (coin == 'BCH' and not self.cfg.cashaddr) else [coin])
|
||||
+ ([] if mmtype == 'E' or (mmtype == 'L' and not proto.testnet) else [mmtype.name.upper()])
|
||||
+ ([proto.network.upper()] if proto.testnet else [])
|
||||
)
|
||||
|
|
@ -206,6 +206,8 @@ class AddrFile(MMGenObject):
|
|||
"""
|
||||
label examples:
|
||||
- Bitcoin legacy mainnet: no label
|
||||
- BCH legacy mainnet (no cashaddr): no label
|
||||
- BCH legacy mainnet (cashaddr): 'BCH'
|
||||
- Bitcoin legacy testnet: 'LEGACY:TESTNET'
|
||||
- Bitcoin Segwit: 'SEGWIT'
|
||||
- Bitcoin Segwit testnet: 'SEGWIT:TESTNET'
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ class AddrListIDStr(HiliteStr):
|
|||
ret = fmt_str.format(s)
|
||||
else:
|
||||
proto = addrlist.proto
|
||||
coin = 'BTC' if proto.coin == 'BCH' else proto.coin
|
||||
coin = 'BTC' if proto.coin == 'BCH' and not addrlist.cfg.cashaddr else proto.coin
|
||||
mmtype = addrlist.al_id.mmtype
|
||||
ret = '{}{}{}[{}]'.format(
|
||||
addrlist.al_id.sid,
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ def check_privkey(key_int):
|
|||
|
||||
class BipHDConfig(Lockable):
|
||||
|
||||
supported_coins = ('btc', 'eth', 'doge', 'ltc')
|
||||
supported_coins = ('btc', 'eth', 'doge', 'ltc', 'bch')
|
||||
|
||||
def __init__(self, base_cfg, coin, network, addr_type, from_path, no_path_checks):
|
||||
|
||||
|
|
|
|||
|
|
@ -195,6 +195,9 @@ class Config(Lockable):
|
|||
carol = False
|
||||
regtest_user = ''
|
||||
|
||||
# altcoin:
|
||||
cashaddr = True
|
||||
|
||||
# Monero:
|
||||
monero_wallet_rpc_user = 'monero'
|
||||
monero_wallet_rpc_password = ''
|
||||
|
|
@ -273,6 +276,7 @@ class Config(Lockable):
|
|||
'subseeds',
|
||||
'testnet',
|
||||
'usr_randchars',
|
||||
'bch_cashaddr',
|
||||
'bch_max_tx_fee',
|
||||
'btc_max_tx_fee',
|
||||
'eth_max_tx_fee',
|
||||
|
|
|
|||
|
|
@ -115,6 +115,9 @@
|
|||
## Altcoin options ##
|
||||
#####################
|
||||
|
||||
# Set this to false to prefer legacy BCH address format:
|
||||
# bch_cashaddr true
|
||||
|
||||
# Set the maximum transaction fee for BCH:
|
||||
# bch_max_tx_fee 0.1
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
15.0.0
|
||||
15.1.dev1
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ long_opts_data = {
|
|||
--, --accept-defaults Accept defaults at all prompts
|
||||
--, --coin=c Choose coin unit. Default: BTC. Current choice: {cu_dfl}
|
||||
--, --token=t Specify an ERC20 token by address or symbol
|
||||
--, --cashaddr=0|1 Display BCH addresses in cashaddr format (default: 1)
|
||||
--, --color=0|1 Disable or enable color output (default: 1)
|
||||
--, --columns=N Force N columns of output with certain commands
|
||||
--, --scroll Use the curses-like scrolling interface for
|
||||
|
|
|
|||
|
|
@ -12,7 +12,11 @@
|
|||
proto.bch.params: Bitcoin Cash protocol
|
||||
"""
|
||||
|
||||
from ...protocol import decoded_addr_multiview
|
||||
from ...addr import CoinAddr
|
||||
from ..btc.params import mainnet, _finfo
|
||||
from ..btc.common import b58chk_decode, b58chk_encode
|
||||
from .cashaddr import cashaddr_decode_addr, cashaddr_encode_addr, cashaddr_addr_types
|
||||
|
||||
class mainnet(mainnet):
|
||||
is_fork_of = 'Bitcoin'
|
||||
|
|
@ -25,6 +29,50 @@ class mainnet(mainnet):
|
|||
coin_amt = 'BCHAmt'
|
||||
max_tx_fee = '0.1'
|
||||
ignore_daemon_version = False
|
||||
cashaddr_pfx = 'bitcoincash'
|
||||
cashaddr = True
|
||||
|
||||
def decode_addr(self, addr):
|
||||
if len(addr) >= 42: # cashaddr
|
||||
if addr.islower():
|
||||
pass
|
||||
elif addr.isupper():
|
||||
addr = addr.lower()
|
||||
else:
|
||||
raise ValueError(f'{addr}: address has mixed case!')
|
||||
if ':' in addr:
|
||||
assert addr.startswith(self.cashaddr_pfx), f'{addr}: address has invalid prefix!'
|
||||
else:
|
||||
addr = f'{self.cashaddr_pfx}:{addr}'
|
||||
dec = cashaddr_decode_addr(addr)
|
||||
ver_bytes = self.addr_fmt_to_ver_bytes[dec.addr_type]
|
||||
return decoded_addr_multiview(
|
||||
dec.bytes,
|
||||
ver_bytes,
|
||||
dec.addr_type,
|
||||
addr,
|
||||
[dec.payload, b58chk_encode(ver_bytes+dec.bytes)] if len(dec.bytes) == self.addr_len else
|
||||
[dec.payload],
|
||||
0)
|
||||
else:
|
||||
dec = self.decode_addr_bytes(b58chk_decode(addr))
|
||||
enc = cashaddr_encode_addr(
|
||||
cashaddr_addr_types[dec.fmt],
|
||||
len(dec.bytes),
|
||||
self.cashaddr_pfx,
|
||||
dec.bytes)
|
||||
return decoded_addr_multiview(*dec, enc.addr, [enc.payload, addr], 1)
|
||||
|
||||
def pubhash2addr(self, pubhash, addr_type):
|
||||
return CoinAddr(
|
||||
self,
|
||||
cashaddr_encode_addr(
|
||||
cashaddr_addr_types[addr_type],
|
||||
len(pubhash),
|
||||
self.cashaddr_pfx,
|
||||
pubhash).addr
|
||||
if self.cfg.cashaddr else
|
||||
b58chk_encode(self.addr_fmt_to_ver_bytes[addr_type] + pubhash))
|
||||
|
||||
def pubhash2redeem_script(self,pubhash):
|
||||
raise NotImplementedError
|
||||
|
|
@ -35,6 +83,8 @@ class mainnet(mainnet):
|
|||
class testnet(mainnet):
|
||||
addr_ver_info = { '6f': 'p2pkh', 'c4': 'p2sh' }
|
||||
wif_ver_num = { 'std': 'ef' }
|
||||
cashaddr_pfx = 'bchtest'
|
||||
|
||||
class regtest(testnet):
|
||||
halving_interval = 150
|
||||
cashaddr_pfx = 'bchreg'
|
||||
|
|
|
|||
|
|
@ -79,7 +79,6 @@ class bitcoin_core_daemon(CoinDaemon):
|
|||
['--pid='+self.pidfile, self.use_pidfile],
|
||||
['--daemon', self.platform in ('linux', 'darwin') and not self.opt.no_daemonize],
|
||||
['--fallbackfee=0.0002', self.coin == 'BTC' and self.network == 'regtest'],
|
||||
['--usecashaddr=0', self.coin == 'BCH'],
|
||||
['--deprecatedrpc=create_bdb', self.coin == 'BTC' and self.opt.bdb_wallet],
|
||||
['--mempoolreplacement=1', self.coin == 'LTC'],
|
||||
['--txindex=1', self.coin == 'LTC' or self.network == 'regtest'],
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ class BitcoinTwAddresses(TwAddresses,BitcoinTwRPC):
|
|||
'Filters: show [E]mpty addrs, [u]sed addrs, all [L]abels',
|
||||
'View/Print: pager [v]iew, [w]ide pager view, [p]rint{s}',
|
||||
'Actions: [q]uit menu, r[e]draw, add [l]abel:']
|
||||
prompt_fs_repl = {
|
||||
'BCH': (1, 'Column options: toggle [D]ays/date/confs/block, cas[h]addr')
|
||||
}
|
||||
key_mappings = {
|
||||
'a':'s_amt',
|
||||
'A':'s_age',
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ class BitcoinTwAddressesPrune(BitcoinTwAddresses,TwAddressesPrune):
|
|||
'Filters: show [E]mpty addrs, [U]sed addrs, all [L]abels',
|
||||
'View/Actions: pager [v]iew, [w]ide view, r[e]draw{s}',
|
||||
'Pruning: [q]uit pruning, [p]rune, [u]nprune, [c]lear prune list:']
|
||||
prompt_fs_repl = {
|
||||
'BCH': (1, 'Column options: toggle [D]ays/date/confs/block, cas[h]addr')
|
||||
}
|
||||
key_mappings = {
|
||||
'a':'s_amt',
|
||||
'A':'s_age',
|
||||
|
|
|
|||
|
|
@ -240,6 +240,9 @@ class BitcoinTwTxHistory(TwTxHistory,BitcoinTwRPC):
|
|||
'Column options: toggle [D]ays/date/confs/block, tx[i]d, [T]otal amt',
|
||||
'View/Print: pager [v]iew, full pager [V]iew, [p]rint, full [P]rint{s}',
|
||||
'Filters/Actions: show [u]nconfirmed, [q]uit menu, r[e]draw:']
|
||||
prompt_fs_repl = {
|
||||
'BCH': (1, 'Column options: toggle [D]ate/confs, cas[h]addr, tx[i]d, [T]otal amt')
|
||||
}
|
||||
key_mappings = {
|
||||
'A':'s_age',
|
||||
'n':'s_blockheight',
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ class BitcoinTwUnspentOutputs(TwUnspentOutputs):
|
|||
'Column options: toggle [D]ays/date/confs/block, gr[o]up, show [m]mgen addr',
|
||||
'View options: pager [v]iew, [w]ide pager view{s}',
|
||||
'Actions: [q]uit menu, [p]rint, r[e]draw, add [l]abel:']
|
||||
prompt_fs_repl = {
|
||||
'BCH': (1, 'Column options: toggle [D]ate/confs, cas[h]addr, gr[o]up, show [m]mgen addr')
|
||||
}
|
||||
key_mappings = {
|
||||
't':'s_txid',
|
||||
'a':'s_amt',
|
||||
|
|
|
|||
|
|
@ -89,6 +89,8 @@ class TxInfo(TxInfo):
|
|||
get_mmid_fmt(e, is_input),
|
||||
e.amt.fmt(iwidth=iwidth,color=True),
|
||||
tx.dcoin )
|
||||
if have_bch:
|
||||
yield '{:3} [{}]\n'.format('', e.addr.hl(vp2, color=False))
|
||||
else:
|
||||
col1_w = len(str(len(io))) + 1
|
||||
for n,e in enumerate(io_sorted()):
|
||||
|
|
@ -100,8 +102,12 @@ class TxInfo(TxInfo):
|
|||
if is_input:
|
||||
yield (n+1, 'tx,vout:', f'{e.txid.hl()},{red(str(e.vout))}')
|
||||
yield ('', 'address:', f'{e.addr.hl(vp1)} {mmid_fmt}')
|
||||
if have_bch:
|
||||
yield ('', '', f'[{e.addr.hl(vp2, color=False)}]')
|
||||
else:
|
||||
yield (n+1, 'address:', f'{e.addr.hl(vp1)} {mmid_fmt}')
|
||||
if have_bch:
|
||||
yield ('', '', f'[{e.addr.hl(vp2, color=False)}]')
|
||||
if e.comment:
|
||||
yield ('', 'comment:', e.comment.hl())
|
||||
yield ('', 'amount:', f'{e.amt.hl()} {tx.dcoin}')
|
||||
|
|
@ -112,7 +118,14 @@ class TxInfo(TxInfo):
|
|||
yield '\n'.join('{:>{w}} {:<8} {}'.format(*d,w=col1_w) for d in gen()) + '\n\n'
|
||||
|
||||
tx = self.tx
|
||||
vp1 = 0
|
||||
|
||||
if self.cfg._proto.coin == 'BCH':
|
||||
have_bch = True
|
||||
vp1 = 1 if not self.cfg.cashaddr else not self.cfg._proto.cashaddr
|
||||
vp2 = (vp1 + 1) % 2
|
||||
else:
|
||||
have_bch = False
|
||||
vp1 = 0
|
||||
|
||||
return (
|
||||
'Displaying inputs and outputs in {} sort order'.format({'raw':'raw','addr':'address'}[sort])
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ from .objmethods import MMGenObject
|
|||
|
||||
decoded_wif = namedtuple('decoded_wif',['sec','pubkey_type','compressed'])
|
||||
decoded_addr = namedtuple('decoded_addr', ['bytes', 'ver_bytes', 'fmt'])
|
||||
decoded_addr_multiview = namedtuple('mv_decoded_addr', ['bytes', 'ver_bytes', 'fmt', 'addr', 'views', 'view_pref'])
|
||||
parsed_addr = namedtuple('parsed_addr',['ver_bytes','data'])
|
||||
|
||||
_finfo = namedtuple('fork_info',['height','hash','name','replayable'])
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ class TwView(MMGenObject,metaclass=AsyncInit):
|
|||
sort_key = 'age'
|
||||
display_hdr = ()
|
||||
display_body = ()
|
||||
prompt_fs_repl = {}
|
||||
nodata_msg = '[no data for requested parameters]'
|
||||
cols = 0
|
||||
term_height = 0
|
||||
|
|
@ -122,6 +123,8 @@ class TwView(MMGenObject,metaclass=AsyncInit):
|
|||
age_fmts_date_dependent = ('days','date','date_time')
|
||||
_age_fmt = 'confs'
|
||||
|
||||
bch_addr_fmts = ('cashaddr', 'legacy')
|
||||
|
||||
age_col_params = {
|
||||
'confs': (7, 'Confs'),
|
||||
'block': (8, 'Block'),
|
||||
|
|
@ -195,7 +198,12 @@ class TwView(MMGenObject,metaclass=AsyncInit):
|
|||
from .ctl import TwCtl
|
||||
self.twctl = await TwCtl(cfg,proto,mode='w')
|
||||
self.amt_keys = {'amt':'iwidth','amt2':'iwidth2'} if self.has_amt2 else {'amt':'iwidth'}
|
||||
if repl := self.prompt_fs_repl.get(self.proto.coin):
|
||||
self.prompt_fs_in[repl[0]] = repl[1]
|
||||
self.prompt_fs = '\n'.join(self.prompt_fs_in)
|
||||
if self.proto.coin == 'BCH':
|
||||
self.key_mappings.update({'h': 'd_addr_view_pref'})
|
||||
self.addr_view_pref = 1 if not self.cfg.cashaddr else not self.proto.cashaddr
|
||||
|
||||
@property
|
||||
def age_w(self):
|
||||
|
|
|
|||
|
|
@ -54,8 +54,7 @@ class CmdTestBase:
|
|||
self.usr_rand_arg = f'-r{self.usr_rand_chars}'
|
||||
self.tn_ext = ('','.testnet')[self.proto.testnet]
|
||||
self.coin = self.proto.coin.lower()
|
||||
self.bch_legacy = self.coin == 'bch'
|
||||
self.fork = 'btc' if self.bch_legacy else self.coin
|
||||
self.fork = 'btc' if self.coin == 'bch' and not cfg.cashaddr else self.coin
|
||||
self.altcoin_pfx = '' if self.fork == 'btc' else f'-{self.proto.coin}'
|
||||
if len(self.tmpdir_nums) == 1:
|
||||
self.tmpdir_num = self.tmpdir_nums[0]
|
||||
|
|
@ -115,3 +114,6 @@ class CmdTestBase:
|
|||
|
||||
def noop(self):
|
||||
return 'ok'
|
||||
|
||||
def _cashaddr_opt(self, val):
|
||||
return [f'--cashaddr={val}'] if self.proto.coin == 'BCH' else []
|
||||
|
|
|
|||
|
|
@ -63,6 +63,10 @@ class CmdTestMisc(CmdTestBase):
|
|||
passthru_opts = ('daemon_data_dir','rpc_port')
|
||||
cmd_group = (
|
||||
('rpc_backends', 'RPC backends'),
|
||||
('bch_txview_legacy1', "'mmgen-tool --coin=bch --cashaddr=0 txview terse=0'"),
|
||||
('bch_txview_legacy2', "'mmgen-tool --coin=bch --cashaddr=0 txview terse=1'"),
|
||||
('bch_txview_cashaddr1', "'mmgen-tool --coin=bch --cashaddr=1 txview terse=0'"),
|
||||
('bch_txview_cashaddr2', "'mmgen-tool --coin=bch --cashaddr=1 txview terse=1'"),
|
||||
('xmrwallet_txview', "'mmgen-xmrwallet' txview"),
|
||||
('xmrwallet_txlist', "'mmgen-xmrwallet' txlist"),
|
||||
('coin_daemon_info', "'examples/coin-daemon-info.py'"),
|
||||
|
|
@ -79,6 +83,27 @@ class CmdTestMisc(CmdTestBase):
|
|||
t = self.spawn_chk('mmgen-tool',[f'--rpc-backend={b}','daemon_version'],extra_desc=f'({b})')
|
||||
return t
|
||||
|
||||
def _bch_txview(self, view_pref, terse, expect):
|
||||
if cfg.no_altcoin:
|
||||
return 'skip'
|
||||
tx = 'test/ref/bitcoin_cash/895108-BCH[2.65913].rawtx'
|
||||
t = self.spawn('mmgen-tool', ['--coin=bch', f'--cashaddr={view_pref}', 'txview', tx, f'terse={terse}'])
|
||||
#t = self.spawn('mmgen-tool', ['--coin=bch', '--longhelp'])
|
||||
t.expect(expect)
|
||||
return t
|
||||
|
||||
def bch_txview_legacy1(self):
|
||||
return self._bch_txview(0, 0, '[qzuffa536e0eqfwz3smapckhlw9wge4p5spvx5j7h7]')
|
||||
|
||||
def bch_txview_legacy2(self):
|
||||
return self._bch_txview(0, 1, '[qzuffa536e0eqfwz3smapckhlw9wge4p5spvx5j7h7]')
|
||||
|
||||
def bch_txview_cashaddr1(self):
|
||||
return self._bch_txview(1, 0, '[1HpynST7vkLn8yNtdrqPfeghexZk4sdB3W]')
|
||||
|
||||
def bch_txview_cashaddr2(self):
|
||||
return self._bch_txview(1, 1, '[1HpynST7vkLn8yNtdrqPfeghexZk4sdB3W]')
|
||||
|
||||
def xmrwallet_txview(self,op='txview'):
|
||||
if cfg.no_altcoin:
|
||||
return 'skip'
|
||||
|
|
|
|||
|
|
@ -214,8 +214,8 @@ class CmdTestRef3Seed(CmdTestBase,CmdTestShared):
|
|||
|
||||
class CmdTestRef3Addr(CmdTestRef3Seed):
|
||||
'generated reference address, key and password files for 128-, 192- and 256-bit seeds'
|
||||
networks = ('btc', 'btc_tn', 'ltc', 'ltc_tn')
|
||||
passthru_opts = ('coin', 'testnet')
|
||||
networks = ('btc', 'btc_tn', 'ltc', 'ltc_tn', 'bch', 'bch_tn')
|
||||
passthru_opts = ('coin', 'testnet', 'cashaddr')
|
||||
tmpdir_nums = [26, 27, 28]
|
||||
shared_deps = ['mmdat', pwfile]
|
||||
|
||||
|
|
@ -224,6 +224,7 @@ class CmdTestRef3Addr(CmdTestRef3Seed):
|
|||
'sids': ('FE3C6545', '1378FC64', '98831F3A'),
|
||||
'refaddrgen_legacy_1': {
|
||||
'btc': ('B230 7526 638F 38CB','A9DC 5A13 12CB 1317'),
|
||||
'bch': ('026D AFE0 8C60 6CFF','B406 4937 D884 6E48'),
|
||||
'ltc': ('2B23 5E97 848A B961','AEC3 E774 0B21 0202'),
|
||||
},
|
||||
'refaddrgen_segwit_1': {
|
||||
|
|
@ -236,14 +237,17 @@ class CmdTestRef3Addr(CmdTestRef3Seed):
|
|||
},
|
||||
'refaddrgen_compressed_1': {
|
||||
'btc': ('95EB 8CC0 7B3B 7856','16E6 6170 154D 2202'),
|
||||
'bch': ('C560 A343 CEAB 118E','3F56 8DC5 0383 CD78'),
|
||||
'ltc': ('35D5 8ECA 9A42 46C3','15B3 5492 D3D3 6854'),
|
||||
},
|
||||
'refkeyaddrgen_legacy_1': {
|
||||
'btc': ('CF83 32FB 8A8B 08E2','1F67 B73A FF8C 5D15'),
|
||||
'bch': ('6909 4C64 119A 7681','7E48 5071 5E41 D1AE'),
|
||||
'ltc': ('1896 A26C 7F14 2D01','FA0E CD4E ADAF DBF4'),
|
||||
},
|
||||
'refkeyaddrgen_compressed_1': {
|
||||
'btc': ('E43A FA46 5751 720A','FDEE 8E45 1C0A 02AD'),
|
||||
'bch': ('7068 9B37 8ABF 3E31','C688 29A5 BA4C 21B2'),
|
||||
'ltc': ('7603 2FE3 2145 FFAD','3FE0 5A8E 5FBE FF3E'),
|
||||
},
|
||||
'refkeyaddrgen_segwit_1': {
|
||||
|
|
@ -265,10 +269,12 @@ class CmdTestRef3Addr(CmdTestRef3Seed):
|
|||
'ref_hex2bip39_24_passwdgen_1': '91AF E735 A31D 72A0',
|
||||
'refaddrgen_legacy_2': {
|
||||
'btc': ('8C17 A5FA 0470 6E89','764C 66F9 7502 AAEA'),
|
||||
'bch': ('8117 24B6 3FDA 6B40','E58C A8A4 C371 66AE'),
|
||||
'ltc': ('2B77 A009 D5D0 22AD','51D1 979D 0A35 F24B'),
|
||||
},
|
||||
'refaddrgen_compressed_2': {
|
||||
'btc': ('2615 8401 2E98 7ECA','A386 EE07 A356 906D'),
|
||||
'bch': ('3364 0F9D 8355 2A53','3451 F741 0A8A FA56'),
|
||||
'ltc': ('197C C48C 3C37 AB0F','8DDC 5FE3 BFF9 1226'),
|
||||
},
|
||||
'refaddrgen_segwit_2': {
|
||||
|
|
@ -281,10 +287,12 @@ class CmdTestRef3Addr(CmdTestRef3Seed):
|
|||
},
|
||||
'refkeyaddrgen_legacy_2': {
|
||||
'btc': ('9648 5132 B98E 3AD9','1BD3 5A36 D51C 256D'),
|
||||
'bch': ('C4D8 7C36 DC77 F8C2','953D 245C 8CFF AC72'),
|
||||
'ltc': ('DBD4 FAB6 7E46 CD07','8822 3FDF FEC0 6A8C'),
|
||||
},
|
||||
'refkeyaddrgen_compressed_2': {
|
||||
'btc': ('6D6D 3D35 04FD B9C3','94BF 4BCF 10B2 394B'),
|
||||
'bch': ('3E7F C369 2AB9 BD58','0C99 14CD 5ADE 6782'),
|
||||
'ltc': ('F5DA 9D60 6798 C4E9','7918 88DE 9096 DD7A'),
|
||||
},
|
||||
'refkeyaddrgen_segwit_2': {
|
||||
|
|
@ -306,10 +314,12 @@ class CmdTestRef3Addr(CmdTestRef3Seed):
|
|||
'ref_hex2bip39_24_passwdgen_2': '0E8E 23C9 923F 7C2D',
|
||||
'refaddrgen_legacy_3': {
|
||||
'btc': ('6FEF 6FB9 7B13 5D91','424E 4326 CFFE 5F51'),
|
||||
'bch': ('E580 43BB 0F96 AA93','630E 174A 8DDE 1BCE'),
|
||||
'ltc': ('AD52 C3FE 8924 AAF0','4EBE 2E85 E969 1B30'),
|
||||
},
|
||||
'refaddrgen_compressed_3': {
|
||||
'btc': ('A33C 4FDE F515 F5BC','6C48 AA57 2056 C8C8'),
|
||||
'bch': ('E37B AF41 7997 A28C','0D5D 9A58 D6E9 92EE'),
|
||||
'ltc': ('3FC0 8F03 C2D6 BD19','4C0A 49B6 2DD1 1BE0'),
|
||||
},
|
||||
'refaddrgen_segwit_3': {
|
||||
|
|
@ -322,10 +332,12 @@ class CmdTestRef3Addr(CmdTestRef3Seed):
|
|||
},
|
||||
'refkeyaddrgen_legacy_3': {
|
||||
'btc': ('9F2D D781 1812 8BAD','88CC 5120 9A91 22C2'),
|
||||
'bch': ('A0EE B039 48F4 24AE','B014 E0AB 5F87 EC64'),
|
||||
'ltc': ('B804 978A 8796 3ED4','98B5 AC35 F334 0398'),
|
||||
},
|
||||
'refkeyaddrgen_compressed_3': {
|
||||
'btc': ('420A 8EB5 A9E2 7814','F43A CB4A 81F3 F735'),
|
||||
'bch': ('33E7 5C06 88CF 2792','6E09 FF73 B7C8 00D4'),
|
||||
'ltc': ('8D1C 781F EB7F 44BC','05F3 5C68 FD31 FCEF'),
|
||||
},
|
||||
'refkeyaddrgen_segwit_3': {
|
||||
|
|
@ -379,8 +391,12 @@ class CmdTestRef3Addr(CmdTestRef3Seed):
|
|||
def refaddrgen_compressed(self):
|
||||
return self.call_addrgen('compressed')
|
||||
def refaddrgen_segwit(self):
|
||||
if cfg.coin == 'BCH':
|
||||
return 'skip'
|
||||
return self.call_addrgen('segwit')
|
||||
def refaddrgen_bech32(self):
|
||||
if cfg.coin == 'BCH':
|
||||
return 'skip'
|
||||
return self.call_addrgen('bech32')
|
||||
|
||||
def refkeyaddrgen_legacy(self):
|
||||
|
|
@ -388,8 +404,12 @@ class CmdTestRef3Addr(CmdTestRef3Seed):
|
|||
def refkeyaddrgen_compressed(self):
|
||||
return self.call_addrgen('compressed', 'keyaddrgen')
|
||||
def refkeyaddrgen_segwit(self):
|
||||
if cfg.coin == 'BCH':
|
||||
return 'skip'
|
||||
return self.call_addrgen('segwit', 'keyaddrgen')
|
||||
def refkeyaddrgen_bech32(self):
|
||||
if cfg.coin == 'BCH':
|
||||
return 'skip'
|
||||
return self.call_addrgen('bech32', 'keyaddrgen')
|
||||
|
||||
def pwgen(self, ftype, id_str, pwfmt=None, pwlen=None, extra_opts=[], stdout=False):
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ import os, json, time, re
|
|||
from decimal import Decimal
|
||||
|
||||
from mmgen.proto.btc.regtest import MMGenRegtest
|
||||
from mmgen.proto.bch.cashaddr import b32a
|
||||
from mmgen.proto.btc.common import b58a
|
||||
from mmgen.color import yellow
|
||||
from mmgen.util import msg_r,die,gmsg,capfirst,fmt_list
|
||||
from mmgen.protocol import init_proto
|
||||
|
|
@ -394,6 +396,7 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
|
|||
'view': (
|
||||
'viewing addresses and unspent outputs',
|
||||
('alice_listaddresses_scroll', 'listaddresses (--scroll, interactive=1)'),
|
||||
('alice_listaddresses_cashaddr', 'listaddresses (BCH cashaddr)'),
|
||||
('alice_listaddresses_empty', 'listaddresses (no data)'),
|
||||
('alice_listaddresses_menu', 'listaddresses (menu items)'),
|
||||
('alice_listaddresses1', 'listaddresses'),
|
||||
|
|
@ -404,6 +407,7 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
|
|||
('alice_twview_days', 'twview (age_fmt=days)'),
|
||||
('alice_twview_date', 'twview (age_fmt=date)'),
|
||||
('alice_twview_date_time', 'twview (age_fmt=date_time)'),
|
||||
('alice_twview_interactive_cashaddr', 'twview (interactive=1, BCH cashaddr)'),
|
||||
('alice_txcreate_info', 'txcreate -i'),
|
||||
('alice_txcreate_info_term', 'txcreate -i (pexpect_spawn)'),
|
||||
('bob_send_to_alice_2addr', 'sending a TX to 2 addresses in Alice’s wallet'),
|
||||
|
|
@ -763,10 +767,10 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
|
|||
return self.user_bal('alice',rtBals[8])
|
||||
|
||||
def bob_bal1(self):
|
||||
return self.user_bal('bob',rtFundAmt)
|
||||
return self.user_bal('bob', rtFundAmt, self._cashaddr_opt(0))
|
||||
|
||||
def bob_bal2(self):
|
||||
return self.user_bal('bob',rtBals[0])
|
||||
return self.user_bal('bob', rtBals[0], self._cashaddr_opt(1))
|
||||
|
||||
def bob_bal2a(self):
|
||||
return self.user_bal('bob',rtBals[0],args=['showempty=1','age_fmt=confs'])
|
||||
|
|
@ -827,11 +831,21 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
|
|||
|
||||
def bob_twview2(self):
|
||||
sid1 = self._get_user_subsid('bob','29L')
|
||||
return self.user_twview('bob',chk=(sid1+':C:2','0.29'),sort='twmmid')
|
||||
return self.user_twview(
|
||||
'bob',
|
||||
opts = self._cashaddr_opt(0),
|
||||
chk = (f'{sid1}:C:2', '0.29'),
|
||||
sort = 'twmmid',
|
||||
expect = rf'[{b58a}]{{8}}' if self.proto.coin == 'BCH' else None)
|
||||
|
||||
def bob_twview3(self):
|
||||
sid2 = self._get_user_subsid('bob','127S')
|
||||
return self.user_twview('bob',chk=(sid2+':C:3','0.127'),sort='amt')
|
||||
return self.user_twview(
|
||||
'bob',
|
||||
opts = self._cashaddr_opt(1),
|
||||
chk = (f'{sid2}:C:3', '0.127'),
|
||||
sort = 'amt',
|
||||
expect = rf'[{b32a}]{{8}}' if self.proto.coin == 'BCH' else None)
|
||||
|
||||
def bob_subwallet_txcreate(self):
|
||||
sid1 = self._get_user_subsid('bob','29L')
|
||||
|
|
@ -873,13 +887,17 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
|
|||
|
||||
def bob_txhist1(self):
|
||||
return self.user_txhist('bob',
|
||||
opts = self._cashaddr_opt(1),
|
||||
args = ['sort=age'],
|
||||
expect = fr'\s1\).*\s{rtFundAmt}\s' )
|
||||
expect = fr'\s1\).*\s{rtFundAmt}\s',
|
||||
expect2 = rf'[{b32a}]{{8}}' if self.proto.coin == 'BCH' else None)
|
||||
|
||||
def bob_txhist2(self):
|
||||
return self.user_txhist('bob',
|
||||
opts = self._cashaddr_opt(0),
|
||||
args = ['sort=blockheight','reverse=1','age_fmt=block'],
|
||||
expect = fr'\s1\).*:{self.dfl_mmtype}:1\s' )
|
||||
expect = fr'\s1\).*:{self.dfl_mmtype}:1\s',
|
||||
expect2 = rf'[{b58a}]{{8}}' if self.proto.coin == 'BCH' else None)
|
||||
|
||||
def bob_txhist3(self):
|
||||
return self.user_txhist('bob',
|
||||
|
|
@ -903,6 +921,13 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
|
|||
self.get_file_with_ext('out',delete_all=True)
|
||||
t = self.spawn('mmgen-tool',
|
||||
['--bob',f'--outdir={self.tmpdir}','txhist','age_fmt=date_time','interactive=true'] )
|
||||
if self.proto.coin == 'BCH':
|
||||
for expect, resp in (
|
||||
(rf'[{b32a}]{{8}}', 'h'),
|
||||
(rf'[{b58a}]{{8}}', 'h')
|
||||
):
|
||||
t.expect(expect, regex=True)
|
||||
t.expect('draw:\b', resp, regex=True)
|
||||
for resp in ('u','i','t','a','m','T','A','r','r','D','D','D','D','p','P','n','V'):
|
||||
t.expect('draw:\b',resp,regex=True)
|
||||
if t.pexpect_spawn:
|
||||
|
|
@ -1673,6 +1698,18 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
|
|||
t.expect(prompt, s)
|
||||
return t
|
||||
|
||||
def alice_listaddresses_cashaddr(self):
|
||||
if self.proto.coin != 'BCH':
|
||||
return 'skip'
|
||||
prompt = 'abel:\b'
|
||||
expect = (
|
||||
[rf'[{b32a}]{{8}}'],
|
||||
[prompt, 'h'],
|
||||
[rf'[{b58a}]{{8}}'],
|
||||
[prompt, 'q']
|
||||
)
|
||||
return self._alice_listaddresses_interactive(expect=expect)
|
||||
|
||||
def alice_listaddresses_empty(self):
|
||||
return self._alice_listaddresses_interactive(expect_menu='uuEq')
|
||||
|
||||
|
|
@ -1731,6 +1768,17 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
|
|||
args = ['age_fmt=date_time'],
|
||||
expect = (rtAmts[0],pat_date_time) )
|
||||
|
||||
def alice_twview_interactive_cashaddr(self):
|
||||
if self.proto.coin != 'BCH':
|
||||
return 'skip'
|
||||
t = self.spawn('mmgen-tool', ['--alice', 'twview', 'interactive=true'])
|
||||
prompt = 'abel:\b'
|
||||
t.expect(rf'[{b32a}]{{8}}', regex=True)
|
||||
t.expect(prompt, 'h')
|
||||
t.expect(rf'[{b58a}]{{8}}', regex=True)
|
||||
t.expect(prompt, 'q')
|
||||
return t
|
||||
|
||||
def alice_txcreate_info(self,pexpect_spawn=False):
|
||||
t = self.spawn('mmgen-txcreate',['--alice','-Bi'],pexpect_spawn=pexpect_spawn)
|
||||
pats = (
|
||||
|
|
|
|||
|
|
@ -294,7 +294,7 @@ def do_ab_test(proto,scfg,addr_type,gen1,kg2,ag,tool,cache_data):
|
|||
sec = PrivKey(proto,in_bytes,compressed=addr_type.compressed,pubkey_type=addr_type.pubkey_type)
|
||||
data = kg1.gen_data(sec)
|
||||
addr1 = ag.to_addr(data)
|
||||
view_pref = 0
|
||||
view_pref = 1 if proto.coin == 'BCH' else 0
|
||||
tinfo = ( in_bytes, sec, sec.wif, type(kg1).__name__, type(kg2).__name__ if kg2 else tool.desc )
|
||||
|
||||
def do_msg():
|
||||
|
|
|
|||
5
test/ref/bitcoin_cash/895108-BCH[2.65913].rawtx
Normal file
5
test/ref/bitcoin_cash/895108-BCH[2.65913].rawtx
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
0bd373
|
||||
BCH MAINNET 895108 2.65913 20240926_071550 1000000
|
||||
0200000002eb4f3508ac2ca1ec5c2851274214aee247dfc60ae3c739bae926216f13b8ed4e0000000000ffffffffd751a1d02474628bffca80020a4f430a5ab97e52c8eb0327255bce8f406844610700000000ffffffff030859de01000000001976a9140d5ea98cdb1d5c41bbb73750c579352b63cb8b6e88aca029fb0d000000001976a914f956b8114948fb7d8b651fc23fef66e0087412f388ac63b07167010000001976a914295e2be7fb7ae4a00d8e0ed267da0e00f14eb00588ac00000000
|
||||
[{'vout': 0, 'txid': '4eedb8136f2126e9ba39c7e30ac6df47e2ae14422751285ceca12cac08354feb', 'scriptPubKey': '76a914b894f691d65f9025c28c37d0e2d7fb8ae466a1a488ac', 'comment': 'Alice\u2019s allowance', 'amt': '37.52425504', 'addr': 'bitcoincash:qzuffa536e0eqfwz3smapckhlw9wge4p5spvx5j7h7', 'confs': 574214, 'mmid': 'EB5572C5:L:1', 'sequence': 4294967295}, {'vout': 7, 'txid': '614468408fce5b252703ebc8527eb95a0a434f0a0280caff8b627424d0a151d7', 'scriptPubKey': '76a91460e025db040aaa5ed9a7a8051cb9e82f58df489588ac', 'comment': '', 'amt': '25.44058763', 'addr': 'bitcoincash:qpswqfwmqs925hke575q289eaqh43h6gj54ysy3xae', 'confs': 676627, 'sequence': 4294967295}]
|
||||
[{'addr': 'bitcoincash:qqx4a2vvmvw4csdmkum4p3tex54k8jutdctzd50x4u', 'amt': '0.31349', 'is_chg': False}, {'addr': 'bitcoincash:qru4dwq3f9y0klvtv50uy0l0vmsqsaqj7vugke5esy', 'amt': '2.34564', 'is_chg': False, 'mmid': 'EB5572C5:L:7'}, {'addr': 'bitcoincash:qq54u2l8ldawfgqd3c8dye76pcq0zn4sq5letrxcdf', 'amt': '60.30471267', 'is_chg': True, 'mmid': 'EB5572C5:L:8'}]
|
||||
57
test/ref/bitcoin_cash/bchwallet-testnet.dump
Normal file
57
test/ref/bitcoin_cash/bchwallet-testnet.dump
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
# Wallet dump created by Bitcoin Cash Node v27.1.0-9f9aa5a6e
|
||||
# * Created on 2024-09-28T09:13:38Z
|
||||
# * Best block at time of backup was 0 (000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943),
|
||||
# mined on 2011-02-02T23:16:42Z
|
||||
|
||||
# extended private masterkey: tprv8ZgxMBicQKsPexYGMbCXgorSb94LSNHruGV8TcYGnvvAmfYhMsFgeLQNcZNGjpFNGZECug2pNiGx9CxgPfmm1MBai3ChRco9zvMhGgjCrbc
|
||||
|
||||
cVp8wiSLfBHmFTM8ANuNQaGSYdaeGzQPTjzy35cctkD5NYpWVedV 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qqtw9k8rrz5yuuu8mpxqrrlt05nslxp3qqsswccy0t hdkeypath=m/0'/0'/636'
|
||||
cRLvPdrsqR3izskvzcz4cS8pGzLTsnMDA6Lo6vPepYhp8vEc7NnD 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qq57qrhm3r3w0cjjtr865l7qq47ed66gqqtz3dcqh2 hdkeypath=m/0'/0'/668'
|
||||
cNUKQrbW6y9usj4rn8cX1LTP4f3rDmLcouuQcex1d8UykdyNvGqN 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qp2f2fvxccmpdnkzc3h252d3gupzj9y9qqw7qa6wus hdkeypath=m/0'/0'/650'
|
||||
cRvhFvDo4DQ6xeFDyG8N6kfgff3FS2sJL2yRCYWeG9rFHHhBMqD5 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qp74u03veyxpwr0fr6mn5vamvr5gd8ufqqttu5hvz9 hdkeypath=m/0'/1'/438'
|
||||
cUxwL9tKy83GX5zUHtGbsfZK23Y4CQ6hKdqbCiMkLJpNMvRyboV2 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qrrdu293cnrdy0eyfc29pugulk339ddpqqnz5h86m4 hdkeypath=m/0'/0'/572'
|
||||
cUxUVnJ1CzoTCA4nsC1zKWJHwYYhNCGghc3iaLecnS5Yez57DTKV 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qzju897ltu2gwuy029grdesgp64dwv49qq7g4u4jrp hdkeypath=m/0'/1'/650'
|
||||
cNeXwV6a2XnvkmhxRJFjTBrZuFrmR8geii1AWzK8TyPxMd9R5yHX 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qql35gw4lcvjn7y0rtajtjvar566rpwzqqwg9v8wz6 hdkeypath=m/0'/1'/26'
|
||||
cNY9Aw3KUXbu2fVoNHJKEeyae2dcu6wkrehuUY5FtDPATaoyGqqy 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qqr52pjym9zx3q660ya989shtrs3dlk5qqjskuc2cz hdkeypath=m/0'/0'/245'
|
||||
cS8qYyAg8QGRGn1HPTpaT5yogQdhxy7EG2tJvhrNRVF4SSpevwcp 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qzycyx62gt2r9aa40zqry38mzcdplfkeqq79tkmya8 hdkeypath=m/0'/0'/59'
|
||||
cTdMWafCwAd9o5UDNQNwXfVRcAvybo98NguKyxDVCDRLrDRax3TL 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qz4rxgqy0duzf5kxhd7te53edqca9qklqqtf0jv8dc hdkeypath=m/0'/1'/575'
|
||||
cPtJLThtyGbj8QnmiuXiQhX6A4Mdb8DPyRYMYrQ4cLnKeRxXLdF6 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qzpwh9dh6j6g0juc50cl9dslcgmcs4hmqq9djlmk5j hdkeypath=m/0'/1'/425'
|
||||
cRzHF8okeRPFVMSewpAjWqfiWgjkjFxZqAEVPjiFt5ZCdyZUr3C7 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qp97umelqwpukmtaf72y083dy54lqmqdqy7yjcvjmj hdkeypath=m/0'/1'/559'
|
||||
cS99oNTaQB5RBpHDSHJEenyjmJhF9KyWDtq96J91wKHkBmbU8ANq 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qpc5qjz6lt0v5cjeg5z9h0u65sd3lpe9qydu3d30uf hdkeypath=m/0'/1'/765'
|
||||
cTkaVbTNPfYEZvVQum7vf7RWYy4hwqrg4BD1cnk2TE8fSe5LDiex 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qqqdmv4u2l8g3vttakq8a0vdpgw0v2fsqyutg60vpd hdkeypath=m/0'/1'/29'
|
||||
cNZqJhwScX3TrAF4pMcZnzku9QoLmfbamuxCVMVmZNJkubRyv4ht 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qz7vmyvj805g7ahnmrz623qg9t49jh6mqy8xhz29az hdkeypath=m/0'/1'/491'
|
||||
cV5FaqsEYyYWokVNRMGgoweUneU8AJhVJ8F8PrSc5XsL3g8fUT4A 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qz0u3kgqq5xrkj8zch8v28jypdvtaur5qyjfv33a4r hdkeypath=m/0'/1'/190'
|
||||
cUyaVudNPss23dKjJUfs4cqKDnvh1taigAhtHDRXone75VWmMbMN 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qp9mkm0u9jcuf8yzmntk497d8vccfw5hqy40lxngtk hdkeypath=m/0'/0'/978'
|
||||
cNLhJ4nomtwsvDKoFXGDondDZJFgfF2e8XTxDPERs9zP9NPqUDKg 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qpx96famcmfr7g7370qufkh58ffmwp4nqylaj6tsw2 hdkeypath=m/0'/0'/564'
|
||||
cR3JBZBk7RtbEwt3VMKqQimWZXKyhuidU5pwpLoY2GGNLphSnrsP 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qp5recsz4w0lsqxkudzjwe4syhqqpr8xqyx06hqhdt hdkeypath=m/0'/1'/329'
|
||||
cRkrg9gFU8e51RBW8ZXZYoEoktWRYLV3RZFL5aEdpfk6wkparAHD 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qqk48mrkq8hjzysdz2y53vs6u4ulkt8aqy7he5yr9x hdkeypath=m/0'/0'/569'
|
||||
cMzNpPeeXtYTVswwULSF6AAoa2nUBHb6myufP7AF4hoovMU4RAZh 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qr5fceuvff9khx5304aqkvxhzwmemngpqgcykgc7ts hdkeypath=m/0'/1'/495'
|
||||
cSJ4aztJyTfzsR2yRhQXBtYm6hoANLQHmV1fRodnepWaNps7N5Fy 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qzveklahtds9u4p0pt04f3vz4gznsccdqgqd9zn7gy hdkeypath=m/0'/1'/583'
|
||||
cTrDo25RNhpGw4j7Kn8oTVfYioJ7kVKPt52Vu8mbWQA7LZfQ9uTY 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qrd4ctzd9lfqksyxyh4rk3ydvs9ncfs4qgln04njqf hdkeypath=m/0'/0'/985'
|
||||
cRxbuanYahFoZxykkFJPCYpHLkhzGznmcDiE3pjJAbaALDy7t4iX 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qzg4jh3lakadpm0vmenms59javvevcfmqgtprztuje hdkeypath=m/0'/1'/48'
|
||||
cQcnMRahdsvAEUZo6GGMhCi3KJdhZiTE7PLjvoZFSWUHDZSZVpHz 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qzxmlct4rjemuw7l3mecc7lehkt8hxzjqg0ry8h6z8 hdkeypath=m/0'/1'/635'
|
||||
cV9hcAoazBJTRuDoBhDfMgrb5b484g2UechpaCCbbLhEvxktGVit 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qq95ljjemaf528krs6xgja9zpzd6656eqgg6f7atfa hdkeypath=m/0'/1'/387'
|
||||
cNc5Y7fwUFumaWxnq63FGACVK2Uy5aUCMCeqzEGEzLFBaU4oqLxW 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qrhqfqsetnxmc9ajwsfjwluefqy6uytsqgahzal7wx hdkeypath=m/0'/0'/353'
|
||||
cTmGh4sv7gDJUDe8PBsZQ77KoKpEZrpz9MTM6mxeTgSC5ikYbLNK 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qqeqttck033lrgac0smvnq44cryfqw5fqgfws59ujw hdkeypath=m/0'/0'/384'
|
||||
cUNh8FEFYuJYEb2dfRst1SwMPonbBbUxy5QGP2ednbxm9KahzY67 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qrspfwz5mwlgc55vxmjls2xy5yd3tkvwqga5xut3sc hdkeypath=m/0'/0'/493'
|
||||
cVQeD6M16HKPsR5BZdiKHk576cxoT1emU43w7R8XDQkeCi2oGg5y 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qzeq0wr07r75mkygukase2ye7dxg42asqgwhh8uhpa hdkeypath=m/0'/1'/442'
|
||||
cVCah2gzytEK4iBXVJLeTNHmvmGzLNqFLrR5dR1XtstMsCgwyCgC 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qz8cavad8ujsj5p8mnuycg6efcsupxlpqg0wd35j2e hdkeypath=m/0'/1'/687'
|
||||
cUFejVszCwodxV3B3ppB9CSbBc6yJ9e9RjGR4aK6Z5LPXnbdCEv2 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qrm9hrvw2stpnlkl0f6rje75ltv4ftpzqvvgawxhcd hdkeypath=m/0'/1'/469'
|
||||
cQEYTwzo22pEwE7T1zWATsL4eZ7gYYanQR3XxdLdo8RGpqd1KSeZ 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qqtgazx0dcyypeaxy50x00fve5y3zkeeqvrl76ku5k hdkeypath=m/0'/1'/910'
|
||||
cRoFNNQYRm5V72cokeAjoWUYuCjieZTjTvd6743m8cmYXazSp22m 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qzenr7dmrt68tcjm7daawn6srkcy76jtqvn92m6de2 hdkeypath=m/0'/1'/287'
|
||||
cSK2tKxkNZQojqtohor5yL7dSb4edeuG5qMh8JzUJeLZvN8cxukt 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qq2w0d3vw5202hse28p0la9rvcne5j24qv6t4hj58d hdkeypath=m/0'/0'/555'
|
||||
cVPsuH8v4PpLJieDFMYyXuRAVmFkVmRTHBGxEeGELo4QMPz8bYyZ 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qp8nn4zyy5v8su6v3c6sf2hq0nrxeqzuqvqs4h5xam hdkeypath=m/0'/0'/858'
|
||||
cPGthbqMbX6kCUXG72kZfYWZX1cwWhLUaRvKj1LeNTZTEQkEQKez 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qzy7flccw4g3nhh4mksxwwuz2smx85naqvcealz8pc hdkeypath=m/0'/0'/89'
|
||||
cV76D5Z8UxuskGaerD5VYR6oies1HUHDvq8eLuQ9dnEnrupiHesN 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qqeug07w2n6gjrnzflr8dp2x4ku3794dqv46y80v4e hdkeypath=m/0'/1'/849'
|
||||
cPi5RxfS2HHMWMt3YnY5x2JnLLis5wtYoX7uf8swYb2DaC93ja83 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qzn0nkz9klkctg3s08zgf7xwexung27qqv33s57lfa hdkeypath=m/0'/0'/445'
|
||||
cTmE2XrXjay4pN6rSQqGdQ61RfH71716i9Gr41XRE1H5am998HWT 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qq9vkfzflckgrzndj5um4xnxtzkwl5wtqvrurey9a6 hdkeypath=m/0'/1'/97'
|
||||
cQLSaL6A4taGdsWLGWQK2RrAjsRHE3iKQ9bQ4sNFFFJaPqeSzEdW 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qrje963zup3k4w0usvfcfm6xwm6rmah3qvp3y5p5f2 hdkeypath=m/0'/1'/807'
|
||||
cUwbXhFJzLvDM6cahsmjteUSPB9R86pNjRWbGiidcdnHQtZcjffS 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qpzqpt9nnqvrpzp4kydxrl87jq5qv2glqs3lty3jqv hdkeypath=m/0'/0'/76'
|
||||
cNnhDbhrvxMsmr8NQwuBubg2LqtdmyVF1cZCCUNZXtkQvCFzeisB 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qql8htcgd7fmk94q443jptzn0ulv06zqqsl0k7pxlh hdkeypath=m/0'/0'/51'
|
||||
cUqbctTgaD19iZ8FJjKMGr5YdqCXs3ti3KHqtZNPNryVaa9EA2RD 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qzz6rhxw92daxjawff92c2ghxfjjwkmqqszz0s68te hdkeypath=m/0'/0'/26'
|
||||
cQXB8bGdcPjyNVnrPwUKCdJcx4yNJoYauAGE4pZvcB8ZrAe1Z8ZT 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qqex9m5ty059pgqwryfffm9dzuapfg4rqskq3hqm0s hdkeypath=m/0'/1'/896'
|
||||
cNReXczzABpyPxPBAPK1ddwwV1aoy2xnqeMt9mXGH7EpqEiiisqm 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qr6gf7vx08rq0uchl0wwsh0jlnp9l6ayqsds94yuqd hdkeypath=m/0'/1'/712'
|
||||
cTZ1XaNjpTnr5dgCGAkeV4NZCxZhoYwRrJoenmAqbgWC2yzA1vLi 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qrhyd89258ultrjf3hsk72lg3n7wx3lxqsrvpgx04e hdkeypath=m/0'/1'/224'
|
||||
cSnbnKjTEinAxVMk4i7qDzAeC7duseKvVLninzCiVskSVjwSmAv4 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qp05qf87mkfgxs0hpgvgdchtj3zqex8wqs8h8954e9 hdkeypath=m/0'/1'/717'
|
||||
cVLJtk7kFFCAfEvj3ULNr59ogFhprhY4LmBSaKyepDtssuBV4aoj 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qz6pxp99qtvewl6zxa90268y6nwx3mhhqsfkf4d7ms hdkeypath=m/0'/0'/779'
|
||||
cTrScwV6E1uRtrcNufcDPJyord3AXgGiAz7HHPk88d5AFD6WVbUx 2024-09-28T09:13:20Z reserve=1 # addr=bchtest:qqeyp4gqhd3thj235xw8rkjxyg2hh7leqs55paumr5 hdkeypath=m/0'/1'/565'
|
||||
57
test/ref/bitcoin_cash/bchwallet.dump
Normal file
57
test/ref/bitcoin_cash/bchwallet.dump
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
# Wallet dump created by Bitcoin Cash Node v27.1.0-9f9aa5a6e
|
||||
# * Created on 2024-09-28T09:01:27Z
|
||||
# * Best block at time of backup was 0 (000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f),
|
||||
# mined on 2009-01-03T18:15:05Z
|
||||
|
||||
# extended private masterkey: xprv9s21ZrQH143K3rtmqd4EARwck2w9PMoozEdPXdN3q7G34xYWJUi6f78acEx3go1648yunqrmRzcbjQDYuFTPAXnG1CUjqc7LZnkwMNg3QBG
|
||||
|
||||
KzVH2yXbj8oKGPiBqqwze9CyfkE5bsCUVCt6hd8nVxwZg7MCjaVh 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qryzwf3zl5vl4txc4v03yuzymenfrfwmqqye26zhtv hdkeypath=m/0'/0'/13'
|
||||
KzF25zJ1SEZrWFbc1V7GnCrXWgUFCHXirpi5UDNZ83PTd524Qz9B 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qqw6uwxf096nmgfucnqjdlgnhu9jxyswqyuejq9cac hdkeypath=m/0'/0'/9'
|
||||
L4t5RMzGSUps2pVtFS2gfx1W9hTaLXKkLfdsowt6de3NUvd9g6kv 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qzjz6zrkjxcm0t7xv2p6d5ylrvnrj5x4pqrxczzt6d hdkeypath=m/0'/0'/3'
|
||||
L3WHKc7JY9QtnPQmrmk6w8rbMugBpy2ydNhzYpgoG6vxzTofxTAQ 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qz4vyfzutpp53nfnzqtwasavh9zvr45r9vequueu05 hdkeypath=m/0'/0'/4'
|
||||
L3C7osemZLh9dzUmtBpL3xz2zgkFuY1wt5ykFAevZigudUsSjHDd 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qz7uunmyx67nvujz9qg59yh2dedv4q6v9sddgmywe7 hdkeypath=m/0'/0'/2'
|
||||
L1ua9H1EJq6bGTgrj4SjSipEBMPhM4naE2udaGZxeYyXxmgEDWSG 2024-09-28T09:00:51Z hdseed=1 # addr=bitcoincash:qzaatxgp2p6dqjppu43jxwpsllyh94s6xy4dgksysv hdkeypath=s
|
||||
L2PZUxH9n9J6dLu8MUvKzpngcg1EJLQy9QfWfFtBj5yLQb1Uqr5L 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qpy40kh7nkfd9heuc5f0fy2yq9s400quxv8y4xntu6 hdkeypath=m/0'/0'/21'
|
||||
L3cPRuFrvewas5WyAksyYnNmjBJzkEsFtrTqKKJKEz5VpfW2FPcW 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qpneya8njpm6n6mfsrcj3s9evr9k67jyxs5gfrgzcj hdkeypath=m/0'/0'/17'
|
||||
KxRmkfp4cJy4inmxy7sPVjrqN6F8d2pxJoZf7rBfyYc4KK7wokdh 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qqa4ezt3gzf3j7uqcjgudntpwvlxvp5d8vjqav3rht hdkeypath=m/0'/0'/20'
|
||||
KzM9HmLtuD8skinau2eUtkMeaqjokiTXVgrYPzCw7ySJfSa6cQsb 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qz9aw6gv4d69v8lmd7srn2gcwda2t0a085w8xunskq hdkeypath=m/0'/0'/6'
|
||||
L2Xze59SbhtNUwv1JwUMzzA5RQB4dw3j8FZZdrt9QC7ErSB5w4L1 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qpmx2se4glcfc83mtm4eglthhyqm7ee52ss72alnmy hdkeypath=m/0'/0'/19'
|
||||
KwdDU4G4rppt773ois2BULKGP8Lr6PoBVtWjfMGYD8WJAbq1Fk67 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qrq6cm6cml3xyn63c7lgdncqszqka7a0tu4zlkfynh hdkeypath=m/0'/0'/0'
|
||||
Kxfb92ePatCnDcjpJhdtqvyWfE63KWNtqiNpbmzuecFQRvPB2giB 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qzuq9zummldyc5xjxsqgauprm2rqqjmqvvy9jcflq3 hdkeypath=m/0'/0'/12'
|
||||
L1FpyeQFFmk1YkFC4FU4WhTjDETi9TRYDxVqZC48phUigfJnCGLf 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qq2vn4qf04pwjrfddn8zwx0afqv9u674dul0p9tqyz hdkeypath=m/0'/0'/7'
|
||||
KxeABzNJ32G81B2KYis3QgCmPH2LmgrvsLKUyTbFTa9TBBpMXpGU 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qpm786fm57k3qr9m2yrpj33exgvedrha0ua9pk5dfz hdkeypath=m/0'/0'/8'
|
||||
KwfUszgfu1SLJAydoHDz6HYCsj5x7yeLUfEkWkRBk6pHHQmdvdNT 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qzz2gms7w3g0u2jqrgwqf00pnpw4xv5w3g68pn0lwl hdkeypath=m/0'/0'/10'
|
||||
KyFEkJhebt7ZnzaLTGBokkeKECj3eUHSMLVz16LmQiKE9YkYjnDx 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qzudzz8um9thpe3n6sx6y2s83g3f5gffnvzvydmrd2 hdkeypath=m/0'/0'/15'
|
||||
KzjQPk5xVmsqfTai9Qnwsw8PrUxSjoLT9TqXi2iXrCHAPqFEN9KL 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qz2wp0tsd2222hf2nw23rhvjp8cgyext4gnuruujts hdkeypath=m/0'/0'/16'
|
||||
KwrEu8kc7FWbAJnfpGniYVvLkCyQXdsZANtYmfXEzRnTUoNTFkL5 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qr5d0gr79c5gcy6f46x3f997aw98ttaxkszemm2sc5 hdkeypath=m/0'/0'/5'
|
||||
L1QrY5tecZ6pQ7FjaUG3ZFWPy55qm7JRjivaPzp7tUHorLVpxsts 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qzf8e846e070d4ms6rkrrcwfhfvqgzvhhvjemgw90y hdkeypath=m/0'/0'/14'
|
||||
L4fjz4VZL8MyhSXXnmqCaPpJ1gpDJSWVkEj9JwGqHNh3ftFt7fSK 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qq5j965zc0ynlyx7gu8a3ay6ynwpgjcwmuge4nx9d7 hdkeypath=m/0'/0'/11'
|
||||
Kx5doQ9MZZNNjdaR9AjV18SFojQf3dDyvqR8xgu5f99kaPFrxfih 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qqgjaznt55w8p6445jvlp3l99vpd58pqugvgdw54m6 hdkeypath=m/0'/0'/18'
|
||||
Ky4UDQL9uJn9BsgqhEpyZzCwKM4S3VZbjj7MizaZv4qoktSco4SK 2024-09-28T09:00:51Z reserve=1 # addr=bitcoincash:qqq5jwnp0lhszkly4href262wnl3e8dxaqx67edhwj hdkeypath=m/0'/0'/1'
|
||||
L4Pg3BFXMD4GxfsDujY56is1GDt7TuFUzq9D8EpzmZAMoxG5VGe1 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qzq2l67xz9zver23lyhqdn6j4fxa0v32qqgy7tuxpx hdkeypath=m/0'/1'/392'
|
||||
KzmaLSVCL5RythXGPUw4uyJQDS2j5qXxcLUxWkQbDsRpKTiMyr9h 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qqt30vesj72xegyxhhu5vph9s474gjt9qq0vcxvp8k hdkeypath=m/0'/1'/217'
|
||||
KxNiUoG6xoWn1dBqDW6QU5n1hSD1rdPNPPfv8BqnMsdPDViYtDMG 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qzmrdx6m0lmn5qxcg2p7yghkndwtusunqqzhy0a937 hdkeypath=m/0'/0'/991'
|
||||
Kwf7frjVxR8geZwMGr4YY4rd3urTyThTQmPwmzZHsRmJYopuVEdR 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qzjp3udaawrwzjpp0ha3r2u8v0cpcmvaqqqgrhvhvp hdkeypath=m/0'/1'/146'
|
||||
L3RXLas6ZmBKENVQB9PCgFqZqvpCaJH8yc5SD29e3ysfViaodV2K 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qqa267qf9a07z6la89hvr6dppyckzfkwqq20wrhypu hdkeypath=m/0'/0'/965'
|
||||
L1Uyd6thQJnRbFr9ytWPJz1ogZLZNdhfTgmpDt16FwANedb7oteS 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qzkxc8c5ull9qc485yyjzh06tcmkw4l7qq9seqpqy7 hdkeypath=m/0'/0'/963'
|
||||
L2LpY1dUY5VL9bDqc11zLzCSJKEmfkAZNaJRwjrbk2HJFKkM2fmr 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qzvrcr3f46czytk3wr3runlqwznv9p3zqy9lzjvetm hdkeypath=m/0'/1'/927'
|
||||
KweRCR3RkpfhZvRRMFBpq16z3XpB29N6UguN8VWjD4PQr96kmqVP 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qzllfzpwshvhjxe98y7vq3sm0ulz42peqy2ngg2xpz hdkeypath=m/0'/0'/268'
|
||||
L3GYWNvrReSpL6ED6bmN6NmVoPrJeQg2363BBZNAbfJXE8ofTcjP 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qzgtmde25a7q29tpu4jf38dvkcujw4j2qyh0l62alz hdkeypath=m/0'/0'/332'
|
||||
L3VwEfgMaWViYkY2xdvZknGMNHSWbfqjrokpzX5KAL2w347Tahho 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qzvqr39nmtylzhzpf7cjjxzgjv5syx6dqyl38cuyt3 hdkeypath=m/0'/0'/884'
|
||||
KydYvd86K9d88CdxWbTNrM3gnoos4jvKENfgiDtPraKiEYmv4MNX 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qpwssgatqta6nx5ru58r20w8qcrzaxrjqyvvz5q7n5 hdkeypath=m/0'/0'/876'
|
||||
L2Ka61jjXQvNKFsZXJyB6YhYcSeSSpKqPy6zW5ABVXftxT9Bqjwu 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qraclt7lpx6um64s3ruyqtznt0hhn6vnqyyjf04z6y hdkeypath=m/0'/1'/260'
|
||||
L2Bko5eZ4nSSowtZZuUUZHTQEkr5sHvzjGprkG9QwGqpf7AUhHV3 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qr78tq3cgdv5h0ywqep89fyhy34l9t4dqyc5dcenvm hdkeypath=m/0'/1'/865'
|
||||
L45JdFaTJe4TagqcsMCo7WHfKHyitKDG6eC5BoeiVF7yqfU4BG44 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qpzu3sq2ljmvmwr0rjdxjg0xal26yyh2qynadya0r5 hdkeypath=m/0'/0'/704'
|
||||
L4ZfyviTt2Js2nH2X6ogGNoLnoauma9VfZYioga9f5iJzp1yKBsj 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qqff4nfsr7zwt3rw79u75gtnr72velcxqgn30n9dn9 hdkeypath=m/0'/1'/745'
|
||||
Kz3oWqWx8p4bYT11rQG6GjADNC5ykuUtpRb7pBWQogQDGRYBQzyc 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qz85l6lfl7d7qzg9c3nmtg958kvfzqsgqgvv2pr0zs hdkeypath=m/0'/0'/456'
|
||||
L5SZrXNW8Z9yvYdUkruhBNwcKEjJVHXT5zH78HXDYGCjM1HDoPRC 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qpcp3jvcxu89a5lxmdkns29ejxxn53fgqgv0l9ksna hdkeypath=m/0'/1'/515'
|
||||
KzLmpFiekUUpwchKLw14m1nDsx5UVvzvEwU6PY7qCb8bFFdfgVue 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qzv0v5wq7vqxeq9fuz5rm8f7azu2g43wqgvrlkxzyf hdkeypath=m/0'/1'/885'
|
||||
L4g6VoesU45xfbD1dpjKn4bSEQz26dumPD4vsTc4FFAyhphwxnbh 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qzp565dxv8efvmc3uh4z4h0ylds0cn36qgegl9fm5p hdkeypath=m/0'/0'/741'
|
||||
Kxwbnh2SjK5yoZwPTZ69VP4J6fnTEYPFtPbys9S7xU8xFxq512Zm 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qqea3z09daw8tj25w47npuwx5lsp9njaqgwddrunhc hdkeypath=m/0'/1'/246'
|
||||
L15Eg9gUugCAZvMRUi3282xb8Q9J7d5tiVawtJejZieHX457jgdk 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qrt7ej2m2hzu5yshuutm2pka6l8n0nnxqgqx92plfm hdkeypath=m/0'/1'/801'
|
||||
L2K5S297cfQnEx4tkaSS1xan6N5HVoH5TARavLEgdQbcPhhPbEjT 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qqe2kanrhh720y00uk6c5w63rd43gr4hqgwkgrrn33 hdkeypath=m/0'/1'/737'
|
||||
KyXyudwnHEDFvE1mVFY5m175Xw45BUF5bLMxJ1Xi5fHCqMoQ6kbk 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qqc0g42hx2czecul7u94ke7fh3mvh3ggqv3mrq8suu hdkeypath=m/0'/0'/518'
|
||||
KyXJuaTB4JwhHFvp6pHHFhNUv5JHfjTc1CJpfX1SCvZqEkW6Mg4f 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qr9kx4a6puadxwtm3vjqtf5hkjaa56qwqv7nqnczgm hdkeypath=m/0'/1'/39'
|
||||
KzcozomWBQgkGq1FB94UBqdBQeAaWHj6bP9wLwUVu7Vh2WiorTqF 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qp0p9t0075uf56nm2t2x2gc4xd7909ceqvccy6gsdp hdkeypath=m/0'/0'/376'
|
||||
KwS6Ln2E3bFqYNW1y7AAfWXNSuJdTmksmi1a3nt4TULmRqg44rMC 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qpj7z3vx762z0m2cnf92xtc8yw5e65ftqv99x2u3nv hdkeypath=m/0'/1'/628'
|
||||
L4BGf9Ri2ELjNgAyLipKX3j2vLst7t3jSK7XBhmk5cf2Z8SxAMEk 2024-09-28T09:00:52Z reserve=1 # addr=bitcoincash:qpmhuh97dpa00c2ha406fh7kcu6k68f0qvqnkj6d7c hdkeypath=m/0'/0'/892'
|
||||
|
|
@ -142,7 +142,8 @@ def make_coin_test_data():
|
|||
coin, mmtype = id_str.split('_', 1) if '_' in id_str else (id_str, None)
|
||||
opts = list_gen(
|
||||
[f'--coin={coin}'],
|
||||
[f'--type={mmtype}', mmtype]
|
||||
[f'--type={mmtype}', mmtype],
|
||||
[ '--cashaddr=0', coin == 'bch']
|
||||
)
|
||||
yield ('mmgen-addrgen', opts, [], [], test_data, 'address')
|
||||
|
||||
|
|
|
|||
|
|
@ -197,10 +197,16 @@ init_tests() {
|
|||
"
|
||||
|
||||
d_bch="overall operations with emulated RPC data (Bitcoin Cash Node)"
|
||||
t_bch="- $cmdtest_py --coin=bch --exclude regtest"
|
||||
t_bch="
|
||||
- $cmdtest_py --coin=bch --exclude regtest
|
||||
- $cmdtest_py --coin=bch --cashaddr=0 ref3_addr
|
||||
"
|
||||
|
||||
d_bch_tn="overall operations with emulated RPC data (Bitcoin Cash Node testnet)"
|
||||
t_bch_tn="- $cmdtest_py --coin=bch --testnet=1"
|
||||
t_bch_tn="
|
||||
- $cmdtest_py --coin=bch --testnet=1
|
||||
- $cmdtest_py --coin=bch --testnet=1 --cashaddr=0 ref3_addr
|
||||
"
|
||||
|
||||
d_bch_rt="overall operations using the regtest network (Bitcoin Cash Node)"
|
||||
t_bch_rt="- $cmdtest_py --coin=bch regtest"
|
||||
|
|
@ -286,6 +292,9 @@ init_tests() {
|
|||
a $gentest_py --coin=ltc --type=segwit 1 $REFDIR/litecoin/ltcwallet-segwit.dump
|
||||
a $gentest_py --coin=ltc --type=bech32 1 $REFDIR/litecoin/ltcwallet-bech32.dump
|
||||
a $gentest_py --coin=ltc --type=compressed --testnet=1 1 $REFDIR/litecoin/ltcwallet-testnet.dump
|
||||
a $gentest_py --coin=bch --type=compressed --cashaddr=0 1 $REFDIR/bitcoin_cash/bchwallet.dump
|
||||
a $gentest_py --coin=bch --type=compressed --cashaddr=1 1 $REFDIR/bitcoin_cash/bchwallet.dump
|
||||
a $gentest_py --coin=bch --type=compressed --testnet=1 1 $REFDIR/bitcoin_cash/bchwallet-testnet.dump
|
||||
- # libsecp256k1 vs python-ecdsa:
|
||||
- $gentest_py --type=legacy 1:2 $rounds100x
|
||||
- $gentest_py --type=compressed 1:2 $rounds100x
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ vectors_multicoin = {
|
|||
'doge': 'DFX88RXpi4S4W24YVvuMgbdUcCAYNeEYGd',
|
||||
'avax-c': '0x373731f4d885Fc7Da05498F9f0804a87A14F891b',
|
||||
'ltc_bech32': 'ltc1q3uh5ga5cp9kkdfx6a52uymxj9keq4tpzep7er0',
|
||||
'bch_cashaddr': 'bitcoincash:qpqpcllprftg4s0chdgkpxhxv23wfymq3gj7n0a9vw',
|
||||
'bch_compressed': 'bitcoincash:qpqpcllprftg4s0chdgkpxhxv23wfymq3gj7n0a9vw',
|
||||
'bsc_smart': '0x373731f4d885Fc7Da05498F9f0804a87A14F891b',
|
||||
'bnb_beacon': 'bnb179c3ymltqm4utlp089zxqeta5dvn48a305rhe5',
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,10 +9,23 @@ altcoin_dep = True
|
|||
from collections import namedtuple
|
||||
|
||||
from mmgen.proto.bch.cashaddr import cashaddr_parse_addr, cashaddr_decode_addr, cashaddr_encode_addr
|
||||
from mmgen.addr import CoinAddr
|
||||
|
||||
from ..include.common import vmsg
|
||||
from ..include.common import cfg, vmsg
|
||||
|
||||
from mmgen.protocol import init_proto
|
||||
proto = init_proto(cfg, 'bch')
|
||||
|
||||
# Source: https://upgradespecs.bitcoincashnode.org/cashaddr
|
||||
alias_data = """
|
||||
1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a
|
||||
1KXrWXciRDZUpQwQmuM1DbwsKDLYAYsVLR bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy
|
||||
16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r
|
||||
3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq
|
||||
3LDsS579y7sruadqu11beEJoTjdFiFCdX4 bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e
|
||||
31nwvkZwyPdgzjBJZXfDmSWsC4ZLKpYyUw bitcoincash:pqq3728yw0y47sqn6l2na30mcw6zm78dzq5ucqzc37
|
||||
"""
|
||||
|
||||
vec_data = """
|
||||
F5BF48B397DAE70BE82B3CCA4793F8EB2B6CDAC9
|
||||
20 0 bitcoincash:qr6m7j9njldwwzlg9v7v53unlr4jkmx6eylep8ekg2
|
||||
|
|
@ -78,6 +91,11 @@ class unit_tests:
|
|||
yield t(int(d[0]), int(d[1]), d[2], data)
|
||||
return list(gen())
|
||||
|
||||
@property
|
||||
def aliases(self):
|
||||
t = namedtuple('aliases', ['legacy', 'cashaddr'])
|
||||
return [t(*a.split()) for a in alias_data.splitlines() if a]
|
||||
|
||||
def encode(self, name, ut, desc='low-level address encoding'):
|
||||
data = None
|
||||
for v in self.vectors:
|
||||
|
|
@ -99,3 +117,35 @@ class unit_tests:
|
|||
ret = cashaddr_decode_addr(v.addr)
|
||||
assert ret.bytes.hex() == v.data
|
||||
return True
|
||||
|
||||
def coinaddr(self, name, ut, desc='CoinAddr class'):
|
||||
for e in self.aliases:
|
||||
for addr in (
|
||||
e.cashaddr.upper(),
|
||||
e.cashaddr,
|
||||
e.cashaddr.split(':')[1],
|
||||
e.legacy,
|
||||
):
|
||||
a = CoinAddr(proto, addr)
|
||||
vmsg(addr)
|
||||
assert e.legacy == a.views[1]
|
||||
assert e.cashaddr == a.proto.cashaddr_pfx + ':' + a.views[0]
|
||||
vmsg('')
|
||||
return True
|
||||
|
||||
def errors(self, name, ut, desc='error handling'):
|
||||
# could do these in objtest.py:
|
||||
def bad1(): a = CoinAddr(proto, self.aliases[0].cashaddr.replace('g','G'))
|
||||
def bad2(): a = CoinAddr(proto, 'x' + self.aliases[0].cashaddr)
|
||||
def bad3(): a = CoinAddr(proto, self.aliases[0].cashaddr[:-1])
|
||||
def bad4(): a = CoinAddr(proto, self.aliases[0].cashaddr[:-1]+'i')
|
||||
def bad5(): a = CoinAddr(proto, self.aliases[0].cashaddr[:-1]+'x')
|
||||
|
||||
ut.process_bad_data((
|
||||
('case', 'ObjectInitError', 'mixed case', bad1),
|
||||
('prefix', 'ObjectInitError', 'invalid prefix', bad2),
|
||||
('data', 'ObjectInitError', 'too short', bad3),
|
||||
('b32 char', 'ObjectInitError', 'substring', bad4),
|
||||
('chksum', 'ObjectInitError', 'checksum', bad5),
|
||||
))
|
||||
return True
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue