Remove dead code.
Also use native python3 functions to speed up 2 lib functions
This commit is contained in:
parent
604698ad0d
commit
8e6e8329ac
@ -12,8 +12,6 @@ import struct
|
|||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
from lib.enum import Enumeration
|
from lib.enum import Enumeration
|
||||||
from lib.hash import hash160
|
|
||||||
from lib.util import cachedproperty
|
|
||||||
|
|
||||||
|
|
||||||
class ScriptError(Exception):
|
class ScriptError(Exception):
|
||||||
@ -58,80 +56,6 @@ assert OpCodes.OP_CHECKSIG == 0xac
|
|||||||
assert OpCodes.OP_CHECKMULTISIG == 0xae
|
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):
|
class ScriptPubKey(object):
|
||||||
'''A class for handling a tx output script that gives conditions
|
'''A class for handling a tx output script that gives conditions
|
||||||
necessary for spending.
|
necessary for spending.
|
||||||
|
|||||||
13
lib/util.py
13
lib/util.py
@ -82,6 +82,7 @@ def subclasses(base_class, strict=True):
|
|||||||
pairs = inspect.getmembers(sys.modules[base_class.__module__], select)
|
pairs = inspect.getmembers(sys.modules[base_class.__module__], select)
|
||||||
return [pair[1] for pair in pairs]
|
return [pair[1] for pair in pairs]
|
||||||
|
|
||||||
|
|
||||||
def chunks(items, size):
|
def chunks(items, size):
|
||||||
'''Break up items, an iterable, into chunks of length size.'''
|
'''Break up items, an iterable, into chunks of length size.'''
|
||||||
for i in range(0, len(items), size):
|
for i in range(0, len(items), size):
|
||||||
@ -90,20 +91,12 @@ def chunks(items, size):
|
|||||||
|
|
||||||
def bytes_to_int(be_bytes):
|
def bytes_to_int(be_bytes):
|
||||||
'''Interprets a big-endian sequence of bytes as an integer'''
|
'''Interprets a big-endian sequence of bytes as an integer'''
|
||||||
assert isinstance(be_bytes, (bytes, bytearray))
|
return int.from_bytes(be_bytes, 'big')
|
||||||
value = 0
|
|
||||||
for byte in be_bytes:
|
|
||||||
value = value * 256 + byte
|
|
||||||
return value
|
|
||||||
|
|
||||||
|
|
||||||
def int_to_bytes(value):
|
def int_to_bytes(value):
|
||||||
'''Converts an integer to a big-endian sequence of bytes'''
|
'''Converts an integer to a big-endian sequence of bytes'''
|
||||||
mods = []
|
return value.to_bytes((value.bit_length() + 7) // 8, 'big')
|
||||||
while value:
|
|
||||||
value, mod = divmod(value, 256)
|
|
||||||
mods.append(mod)
|
|
||||||
return bytes(reversed(mods))
|
|
||||||
|
|
||||||
|
|
||||||
def increment_byte_string(bs):
|
def increment_byte_string(bs):
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user