Solidity:是否可以结合事件发出和要求?
Solidity: Is it possible to combine event emit and require?
如果用户没有发送足够的 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) this is the one that creates and Event log. And opRevert
(https://github.com/ethereum/go-ethereum/blob/2aaff0ad76991be8851ae30454d2e2e967704102/core/vm/instructions.go#L806) ,因此如果您进行还原,您的 Call()
将 return 出错,并且所有以太坊状态数据库上的交易结果将被还原,并且不会保存任何内容。由于存储被取消,您的Log无法保存在区块链上。
这是将检查错误并恢复到之前保存的状态(又名快照)的代码:
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
}
即使 opRevert() 指令没有明确 return 错误,跳转 table 配置为始终 return opRevert
错误:
instructionSet[REVERT] = &operation{
execute: opRevert,
dynamicGas: gasRevert,
minStack: minStack(2, 0),
maxStack: maxStack(2, 0),
memorySize: memoryRevert,
reverts: true,
returns: true,
}
解释器将自己发出errExecutionReverted
:
case operation.reverts:
return res, ErrExecutionReverted
如果用户没有发送足够的 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) this is the one that creates and Event log. And opRevert
(https://github.com/ethereum/go-ethereum/blob/2aaff0ad76991be8851ae30454d2e2e967704102/core/vm/instructions.go#L806) ,因此如果您进行还原,您的 Call()
将 return 出错,并且所有以太坊状态数据库上的交易结果将被还原,并且不会保存任何内容。由于存储被取消,您的Log无法保存在区块链上。
这是将检查错误并恢复到之前保存的状态(又名快照)的代码:
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
}
即使 opRevert() 指令没有明确 return 错误,跳转 table 配置为始终 return opRevert
错误:
instructionSet[REVERT] = &operation{
execute: opRevert,
dynamicGas: gasRevert,
minStack: minStack(2, 0),
maxStack: maxStack(2, 0),
memorySize: memoryRevert,
reverts: true,
returns: true,
}
解释器将自己发出errExecutionReverted
:
case operation.reverts:
return res, ErrExecutionReverted