, ,

Solidity教學第三集_函式可視性與修飾語

Solidity教學

Solidity教學第三集_函式可視性與修飾語

區塊鏈的應用日趨廣泛,智能合約現階段也在金融、供應鏈等領域快速發展,讓許多流程高效率自動化,同時資安管控品質也大幅提升。以下將會有五篇教學文章,讓有或沒有程式背景的讀者都能先撰寫基礎智能合約,以便繼續深造或參與區塊鏈相關項目之商業開發案時能順利溝通。

上一篇章我們介紹了資料型別與架構,忘記的朋友可以回去多家複習。這一集我們將會針對Function Visibility, Modifiers & Time做教學,承接上一集的程式碼繼續。

Function Visibility

本集先學習function的Visibility可視性吧,在之前的課程中我們用了public 讓function只要在帳戶連進去的狀況下被智能合約外部呼叫。

Solidity教學
【沿用上期】

那如果今天我們想要建立一個function只能被智能合約內部所呼叫,那我們就要使用internal這個方法,讓我們來實作看看。

function incrementCount() internal {
    peopleCount += 1;
}

這樣一來這個function就只能被內部所呼叫,並且不能被外部所呼叫接下來我們就可以結合上週的練習,並在addPerson() 這個function裡面呼叫。

function addPerson(string memory _firstName, string memory _lastName) public {
    incrementCount()
    people[peopleCount] = Person(peopleCount, _firstName, _lastName);
}

Solidity教學
【範例 : internal】
Solidity教學
【第一次增加count為1】
Solidity教學
【第二次增加count為2】

Modifiers

接下來我們來講另一個function可視性的狀況,那就是modifiers他與允許我們增加一些特別的行為到我們的function當中,像是增加許可。我們來建立一個modifier只能讓特定的使用者或是擁有者去呼叫addPerson()這個function,並去限制其他人去呼叫這個function。

首先,我們建立一個儲存智能合約使用者的方法,我們可以用state變數。

address owner;

現在我們建立一個modifier,當使用者呼叫的時候可以去做check的動作

modifier onlyOwner() {
    require(msg.sender == owner);
    _;
}

我來講解一下這段程式碼在做什麼?

  • 第一我們宣告了modifier,並用了modifier這個語法,並寫上他的名稱onlyOwner
  • 第二,我們去存取現在呼叫這個function的account,msg.sender solidity在msg裡面提供了sender這個變數可以去查看現在有誰在交易過程中送出資料
  • 第三,我們使用require()去check account當中呼叫呼叫這個function的使用者,如果是對的話也就是true 程式繼續執行,而如果不是的話丟出錯誤
Solidity教學
【範例 : modifier】

現在我們可以設定一個擁有者、使用者在我們的智能合約當中。

constructor() public {
    owner = msg.sender;
}

現在我們可以加入modifier到我們的addperson,這樣一來只有owner可以呼叫他,而現在的程式碼是不是看起來有點亂,讓我們來有系統的整理一下歐

function addPerson(
    string memory _firstName,
    string memory _lastName
)
    public
    onlyOwner
{
    incrementCount()
    people[peopleCount] = Person(peopleCount, _firstName, _lastName);
}

接下來我們來試試看結合之前以及目前的內容來執行看看

pragma solidity 0.5.1;

contract MyContract {
    uint256 public peopleCount = 0;
    mapping(uint => Person) public people;

    address owner;

    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }
    struct Person {
        uint _id;
        string _firstName;
        string _lastName;
    }
    constructor() public {
        owner = msg.sender;
    }
    function addPerson(
        string memory _firstName,
        string memory _lastName
    )
        public
        onlyOwner
    {
        incrementCount()
        people[peopleCount] = Person(peopleCount, _firstName, _lastName);
    }
    function incrementCount() internal {
        peopleCount += 1;
    }
}

Solidity教學
【範例 : 結合先前內容】
Solidity教學
先選擇帳號一做為deploy,並執行剛剛的addperson跟count指令
Solidity教學
再來選擇帳號二同樣執行addperson以及count指令
Solidity教學
帳號二出現失敗,因為我們有限制我們的modifier所以不能讓其他帳號做呼叫

Time

現在我們來講時間,我們可以創造一個代表時間的modifier,我們建立一個新的modifier onlyWhileOpen,這個modifier可以檢查現在的時間是否有超過我們指定的時間,

這煞一個很常使用的做法,當我們在建立ICO的智能合約時它具有開啟時間通常這些類型的智能合約將會禁止投資者在合約開始前做貢獻,我們可以利用剛剛的addPerson()去模擬這樣的一個狀況,直到打開的時間過去,第一我們先建立一個state變數去儲存我們的打開時間

uint256 startTime;

我們可以儲存我們的startTime,這就是在solidity當中我們將時間戳紀錄的方式,事實上時間戳記所代表的是unix的時間。

現在我們可以設定我們的開始時間。

constructor() public {
    startTime = 1544668513;
}

在你看到這個文章時,時間一定已經過了所以你們可以利用這個網站,他可以產出unix的時間戳記,現在我們來建立一個modifier去檢查我的開始時間是否過了

modifier onlyWhileOpen() {
    require(block.timestamp >= startTime);
    _;
}

我來講解一下這個程式碼

  • 第一,我們宣告了一個modifier,就像我們前面講的一樣
  • 第二,我們需要一個狀況就像前面的飯粒一樣
  • 接者我們我們比較現在的時間,而呼叫現在時間的方式就用block.timestamp.這樣一來就會呼叫現在solidity的時間

現在我們可以增加我們的modifier到我們的addPerson(),試者跑跑看這段程式碼

如果未來要再跑這段程式碼記得要講時間更改歐,而完整的程式碼會長這樣

pragma solidity 0.5.1;

contract MyContract {
    uint256 public peopleCount = 0;
    mapping(uint => Person) public people;

    uint256 startTime;

    modifier onlyWhileOpen() {
        require(block.timestamp >= startTime);
        _;
    }

    struct Person {
        uint _id;
        string _firstName;
        string _lastName;
    }

    constructor() public {
        startTime = 1544668513; // Update this value
    }

    function addPerson(
        string memory _firstName,
        string memory _lastName
    )

        public
        onlyWhileOpen
    {
        people[peopleCount] = Person(peopleCount, _firstName, _lastName);
    }

    function incrementCount() internal {
        peopleCount += 1;
    }
}

Solidity教學
【範例 : onlyWhileOpen】
Solidity教學

我們先打開unix clock的網站,複製這段時間段並將這段時間加上40-50

Ex:上圖的時間為159244727246(現在時間),在這邊我將startTime設定為159244727400,這麼做的目的是因為要滿足我們設定的條件,當現在時間大於我們設定的時間才能執行。

Solidity教學

我們deploy後使用addperson跟count會發現失敗

因為我們的條件有設定只有當現在時間超過我們設定的時間才可以執行,因為159244727246 < 159244727400所以失敗

Solidity教學

現在時間過了已經到159244727404所以我們在執行一次

Solidity教學

條件滿足,可以成功執行

發佈留言