Solidity:是否可以将事件发射和要求结合起来?

问题描述

如果用户没有发送足够多的 Eth,我希望 UI 知道并回复一条消息。

函数验证 msg.value,但我想在这种情况下触发和事件(UI 可以响应)。

function doSomething() external payable {
  require(
      msg.value == price,'Please send the correct amount of ETH'
  );
  //Do something
}

这是正确的做法吗?

有没有办法将 require() 与发送事件结合起来?

function doSomething() external payable {
 if (msg.value < amount){
   emit NotEnoughEth('Please make sure to send correct amount');
   revert();
 }

  //Do something
}

解决方法

emit NotEnoughEth('Please make sure to send correct amount');

你不能这样做。 为了能够发出 types.Log,您需要执行 evm.Call() 而无需执行还原。您所指的 EVM 中有 2 条指令:makeLog (https://github.com/ethereum/go-ethereum/blob/2aaff0ad76991be8851ae30454d2e2e967704102/core/vm/instructions.go#L828) 这是创建事件日志的指令。和 opRevert (https://github.com/ethereum/go-ethereum/blob/2aaff0ad76991be8851ae30454d2e2e967704102/core/vm/instructions.go#L806) ,所以如果你进行恢复,你的 Call() 将返回一个错误,并且以太坊状态数据库上的所有交易结果都将被恢复,并且什么都不会保存。由于取消存储,您的日志无法保存在区块链上。

这是将检查错误并恢复到以前保存的状态(又名快照)的代码:

    if err != nil {
        evm.StateDB.RevertToSnapshot(snapshot)
        if err != ErrExecutionReverted {
            gas = 0
        }
        // TODO: consider clearing up unused snapshots:
        //} else {
        //  evm.StateDB.DiscardSnapshot(snapshot)
    }
    return ret,gas,err
}

https://github.com/ethereum/go-ethereum/blob/2aaff0ad76991be8851ae30454d2e2e967704102/core/vm/evm.go#L280

即使 opRevert() 指令没有明确返回错误,跳转表配置为始终为 opRevert 返回错误:

instructionSet[REVERT] = &operation{
    execute:    opRevert,dynamicGas: gasRevert,minStack:   minStack(2,0),maxStack:   maxStack(2,memorySize: memoryRevert,reverts:    true,returns:    true,}

https://github.com/ethereum/go-ethereum/blob/2aaff0ad76991be8851ae30454d2e2e967704102/core/vm/jump_table.go#L155

并且解释器会自行发出 errExecutionReverted

    case operation.reverts:
        return res,ErrExecutionReverted

https://github.com/ethereum/go-ethereum/blob/2aaff0ad76991be8851ae30454d2e2e967704102/core/vm/interpreter.go#L297

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...