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中有两条说明: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((指令没有显式返回错误,Jump表也被配置为始终返回opRevert:的错误

instructionSet[REVERT] = &operation{
execute:    opRevert,
dynamicGas: gasRevert,
minStack:   minStack(2, 0),
maxStack:   maxStack(2, 0),
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

最新更新