assert remove
This commit is contained in:
parent
f266118981
commit
2432e59d2a
@ -113,6 +113,7 @@ class PublicKey():
|
|||||||
public_key = private_to_public_key(key.key,
|
public_key = private_to_public_key(key.key,
|
||||||
compressed=key.compressed,
|
compressed=key.compressed,
|
||||||
hex=False)
|
hex=False)
|
||||||
|
|
||||||
#: public key in bytes (bytes)
|
#: public key in bytes (bytes)
|
||||||
self.key = public_key
|
self.key = public_key
|
||||||
#: public key in HEX (string)
|
#: public key in HEX (string)
|
||||||
@ -265,6 +266,6 @@ class ScriptAddress():
|
|||||||
a = private_to_public_key(a)
|
a = private_to_public_key(a)
|
||||||
if len(a) != 33:
|
if len(a) != 33:
|
||||||
raise TypeError("invalid public key list element size")
|
raise TypeError("invalid public key list element size")
|
||||||
script += int_to_var_int(len(a)) + a
|
script += b"%s%s" % (int_to_var_int(len(a)), a)
|
||||||
script += bytes([0x50 + m]) + OP_CHECKMULTISIG
|
script += b"%s%s" % (bytes([0x50 + m]),OP_CHECKMULTISIG)
|
||||||
return cls(script, testnet=testnet, witness_version=witness_version)
|
return cls(script, testnet=testnet, witness_version=witness_version)
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
from .transaction import Transaction
|
from .transaction import Transaction
|
||||||
from struct import pack, unpack
|
from struct import unpack
|
||||||
from .functions import *
|
from .functions import *
|
||||||
|
|
||||||
class Block(dict):
|
class Block(dict):
|
||||||
|
|||||||
@ -35,7 +35,7 @@ def hash_to_address(address_hash, testnet=False, script_hash=False, witness_vers
|
|||||||
prefix = TESTNET_ADDRESS_BYTE_PREFIX
|
prefix = TESTNET_ADDRESS_BYTE_PREFIX
|
||||||
else:
|
else:
|
||||||
prefix = MAINNET_ADDRESS_BYTE_PREFIX
|
prefix = MAINNET_ADDRESS_BYTE_PREFIX
|
||||||
address_hash = prefix + address_hash
|
address_hash = b"%s%s" % (prefix, address_hash)
|
||||||
address_hash += double_sha256(address_hash)[:4]
|
address_hash += double_sha256(address_hash)[:4]
|
||||||
return encode_base58(address_hash)
|
return encode_base58(address_hash)
|
||||||
else:
|
else:
|
||||||
@ -47,7 +47,7 @@ def hash_to_address(address_hash, testnet=False, script_hash=False, witness_vers
|
|||||||
prefix = TESTNET_SCRIPT_ADDRESS_BYTE_PREFIX
|
prefix = TESTNET_SCRIPT_ADDRESS_BYTE_PREFIX
|
||||||
else:
|
else:
|
||||||
prefix = MAINNET_SCRIPT_ADDRESS_BYTE_PREFIX
|
prefix = MAINNET_SCRIPT_ADDRESS_BYTE_PREFIX
|
||||||
address_hash = prefix + address_hash
|
address_hash = b"%s%s" % (prefix, address_hash)
|
||||||
address_hash += double_sha256(address_hash)[:4]
|
address_hash += double_sha256(address_hash)[:4]
|
||||||
return encode_base58(address_hash)
|
return encode_base58(address_hash)
|
||||||
|
|
||||||
@ -265,7 +265,7 @@ def is_address_valid(address, testnet=False):
|
|||||||
d = rebase_32_to_5(payload)
|
d = rebase_32_to_5(payload)
|
||||||
address_hash = d[:-6]
|
address_hash = d[:-6]
|
||||||
checksum = d[-6:]
|
checksum = d[-6:]
|
||||||
checksum2 = bech32_polymod(stripped_prefix + address_hash + b"\x00" * 6)
|
checksum2 = bech32_polymod(b"%s%s%s" % (stripped_prefix, address_hash, b"\x00" * 6))
|
||||||
checksum2 = rebase_8_to_5(checksum2.to_bytes(5, "big"))[2:]
|
checksum2 = rebase_8_to_5(checksum2.to_bytes(5, "big"))[2:]
|
||||||
if checksum != checksum2:
|
if checksum != checksum2:
|
||||||
return False
|
return False
|
||||||
|
|||||||
@ -13,7 +13,7 @@ from .address import hash_to_address
|
|||||||
|
|
||||||
def public_key_to_pubkey_script(key, hex=True):
|
def public_key_to_pubkey_script(key, hex=True):
|
||||||
if isinstance(key, str):
|
if isinstance(key, str):
|
||||||
key = bytes.from_hex(key)
|
key = bytes.fromhex(key)
|
||||||
s = b"%s%s%s" % (bytes([len(key)]), key, OP_CHECKSIG)
|
s = b"%s%s%s" % (bytes([len(key)]), key, OP_CHECKSIG)
|
||||||
return s.hex() if hex else s
|
return s.hex() if hex else s
|
||||||
|
|
||||||
@ -218,7 +218,7 @@ def delete_from_script(script, sub_script):
|
|||||||
"""
|
"""
|
||||||
Decode OPCODE or subscript from script.
|
Decode OPCODE or subscript from script.
|
||||||
|
|
||||||
:param script: traget script in bytes or HEX encoded string.
|
:param script: target script in bytes or HEX encoded string.
|
||||||
:param sub_script: sub_script which is necessary to remove from target script in bytes or HEX encoded string.
|
:param sub_script: sub_script which is necessary to remove from target script in bytes or HEX encoded string.
|
||||||
:return: script in bytes or HEX encoded string corresponding to the format of target script.
|
:return: script in bytes or HEX encoded string corresponding to the format of target script.
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -115,7 +115,7 @@ class Transaction(dict):
|
|||||||
if sw:
|
if sw:
|
||||||
self["segwit"] = True
|
self["segwit"] = True
|
||||||
self["hash"] = double_sha256(b)
|
self["hash"] = double_sha256(b)
|
||||||
self["txId"] = double_sha256(b[:4] + b[6:sw] + b[-4:])
|
self["txId"] = double_sha256(b"%s%s%s" % (b[:4], b[6:sw],b[-4:]))
|
||||||
else:
|
else:
|
||||||
self["segwit"] = False
|
self["segwit"] = False
|
||||||
self["txId"] = double_sha256(b)
|
self["txId"] = double_sha256(b)
|
||||||
@ -125,7 +125,7 @@ class Transaction(dict):
|
|||||||
|
|
||||||
def decode(self, testnet=None):
|
def decode(self, testnet=None):
|
||||||
"""
|
"""
|
||||||
change Transacion object representation to "decoded" human readable format
|
change Transaction object representation to "decoded" human readable format
|
||||||
|
|
||||||
:param bool testnet: (optional) address type for "decoded" transaction representation, by default None.
|
:param bool testnet: (optional) address type for "decoded" transaction representation, by default None.
|
||||||
if None used type from transaction property "format".
|
if None used type from transaction property "format".
|
||||||
@ -433,6 +433,8 @@ class Transaction(dict):
|
|||||||
script = address_to_script(address)
|
script = address_to_script(address)
|
||||||
elif type(address) in (Address, ScriptAddress):
|
elif type(address) in (Address, ScriptAddress):
|
||||||
script = address_to_script(address.address)
|
script = address_to_script(address.address)
|
||||||
|
else:
|
||||||
|
raise TypeError("address invalid")
|
||||||
if script_pub_key:
|
if script_pub_key:
|
||||||
if script_pub_key != script:
|
if script_pub_key != script:
|
||||||
raise Exception("address not match script")
|
raise Exception("address not match script")
|
||||||
@ -478,12 +480,14 @@ class Transaction(dict):
|
|||||||
if address is None and script_pub_key is None:
|
if address is None and script_pub_key is None:
|
||||||
raise Exception("unable to add output, address or script required")
|
raise Exception("unable to add output, address or script required")
|
||||||
if type(amount) != int:
|
if type(amount) != int:
|
||||||
raise Exception("unable to add output, amount type error")
|
raise TypeError("unable to add output, amount type error")
|
||||||
assert amount >= 0 and amount <= MAX_AMOUNT
|
if amount < 0 or amount > MAX_AMOUNT:
|
||||||
|
raise Exception("unable to add output, amount value error")
|
||||||
if script_pub_key:
|
if script_pub_key:
|
||||||
if type(script_pub_key) == str:
|
if isinstance(script_pub_key, str):
|
||||||
script_pub_key = bytes.fromhex(script_pub_key)
|
script_pub_key = bytes.fromhex(script_pub_key)
|
||||||
assert type(script_pub_key) == bytes
|
if not isinstance(script_pub_key, bytes):
|
||||||
|
raise TypeError("unable to add output, script_pub_key type error")
|
||||||
else:
|
else:
|
||||||
if type(address) == Address:
|
if type(address) == Address:
|
||||||
address = address.address
|
address = address.address
|
||||||
@ -891,59 +895,54 @@ class Transaction(dict):
|
|||||||
return r
|
return r
|
||||||
|
|
||||||
def sig_hash(self, n, script_pub_key=None, sighash_type=SIGHASH_ALL, preimage=False):
|
def sig_hash(self, n, script_pub_key=None, sighash_type=SIGHASH_ALL, preimage=False):
|
||||||
# check n
|
try:
|
||||||
assert n >= 0
|
self["vIn"][n]
|
||||||
tx_in_count = len(self["vIn"])
|
except:
|
||||||
|
raise Exception("sig_hash error, input not exist")
|
||||||
if n >= tx_in_count:
|
|
||||||
if self["format"] == "raw":
|
|
||||||
return b'\x01' + b'\x00' * 31
|
|
||||||
else:
|
|
||||||
return rh2s(b'\x01' + b'\x00' * 31)
|
|
||||||
|
|
||||||
# check script_pub_key for input
|
# check script_pub_key for input
|
||||||
if script_pub_key is not None:
|
if script_pub_key is not None:
|
||||||
script_code = script_pub_key
|
script_code = script_pub_key
|
||||||
else:
|
else:
|
||||||
assert "scriptPubKey" in self["vIn"][n]
|
if "scriptPubKey" not in self["vIn"][n]:
|
||||||
|
raise Exception("sig_hash error, scriptPubKey required")
|
||||||
script_code = self["vIn"][n]["scriptPubKey"]
|
script_code = self["vIn"][n]["scriptPubKey"]
|
||||||
if type(script_code) == str:
|
if isinstance(script_code, str):
|
||||||
script_code = bytes.fromhex(script_code)
|
script_code = bytes.fromhex(script_code)
|
||||||
assert type(script_code) == bytes
|
if not isinstance(script_code,bytes):
|
||||||
|
raise Exception("sig_hash error, script_code type error")
|
||||||
|
|
||||||
# remove opcode separators
|
# remove opcode separators
|
||||||
script_code = delete_from_script(script_code, BYTE_OPCODE["OP_CODESEPARATOR"])
|
|
||||||
pm = bytearray()
|
|
||||||
|
|
||||||
if ((sighash_type & 31) == SIGHASH_SINGLE) and (n >= (len(self["vOut"]))):
|
if ((sighash_type & 31) == SIGHASH_SINGLE) and (n >= (len(self["vOut"]))):
|
||||||
if self["format"] == "raw":
|
if self["format"] == "raw":
|
||||||
return b'\x01' + b'\x00' * 31
|
return b'\x01%s' % (b'\x00' * 31)
|
||||||
else:
|
return rh2s(b'\x01%s' % (b'\x00' * 31))
|
||||||
return rh2s(b'\x01' + b'\x00' * 31)
|
|
||||||
|
|
||||||
pm += struct.pack('<L', self["version"])
|
|
||||||
pm += b'\x01' if sighash_type & SIGHASH_ANYONECANPAY else int_to_var_int(tx_in_count)
|
|
||||||
|
|
||||||
|
script_code = delete_from_script(script_code, BYTE_OPCODE["OP_CODESEPARATOR"])
|
||||||
|
pm = bytearray()
|
||||||
|
pm += b"%s%s" % (struct.pack('<L', self["version"]),
|
||||||
|
b'\x01' if sighash_type & SIGHASH_ANYONECANPAY else int_to_var_int(len(self["vIn"])))
|
||||||
for i in self["vIn"]:
|
for i in self["vIn"]:
|
||||||
# skip all other inputs for SIGHASH_ANYONECANPAY case
|
# skip all other inputs for SIGHASH_ANYONECANPAY case
|
||||||
if (sighash_type & SIGHASH_ANYONECANPAY) and (n != i):
|
if (sighash_type & SIGHASH_ANYONECANPAY) and (n != i):
|
||||||
continue
|
continue
|
||||||
sequence = self["vIn"][i]["sequence"]
|
sequence = self["vIn"][i]["sequence"]
|
||||||
if (sighash_type & 31) == SIGHASH_SINGLE and (n != i):
|
if ((sighash_type & 31) == SIGHASH_SINGLE or (sighash_type & 31) == SIGHASH_NONE) and (n != i):
|
||||||
sequence = 0
|
|
||||||
if (sighash_type & 31) == SIGHASH_NONE and (n != i):
|
|
||||||
sequence = 0
|
sequence = 0
|
||||||
tx_id = self["vIn"][i]["txId"]
|
tx_id = self["vIn"][i]["txId"]
|
||||||
if type(tx_id) == str:
|
if isinstance(tx_id, str):
|
||||||
tx_id = s2rh(tx_id)
|
tx_id = s2rh(tx_id)
|
||||||
input = tx_id + struct.pack('<L', self["vIn"][i]["vOut"])
|
|
||||||
if n == i:
|
|
||||||
input += int_to_var_int(len(script_code)) + script_code
|
|
||||||
input += struct.pack('<L', sequence)
|
|
||||||
else:
|
|
||||||
input += b'\x00' + struct.pack('<L', sequence)
|
|
||||||
pm += input
|
|
||||||
|
|
||||||
|
if n == i:
|
||||||
|
pm += b"%s%s%s%s%s" % (tx_id,
|
||||||
|
struct.pack('<L', self["vIn"][i]["vOut"]),
|
||||||
|
int_to_var_int(len(script_code)),
|
||||||
|
script_code,
|
||||||
|
struct.pack('<L', sequence))
|
||||||
|
else:
|
||||||
|
pm += b'%s%s\x00%s' % (tx_id,
|
||||||
|
struct.pack('<L', self["vIn"][i]["vOut"]),
|
||||||
|
struct.pack('<L', sequence))
|
||||||
if (sighash_type & 31) == SIGHASH_NONE:
|
if (sighash_type & 31) == SIGHASH_NONE:
|
||||||
pm += b'\x00'
|
pm += b'\x00'
|
||||||
else:
|
else:
|
||||||
@ -955,42 +954,38 @@ class Transaction(dict):
|
|||||||
if (sighash_type & 31) != SIGHASH_NONE:
|
if (sighash_type & 31) != SIGHASH_NONE:
|
||||||
for i in self["vOut"]:
|
for i in self["vOut"]:
|
||||||
script_pub_key = self["vOut"][i]["scriptPubKey"]
|
script_pub_key = self["vOut"][i]["scriptPubKey"]
|
||||||
if type(self["vOut"][i]["scriptPubKey"]) == str:
|
if isinstance(self["vOut"][i]["scriptPubKey"], str):
|
||||||
script_pub_key = bytes.fromhex(script_pub_key)
|
script_pub_key = bytes.fromhex(script_pub_key)
|
||||||
if i > n and (sighash_type & 31) == SIGHASH_SINGLE:
|
if i > n and (sighash_type & 31) == SIGHASH_SINGLE:
|
||||||
continue
|
continue
|
||||||
if (sighash_type & 31) == SIGHASH_SINGLE and (n != i):
|
if (sighash_type & 31) == SIGHASH_SINGLE and (n != i):
|
||||||
pm += b'\xff' * 8 + b'\x00'
|
pm += b"%s%s" % (b'\xff' * 8, b'\x00')
|
||||||
else:
|
else:
|
||||||
pm += self["vOut"][i]["value"].to_bytes(8, 'little')
|
pm += b"%s%s%s" % (self["vOut"][i]["value"].to_bytes(8, 'little'),
|
||||||
pm += int_to_var_int(len(script_pub_key)) + script_pub_key
|
int_to_var_int(len(script_pub_key)),
|
||||||
|
script_pub_key)
|
||||||
pm += self["lockTime"].to_bytes(4, 'little')
|
pm += b"%s%s" % (self["lockTime"].to_bytes(4, 'little'), struct.pack(b"<i", sighash_type))
|
||||||
pm += struct.pack(b"<i", sighash_type)
|
|
||||||
if not preimage:
|
if not preimage:
|
||||||
pm = double_sha256(pm)
|
pm = double_sha256(pm)
|
||||||
return pm if self["format"] == "raw" else rh2s(pm)
|
return pm if self["format"] == "raw" else rh2s(pm)
|
||||||
|
|
||||||
def sig_hash_segwit(self, n, amount, script_pub_key=None, sighash_type=SIGHASH_ALL, preimage=False):
|
def sig_hash_segwit(self, n, amount, script_pub_key=None, sighash_type=SIGHASH_ALL, preimage=False):
|
||||||
# check n
|
try:
|
||||||
assert n >= 0
|
self["vIn"][n]
|
||||||
tx_in_count = len(self["vIn"])
|
except:
|
||||||
|
raise Exception("sig_hash error, input not exist")
|
||||||
if n >= tx_in_count:
|
|
||||||
if self["format"] == "raw":
|
|
||||||
return b'\x01' + b'\x00' * 31
|
|
||||||
else:
|
|
||||||
return rh2s(b'\x01' + b'\x00' * 31)
|
|
||||||
|
|
||||||
# check script_pub_key for input
|
# check script_pub_key for input
|
||||||
if script_pub_key is not None:
|
if script_pub_key is not None:
|
||||||
script_code = script_pub_key
|
script_code = script_pub_key
|
||||||
else:
|
else:
|
||||||
assert "scriptPubKey" in self["vIn"][n]
|
if "scriptPubKey" not in self["vIn"][n]:
|
||||||
|
raise Exception("sig_hash error, scriptPubKey required")
|
||||||
script_code = self["vIn"][n]["scriptPubKey"]
|
script_code = self["vIn"][n]["scriptPubKey"]
|
||||||
if type(script_code) == str:
|
if isinstance(script_code, str):
|
||||||
script_code = bytes.fromhex(script_code)
|
script_code = bytes.fromhex(script_code)
|
||||||
assert type(script_code) == bytes
|
if not isinstance(script_code,bytes):
|
||||||
|
raise Exception("sig_hash error, script_code type error")
|
||||||
|
|
||||||
# remove opcode separators
|
# remove opcode separators
|
||||||
pm = bytearray()
|
pm = bytearray()
|
||||||
@ -1009,11 +1004,11 @@ class Transaction(dict):
|
|||||||
if type(tx_id) == str:
|
if type(tx_id) == str:
|
||||||
tx_id = s2rh(tx_id)
|
tx_id = s2rh(tx_id)
|
||||||
if not (sighash_type & SIGHASH_ANYONECANPAY):
|
if not (sighash_type & SIGHASH_ANYONECANPAY):
|
||||||
hp += tx_id + struct.pack('<L', self["vIn"][i]["vOut"])
|
hp += b"%s%s" % (tx_id, struct.pack('<L', self["vIn"][i]["vOut"]))
|
||||||
if (sighash_type & 31) != SIGHASH_SINGLE and (sighash_type & 31) != SIGHASH_NONE:
|
if (sighash_type & 31) != SIGHASH_SINGLE and (sighash_type & 31) != SIGHASH_NONE:
|
||||||
hs += struct.pack('<L', self["vIn"][i]["sequence"])
|
hs += struct.pack('<L', self["vIn"][i]["sequence"])
|
||||||
if i == n:
|
if i == n:
|
||||||
outpoint = tx_id + struct.pack('<L', self["vIn"][i]["vOut"])
|
outpoint = b"%s%s" % (tx_id, struct.pack('<L', self["vIn"][i]["vOut"]))
|
||||||
n_sequence = struct.pack('<L', self["vIn"][i]["sequence"])
|
n_sequence = struct.pack('<L', self["vIn"][i]["sequence"])
|
||||||
hash_prevouts = double_sha256(hp) if hp else b'\x00' * 32
|
hash_prevouts = double_sha256(hp) if hp else b'\x00' * 32
|
||||||
hash_sequence = double_sha256(hs) if hs else b'\x00' * 32
|
hash_sequence = double_sha256(hs) if hs else b'\x00' * 32
|
||||||
@ -1025,17 +1020,19 @@ class Transaction(dict):
|
|||||||
if type(self["vOut"][o]["scriptPubKey"]) == str:
|
if type(self["vOut"][o]["scriptPubKey"]) == str:
|
||||||
script_pub_key = bytes.fromhex(script_pub_key)
|
script_pub_key = bytes.fromhex(script_pub_key)
|
||||||
if (sighash_type & 31) != SIGHASH_SINGLE and (sighash_type & 31) != SIGHASH_NONE:
|
if (sighash_type & 31) != SIGHASH_SINGLE and (sighash_type & 31) != SIGHASH_NONE:
|
||||||
ho += self["vOut"][o]["value"].to_bytes(8, 'little')
|
ho += b"%s%s%s" % (self["vOut"][o]["value"].to_bytes(8, 'little'),
|
||||||
ho += int_to_var_int(len(script_pub_key)) + script_pub_key
|
int_to_var_int(len(script_pub_key)),
|
||||||
|
script_pub_key)
|
||||||
elif (sighash_type & 31) == SIGHASH_SINGLE and n < len(self["vOut"]):
|
elif (sighash_type & 31) == SIGHASH_SINGLE and n < len(self["vOut"]):
|
||||||
if o == n:
|
if o == n:
|
||||||
ho += self["vOut"][o]["value"].to_bytes(8, 'little')
|
ho += b"%s%s%s" % (self["vOut"][o]["value"].to_bytes(8, 'little'),
|
||||||
ho += int_to_var_int(len(script_pub_key)) + script_pub_key
|
int_to_var_int(len(script_pub_key)),
|
||||||
|
script_pub_key)
|
||||||
hash_outputs = double_sha256(ho) if ho else b'\x00' * 32
|
hash_outputs = double_sha256(ho) if ho else b'\x00' * 32
|
||||||
pm += hash_prevouts + hash_sequence + outpoint
|
pm += b"%s%s%s%s%s%s%s%s%s" % (hash_prevouts, hash_sequence, outpoint,
|
||||||
pm += script_code + value + n_sequence + hash_outputs
|
script_code, value, n_sequence, hash_outputs,
|
||||||
pm += struct.pack('<L', self["lockTime"])
|
struct.pack('<L', self["lockTime"]),
|
||||||
pm += struct.pack('<L', sighash_type)
|
struct.pack('<L', sighash_type))
|
||||||
if not preimage:
|
if not preimage:
|
||||||
pm = double_sha256(pm)
|
pm = double_sha256(pm)
|
||||||
return pm if self["format"] == "raw" else pm.hex()
|
return pm if self["format"] == "raw" else pm.hex()
|
||||||
|
|||||||
@ -1,11 +1,4 @@
|
|||||||
import os
|
from struct import unpack
|
||||||
import hmac
|
|
||||||
|
|
||||||
from secp256k1 import ffi
|
|
||||||
from struct import pack, unpack
|
|
||||||
from hashlib import pbkdf2_hmac
|
|
||||||
from binascii import hexlify, unhexlify
|
|
||||||
from .constants import *
|
|
||||||
from .functions import *
|
from .functions import *
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user