『0008』- Solidity中public、internal、private在狀態變量和函數中的使用以及Solidity智能合約繼承、重寫

孔壹學院:國內區塊鏈職業教育領先品牌

作者:黎躍春,區塊鏈、高可用架構工程師
微信:liyc1215 QQ羣:348924182 博客:http://liyuechun.org

在上一小節中我們在函數參數中使用storage這個關鍵字時,當前的函數必須是internal或者private類型。

在本小節中,我(微信:liyc1215)將重點爲大家介紹屬性函數的使用權限。

狀態變量、函數的權限

一、public

備註:爲了演示方便,我直接通過https://remix.ethereum.org/來進行演示。

public類型的狀態變量函數的權限最大,可供外部、子合約、合約內部訪問。

pragma solidity ^0.4.4;

contract Animal {


    string _birthDay; // 生日
    int public _age; // 年齡
    int internal _weight; // 身高
    string private _name; // 姓名


    function Animal() {
      _age = 29;
      _weight = 170;
      _name = "Lucky dog";
      _birthDay = "2011-01-01";
    }

    function birthDay() constant returns (string) {
      return _birthDay;
    }

    function age() constant public returns (int) {
      return _age;
    }

    function height() constant internal returns (int) {
      return _weight;
    }

    function name() constant private returns (string) {
      return _name;
    }

}

solidity public

在這個合約中,我們通過運行結果不難看出,可供外部調用的一個有三個函數,分別爲birthDay_age,age,也許有人會問,爲什麼外部可以調用_age函數呢,爲什麼外部可以調用_age函數呢,爲什麼外部可以調用_age函數呢,原因是因爲我們的狀態變量_age的權限是public,當一個狀態變量的權限爲public類型時,它就會自動生成一個可供外部調用的get函數。在我們這個合約中,因爲_agepublic類型,所以在合約中其實會有一個默認的和狀態變量同名的get函數,如下所示:

function _age() constant public returns (int) {
  return _age;
}

在我們顯示聲明的四個函數中:

function birthDay() constant returns (string) {
  return _birthDay;
}

function age() constant public returns (int) {
  return _age;
}

function height() constant internal returns (int) {
  return _weight;
}

function name() constant private returns (string) {
  return _name;
}

由上面的運行結果,我們知道,這四個函數中,只有birthDayage函數可供外部訪問,【PS:age函數是我顯示聲明的,_age函數是因爲狀態變量_agepublic自動生成的,因爲狀態變量默認爲internal類型,所以不會自動生成可供外部訪問的和狀態變量同名的函數】,換句話說,只有public類型的函數纔可以供外部訪問,由此可知,函數聲明時,它默認爲是public類型,而狀態變量聲明時,默認爲internal類型

小結:

  • 狀態變量聲明時,默認爲internal類型,只有顯示聲明爲public類型的狀態變量纔會自動生成一個和狀態變量同名的get函數以供外部獲取當前狀態變量的值。
  • 函數聲明時默認爲public類型,和顯示聲明爲public類型的函數一樣,都可供外部訪問。

二、internal

  • internal類型的狀態變量可供外部子合約調用。
  • internal類型的函數private類型的函數一樣,智能合約自己內部調用,它和其他語言中的protected不完全一樣。
pragma solidity ^0.4.4;

contract Animal {

    string _birthDay; // 生日
    int public _age; // 年齡
    int internal _weight; // 身高
    string private _name; // 姓名

    function Animal() {
      _age = 29;
      _weight = 170;
      _name = "Lucky dog";
      _birthDay = "2011-01-01";
    }

    function birthDay() constant returns (string) {
      return _birthDay;
    }

    function age() constant public returns (int) {
      return _age;
    }

    function height() constant internal returns (int) {
      return _weight;
    }

    function name() constant private returns (string) {
      return _name;
    }

}


contract Person is Animal {

    function Person() {

        _age = 50;
        _weight = 270;
        _birthDay = "2017-01-01";

    }
}

solidity 合約 繼承

在這個案例中,contract Person is AnimalPerson合約繼承了Animal合約的public/internal的所有狀態變量,但是隻能繼承父合約中的所有的public類型的函數,不能繼承internal/private的函數,不能繼承internal/private的函數,不能繼承internal/private的函數。

三、private

我們在person合約中嘗試調用_name狀態變量,你會發現,編譯沒法通過。

solidity private

因爲_name狀態變量在Animal合約中屬於private私有類型,只能在Animal內部使用,所以到我們在子合約Person中嘗試使用時,就會報錯。

四、重寫

子合約可以將父合約public類型的函數,只能繼承public類型的函數,只能繼承public類型的函數,只能繼承public類型的函數,我們可以直接調用繼承過來的函數,當然,我們還可以對繼承過來的函數進行重寫。

  • 重寫前
pragma solidity ^0.4.4;

contract Animal {

    string _birthDay; // 生日
    int public _age; // 年齡
    int internal _weight; // 身高
    string private _name; // 姓名

    function Animal() {
      _age = 29;
      _weight = 170;
      _name = "Lucky dog";
      _birthDay = "2011-01-01";
    }

    function birthDay() constant returns (string) {
      return _birthDay;
    }

    function age() constant public returns (int) {
      return _age;
    }

    function height() constant internal returns (int) {
      return _weight;
    }

    function name() constant private returns (string) {
      return _name;
    }

}


contract Person is Animal {

}

solidity 重寫前

  • 重寫後
pragma solidity ^0.4.4;

contract Animal {

    string _birthDay; // 生日
    int public _age; // 年齡
    int internal _weight; // 身高
    string private _name; // 姓名

    function Animal() {
      _age = 29;
      _weight = 170;
      _name = "Lucky dog";
      _birthDay = "2011-01-01";
    }

    function birthDay() constant returns (string) {
      return _birthDay;
    }

    function age() constant public returns (int) {
      return _age;
    }

    function height() constant internal returns (int) {
      return _weight;
    }

    function name() constant private returns (string) {
      return _name;
    }

}


contract Person is Animal {

    function birthDay() constant returns (string) {

      return "2020-12-15";
    }

}

solidity 重寫後

小結

本篇文章主要全面介紹了合約中狀態變量和函數中public、internal、private三種權限在合約內部、外部以及子合約中的應用。通過本篇教程的學習,我相信你一定會進一步瞭解狀態變量的繼承以及函數繼承重寫。接下來的系列文章中,我們將進一步講師Solidity中相關的語法以及開發中的注意事項。

技術交流

  • 區塊鏈技術交流QQ羣:348924182

  • 「區塊鏈部落」官方公衆號

發佈了94 篇原創文章 · 獲贊 31 · 訪問量 26萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章