mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-08-30 17:01:34 +00:00
support sending to segwit native addresses (bip173)
This commit is contained in:
parent
5f35081bc9
commit
f56a8702c2
2 changed files with 31 additions and 15 deletions
|
@ -29,47 +29,49 @@ import re
|
||||||
import hmac
|
import hmac
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
import ecdsa
|
||||||
|
import pyaes
|
||||||
|
|
||||||
from .util import bfh, bh2u, to_string
|
from .util import bfh, bh2u, to_string
|
||||||
from . import version
|
from . import version
|
||||||
from .util import print_error, InvalidPassword, assert_bytes, to_bytes
|
from .util import print_error, InvalidPassword, assert_bytes, to_bytes
|
||||||
|
from . import segwit_addr
|
||||||
|
|
||||||
import ecdsa
|
|
||||||
import pyaes
|
|
||||||
|
|
||||||
# Bitcoin network constants
|
# Bitcoin network constants
|
||||||
TESTNET = False
|
TESTNET = False
|
||||||
NOLNET = False
|
NOLNET = False
|
||||||
ADDRTYPE_P2PKH = 0
|
ADDRTYPE_P2PKH = 0
|
||||||
ADDRTYPE_P2SH = 5
|
ADDRTYPE_P2SH = 5
|
||||||
ADDRTYPE_P2WPKH = 6
|
SEGWIT_HRP = "bc"
|
||||||
XPRV_HEADER = 0x0488ade4
|
XPRV_HEADER = 0x0488ade4
|
||||||
XPUB_HEADER = 0x0488b21e
|
XPUB_HEADER = 0x0488b21e
|
||||||
HEADERS_URL = "https://headers.electrum.org/blockchain_headers"
|
HEADERS_URL = "https://headers.electrum.org/blockchain_headers"
|
||||||
GENESIS = "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
|
GENESIS = "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
|
||||||
|
|
||||||
def set_testnet():
|
def set_testnet():
|
||||||
global ADDRTYPE_P2PKH, ADDRTYPE_P2SH, ADDRTYPE_P2WPKH
|
global ADDRTYPE_P2PKH, ADDRTYPE_P2SH
|
||||||
global XPRV_HEADER, XPUB_HEADER
|
global XPRV_HEADER, XPUB_HEADER
|
||||||
global TESTNET, HEADERS_URL
|
global TESTNET, HEADERS_URL
|
||||||
global GENESIS
|
global GENESIS
|
||||||
|
global SEGWIT_HRP
|
||||||
TESTNET = True
|
TESTNET = True
|
||||||
ADDRTYPE_P2PKH = 111
|
ADDRTYPE_P2PKH = 111
|
||||||
ADDRTYPE_P2SH = 196
|
ADDRTYPE_P2SH = 196
|
||||||
ADDRTYPE_P2WPKH = 3
|
SEGWIT_HRP = "tb"
|
||||||
XPRV_HEADER = 0x04358394
|
XPRV_HEADER = 0x04358394
|
||||||
XPUB_HEADER = 0x043587cf
|
XPUB_HEADER = 0x043587cf
|
||||||
HEADERS_URL = "https://headers.electrum.org/testnet_headers"
|
HEADERS_URL = "https://headers.electrum.org/testnet_headers"
|
||||||
GENESIS = "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"
|
GENESIS = "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"
|
||||||
|
|
||||||
def set_nolnet():
|
def set_nolnet():
|
||||||
global ADDRTYPE_P2PKH, ADDRTYPE_P2SH, ADDRTYPE_P2WPKH
|
global ADDRTYPE_P2PKH, ADDRTYPE_P2SH
|
||||||
global XPRV_HEADER, XPUB_HEADER
|
global XPRV_HEADER, XPUB_HEADER
|
||||||
global NOLNET, HEADERS_URL
|
global NOLNET, HEADERS_URL
|
||||||
global GENESIS
|
global GENESIS
|
||||||
TESTNET = True
|
TESTNET = True
|
||||||
ADDRTYPE_P2PKH = 0
|
ADDRTYPE_P2PKH = 0
|
||||||
ADDRTYPE_P2SH = 5
|
ADDRTYPE_P2SH = 5
|
||||||
ADDRTYPE_P2WPKH = 6
|
|
||||||
XPRV_HEADER = 0x0488ade4
|
XPRV_HEADER = 0x0488ade4
|
||||||
XPUB_HEADER = 0x0488b21e
|
XPUB_HEADER = 0x0488b21e
|
||||||
HEADERS_URL = "https://headers.electrum.org/nolnet_headers"
|
HEADERS_URL = "https://headers.electrum.org/nolnet_headers"
|
||||||
|
@ -290,8 +292,6 @@ def hash_160(public_key):
|
||||||
|
|
||||||
def hash160_to_b58_address(h160, addrtype, witness_program_version=1):
|
def hash160_to_b58_address(h160, addrtype, witness_program_version=1):
|
||||||
s = bytes([addrtype])
|
s = bytes([addrtype])
|
||||||
if addrtype == ADDRTYPE_P2WPKH:
|
|
||||||
s += bytes([witness_program_version]) + b'\x00'
|
|
||||||
s += h160
|
s += h160
|
||||||
return base_encode(s+Hash(s)[0:4], base=58)
|
return base_encode(s+Hash(s)[0:4], base=58)
|
||||||
|
|
||||||
|
@ -313,11 +313,14 @@ def hash160_to_p2sh(h160):
|
||||||
def public_key_to_p2pkh(public_key):
|
def public_key_to_p2pkh(public_key):
|
||||||
return hash160_to_p2pkh(hash_160(public_key))
|
return hash160_to_p2pkh(hash_160(public_key))
|
||||||
|
|
||||||
|
def hash160_to_segwit_addr(h160):
|
||||||
def public_key_to_p2wpkh(public_key):
|
return segwit_addr.encode(SEGWIT_HRP, 0, h160)
|
||||||
return hash160_to_b58_address(hash_160(public_key), ADDRTYPE_P2WPKH)
|
|
||||||
|
|
||||||
def address_to_script(addr):
|
def address_to_script(addr):
|
||||||
|
if is_segwit_address(addr):
|
||||||
|
witver, witprog = segwit_addr.decode(SEGWIT_HRP, addr)
|
||||||
|
script = bytes([witver]).hex() + push_script(bytes(witprog).hex())
|
||||||
|
return script
|
||||||
addrtype, hash_160 = b58_address_to_hash160(addr)
|
addrtype, hash_160 = b58_address_to_hash160(addr)
|
||||||
if addrtype == ADDRTYPE_P2PKH:
|
if addrtype == ADDRTYPE_P2PKH:
|
||||||
script = '76a9' # op_dup, op_hash_160
|
script = '76a9' # op_dup, op_hash_160
|
||||||
|
@ -476,7 +479,11 @@ def address_from_private_key(sec):
|
||||||
address = public_key_to_p2pkh(bfh(public_key))
|
address = public_key_to_p2pkh(bfh(public_key))
|
||||||
return address
|
return address
|
||||||
|
|
||||||
def is_address(addr):
|
def is_segwit_address(addr):
|
||||||
|
witver, witprog = segwit_addr.decode(SEGWIT_HRP, addr)
|
||||||
|
return witprog is not None
|
||||||
|
|
||||||
|
def is_b58_address(addr):
|
||||||
try:
|
try:
|
||||||
addrtype, h = b58_address_to_hash160(addr)
|
addrtype, h = b58_address_to_hash160(addr)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -485,6 +492,10 @@ def is_address(addr):
|
||||||
return False
|
return False
|
||||||
return addr == hash160_to_b58_address(h, addrtype)
|
return addr == hash160_to_b58_address(h, addrtype)
|
||||||
|
|
||||||
|
def is_address(addr):
|
||||||
|
return is_segwit_address(addr) or is_b58_address(addr)
|
||||||
|
|
||||||
|
|
||||||
def is_p2pkh(addr):
|
def is_p2pkh(addr):
|
||||||
if is_address(addr):
|
if is_address(addr):
|
||||||
addrtype, h = b58_address_to_hash160(addr)
|
addrtype, h = b58_address_to_hash160(addr)
|
||||||
|
|
|
@ -393,6 +393,11 @@ def get_address_from_output_script(_bytes):
|
||||||
if match_decoded(decoded, match):
|
if match_decoded(decoded, match):
|
||||||
return TYPE_ADDRESS, hash160_to_p2sh(decoded[1][1])
|
return TYPE_ADDRESS, hash160_to_p2sh(decoded[1][1])
|
||||||
|
|
||||||
|
# segwit address
|
||||||
|
match = [ opcodes.OP_0, opcodes.OP_PUSHDATA4 ]
|
||||||
|
if match_decoded(decoded, match):
|
||||||
|
return TYPE_ADDRESS, hash160_to_segwit_addr(decoded[1][1])
|
||||||
|
|
||||||
return TYPE_SCRIPT, bh2u(_bytes)
|
return TYPE_SCRIPT, bh2u(_bytes)
|
||||||
|
|
||||||
|
|
||||||
|
@ -584,7 +589,7 @@ class Transaction:
|
||||||
@classmethod
|
@classmethod
|
||||||
def pay_script(self, output_type, addr):
|
def pay_script(self, output_type, addr):
|
||||||
if output_type == TYPE_SCRIPT:
|
if output_type == TYPE_SCRIPT:
|
||||||
return bh2u(addr)
|
return addr
|
||||||
elif output_type == TYPE_ADDRESS:
|
elif output_type == TYPE_ADDRESS:
|
||||||
return bitcoin.address_to_script(addr)
|
return bitcoin.address_to_script(addr)
|
||||||
else:
|
else:
|
||||||
|
@ -835,7 +840,7 @@ class Transaction:
|
||||||
elif type == TYPE_PUBKEY:
|
elif type == TYPE_PUBKEY:
|
||||||
addr = bitcoin.public_key_to_p2pkh(bfh(x))
|
addr = bitcoin.public_key_to_p2pkh(bfh(x))
|
||||||
else:
|
else:
|
||||||
addr = 'SCRIPT ' + bh2u(x)
|
addr = 'SCRIPT ' + x
|
||||||
o.append((addr,v)) # consider using yield (addr, v)
|
o.append((addr,v)) # consider using yield (addr, v)
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue