Pure functions docs

This commit is contained in:
4tochka 2018-06-19 03:13:55 +04:00
parent 4ecdadc0f4
commit 692aaba689
7 changed files with 65 additions and 36 deletions

View File

@ -20,9 +20,11 @@ sys.path.insert(0, os.path.abspath('..'))
sys.path.insert(0, os.path.abspath('../_static/')) sys.path.insert(0, os.path.abspath('../_static/'))
sys.path.insert(0, os.path.abspath('../../_static/')) sys.path.insert(0, os.path.abspath('../../_static/'))
sys.path.insert(0, os.path.abspath('../../pybtc/')) sys.path.insert(0, os.path.abspath('../../pybtc/'))
sys.path.insert(0, os.path.abspath('../../pybtc'))
sys.path.insert(0, os.path.abspath('./_static/')) sys.path.insert(0, os.path.abspath('./_static/'))
sys.path.insert(0, os.path.abspath('..'))
sys.path.insert(0, os.path.abspath('../..'))
# -- Project information ----------------------------------------------------- # -- Project information -----------------------------------------------------
project = 'pybtc' project = 'pybtc'

View File

@ -47,3 +47,6 @@ Addresses
.. autofunction:: pybtc.is_address_valid .. autofunction:: pybtc.is_address_valid
Signatures
==========

View File

@ -6,21 +6,22 @@ class PrivateKey():
if key is None: if key is None:
self.compressed = compressed self.compressed = compressed
self.testnet = testnet self.testnet = testnet
self.raw_key = create_private_key() self.raw_key = create_private_key(wif=False)
else: else:
if type(key) == str: if isinstance(key, str):
try: try:
key = unhexlify(key) key = unhexlify(key)
except: except:
pass pass
if type(key) == bytes: if isinstance(key, bytes):
assert len(key) == 32 if len(key) != 32:
raise TypeError("private key invalid")
self.raw_key = key self.raw_key = key
self.compressed = compressed self.compressed = compressed
self.testnet = testnet self.testnet = testnet
return return
assert type(key) == str assert isinstance(key, str)
self.raw_key = wif_to_private_key(key) self.raw_key = wif_to_private_key(key, hex=False)
if key[0] in (MAINNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX, if key[0] in (MAINNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX,
TESTNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX): TESTNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX):
self.compressed = False self.compressed = False
@ -48,16 +49,19 @@ class PrivateKey():
class PublicKey(): class PublicKey():
def __init__(self, key=None): def __init__(self, key=None):
if type(key) == str: if isinstance(key, str):
try: try:
key = unhexlify(key) key = unhexlify(key)
except: except:
pass pass
if type(key) == PrivateKey: if isinstance(key, PrivateKey):
key = private_to_public_key(key.raw_key, key = private_to_public_key(key.raw_key,
compressed=key.compressed) compressed=key.compressed,
assert type(key) == bytes hex=False)
assert len(key) == 33 or len(key) == 65 if not isinstance(key, bytes):
raise TypeError("public key invalid")
if len(key) != 33 and len(key) != 65:
raise TypeError("public key invalid")
if len(key) == 33: if len(key) == 33:
self.compressed = True self.compressed = True
else: else:
@ -68,7 +72,7 @@ class PublicKey():
return hexlify(self.raw_key).decode() return hexlify(self.raw_key).decode()
def __str__(self): def __str__(self):
return hex() return self.hex()
class Address(): class Address():
@ -79,18 +83,20 @@ class Address():
compressed=compressed) compressed=compressed)
self.public_key = PublicKey(self.private_key) self.public_key = PublicKey(self.private_key)
self.testnet = testnet self.testnet = testnet
elif type(key) == PrivateKey: elif isinstance(key, PrivateKey):
self.private_key = key self.private_key = key
self.testnet = key.testnet self.testnet = key.testnet
compressed = key.compressed compressed = key.compressed
self.public_key = PublicKey(self.private_key) self.public_key = PublicKey(self.private_key)
elif type(key) == PublicKey: elif isinstance(key, PublicKey):
self.public_key = key self.public_key = key
self.testnet = testnet self.testnet = testnet
compressed = key.compressed compressed = key.compressed
assert address_type in ("P2PKH", "PUBKEY", "P2WPKH", "P2SH_P2WPKH") if address_type not in ("P2PKH", "PUBKEY", "P2WPKH", "P2SH_P2WPKH"):
raise TypeError("address type invalid")
if not compressed: if not compressed:
assert address_type in ("P2PKH", "PUBKEY") if address_type not in ("P2PKH", "PUBKEY", "P2SH"):
raise TypeError("compressed public key invalid")
self.type = address_type self.type = address_type
if address_type in ("P2WPKH"): if address_type in ("P2WPKH"):
@ -120,7 +126,7 @@ class ScriptAddress():
testnet=False, witness_version=None): testnet=False, witness_version=None):
self.witness_version = witness_version self.witness_version = witness_version
self.testnet = testnet self.testnet = testnet
if type(script) == str: if isinstance(script, str):
script = unhexlify(script) script = unhexlify(script)
self.script_raw = script self.script_raw = script
self.script = hexlify(self.script_raw).decode() self.script = hexlify(self.script_raw).decode()

View File

@ -129,7 +129,7 @@ def private_to_public_key(private_key, compressed=True, hex=True):
if private_key[0] in (MAINNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX, if private_key[0] in (MAINNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX,
TESTNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX): TESTNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX):
compressed = False compressed = False
private_key = wif_to_private_key(private_key) private_key = wif_to_private_key(private_key, hex=0)
else: else:
raise TypeError("private key must be a bytes or WIF or hex encoded string") raise TypeError("private key must be a bytes or WIF or hex encoded string")
pubkey_ptr = ffi.new('secp256k1_pubkey *') pubkey_ptr = ffi.new('secp256k1_pubkey *')
@ -334,7 +334,7 @@ def address_to_script(address, hex=False):
MAINNET_SCRIPT_ADDRESS_PREFIX): MAINNET_SCRIPT_ADDRESS_PREFIX):
s = [BYTE_OPCODE["OP_HASH160"], s = [BYTE_OPCODE["OP_HASH160"],
b'\x14', b'\x14',
address_to_hash(address), address_to_hash(address, hex=False),
BYTE_OPCODE["OP_EQUAL"]] BYTE_OPCODE["OP_EQUAL"]]
elif address[0] in (MAINNET_ADDRESS_PREFIX, elif address[0] in (MAINNET_ADDRESS_PREFIX,
TESTNET_ADDRESS_PREFIX, TESTNET_ADDRESS_PREFIX,
@ -342,12 +342,12 @@ def address_to_script(address, hex=False):
s = [BYTE_OPCODE["OP_DUP"], s = [BYTE_OPCODE["OP_DUP"],
BYTE_OPCODE["OP_HASH160"], BYTE_OPCODE["OP_HASH160"],
b'\x14', b'\x14',
address_to_hash(address), address_to_hash(address, hex=False),
BYTE_OPCODE["OP_EQUALVERIFY"], BYTE_OPCODE["OP_EQUALVERIFY"],
BYTE_OPCODE["OP_CHECKSIG"]] BYTE_OPCODE["OP_CHECKSIG"]]
elif address[:2] in (TESTNET_SEGWIT_ADDRESS_PREFIX, elif address[:2] in (TESTNET_SEGWIT_ADDRESS_PREFIX,
MAINNET_SEGWIT_ADDRESS_PREFIX): MAINNET_SEGWIT_ADDRESS_PREFIX):
h = address_to_hash(address) h = address_to_hash(address, hex=False)
s = [BYTE_OPCODE["OP_0"], s = [BYTE_OPCODE["OP_0"],
bytes([len(h)]), bytes([len(h)]),
h] h]

View File

@ -1,13 +1,31 @@
#!/usr/bin/python3 #!/usr/bin/python3
# coding: utf-8 # coding: utf-8
# todo install libsec256 part
from distutils.core import setup from setuptools import setup, find_packages
setup(name='pybtc', setup(name='pybtc',
version='1.0.1', version='0.1',
description='Bitcoin library', description='Python Bitcoin library',
keywords='bitcoin',
url='https://github.com/bitaps-com/pybtc',
author='Alexsei Karpov', author='Alexsei Karpov',
author_email='admin@bitaps.com', author_email='admin@bitaps.com',
url='https://github.com/bitaps-com/pybtc', license='GPL-3.0',
packages=['pybtc', ], packages=find_packages(),
) install_requires=[ 'secp256k1', ],
include_package_data=True,
zip_safe=False)
#
# from distutils.core import setup
#
# setup(name='pybtc',
# version='1.0.1',
# description='Bitcoin library',
# author='Alexsei Karpov',
# author_email='admin@bitaps.com',
# url='https://github.com/bitaps-com/pybtc',
# packages=['pybtc'],
#
# )

View File

@ -1,10 +1,10 @@
# from .hash_functions import * from .hash_functions import *
# from .integer import * from .integer import *
# from .address_functions import * from .address_functions import *
from .address_class import * from .address_class import *
# from .ecdsa import * from .ecdsa import *
# from .transaction_deserialize import * from .transaction_deserialize import *
# from .transaction_constructor import * from .transaction_constructor import *
# from .script_deserialize import * # from .script_deserialize import *

View File

@ -47,7 +47,7 @@ class AddressFunctionsTests(unittest.TestCase):
hex=1),p) hex=1),p)
def test_create_private_key(self): def test_create_private_key(self):
p = tools.create_private_key() p = tools.create_private_key(wif=0)
pw = tools.private_key_to_wif(p) pw = tools.private_key_to_wif(p)
self.assertEqual(tools.is_wif_valid(pw), True) self.assertEqual(tools.is_wif_valid(pw), True)