Esempio n. 1
0
def paygas(computation):
    gas_price = computation.stack_pop(type_hint=constants.UINT256)

    # Only valid if (1) triggered in a top level call and
    # (2) not been set already during this transaction execution
    try:
        computation.set_PAYGAS_gasprice(gas_price)
    except (GasPriceAlreadySet, NotTopLevelCall):
        computation.stack_push(0)
    else:
        with computation.state_db(read_only=False) as state_db:
            tx_initiator = computation.msg.to
            tx_initiator_balance = state_db.get_balance(tx_initiator)

            PAYGAS_gasprice = computation.get_PAYGAS_gas_price()
            if PAYGAS_gasprice is None:
                PAYGAS_gasprice = 0
            fee_to_be_charged = (
                PAYGAS_gasprice *
                computation.transaction_context.transaction_gas_limit)

            if tx_initiator_balance < fee_to_be_charged:
                raise InsufficientFunds("Insufficient funds: {0} < {1}".format(
                    tx_initiator_balance, fee_to_be_charged))

            state_db.delta_balance(tx_initiator, -1 * fee_to_be_charged)
        computation.stack_push(1)
Esempio n. 2
0
def _apply_frontier_message(vm, message):
    snapshot = vm.snapshot()

    if message.depth > constants.STACK_DEPTH_LIMIT:
        raise StackDepthLimit("Stack depth limit reached")

    if message.should_transfer_value and message.value:
        with vm.state_db() as state_db:
            sender_balance = state_db.get_balance(message.sender)

            if sender_balance < message.value:
                raise InsufficientFunds("Insufficient funds: {0} < {1}".format(
                    sender_balance, message.value))

            state_db.delta_balance(message.sender, -1 * message.value)
            state_db.delta_balance(message.storage_address, message.value)

        vm.logger.debug(
            "TRANSFERRED: %s from %s -> %s",
            message.value,
            encode_hex(message.sender),
            encode_hex(message.storage_address),
        )

    with vm.state_db() as state_db:
        state_db.touch_account(message.storage_address)

    computation = vm.apply_computation(message)

    if computation.error:
        vm.revert(snapshot)
    else:
        vm.commit(snapshot)

    return computation
Esempio n. 3
0
    def apply_message(self):
        snapshot = self.vm_state.snapshot()

        if self.msg.depth > constants.STACK_DEPTH_LIMIT:
            raise StackDepthLimit("Stack depth limit reached")

        if self.msg.should_transfer_value and self.msg.value:
            with self.vm_state.state_db() as state_db:
                sender_balance = state_db.get_balance(self.msg.sender)

                if sender_balance < self.msg.value:
                    raise InsufficientFunds(
                        "Insufficient funds: {0} < {1}".format(
                            sender_balance, self.msg.value))

                state_db.delta_balance(self.msg.sender, -1 * self.msg.value)
                state_db.delta_balance(self.msg.storage_address,
                                       self.msg.value)

            self.logger.debug(
                "TRANSFERRED: %s from %s -> %s",
                self.msg.value,
                encode_hex(self.msg.sender),
                encode_hex(self.msg.storage_address),
            )

        with self.vm_state.state_db() as state_db:
            state_db.touch_account(self.msg.storage_address)

        computation = self.apply_computation(
            self.vm_state,
            self.msg,
            self.opcodes,
            self.precompiles,
        )

        if computation.is_error:
            self.vm_state.revert(snapshot)
        else:
            self.vm_state.commit(snapshot)

        return computation
Esempio n. 4
0
def _apply_message(evm, message):
    snapshot = evm.snapshot()

    if message.depth > constants.STACK_DEPTH_LIMIT:
        raise StackDepthLimit("Stack depth limit reached")

    if message.should_transfer_value and message.value:
        sender_balance = evm.block.state_db.get_balance(message.sender)

        if sender_balance < message.value:
            raise InsufficientFunds(
                "Insufficient funds: {0} < {1}".format(sender_balance, message.value)
            )

        sender_balance -= message.value
        evm.block.state_db.set_balance(message.sender, sender_balance)

        recipient_balance = evm.block.state_db.get_balance(message.storage_address)
        recipient_balance += message.value
        evm.block.state_db.set_balance(message.storage_address, recipient_balance)

        if evm.logger is not None:
            evm.logger.debug(
                "TRANSFERRED: %s from %s -> %s",
                message.value,
                encode_hex(message.sender),
                encode_hex(message.storage_address),
            )

    if not evm.block.state_db.account_exists(message.storage_address):
        evm.block.state_db.touch_account(message.storage_address)

    computation = evm.apply_computation(message)

    if computation.error:
        evm.revert(snapshot)
    return computation