Solidity关键字:constant,view,pure

关键字:constant,view,pure

constantviewpure三个函数修饰词的作用是告诉编译器,函数不改变/不读取状态变量这样函数执行就可以不消耗gas了,因为不需要矿工来验证。
注:constant在0.5.0以后版本被移除,进而使用view或pure来代替。

constant:代表这个函数可以读取状态变量但是不能改(已经移除)
view:view修饰的函数作用和constant一样,该函数可以读取状态变量但是不能改
pure:代表函数不能改也不能读状态变量,否则编译通不过

例如:

contract constantViewPure(){
    uint public balance;
    
    constructor(){ 
        balance = 10;
    }
    
    function getBalanceByConstant() public constant returns(uint){
        balance += 10;  //声明为constant,试图去改变状态变量的值,编译会报warning, 但是可以通过
        return balance;  // return 20, 但是!状态变量balance的值不会改变,仍然为10!
        //v0.5.0以后报错,^0.4.0可以执行,有及warning提示
    } 
    
    function getBalanceByView() public view returns(uint){
        balance += 10; //view和constant效果一致,编译会报warning,但是可以通过
        return balance; // return 20,但是!状态变量balance的值不会改变,仍然为10!
        //v0.5.0以后报错,^0.4.0可以执行,有及warning提示
    }
    
    function getBalanceByPure() public pure returns(uint){
        return balance; //编译报错!pure比constant和view都要严格,pure完全禁止读写状态变量! 
    } 
    
    function getBalanceByPure2() public pure returns(uint){
        return 10; //可以执行 
    } 
}

详细描述

constant状态变量

状态变量可以被声明为 constant。(支持的仅有值类型和字符串)
在这种情况下,只能使用那些在编译时有确定值的表达式来给它们赋值。
任何通过访问 storage,区块链数据(例如 now, this.balance 或者 block.number)
或执行数据( msg.gas ) 或对外部合约的调用来给它们赋值都是不允许的。

在内存分配上有边界效应(side-effect)的表达式是允许的,但对其他内存对象产生边界效应的表达式则不行。
内建(built-in)函数 keccak256,sha256,ripemd160,ecrecover,addmod 和 mulmod 是允许的(即使他们确实会调用外部合约)

编译器不会为这些变量预留存储,它们的每次出现都会被替换为相应的常量表达式

view 函数

可以将函数声明为 view 类型,这种情况下要保证不修改状态。

下面的语句被认为是修改状态:

  1. 修改状态变量。
  2. 产生事件。
  3. 创建其它合约。
  4. 使用 selfdestruct。
  5. 通过调用发送以太币。
  6. 调用任何没有标记为 view 或者 pure 的函数。
  7. 使用低级调用。
  8. 使用包含特定操作码的内联汇编。

Pure 函数

函数可以声明为 pure ,在这种情况下,承诺不读取或修改状态。

除了上面解释的状态修改语句列表之外,以下被认为是从状态中读取:

  1. 读取状态变量。
  2. 访问 this.balance 或者
    .balance。
  3. 访问 block,tx, msg 中任意成员 (除 msg.sig 和 msg.data 之外)。
  4. 调用任何未标记为 pure 的函数。
  5. 使用包含某些操作码的内联汇编。

你可能感兴趣的:(Solidity关键字:constant,view,pure)