SOLIDITY关键字EMIT

引入emit背景:

ERC20 token标准介绍了一种Transfer事件以及一个transfer()方法。
它们的调用语法不完全相同:
transfer(address to, uint value);
Transfer(address from, address to, uint256 _value);

但是这种相似足够引起混淆。
对未来的Solidity程序员来说这是一个很严重的问题,必须避免意外地将外部调用函数映射到一个
名字相似的事件上,而这导致了去年的DAO攻击。有人建议在事件名前面加上Log前缀来标识以避免将函数和事件混淆,但是最后还是决定引进一个新的关键字emit。

所以:
event Transfer(address from, address to, uint256 _value);
// …
Transfer(from, to, value);
就变为了:

event Transfer(address from, address to, uint256 _value);
// …
emit Transfer(from, to, value);

这就能够让函数调用和事件日志之间具备了语义上的不同。

Transfer事件:
当token被转移的时候必须触发该事件,包括零值转移。
一个创建新token的合约在给_from地址赋0x0值时必须触发一个Transfer事件event Transfer(address indexed _from, address indexed _to, uint256 _value)

transfer方法:
转移_value个token到地址_to,必须激活Transfer事件,若_from账户余额token不足,则该函数应该抛出异常。注意零值转移必须和普通转移一样必须激活Transfer事件

function transfer(address _to, uint256 _value) returns (bool success)

最近3月8日的版本v0.4.21,引进emit关键字来触发事件,这有助于分清功能和事件,这也是之前遭遇DAO攻击导致以太坊硬分叉并催生经典以太坊ETC的原因之一。

根据solidity版本的注释可知:
一般:支持并推荐使用emit EventName()来明确地调用事件。为了让事件较常规函数调用更突出,应该是用emit EventName()而不是EventName()
来调用事件。
下面这个实例用于触发一个事件:
pragma solidity ^0.4.21;
contract ClientReceipt {
event Deposit(
address indexed _from,
bytes32 indexed _id,
uint _value
); //声明一个事件
function deposit(bytes32 _id) public payable {
// Events are emitted using `emit`, followed by
// the name of the event and the arguments
// (if any) in parentheses. Any such invocation
// (even deeply nested) can be detected from
// the JavaScript API by filtering for `Deposit`.
//事件被emit触发,括号内有事件名参数和其他参数,通过JS API过滤Deposit可检测到任何类似的调用
//(即使是深度嵌套也能够检测到)
emit Deposit(msg.sender, _id, msg.value);
}
}

这里必须确保编译器版本为0.4.12及以上,若较低的版本编译器会抛出错误。

你可能感兴趣的:(区块链)