一、定义

在solidity中,我们知道,如果修改了合约的状态变量,那这个改变需要让矿工来通知到整个网络,这意味着需要支付给矿工gas。 但有一些函数,它不会修改状态变量,这就意味着这些函数执行是不需要消耗gas的。 在solidity V0.4.17 版本前,引入了constant关键字,来告知编译器,这些函数执行不修改状态变量,无需消耗gas。 V0.4.17版本及其之后,又做了更进一步的细分,deprecate掉了constant关键字,使用:

二、pure修饰符

对比一下加和不加pure的区别。

pragma solidity ^0.4.24;


contract Modifiers {
    function pureFoo() public pure returns (uint){
		uint a = 0;
        for(uint256 i=0; i<1024; i++)
			a += i;
        return a;
    }
    function nopureFoo() public returns (uint){
		uint a = 0;
        for(uint256 i=0; i<1024; i++)
			a += i;
        return a;
    }
}

pureFoo和nopureFoo的实现是一样的,都不会读取和写入本地数据。 如果没有pure修饰符,则执行结果如下: 需要消耗93273的Gas。但是如果加了pure,则很快就能得到结果,执行结果如下:

也就是加了pure,则不会消耗gas。 如果在pure函数中访问状态变量,则会编译不通过。

contract Modifiers {
	
	uint public b = 1;
    
    function bar() public pure returns (uint){ //编译不通过,pure中禁止访问状态属性b。
        for(uint256 i=0; i<2; i++)
			b += i;
        return b;
    }
}

三、view关键字

和pure一样,声明为view的函数调用也是不需要耗费gas的。 看如下两个函数。

contract Modifiers {

	uint public b = 1;

    function viewBar() public view returns (uint){
		uint c = 0;
        for(uint256 i=0; i<1024; i++)
			c += b;
        return c;
    }
    
    function bar() public view returns (uint){
        for(uint256 i=0; i<2; i++)
			b += i;
        return b;
    }
}

函数viewBar中,仅读取状态变量,调用时不耗费gas。 函数bar中,对状态变量做了修改,但由于方法被声明为pure,调用的时候也不耗费gas。 注意,这也导致对状态变量b的修改是不生效的b在bar执行前后,值都是 1 。
调用bar之后,查询b的值,仍然是 1


感谢您对本文的关注,如果您对区块链技术有兴趣,可以加入我们一起探讨, 请扫码关注“可可链”的微信公众号,并留言“加入可可链”。

本文欢迎转载,转载时请注明本文来自 微信公众号“可可链”。