From 66c264f6130c28f600a26c5d0dc28f0ee79f5298 Mon Sep 17 00:00:00 2001 From: SomberNight Date: Mon, 6 Apr 2020 17:23:22 +0200 Subject: [PATCH] bitcoin.py: change API of address_to_hash --- electrum/bitcoin.py | 34 +++++++++++++++++++++------ electrum/plugins/bitbox02/bitbox02.py | 9 +++---- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/electrum/bitcoin.py b/electrum/bitcoin.py index c1c2d73be..794eb54cd 100644 --- a/electrum/bitcoin.py +++ b/electrum/bitcoin.py @@ -25,7 +25,8 @@ import hashlib from typing import List, Tuple, TYPE_CHECKING, Optional, Union -from enum import IntEnum +import enum +from enum import IntEnum, Enum from .util import bfh, bh2u, BitcoinException, assert_bytes, to_bytes, inv_dict from . import version @@ -432,20 +433,39 @@ def address_to_script(addr: str, *, net=None) -> str: raise BitcoinException(f'unknown address type: {addrtype}') return script -def address_to_hash(addr: str, *, net=None) -> Tuple[int, bytes]: - """Return the pubkey hash / witness program of an address""" + +class OnchainOutputType(Enum): + """Opaque types of scriptPubKeys. + In case of p2sh, p2wsh and similar, no knowledge of redeem script, etc. + """ + P2PKH = enum.auto() + P2SH = enum.auto() + WITVER0_P2WPKH = enum.auto() + WITVER0_P2WSH = enum.auto() + + +def address_to_hash(addr: str, *, net=None) -> Tuple[OnchainOutputType, bytes]: + """Return (type, pubkey hash / witness program) for an address.""" if net is None: net = constants.net if not is_address(addr, net=net): raise BitcoinException(f"invalid bitcoin address: {addr}") witver, witprog = segwit_addr.decode(net.SEGWIT_HRP, addr) if witprog is not None: + if witver != 0: + raise BitcoinException(f"not implemented handling for witver={witver}") if len(witprog) == 20: - return WIF_SCRIPT_TYPES['p2wpkh'], bytes(witprog) - return WIF_SCRIPT_TYPES['p2wsh'], bytes(witprog) + return OnchainOutputType.WITVER0_P2WPKH, bytes(witprog) + elif len(witprog) == 32: + return OnchainOutputType.WITVER0_P2WSH, bytes(witprog) + else: + raise BitcoinException(f"unexpected length for segwit witver=0 witprog: len={len(witprog)}") addrtype, hash_160_ = b58_address_to_hash160(addr) if addrtype == net.ADDRTYPE_P2PKH: - return WIF_SCRIPT_TYPES['p2pkh'], hash_160_ - return WIF_SCRIPT_TYPES['p2sh'], hash_160_ + return OnchainOutputType.P2PKH, hash_160_ + elif addrtype == net.ADDRTYPE_P2SH: + return OnchainOutputType.P2SH, hash_160_ + raise BitcoinException(f"unknown address type: {addrtype}") + def address_to_scripthash(addr: str) -> str: script = address_to_script(addr) diff --git a/electrum/plugins/bitbox02/bitbox02.py b/electrum/plugins/bitbox02/bitbox02.py index ca99f816c..9d6143583 100644 --- a/electrum/plugins/bitbox02/bitbox02.py +++ b/electrum/plugins/bitbox02/bitbox02.py @@ -17,6 +17,7 @@ from electrum.plugin import Device, DeviceInfo from electrum.simple_config import SimpleConfig from electrum.json_db import StoredDict from electrum.storage import get_derivation_used_for_hw_device_encryption +from electrum.bitcoin import OnchainOutputType import electrum.bitcoin as bitcoin import electrum.ecc as ecc @@ -411,13 +412,13 @@ class BitBox02Client(HardwareClientBase): ) else: addrtype, pubkey_hash = bitcoin.address_to_hash(txout.address) - if addrtype == bitcoin.WIF_SCRIPT_TYPES["p2pkh"]: + if addrtype == OnchainOutputType.P2PKH: output_type = bitbox02.btc.P2PKH - elif addrtype == bitcoin.WIF_SCRIPT_TYPES["p2sh"]: + elif addrtype == OnchainOutputType.P2SH: output_type = bitbox02.btc.P2SH - elif addrtype == bitcoin.WIF_SCRIPT_TYPES["p2wpkh"]: + elif addrtype == OnchainOutputType.WITVER0_P2WPKH: output_type = bitbox02.btc.P2WPKH - elif addrtype == bitcoin.WIF_SCRIPT_TYPES["p2wsh"]: + elif addrtype == OnchainOutputType.WITVER0_P2WSH: output_type = bitbox02.btc.P2WSH else: raise UserFacingException(