imports, whitespace
This commit is contained in:
@@ -23,18 +23,16 @@
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
import hashlib
|
||||
from typing import List, Tuple, TYPE_CHECKING, Optional, Union, Sequence, Any
|
||||
from typing import Tuple, TYPE_CHECKING, Optional, Union, Sequence
|
||||
import enum
|
||||
from enum import IntEnum, Enum
|
||||
|
||||
import electrum_ecc as ecc
|
||||
|
||||
from .util import bfh, BitcoinException, assert_bytes, to_bytes, inv_dict, is_hex_str, classproperty
|
||||
from . import version
|
||||
from . import segwit_addr
|
||||
from . import constants
|
||||
from .crypto import sha256d, sha256, hash_160, hmac_oneshot
|
||||
from .crypto import sha256d, sha256, hash_160
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .network import Network
|
||||
@@ -375,29 +373,36 @@ def hash160_to_p2pkh(h160: bytes, *, net=None) -> str:
|
||||
if net is None: net = constants.net
|
||||
return hash160_to_b58_address(h160, net.ADDRTYPE_P2PKH)
|
||||
|
||||
|
||||
def hash160_to_p2sh(h160: bytes, *, net=None) -> str:
|
||||
if net is None: net = constants.net
|
||||
return hash160_to_b58_address(h160, net.ADDRTYPE_P2SH)
|
||||
|
||||
|
||||
def public_key_to_p2pkh(public_key: bytes, *, net=None) -> str:
|
||||
return hash160_to_p2pkh(hash_160(public_key), net=net)
|
||||
|
||||
|
||||
def hash_to_segwit_addr(h: bytes, witver: int, *, net=None) -> str:
|
||||
if net is None: net = constants.net
|
||||
addr = segwit_addr.encode_segwit_address(net.SEGWIT_HRP, witver, h)
|
||||
assert addr is not None
|
||||
return addr
|
||||
|
||||
|
||||
def public_key_to_p2wpkh(public_key: bytes, *, net=None) -> str:
|
||||
return hash_to_segwit_addr(hash_160(public_key), witver=0, net=net)
|
||||
|
||||
|
||||
def script_to_p2wsh(script: bytes, *, net=None) -> str:
|
||||
return hash_to_segwit_addr(sha256(script), witver=0, net=net)
|
||||
|
||||
|
||||
def p2wsh_nested_script(witness_script: bytes) -> bytes:
|
||||
wsh = sha256(witness_script)
|
||||
return construct_script([0, wsh])
|
||||
|
||||
|
||||
def pubkey_to_address(txin_type: str, pubkey: str, *, net=None) -> str:
|
||||
from . import descriptor
|
||||
desc = descriptor.get_singlesig_descriptor_from_legacy_leaf(pubkey=pubkey, script_type=txin_type)
|
||||
@@ -593,12 +598,12 @@ def DecodeBase58Check(psz: Union[bytes, str]) -> bytes:
|
||||
# extended WIF for segwit (used in 3.0.x; but still used internally)
|
||||
# the keys in this dict should be a superset of what Imported Wallets can import
|
||||
WIF_SCRIPT_TYPES = {
|
||||
'p2pkh':0,
|
||||
'p2wpkh':1,
|
||||
'p2wpkh-p2sh':2,
|
||||
'p2sh':5,
|
||||
'p2wsh':6,
|
||||
'p2wsh-p2sh':7
|
||||
'p2pkh': 0,
|
||||
'p2wpkh': 1,
|
||||
'p2wpkh-p2sh': 2,
|
||||
'p2sh': 5,
|
||||
'p2wsh': 6,
|
||||
'p2wsh-p2sh': 7
|
||||
}
|
||||
WIF_SCRIPT_TYPES_INV = inv_dict(WIF_SCRIPT_TYPES)
|
||||
|
||||
@@ -679,6 +684,7 @@ def address_from_private_key(sec: str) -> str:
|
||||
public_key = ecc.ECPrivkey(privkey).get_public_key_hex(compressed=compressed)
|
||||
return pubkey_to_address(txin_type, public_key)
|
||||
|
||||
|
||||
def is_segwit_address(addr: str, *, net=None) -> bool:
|
||||
if net is None: net = constants.net
|
||||
try:
|
||||
@@ -687,6 +693,7 @@ def is_segwit_address(addr: str, *, net=None) -> bool:
|
||||
return False
|
||||
return witprog is not None
|
||||
|
||||
|
||||
def is_taproot_address(addr: str, *, net=None) -> bool:
|
||||
if net is None: net = constants.net
|
||||
try:
|
||||
@@ -695,6 +702,7 @@ def is_taproot_address(addr: str, *, net=None) -> bool:
|
||||
return False
|
||||
return witver == 1
|
||||
|
||||
|
||||
def is_b58_address(addr: str, *, net=None) -> bool:
|
||||
if net is None: net = constants.net
|
||||
try:
|
||||
@@ -706,6 +714,7 @@ def is_b58_address(addr: str, *, net=None) -> bool:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def is_address(addr: str, *, net=None) -> bool:
|
||||
return is_segwit_address(addr, net=net) \
|
||||
or is_b58_address(addr, net=net)
|
||||
@@ -733,6 +742,7 @@ def is_minikey(text: str) -> bool:
|
||||
and all(ord(c) in __b58chars for c in text)
|
||||
and sha256(text + '?')[0] == 0x00)
|
||||
|
||||
|
||||
def minikey_to_private_key(text: str) -> bytes:
|
||||
return sha256(text)
|
||||
|
||||
@@ -740,7 +750,10 @@ def minikey_to_private_key(text: str) -> bytes:
|
||||
def _get_dummy_address(purpose: str) -> str:
|
||||
return redeem_script_to_address('p2wsh', sha256(bytes(purpose, "utf8")))
|
||||
|
||||
|
||||
_dummy_addr_funcs = set()
|
||||
|
||||
|
||||
class DummyAddress:
|
||||
"""dummy address for fee estimation of funding tx
|
||||
Use e.g. as: DummyAddress.CHANNEL
|
||||
@@ -799,22 +812,24 @@ def taproot_tweak_seckey(seckey0: bytes, h: bytes) -> bytes:
|
||||
TapTreeLeaf = Tuple[int, bytes]
|
||||
TapTree = Union[TapTreeLeaf, Sequence['TapTree']]
|
||||
|
||||
|
||||
# FIXME just use electrum_ecc.util.bip340_tagged_hash instead
|
||||
def bip340_tagged_hash(tag: bytes, msg: bytes) -> bytes:
|
||||
# note: _libsecp256k1.secp256k1_tagged_sha256 benchmarks about 70% slower than this (on my machine)
|
||||
return sha256(sha256(tag) + sha256(tag) + msg)
|
||||
|
||||
|
||||
def taproot_tree_helper(script_tree: TapTree):
|
||||
if isinstance(script_tree, tuple):
|
||||
leaf_version, script = script_tree
|
||||
h = bip340_tagged_hash(b"TapLeaf", bytes([leaf_version]) + witness_push(script))
|
||||
return ([((leaf_version, script), bytes())], h)
|
||||
return [((leaf_version, script), bytes())], h
|
||||
left, left_h = taproot_tree_helper(script_tree[0])
|
||||
right, right_h = taproot_tree_helper(script_tree[1])
|
||||
ret = [(l, c + right_h) for l, c in left] + [(l, c + left_h) for l, c in right]
|
||||
if right_h < left_h:
|
||||
left_h, right_h = right_h, left_h
|
||||
return (ret, bip340_tagged_hash(b"TapBranch", left_h + right_h))
|
||||
return ret, bip340_tagged_hash(b"TapBranch", left_h + right_h)
|
||||
|
||||
|
||||
def taproot_output_script(internal_pubkey: bytes, *, script_tree: Optional[TapTree]) -> bytes:
|
||||
@@ -850,11 +865,13 @@ def usermessage_magic(message: bytes) -> bytes:
|
||||
length = var_int(len(message))
|
||||
return b"\x18Bitcoin Signed Message:\n" + length + message
|
||||
|
||||
|
||||
def ecdsa_sign_usermessage(ec_privkey, message: Union[bytes, str], *, is_compressed: bool) -> bytes:
|
||||
message = to_bytes(message, 'utf8')
|
||||
msg32 = sha256d(usermessage_magic(message))
|
||||
return ec_privkey.ecdsa_sign_recoverable(msg32, is_compressed=is_compressed)
|
||||
|
||||
|
||||
def verify_usermessage_with_address(address: str, sig65: bytes, message: bytes, *, net=None) -> bool:
|
||||
from electrum_ecc import ECPubkey
|
||||
assert_bytes(sig65, message)
|
||||
|
||||
Reference in New Issue
Block a user