视图函数(View Functions)
如果一个函数不能修改它的状态变量,那可以声明为view
函数
下面的几种情况被认为是修改了状态:
1.写状态变量
2.触发事件 Emitting events.
3.创造其它合约 Creating other contracts.
4.使用了selfdestruct
5.通过call
调用发送以太币
6.调用了任何没有view
或pure
修饰的函数
7.使用了底层的调用函数(low-level calls)
8.使用了包含特定操作符的内联汇编
pragma solidity ^0.4.16;
contract C {
function f(uint a, uint b) public view returns (uint) {
return a * (b + 42) + now;
}
}
注意:
1、在函数中,constant
是view
的别名,constant已经被弃用,并且计划在0.5.0
版本删除
2、Getter
函数都被标记为view
3、如果使用无效的显示类型转换,即使调用了view
函数,状态也可能修改。当调用这种函数时,你可以切换编译器以使用STATICCALL
,从而通过添加pragma experimental "v0.5.0";
来防止修改EVM级别的状态。
当前编译器并未强制要求声明为view,但建议大家对于不会修改状态的函数的标记为view。
纯函数(Pure Functions)
如果函数即不读取状态,也不修改状态,那函数可以被修改为pure
以下几种情况被认为是读取了状态:
1.读取状态变量
2.访问了this.balance
或 <address>.balance
.
3.访问了block
, tx
, msg
的成员 (msg.sig
和 msg.data
除外).
4.调用了任何没有pure
修饰的函数
5.使用了包含特定操作符的内联汇编
pragma solidity ^0.4.16;
contract C {
function f(uint a, uint b) public pure returns (uint) {
return a * (b + 42);
}
}
尽管view 和 pure 修饰符编译器并未强制要求使用,view 和 pure 修饰也不会带来gas 消耗的改变,但是更好的编码习惯让我们跟容易发现智能合约中的错误。
网友评论