aboutsummaryrefslogtreecommitdiff
path: root/qa/rpc-tests/test_framework/script.py
diff options
context:
space:
mode:
Diffstat (limited to 'qa/rpc-tests/test_framework/script.py')
-rw-r--r--qa/rpc-tests/test_framework/script.py939
1 files changed, 0 insertions, 939 deletions
diff --git a/qa/rpc-tests/test_framework/script.py b/qa/rpc-tests/test_framework/script.py
deleted file mode 100644
index 3d9572788e..0000000000
--- a/qa/rpc-tests/test_framework/script.py
+++ /dev/null
@@ -1,939 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (c) 2015-2016 The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-"""Functionality to build scripts, as well as SignatureHash().
-
-This file is modified from python-bitcoinlib.
-"""
-
-from .mininode import CTransaction, CTxOut, sha256, hash256, uint256_from_str, ser_uint256, ser_string
-from binascii import hexlify
-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
-
-from .bignum import bn2vch
-
-MAX_SCRIPT_SIZE = 10000
-MAX_SCRIPT_ELEMENT_SIZE = 520
-MAX_SCRIPT_OPCODES = 201
-
-OPCODE_NAMES = {}
-
-def hash160(s):
- return hashlib.new('ripemd160', sha256(s)).digest()
-
-
-_opcode_instances = []
-class CScriptOp(int):
- """A single script opcode"""
- __slots__ = []
-
- @staticmethod
- def encode_op_pushdata(d):
- """Encode a PUSHDATA op, returning bytes"""
- if len(d) < 0x4c:
- return b'' + bchr(len(d)) + d # OP_PUSHDATA
- elif len(d) <= 0xff:
- return b'\x4c' + bchr(len(d)) + d # OP_PUSHDATA1
- elif len(d) <= 0xffff:
- return b'\x4d' + struct.pack(b'<H', len(d)) + d # OP_PUSHDATA2
- elif len(d) <= 0xffffffff:
- return b'\x4e' + struct.pack(b'<I', len(d)) + d # OP_PUSHDATA4
- else:
- raise ValueError("Data too long to encode in a PUSHDATA op")
-
- @staticmethod
- def encode_op_n(n):
- """Encode a small integer op, returning an opcode"""
- if not (0 <= n <= 16):
- raise ValueError('Integer must be in range 0 <= n <= 16, got %d' % n)
-
- if n == 0:
- return OP_0
- else:
- return CScriptOp(OP_1 + n-1)
-
- def decode_op_n(self):
- """Decode a small integer opcode, returning an integer"""
- if self == OP_0:
- return 0
-
- if not (self == OP_0 or OP_1 <= self <= OP_16):
- raise ValueError('op %r is not an OP_N' % self)
-
- return int(self - OP_1+1)
-
- def is_small_int(self):
- """Return true if the op pushes a small integer to the stack"""
- if 0x51 <= self <= 0x60 or self == 0:
- return True
- else:
- return False
-
- def __str__(self):
- return repr(self)
-
- def __repr__(self):
- if self in OPCODE_NAMES:
- return OPCODE_NAMES[self]
- else:
- return 'CScriptOp(0x%x)' % self
-
- def __new__(cls, n):
- try:
- return _opcode_instances[n]
- except IndexError:
- assert len(_opcode_instances) == n
- _opcode_instances.append(super(CScriptOp, cls).__new__(cls, n))
- return _opcode_instances[n]
-
-# Populate opcode instance table
-for n in range(0xff+1):
- CScriptOp(n)
-
-
-# push value
-OP_0 = CScriptOp(0x00)
-OP_FALSE = OP_0
-OP_PUSHDATA1 = CScriptOp(0x4c)
-OP_PUSHDATA2 = CScriptOp(0x4d)
-OP_PUSHDATA4 = CScriptOp(0x4e)
-OP_1NEGATE = CScriptOp(0x4f)
-OP_RESERVED = CScriptOp(0x50)
-OP_1 = CScriptOp(0x51)
-OP_TRUE=OP_1
-OP_2 = CScriptOp(0x52)
-OP_3 = CScriptOp(0x53)
-OP_4 = CScriptOp(0x54)
-OP_5 = CScriptOp(0x55)
-OP_6 = CScriptOp(0x56)
-OP_7 = CScriptOp(0x57)
-OP_8 = CScriptOp(0x58)
-OP_9 = CScriptOp(0x59)
-OP_10 = CScriptOp(0x5a)
-OP_11 = CScriptOp(0x5b)
-OP_12 = CScriptOp(0x5c)
-OP_13 = CScriptOp(0x5d)
-OP_14 = CScriptOp(0x5e)
-OP_15 = CScriptOp(0x5f)
-OP_16 = CScriptOp(0x60)
-
-# control
-OP_NOP = CScriptOp(0x61)
-OP_VER = CScriptOp(0x62)
-OP_IF = CScriptOp(0x63)
-OP_NOTIF = CScriptOp(0x64)
-OP_VERIF = CScriptOp(0x65)
-OP_VERNOTIF = CScriptOp(0x66)
-OP_ELSE = CScriptOp(0x67)
-OP_ENDIF = CScriptOp(0x68)
-OP_VERIFY = CScriptOp(0x69)
-OP_RETURN = CScriptOp(0x6a)
-
-# stack ops
-OP_TOALTSTACK = CScriptOp(0x6b)
-OP_FROMALTSTACK = CScriptOp(0x6c)
-OP_2DROP = CScriptOp(0x6d)
-OP_2DUP = CScriptOp(0x6e)
-OP_3DUP = CScriptOp(0x6f)
-OP_2OVER = CScriptOp(0x70)
-OP_2ROT = CScriptOp(0x71)
-OP_2SWAP = CScriptOp(0x72)
-OP_IFDUP = CScriptOp(0x73)
-OP_DEPTH = CScriptOp(0x74)
-OP_DROP = CScriptOp(0x75)
-OP_DUP = CScriptOp(0x76)
-OP_NIP = CScriptOp(0x77)
-OP_OVER = CScriptOp(0x78)
-OP_PICK = CScriptOp(0x79)
-OP_ROLL = CScriptOp(0x7a)
-OP_ROT = CScriptOp(0x7b)
-OP_SWAP = CScriptOp(0x7c)
-OP_TUCK = CScriptOp(0x7d)
-
-# splice ops
-OP_CAT = CScriptOp(0x7e)
-OP_SUBSTR = CScriptOp(0x7f)
-OP_LEFT = CScriptOp(0x80)
-OP_RIGHT = CScriptOp(0x81)
-OP_SIZE = CScriptOp(0x82)
-
-# bit logic
-OP_INVERT = CScriptOp(0x83)
-OP_AND = CScriptOp(0x84)
-OP_OR = CScriptOp(0x85)
-OP_XOR = CScriptOp(0x86)
-OP_EQUAL = CScriptOp(0x87)
-OP_EQUALVERIFY = CScriptOp(0x88)
-OP_RESERVED1 = CScriptOp(0x89)
-OP_RESERVED2 = CScriptOp(0x8a)
-
-# numeric
-OP_1ADD = CScriptOp(0x8b)
-OP_1SUB = CScriptOp(0x8c)
-OP_2MUL = CScriptOp(0x8d)
-OP_2DIV = CScriptOp(0x8e)
-OP_NEGATE = CScriptOp(0x8f)
-OP_ABS = CScriptOp(0x90)
-OP_NOT = CScriptOp(0x91)
-OP_0NOTEQUAL = CScriptOp(0x92)
-
-OP_ADD = CScriptOp(0x93)
-OP_SUB = CScriptOp(0x94)
-OP_MUL = CScriptOp(0x95)
-OP_DIV = CScriptOp(0x96)
-OP_MOD = CScriptOp(0x97)
-OP_LSHIFT = CScriptOp(0x98)
-OP_RSHIFT = CScriptOp(0x99)
-
-OP_BOOLAND = CScriptOp(0x9a)
-OP_BOOLOR = CScriptOp(0x9b)
-OP_NUMEQUAL = CScriptOp(0x9c)
-OP_NUMEQUALVERIFY = CScriptOp(0x9d)
-OP_NUMNOTEQUAL = CScriptOp(0x9e)
-OP_LESSTHAN = CScriptOp(0x9f)
-OP_GREATERTHAN = CScriptOp(0xa0)
-OP_LESSTHANOREQUAL = CScriptOp(0xa1)
-OP_GREATERTHANOREQUAL = CScriptOp(0xa2)
-OP_MIN = CScriptOp(0xa3)
-OP_MAX = CScriptOp(0xa4)
-
-OP_WITHIN = CScriptOp(0xa5)
-
-# crypto
-OP_RIPEMD160 = CScriptOp(0xa6)
-OP_SHA1 = CScriptOp(0xa7)
-OP_SHA256 = CScriptOp(0xa8)
-OP_HASH160 = CScriptOp(0xa9)
-OP_HASH256 = CScriptOp(0xaa)
-OP_CODESEPARATOR = CScriptOp(0xab)
-OP_CHECKSIG = CScriptOp(0xac)
-OP_CHECKSIGVERIFY = CScriptOp(0xad)
-OP_CHECKMULTISIG = CScriptOp(0xae)
-OP_CHECKMULTISIGVERIFY = CScriptOp(0xaf)
-
-# expansion
-OP_NOP1 = CScriptOp(0xb0)
-OP_CHECKLOCKTIMEVERIFY = CScriptOp(0xb1)
-OP_CHECKSEQUENCEVERIFY = CScriptOp(0xb2)
-OP_NOP4 = CScriptOp(0xb3)
-OP_NOP5 = CScriptOp(0xb4)
-OP_NOP6 = CScriptOp(0xb5)
-OP_NOP7 = CScriptOp(0xb6)
-OP_NOP8 = CScriptOp(0xb7)
-OP_NOP9 = CScriptOp(0xb8)
-OP_NOP10 = CScriptOp(0xb9)
-
-# template matching params
-OP_SMALLINTEGER = CScriptOp(0xfa)
-OP_PUBKEYS = CScriptOp(0xfb)
-OP_PUBKEYHASH = CScriptOp(0xfd)
-OP_PUBKEY = CScriptOp(0xfe)
-
-OP_INVALIDOPCODE = CScriptOp(0xff)
-
-VALID_OPCODES = {
- OP_1NEGATE,
- OP_RESERVED,
- OP_1,
- OP_2,
- OP_3,
- OP_4,
- OP_5,
- OP_6,
- OP_7,
- OP_8,
- OP_9,
- OP_10,
- OP_11,
- OP_12,
- OP_13,
- OP_14,
- OP_15,
- OP_16,
-
- OP_NOP,
- OP_VER,
- OP_IF,
- OP_NOTIF,
- OP_VERIF,
- OP_VERNOTIF,
- OP_ELSE,
- OP_ENDIF,
- OP_VERIFY,
- OP_RETURN,
-
- OP_TOALTSTACK,
- OP_FROMALTSTACK,
- OP_2DROP,
- OP_2DUP,
- OP_3DUP,
- OP_2OVER,
- OP_2ROT,
- OP_2SWAP,
- OP_IFDUP,
- OP_DEPTH,
- OP_DROP,
- OP_DUP,
- OP_NIP,
- OP_OVER,
- OP_PICK,
- OP_ROLL,
- OP_ROT,
- OP_SWAP,
- OP_TUCK,
-
- OP_CAT,
- OP_SUBSTR,
- OP_LEFT,
- OP_RIGHT,
- OP_SIZE,
-
- OP_INVERT,
- OP_AND,
- OP_OR,
- OP_XOR,
- OP_EQUAL,
- OP_EQUALVERIFY,
- OP_RESERVED1,
- OP_RESERVED2,
-
- OP_1ADD,
- OP_1SUB,
- OP_2MUL,
- OP_2DIV,
- OP_NEGATE,
- OP_ABS,
- OP_NOT,
- OP_0NOTEQUAL,
-
- OP_ADD,
- OP_SUB,
- OP_MUL,
- OP_DIV,
- OP_MOD,
- OP_LSHIFT,
- OP_RSHIFT,
-
- OP_BOOLAND,
- OP_BOOLOR,
- OP_NUMEQUAL,
- OP_NUMEQUALVERIFY,
- OP_NUMNOTEQUAL,
- OP_LESSTHAN,
- OP_GREATERTHAN,
- OP_LESSTHANOREQUAL,
- OP_GREATERTHANOREQUAL,
- OP_MIN,
- OP_MAX,
-
- OP_WITHIN,
-
- OP_RIPEMD160,
- OP_SHA1,
- OP_SHA256,
- OP_HASH160,
- OP_HASH256,
- OP_CODESEPARATOR,
- OP_CHECKSIG,
- OP_CHECKSIGVERIFY,
- OP_CHECKMULTISIG,
- OP_CHECKMULTISIGVERIFY,
-
- OP_NOP1,
- OP_CHECKLOCKTIMEVERIFY,
- OP_CHECKSEQUENCEVERIFY,
- OP_NOP4,
- OP_NOP5,
- OP_NOP6,
- OP_NOP7,
- OP_NOP8,
- OP_NOP9,
- OP_NOP10,
-
- OP_SMALLINTEGER,
- OP_PUBKEYS,
- OP_PUBKEYHASH,
- OP_PUBKEY,
-}
-
-OPCODE_NAMES.update({
- OP_0 : 'OP_0',
- OP_PUSHDATA1 : 'OP_PUSHDATA1',
- OP_PUSHDATA2 : 'OP_PUSHDATA2',
- OP_PUSHDATA4 : 'OP_PUSHDATA4',
- OP_1NEGATE : 'OP_1NEGATE',
- OP_RESERVED : 'OP_RESERVED',
- OP_1 : 'OP_1',
- OP_2 : 'OP_2',
- OP_3 : 'OP_3',
- OP_4 : 'OP_4',
- OP_5 : 'OP_5',
- OP_6 : 'OP_6',
- OP_7 : 'OP_7',
- OP_8 : 'OP_8',
- OP_9 : 'OP_9',
- OP_10 : 'OP_10',
- OP_11 : 'OP_11',
- OP_12 : 'OP_12',
- OP_13 : 'OP_13',
- OP_14 : 'OP_14',
- OP_15 : 'OP_15',
- OP_16 : 'OP_16',
- OP_NOP : 'OP_NOP',
- OP_VER : 'OP_VER',
- OP_IF : 'OP_IF',
- OP_NOTIF : 'OP_NOTIF',
- OP_VERIF : 'OP_VERIF',
- OP_VERNOTIF : 'OP_VERNOTIF',
- OP_ELSE : 'OP_ELSE',
- OP_ENDIF : 'OP_ENDIF',
- OP_VERIFY : 'OP_VERIFY',
- OP_RETURN : 'OP_RETURN',
- OP_TOALTSTACK : 'OP_TOALTSTACK',
- OP_FROMALTSTACK : 'OP_FROMALTSTACK',
- OP_2DROP : 'OP_2DROP',
- OP_2DUP : 'OP_2DUP',
- OP_3DUP : 'OP_3DUP',
- OP_2OVER : 'OP_2OVER',
- OP_2ROT : 'OP_2ROT',
- OP_2SWAP : 'OP_2SWAP',
- OP_IFDUP : 'OP_IFDUP',
- OP_DEPTH : 'OP_DEPTH',
- OP_DROP : 'OP_DROP',
- OP_DUP : 'OP_DUP',
- OP_NIP : 'OP_NIP',
- OP_OVER : 'OP_OVER',
- OP_PICK : 'OP_PICK',
- OP_ROLL : 'OP_ROLL',
- OP_ROT : 'OP_ROT',
- OP_SWAP : 'OP_SWAP',
- OP_TUCK : 'OP_TUCK',
- OP_CAT : 'OP_CAT',
- OP_SUBSTR : 'OP_SUBSTR',
- OP_LEFT : 'OP_LEFT',
- OP_RIGHT : 'OP_RIGHT',
- OP_SIZE : 'OP_SIZE',
- OP_INVERT : 'OP_INVERT',
- OP_AND : 'OP_AND',
- OP_OR : 'OP_OR',
- OP_XOR : 'OP_XOR',
- OP_EQUAL : 'OP_EQUAL',
- OP_EQUALVERIFY : 'OP_EQUALVERIFY',
- OP_RESERVED1 : 'OP_RESERVED1',
- OP_RESERVED2 : 'OP_RESERVED2',
- OP_1ADD : 'OP_1ADD',
- OP_1SUB : 'OP_1SUB',
- OP_2MUL : 'OP_2MUL',
- OP_2DIV : 'OP_2DIV',
- OP_NEGATE : 'OP_NEGATE',
- OP_ABS : 'OP_ABS',
- OP_NOT : 'OP_NOT',
- OP_0NOTEQUAL : 'OP_0NOTEQUAL',
- OP_ADD : 'OP_ADD',
- OP_SUB : 'OP_SUB',
- OP_MUL : 'OP_MUL',
- OP_DIV : 'OP_DIV',
- OP_MOD : 'OP_MOD',
- OP_LSHIFT : 'OP_LSHIFT',
- OP_RSHIFT : 'OP_RSHIFT',
- OP_BOOLAND : 'OP_BOOLAND',
- OP_BOOLOR : 'OP_BOOLOR',
- OP_NUMEQUAL : 'OP_NUMEQUAL',
- OP_NUMEQUALVERIFY : 'OP_NUMEQUALVERIFY',
- OP_NUMNOTEQUAL : 'OP_NUMNOTEQUAL',
- OP_LESSTHAN : 'OP_LESSTHAN',
- OP_GREATERTHAN : 'OP_GREATERTHAN',
- OP_LESSTHANOREQUAL : 'OP_LESSTHANOREQUAL',
- OP_GREATERTHANOREQUAL : 'OP_GREATERTHANOREQUAL',
- OP_MIN : 'OP_MIN',
- OP_MAX : 'OP_MAX',
- OP_WITHIN : 'OP_WITHIN',
- OP_RIPEMD160 : 'OP_RIPEMD160',
- OP_SHA1 : 'OP_SHA1',
- OP_SHA256 : 'OP_SHA256',
- OP_HASH160 : 'OP_HASH160',
- OP_HASH256 : 'OP_HASH256',
- OP_CODESEPARATOR : 'OP_CODESEPARATOR',
- OP_CHECKSIG : 'OP_CHECKSIG',
- OP_CHECKSIGVERIFY : 'OP_CHECKSIGVERIFY',
- OP_CHECKMULTISIG : 'OP_CHECKMULTISIG',
- OP_CHECKMULTISIGVERIFY : 'OP_CHECKMULTISIGVERIFY',
- OP_NOP1 : 'OP_NOP1',
- OP_CHECKLOCKTIMEVERIFY : 'OP_CHECKLOCKTIMEVERIFY',
- OP_CHECKSEQUENCEVERIFY : 'OP_CHECKSEQUENCEVERIFY',
- OP_NOP4 : 'OP_NOP4',
- OP_NOP5 : 'OP_NOP5',
- OP_NOP6 : 'OP_NOP6',
- OP_NOP7 : 'OP_NOP7',
- OP_NOP8 : 'OP_NOP8',
- OP_NOP9 : 'OP_NOP9',
- OP_NOP10 : 'OP_NOP10',
- OP_SMALLINTEGER : 'OP_SMALLINTEGER',
- OP_PUBKEYS : 'OP_PUBKEYS',
- OP_PUBKEYHASH : 'OP_PUBKEYHASH',
- OP_PUBKEY : 'OP_PUBKEY',
- OP_INVALIDOPCODE : 'OP_INVALIDOPCODE',
-})
-
-OPCODES_BY_NAME = {
- 'OP_0' : OP_0,
- 'OP_PUSHDATA1' : OP_PUSHDATA1,
- 'OP_PUSHDATA2' : OP_PUSHDATA2,
- 'OP_PUSHDATA4' : OP_PUSHDATA4,
- 'OP_1NEGATE' : OP_1NEGATE,
- 'OP_RESERVED' : OP_RESERVED,
- 'OP_1' : OP_1,
- 'OP_2' : OP_2,
- 'OP_3' : OP_3,
- 'OP_4' : OP_4,
- 'OP_5' : OP_5,
- 'OP_6' : OP_6,
- 'OP_7' : OP_7,
- 'OP_8' : OP_8,
- 'OP_9' : OP_9,
- 'OP_10' : OP_10,
- 'OP_11' : OP_11,
- 'OP_12' : OP_12,
- 'OP_13' : OP_13,
- 'OP_14' : OP_14,
- 'OP_15' : OP_15,
- 'OP_16' : OP_16,
- 'OP_NOP' : OP_NOP,
- 'OP_VER' : OP_VER,
- 'OP_IF' : OP_IF,
- 'OP_NOTIF' : OP_NOTIF,
- 'OP_VERIF' : OP_VERIF,
- 'OP_VERNOTIF' : OP_VERNOTIF,
- 'OP_ELSE' : OP_ELSE,
- 'OP_ENDIF' : OP_ENDIF,
- 'OP_VERIFY' : OP_VERIFY,
- 'OP_RETURN' : OP_RETURN,
- 'OP_TOALTSTACK' : OP_TOALTSTACK,
- 'OP_FROMALTSTACK' : OP_FROMALTSTACK,
- 'OP_2DROP' : OP_2DROP,
- 'OP_2DUP' : OP_2DUP,
- 'OP_3DUP' : OP_3DUP,
- 'OP_2OVER' : OP_2OVER,
- 'OP_2ROT' : OP_2ROT,
- 'OP_2SWAP' : OP_2SWAP,
- 'OP_IFDUP' : OP_IFDUP,
- 'OP_DEPTH' : OP_DEPTH,
- 'OP_DROP' : OP_DROP,
- 'OP_DUP' : OP_DUP,
- 'OP_NIP' : OP_NIP,
- 'OP_OVER' : OP_OVER,
- 'OP_PICK' : OP_PICK,
- 'OP_ROLL' : OP_ROLL,
- 'OP_ROT' : OP_ROT,
- 'OP_SWAP' : OP_SWAP,
- 'OP_TUCK' : OP_TUCK,
- 'OP_CAT' : OP_CAT,
- 'OP_SUBSTR' : OP_SUBSTR,
- 'OP_LEFT' : OP_LEFT,
- 'OP_RIGHT' : OP_RIGHT,
- 'OP_SIZE' : OP_SIZE,
- 'OP_INVERT' : OP_INVERT,
- 'OP_AND' : OP_AND,
- 'OP_OR' : OP_OR,
- 'OP_XOR' : OP_XOR,
- 'OP_EQUAL' : OP_EQUAL,
- 'OP_EQUALVERIFY' : OP_EQUALVERIFY,
- 'OP_RESERVED1' : OP_RESERVED1,
- 'OP_RESERVED2' : OP_RESERVED2,
- 'OP_1ADD' : OP_1ADD,
- 'OP_1SUB' : OP_1SUB,
- 'OP_2MUL' : OP_2MUL,
- 'OP_2DIV' : OP_2DIV,
- 'OP_NEGATE' : OP_NEGATE,
- 'OP_ABS' : OP_ABS,
- 'OP_NOT' : OP_NOT,
- 'OP_0NOTEQUAL' : OP_0NOTEQUAL,
- 'OP_ADD' : OP_ADD,
- 'OP_SUB' : OP_SUB,
- 'OP_MUL' : OP_MUL,
- 'OP_DIV' : OP_DIV,
- 'OP_MOD' : OP_MOD,
- 'OP_LSHIFT' : OP_LSHIFT,
- 'OP_RSHIFT' : OP_RSHIFT,
- 'OP_BOOLAND' : OP_BOOLAND,
- 'OP_BOOLOR' : OP_BOOLOR,
- 'OP_NUMEQUAL' : OP_NUMEQUAL,
- 'OP_NUMEQUALVERIFY' : OP_NUMEQUALVERIFY,
- 'OP_NUMNOTEQUAL' : OP_NUMNOTEQUAL,
- 'OP_LESSTHAN' : OP_LESSTHAN,
- 'OP_GREATERTHAN' : OP_GREATERTHAN,
- 'OP_LESSTHANOREQUAL' : OP_LESSTHANOREQUAL,
- 'OP_GREATERTHANOREQUAL' : OP_GREATERTHANOREQUAL,
- 'OP_MIN' : OP_MIN,
- 'OP_MAX' : OP_MAX,
- 'OP_WITHIN' : OP_WITHIN,
- 'OP_RIPEMD160' : OP_RIPEMD160,
- 'OP_SHA1' : OP_SHA1,
- 'OP_SHA256' : OP_SHA256,
- 'OP_HASH160' : OP_HASH160,
- 'OP_HASH256' : OP_HASH256,
- 'OP_CODESEPARATOR' : OP_CODESEPARATOR,
- 'OP_CHECKSIG' : OP_CHECKSIG,
- 'OP_CHECKSIGVERIFY' : OP_CHECKSIGVERIFY,
- 'OP_CHECKMULTISIG' : OP_CHECKMULTISIG,
- 'OP_CHECKMULTISIGVERIFY' : OP_CHECKMULTISIGVERIFY,
- 'OP_NOP1' : OP_NOP1,
- 'OP_CHECKLOCKTIMEVERIFY' : OP_CHECKLOCKTIMEVERIFY,
- 'OP_CHECKSEQUENCEVERIFY' : OP_CHECKSEQUENCEVERIFY,
- 'OP_NOP4' : OP_NOP4,
- 'OP_NOP5' : OP_NOP5,
- 'OP_NOP6' : OP_NOP6,
- 'OP_NOP7' : OP_NOP7,
- 'OP_NOP8' : OP_NOP8,
- 'OP_NOP9' : OP_NOP9,
- 'OP_NOP10' : OP_NOP10,
- 'OP_SMALLINTEGER' : OP_SMALLINTEGER,
- 'OP_PUBKEYS' : OP_PUBKEYS,
- 'OP_PUBKEYHASH' : OP_PUBKEYHASH,
- 'OP_PUBKEY' : OP_PUBKEY,
-}
-
-class CScriptInvalidError(Exception):
- """Base class for CScript exceptions"""
- pass
-
-class CScriptTruncatedPushDataError(CScriptInvalidError):
- """Invalid pushdata due to truncation"""
- def __init__(self, msg, data):
- self.data = data
- super(CScriptTruncatedPushDataError, self).__init__(msg)
-
-# This is used, eg, for blockchain heights in coinbase scripts (bip34)
-class CScriptNum(object):
- def __init__(self, d=0):
- self.value = d
-
- @staticmethod
- def encode(obj):
- r = bytearray(0)
- if obj.value == 0:
- return bytes(r)
- neg = obj.value < 0
- absvalue = -obj.value if neg else obj.value
- while (absvalue):
- r.append(absvalue & 0xff)
- absvalue >>= 8
- if r[-1] & 0x80:
- r.append(0x80 if neg else 0)
- elif neg:
- r[-1] |= 0x80
- return bytes(bchr(len(r)) + r)
-
-
-class CScript(bytes):
- """Serialized script
-
- A bytes subclass, so you can use this directly whenever bytes are accepted.
- Note that this means that indexing does *not* work - you'll get an index by
- byte rather than opcode. This format was chosen for efficiency so that the
- general case would not require creating a lot of little CScriptOP objects.
-
- iter(script) however does iterate by opcode.
- """
- @classmethod
- def __coerce_instance(cls, other):
- # Coerce other into bytes
- if isinstance(other, CScriptOp):
- other = bchr(other)
- elif isinstance(other, CScriptNum):
- if (other.value == 0):
- other = bchr(CScriptOp(OP_0))
- else:
- other = CScriptNum.encode(other)
- elif isinstance(other, int):
- if 0 <= other <= 16:
- other = bytes(bchr(CScriptOp.encode_op_n(other)))
- elif other == -1:
- other = bytes(bchr(OP_1NEGATE))
- else:
- other = CScriptOp.encode_op_pushdata(bn2vch(other))
- elif isinstance(other, (bytes, bytearray)):
- other = CScriptOp.encode_op_pushdata(other)
- return other
-
- def __add__(self, other):
- # Do the coercion outside of the try block so that errors in it are
- # noticed.
- other = self.__coerce_instance(other)
-
- try:
- # bytes.__add__ always returns bytes instances unfortunately
- return CScript(super(CScript, self).__add__(other))
- except TypeError:
- raise TypeError('Can not add a %r instance to a CScript' % other.__class__)
-
- def join(self, iterable):
- # join makes no sense for a CScript()
- raise NotImplementedError
-
- def __new__(cls, value=b''):
- if isinstance(value, bytes) or isinstance(value, bytearray):
- return super(CScript, cls).__new__(cls, value)
- else:
- def coerce_iterable(iterable):
- for instance in iterable:
- yield cls.__coerce_instance(instance)
- # Annoyingly on both python2 and python3 bytes.join() always
- # returns a bytes instance even when subclassed.
- return super(CScript, cls).__new__(cls, b''.join(coerce_iterable(value)))
-
- def raw_iter(self):
- """Raw iteration
-
- Yields tuples of (opcode, data, sop_idx) so that the different possible
- PUSHDATA encodings can be accurately distinguished, as well as
- determining the exact opcode byte indexes. (sop_idx)
- """
- i = 0
- while i < len(self):
- sop_idx = i
- opcode = bord(self[i])
- i += 1
-
- if opcode > OP_PUSHDATA4:
- yield (opcode, None, sop_idx)
- else:
- datasize = None
- pushdata_type = None
- if opcode < OP_PUSHDATA1:
- pushdata_type = 'PUSHDATA(%d)' % opcode
- datasize = opcode
-
- elif opcode == OP_PUSHDATA1:
- pushdata_type = 'PUSHDATA1'
- if i >= len(self):
- raise CScriptInvalidError('PUSHDATA1: missing data length')
- datasize = bord(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)
- 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)
- i += 4
-
- else:
- assert False # shouldn't happen
-
-
- data = bytes(self[i:i+datasize])
-
- # Check for truncation
- if len(data) < datasize:
- raise CScriptTruncatedPushDataError('%s: truncated data' % pushdata_type, data)
-
- i += datasize
-
- yield (opcode, data, sop_idx)
-
- def __iter__(self):
- """'Cooked' iteration
-
- Returns either a CScriptOP instance, an integer, or bytes, as
- appropriate.
-
- See raw_iter() if you need to distinguish the different possible
- PUSHDATA encodings.
- """
- for (opcode, data, sop_idx) in self.raw_iter():
- if data is not None:
- yield data
- else:
- opcode = CScriptOp(opcode)
-
- if opcode.is_small_int():
- yield opcode.decode_op_n()
- else:
- yield CScriptOp(opcode)
-
- def __repr__(self):
- # For Python3 compatibility add b before strings so testcases don't
- # need to change
- def _repr(o):
- if isinstance(o, bytes):
- return b"x('%s')" % hexlify(o).decode('ascii')
- else:
- return repr(o)
-
- ops = []
- i = iter(self)
- while True:
- op = None
- try:
- op = _repr(next(i))
- except CScriptTruncatedPushDataError as err:
- op = '%s...<ERROR: %s>' % (_repr(err.data), err)
- break
- except CScriptInvalidError as err:
- op = '<ERROR: %s>' % err
- break
- except StopIteration:
- break
- finally:
- if op is not None:
- ops.append(op)
-
- return "CScript([%s])" % ', '.join(ops)
-
- def GetSigOpCount(self, fAccurate):
- """Get the SigOp count.
-
- fAccurate - Accurately count CHECKMULTISIG, see BIP16 for details.
-
- Note that this is consensus-critical.
- """
- n = 0
- lastOpcode = OP_INVALIDOPCODE
- for (opcode, data, sop_idx) in self.raw_iter():
- if opcode in (OP_CHECKSIG, OP_CHECKSIGVERIFY):
- n += 1
- elif opcode in (OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY):
- if fAccurate and (OP_1 <= lastOpcode <= OP_16):
- n += opcode.decode_op_n()
- else:
- n += 20
- lastOpcode = opcode
- return n
-
-
-SIGHASH_ALL = 1
-SIGHASH_NONE = 2
-SIGHASH_SINGLE = 3
-SIGHASH_ANYONECANPAY = 0x80
-
-def FindAndDelete(script, sig):
- """Consensus critical, see FindAndDelete() in Satoshi codebase"""
- r = b''
- last_sop_idx = sop_idx = 0
- skip = True
- for (opcode, data, sop_idx) in script.raw_iter():
- if not skip:
- r += script[last_sop_idx:sop_idx]
- last_sop_idx = sop_idx
- if script[sop_idx:sop_idx + len(sig)] == sig:
- skip = True
- else:
- skip = False
- if not skip:
- r += script[last_sop_idx:]
- return CScript(r)
-
-
-def SignatureHash(script, txTo, inIdx, hashtype):
- """Consensus-correct SignatureHash
-
- Returns (hash, err) to precisely match the consensus-critical behavior of
- the SIGHASH_SINGLE bug. (inIdx is *not* checked for validity)
- """
- HASH_ONE = b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
-
- if inIdx >= len(txTo.vin):
- return (HASH_ONE, "inIdx %d out of range (%d)" % (inIdx, len(txTo.vin)))
- txtmp = CTransaction(txTo)
-
- for txin in txtmp.vin:
- txin.scriptSig = b''
- txtmp.vin[inIdx].scriptSig = FindAndDelete(script, CScript([OP_CODESEPARATOR]))
-
- if (hashtype & 0x1f) == SIGHASH_NONE:
- txtmp.vout = []
-
- for i in range(len(txtmp.vin)):
- if i != inIdx:
- txtmp.vin[i].nSequence = 0
-
- elif (hashtype & 0x1f) == SIGHASH_SINGLE:
- outIdx = inIdx
- if outIdx >= len(txtmp.vout):
- return (HASH_ONE, "outIdx %d out of range (%d)" % (outIdx, len(txtmp.vout)))
-
- tmp = txtmp.vout[outIdx]
- txtmp.vout = []
- for i in range(outIdx):
- txtmp.vout.append(CTxOut(-1))
- txtmp.vout.append(tmp)
-
- for i in range(len(txtmp.vin)):
- if i != inIdx:
- txtmp.vin[i].nSequence = 0
-
- if hashtype & SIGHASH_ANYONECANPAY:
- tmp = txtmp.vin[inIdx]
- txtmp.vin = []
- txtmp.vin.append(tmp)
-
- s = txtmp.serialize()
- s += struct.pack(b"<I", hashtype)
-
- hash = hash256(s)
-
- return (hash, None)
-
-# TODO: Allow cached hashPrevouts/hashSequence/hashOutputs to be provided.
-# Performance optimization probably not necessary for python tests, however.
-# Note that this corresponds to sigversion == 1 in EvalScript, which is used
-# for version 0 witnesses.
-def SegwitVersion1SignatureHash(script, txTo, inIdx, hashtype, amount):
-
- hashPrevouts = 0
- hashSequence = 0
- hashOutputs = 0
-
- if not (hashtype & SIGHASH_ANYONECANPAY):
- serialize_prevouts = bytes()
- for i in txTo.vin:
- serialize_prevouts += i.prevout.serialize()
- hashPrevouts = uint256_from_str(hash256(serialize_prevouts))
-
- if (not (hashtype & SIGHASH_ANYONECANPAY) and (hashtype & 0x1f) != SIGHASH_SINGLE and (hashtype & 0x1f) != SIGHASH_NONE):
- serialize_sequence = bytes()
- for i in txTo.vin:
- serialize_sequence += struct.pack("<I", i.nSequence)
- hashSequence = uint256_from_str(hash256(serialize_sequence))
-
- if ((hashtype & 0x1f) != SIGHASH_SINGLE and (hashtype & 0x1f) != SIGHASH_NONE):
- serialize_outputs = bytes()
- for o in txTo.vout:
- serialize_outputs += o.serialize()
- hashOutputs = uint256_from_str(hash256(serialize_outputs))
- elif ((hashtype & 0x1f) == SIGHASH_SINGLE and inIdx < len(txTo.vout)):
- serialize_outputs = txTo.vout[inIdx].serialize()
- hashOutputs = uint256_from_str(hash256(serialize_outputs))
-
- ss = bytes()
- ss += struct.pack("<i", txTo.nVersion)
- ss += ser_uint256(hashPrevouts)
- ss += ser_uint256(hashSequence)
- ss += txTo.vin[inIdx].prevout.serialize()
- ss += ser_string(script)
- ss += struct.pack("<q", amount)
- ss += struct.pack("<I", txTo.vin[inIdx].nSequence)
- ss += ser_uint256(hashOutputs)
- ss += struct.pack("<i", txTo.nLockTime)
- ss += struct.pack("<I", hashtype)
-
- return hash256(ss)