1from . import errno 2 3from .flags import ( 4 SEQUENCE_LOCKTIME_DISABLE_FLAG, SEQUENCE_LOCKTIME_TYPE_FLAG, 5 VERIFY_DISCOURAGE_UPGRADABLE_NOPS, 6 VERIFY_CHECKLOCKTIMEVERIFY, 7 VERIFY_MINIMALIF, VERIFY_CHECKSEQUENCEVERIFY, 8) 9 10from pycoin.coins.SolutionChecker import ScriptError 11 12 13def make_bad_opcode(opcode, even_outside_conditional=False, err=errno.BAD_OPCODE): 14 def bad_opcode(vm): 15 raise ScriptError("invalid opcode %s at %d" % (opcode, vm.pc-1), err) 16 bad_opcode.outside_conditional = even_outside_conditional 17 return bad_opcode 18 19 20def do_OP_CODESEPARATOR(vm): 21 vm.begin_code_hash = vm.pc 22 23 24def do_OP_TOALTSTACK(vm): 25 vm.altstack.append(vm.pop()) 26 27 28def do_OP_RESERVED(vm): 29 if vm.conditional_stack.all_if_true(): 30 raise ScriptError("OP_RESERVED encountered", errno.BAD_OPCODE) 31 vm.op_count -= 1 32 33 34do_OP_RESERVED.outside_conditional = True 35 36 37def do_OP_FROMALTSTACK(vm): 38 if len(vm.altstack) < 1: 39 raise ScriptError("alt stack empty", errno.INVALID_ALTSTACK_OPERATION) 40 vm.append(vm.altstack.pop()) 41 42 43def discourage_nops(vm): 44 if (vm.flags & VERIFY_DISCOURAGE_UPGRADABLE_NOPS): 45 raise ScriptError("discouraging nops", errno.DISCOURAGE_UPGRADABLE_NOPS) 46 47 48def make_if(reverse_bool=False): 49 def f(vm): 50 stack = vm.stack 51 conditional_stack = vm.conditional_stack 52 the_bool = False 53 if conditional_stack.all_if_true(): 54 if len(stack) < 1: 55 raise ScriptError("IF with no condition", errno.UNBALANCED_CONDITIONAL) 56 item = vm.pop() 57 if vm.flags & VERIFY_MINIMALIF: 58 if item not in (vm.VM_FALSE, vm.VM_TRUE): 59 raise ScriptError("non-minimal IF", errno.MINIMALIF) 60 the_bool = vm.bool_from_script_bytes(item) 61 vm.conditional_stack.OP_IF(the_bool, reverse_bool=reverse_bool) 62 f.outside_conditional = True 63 return f 64 65 66def do_OP_ELSE(vm): 67 vm.conditional_stack.OP_ELSE() 68 69 70do_OP_ELSE.outside_conditional = True 71 72 73def do_OP_ENDIF(vm): 74 vm.conditional_stack.OP_ENDIF() 75 76 77do_OP_ENDIF.outside_conditional = True 78 79 80def do_OP_CHECKLOCKTIMEVERIFY(vm): 81 if not (vm.flags & VERIFY_CHECKLOCKTIMEVERIFY): 82 if (vm.flags & VERIFY_DISCOURAGE_UPGRADABLE_NOPS): 83 raise ScriptError("discouraging nops", errno.DISCOURAGE_UPGRADABLE_NOPS) 84 return 85 if vm.tx_context.sequence == 0xffffffff: 86 raise ScriptError("nSequence equal to 0xffffffff") 87 if len(vm.stack) < 1: 88 raise ScriptError("empty stack on CHECKLOCKTIMEVERIFY") 89 if len(vm.stack[-1]) > 5: 90 raise ScriptError("script number overflow") 91 max_lock_time = vm.pop_int() 92 vm.push_int(max_lock_time) 93 if max_lock_time < 0: 94 raise ScriptError("top stack item negative on CHECKLOCKTIMEVERIFY") 95 era_max = (max_lock_time >= 500000000) 96 era_lock_time = (vm.tx_context.lock_time >= 500000000) 97 if era_max != era_lock_time: 98 raise ScriptError("eras differ in CHECKLOCKTIMEVERIFY") 99 if max_lock_time > vm.tx_context.lock_time: 100 raise ScriptError("nLockTime too soon") 101 102 103def _check_sequence_verify(sequence, tx_context_sequence): 104 # this mask is applied to extract lock-time from the sequence field 105 SEQUENCE_LOCKTIME_MASK = 0xffff 106 107 mask = SEQUENCE_LOCKTIME_TYPE_FLAG | SEQUENCE_LOCKTIME_MASK 108 sequence_masked = sequence & mask 109 tx_sequence_masked = tx_context_sequence & mask 110 if not (((tx_sequence_masked < SEQUENCE_LOCKTIME_TYPE_FLAG) and 111 (sequence_masked < SEQUENCE_LOCKTIME_TYPE_FLAG)) or 112 ((tx_sequence_masked >= SEQUENCE_LOCKTIME_TYPE_FLAG) and 113 (sequence_masked >= SEQUENCE_LOCKTIME_TYPE_FLAG))): 114 raise ScriptError("sequence numbers not comparable") 115 if sequence_masked > tx_sequence_masked: 116 raise ScriptError("sequence number too small") 117 118 119def do_OP_CHECKSEQUENCEVERIFY(vm): 120 if not (vm.flags & VERIFY_CHECKSEQUENCEVERIFY): 121 if (vm.flags & VERIFY_DISCOURAGE_UPGRADABLE_NOPS): 122 raise ScriptError("discouraging nops", errno.DISCOURAGE_UPGRADABLE_NOPS) 123 return 124 if len(vm.stack) < 1: 125 raise ScriptError("empty stack on CHECKSEQUENCEVERIFY", errno.INVALID_STACK_OPERATION) 126 if len(vm.stack[-1]) > 5: 127 raise ScriptError("script number overflow", errno.INVALID_STACK_OPERATION+1) 128 sequence = vm.pop_int() 129 vm.push_int(sequence) 130 if sequence < 0: 131 raise ScriptError( 132 "top stack item negative on CHECKSEQUENCEVERIFY", errno.NEGATIVE_LOCKTIME) 133 if sequence & SEQUENCE_LOCKTIME_DISABLE_FLAG: 134 return 135 # do the actual check 136 if vm.tx_context.version < 2: 137 raise ScriptError("CHECKSEQUENCEVERIFY: bad tx version", errno.UNSATISFIED_LOCKTIME) 138 if vm.tx_context.sequence & SEQUENCE_LOCKTIME_DISABLE_FLAG: 139 raise ScriptError("CHECKSEQUENCEVERIFY: locktime disabled") 140 141 _check_sequence_verify(sequence, vm.tx_context.sequence) 142 143 144def extra_opcodes(): 145 d = {} 146 BAD_OPCODES = "OP_VERIF OP_VERNOTIF ".split() 147 for opcode in BAD_OPCODES: 148 d[opcode] = make_bad_opcode(opcode, even_outside_conditional=True) 149 150 DISABLED_OPCODES = ( 151 "OP_CAT OP_SUBSTR OP_LEFT OP_RIGHT OP_INVERT OP_AND OP_OR OP_XOR OP_2MUL OP_2DIV OP_MUL " 152 "OP_DIV OP_MOD OP_LSHIFT OP_RSHIFT".split()) 153 for opcode in DISABLED_OPCODES: 154 d[opcode] = make_bad_opcode( 155 opcode, even_outside_conditional=True, err=errno.DISABLED_OPCODE) 156 157 BAD_OPCODES_OUTSIDE_IF = "OP_NULLDATA OP_PUBKEYHASH OP_PUBKEY OP_INVALIDOPCODE".split() 158 for opcode in BAD_OPCODES_OUTSIDE_IF: 159 d[opcode] = make_bad_opcode(opcode, even_outside_conditional=False) 160 161 NOP_SET = ( 162 "OP_NOP1 OP_NOP3 OP_NOP4 OP_NOP5 OP_NOP6 OP_NOP7 OP_NOP8 OP_NOP9 OP_NOP10".split()) 163 for opcode in NOP_SET: 164 d[opcode] = discourage_nops 165 166 d["OP_IF"] = make_if() 167 d["OP_NOTIF"] = make_if(reverse_bool=True) 168 169 for i in (1, 2, 4): 170 d["OP_PUSHDATA%d" % i] = lambda s: 0 171 172 for v in range(0, 128): 173 d["OP_%d" % v] = lambda s: 0 174 return d 175 176 177""" 178The MIT License (MIT) 179 180Copyright (c) 2013-2017 by Richard Kiss 181 182Permission is hereby granted, free of charge, to any person obtaining a copy 183of this software and associated documentation files (the "Software"), to deal 184in the Software without restriction, including without limitation the rights 185to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 186copies of the Software, and to permit persons to whom the Software is 187furnished to do so, subject to the following conditions: 188 189The above copyright notice and this permission notice shall be included in 190all copies or substantial portions of the Software. 191 192THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 193IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 194FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 195AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 196LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 197OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 198THE SOFTWARE. 199""" 200