|
|
@ -10,15 +10,6 @@ This file is modified from python-bitcoinlib.
|
|
|
|
from .mininode import CTransaction, CTxOut, sha256, hash256, uint256_from_str, ser_uint256, ser_string
|
|
|
|
from .mininode import CTransaction, CTxOut, sha256, hash256, uint256_from_str, ser_uint256, ser_string
|
|
|
|
from binascii import hexlify
|
|
|
|
from binascii import hexlify
|
|
|
|
import hashlib
|
|
|
|
import hashlib
|
|
|
|
|
|
|
|
|
|
|
|
import sys
|
|
|
|
|
|
|
|
bchr = chr
|
|
|
|
|
|
|
|
bord = ord
|
|
|
|
|
|
|
|
if sys.version > '3':
|
|
|
|
|
|
|
|
long = int
|
|
|
|
|
|
|
|
bchr = lambda x: bytes([x])
|
|
|
|
|
|
|
|
bord = lambda x: x
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import struct
|
|
|
|
import struct
|
|
|
|
|
|
|
|
|
|
|
|
from .bignum import bn2vch
|
|
|
|
from .bignum import bn2vch
|
|
|
@ -40,9 +31,9 @@ class CScriptOp(int):
|
|
|
|
def encode_op_pushdata(d):
|
|
|
|
def encode_op_pushdata(d):
|
|
|
|
"""Encode a PUSHDATA op, returning bytes"""
|
|
|
|
"""Encode a PUSHDATA op, returning bytes"""
|
|
|
|
if len(d) < 0x4c:
|
|
|
|
if len(d) < 0x4c:
|
|
|
|
return b'' + bchr(len(d)) + d # OP_PUSHDATA
|
|
|
|
return b'' + bytes([len(d)]) + d # OP_PUSHDATA
|
|
|
|
elif len(d) <= 0xff:
|
|
|
|
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:
|
|
|
|
elif len(d) <= 0xffff:
|
|
|
|
return b'\x4d' + struct.pack(b'<H', len(d)) + d # OP_PUSHDATA2
|
|
|
|
return b'\x4d' + struct.pack(b'<H', len(d)) + d # OP_PUSHDATA2
|
|
|
|
elif len(d) <= 0xffffffff:
|
|
|
|
elif len(d) <= 0xffffffff:
|
|
|
@ -388,7 +379,7 @@ class CScriptNum():
|
|
|
|
r.append(0x80 if neg else 0)
|
|
|
|
r.append(0x80 if neg else 0)
|
|
|
|
elif neg:
|
|
|
|
elif neg:
|
|
|
|
r[-1] |= 0x80
|
|
|
|
r[-1] |= 0x80
|
|
|
|
return bytes(bchr(len(r)) + r)
|
|
|
|
return bytes(bytes([len(r)]) + r)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CScript(bytes):
|
|
|
|
class CScript(bytes):
|
|
|
@ -405,17 +396,17 @@ class CScript(bytes):
|
|
|
|
def __coerce_instance(cls, other):
|
|
|
|
def __coerce_instance(cls, other):
|
|
|
|
# Coerce other into bytes
|
|
|
|
# Coerce other into bytes
|
|
|
|
if isinstance(other, CScriptOp):
|
|
|
|
if isinstance(other, CScriptOp):
|
|
|
|
other = bchr(other)
|
|
|
|
other = bytes([other])
|
|
|
|
elif isinstance(other, CScriptNum):
|
|
|
|
elif isinstance(other, CScriptNum):
|
|
|
|
if (other.value == 0):
|
|
|
|
if (other.value == 0):
|
|
|
|
other = bchr(CScriptOp(OP_0))
|
|
|
|
other = bytes([CScriptOp(OP_0)])
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
other = CScriptNum.encode(other)
|
|
|
|
other = CScriptNum.encode(other)
|
|
|
|
elif isinstance(other, int):
|
|
|
|
elif isinstance(other, int):
|
|
|
|
if 0 <= other <= 16:
|
|
|
|
if 0 <= other <= 16:
|
|
|
|
other = bytes(bchr(CScriptOp.encode_op_n(other)))
|
|
|
|
other = bytes(bytes([CScriptOp.encode_op_n(other)]))
|
|
|
|
elif other == -1:
|
|
|
|
elif other == -1:
|
|
|
|
other = bytes(bchr(OP_1NEGATE))
|
|
|
|
other = bytes(bytes([OP_1NEGATE]))
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
other = CScriptOp.encode_op_pushdata(bn2vch(other))
|
|
|
|
other = CScriptOp.encode_op_pushdata(bn2vch(other))
|
|
|
|
elif isinstance(other, (bytes, bytearray)):
|
|
|
|
elif isinstance(other, (bytes, bytearray)):
|
|
|
@ -458,7 +449,7 @@ class CScript(bytes):
|
|
|
|
i = 0
|
|
|
|
i = 0
|
|
|
|
while i < len(self):
|
|
|
|
while i < len(self):
|
|
|
|
sop_idx = i
|
|
|
|
sop_idx = i
|
|
|
|
opcode = bord(self[i])
|
|
|
|
opcode = self[i]
|
|
|
|
i += 1
|
|
|
|
i += 1
|
|
|
|
|
|
|
|
|
|
|
|
if opcode > OP_PUSHDATA4:
|
|
|
|
if opcode > OP_PUSHDATA4:
|
|
|
@ -474,21 +465,21 @@ class CScript(bytes):
|
|
|
|
pushdata_type = 'PUSHDATA1'
|
|
|
|
pushdata_type = 'PUSHDATA1'
|
|
|
|
if i >= len(self):
|
|
|
|
if i >= len(self):
|
|
|
|
raise CScriptInvalidError('PUSHDATA1: missing data length')
|
|
|
|
raise CScriptInvalidError('PUSHDATA1: missing data length')
|
|
|
|
datasize = bord(self[i])
|
|
|
|
datasize = self[i]
|
|
|
|
i += 1
|
|
|
|
i += 1
|
|
|
|
|
|
|
|
|
|
|
|
elif opcode == OP_PUSHDATA2:
|
|
|
|
elif opcode == OP_PUSHDATA2:
|
|
|
|
pushdata_type = 'PUSHDATA2'
|
|
|
|
pushdata_type = 'PUSHDATA2'
|
|
|
|
if i + 1 >= len(self):
|
|
|
|
if i + 1 >= len(self):
|
|
|
|
raise CScriptInvalidError('PUSHDATA2: missing data length')
|
|
|
|
raise CScriptInvalidError('PUSHDATA2: missing data length')
|
|
|
|
datasize = bord(self[i]) + (bord(self[i+1]) << 8)
|
|
|
|
datasize = self[i] + (self[i+1] << 8)
|
|
|
|
i += 2
|
|
|
|
i += 2
|
|
|
|
|
|
|
|
|
|
|
|
elif opcode == OP_PUSHDATA4:
|
|
|
|
elif opcode == OP_PUSHDATA4:
|
|
|
|
pushdata_type = 'PUSHDATA4'
|
|
|
|
pushdata_type = 'PUSHDATA4'
|
|
|
|
if i + 3 >= len(self):
|
|
|
|
if i + 3 >= len(self):
|
|
|
|
raise CScriptInvalidError('PUSHDATA4: missing data length')
|
|
|
|
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
|
|
|
|
i += 4
|
|
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|