Beispiel #1
0
    def from_buffer(buffer):
        # Inverse operation of Output.to_bytes(), check that out.
        amount = decode_int(buffer.read(8), big_endian = False)

        script_len = buffer.read_varint()
        script = Script.from_bytes(buffer.read(script_len))

        return Output.create(amount, script)
Beispiel #2
0
    def test_binary_const_pushes(self):
        for length in xrange(1, 76):
            opcode = Opcode(length)
            string = 'a' * length

            s = Script.from_bytes(chr(length) + string)

            assert s.instructions == [Instruction(opcode, string)]
Beispiel #3
0
    def from_buffer(buffer):
        # Inverse operation of Output.to_bytes(), check that out.
        amount = decode_int(buffer.read(8), big_endian=False)

        script_len = buffer.read_varint()
        script = Script.from_bytes(buffer.read(script_len))

        return Output.create(amount, script)
Beispiel #4
0
    def test_binary_all_nonpush_opcodes(self):
        opcodes = []
        for name, value in inspect.getmembers(opcode):
            if isinstance(value, Opcode) and not value.is_push():
                opcodes.append(value)

        bytes = ''.join(chr(opcode.number) for opcode in opcodes)

        s = Script.from_bytes(bytes)
        assert s.instructions == map(Instruction, opcodes)
Beispiel #5
0
    def from_buffer(cls, buffer):
        # Inverse operation of Input.to_bytes(), check that out.
        tx_id     = encode_hex(buffer.read(32)[::-1]) # reversed
        txo_index = decode_int(buffer.read(4), big_endian = False)

        script_len = buffer.read_varint()
        script     = Script.from_bytes(buffer.read(script_len))

        seq_number = decode_int(buffer.read(4), big_endian = False)

        return cls(tx_id, txo_index, script, seq_number)
Beispiel #6
0
    def test_binary_var_pushes(self):
        s1 = Script.from_bytes(chr(OP_PUSHDATA1.number) + '\3' + 'abc')
        assert s1.instructions == [Instruction(OP_PUSHDATA1, 'abc')]

        s2 = Script.from_bytes(chr(OP_PUSHDATA2.number) + '\3\0' + 'abc')
        assert s2.instructions == [Instruction(OP_PUSHDATA2, 'abc')]

        s2 = Script.from_bytes(chr(OP_PUSHDATA4.number) + '\3\0\0\0' + 'abc')
        assert s2.instructions == [Instruction(OP_PUSHDATA4, 'abc')]

        with raises(Buffer.InsufficientData):
            Script.from_bytes(chr(OP_PUSHDATA1.number) + '\3' + 'a')

        with raises(Buffer.InsufficientData):
            Script.from_bytes(chr(OP_PUSHDATA2.number) + '\3\0' + 'a')

        with raises(Buffer.InsufficientData):
            Script.from_bytes(chr(OP_PUSHDATA4.number) + '\3\0\0\0' + 'a')
Beispiel #7
0
 def test_binary_single(self):
     s = Script.from_bytes('\0')
     assert s.instructions == [Instruction(OP_0)]
Beispiel #8
0
    def verify(self, script_sig, script_pubkey, tx = None, nin = 0, flags = 0):
        """
        Verifies a Script by executing it and returns true if it is valid.
        This function needs to be provided with the scriptSig and the scriptPubkey
        separately.

        :param script_sig: the script's first part (corresponding to the tx input)
        :param script_pubkey: the script's last part (corresponding to the tx output)
        :param tx: the transaction containing the script_sig in one input (used to
            check signature validity for some opcodes like OP_CHECKSIG)
        :param nin: index of the transaction input containing the scriptSig verified.
        :param flags: evaluation flags. See Interpreter.SCRIPT_* constants

        Translated from bitcoind's VerifyScript
        """
        self.initialize()
        self.script = script_sig
        self.tx = tx or Transaction([ Input('', 0, Script()) ], [ Output(0, Script()) ])
        self.nin = nin
        self.flags = flags

        if flags & Interpreter.SCRIPT_VERIFY_SIGPUSHONLY and not script_sig.is_push_only():
            self.errstr = 'SCRIPT_ERR_SIG_PUSHONLY'
            return False

        # Evaluate script_sig
        if not self.evaluate():
            return False

        if self.flags & Interpreter.SCRIPT_VERIFY_P2SH:
            stack_copy = list(self.stack)

        stack = self.stack
        self.initialize()
        self.script = script_pubkey
        self.stack = stack
        self.tx = tx or Transaction([ Input('', 0, Script()) ], [ Output(0, Script()) ])
        self.nin = nin or 0
        self.flags = flags or 0

        # evaluate script_pubkey
        if not self.evaluate():
            return False

        if len(self.stack) == 0:
            self.errstr = 'SCRIPT_ERR_EVAL_FALSE_NO_RESULT'
            return False

        bytes = self.stack[-1]
        if not Interpreter.cast_to_bool(bytes):
            self.errstr = 'SCRIPT_ERR_EVAL_FALSE_IN_STACK'
            return False

        # Additional validation for spend-to-script-hash transactions:
        if (self.flags & Interpreter.SCRIPT_VERIFY_P2SH) and script_sig.is_script_hash_out():
            # script_sig must be literals-only or validation fails
            if not script_sig.is_push_only():
                self.errstr = 'SCRIPT_ERR_SIG_PUSHONLY'
                return False

            # stack_copy cannot be empty here, because if it was the
            # P2SH  HASH <> EQUAL  script_pubkey would be evaluated with
            # an empty stack and the EvalScript above would return false.
            if len(stack_copy) == 0:
                raise Exception('internal error - stack copy empty')

            redeem_bytes = stack_copy[-1]
            redeem_script = Script.from_bytes(redeem_bytes)
            stack_copy = stack_copy[:-1]

            self.initialize()
            self.script = redeem_script
            self.stack = stack_copy
            self.tx = tx or Transaction([ Input('', 0, Script()) ], [ Output(0, Script()) ])
            self.nin = nin or 0
            self.flags = flags or 0

            # Evaluate redeem_script
            if not self.evaluate():
                return False

            if len(stack_copy) == 0:
                self.errstr = 'SCRIPT_ERR_EVAL_FALSE_NO_P2SH_STACK'
                return False

            if not Interpreter.cast_to_bool(stack_copy[-1]):
                self.errstr = 'SCRIPT_ERR_EVAL_FALSE_IN_P2SH_STACK'
                return False

        return True
Beispiel #9
0
    def verify(self, script_sig, script_pubkey, tx=None, nin=0, flags=0):
        """
        Verifies a Script by executing it and returns true if it is valid.
        This function needs to be provided with the scriptSig and the scriptPubkey
        separately.

        :param script_sig: the script's first part (corresponding to the tx input)
        :param script_pubkey: the script's last part (corresponding to the tx output)
        :param tx: the transaction containing the script_sig in one input (used to
            check signature validity for some opcodes like OP_CHECKSIG)
        :param nin: index of the transaction input containing the scriptSig verified.
        :param flags: evaluation flags. See Interpreter.SCRIPT_* constants

        Translated from bitcoind's VerifyScript
        """
        self.initialize()
        self.script = script_sig
        self.tx = tx or Transaction([Input('', 0, Script())],
                                    [Output(0, Script())])
        self.nin = nin
        self.flags = flags

        if flags & Interpreter.SCRIPT_VERIFY_SIGPUSHONLY and not script_sig.is_push_only(
        ):
            self.errstr = 'SCRIPT_ERR_SIG_PUSHONLY'
            return False

        # Evaluate script_sig
        if not self.evaluate():
            return False

        if self.flags & Interpreter.SCRIPT_VERIFY_P2SH:
            stack_copy = list(self.stack)

        stack = self.stack
        self.initialize()
        self.script = script_pubkey
        self.stack = stack
        self.tx = tx or Transaction([Input('', 0, Script())],
                                    [Output(0, Script())])
        self.nin = nin or 0
        self.flags = flags or 0

        # evaluate script_pubkey
        if not self.evaluate():
            return False

        if len(self.stack) == 0:
            self.errstr = 'SCRIPT_ERR_EVAL_FALSE_NO_RESULT'
            return False

        bytes = self.stack[-1]
        if not Interpreter.cast_to_bool(bytes):
            self.errstr = 'SCRIPT_ERR_EVAL_FALSE_IN_STACK'
            return False

        # Additional validation for spend-to-script-hash transactions:
        if (self.flags & Interpreter.SCRIPT_VERIFY_P2SH
            ) and script_sig.is_script_hash_out():
            # script_sig must be literals-only or validation fails
            if not script_sig.is_push_only():
                self.errstr = 'SCRIPT_ERR_SIG_PUSHONLY'
                return False

            # stack_copy cannot be empty here, because if it was the
            # P2SH  HASH <> EQUAL  script_pubkey would be evaluated with
            # an empty stack and the EvalScript above would return false.
            if len(stack_copy) == 0:
                raise Exception('internal error - stack copy empty')

            redeem_bytes = stack_copy[-1]
            redeem_script = Script.from_bytes(redeem_bytes)
            stack_copy = stack_copy[:-1]

            self.initialize()
            self.script = redeem_script
            self.stack = stack_copy
            self.tx = tx or Transaction([Input('', 0, Script())],
                                        [Output(0, Script())])
            self.nin = nin or 0
            self.flags = flags or 0

            # Evaluate redeem_script
            if not self.evaluate():
                return False

            if len(stack_copy) == 0:
                self.errstr = 'SCRIPT_ERR_EVAL_FALSE_NO_P2SH_STACK'
                return False

            if not Interpreter.cast_to_bool(stack_copy[-1]):
                self.errstr = 'SCRIPT_ERR_EVAL_FALSE_IN_P2SH_STACK'
                return False

        return True