如果用户没有发送足够的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