script.py raw

   1  #!/usr/bin/env python3
   2  # Copyright (c) 2015-2022 The Limenka developers
   3  # Distributed under the MIT software license, see the accompanying
   4  # file COPYING or http://www.opensource.org/licenses/mit-license.php.
   5  """Functionality to build scripts, as well as signature hash functions.
   6  
   7  This file is modified from python-limenkalib.
   8  """
   9  
  10  from collections import namedtuple
  11  import unittest
  12  
  13  from .key import TaggedHash, tweak_add_pubkey, compute_xonly_pubkey
  14  
  15  from .messages import (
  16      CTransaction,
  17      CTxOut,
  18      hash256,
  19      ser_string,
  20      ser_uint256,
  21      sha256,
  22      uint256_from_str,
  23  )
  24  
  25  from .crypto.ripemd160 import ripemd160
  26  
  27  MAX_SCRIPT_ELEMENT_SIZE = 520
  28  MAX_PUBKEYS_PER_MULTI_A = 999
  29  LOCKTIME_THRESHOLD = 500000000
  30  ANNEX_TAG = 0x50
  31  
  32  TAPROOT_CONTROL_MAX_NODE_COUNT_REDUCED = 7
  33  LEAF_VERSION_TAPSCRIPT = 0xc0
  34  
  35  def hash160(s):
  36      return ripemd160(sha256(s))
  37  
  38  def bn2vch(v):
  39      """Convert number to limenka-specific little endian format."""
  40      # We need v.bit_length() bits, plus a sign bit for every nonzero number.
  41      n_bits = v.bit_length() + (v != 0)
  42      # The number of bytes for that is:
  43      n_bytes = (n_bits + 7) // 8
  44      # Convert number to absolute value + sign in top bit.
  45      encoded_v = 0 if v == 0 else abs(v) | ((v < 0) << (n_bytes * 8 - 1))
  46      # Serialize to bytes
  47      return encoded_v.to_bytes(n_bytes, 'little')
  48  
  49  class CScriptOp(int):
  50      """A single script opcode"""
  51      __slots__ = ()
  52  
  53      @staticmethod
  54      def encode_op_pushdata(d):
  55          """Encode a PUSHDATA op, returning bytes"""
  56          if len(d) < 0x4c:
  57              return b'' + bytes([len(d)]) + d  # OP_PUSHDATA
  58          elif len(d) <= 0xff:
  59              return b'\x4c' + bytes([len(d)]) + d  # OP_PUSHDATA1
  60          elif len(d) <= 0xffff:
  61              return b'\x4d' + len(d).to_bytes(2, "little") + d  # OP_PUSHDATA2
  62          elif len(d) <= 0xffffffff:
  63              return b'\x4e' + len(d).to_bytes(4, "little") + d  # OP_PUSHDATA4
  64          else:
  65              raise ValueError("Data too long to encode in a PUSHDATA op")
  66  
  67      @staticmethod
  68      def encode_op_n(n):
  69          """Encode a small integer op, returning an opcode"""
  70          if not (0 <= n <= 16):
  71              raise ValueError('Integer must be in range 0 <= n <= 16, got %d' % n)
  72  
  73          if n == 0:
  74              return OP_0
  75          else:
  76              return CScriptOp(OP_1 + n - 1)
  77  
  78      def decode_op_n(self):
  79          """Decode a small integer opcode, returning an integer"""
  80          if self == OP_0:
  81              return 0
  82  
  83          if not (self == OP_0 or OP_1 <= self <= OP_16):
  84              raise ValueError('op %r is not an OP_N' % self)
  85  
  86          return int(self - OP_1 + 1)
  87  
  88      def is_small_int(self):
  89          """Return true if the op pushes a small integer to the stack"""
  90          if 0x51 <= self <= 0x60 or self == 0:
  91              return True
  92          else:
  93              return False
  94  
  95      def __str__(self):
  96          return repr(self)
  97  
  98      def __repr__(self):
  99          if self in OPCODE_NAMES:
 100              return OPCODE_NAMES[self]
 101          else:
 102              return 'CScriptOp(0x%x)' % self
 103  
 104      def __new__(cls, n):
 105          try:
 106              return _opcode_instances[n]
 107          except IndexError:
 108              assert len(_opcode_instances) == n
 109              _opcode_instances.append(super().__new__(cls, n))
 110              return _opcode_instances[n]
 111  
 112  OPCODE_NAMES: dict[CScriptOp, str] = {}
 113  _opcode_instances: list[CScriptOp] = []
 114  
 115  # Populate opcode instance table
 116  for n in range(0xff + 1):
 117      CScriptOp(n)
 118  
 119  
 120  # push value
 121  OP_0 = CScriptOp(0x00)
 122  OP_FALSE = OP_0
 123  OP_PUSHDATA1 = CScriptOp(0x4c)
 124  OP_PUSHDATA2 = CScriptOp(0x4d)
 125  OP_PUSHDATA4 = CScriptOp(0x4e)
 126  OP_1NEGATE = CScriptOp(0x4f)
 127  OP_RESERVED = CScriptOp(0x50)
 128  OP_1 = CScriptOp(0x51)
 129  OP_TRUE = OP_1
 130  OP_2 = CScriptOp(0x52)
 131  OP_3 = CScriptOp(0x53)
 132  OP_4 = CScriptOp(0x54)
 133  OP_5 = CScriptOp(0x55)
 134  OP_6 = CScriptOp(0x56)
 135  OP_7 = CScriptOp(0x57)
 136  OP_8 = CScriptOp(0x58)
 137  OP_9 = CScriptOp(0x59)
 138  OP_10 = CScriptOp(0x5a)
 139  OP_11 = CScriptOp(0x5b)
 140  OP_12 = CScriptOp(0x5c)
 141  OP_13 = CScriptOp(0x5d)
 142  OP_14 = CScriptOp(0x5e)
 143  OP_15 = CScriptOp(0x5f)
 144  OP_16 = CScriptOp(0x60)
 145  
 146  # control
 147  OP_NOP = CScriptOp(0x61)
 148  OP_VER = CScriptOp(0x62)
 149  OP_IF = CScriptOp(0x63)
 150  OP_NOTIF = CScriptOp(0x64)
 151  OP_VERIF = CScriptOp(0x65)
 152  OP_VERNOTIF = CScriptOp(0x66)
 153  OP_ELSE = CScriptOp(0x67)
 154  OP_ENDIF = CScriptOp(0x68)
 155  OP_VERIFY = CScriptOp(0x69)
 156  OP_RETURN = CScriptOp(0x6a)
 157  
 158  # stack ops
 159  OP_TOALTSTACK = CScriptOp(0x6b)
 160  OP_FROMALTSTACK = CScriptOp(0x6c)
 161  OP_2DROP = CScriptOp(0x6d)
 162  OP_2DUP = CScriptOp(0x6e)
 163  OP_3DUP = CScriptOp(0x6f)
 164  OP_2OVER = CScriptOp(0x70)
 165  OP_2ROT = CScriptOp(0x71)
 166  OP_2SWAP = CScriptOp(0x72)
 167  OP_IFDUP = CScriptOp(0x73)
 168  OP_DEPTH = CScriptOp(0x74)
 169  OP_DROP = CScriptOp(0x75)
 170  OP_DUP = CScriptOp(0x76)
 171  OP_NIP = CScriptOp(0x77)
 172  OP_OVER = CScriptOp(0x78)
 173  OP_PICK = CScriptOp(0x79)
 174  OP_ROLL = CScriptOp(0x7a)
 175  OP_ROT = CScriptOp(0x7b)
 176  OP_SWAP = CScriptOp(0x7c)
 177  OP_TUCK = CScriptOp(0x7d)
 178  
 179  # splice ops
 180  OP_CAT = CScriptOp(0x7e)
 181  OP_SUBSTR = CScriptOp(0x7f)
 182  OP_LEFT = CScriptOp(0x80)
 183  OP_RIGHT = CScriptOp(0x81)
 184  OP_SIZE = CScriptOp(0x82)
 185  
 186  # bit logic
 187  OP_INVERT = CScriptOp(0x83)
 188  OP_AND = CScriptOp(0x84)
 189  OP_OR = CScriptOp(0x85)
 190  OP_XOR = CScriptOp(0x86)
 191  OP_EQUAL = CScriptOp(0x87)
 192  OP_EQUALVERIFY = CScriptOp(0x88)
 193  OP_RESERVED1 = CScriptOp(0x89)
 194  OP_RESERVED2 = CScriptOp(0x8a)
 195  
 196  # numeric
 197  OP_1ADD = CScriptOp(0x8b)
 198  OP_1SUB = CScriptOp(0x8c)
 199  OP_2MUL = CScriptOp(0x8d)
 200  OP_2DIV = CScriptOp(0x8e)
 201  OP_NEGATE = CScriptOp(0x8f)
 202  OP_ABS = CScriptOp(0x90)
 203  OP_NOT = CScriptOp(0x91)
 204  OP_0NOTEQUAL = CScriptOp(0x92)
 205  
 206  OP_ADD = CScriptOp(0x93)
 207  OP_SUB = CScriptOp(0x94)
 208  OP_MUL = CScriptOp(0x95)
 209  OP_DIV = CScriptOp(0x96)
 210  OP_MOD = CScriptOp(0x97)
 211  OP_LSHIFT = CScriptOp(0x98)
 212  OP_RSHIFT = CScriptOp(0x99)
 213  
 214  OP_BOOLAND = CScriptOp(0x9a)
 215  OP_BOOLOR = CScriptOp(0x9b)
 216  OP_NUMEQUAL = CScriptOp(0x9c)
 217  OP_NUMEQUALVERIFY = CScriptOp(0x9d)
 218  OP_NUMNOTEQUAL = CScriptOp(0x9e)
 219  OP_LESSTHAN = CScriptOp(0x9f)
 220  OP_GREATERTHAN = CScriptOp(0xa0)
 221  OP_LESSTHANOREQUAL = CScriptOp(0xa1)
 222  OP_GREATERTHANOREQUAL = CScriptOp(0xa2)
 223  OP_MIN = CScriptOp(0xa3)
 224  OP_MAX = CScriptOp(0xa4)
 225  
 226  OP_WITHIN = CScriptOp(0xa5)
 227  
 228  # crypto
 229  OP_RIPEMD160 = CScriptOp(0xa6)
 230  OP_SHA1 = CScriptOp(0xa7)
 231  OP_SHA256 = CScriptOp(0xa8)
 232  OP_HASH160 = CScriptOp(0xa9)
 233  OP_HASH256 = CScriptOp(0xaa)
 234  OP_CODESEPARATOR = CScriptOp(0xab)
 235  OP_CHECKSIG = CScriptOp(0xac)
 236  OP_CHECKSIGVERIFY = CScriptOp(0xad)
 237  OP_CHECKMULTISIG = CScriptOp(0xae)
 238  OP_CHECKMULTISIGVERIFY = CScriptOp(0xaf)
 239  
 240  # expansion
 241  OP_NOP1 = CScriptOp(0xb0)
 242  OP_CHECKLOCKTIMEVERIFY = CScriptOp(0xb1)
 243  OP_CHECKSEQUENCEVERIFY = CScriptOp(0xb2)
 244  OP_NOP4 = CScriptOp(0xb3)
 245  OP_NOP5 = CScriptOp(0xb4)
 246  OP_NOP6 = CScriptOp(0xb5)
 247  OP_NOP7 = CScriptOp(0xb6)
 248  OP_NOP8 = CScriptOp(0xb7)
 249  OP_NOP9 = CScriptOp(0xb8)
 250  OP_NOP10 = CScriptOp(0xb9)
 251  
 252  # BIP 342 opcodes (Tapscript)
 253  OP_CHECKSIGADD = CScriptOp(0xba)
 254  
 255  OP_INVALIDOPCODE = CScriptOp(0xff)
 256  
 257  OPCODE_NAMES.update({
 258      OP_0: 'OP_0',
 259      OP_PUSHDATA1: 'OP_PUSHDATA1',
 260      OP_PUSHDATA2: 'OP_PUSHDATA2',
 261      OP_PUSHDATA4: 'OP_PUSHDATA4',
 262      OP_1NEGATE: 'OP_1NEGATE',
 263      OP_RESERVED: 'OP_RESERVED',
 264      OP_1: 'OP_1',
 265      OP_2: 'OP_2',
 266      OP_3: 'OP_3',
 267      OP_4: 'OP_4',
 268      OP_5: 'OP_5',
 269      OP_6: 'OP_6',
 270      OP_7: 'OP_7',
 271      OP_8: 'OP_8',
 272      OP_9: 'OP_9',
 273      OP_10: 'OP_10',
 274      OP_11: 'OP_11',
 275      OP_12: 'OP_12',
 276      OP_13: 'OP_13',
 277      OP_14: 'OP_14',
 278      OP_15: 'OP_15',
 279      OP_16: 'OP_16',
 280      OP_NOP: 'OP_NOP',
 281      OP_VER: 'OP_VER',
 282      OP_IF: 'OP_IF',
 283      OP_NOTIF: 'OP_NOTIF',
 284      OP_VERIF: 'OP_VERIF',
 285      OP_VERNOTIF: 'OP_VERNOTIF',
 286      OP_ELSE: 'OP_ELSE',
 287      OP_ENDIF: 'OP_ENDIF',
 288      OP_VERIFY: 'OP_VERIFY',
 289      OP_RETURN: 'OP_RETURN',
 290      OP_TOALTSTACK: 'OP_TOALTSTACK',
 291      OP_FROMALTSTACK: 'OP_FROMALTSTACK',
 292      OP_2DROP: 'OP_2DROP',
 293      OP_2DUP: 'OP_2DUP',
 294      OP_3DUP: 'OP_3DUP',
 295      OP_2OVER: 'OP_2OVER',
 296      OP_2ROT: 'OP_2ROT',
 297      OP_2SWAP: 'OP_2SWAP',
 298      OP_IFDUP: 'OP_IFDUP',
 299      OP_DEPTH: 'OP_DEPTH',
 300      OP_DROP: 'OP_DROP',
 301      OP_DUP: 'OP_DUP',
 302      OP_NIP: 'OP_NIP',
 303      OP_OVER: 'OP_OVER',
 304      OP_PICK: 'OP_PICK',
 305      OP_ROLL: 'OP_ROLL',
 306      OP_ROT: 'OP_ROT',
 307      OP_SWAP: 'OP_SWAP',
 308      OP_TUCK: 'OP_TUCK',
 309      OP_CAT: 'OP_CAT',
 310      OP_SUBSTR: 'OP_SUBSTR',
 311      OP_LEFT: 'OP_LEFT',
 312      OP_RIGHT: 'OP_RIGHT',
 313      OP_SIZE: 'OP_SIZE',
 314      OP_INVERT: 'OP_INVERT',
 315      OP_AND: 'OP_AND',
 316      OP_OR: 'OP_OR',
 317      OP_XOR: 'OP_XOR',
 318      OP_EQUAL: 'OP_EQUAL',
 319      OP_EQUALVERIFY: 'OP_EQUALVERIFY',
 320      OP_RESERVED1: 'OP_RESERVED1',
 321      OP_RESERVED2: 'OP_RESERVED2',
 322      OP_1ADD: 'OP_1ADD',
 323      OP_1SUB: 'OP_1SUB',
 324      OP_2MUL: 'OP_2MUL',
 325      OP_2DIV: 'OP_2DIV',
 326      OP_NEGATE: 'OP_NEGATE',
 327      OP_ABS: 'OP_ABS',
 328      OP_NOT: 'OP_NOT',
 329      OP_0NOTEQUAL: 'OP_0NOTEQUAL',
 330      OP_ADD: 'OP_ADD',
 331      OP_SUB: 'OP_SUB',
 332      OP_MUL: 'OP_MUL',
 333      OP_DIV: 'OP_DIV',
 334      OP_MOD: 'OP_MOD',
 335      OP_LSHIFT: 'OP_LSHIFT',
 336      OP_RSHIFT: 'OP_RSHIFT',
 337      OP_BOOLAND: 'OP_BOOLAND',
 338      OP_BOOLOR: 'OP_BOOLOR',
 339      OP_NUMEQUAL: 'OP_NUMEQUAL',
 340      OP_NUMEQUALVERIFY: 'OP_NUMEQUALVERIFY',
 341      OP_NUMNOTEQUAL: 'OP_NUMNOTEQUAL',
 342      OP_LESSTHAN: 'OP_LESSTHAN',
 343      OP_GREATERTHAN: 'OP_GREATERTHAN',
 344      OP_LESSTHANOREQUAL: 'OP_LESSTHANOREQUAL',
 345      OP_GREATERTHANOREQUAL: 'OP_GREATERTHANOREQUAL',
 346      OP_MIN: 'OP_MIN',
 347      OP_MAX: 'OP_MAX',
 348      OP_WITHIN: 'OP_WITHIN',
 349      OP_RIPEMD160: 'OP_RIPEMD160',
 350      OP_SHA1: 'OP_SHA1',
 351      OP_SHA256: 'OP_SHA256',
 352      OP_HASH160: 'OP_HASH160',
 353      OP_HASH256: 'OP_HASH256',
 354      OP_CODESEPARATOR: 'OP_CODESEPARATOR',
 355      OP_CHECKSIG: 'OP_CHECKSIG',
 356      OP_CHECKSIGVERIFY: 'OP_CHECKSIGVERIFY',
 357      OP_CHECKMULTISIG: 'OP_CHECKMULTISIG',
 358      OP_CHECKMULTISIGVERIFY: 'OP_CHECKMULTISIGVERIFY',
 359      OP_NOP1: 'OP_NOP1',
 360      OP_CHECKLOCKTIMEVERIFY: 'OP_CHECKLOCKTIMEVERIFY',
 361      OP_CHECKSEQUENCEVERIFY: 'OP_CHECKSEQUENCEVERIFY',
 362      OP_NOP4: 'OP_NOP4',
 363      OP_NOP5: 'OP_NOP5',
 364      OP_NOP6: 'OP_NOP6',
 365      OP_NOP7: 'OP_NOP7',
 366      OP_NOP8: 'OP_NOP8',
 367      OP_NOP9: 'OP_NOP9',
 368      OP_NOP10: 'OP_NOP10',
 369      OP_CHECKSIGADD: 'OP_CHECKSIGADD',
 370      OP_INVALIDOPCODE: 'OP_INVALIDOPCODE',
 371  })
 372  
 373  class CScriptInvalidError(Exception):
 374      """Base class for CScript exceptions"""
 375      pass
 376  
 377  class CScriptTruncatedPushDataError(CScriptInvalidError):
 378      """Invalid pushdata due to truncation"""
 379      def __init__(self, msg, data):
 380          self.data = data
 381          super().__init__(msg)
 382  
 383  
 384  # This is used, eg, for blockchain heights in coinbase scripts (bip34)
 385  class CScriptNum:
 386      __slots__ = ("value",)
 387  
 388      def __init__(self, d=0):
 389          self.value = d
 390  
 391      @staticmethod
 392      def encode(obj):
 393          r = bytearray(0)
 394          if obj.value == 0:
 395              return bytes(r)
 396          neg = obj.value < 0
 397          absvalue = -obj.value if neg else obj.value
 398          while (absvalue):
 399              r.append(absvalue & 0xff)
 400              absvalue >>= 8
 401          if r[-1] & 0x80:
 402              r.append(0x80 if neg else 0)
 403          elif neg:
 404              r[-1] |= 0x80
 405          return bytes([len(r)]) + r
 406  
 407      @staticmethod
 408      def decode(vch):
 409          result = 0
 410          # We assume valid push_size and minimal encoding
 411          value = vch[1:]
 412          if len(value) == 0:
 413              return result
 414          for i, byte in enumerate(value):
 415              result |= int(byte) << 8 * i
 416          if value[-1] >= 0x80:
 417              # Mask for all but the highest result bit
 418              num_mask = (2**(len(value) * 8) - 1) >> 1
 419              result &= num_mask
 420              result *= -1
 421          return result
 422  
 423  
 424  class CScript(bytes):
 425      """Serialized script
 426  
 427      A bytes subclass, so you can use this directly whenever bytes are accepted.
 428      Note that this means that indexing does *not* work - you'll get an index by
 429      byte rather than opcode. This format was chosen for efficiency so that the
 430      general case would not require creating a lot of little CScriptOP objects.
 431  
 432      iter(script) however does iterate by opcode.
 433      """
 434      __slots__ = ()
 435  
 436      @classmethod
 437      def __coerce_instance(cls, other):
 438          # Coerce other into bytes
 439          if isinstance(other, CScriptOp):
 440              other = bytes([other])
 441          elif isinstance(other, CScriptNum):
 442              if (other.value == 0):
 443                  other = bytes([CScriptOp(OP_0)])
 444              else:
 445                  other = CScriptNum.encode(other)
 446          elif isinstance(other, int):
 447              if 0 <= other <= 16:
 448                  other = bytes([CScriptOp.encode_op_n(other)])
 449              elif other == -1:
 450                  other = bytes([OP_1NEGATE])
 451              else:
 452                  other = CScriptOp.encode_op_pushdata(bn2vch(other))
 453          elif isinstance(other, (bytes, bytearray)):
 454              other = CScriptOp.encode_op_pushdata(other)
 455          return other
 456  
 457      def __add__(self, other):
 458          # add makes no sense for a CScript()
 459          raise NotImplementedError
 460  
 461      def join(self, iterable):
 462          # join makes no sense for a CScript()
 463          raise NotImplementedError
 464  
 465      def __new__(cls, value=b''):
 466          if isinstance(value, bytes) or isinstance(value, bytearray):
 467              return super().__new__(cls, value)
 468          else:
 469              def coerce_iterable(iterable):
 470                  for instance in iterable:
 471                      yield cls.__coerce_instance(instance)
 472              # Annoyingly on both python2 and python3 bytes.join() always
 473              # returns a bytes instance even when subclassed.
 474              return super().__new__(cls, b''.join(coerce_iterable(value)))
 475  
 476      def raw_iter(self):
 477          """Raw iteration
 478  
 479          Yields tuples of (opcode, data, sop_idx) so that the different possible
 480          PUSHDATA encodings can be accurately distinguished, as well as
 481          determining the exact opcode byte indexes. (sop_idx)
 482          """
 483          i = 0
 484          while i < len(self):
 485              sop_idx = i
 486              opcode = CScriptOp(self[i])
 487              i += 1
 488  
 489              if opcode > OP_PUSHDATA4:
 490                  yield (opcode, None, sop_idx)
 491              else:
 492                  datasize = None
 493                  pushdata_type = None
 494                  if opcode < OP_PUSHDATA1:
 495                      pushdata_type = 'PUSHDATA(%d)' % opcode
 496                      datasize = opcode
 497  
 498                  elif opcode == OP_PUSHDATA1:
 499                      pushdata_type = 'PUSHDATA1'
 500                      if i >= len(self):
 501                          raise CScriptInvalidError('PUSHDATA1: missing data length')
 502                      datasize = self[i]
 503                      i += 1
 504  
 505                  elif opcode == OP_PUSHDATA2:
 506                      pushdata_type = 'PUSHDATA2'
 507                      if i + 1 >= len(self):
 508                          raise CScriptInvalidError('PUSHDATA2: missing data length')
 509                      datasize = self[i] + (self[i + 1] << 8)
 510                      i += 2
 511  
 512                  elif opcode == OP_PUSHDATA4:
 513                      pushdata_type = 'PUSHDATA4'
 514                      if i + 3 >= len(self):
 515                          raise CScriptInvalidError('PUSHDATA4: missing data length')
 516                      datasize = self[i] + (self[i + 1] << 8) + (self[i + 2] << 16) + (self[i + 3] << 24)
 517                      i += 4
 518  
 519                  else:
 520                      assert False  # shouldn't happen
 521  
 522                  data = bytes(self[i:i + datasize])
 523  
 524                  # Check for truncation
 525                  if len(data) < datasize:
 526                      raise CScriptTruncatedPushDataError('%s: truncated data' % pushdata_type, data)
 527  
 528                  i += datasize
 529  
 530                  yield (opcode, data, sop_idx)
 531  
 532      def __iter__(self):
 533          """'Cooked' iteration
 534  
 535          Returns either a CScriptOP instance, an integer, or bytes, as
 536          appropriate.
 537  
 538          See raw_iter() if you need to distinguish the different possible
 539          PUSHDATA encodings.
 540          """
 541          for (opcode, data, sop_idx) in self.raw_iter():
 542              if data is not None:
 543                  yield data
 544              else:
 545                  opcode = CScriptOp(opcode)
 546  
 547                  if opcode.is_small_int():
 548                      yield opcode.decode_op_n()
 549                  else:
 550                      yield CScriptOp(opcode)
 551  
 552      def __repr__(self):
 553          def _repr(o):
 554              if isinstance(o, bytes):
 555                  return "x('%s')" % o.hex()
 556              else:
 557                  return repr(o)
 558  
 559          ops = []
 560          i = iter(self)
 561          while True:
 562              op = None
 563              try:
 564                  op = _repr(next(i))
 565              except CScriptTruncatedPushDataError as err:
 566                  op = '%s...<ERROR: %s>' % (_repr(err.data), err)
 567                  break
 568              except CScriptInvalidError as err:
 569                  op = '<ERROR: %s>' % err
 570                  break
 571              except StopIteration:
 572                  break
 573              finally:
 574                  if op is not None:
 575                      ops.append(op)
 576  
 577          return "CScript([%s])" % ', '.join(ops)
 578  
 579      def GetSigOpCount(self, fAccurate):
 580          """Get the SigOp count.
 581  
 582          fAccurate - Accurately count CHECKMULTISIG, see BIP16 for details.
 583  
 584          Note that this is consensus-critical.
 585          """
 586          n = 0
 587          lastOpcode = OP_INVALIDOPCODE
 588          for (opcode, data, sop_idx) in self.raw_iter():
 589              if opcode in (OP_CHECKSIG, OP_CHECKSIGVERIFY):
 590                  n += 1
 591              elif opcode in (OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY):
 592                  if fAccurate and (OP_1 <= lastOpcode <= OP_16):
 593                      n += lastOpcode.decode_op_n()
 594                  else:
 595                      n += 20
 596              lastOpcode = opcode
 597          return n
 598  
 599      def IsWitnessProgram(self):
 600          """A witness program is any valid CScript that consists of a 1-byte
 601             push opcode followed by a data push between 2 and 40 bytes."""
 602          return ((4 <= len(self) <= 42) and
 603                  (self[0] == OP_0 or (OP_1 <= self[0] <= OP_16)) and
 604                  (self[1] + 2 == len(self)))
 605  
 606  
 607  SIGHASH_DEFAULT = 0 # Taproot-only default, semantics same as SIGHASH_ALL
 608  SIGHASH_ALL = 1
 609  SIGHASH_NONE = 2
 610  SIGHASH_SINGLE = 3
 611  SIGHASH_ANYONECANPAY = 0x80
 612  
 613  def FindAndDelete(script, sig):
 614      """Consensus critical, see FindAndDelete() in Satoshi codebase"""
 615      r = b''
 616      last_sop_idx = sop_idx = 0
 617      skip = True
 618      for (opcode, data, sop_idx) in script.raw_iter():
 619          if not skip:
 620              r += script[last_sop_idx:sop_idx]
 621          last_sop_idx = sop_idx
 622          if script[sop_idx:sop_idx + len(sig)] == sig:
 623              skip = True
 624          else:
 625              skip = False
 626      if not skip:
 627          r += script[last_sop_idx:]
 628      return CScript(r)
 629  
 630  def LegacySignatureMsg(script, txTo, inIdx, hashtype):
 631      """Preimage of the signature hash, if it exists.
 632  
 633      Returns either (None, err) to indicate error (which translates to sighash 1),
 634      or (msg, None).
 635      """
 636  
 637      if inIdx >= len(txTo.vin):
 638          return (None, "inIdx %d out of range (%d)" % (inIdx, len(txTo.vin)))
 639      txtmp = CTransaction(txTo)
 640  
 641      for txin in txtmp.vin:
 642          txin.scriptSig = b''
 643      txtmp.vin[inIdx].scriptSig = FindAndDelete(script, CScript([OP_CODESEPARATOR]))
 644  
 645      if (hashtype & 0x1f) == SIGHASH_NONE:
 646          txtmp.vout = []
 647  
 648          for i in range(len(txtmp.vin)):
 649              if i != inIdx:
 650                  txtmp.vin[i].nSequence = 0
 651  
 652      elif (hashtype & 0x1f) == SIGHASH_SINGLE:
 653          outIdx = inIdx
 654          if outIdx >= len(txtmp.vout):
 655              return (None, "outIdx %d out of range (%d)" % (outIdx, len(txtmp.vout)))
 656  
 657          tmp = txtmp.vout[outIdx]
 658          txtmp.vout = []
 659          for _ in range(outIdx):
 660              txtmp.vout.append(CTxOut(-1))
 661          txtmp.vout.append(tmp)
 662  
 663          for i in range(len(txtmp.vin)):
 664              if i != inIdx:
 665                  txtmp.vin[i].nSequence = 0
 666  
 667      if hashtype & SIGHASH_ANYONECANPAY:
 668          tmp = txtmp.vin[inIdx]
 669          txtmp.vin = []
 670          txtmp.vin.append(tmp)
 671  
 672      s = txtmp.serialize_without_witness()
 673      s += hashtype.to_bytes(4, "little")
 674  
 675      return (s, None)
 676  
 677  def LegacySignatureHash(*args, **kwargs):
 678      """Consensus-correct SignatureHash
 679  
 680      Returns (hash, err) to precisely match the consensus-critical behavior of
 681      the SIGHASH_SINGLE bug. (inIdx is *not* checked for validity)
 682      """
 683  
 684      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'
 685      msg, err = LegacySignatureMsg(*args, **kwargs)
 686      if msg is None:
 687          return (HASH_ONE, err)
 688      else:
 689          return (hash256(msg), err)
 690  
 691  def sign_input_legacy(tx, input_index, input_scriptpubkey, privkey, sighash_type=SIGHASH_ALL):
 692      """Add legacy ECDSA signature for a given transaction input. Note that the signature
 693         is prepended to the scriptSig field, i.e. additional data pushes necessary for more
 694         complex spends than P2PK (e.g. pubkey for P2PKH) can be already set before."""
 695      (sighash, err) = LegacySignatureHash(input_scriptpubkey, tx, input_index, sighash_type)
 696      assert err is None
 697      der_sig = privkey.sign_ecdsa(sighash)
 698      tx.vin[input_index].scriptSig = bytes(CScript([der_sig + bytes([sighash_type])])) + tx.vin[input_index].scriptSig
 699      tx.rehash()
 700  
 701  def sign_input_segwitv0(tx, input_index, input_scriptpubkey, input_amount, privkey, sighash_type=SIGHASH_ALL):
 702      """Add segwitv0 ECDSA signature for a given transaction input. Note that the signature
 703         is inserted at the bottom of the witness stack, i.e. additional witness data
 704         needed (e.g. pubkey for P2WPKH) can already be set before."""
 705      sighash = SegwitV0SignatureHash(input_scriptpubkey, tx, input_index, sighash_type, input_amount)
 706      der_sig = privkey.sign_ecdsa(sighash)
 707      tx.wit.vtxinwit[input_index].scriptWitness.stack.insert(0, der_sig + bytes([sighash_type]))
 708      tx.rehash()
 709  
 710  # TODO: Allow cached hashPrevouts/hashSequence/hashOutputs to be provided.
 711  # Performance optimization probably not necessary for python tests, however.
 712  # Note that this corresponds to sigversion == 1 in EvalScript, which is used
 713  # for version 0 witnesses.
 714  def SegwitV0SignatureMsg(script, txTo, inIdx, hashtype, amount):
 715  
 716      hashPrevouts = 0
 717      hashSequence = 0
 718      hashOutputs = 0
 719  
 720      if not (hashtype & SIGHASH_ANYONECANPAY):
 721          serialize_prevouts = bytes()
 722          for i in txTo.vin:
 723              serialize_prevouts += i.prevout.serialize()
 724          hashPrevouts = uint256_from_str(hash256(serialize_prevouts))
 725  
 726      if (not (hashtype & SIGHASH_ANYONECANPAY) and (hashtype & 0x1f) != SIGHASH_SINGLE and (hashtype & 0x1f) != SIGHASH_NONE):
 727          serialize_sequence = bytes()
 728          for i in txTo.vin:
 729              serialize_sequence += i.nSequence.to_bytes(4, "little")
 730          hashSequence = uint256_from_str(hash256(serialize_sequence))
 731  
 732      if ((hashtype & 0x1f) != SIGHASH_SINGLE and (hashtype & 0x1f) != SIGHASH_NONE):
 733          serialize_outputs = bytes()
 734          for o in txTo.vout:
 735              serialize_outputs += o.serialize()
 736          hashOutputs = uint256_from_str(hash256(serialize_outputs))
 737      elif ((hashtype & 0x1f) == SIGHASH_SINGLE and inIdx < len(txTo.vout)):
 738          serialize_outputs = txTo.vout[inIdx].serialize()
 739          hashOutputs = uint256_from_str(hash256(serialize_outputs))
 740  
 741      ss = bytes()
 742      ss += txTo.version.to_bytes(4, "little")
 743      ss += ser_uint256(hashPrevouts)
 744      ss += ser_uint256(hashSequence)
 745      ss += txTo.vin[inIdx].prevout.serialize()
 746      ss += ser_string(script)
 747      ss += amount.to_bytes(8, "little", signed=True)
 748      ss += txTo.vin[inIdx].nSequence.to_bytes(4, "little")
 749      ss += ser_uint256(hashOutputs)
 750      ss += txTo.nLockTime.to_bytes(4, "little")
 751      ss += hashtype.to_bytes(4, "little")
 752      return ss
 753  
 754  def SegwitV0SignatureHash(*args, **kwargs):
 755      return hash256(SegwitV0SignatureMsg(*args, **kwargs))
 756  
 757  class TestFrameworkScript(unittest.TestCase):
 758      def test_bn2vch(self):
 759          self.assertEqual(bn2vch(0), bytes([]))
 760          self.assertEqual(bn2vch(1), bytes([0x01]))
 761          self.assertEqual(bn2vch(-1), bytes([0x81]))
 762          self.assertEqual(bn2vch(0x7F), bytes([0x7F]))
 763          self.assertEqual(bn2vch(-0x7F), bytes([0xFF]))
 764          self.assertEqual(bn2vch(0x80), bytes([0x80, 0x00]))
 765          self.assertEqual(bn2vch(-0x80), bytes([0x80, 0x80]))
 766          self.assertEqual(bn2vch(0xFF), bytes([0xFF, 0x00]))
 767          self.assertEqual(bn2vch(-0xFF), bytes([0xFF, 0x80]))
 768          self.assertEqual(bn2vch(0x100), bytes([0x00, 0x01]))
 769          self.assertEqual(bn2vch(-0x100), bytes([0x00, 0x81]))
 770          self.assertEqual(bn2vch(0x7FFF), bytes([0xFF, 0x7F]))
 771          self.assertEqual(bn2vch(-0x8000), bytes([0x00, 0x80, 0x80]))
 772          self.assertEqual(bn2vch(-0x7FFFFF), bytes([0xFF, 0xFF, 0xFF]))
 773          self.assertEqual(bn2vch(0x80000000), bytes([0x00, 0x00, 0x00, 0x80, 0x00]))
 774          self.assertEqual(bn2vch(-0x80000000), bytes([0x00, 0x00, 0x00, 0x80, 0x80]))
 775          self.assertEqual(bn2vch(0xFFFFFFFF), bytes([0xFF, 0xFF, 0xFF, 0xFF, 0x00]))
 776          self.assertEqual(bn2vch(123456789), bytes([0x15, 0xCD, 0x5B, 0x07]))
 777          self.assertEqual(bn2vch(-54321), bytes([0x31, 0xD4, 0x80]))
 778  
 779      def test_cscriptnum_encoding(self):
 780          # round-trip negative and multi-byte CScriptNums
 781          values = [0, 1, -1, -2, 127, 128, -255, 256, (1 << 15) - 1, -(1 << 16), (1 << 24) - 1, (1 << 31), 1 - (1 << 32), 1 << 40, 1500, -1500]
 782          for value in values:
 783              self.assertEqual(CScriptNum.decode(CScriptNum.encode(CScriptNum(value))), value)
 784  
 785      def test_legacy_sigopcount(self):
 786          # test repeated single sig ops
 787          for n_ops in range(1, 100, 10):
 788              for singlesig_op in (OP_CHECKSIG, OP_CHECKSIGVERIFY):
 789                  singlesigs_script = CScript([singlesig_op]*n_ops)
 790                  self.assertEqual(singlesigs_script.GetSigOpCount(fAccurate=False), n_ops)
 791                  self.assertEqual(singlesigs_script.GetSigOpCount(fAccurate=True), n_ops)
 792          # test multisig op (including accurate counting, i.e. BIP16)
 793          for n in range(1, 16+1):
 794              for multisig_op in (OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY):
 795                  multisig_script = CScript([CScriptOp.encode_op_n(n), multisig_op])
 796                  self.assertEqual(multisig_script.GetSigOpCount(fAccurate=False), 20)
 797                  self.assertEqual(multisig_script.GetSigOpCount(fAccurate=True), n)
 798  
 799  def BIP341_sha_prevouts(txTo):
 800      return sha256(b"".join(i.prevout.serialize() for i in txTo.vin))
 801  
 802  def BIP341_sha_amounts(spent_utxos):
 803      return sha256(b"".join(u.nValue.to_bytes(8, "little", signed=True) for u in spent_utxos))
 804  
 805  def BIP341_sha_scriptpubkeys(spent_utxos):
 806      return sha256(b"".join(ser_string(u.scriptPubKey) for u in spent_utxos))
 807  
 808  def BIP341_sha_sequences(txTo):
 809      return sha256(b"".join(i.nSequence.to_bytes(4, "little") for i in txTo.vin))
 810  
 811  def BIP341_sha_outputs(txTo):
 812      return sha256(b"".join(o.serialize() for o in txTo.vout))
 813  
 814  def TaprootSignatureMsg(txTo, spent_utxos, hash_type, input_index=0, *, scriptpath=False, leaf_script=None, codeseparator_pos=-1, annex=None, leaf_ver=LEAF_VERSION_TAPSCRIPT):
 815      assert (len(txTo.vin) == len(spent_utxos))
 816      assert (input_index < len(txTo.vin))
 817      out_type = SIGHASH_ALL if hash_type == 0 else hash_type & 3
 818      in_type = hash_type & SIGHASH_ANYONECANPAY
 819      spk = spent_utxos[input_index].scriptPubKey
 820      ss = bytes([0, hash_type]) # epoch, hash_type
 821      ss += txTo.version.to_bytes(4, "little")
 822      ss += txTo.nLockTime.to_bytes(4, "little")
 823      if in_type != SIGHASH_ANYONECANPAY:
 824          ss += BIP341_sha_prevouts(txTo)
 825          ss += BIP341_sha_amounts(spent_utxos)
 826          ss += BIP341_sha_scriptpubkeys(spent_utxos)
 827          ss += BIP341_sha_sequences(txTo)
 828      if out_type == SIGHASH_ALL:
 829          ss += BIP341_sha_outputs(txTo)
 830      spend_type = 0
 831      if annex is not None:
 832          spend_type |= 1
 833      if scriptpath:
 834          spend_type |= 2
 835      ss += bytes([spend_type])
 836      if in_type == SIGHASH_ANYONECANPAY:
 837          ss += txTo.vin[input_index].prevout.serialize()
 838          ss += spent_utxos[input_index].nValue.to_bytes(8, "little", signed=True)
 839          ss += ser_string(spk)
 840          ss += txTo.vin[input_index].nSequence.to_bytes(4, "little")
 841      else:
 842          ss += input_index.to_bytes(4, "little")
 843      if (spend_type & 1):
 844          ss += sha256(ser_string(annex))
 845      if out_type == SIGHASH_SINGLE:
 846          if input_index < len(txTo.vout):
 847              ss += sha256(txTo.vout[input_index].serialize())
 848          else:
 849              ss += bytes(0 for _ in range(32))
 850      if scriptpath:
 851          ss += TaggedHash("TapLeaf", bytes([leaf_ver]) + ser_string(leaf_script))
 852          ss += bytes([0])
 853          ss += codeseparator_pos.to_bytes(4, "little", signed=True)
 854      assert len(ss) == 175 - (in_type == SIGHASH_ANYONECANPAY) * 49 - (out_type != SIGHASH_ALL and out_type != SIGHASH_SINGLE) * 32 + (annex is not None) * 32 + scriptpath * 37
 855      return ss
 856  
 857  def TaprootSignatureHash(*args, **kwargs):
 858      return TaggedHash("TapSighash", TaprootSignatureMsg(*args, **kwargs))
 859  
 860  def taproot_tree_helper(scripts):
 861      if len(scripts) == 0:
 862          return ([], bytes())
 863      if len(scripts) == 1:
 864          # One entry: treat as a leaf
 865          script = scripts[0]
 866          assert not callable(script)
 867          if isinstance(script, list):
 868              return taproot_tree_helper(script)
 869          assert isinstance(script, tuple)
 870          version = LEAF_VERSION_TAPSCRIPT
 871          name = script[0]
 872          code = script[1]
 873          if len(script) == 3:
 874              version = script[2]
 875          assert version & 1 == 0
 876          assert isinstance(code, bytes)
 877          h = TaggedHash("TapLeaf", bytes([version]) + ser_string(code))
 878          if name is None:
 879              return ([], h)
 880          return ([(name, version, code, bytes(), h)], h)
 881      elif len(scripts) == 2 and callable(scripts[1]):
 882          # Two entries, and the right one is a function
 883          left, left_h = taproot_tree_helper(scripts[0:1])
 884          right_h = scripts[1](left_h)
 885          left = [(name, version, script, control + right_h, leaf) for name, version, script, control, leaf in left]
 886          right = []
 887      else:
 888          # Two or more entries: descend into each side
 889          split_pos = len(scripts) // 2
 890          left, left_h = taproot_tree_helper(scripts[0:split_pos])
 891          right, right_h = taproot_tree_helper(scripts[split_pos:])
 892          left = [(name, version, script, control + right_h, leaf) for name, version, script, control, leaf in left]
 893          right = [(name, version, script, control + left_h, leaf) for name, version, script, control, leaf in right]
 894      if right_h < left_h:
 895          right_h, left_h = left_h, right_h
 896      h = TaggedHash("TapBranch", left_h + right_h)
 897      return (left + right, h)
 898  
 899  # A TaprootInfo object has the following fields:
 900  # - scriptPubKey: the scriptPubKey (witness v1 CScript)
 901  # - internal_pubkey: the internal pubkey (32 bytes)
 902  # - negflag: whether the pubkey in the scriptPubKey was negated from internal_pubkey+tweak*G (bool).
 903  # - tweak: the tweak (32 bytes)
 904  # - leaves: a dict of name -> TaprootLeafInfo objects for all known leaves
 905  # - merkle_root: the script tree's Merkle root, or bytes() if no leaves are present
 906  TaprootInfo = namedtuple("TaprootInfo", "scriptPubKey,internal_pubkey,negflag,tweak,leaves,merkle_root,output_pubkey")
 907  
 908  # A TaprootLeafInfo object has the following fields:
 909  # - script: the leaf script (CScript or bytes)
 910  # - version: the leaf version (0xc0 for BIP342 tapscript)
 911  # - merklebranch: the merkle branch to use for this leaf (32*N bytes)
 912  TaprootLeafInfo = namedtuple("TaprootLeafInfo", "script,version,merklebranch,leaf_hash")
 913  
 914  def taproot_construct(pubkey, scripts=None, treat_internal_as_infinity=False):
 915      """Construct a tree of Taproot spending conditions
 916  
 917      pubkey: a 32-byte xonly pubkey for the internal pubkey (bytes)
 918      scripts: a list of items; each item is either:
 919               - a (name, CScript or bytes, leaf version) tuple
 920               - a (name, CScript or bytes) tuple (defaulting to leaf version 0xc0)
 921               - another list of items (with the same structure)
 922               - a list of two items; the first of which is an item itself, and the
 923                 second is a function. The function takes as input the Merkle root of the
 924                 first item, and produces a (fictitious) partner to hash with.
 925  
 926      Returns: a TaprootInfo object
 927      """
 928      if scripts is None:
 929          scripts = []
 930  
 931      ret, h = taproot_tree_helper(scripts)
 932      tweak = TaggedHash("TapTweak", pubkey + h)
 933      if treat_internal_as_infinity:
 934          tweaked, negated = compute_xonly_pubkey(tweak)
 935      else:
 936          tweaked, negated = tweak_add_pubkey(pubkey, tweak)
 937      leaves = dict((name, TaprootLeafInfo(script, version, merklebranch, leaf)) for name, version, script, merklebranch, leaf in ret)
 938      return TaprootInfo(CScript([OP_1, tweaked]), pubkey, negated + 0, tweak, leaves, h, tweaked)
 939  
 940  def is_op_success(o):
 941      return o == 0x50 or o == 0x62 or o == 0x89 or o == 0x8a or o == 0x8d or o == 0x8e or (o >= 0x7e and o <= 0x81) or (o >= 0x83 and o <= 0x86) or (o >= 0x95 and o <= 0x99) or (o >= 0xbb and o <= 0xfe)
 942