Browse Source

Remove dead code.

Also use native python3 functions to speed up 2 lib functions
master
Neil Booth 8 years ago
parent
commit
8e6e8329ac
  1. 76
      lib/script.py
  2. 13
      lib/util.py

76
lib/script.py

@ -12,8 +12,6 @@ import struct
from collections import namedtuple
from lib.enum import Enumeration
from lib.hash import hash160
from lib.util import cachedproperty
class ScriptError(Exception):
@ -58,80 +56,6 @@ assert OpCodes.OP_CHECKSIG == 0xac
assert OpCodes.OP_CHECKMULTISIG == 0xae
class ScriptSig(object):
'''A script from a tx input.
Typically provides one or more signatures.'''
SIG_ADDRESS, SIG_MULTI, SIG_PUBKEY, SIG_UNKNOWN = range(4)
def __init__(self, script, coin, kind, sigs, pubkeys):
self.script = script
self.coin = coin
self.kind = kind
self.sigs = sigs
self.pubkeys = pubkeys
@cachedproperty
def address(self):
if self.kind == SIG_ADDRESS:
return self.coin.address_from_pubkey(self.pubkeys[0])
if self.kind == SIG_MULTI:
return self.coin.multsig_address(self.pubkeys)
return 'Unknown'
@classmethod
def from_script(cls, script, coin):
'''Return an instance of this class.
Return an object with kind SIG_UNKNOWN for unrecognised scripts.'''
try:
return cls.parse_script(script, coin)
except ScriptError:
return cls(script, coin, SIG_UNKNOWN, [], [])
@classmethod
def parse_script(cls, script, coin):
'''Return an instance of this class.
Raises on unrecognised scripts.'''
ops, datas = Script.get_ops(script)
# Address, PubKey and P2SH redeems only push data
if not ops or not Script.match_ops(ops, [-1] * len(ops)):
raise ScriptError('unknown scriptsig pattern')
# Assume double data pushes are address redeems, single data
# pushes are pubkey redeems
if len(ops) == 2: # Signature, pubkey
return cls(script, coin, SIG_ADDRESS, [datas[0]], [datas[1]])
if len(ops) == 1: # Pubkey
return cls(script, coin, SIG_PUBKEY, [datas[0]], [])
# Presumably it is P2SH (though conceivably the above could be
# too; cannot be sure without the send-to script). We only
# handle CHECKMULTISIG P2SH, which because of a bitcoin core
# bug always start with an unused OP_0.
if ops[0] != OpCodes.OP_0:
raise ScriptError('unknown scriptsig pattern; expected OP_0')
# OP_0, Sig1, ..., SigM, pk_script
m = len(ops) - 2
pk_script = datas[-1]
pk_ops, pk_datas = Script.get_ops(script)
# OP_2 pubkey1 pubkey2 pubkey3 OP_3 OP_CHECKMULTISIG
n = len(pk_ops) - 3
pattern = ([OpCodes.OP_1 + m - 1] + [-1] * n
+ [OpCodes.OP_1 + n - 1, OpCodes.OP_CHECKMULTISIG])
if m <= n and Script.match_ops(pk_ops, pattern):
return cls(script, coin, SIG_MULTI, datas[1:-1], pk_datas[1:-2])
raise ScriptError('unknown multisig P2SH pattern')
class ScriptPubKey(object):
'''A class for handling a tx output script that gives conditions
necessary for spending.

13
lib/util.py

@ -82,6 +82,7 @@ def subclasses(base_class, strict=True):
pairs = inspect.getmembers(sys.modules[base_class.__module__], select)
return [pair[1] for pair in pairs]
def chunks(items, size):
'''Break up items, an iterable, into chunks of length size.'''
for i in range(0, len(items), size):
@ -90,20 +91,12 @@ def chunks(items, size):
def bytes_to_int(be_bytes):
'''Interprets a big-endian sequence of bytes as an integer'''
assert isinstance(be_bytes, (bytes, bytearray))
value = 0
for byte in be_bytes:
value = value * 256 + byte
return value
return int.from_bytes(be_bytes, 'big')
def int_to_bytes(value):
'''Converts an integer to a big-endian sequence of bytes'''
mods = []
while value:
value, mod = divmod(value, 256)
mods.append(mod)
return bytes(reversed(mods))
return value.to_bytes((value.bit_length() + 7) // 8, 'big')
def increment_byte_string(bs):

Loading…
Cancel
Save