區塊鏈研究實驗室 | 智慧合約如何建立和繼承

買賣虛擬貨幣

在上一篇文章中(傳送門:區塊鏈研究實驗室 | 手把手教你使用Solidity開發智慧合約(五)),我們瞭解瞭如何使用函式,並應用了到目前為止所學到的一切來構建一個多功能簽名錢包。

在本文中,我們將看到如何從另一個合同中建立一個合同,以及如何定義抽象合同和介面。

合同建立

可以透過以太坊交易或在Solidity合約中使用new關鍵字建立合約,該關鍵字將部署該合約的新例項並返回其地址。

透過檢查Solidity文件中給出的示例,讓我們仔細看一下它是如何工作的。我建立了name變數,public以便我們可以檢查其值並建立一個事件以讀取該createToken函式的返回值(我們將在事件的另一篇文章中介紹):

    // SPDX-License-Identifier: GPL-3.0pragma solidity >=0.4.22 <0.8.0;

    contract OwnedToken { TokenCreator creator; address owner; bytes32 public name;constructor(bytes32 _name) { owner = msg.sender; creator = TokenCreator(msg.sender); name = _name; }
    functionchangeName(bytes32 newName) public{if (msg.sender == address(creator)) name = newName; }
    functiontransfer(address newOwner) public{if (msg.sender != owner) return;
    if (creator.isTokenTransferOK(owner, newOwner)) owner = newOwner; }}

    contract TokenCreator { event TokenCreated(bytes32 name, address tokenAddress);
    functioncreateToken(bytes32 name)publicreturns (OwnedToken tokenAddress){ tokenAddress = new OwnedToken(name); emit TokenCreated(name, address(tokenAddress)); }
    functionchangeName(OwnedToken tokenAddress, bytes32 name) public{
    tokenAddress.changeName(name); }
    functionisTokenTransferOK(address currentOwner, address newOwner)publicpurereturns (bool ok){
    return keccak256(abi.encodePacked(currentOwner, newOwner))[0] == 0x7f; }}

    這次,我將使用Tuffle框架——您可以按照他們製作的快速入門指南對其進行學習。

    首先,我們將建立一個新專案並透過執行以下命令對其進行初始化:

      > mkdir token>cd token> truffle init

      開啟專案,然後更新truffle-config.js檔案以使用您將在其中部署合同的網路IP和埠以及您正在使用的Solidity編譯器的版本。就我而言,我正在使用Ganache執行網路。

      現在,我們可以在contracts資料夾中建立合同。複製並貼上程式碼後,您需要在migrations資料夾中建立一個遷移檔案以部署TokenCreator合同。將其命名為2_deploy_token.js,然後複製並貼上以下程式碼。

        const TokenCreator = artifacts.require("TokenCreator");module.exports = function (deployer) { deployer.deploy(TokenCreator);};

        現在返回命令列,然後鍵入truffle console以啟動Truffle控制檯-您可以在其中編譯和部署合同:

        我們現在要做的是檢索TokenCreator已部署例項的例項。然後,我們將呼叫該createToken函式兩次,並儲存每個新建立合約的地址。

        如果使用的是Ganache,則可以看到兩個代表合同呼叫的交易新增到了交易列表中,其中資料欄位設定為函式選擇器的四個位元組,並傳遞了引數。如果您想知道真正發生了什麼以及如何建立這些合同,請繼續關注我。

        正如我們所知,合同只是另一種型別的帳戶,那麼到底發生了什麼,當我們所謂的createToken功能狀態資料庫進行了更新,包括與四個變數,每個帳戶儲存(新建立的帳戶nonce,balance,storage_root,code_hash)正確初始化。

        如果現在返回到Truffle控制檯,則可以檢查每個事務的日誌以獲取每個合同的地址,然後可以呼叫名稱getter來驗證它們確實是兩個單獨的實體。

        建設者宣言

        合同的建構函式在建立合同時被呼叫,並且不會與其餘的合同程式碼一起儲存在區塊鏈上。
        建構函式是可選的。只允許一個建構函式,這意味著不支援過載。

        使用constructor關鍵字宣告建構函式:

          contractA {uinta;boolb;constructor(uint_a, bool _b){a = _a;b = _b;}...}

          抽象合約

          需要將合同標記為abstract未執行其至少一項功能時。abstract即使實現了所有功能,合同也可能被標記為。

          這可以使用abstract合同的關鍵字來完成,未實現的功能應具有virtual允許多型的關鍵字。

            abstract contract A {function f() public pure virtual;}

            即使所有功能都已實現,抽象協定也無法直接例項化。它們可以用作定義其他合同繼承的特定行為的基本合同。已實現的功能應具有override關鍵字。

              abstract contract A {function f() public pure virtual;}abstract contract B is A {function f() public pure override {//function body }}

              如果派生合同未實現所有未實現的功能,則也需要對其進行標記abstract。

              介面

              介面類似於抽象協定,但是不能實現任何功能。還有其他限制:

              • 它們不能從其他合同繼承,但是可以從其他介面繼承

              • 所有宣告的函式必須是外部的

              • 他們不能宣告建構函式

              • 他們不能宣告狀態變數

              介面使用interface關鍵字宣告。

                interfaceA{functionf()externalpure;}

                介面中宣告的所有函式都是隱式的virtual。

                結論

                至此,我們對智慧合約的建立與繼承講完了。下次,我們將研究工廠模式以及如何在Solidity中使用它們。

                作者:鏈三豐,來源:區塊鏈研究實驗室

                免責聲明:

                1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
                2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
                3. 鏈報僅提供相關項目信息,不構成任何投資建議

                推荐阅读

                ;