區塊鏈100講:Solidity語法constant/view/pure關鍵字定義

image

經過本文學習,熟悉瞭解以太坊智能合約語言Solidity語法中constant,view,pure的區別。html

1

區別總結

在Solidity中constant,view,pure三個函數修飾詞的做用是告訴編譯器,函數不改變/不讀取狀態變量,這樣函數執行就能夠不消耗gas了(是徹底不消耗!),由於不須要礦工來驗證。ide

在Solidity v4.17以前,只有constant,後來有人嫌constant這個詞自己表明變量中的常量,不適合用來修飾函數,因此將constant拆成了view和pure。函數

  • view的做用和constant如出一轍,能夠讀取狀態變量可是不能改;學習

  • pure則更爲嚴格,pure修飾的函數不能改也不能讀狀態變量,不然編譯通不過。區塊鏈

你們能夠運行如下測試代碼來加深這3個關鍵字的理解。測試

contract constantViewPure{

    string name;

    uint public age;

        function constantViewPure() public{

        name = "liushiming";

        age = 29;

    }

        function getAgeByConstant() public constant returns(uint){

        age += 1;  //聲明爲constant,在函數體中又試圖去改變狀態變量的值,編譯會報warning, 可是能夠經過

        return age;  // return 30, 可是!狀態變量age的值不會改變,仍然爲29!

    }

         function getAgeByView() public view returns(uint){

        age += 1; //view和constant效果一致,編譯會報warning,可是能夠經過

        return age; // return 30,可是!狀態變量age的值不會改變,仍然爲29!

    }

        function getAgeByPure() public pure returns(uint){ 

       return age; //編譯報錯!pure比constant和view都要嚴格,pure徹底禁止讀寫狀態變量!

        return 1;

    }

}

2

詳細描述

2.1 Constant 狀態變量優化

狀態變量能夠被聲明爲 constant。在這種狀況下,只能使用那些在編譯時有肯定值的表達式來給它們賦值。 任何經過訪問 storage,區塊鏈數據(例如 now, this.balance 或者 block.number)或執行數據( msg.gas ) 或對外部合約的調用來給它們賦值都是不容許的。 在內存分配上有邊界效應(side-effect)的表達式是容許的,但對其餘內存對象產生邊界效應的表達式則不行。 內建(built-in)函數 keccak256,sha256,ripemd160,ecrecover,addmod 和 mulmod 是容許的(即便他們確實會調用外部合約)。ui

容許帶有邊界效應的內存分配器的緣由是這將容許構建複雜的對象,好比查找表(lookup-table)。 此功能還沒有徹底可用。this

編譯器不會爲這些變量預留存儲,它們的每次出現都會被替換爲相應的常量表達式(這將可能被優化器計算爲實際的某個值)。code

不是全部類型的狀態變量都支持用 constant 來修飾,當前支持的僅有值類型和字符串。

pragma solidity ^0.4.0;

contract C {

    uint constant x = 32**22 + 8;

    string constant text = "abc";

    bytes32 constant myHash = keccak256("abc");

}

2.2 View 函數

能夠將函數聲明爲 view 類型,這種狀況下要保證不修改狀態。

下面的語句被認爲是修改狀態:

pragma solidity ^0.4.16;

contract C {

    function f(uint a, uint b) public view returns (uint) {

        return a * (b + 42) + now;

    }

}

註解:

  • onstant 是 view 的別名。

  • Getter 方法被標記爲 view。

  • 編譯器沒有強制 view 方法不能修改狀態。

2.3 Pure 函數

函數能夠聲明爲 pure ,在這種狀況下,承諾不讀取或修改狀態。

除了上面解釋的狀態修改語句列表以外,如下被認爲是從狀態中讀取:

  • 讀取狀態變量。

  • 訪問 this.balance 或者 <address>.balance。

  • 訪問 block,tx, msg 中任意成員 (除 msg.sig 和 msg.data 以外)。

  • 調用任何未標記爲 pure 的函數。

  • 使用包含某些操做碼的內聯彙編。

pragma solidity ^0.4.16;

contract C {

    function f(uint a, uint b) public pure returns (uint) {

        return a * (b + 42);
   }
}

警告

編譯器沒有強制 pure 方法不能讀取狀態。

本文做者:HiBlock區塊鏈社區技術佈道者輝哥

原文發佈於簡書

區塊鏈馬拉松|Blockathon(2018)上海 邀請你來觀看路演啦~

如下是咱們的社區介紹,歡迎各類合做、交流、學習:)

image

相關文章
相關標籤/搜索