proto.btc.tx.base: scriptPubKey2addr() -> decodeScriptPubKey()
This commit is contained in:
parent
037c6bfb6f
commit
e3dd55e909
4 changed files with 23 additions and 16 deletions
|
|
@ -31,15 +31,22 @@ def addr2scriptPubKey(proto, addr):
|
|||
'bech32': proto.witness_vernum_hex + '14' + decode_addr(proto, addr)
|
||||
}[addr.addr_fmt]
|
||||
|
||||
def scriptPubKey2addr(proto, s):
|
||||
def decodeScriptPubKey(proto, s):
|
||||
# src/wallet/rpc/addresses.cpp:
|
||||
# types: nonstandard, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_keyhash
|
||||
ret = namedtuple('decoded_scriptPubKey', ['type', 'addr_fmt', 'addr', 'data'])
|
||||
|
||||
if len(s) == 50 and s[:6] == '76a914' and s[-4:] == '88ac':
|
||||
return proto.pubhash2addr(bytes.fromhex(s[6:-4]), 'p2pkh'), 'p2pkh'
|
||||
return ret('pubkeyhash', 'p2pkh', proto.pubhash2addr(bytes.fromhex(s[6:-4]), 'p2pkh'), None)
|
||||
|
||||
elif len(s) == 46 and s[:4] == 'a914' and s[-2:] == '87':
|
||||
return proto.pubhash2addr(bytes.fromhex(s[4:-2]), 'p2sh'), 'p2sh'
|
||||
return ret('scripthash', 'p2sh', proto.pubhash2addr(bytes.fromhex(s[4:-2]), 'p2sh'), None)
|
||||
|
||||
elif len(s) == 44 and s[:4] == proto.witness_vernum_hex + '14':
|
||||
return proto.pubhash2bech32addr(bytes.fromhex(s[4:])), 'bech32'
|
||||
return ret('witness_v0_keyhash', 'bech32', proto.pubhash2bech32addr(bytes.fromhex(s[4:])), None)
|
||||
|
||||
else:
|
||||
raise NotImplementedError(f'Unknown scriptPubKey ({s})')
|
||||
raise NotImplementedError(f'Unrecognized scriptPubKey ({s})')
|
||||
|
||||
def DeserializeTX(proto, txhex):
|
||||
"""
|
||||
|
|
@ -119,7 +126,7 @@ def DeserializeTX(proto, txhex):
|
|||
} for i in range(d['num_txouts'])])
|
||||
|
||||
for o in d['txouts']:
|
||||
o['address'] = scriptPubKey2addr(proto, o['scriptPubKey'])[0]
|
||||
o.update(decodeScriptPubKey(proto, o['scriptPubKey'])._asdict())
|
||||
|
||||
if has_witness:
|
||||
# https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki
|
||||
|
|
@ -317,7 +324,7 @@ class Base(TxBase.Base):
|
|||
|
||||
check_equal(
|
||||
'outputs',
|
||||
sorted((o['address'], o['amt']) for o in dtx.txouts),
|
||||
sorted((o['addr'], o['amt']) for o in dtx.txouts),
|
||||
sorted((o.addr, o.amt) for o in self.outputs))
|
||||
|
||||
if str(self.txid) != make_chksum_6(bytes.fromhex(dtx.unsigned_hex)).upper():
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ proto.btc.tx.completed: Bitcoin completed transaction class
|
|||
from ....tx import completed as TxBase
|
||||
from ....obj import HexStr
|
||||
from ....util import msg, die
|
||||
from .base import Base, scriptPubKey2addr
|
||||
from .base import Base, decodeScriptPubKey
|
||||
|
||||
class Completed(Base, TxBase.Completed):
|
||||
fn_fee_unit = 'satoshi'
|
||||
|
|
@ -45,17 +45,17 @@ class Completed(Base, TxBase.Completed):
|
|||
|
||||
def check_pubkey_scripts(self):
|
||||
for n, i in enumerate(self.inputs, 1):
|
||||
addr, fmt = scriptPubKey2addr(self.proto, i.scriptPubKey)
|
||||
if i.addr != addr:
|
||||
if fmt != i.addr.addr_fmt:
|
||||
ds = decodeScriptPubKey(self.proto, i.scriptPubKey)
|
||||
if ds.addr != i.addr:
|
||||
if ds.addr_fmt != i.addr.addr_fmt:
|
||||
m = 'Address format of scriptPubKey ({}) does not match that of address ({}) in input #{}'
|
||||
msg(m.format(fmt, i.addr.addr_fmt, n))
|
||||
msg(m.format(ds.addr_fmt, i.addr.addr_fmt, n))
|
||||
m = 'ERROR: Address and scriptPubKey of transaction input #{} do not match!'
|
||||
die(3, (m+'\n {:23}{}'*3).format(
|
||||
n,
|
||||
'address:', i.addr,
|
||||
'scriptPubKey:', i.scriptPubKey,
|
||||
'scriptPubKey->address:', addr))
|
||||
'scriptPubKey->address:', ds.addr))
|
||||
|
||||
# def is_replaceable_from_rpc(self):
|
||||
# dec_tx = await self.rpc.call('decoderawtransaction', self.serialized)
|
||||
|
|
|
|||
|
|
@ -184,8 +184,8 @@ class tool_cmd(tool_cmd_base):
|
|||
|
||||
def scriptpubkey2addr(self, hexstr: 'sstr'):
|
||||
"convert scriptPubKey to coin address"
|
||||
from ..proto.btc.tx.base import scriptPubKey2addr
|
||||
return scriptPubKey2addr(self.proto, hexstr)[0]
|
||||
from ..proto.btc.tx.base import decodeScriptPubKey
|
||||
return decodeScriptPubKey(self.proto, hexstr).addr
|
||||
|
||||
def eth_checksummed_addr(self, addr: 'sstr'):
|
||||
"create a checksummed Ethereum address"
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ async def test_tx(tx_proto, tx_hex, desc, n):
|
|||
for i in range(len(a)):
|
||||
if 'addresses' in a[i]['scriptPubKey']:
|
||||
A = a[i]['scriptPubKey']['addresses'][0]
|
||||
B = b[i]['address']
|
||||
B = b[i]['addr']
|
||||
fs = 'address of output {} does not match\nA: {}\nB: {}'
|
||||
assert A == B, fs.format(i, A, B)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue