diff --git a/bitcoin/__init__.py b/bitcoin/__init__.py index 841b42b9..e4eaceac 100644 --- a/bitcoin/__init__.py +++ b/bitcoin/__init__.py @@ -9,7 +9,6 @@ # propagated, or distributed except according to the terms contained in the # LICENSE file. -from __future__ import absolute_import, division, print_function, unicode_literals import bitcoin.core diff --git a/bitcoin/base58.py b/bitcoin/base58.py index 4253240e..18956223 100644 --- a/bitcoin/base58.py +++ b/bitcoin/base58.py @@ -12,15 +12,6 @@ """Base58 encoding and decoding""" -from __future__ import absolute_import, division, print_function, unicode_literals - -import sys -_bchr = chr -_bord = ord -if sys.version > '3': - long = int - _bchr = lambda x: bytes([x]) - _bord = lambda x: x import binascii @@ -52,10 +43,7 @@ def encode(b): res = ''.join(res[::-1]) # Encode leading zeros as base58 zeros - czero = b'\x00' - if sys.version > '3': - # In Python3 indexing a bytes returns numbers, not characters. - czero = 0 + czero = 0 pad = 0 for c in b: if c == czero: @@ -108,7 +96,7 @@ def __new__(cls, s): if check0 != check1: raise Base58ChecksumError('Checksum mismatch: expected %r, calculated %r' % (check0, check1)) - return cls.from_bytes(data, _bord(verbyte[0])) + return cls.from_bytes(data, verbyte[0]) def __init__(self, s): """Initialize from base58-encoded string @@ -138,7 +126,7 @@ def to_bytes(self): def __str__(self): """Convert to string""" - vs = _bchr(self.nVersion) + self + vs = bytes([self.nVersion]) + self check = bitcoin.core.Hash(vs)[0:4] return encode(vs + check) diff --git a/bitcoin/bech32.py b/bitcoin/bech32.py index fe95c70c..f140b0ae 100644 --- a/bitcoin/bech32.py +++ b/bitcoin/bech32.py @@ -11,14 +11,6 @@ """Bech32 encoding and decoding""" -import sys -_bchr = chr -_bord = ord -if sys.version > '3': - long = int - _bchr = lambda x: bytes([x]) - _bord = lambda x: x - from bitcoin.segwit_addr import encode, decode import bitcoin diff --git a/bitcoin/bloom.py b/bitcoin/bloom.py index f74980cf..50073dc3 100644 --- a/bitcoin/bloom.py +++ b/bitcoin/bloom.py @@ -11,10 +11,8 @@ """Bloom filter support""" -from __future__ import absolute_import, division, print_function, unicode_literals import struct -import sys import math import bitcoin.core @@ -56,16 +54,12 @@ def MurmurHash3(nHashSeed, vDataToHash): # tail k1 = 0 j = (len(vDataToHash) // 4) * 4 - bord = ord - if sys.version > '3': - # In Py3 indexing bytes returns numbers, not characters - bord = lambda x: x if len(vDataToHash) & 3 >= 3: - k1 ^= bord(vDataToHash[j+2]) << 16 + k1 ^= vDataToHash[j+2] << 16 if len(vDataToHash) & 3 >= 2: - k1 ^= bord(vDataToHash[j+1]) << 8 + k1 ^= vDataToHash[j+1] << 8 if len(vDataToHash) & 3 >= 1: - k1 ^= bord(vDataToHash[j]) + k1 ^= vDataToHash[j] k1 &= 0xFFFFFFFF k1 = (k1 * c1) & 0xFFFFFFFF @@ -180,11 +174,7 @@ def stream_deserialize(cls, f): return deserialized def stream_serialize(self, f): - if sys.version > '3': - bitcoin.core.serialize.BytesSerializer.stream_serialize(self.vData, f) - else: - # 2.7 has problems with f.write(bytearray()) - bitcoin.core.serialize.BytesSerializer.stream_serialize(bytes(self.vData), f) + bitcoin.core.serialize.BytesSerializer.stream_serialize(self.vData, f) f.write(self.__struct.pack(self.nHashFuncs, self.nTweak, self.nFlags)) __all__ = ( diff --git a/bitcoin/core/__init__.py b/bitcoin/core/__init__.py index 272bec5c..08961edc 100644 --- a/bitcoin/core/__init__.py +++ b/bitcoin/core/__init__.py @@ -9,28 +9,22 @@ # propagated, or distributed except according to the terms contained in the # LICENSE file. -from __future__ import absolute_import, division, print_function import binascii import struct -import sys import time -from .script import CScript, CScriptWitness, CScriptOp, OP_RETURN +from . import script +from .script import CScript, CScriptWitness, OP_RETURN from .serialize import * -if sys.version > '3': - _bytes = bytes -else: - _bytes = lambda x: bytes(bytearray(x)) - # Core definitions COIN = 100000000 MAX_BLOCK_SIZE = 1000000 MAX_BLOCK_WEIGHT = 4000000 MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50 -WITNESS_COINBASE_SCRIPTPUBKEY_MAGIC = _bytes([OP_RETURN, 0x24, 0xaa, 0x21, 0xa9, 0xed]) +WITNESS_COINBASE_SCRIPTPUBKEY_MAGIC = bytes([OP_RETURN, 0x24, 0xaa, 0x21, 0xa9, 0xed]) def MoneyRange(nValue, params=None): global coreparams @@ -39,30 +33,14 @@ def MoneyRange(nValue, params=None): return 0 <= nValue <= params.MAX_MONEY -def _py2_x(h): - """Convert a hex string to bytes""" - return binascii.unhexlify(h) - def x(h): """Convert a hex string to bytes""" return binascii.unhexlify(h.encode('utf8')) -def _py2_b2x(b): - """Convert bytes to a hex string""" - return binascii.hexlify(b) - def b2x(b): """Convert bytes to a hex string""" return binascii.hexlify(b).decode('utf8') -def _py2_lx(h): - """Convert a little-endian hex string to bytes - - Lets you write uint256's and uint160's the way the Satoshi codebase shows - them. - """ - return binascii.unhexlify(h)[::-1] - def lx(h): """Convert a little-endian hex string to bytes @@ -71,14 +49,6 @@ def lx(h): """ return binascii.unhexlify(h.encode('utf8'))[::-1] -def _py2_b2lx(b): - """Convert bytes to a little-endian hex string - - Lets you show uint256's and uint160's the way the Satoshi codebase shows - them. - """ - return binascii.hexlify(b[::-1]) - def b2lx(b): """Convert bytes to a little-endian hex string @@ -87,18 +57,6 @@ def b2lx(b): """ return binascii.hexlify(b[::-1]).decode('utf8') -if not (sys.version > '3'): - x = _py2_x - b2x = _py2_b2x - lx = _py2_lx - b2lx = _py2_b2lx - -del _py2_x -del _py2_b2x -del _py2_lx -del _py2_b2lx - - def str_money_value(value): """Convert an integer money value to a fixed point string""" r = '%i.%08i' % (value // COIN, value % COIN) diff --git a/bitcoin/core/_bignum.py b/bitcoin/core/_bignum.py index 42985a7f..6edd7065 100644 --- a/bitcoin/core/_bignum.py +++ b/bitcoin/core/_bignum.py @@ -13,7 +13,6 @@ # # Internally used for script evaluation; not to be used externally. -from __future__ import absolute_import, division, print_function, unicode_literals import struct diff --git a/bitcoin/core/key.py b/bitcoin/core/key.py index 37615e51..daee9a40 100644 --- a/bitcoin/core/key.py +++ b/bitcoin/core/key.py @@ -18,17 +18,10 @@ import ctypes import ctypes.util import hashlib -import sys from os import urandom import bitcoin import bitcoin.signature -_bchr = chr -_bord = ord -if sys.version > '3': - _bchr = lambda x: bytes([x]) - _bord = lambda x: x - import bitcoin.core.script _ssl = ctypes.cdll.LoadLibrary( @@ -587,8 +580,8 @@ def recover_compact(cls, hash, sig): # pylint: disable=redefined-builtin if len(sig) != 65: raise ValueError("Signature should be 65 characters, not [%d]" % (len(sig), )) - recid = (_bord(sig[0]) - 27) & 3 - compressed = (_bord(sig[0]) - 27) & 4 != 0 + recid = (sig[0] - 27) & 3 + compressed = (sig[0] - 27) & 4 != 0 cec_key = CECKey() cec_key.set_compressed(compressed) @@ -620,12 +613,7 @@ def __str__(self): return repr(self) def __repr__(self): - # Always have represent as b'' so test cases don't have to - # change for py2/3 - if sys.version > '3': - return '%s(%s)' % (self.__class__.__name__, super(CPubKey, self).__repr__()) - else: - return '%s(b%s)' % (self.__class__.__name__, super(CPubKey, self).__repr__()) + return '%s(%s)' % (self.__class__.__name__, super(CPubKey, self).__repr__()) __all__ = ( 'CECKey', diff --git a/bitcoin/core/script.py b/bitcoin/core/script.py index 46b83bd7..aa2cff87 100644 --- a/bitcoin/core/script.py +++ b/bitcoin/core/script.py @@ -15,18 +15,8 @@ is in bitcoin.core.scripteval """ -from __future__ import absolute_import, division, print_function - -import sys -_bchr = chr -_bord = ord -if sys.version > '3': - long = int - _bchr = lambda x: bytes([x]) - _bord = lambda x: x - from io import BytesIO as _BytesIO -else: - from cStringIO import StringIO as _BytesIO + +from io import BytesIO import struct @@ -50,9 +40,9 @@ class CScriptOp(int): def encode_op_pushdata(d): """Encode a PUSHDATA op, returning bytes""" if len(d) < 0x4c: - return b'' + _bchr(len(d)) + d # OP_PUSHDATA + return bytes([len(d)]) + d # OP_PUSHDATA elif len(d) <= 0xff: - return b'\x4c' + _bchr(len(d)) + d # OP_PUSHDATA1 + return b'\x4c' + bytes([len(d)]) + d # OP_PUSHDATA1 elif len(d) <= 0xffff: return b'\x4d' + struct.pack(b' OP_PUSHDATA4: @@ -588,21 +578,21 @@ def raw_iter(self): pushdata_type = 'PUSHDATA1' if i >= len(self): raise CScriptInvalidError('PUSHDATA1: missing data length') - datasize = _bord(self[i]) + datasize = self[i] i += 1 elif opcode == OP_PUSHDATA2: pushdata_type = 'PUSHDATA2' if i + 1 >= len(self): raise CScriptInvalidError('PUSHDATA2: missing data length') - datasize = _bord(self[i]) + (_bord(self[i+1]) << 8) + datasize = self[i] + (self[i+1] << 8) i += 2 elif opcode == OP_PUSHDATA4: pushdata_type = 'PUSHDATA4' if i + 3 >= len(self): raise CScriptInvalidError('PUSHDATA4: missing data length') - datasize = _bord(self[i]) + (_bord(self[i+1]) << 8) + (_bord(self[i+2]) << 16) + (_bord(self[i+3]) << 24) + datasize = self[i] + (self[i+1] << 8) + (self[i+2] << 16) + (self[i+3] << 24) i += 4 else: @@ -676,9 +666,9 @@ def is_p2sh(self): Note that this test is consensus-critical. """ return (len(self) == 23 and - _bord(self[0]) == OP_HASH160 and - _bord(self[1]) == 0x14 and - _bord(self[22]) == OP_EQUAL) + self[0] == OP_HASH160 and + self[1] == 0x14 and + self[22] == OP_EQUAL) def is_witness_scriptpubkey(self): """Returns true if this is a scriptpubkey signaling segregated witness data. @@ -747,7 +737,7 @@ def has_canonical_pushes(self): if op > OP_16: continue - elif op < OP_PUSHDATA1 and op > OP_0 and len(data) == 1 and _bord(data[0]) <= 16: + elif op < OP_PUSHDATA1 and op > OP_0 and len(data) == 1 and data[0] <= 16: # Could have used an OP_n code, rather than a 1-byte push. return False @@ -770,7 +760,7 @@ def has_canonical_pushes(self): def is_unspendable(self): """Test if the script is provably unspendable""" return (len(self) > 0 and - _bord(self[0]) == OP_RETURN) + self[0] == OP_RETURN) def is_valid(self): """Return True if the script is valid, False otherwise @@ -1018,7 +1008,7 @@ def SignatureHash(script, txTo, inIdx, hashtype, amount=None, sigversion=SIGVERS serialize_outputs = txTo.vout[inIdx].serialize() hashOutputs = bitcoin.core.Hash(serialize_outputs) - f = _BytesIO() + f = BytesIO() f.write(struct.pack(" '3': - long = int - _bord = lambda x: x import hashlib @@ -122,7 +115,7 @@ def _CastToBigNum(s, err_raiser): def _CastToBool(s): for i in range(len(s)): - sv = _bord(s[i]) + sv = s[i] if sv != 0: if (i == (len(s) - 1)) and (sv == 0x80): return False @@ -137,7 +130,7 @@ def _CheckSig(sig, pubkey, script, txTo, inIdx, err_raiser): if len(sig) == 0: return False - hashtype = _bord(sig[-1]) + hashtype = sig[-1] sig = sig[:-1] # Raw signature hash due to the SIGHASH_SINGLE bug @@ -260,10 +253,10 @@ def _UnaryOp(opcode, stack, err_raiser): bn = -bn elif opcode == OP_NOT: - bn = long(bn == 0) + bn = int(bn == 0) elif opcode == OP_0NOTEQUAL: - bn = long(bn != 0) + bn = int(bn != 0) else: raise AssertionError("Unknown unary opcode encountered; this should not happen") @@ -305,16 +298,16 @@ def _BinOp(opcode, stack, err_raiser): bn = bn1 - bn2 elif opcode == OP_BOOLAND: - bn = long(bn1 != 0 and bn2 != 0) + bn = int(bn1 != 0 and bn2 != 0) elif opcode == OP_BOOLOR: - bn = long(bn1 != 0 or bn2 != 0) + bn = int(bn1 != 0 or bn2 != 0) elif opcode == OP_NUMEQUAL: - bn = long(bn1 == bn2) + bn = int(bn1 == bn2) elif opcode == OP_NUMEQUALVERIFY: - bn = long(bn1 == bn2) + bn = int(bn1 == bn2) if not bn: err_raiser(VerifyOpFailedError, opcode) else: @@ -324,19 +317,19 @@ def _BinOp(opcode, stack, err_raiser): return elif opcode == OP_NUMNOTEQUAL: - bn = long(bn1 != bn2) + bn = int(bn1 != bn2) elif opcode == OP_LESSTHAN: - bn = long(bn1 < bn2) + bn = int(bn1 < bn2) elif opcode == OP_GREATERTHAN: - bn = long(bn1 > bn2) + bn = int(bn1 > bn2) elif opcode == OP_LESSTHANOREQUAL: - bn = long(bn1 <= bn2) + bn = int(bn1 <= bn2) elif opcode == OP_GREATERTHANOREQUAL: - bn = long(bn1 >= bn2) + bn = int(bn1 >= bn2) elif opcode == OP_MIN: if bn1 < bn2: diff --git a/bitcoin/core/serialize.py b/bitcoin/core/serialize.py index c89b73e4..f1346b92 100644 --- a/bitcoin/core/serialize.py +++ b/bitcoin/core/serialize.py @@ -14,22 +14,11 @@ You probabably don't need to use these directly. """ -from __future__ import absolute_import, division, print_function, unicode_literals import hashlib import struct -# Py3 compatibility -import sys - -if sys.version > '3': - _bchr = lambda x: bytes([x]) - _bord = lambda x: x[0] - from io import BytesIO as _BytesIO -else: - _bchr = chr - _bord = ord - from cStringIO import StringIO as _BytesIO +from io import BytesIO MAX_SIZE = 0x02000000 @@ -98,7 +87,7 @@ def stream_deserialize(cls, f, **kwargs): def serialize(self, params={}): """Serialize, returning bytes""" - f = _BytesIO() + f = BytesIO() self.stream_serialize(f, **params) return f.getvalue() @@ -111,7 +100,7 @@ def deserialize(cls, buf, allow_padding=False, params={}): If allow_padding is False and not all bytes are consumed during deserialization DeserializationExtraDataError will be raised. """ - fd = _BytesIO(buf) + fd = BytesIO(buf) r = cls.stream_deserialize(fd, **params) if not allow_padding: padding = fd.read() @@ -179,14 +168,14 @@ def stream_deserialize(cls, f): @classmethod def serialize(cls, obj): - f = _BytesIO() + f = BytesIO() cls.stream_serialize(obj, f) return f.getvalue() @classmethod def deserialize(cls, buf): if isinstance(buf, str) or isinstance(buf, bytes): - buf = _BytesIO(buf) + buf = BytesIO(buf) return cls.stream_deserialize(buf) @@ -197,20 +186,20 @@ def stream_serialize(cls, i, f): if i < 0: raise ValueError('varint must be non-negative integer') elif i < 0xfd: - f.write(_bchr(i)) + f.write(bytes([i])) elif i <= 0xffff: - f.write(_bchr(0xfd)) + f.write(b'\xfd') f.write(struct.pack(b' '3': - _bchr = lambda x: bytes([x]) - _bord = lambda x: x[0] - from io import BytesIO as _BytesIO -else: - _bchr = chr - _bord = ord - from cStringIO import StringIO as _BytesIO +from io import BytesIO # Bad practice, so we have a __all__ at the end; this should be cleaned up # later. @@ -59,7 +51,7 @@ def msg_deser(cls, f, protover=PROTO_VERSION): raise NotImplementedError def to_bytes(self): - f = _BytesIO() + f = BytesIO() self.msg_ser(f) body = f.getvalue() res = bitcoin.params.MESSAGE_START @@ -77,7 +69,7 @@ def to_bytes(self): @classmethod def from_bytes(cls, b, protover=PROTO_VERSION): - f = _BytesIO(b) + f = BytesIO(b) return MsgSerializable.stream_deserialize(f, protover=protover) @classmethod @@ -107,7 +99,7 @@ def stream_deserialize(cls, f, protover=PROTO_VERSION): if command in messagemap: cls = messagemap[command] # print("Going to deserialize '%s'" % msg) - return cls.msg_deser(_BytesIO(msg)) + return cls.msg_deser(BytesIO(msg)) else: print("Command '%s' not in messagemap" % repr(command)) return None @@ -160,7 +152,7 @@ def msg_deser(cls, f, protover=PROTO_VERSION): else: c.fRelay = True return c - + def msg_ser(self, f): f.write(struct.pack(b" '3': - unhexlify = lambda h: binascii.unhexlify(h.encode('utf8')) - hexlify = lambda b: binascii.hexlify(b).decode('utf8') +def unhexlify_str(h): + """ + Converts a string containing hexadecimal encoding into a bytes-object. + + It works by encoding the given string h as ASCII, then interpreting each of + its two-character ASCII tuples as bytes: + - "00" to byte 0 + - "ff" to byte 255 + - "FF" also to byte 255 + + The string must only contain characters in the ranges 0-9, a-f and A-F. + + If the string contains characters not in ASCII, + UnicodeEncodeError is raised. + If the string contains out-of-range ASCII characters, + binascii.Error is raised. + If number of encoded ASCII bytes is odd, + binascii.Error is raised. + """ + return binascii.unhexlify(h.encode('ascii')) + +def hexlify_str(b): + """ + Given an arbitrary bytes-like object, returns a string (that would encode + as ASCII) containing the hex-representation of the bytes-like object. + + Always succeeds. + """ + return binascii.hexlify(b).decode('ascii') class JSONRPCError(Exception): @@ -379,10 +392,10 @@ def fundrawtransaction(self, tx, include_watching=False): 'changepos': Position of added change output, or -1, } """ - hextx = hexlify(tx.serialize()) + hextx = hexlify_str(tx.serialize()) r = self._call('fundrawtransaction', hextx, include_watching) - r['tx'] = CTransaction.deserialize(unhexlify(r['hex'])) + r['tx'] = CTransaction.deserialize(unhexlify_str(r['hex'])) del r['hex'] r['fee'] = int(r['fee'] * COIN) @@ -392,7 +405,7 @@ def fundrawtransaction(self, tx, include_watching=False): def generate(self, numblocks): """ DEPRECATED (will be removed in bitcoin-core v0.19) - + Mine blocks immediately (before the RPC call returns) numblocks - How many blocks are generated immediately. @@ -401,10 +414,10 @@ def generate(self, numblocks): """ r = self._call('generate', numblocks) return (lx(blk_hash) for blk_hash in r) - + def generatetoaddress(self, numblocks, addr): """Mine blocks immediately (before the RPC call returns) and - allocate block reward to passed address. Replaces deprecated + allocate block reward to passed address. Replaces deprecated "generate(self,numblocks)" method. numblocks - How many blocks are generated immediately. @@ -470,7 +483,7 @@ def getblockheader(self, block_hash, verbose=False): 'nextblockhash':nextblockhash, 'chainwork':x(r['chainwork'])} else: - return CBlockHeader.deserialize(unhexlify(r)) + return CBlockHeader.deserialize(unhexlify_str(r)) def getblock(self, block_hash): @@ -491,7 +504,7 @@ def getblock(self, block_hash): except InvalidAddressOrKeyError as ex: raise IndexError('%s.getblock(): %s (%d)' % (self.__class__.__name__, ex.error['message'], ex.error['code'])) - return CBlock.deserialize(unhexlify(r)) + return CBlock.deserialize(unhexlify_str(r)) def getblockcount(self): """Return the number of blocks in the longest block chain""" @@ -570,7 +583,7 @@ def getrawtransaction(self, txid, verbose=False): raise IndexError('%s.getrawtransaction(): %s (%d)' % (self.__class__.__name__, ex.error['message'], ex.error['code'])) if verbose: - r['tx'] = CTransaction.deserialize(unhexlify(r['hex'])) + r['tx'] = CTransaction.deserialize(unhexlify_str(r['hex'])) del r['hex'] del r['txid'] del r['version'] @@ -579,7 +592,7 @@ def getrawtransaction(self, txid, verbose=False): del r['vout'] r['blockhash'] = lx(r['blockhash']) if 'blockhash' in r else None else: - r = CTransaction.deserialize(unhexlify(r)) + r = CTransaction.deserialize(unhexlify_str(r)) return r @@ -627,7 +640,7 @@ def gettxout(self, outpoint, includemempool=True): raise IndexError('%s.gettxout(): unspent txout %r not found' % (self.__class__.__name__, outpoint)) r['txout'] = CTxOut(int(r['value'] * COIN), - CScript(unhexlify(r['scriptPubKey']['hex']))) + CScript(unhexlify_str(r['scriptPubKey']['hex']))) del r['value'] del r['scriptPubKey'] r['bestblock'] = lx(r['bestblock']) @@ -667,7 +680,7 @@ def listunspent(self, minconf=0, maxconf=9999999, addrs=None): unspent['address'] = CBitcoinAddress(unspent['address']) except KeyError: pass - unspent['scriptPubKey'] = CScript(unhexlify(unspent['scriptPubKey'])) + unspent['scriptPubKey'] = CScript(unhexlify_str(unspent['scriptPubKey'])) unspent['amount'] = int(unspent['amount'] * COIN) r2.append(unspent) return r2 @@ -683,7 +696,7 @@ def sendrawtransaction(self, tx, allowhighfees=False): allowhighfees - Allow even if fees are unreasonably high. """ - hextx = hexlify(tx.serialize()) + hextx = hexlify_str(tx.serialize()) r = None if allowhighfees: r = self._call('sendrawtransaction', hextx, True) @@ -713,9 +726,9 @@ def signrawtransaction(self, tx, *args): FIXME: implement options """ - hextx = hexlify(tx.serialize()) + hextx = hexlify_str(tx.serialize()) r = self._call('signrawtransaction', hextx, *args) - r['tx'] = CTransaction.deserialize(unhexlify(r['hex'])) + r['tx'] = CTransaction.deserialize(unhexlify_str(r['hex'])) del r['hex'] return r @@ -725,9 +738,9 @@ def signrawtransactionwithwallet(self, tx, *args): FIXME: implement options """ - hextx = hexlify(tx.serialize()) + hextx = hexlify_str(tx.serialize()) r = self._call('signrawtransactionwithwallet', hextx, *args) - r['tx'] = CTransaction.deserialize(unhexlify(r['hex'])) + r['tx'] = CTransaction.deserialize(unhexlify_str(r['hex'])) del r['hex'] return r @@ -737,7 +750,7 @@ def submitblock(self, block, params=None): params is optional and is currently ignored by bitcoind. See https://en.bitcoin.it/wiki/BIP_0022 for full specification. """ - hexblock = hexlify(block.serialize()) + hexblock = hexlify_str(block.serialize()) if params is not None: return self._call('submitblock', hexblock, params) else: @@ -749,7 +762,7 @@ def validateaddress(self, address): if r['isvalid']: r['address'] = CBitcoinAddress(r['address']) if 'pubkey' in r: - r['pubkey'] = unhexlify(r['pubkey']) + r['pubkey'] = unhexlify_str(r['pubkey']) return r def unlockwallet(self, password, timeout=60): diff --git a/bitcoin/segwit_addr.py b/bitcoin/segwit_addr.py index 67d17cff..c762fdd8 100644 --- a/bitcoin/segwit_addr.py +++ b/bitcoin/segwit_addr.py @@ -20,14 +20,6 @@ """Reference implementation for Bech32 and segwit addresses.""" -import sys -_bchr = chr -_bord = lambda x: ord(x) if isinstance(x, str) else x -if sys.version > '3': - long = int - _bchr = lambda x: bytes([x]) - _bord = lambda x: x - CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l" @@ -92,7 +84,6 @@ def convertbits(data, frombits, tobits, pad=True): maxv = (1 << tobits) - 1 max_acc = (1 << (frombits + tobits - 1)) - 1 for value in data: - value = _bord(value) if value < 0 or (value >> frombits): return None acc = ((acc << frombits) | value) & max_acc diff --git a/bitcoin/signature.py b/bitcoin/signature.py index f339491e..fd1d7404 100644 --- a/bitcoin/signature.py +++ b/bitcoin/signature.py @@ -9,17 +9,13 @@ # propagated, or distributed except according to the terms contained in the # LICENSE file. -from __future__ import absolute_import, division, print_function, unicode_literals from bitcoin.core.serialize import * # Py3 compatibility import sys -if sys.version > '3': - from io import BytesIO as _BytesIO -else: - from cStringIO import StringIO as _BytesIO +from io import BytesIO class DERSignature(ImmutableSerializable): @@ -34,7 +30,7 @@ def __init__(self, r, s, length): def stream_deserialize(cls, f): assert ser_read(f, 1) == b"\x30" rs = BytesSerializer.stream_deserialize(f) - f = _BytesIO(rs) + f = BytesIO(rs) assert ser_read(f, 1) == b"\x02" r = BytesSerializer.stream_deserialize(f) assert ser_read(f, 1) == b"\x02" diff --git a/bitcoin/signmessage.py b/bitcoin/signmessage.py index a62fe8c1..38c20dc8 100644 --- a/bitcoin/signmessage.py +++ b/bitcoin/signmessage.py @@ -9,21 +9,12 @@ # propagated, or distributed except according to the terms contained in the # LICENSE file. -from __future__ import absolute_import, division, print_function, unicode_literals from bitcoin.core.key import CPubKey from bitcoin.core.serialize import ImmutableSerializable from bitcoin.wallet import P2PKHBitcoinAddress import bitcoin import base64 -import sys - -_bchr = chr -_bord = ord -if sys.version > '3': - long = int - _bchr = lambda x: bytes([x]) - _bord = lambda x: x def VerifyMessage(address, message, sig): @@ -42,7 +33,7 @@ def SignMessage(key, message): if key.is_compressed: meta += 4 - return base64.b64encode(_bchr(meta) + sig) + return base64.b64encode(bytes([meta]) + sig) class BitcoinMessage(ImmutableSerializable): diff --git a/bitcoin/tests/__init__.py b/bitcoin/tests/__init__.py index 1d9a3755..770ca60a 100644 --- a/bitcoin/tests/__init__.py +++ b/bitcoin/tests/__init__.py @@ -9,4 +9,3 @@ # propagated, or distributed except according to the terms contained in the # LICENSE file. -from __future__ import absolute_import, division, print_function, unicode_literals diff --git a/bitcoin/tests/test_base58.py b/bitcoin/tests/test_base58.py index a57d1fe1..74840205 100644 --- a/bitcoin/tests/test_base58.py +++ b/bitcoin/tests/test_base58.py @@ -9,7 +9,6 @@ # propagated, or distributed except according to the terms contained in the # LICENSE file. -from __future__ import absolute_import, division, print_function, unicode_literals import json import os diff --git a/bitcoin/tests/test_bech32.py b/bitcoin/tests/test_bech32.py index 3efebca5..9d7db073 100644 --- a/bitcoin/tests/test_bech32.py +++ b/bitcoin/tests/test_bech32.py @@ -9,22 +9,10 @@ # propagated, or distributed except according to the terms contained in the # LICENSE file. -from __future__ import absolute_import, division, print_function, unicode_literals import json import os import unittest -import array -import sys -_bchr = chr -_bord = ord -_tobytes = lambda x: array.array('B', x).tostring() -if sys.version > '3': - long = int - _bchr = lambda x: bytes([x]) - _bord = lambda x: x - _tobytes = bytes - from binascii import unhexlify from bitcoin.core.script import CScript, OP_0, OP_1, OP_16 @@ -39,7 +27,7 @@ def load_test_vectors(name): def to_scriptPubKey(witver, witprog): """Decoded bech32 address to script""" - return CScript([witver]) + CScript(_tobytes(witprog)) + return CScript([witver]) + CScript(bytes(witprog)) class Test_bech32(unittest.TestCase): @@ -53,7 +41,7 @@ def op_decode(self, witver): def test_encode_decode(self): for exp_bin, exp_bech32 in load_test_vectors('bech32_encode_decode.json'): - exp_bin = [_bord(y) for y in unhexlify(exp_bin.encode('utf8'))] + exp_bin = unhexlify(exp_bin.encode('utf8')) witver = self.op_decode(exp_bin[0]) hrp = exp_bech32[:exp_bech32.rindex('1')].lower() self.assertEqual(exp_bin[1], len(exp_bin[2:])) @@ -61,7 +49,7 @@ def test_encode_decode(self): act_bin = decode(hrp, exp_bech32) self.assertEqual(act_bech32.lower(), exp_bech32.lower()) - self.assertEqual(to_scriptPubKey(*act_bin), _tobytes(exp_bin)) + self.assertEqual(to_scriptPubKey(*act_bin), bytes(exp_bin)) class Test_CBech32Data(unittest.TestCase): def test_from_data(self): diff --git a/bitcoin/tests/test_bloom.py b/bitcoin/tests/test_bloom.py index c0d7a019..f637600d 100644 --- a/bitcoin/tests/test_bloom.py +++ b/bitcoin/tests/test_bloom.py @@ -9,7 +9,6 @@ # propagated, or distributed except according to the terms contained in the # LICENSE file. -from __future__ import absolute_import, division, print_function, unicode_literals import unittest diff --git a/bitcoin/tests/test_checkblock.py b/bitcoin/tests/test_checkblock.py index a011fe26..a2bf9ad0 100644 --- a/bitcoin/tests/test_checkblock.py +++ b/bitcoin/tests/test_checkblock.py @@ -9,7 +9,6 @@ # propagated, or distributed except according to the terms contained in the # LICENSE file. -from __future__ import absolute_import, division, print_function, unicode_literals import json import unittest diff --git a/bitcoin/tests/test_core.py b/bitcoin/tests/test_core.py index 1d612afd..66ab16dd 100644 --- a/bitcoin/tests/test_core.py +++ b/bitcoin/tests/test_core.py @@ -9,7 +9,6 @@ # propagated, or distributed except according to the terms contained in the # LICENSE file. -from __future__ import absolute_import, division, print_function, unicode_literals import unittest diff --git a/bitcoin/tests/test_key.py b/bitcoin/tests/test_key.py index a99aa873..2526b948 100644 --- a/bitcoin/tests/test_key.py +++ b/bitcoin/tests/test_key.py @@ -9,7 +9,6 @@ # propagated, or distributed except according to the terms contained in the # LICENSE file. -from __future__ import absolute_import, division, print_function, unicode_literals import unittest diff --git a/bitcoin/tests/test_messages.py b/bitcoin/tests/test_messages.py index 8b51a126..b5e115dd 100644 --- a/bitcoin/tests/test_messages.py +++ b/bitcoin/tests/test_messages.py @@ -16,11 +16,7 @@ msg_block, msg_getaddr, msg_ping, msg_pong, msg_mempool, MsgSerializable, \ msg_notfound, msg_reject -import sys -if sys.version > '3': - from io import BytesIO -else: - from cStringIO import StringIO as BytesIO +from io import BytesIO class MessageTestCase(unittest.TestCase): diff --git a/bitcoin/tests/test_net.py b/bitcoin/tests/test_net.py index df83856f..80f6d775 100644 --- a/bitcoin/tests/test_net.py +++ b/bitcoin/tests/test_net.py @@ -13,13 +13,7 @@ from bitcoin.net import CAddress, CAlert, CUnsignedAlert, CInv -# Py3 compatibility -import sys - -if sys.version > '3': - from io import BytesIO as _BytesIO -else: - from cStringIO import StringIO as _BytesIO +from io import BytesIO class TestUnsignedAlert(unittest.TestCase): @@ -27,10 +21,10 @@ def test_serialization(self): alert = CUnsignedAlert() alert.setCancel = [1, 2, 3] alert.strComment = b"Comment" - stream = _BytesIO() + stream = BytesIO() alert.stream_serialize(stream) - serialized = _BytesIO(stream.getvalue()) + serialized = BytesIO(stream.getvalue()) deserialized = CUnsignedAlert.stream_deserialize(serialized) self.assertEqual(deserialized, alert) @@ -41,10 +35,10 @@ def test_serialization(self): alert = CAlert() alert.setCancel = [1, 2, 3] alert.strComment = b"Comment" - stream = _BytesIO() + stream = BytesIO() alert.stream_serialize(stream) - serialized = _BytesIO(stream.getvalue()) + serialized = BytesIO(stream.getvalue()) deserialized = CAlert.stream_deserialize(serialized) self.assertEqual(deserialized, alert) @@ -55,10 +49,10 @@ def test_serialization(self): inv = CInv() inv.type = 123 inv.hash = b"0" * 32 - stream = _BytesIO() + stream = BytesIO() inv.stream_serialize(stream) - serialized = _BytesIO(stream.getvalue()) + serialized = BytesIO(stream.getvalue()) deserialized = CInv.stream_deserialize(serialized) self.assertEqual(deserialized, inv) diff --git a/bitcoin/tests/test_rpc.py b/bitcoin/tests/test_rpc.py index 07d1f964..716fb816 100644 --- a/bitcoin/tests/test_rpc.py +++ b/bitcoin/tests/test_rpc.py @@ -9,7 +9,6 @@ # propagated, or distributed except according to the terms contained in the # LICENSE file. -from __future__ import absolute_import, division, print_function, unicode_literals import unittest diff --git a/bitcoin/tests/test_script.py b/bitcoin/tests/test_script.py index b461e675..ca4598ff 100644 --- a/bitcoin/tests/test_script.py +++ b/bitcoin/tests/test_script.py @@ -9,7 +9,6 @@ # propagated, or distributed except according to the terms contained in the # LICENSE file. -from __future__ import absolute_import, division, print_function, unicode_literals import unittest import os diff --git a/bitcoin/tests/test_scripteval.py b/bitcoin/tests/test_scripteval.py index ee2ceb96..59f12182 100644 --- a/bitcoin/tests/test_scripteval.py +++ b/bitcoin/tests/test_scripteval.py @@ -9,16 +9,11 @@ # propagated, or distributed except according to the terms contained in the # LICENSE file. -from __future__ import absolute_import, division, print_function, unicode_literals import json import os import unittest -import sys -if sys.version > '3': - long = int - from binascii import unhexlify from bitcoin.core import * @@ -40,7 +35,7 @@ def ishex(s): for word in s.split(): if word.isdigit() or (word[0] == '-' and word[1:].isdigit()): - r.append(CScript([long(word)])) + r.append(CScript([int(word)])) elif word.startswith('0x') and ishex(word[2:]): # Raw ex data, inserted NOT pushed onto stack: r.append(unhexlify(word[2:].encode('utf8'))) diff --git a/bitcoin/tests/test_segwit.py b/bitcoin/tests/test_segwit.py index 9273fded..b2a0e1c8 100644 --- a/bitcoin/tests/test_segwit.py +++ b/bitcoin/tests/test_segwit.py @@ -9,7 +9,6 @@ # propagated, or distributed except according to the terms contained in the # LICENSE file. -from __future__ import absolute_import, division, print_function, unicode_literals import unittest import random @@ -20,11 +19,6 @@ from bitcoin.core.script import * from bitcoin.wallet import * -if sys.version > '3': - _bytes = bytes -else: - _bytes = lambda x: bytes(bytearray(x)) - # Test serialization @@ -122,7 +116,7 @@ def test_checkblock(self): str_tx = '0100000001e3d0c1d051a3abe79d5951dcab86f71d8926aff5caed5ff9bd72cb593e4ebaf5010000006b483045022100a28e1c57e160296953e1af85c5034bb1b907c12c50367da75ba547874a8a8c52022040682e888ddce7fd5c72519a9f28f22f5164c8af864d33332bbc7f65596ad4ae012102db30394fd5cc8288bed607b9382338240c014a98c9c0febbfb380db74ceb30a3ffffffff020d920000000000001976a914ad781c8ffcc18b2155433cba2da4601180a66eef88aca3170000000000001976a914bacb1c4b0725e61e385c7093b4260533953c8e1688ac00000000' # SegWit transaction str_w_tx = '0100000000010115e180dc28a2327e687facc33f10f2a20da717e5548406f7ae8b4c811072f8560100000000ffffffff0100b4f505000000001976a9141d7cd6c75c2e86f4cbf98eaed221b30bd9a0b92888ac02483045022100df7b7e5cda14ddf91290e02ea10786e03eb11ee36ec02dd862fe9a326bbcb7fd02203f5b4496b667e6e281cc654a2da9e4f08660c620a1051337fa8965f727eb19190121038262a6c6cec93c2d3ecd6c6072efea86d02ff8e3328bbd0242b20af3425990ac00000000' - witness_nonce = _bytes(random.getrandbits(8) for _ in range(32)) + witness_nonce = bytes(random.getrandbits(8) for _ in range(32)) coinbase = CMutableTransaction.deserialize(x(str_coinbase)) coinbase.wit = CTxWitness([CTxInWitness(CScriptWitness([witness_nonce]))]) diff --git a/bitcoin/tests/test_serialize.py b/bitcoin/tests/test_serialize.py index a5e45330..cc1056b8 100644 --- a/bitcoin/tests/test_serialize.py +++ b/bitcoin/tests/test_serialize.py @@ -9,7 +9,6 @@ # propagated, or distributed except according to the terms contained in the # LICENSE file. -from __future__ import absolute_import, division, print_function, unicode_literals import unittest, random diff --git a/bitcoin/tests/test_signmessage.py b/bitcoin/tests/test_signmessage.py index 33dd7ad8..a643f574 100644 --- a/bitcoin/tests/test_signmessage.py +++ b/bitcoin/tests/test_signmessage.py @@ -9,23 +9,14 @@ # propagated, or distributed except according to the terms contained in the # LICENSE file. -from __future__ import absolute_import, division, print_function, unicode_literals import unittest from bitcoin.wallet import CBitcoinSecret from bitcoin.signmessage import BitcoinMessage, VerifyMessage, SignMessage -import sys import os import json -_bchr = chr -_bord = ord -if sys.version > '3': - long = int - _bchr = lambda x: bytes([x]) - _bord = lambda x: x - def load_test_vectors(name): with open(os.path.dirname(__file__) + '/data/' + name, 'r') as fd: return json.load(fd) diff --git a/bitcoin/tests/test_transactions.py b/bitcoin/tests/test_transactions.py index f96c5b32..2753e9fe 100644 --- a/bitcoin/tests/test_transactions.py +++ b/bitcoin/tests/test_transactions.py @@ -9,7 +9,6 @@ # propagated, or distributed except according to the terms contained in the # LICENSE file. -from __future__ import absolute_import, division, print_function, unicode_literals import json import unittest diff --git a/bitcoin/tests/test_wallet.py b/bitcoin/tests/test_wallet.py index ed7b81b5..c178cd51 100644 --- a/bitcoin/tests/test_wallet.py +++ b/bitcoin/tests/test_wallet.py @@ -9,7 +9,6 @@ # propagated, or distributed except according to the terms contained in the # LICENSE file. -from __future__ import absolute_import, division, print_function, unicode_literals import hashlib import unittest diff --git a/bitcoin/wallet.py b/bitcoin/wallet.py index 4579d285..eb5eeb98 100644 --- a/bitcoin/wallet.py +++ b/bitcoin/wallet.py @@ -15,16 +15,6 @@ scriptPubKeys; currently there is no actual wallet support implemented. """ -from __future__ import absolute_import, division, print_function, unicode_literals - -import array -import sys - -_bord = ord -_tobytes = lambda x: array.array('B', x).tostring() -if sys.version > '3': - _bord = lambda x: x - _tobytes = bytes import bitcoin import bitcoin.base58 @@ -78,7 +68,7 @@ def from_bytes(cls, witver, witprog): assert witver == 0 self = super(CBech32BitcoinAddress, cls).from_bytes( witver, - _tobytes(witprog) + bytes(witprog) ) if len(self) == 32: @@ -250,11 +240,11 @@ def from_scriptPubKey(cls, scriptPubKey, accept_non_canonical_pushdata=True, acc elif scriptPubKey.is_witness_v0_nested_keyhash(): return cls.from_bytes(scriptPubKey[3:23], bitcoin.params.BASE58_PREFIXES['PUBKEY_ADDR']) elif (len(scriptPubKey) == 25 - and _bord(scriptPubKey[0]) == script.OP_DUP - and _bord(scriptPubKey[1]) == script.OP_HASH160 - and _bord(scriptPubKey[2]) == 0x14 - and _bord(scriptPubKey[23]) == script.OP_EQUALVERIFY - and _bord(scriptPubKey[24]) == script.OP_CHECKSIG): + and scriptPubKey[0] == script.OP_DUP + and scriptPubKey[1] == script.OP_HASH160 + and scriptPubKey[2] == 0x14 + and scriptPubKey[23] == script.OP_EQUALVERIFY + and scriptPubKey[24] == script.OP_CHECKSIG): return cls.from_bytes(scriptPubKey[3:23], bitcoin.params.BASE58_PREFIXES['PUBKEY_ADDR']) elif accept_bare_checksig: @@ -263,14 +253,14 @@ def from_scriptPubKey(cls, scriptPubKey, accept_non_canonical_pushdata=True, acc # We can operate on the raw bytes directly because we've # canonicalized everything above. if (len(scriptPubKey) == 35 # compressed - and _bord(scriptPubKey[0]) == 0x21 - and _bord(scriptPubKey[34]) == script.OP_CHECKSIG): + and scriptPubKey[0] == 0x21 + and scriptPubKey[34] == script.OP_CHECKSIG): pubkey = scriptPubKey[1:34] elif (len(scriptPubKey) == 67 # uncompressed - and _bord(scriptPubKey[0]) == 0x41 - and _bord(scriptPubKey[66]) == script.OP_CHECKSIG): + and scriptPubKey[0] == 0x41 + and scriptPubKey[66] == script.OP_CHECKSIG): pubkey = scriptPubKey[1:65] @@ -379,7 +369,7 @@ def __init__(self, s): raise CBitcoinSecretError('Not a base58-encoded secret key: got nVersion=%d; expected nVersion=%d' % \ (self.nVersion, bitcoin.params.BASE58_PREFIXES['SECRET_KEY'])) - CKey.__init__(self, self[0:32], len(self) > 32 and _bord(self[32]) == 1) + CKey.__init__(self, self[0:32], len(self) > 32 and self[32] == 1) __all__ = ( diff --git a/examples/make-bootstrap-rpc.py b/examples/make-bootstrap-rpc.py index d2e15ce7..4279cc28 100755 --- a/examples/make-bootstrap-rpc.py +++ b/examples/make-bootstrap-rpc.py @@ -13,11 +13,6 @@ """Make a boostrap.dat file by getting the blocks from the RPC interface.""" -import sys -if sys.version_info.major < 3: - sys.stderr.write('Sorry, Python 3.x required by this example.\n') - sys.exit(1) - import bitcoin import bitcoin.rpc diff --git a/examples/msg-serializable.py b/examples/msg-serializable.py index ae6004b9..b3c5aa69 100755 --- a/examples/msg-serializable.py +++ b/examples/msg-serializable.py @@ -13,11 +13,6 @@ """Serialize some bitcoin datastructures and show them in serialized and repr form.""" -import sys -if sys.version_info.major < 3: - sys.stderr.write('Sorry, Python 3.x required by this example.\n') - sys.exit(1) - from bitcoin import SelectParams from bitcoin.messages import msg_version, msg_tx, msg_block diff --git a/examples/publish-text.py b/examples/publish-text.py index 5c0cf504..afb15c16 100755 --- a/examples/publish-text.py +++ b/examples/publish-text.py @@ -28,13 +28,7 @@ # # https://github.com/petertodd/python-bitcoinlib/commit/6a0a2b9429edea318bea7b65a68a950cae536790 -import sys -if sys.version_info.major < 3: - sys.stderr.write('Sorry, Python 3.x required by this example.\n') - sys.exit(1) - import argparse -import hashlib import logging import sys import os diff --git a/examples/spend-p2pkh-txout.py b/examples/spend-p2pkh-txout.py index 7da294a6..da2fd818 100755 --- a/examples/spend-p2pkh-txout.py +++ b/examples/spend-p2pkh-txout.py @@ -13,11 +13,6 @@ """Low-level example of how to spend a standard pay-to-pubkey-hash (P2PKH) txout""" -import sys -if sys.version_info.major < 3: - sys.stderr.write('Sorry, Python 3.x required by this example.\n') - sys.exit(1) - import hashlib from bitcoin import SelectParams diff --git a/examples/spend-p2sh-txout.py b/examples/spend-p2sh-txout.py index 9f0215b0..b28396ec 100755 --- a/examples/spend-p2sh-txout.py +++ b/examples/spend-p2sh-txout.py @@ -13,11 +13,6 @@ """Low-level example of how to spend a P2SH/BIP16 txout""" -import sys -if sys.version_info.major < 3: - sys.stderr.write('Sorry, Python 3.x required by this example.\n') - sys.exit(1) - import hashlib from bitcoin import SelectParams diff --git a/examples/spend-p2wpkh.py b/examples/spend-p2wpkh.py index 9992d388..9e499b73 100755 --- a/examples/spend-p2wpkh.py +++ b/examples/spend-p2wpkh.py @@ -14,9 +14,6 @@ """Low-level example of how to spend a P2WPKH output.""" import sys -if sys.version_info.major < 3: - sys.stderr.write("Sorry, Python 3.x required by this example.\n") - sys.exit(1) import hashlib diff --git a/examples/spend-p2wsh-txout.py b/examples/spend-p2wsh-txout.py index df1044d1..7d77c58f 100644 --- a/examples/spend-p2wsh-txout.py +++ b/examples/spend-p2wsh-txout.py @@ -13,11 +13,6 @@ """Low-level example of how to spend a P2WSH/BIP141 txout""" -import sys -if sys.version_info.major < 3: - sys.stderr.write('Sorry, Python 3.x required by this example.\n') - sys.exit(1) - import hashlib from bitcoin import SelectParams diff --git a/examples/timestamp-op-ret.py b/examples/timestamp-op-ret.py index 63d4758f..c8ae0a97 100755 --- a/examples/timestamp-op-ret.py +++ b/examples/timestamp-op-ret.py @@ -13,12 +13,6 @@ """Example of timestamping a file via OP_RETURN""" -import sys -if sys.version_info.major < 3: - sys.stderr.write('Sorry, Python 3.x required by this example.\n') - sys.exit(1) - -import hashlib import bitcoin.rpc import sys