, ,

Solidity教學第五集_智能合約互動

Solidity教學

Solidity教學第五集_智能合約互動

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

上一篇章我們介紹了buyToken、fallback與Time。忘記的朋友可以回去多加複習。

這一集我們將會教你們如何在solidity當中使用多個智能合約。

智能合約間互相呼叫、MINT

首先我會教你們如何在不同的智能合約間互相呼叫,接下來會教你們繼承(inherit)行為,子智能合約如何繼承父智能合約。

第一我會先將我之前的程式碼重新建構,並創建另一個創造token的智能合約而這個智能合約則是從先前的MyContract分離出來的,這會是一個假的ERC20 token,裡面並不會包含真正ERC-20 智能合約內的所有功能。

現在我們來建立一個token 合約

contract ERC20Token {
    string name;
    mapping(address => uint256) public balances;

    function mint() public {
        balances[msg.sender] += 1;
    }
}

而讓我們來講解一下 mint()這個function是一個建造token的地方,而為什麼mint是製造token的function因為英文的mint也是製幣廠的意思。再來我們需要有一個name變數以及balances的mapping。接下來我們就可以mint我們的token並在MyContract裡面呼叫 ERC20Token這個智能合約,為了做到這件事我們需要在MyContract裡面建立一個address

contract MyContract {
    address public token;
    //…
}

現在我們可以在constructor中去設定我們的位置以及數值,可以將ERC20Token的參數只訂到我們的token當中

constructor(address payable _wallet, ERC20Token _token) public {
    wallet = _wallet;
    token = _token;
}

現在我們的address可以公開使用了,我們就可以在buyToken() 裡面呼叫 mint()

function buyToken() public payable {
    ERC20Token _token = ERC20Token(address(token));
    _token.mint();
    wallet.transfer(msg.value);
}

接下來要講一個比較特別需要注意的部分,如果你現在想要在自己的帳號內去mint token後並查詢balances你會發現沒辦法成功那是為啥呢?我們再來重新看一下我們的程式碼部分:

function mint() public {
    balances[msg.sender] += 1;
}

因為我們在function內寫的是從msg.sender,他是參照MyContract的地址的,那如果我們想要在自己的帳號裡面去mint token要怎麼做呢?我們需要將balances裡面的改成tx.origin

function mint() public {
    balances[tx.origin] += 1;
}

接下來就可以在其他的智能合約mint token拉!

pragma solidity 0.5.1;

contract ERC20Token {
    string name;
    mapping(address => uint256) public balances;

    function mint() public {
        balances[tx.origin] += 1;
    }
}

contract MyContract {
    address public token;
    address payable wallet;

    constructor(address payable _wallet, address _token) public {
        wallet = _wallet;
        token = _token;
    }

    function buyToken() public payable {
        ERC20Token _token = ERC20Token(address(token));
        _token.mint();
        wallet.transfer(msg.value);
    }
}

Solidity教學
先選擇ERC20 TOKEN
Solidity教學
點開下半部分
Solidity教學
接著複製裡面的contract address
Solidity教學
選到mycontract做deploy
Solidity教學
這邊帶入兩個參數
Solidity教學
第一個是account add,第二個則是剛剛的token add
Solidity教學
接著我們點擊buytoke後,在按下token就會看到我們的token add了
Solidity教學
並在ERC TOKEN裡面將地址貼上後並按下balances就會看到增加一了
Solidity教學
我們按mint也是得到同樣的效果歐

繼承、Inherit

接下來我們來講繼承,solidity允許我們繼承不同的contract接下來我們來建立一個MyToken,並繼承之前所寫的ERC20TOKEN的contract,這樣我們的子合約就能使用父合約的功能嘍

contract MyToken is ERC20Token {
    // …
}

接著我們將我們的ERC20TOKEN改寫

pragma solidity 0.5.1;

contract ERC20Token {
    string public name;
    mapping(address => uint256) public balances;
    constructor(string memory _name) public {
        name = _name;
    }

    function mint() public {
        balances[tx.origin] ++;
    }
}

我們可以在constructor中覆蓋父合約,接著我們必須建立子合約的符號以及名稱ERC20Token(_name)的作用就是使用了ERC20Token裡面的功能將token名稱設定

contract MyToken is ERC20Token {
    string public symbol;

    constructor(
        string memory _name,
        string memory _symbol
    )
        ERC20Token(_name)
    public {
        symbol = _symbol;
    }
}

接著我們來客製我們的MyToken,我們先來更新一下我們的mint()function,首先我們要建立用來儲存擁有者以及擁有者數量的變數

contract MyToken is ERC20Token {
    address[] public owners;
    uint256 public ownerCount;
    //…
}

接下來我們來更新我們的mint(),當我們要保持在父合約內行為時我們就會用到super這個方法,這樣當我們呼叫mint()時也會去呼叫到父合約的mint() function呼叫完後就會將擁有者加上1並將地址push進去owners變數當中

function mint() public {
    super.mint();
    ownerCount ++;
    owners.push(msg.sender);
}

這樣一來我們就成功建立我們的客製token拉!,並擁有繼承父合約的特性而現在整個合約應該會像這樣

pragma solidity 0.5.1;

contract ERC20Token {
    string public name;
    mapping(address => uint256) public balances;

    constructor(string memory _name) public {
        name = _name;
    }

    function mint() public {
        balances[tx.origin] ++;
    }
}

contract MyToken is ERC20Token {
    string public symbol;
    address[] public owners;
    uint256 public ownerCount;

    constructor(
        string memory _name,
        string memory _symbol
    )
        ERC20Token(_name)
    public {
        symbol = _symbol;
    }

    function mint() public {
        super.mint();
        ownerCount ++;
        owners.push(msg.sender);
    }
}

Solidity教學
選擇mytoken做deploy
Solidity教學
輸入token名稱以及他的symbol
Solidity教學
執行結果
Solidity教學
查詢balances
Solidity教學
token名稱
Solidity教學
現在擁有者的數量跟特定擁有者的地址
Solidity教學
最後是symbol

這些我們所看到的功能以及變數,有些都是繼承所得到的結果。


如果喜歡看更多與區塊鏈技術、應用、科技新知相關的內容,記得留下您的Email並追蹤我們的粉專,那麼新文章上線時,我們將在第一時間通知您,不用再擔心錯過最新消息。

台灣區塊鏈協會證照專班  (企業內訓、個人進修、就業輔導、活動邀約等)

CBA亞洲區塊鏈學院

亞洲區系統技術開發商  (智慧生產系統、網站建置、智能合約、區塊鏈技術等)

巴克夏夫科技股份有限公司