diff --git a/pybtc/address.py b/pybtc/address.py index 0828877..2f46a43 100644 --- a/pybtc/address.py +++ b/pybtc/address.py @@ -19,7 +19,7 @@ class PrivateKey(): self.testnet = testnet return assert type(key) == str - self.raw_key = WIF_to_private_key(key) + self.raw_key = wif_to_private_key(key) if key[0] in (MAINNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX, TESTNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX): self.compressed = False @@ -39,7 +39,7 @@ class PrivateKey(): compressed = self.compressed if testnet is None: testnet = self.testnet - return private_key_to_WIF(self.raw_key, compressed, testnet) + return private_key_to_wif(self.raw_key, compressed, testnet) class PublicKey(): @@ -95,7 +95,7 @@ class Address(): if address_type == "P2SH_P2WPKH": self.script_hash = True - self.redeem_script = public_key_to_P2SH_P2WPKH_script(self.public_key.raw_key) + self.redeem_script = public_key_to_p2sh_p2wpkh_script(self.public_key.raw_key) self.redeem_script_hex = hexlify(self.redeem_script).decode() self.hash = hash160(self.redeem_script) else: diff --git a/pybtc/blockchain.py b/pybtc/blockchain.py index c52f211..8f6fbd4 100644 --- a/pybtc/blockchain.py +++ b/pybtc/blockchain.py @@ -196,7 +196,7 @@ class OLDTransaction(): def sign_P2SHP2WPKH_input(self, sighash_type, input_index, private_key = None, amount = None): if type(private_key) == str: - private_key = WIF_to_private_key(private_key) + private_key = wif_to_private_key(private_key) if amount is not None: self.tx_in[input_index].amount = amount else: diff --git a/pybtc/constants.py b/pybtc/constants.py index cdc508f..352906c 100644 --- a/pybtc/constants.py +++ b/pybtc/constants.py @@ -1,5 +1,4 @@ from secp256k1 import lib as secp256k1 -from secp256k1 import ffi import random SIGHASH_ALL = 0x00000001 diff --git a/pybtc/tools.py b/pybtc/tools.py index dbed6bd..7993637 100644 --- a/pybtc/tools.py +++ b/pybtc/tools.py @@ -1,5 +1,6 @@ import time import struct +from secp256k1 import ffi from .constants import * from .opcodes import * from .hash import * @@ -14,22 +15,24 @@ def create_private_key(hex=False): """ :return: 32 bytes private key """ - a = random.SystemRandom().randint(0,MAX_INT_PRIVATE_KEY) - i = int((time.time()%0.01)*100000) - h = a.to_bytes(32,byteorder="big") + a = random.SystemRandom().randint(0, MAX_INT_PRIVATE_KEY) + i = int((time.time() % 0.01)*100000) + h = a.to_bytes(32, byteorder="big") while True: h = hashlib.sha256(h).digest() - if i>1: i -= 1 + if i > 1: + i -= 1 else: - if int.from_bytes(h,byteorder="big") 73): @@ -512,41 +523,41 @@ def is_valid_signature_encoding(sig): if sig[1] != (length - 3): return False # Extract the length of the R element. - lenR = sig[3] + len_r = sig[3] # Make sure the length of the S element is still inside the signature. - if (5 + lenR) >= length: + if (5 + len_r) >= length: return False # Extract the length of the S element. - lenS = sig[5 + lenR] + len_s = sig[5 + len_r] # Verify that the length of the signature matches the sum of the length # of the elements. - if (lenR + lenS + 7) != length: + if (len_r + len_s + 7) != length: return False # Check whether the R element is an integer. if sig[2] != 0x02: return False # Zero-length integers are not allowed for R. - if lenR == 0: + if len_r == 0: return False # Negative numbers are not allowed for R. if sig[4] & 0x80: return False # Null bytes at the start of R are not allowed, unless R would # otherwise be interpreted as a negative number. - if (lenR > 1) and (sig[4] == 0x00) and (not sig[5] & 0x80): + if (len_r > 1) and (sig[4] == 0x00) and (not sig[5] & 0x80): return False # Check whether the S element is an integer. - if sig[lenR + 4] != 0x02: + if sig[len_r + 4] != 0x02: return False # Zero-length integers are not allowed for S. - if lenS == 0: + if len_s == 0: return False # Negative numbers are not allowed for S. - if sig[lenR + 6] & 0x80: + if sig[len_r + 6] & 0x80: return False # Null bytes at the start of S are not allowed, unless S would otherwise be # interpreted as a negative number. - if (lenS > 1) and (sig[lenR + 6] == 0x00) and (not sig[lenR + 7] & 0x80): + if (len_s > 1) and (sig[len_r + 6] == 0x00) and (not sig[len_r + 7] & 0x80): return False return True @@ -556,15 +567,20 @@ def is_valid_signature_encoding(sig): # def rh2s(tthash): + # raw hash to string return hexlify(tthash[::-1]).decode() + def s2rh(hash_string): + # string to raw hash return unhexlify(hash_string)[::-1] + def s2rh_step4(hash_string): h = unhexlify(hash_string) return reverse_hash(h) + def reverse_hash(h): return struct.pack('>IIIIIIII', *struct.unpack('>IIIIIIII', h)[::-1])[::-1] @@ -572,6 +588,7 @@ def reverse_hash(h): # # + def merkleroot(tx_hash_list): tx_hash_list = list(tx_hash_list) if len(tx_hash_list) == 1: @@ -590,6 +607,7 @@ def merkleroot(tx_hash_list): else: return new_hash_list[0] + def merkle_branches(tx_hash_list): tx_hash_list = list(tx_hash_list) branches = [] @@ -613,6 +631,7 @@ def merkle_branches(tx_hash_list): branches.append(new_hash_list.pop(0)) return branches + def merkleroot_from_branches(merkle_branches, coinbase_hash_bin): merkle_root = coinbase_hash_bin for h in merkle_branches: @@ -621,6 +640,7 @@ def merkleroot_from_branches(merkle_branches, coinbase_hash_bin): merkle_root = double_sha256(merkle_root + h) return merkle_root + def bits_to_target(bits): if type(bits) == str: bits = unhexlify(bits) @@ -631,12 +651,15 @@ def bits_to_target(bits): target = (bits & 0xffffff) * (1 << (8 * (shift - 3))) return target + def target_to_difficulty(target): return 0x00000000FFFF0000000000000000000000000000000000000000000000000000 / target + def bits_to_difficulty(bits): return target_to_difficulty(bits_to_target(bits)) + def difficulty_to_target(difficulty): return int(0x00000000FFFF0000000000000000000000000000000000000000000000000000 / difficulty) @@ -647,12 +670,14 @@ def difficulty_to_target(difficulty): def bytes_needed(n): if n == 0: - return 1 + return 1 return math.ceil(n.bit_length()/8) + def int_to_bytes(i, byteorder='big'): return i.to_bytes(bytes_needed(i), byteorder=byteorder, signed=False) + def bytes_to_int(i, byteorder='big'): return int.from_bytes(i, byteorder=byteorder, signed=False) @@ -668,6 +693,7 @@ def int_to_var_int(i): return b'\xfe' + struct.pack(' 0: have_ext = (v.bit_length() & 0x07) == 0 - neg = False if v < 0: neg = True v = -v - s = struct.pack(b">I", bn_bytes(v, have_ext)) ext = bytearray() if have_ext: @@ -816,7 +843,6 @@ def mpi2bn(s): return None if v_len == 0: return 0 - v_str = bytearray(s[4:]) neg = False i = v_str[0] @@ -824,7 +850,6 @@ def mpi2bn(s): neg = True i &= ~0x80 v_str[0] = i - v = bin2bn(v_str) if neg: @@ -861,6 +886,7 @@ def i2b(i): return bn2vch(i) def b2i(b): return vch2bn(b) + def get_stream(stream): if type(stream) != io.BytesIO: if type(stream) == str: diff --git a/tests/test/address_functions.py b/tests/test/address_functions.py index f7730d5..8b4ab53 100644 --- a/tests/test/address_functions.py +++ b/tests/test/address_functions.py @@ -20,36 +20,36 @@ class AddressFunctionsTests(unittest.TestCase): pum = "5KPPLXhtga99qqMceRo4Z6LXV3Kx6a9hRx3ez2U7EwP5KZfy2Wf" put = "93A1vGXSGoDHotruGmgyRgtV8hgfFjgtmtuc4epcag886W9d44L" pct = "cUWo47XLYiyFByuFicFS3y4FAza3r3R5XA7Bm7wA3dgSKDYox7h6" - self.assertEqual(tools.private_key_to_WIF(p, compressed=1, testnet=0), pcm) - self.assertEqual(tools.private_key_to_WIF(p, compressed=0, testnet=0), pum) - self.assertEqual(tools.private_key_to_WIF(p, compressed=1, testnet=1), pct) - self.assertEqual(tools.private_key_to_WIF(p, compressed=0, testnet=1), put) + self.assertEqual(tools.private_key_to_wif(p, compressed=1, testnet=0), pcm) + self.assertEqual(tools.private_key_to_wif(p, compressed=0, testnet=0), pum) + self.assertEqual(tools.private_key_to_wif(p, compressed=1, testnet=1), pct) + self.assertEqual(tools.private_key_to_wif(p, compressed=0, testnet=1), put) def test_is_WIF_valid(self): - self.assertEqual(tools.is_WIF_valid("L49obCXV7fGz2YRzLCSJgeZBYmGeBbKPT7xiehUeYX2S4URkPFZX"),1) - self.assertEqual(tools.is_WIF_valid("5KPPLXhtga99qqMceRo4Z6LXV3Kx6a9hRx3ez2U7EwP5KZfy2Wf"),1) - self.assertEqual(tools.is_WIF_valid("5KPPLXhtga99qqMcWRo4Z6LXV3Kx6a9hRx3ez2U7EwP5KZfy2Wf"),0) - self.assertEqual(tools.is_WIF_valid("93A1vGXSGoDHotruGmgyRgtV8hgfFjgtmtuc4epcag886W9d44L"),1) - self.assertEqual(tools.is_WIF_valid("cUWo47XLYiyFByuFicFS3y4FAza3r3R5XA7Bm7wA3dgSKDYox7h6"),1) - self.assertEqual(tools.is_WIF_valid("cUWo47XLYiyByuFicFS3y4FAza3r3R5XA7Bm7wA3dgSKDYox7h6"),0) + self.assertEqual(tools.is_wif_valid("L49obCXV7fGz2YRzLCSJgeZBYmGeBbKPT7xiehUeYX2S4URkPFZX"), 1) + self.assertEqual(tools.is_wif_valid("5KPPLXhtga99qqMceRo4Z6LXV3Kx6a9hRx3ez2U7EwP5KZfy2Wf"), 1) + self.assertEqual(tools.is_wif_valid("5KPPLXhtga99qqMcWRo4Z6LXV3Kx6a9hRx3ez2U7EwP5KZfy2Wf"), 0) + self.assertEqual(tools.is_wif_valid("93A1vGXSGoDHotruGmgyRgtV8hgfFjgtmtuc4epcag886W9d44L"), 1) + self.assertEqual(tools.is_wif_valid("cUWo47XLYiyFByuFicFS3y4FAza3r3R5XA7Bm7wA3dgSKDYox7h6"), 1) + self.assertEqual(tools.is_wif_valid("cUWo47XLYiyByuFicFS3y4FAza3r3R5XA7Bm7wA3dgSKDYox7h6"), 0) def test_WIF_to_private_key(self): p = "ceda1ae4286015d45ec5147fe3f63e9377ccd6d4e98bcf0847df9937da1944a4" - self.assertEqual(tools.WIF_to_private_key("L49obCXV7fGz2YRzLCSJgeZBYmGeBbKPT7xiehUeYX2S4URkPFZX", + self.assertEqual(tools.wif_to_private_key("L49obCXV7fGz2YRzLCSJgeZBYmGeBbKPT7xiehUeYX2S4URkPFZX", hex=1),p) - self.assertEqual(tools.WIF_to_private_key("L49obCXV7fGz2YRzLCSJgeZBYmGeBbKPT7xiehUeYX2S4URkPFZX", + self.assertEqual(tools.wif_to_private_key("L49obCXV7fGz2YRzLCSJgeZBYmGeBbKPT7xiehUeYX2S4URkPFZX", hex=0),unhexlify(p)) - self.assertEqual(tools.WIF_to_private_key("5KPPLXhtga99qqMceRo4Z6LXV3Kx6a9hRx3ez2U7EwP5KZfy2Wf", + self.assertEqual(tools.wif_to_private_key("5KPPLXhtga99qqMceRo4Z6LXV3Kx6a9hRx3ez2U7EwP5KZfy2Wf", hex=1),p) - self.assertEqual(tools.WIF_to_private_key("93A1vGXSGoDHotruGmgyRgtV8hgfFjgtmtuc4epcag886W9d44L", + self.assertEqual(tools.wif_to_private_key("93A1vGXSGoDHotruGmgyRgtV8hgfFjgtmtuc4epcag886W9d44L", hex=1),p) - self.assertEqual(tools.WIF_to_private_key("cUWo47XLYiyFByuFicFS3y4FAza3r3R5XA7Bm7wA3dgSKDYox7h6", + self.assertEqual(tools.wif_to_private_key("cUWo47XLYiyFByuFicFS3y4FAza3r3R5XA7Bm7wA3dgSKDYox7h6", hex=1),p) def test_create_private_key(self): p = tools.create_private_key() - pw = tools.private_key_to_WIF(p) - self.assertEqual(tools.is_WIF_valid(pw), True) + pw = tools.private_key_to_wif(p) + self.assertEqual(tools.is_wif_valid(pw), True) diff --git a/tests/test/transaction_deserialize.py b/tests/test/transaction_deserialize.py index 5454bd3..5833257 100644 --- a/tests/test/transaction_deserialize.py +++ b/tests/test/transaction_deserialize.py @@ -1,14 +1,16 @@ import unittest -import os, sys +import os +import sys import time parentPath = os.path.abspath("..") if parentPath not in sys.path: sys.path.insert(0, parentPath) + from pybtc.tools import * from pybtc.hash import * from pybtc.transaction import * from binascii import unhexlify -from pybtc import address_to_hash as address2hash160 +from pybtc import address_to_hash as address2hash160 def decode_block_tx(block):