1 from p2pool.util import math, pack
6 return lambda f: pack.read(f, length)
7 def protoPUSHDATA(size_len):
9 length_str, f = pack.read(f, size_len)
10 length = math.string_to_natural(length_str[::-1].lstrip(chr(0)))
11 data, f = pack.read(f, length)
17 opcodes[i] = 'UNK_' + str(i), reads_nothing
19 opcodes[0] = 'PUSH', lambda f: ('', f)
20 for i in xrange(1, 76):
21 opcodes[i] = 'PUSH', protoPUSH(i)
22 opcodes[76] = 'PUSH', protoPUSHDATA(1)
23 opcodes[77] = 'PUSH', protoPUSHDATA(2)
24 opcodes[78] = 'PUSH', protoPUSHDATA(4)
25 opcodes[79] = 'PUSH', lambda f: ('\x81', f)
26 for i in xrange(81, 97):
27 opcodes[i] = 'PUSH', lambda f, _i=i: (chr(_i - 80), f)
29 opcodes[172] = 'CHECKSIG', reads_nothing
30 opcodes[173] = 'CHECKSIGVERIFY', reads_nothing
31 opcodes[174] = 'CHECKMULTISIG', reads_nothing
32 opcodes[175] = 'CHECKMULTISIGVERIFY', reads_nothing
37 opcode_str, f = pack.read(f, 1)
38 opcode = ord(opcode_str)
39 opcode_name, read_func = opcodes[opcode]
40 opcode_arg, f = read_func(f)
41 yield opcode_name, opcode_arg
43 def get_sigop_count(script):
48 'CHECKMULTISIGVERIFY': 20,
50 return sum(weights.get(opcode_name, 0) for opcode_name, opcode_arg in parse(script))
52 def create_push_script(datums): # datums can be ints or strs
55 if isinstance(datum, (int, long)):
56 if datum == -1 or 1 <= datum <= 16:
57 res.append(chr(datum + 80))
60 datum = math.natural_to_string(abs(datum))
61 if datum and ord(datum[0]) & 128:
62 datum = '\x00' + datum
64 datum = chr(ord(datum[0]) + 128) + datum[1:]
67 res.append(chr(len(datum)))
68 elif len(datum) <= 0xff:
70 res.append(chr(len(datum)))
71 elif len(datum) <= 0xffff:
73 res.append(pack.IntType(16).pack(len(datum)))
74 elif len(datum) <= 0xffffffff:
76 res.append(pack.IntType(32).pack(len(datum)))
78 raise ValueError('string too long')