assert remove

This commit is contained in:
4tochka 2019-03-14 14:47:14 +04:00
parent f266118981
commit 2432e59d2a
7 changed files with 74 additions and 83 deletions

View File

@ -113,6 +113,7 @@ class PublicKey():
public_key = private_to_public_key(key.key,
compressed=key.compressed,
hex=False)
#: public key in bytes (bytes)
self.key = public_key
#: public key in HEX (string)
@ -265,6 +266,6 @@ class ScriptAddress():
a = private_to_public_key(a)
if len(a) != 33:
raise TypeError("invalid public key list element size")
script += int_to_var_int(len(a)) + a
script += bytes([0x50 + m]) + OP_CHECKMULTISIG
script += b"%s%s" % (int_to_var_int(len(a)), a)
script += b"%s%s" % (bytes([0x50 + m]),OP_CHECKMULTISIG)
return cls(script, testnet=testnet, witness_version=witness_version)

View File

@ -1,5 +1,5 @@
from .transaction import Transaction
from struct import pack, unpack
from struct import unpack
from .functions import *
class Block(dict):

View File

@ -35,7 +35,7 @@ def hash_to_address(address_hash, testnet=False, script_hash=False, witness_vers
prefix = TESTNET_ADDRESS_BYTE_PREFIX
else:
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]
return encode_base58(address_hash)
else:
@ -47,7 +47,7 @@ def hash_to_address(address_hash, testnet=False, script_hash=False, witness_vers
prefix = TESTNET_SCRIPT_ADDRESS_BYTE_PREFIX
else:
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]
return encode_base58(address_hash)
@ -265,7 +265,7 @@ def is_address_valid(address, testnet=False):
d = rebase_32_to_5(payload)
address_hash = 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:]
if checksum != checksum2:
return False

View File

@ -13,7 +13,7 @@ from .address import hash_to_address
def public_key_to_pubkey_script(key, hex=True):
if isinstance(key, str):
key = bytes.from_hex(key)
key = bytes.fromhex(key)
s = b"%s%s%s" % (bytes([len(key)]), key, OP_CHECKSIG)
return s.hex() if hex else s
@ -218,7 +218,7 @@ def delete_from_script(script, sub_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.
:return: script in bytes or HEX encoded string corresponding to the format of target script.
"""

View File

@ -115,7 +115,7 @@ class Transaction(dict):
if sw:
self["segwit"] = True
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:
self["segwit"] = False
self["txId"] = double_sha256(b)
@ -125,7 +125,7 @@ class Transaction(dict):
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.
if None used type from transaction property "format".
@ -433,6 +433,8 @@ class Transaction(dict):
script = address_to_script(address)
elif type(address) in (Address, ScriptAddress):
script = address_to_script(address.address)
else:
raise TypeError("address invalid")
if script_pub_key:
if script_pub_key != script:
raise Exception("address not match script")
@ -478,12 +480,14 @@ class Transaction(dict):
if address is None and script_pub_key is None:
raise Exception("unable to add output, address or script required")
if type(amount) != int:
raise Exception("unable to add output, amount type error")
assert amount >= 0 and amount <= MAX_AMOUNT
raise TypeError("unable to add output, amount type error")
if amount < 0 or amount > MAX_AMOUNT:
raise Exception("unable to add output, amount value error")
if script_pub_key:
if type(script_pub_key) == str:
if isinstance(script_pub_key, str):
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:
if type(address) == Address:
address = address.address
@ -891,59 +895,54 @@ class Transaction(dict):
return r
def sig_hash(self, n, script_pub_key=None, sighash_type=SIGHASH_ALL, preimage=False):
# check n
assert n >= 0
tx_in_count = len(self["vIn"])
if n >= tx_in_count:
if self["format"] == "raw":
return b'\x01' + b'\x00' * 31
else:
return rh2s(b'\x01' + b'\x00' * 31)
try:
self["vIn"][n]
except:
raise Exception("sig_hash error, input not exist")
# check script_pub_key for input
if script_pub_key is not None:
script_code = script_pub_key
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"]
if type(script_code) == str:
if isinstance(script_code, str):
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
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 self["format"] == "raw":
return b'\x01' + b'\x00' * 31
else:
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)
return b'\x01%s' % (b'\x00' * 31)
return rh2s(b'\x01%s' % (b'\x00' * 31))
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"]:
# skip all other inputs for SIGHASH_ANYONECANPAY case
if (sighash_type & SIGHASH_ANYONECANPAY) and (n != i):
continue
sequence = self["vIn"][i]["sequence"]
if (sighash_type & 31) == SIGHASH_SINGLE and (n != i):
sequence = 0
if (sighash_type & 31) == SIGHASH_NONE and (n != i):
if ((sighash_type & 31) == SIGHASH_SINGLE or (sighash_type & 31) == SIGHASH_NONE) and (n != i):
sequence = 0
tx_id = self["vIn"][i]["txId"]
if type(tx_id) == str:
if isinstance(tx_id, str):
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:
pm += b'\x00'
else:
@ -955,42 +954,38 @@ class Transaction(dict):
if (sighash_type & 31) != SIGHASH_NONE:
for i in self["vOut"]:
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)
if i > n and (sighash_type & 31) == SIGHASH_SINGLE:
continue
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:
pm += self["vOut"][i]["value"].to_bytes(8, 'little')
pm += int_to_var_int(len(script_pub_key)) + script_pub_key
pm += self["lockTime"].to_bytes(4, 'little')
pm += struct.pack(b"<i", sighash_type)
pm += b"%s%s%s" % (self["vOut"][i]["value"].to_bytes(8, 'little'),
int_to_var_int(len(script_pub_key)),
script_pub_key)
pm += b"%s%s" % (self["lockTime"].to_bytes(4, 'little'), struct.pack(b"<i", sighash_type))
if not preimage:
pm = double_sha256(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):
# check n
assert n >= 0
tx_in_count = len(self["vIn"])
if n >= tx_in_count:
if self["format"] == "raw":
return b'\x01' + b'\x00' * 31
else:
return rh2s(b'\x01' + b'\x00' * 31)
try:
self["vIn"][n]
except:
raise Exception("sig_hash error, input not exist")
# check script_pub_key for input
if script_pub_key is not None:
script_code = script_pub_key
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"]
if type(script_code) == str:
if isinstance(script_code, str):
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
pm = bytearray()
@ -1009,11 +1004,11 @@ class Transaction(dict):
if type(tx_id) == str:
tx_id = s2rh(tx_id)
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:
hs += struct.pack('<L', self["vIn"][i]["sequence"])
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"])
hash_prevouts = double_sha256(hp) if hp 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:
script_pub_key = bytes.fromhex(script_pub_key)
if (sighash_type & 31) != SIGHASH_SINGLE and (sighash_type & 31) != SIGHASH_NONE:
ho += self["vOut"][o]["value"].to_bytes(8, 'little')
ho += int_to_var_int(len(script_pub_key)) + script_pub_key
ho += b"%s%s%s" % (self["vOut"][o]["value"].to_bytes(8, 'little'),
int_to_var_int(len(script_pub_key)),
script_pub_key)
elif (sighash_type & 31) == SIGHASH_SINGLE and n < len(self["vOut"]):
if o == n:
ho += self["vOut"][o]["value"].to_bytes(8, 'little')
ho += int_to_var_int(len(script_pub_key)) + script_pub_key
ho += b"%s%s%s" % (self["vOut"][o]["value"].to_bytes(8, 'little'),
int_to_var_int(len(script_pub_key)),
script_pub_key)
hash_outputs = double_sha256(ho) if ho else b'\x00' * 32
pm += hash_prevouts + hash_sequence + outpoint
pm += script_code + value + n_sequence + hash_outputs
pm += struct.pack('<L', self["lockTime"])
pm += struct.pack('<L', sighash_type)
pm += b"%s%s%s%s%s%s%s%s%s" % (hash_prevouts, hash_sequence, outpoint,
script_code, value, n_sequence, hash_outputs,
struct.pack('<L', self["lockTime"]),
struct.pack('<L', sighash_type))
if not preimage:
pm = double_sha256(pm)
return pm if self["format"] == "raw" else pm.hex()

View File

@ -1,11 +1,4 @@
import os
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 struct import unpack
from .functions import *