Extend Wallet Import Format with txin type. Extend class Imported_Wallet.
This commit is contained in:
@@ -35,7 +35,7 @@ import pyaes
|
||||
|
||||
from .util import bfh, bh2u, to_string
|
||||
from . import version
|
||||
from .util import print_error, InvalidPassword, assert_bytes, to_bytes
|
||||
from .util import print_error, InvalidPassword, assert_bytes, to_bytes, inv_dict
|
||||
from . import segwit_addr
|
||||
|
||||
def read_json_dict(filename):
|
||||
@@ -65,7 +65,6 @@ XPUB_HEADERS = {
|
||||
|
||||
# Bitcoin network constants
|
||||
TESTNET = False
|
||||
NOLNET = False
|
||||
ADDRTYPE_P2PKH = 0
|
||||
ADDRTYPE_P2SH = 5
|
||||
SEGWIT_HRP = "bc"
|
||||
@@ -334,6 +333,30 @@ def script_to_p2wsh(script):
|
||||
return hash_to_segwit_addr(sha256(bfh(script)))
|
||||
|
||||
|
||||
def pubkey_to_address(txin_type, pubkey):
|
||||
if txin_type == 'p2pkh':
|
||||
return public_key_to_p2pkh(bfh(pubkey))
|
||||
elif txin_type == 'p2wpkh':
|
||||
return hash_to_segwit_addr(hash_160(bfh(pubkey)))
|
||||
elif txin_type == 'p2wpkh-p2sh':
|
||||
scriptSig = transaction.p2wpkh_nested_script(pubkey)
|
||||
return hash160_to_p2sh(hash_160(bfh(scriptSig)))
|
||||
else:
|
||||
raise NotImplementedError(txin_type)
|
||||
|
||||
def redeem_script_to_address(txin_type, redeem_script):
|
||||
if txin_type == 'p2sh':
|
||||
return hash160_to_p2sh(hash_160(bfh(redeem_script)))
|
||||
elif txin_type == 'p2wsh':
|
||||
return script_to_p2wsh(redeem_script)
|
||||
elif txin_type == 'p2wsh-p2sh':
|
||||
scriptSig = transaction.p2wsh_nested_script(redeem_script)
|
||||
return hash160_to_p2sh(hash_160(bfh(scriptSig)))
|
||||
else:
|
||||
raise NotImplementedError(txin_type)
|
||||
|
||||
|
||||
|
||||
def address_to_script(addr):
|
||||
witver, witprog = segwit_addr.decode(SEGWIT_HRP, addr)
|
||||
if witprog is not None:
|
||||
@@ -448,33 +471,42 @@ def DecodeBase58Check(psz):
|
||||
return key
|
||||
|
||||
|
||||
def PrivKeyToSecret(privkey):
|
||||
return privkey[9:9+32]
|
||||
|
||||
# extended key export format for segwit
|
||||
|
||||
SCRIPT_TYPES = {
|
||||
'p2pkh':0,
|
||||
'p2wpkh':1,
|
||||
'p2wpkh-p2sh':2,
|
||||
'p2sh':5,
|
||||
'p2wsh':6,
|
||||
'p2wsh-p2sh':7
|
||||
}
|
||||
|
||||
|
||||
def SecretToASecret(secret, compressed=False):
|
||||
addrtype = ADDRTYPE_P2PKH
|
||||
vchIn = bytes([(addrtype+128)&255]) + secret
|
||||
if compressed: vchIn += b'\01'
|
||||
def serialize_privkey(secret, compressed, txin_type):
|
||||
prefix = bytes([(SCRIPT_TYPES[txin_type]+128)&255])
|
||||
suffix = b'\01' if compressed else b''
|
||||
vchIn = prefix + secret + suffix
|
||||
return EncodeBase58Check(vchIn)
|
||||
|
||||
|
||||
def ASecretToSecret(key):
|
||||
addrtype = ADDRTYPE_P2PKH
|
||||
def deserialize_privkey(key):
|
||||
# whether the pubkey is compressed should be visible from the keystore
|
||||
vch = DecodeBase58Check(key)
|
||||
if vch and vch[0] == ((addrtype+128)&255):
|
||||
return vch[1:]
|
||||
elif is_minikey(key):
|
||||
return minikey_to_private_key(key)
|
||||
if is_minikey(key):
|
||||
return 'p2pkh', minikey_to_private_key(key), True
|
||||
elif vch:
|
||||
txin_type = inv_dict(SCRIPT_TYPES)[vch[0] - 128]
|
||||
assert len(vch) in [33, 34]
|
||||
compressed = len(vch) == 34
|
||||
return txin_type, vch[1:33], compressed
|
||||
else:
|
||||
return False
|
||||
|
||||
def regenerate_key(sec):
|
||||
b = ASecretToSecret(sec)
|
||||
if not b:
|
||||
return False
|
||||
b = b[0:32]
|
||||
return EC_KEY(b)
|
||||
def regenerate_key(pk):
|
||||
assert len(pk) == 32
|
||||
return EC_KEY(pk)
|
||||
|
||||
|
||||
def GetPubKey(pubkey, compressed=False):
|
||||
@@ -486,15 +518,12 @@ def GetSecret(pkey):
|
||||
|
||||
|
||||
def is_compressed(sec):
|
||||
b = ASecretToSecret(sec)
|
||||
return len(b) == 33
|
||||
return deserialize_privkey(sec)[2]
|
||||
|
||||
|
||||
def public_key_from_private_key(sec):
|
||||
def public_key_from_private_key(pk, compressed):
|
||||
# rebuild public key from private key, compressed or uncompressed
|
||||
pkey = regenerate_key(sec)
|
||||
assert pkey
|
||||
compressed = is_compressed(sec)
|
||||
pkey = regenerate_key(pk)
|
||||
public_key = GetPubKey(pkey.pubkey, compressed)
|
||||
return bh2u(public_key)
|
||||
|
||||
@@ -533,7 +562,7 @@ def is_p2sh(addr):
|
||||
|
||||
def is_private_key(key):
|
||||
try:
|
||||
k = ASecretToSecret(key)
|
||||
k = deserialize_privkey(key)
|
||||
return k is not False
|
||||
except:
|
||||
return False
|
||||
@@ -970,5 +999,4 @@ def bip32_public_derivation(xpub, branch, sequence):
|
||||
def bip32_private_key(sequence, k, chain):
|
||||
for i in sequence:
|
||||
k, chain = CKD_priv(k, chain, i)
|
||||
return SecretToASecret(k, True)
|
||||
|
||||
return k
|
||||
|
||||
Reference in New Issue
Block a user