Solidity語言學習筆記————32、建立合約

FLy_鵬程萬里發表於2018-07-03

Solidity的合約類似於面嚮物件語言中的類。它們包含存放持久化資料的狀態變數和可修改這些變數的函式。呼叫不同的合約例項上的函式將執行EVM函式呼叫,從而切換上下文,使得狀態變數不可訪問。

建立合約(Creating Contracts)

合約可以從“外部”建立,也可以由Solidity合約創立。

Remix這類IDE,可以用UI介面使建立過程無縫連線。

最好在Ethereum上以程式設計方式通過Web3.js建立合約。到今天為止,它有一種叫做web3.eth.Contract的方法來幫助合約的建立。

當建立一個合約時,它的建構函式被執行一次。建構函式是可選的。只允許一個建構函式,這意味著不支援過載。

在內部,建構函式的引數要放在在合約程式碼編譯成的ABI之後,但是如果使用Web3.js,則不必關心這一點。

如果是一個合約要創立另外一個合約,被創立的合約的原始碼(和二進位制程式碼)要能被創立者知曉。這意味著迴圈建立依賴就成為不可能的事情。

pragma solidity ^0.4.16;

contract OwnedToken {
    // TokenCreator是在下面定義的合約型別
    // 若它本身不用於建立新的合約的話,它就是一個引用
    TokenCreator creator;
    address owner;
    bytes32 name;

    // 這個是記載建立者者和賦值名稱的建構函式
    function OwnedToken(bytes32 _name) {
        owner = msg.sender;
        // 我們做一次由`address`到`TokenCreator` 的顯式轉換,
        // 確保呼叫合約的型別是 TokenCreator,(因為沒有辦法來檢測這一點)
        creator = TokenCreator(msg.sender);
        name = _name;
    }

    function changeName(bytes32 newName) {
        // 僅僅是創立者可以改變名稱--
        // 因為合約是隱式轉換成地址上,所以這種比較是可能的
        if (msg.sender == creator) name = newName;
    }

    function transfer(address newOwner) {
        // 只有當前合約所有者可以轉移 token
        if (msg.sender != owner) return;
        // 我們還要詢問合約建立者"轉移是否成功"
        // 注意這會呼叫合約定義在下面的函式
        // 如果函式呼叫失敗,(如gas用完了等原因)
        // 程式的執行將立刻停止
        if (creator.isTokenTransferOK(owner, newOwner))
            owner = newOwner;
    }}

contract TokenCreator {
    function createToken(bytes32 name)
       returns (OwnedToken tokenAddress)
    {
        // 創立一個新的Token合約,並且返回它的地址
        // 從 JavaScript觀點看,返回的地址型別是"address"
        // 這個是和ABI最接近的型別
        return new OwnedToken(name);
    }

    function changeName(OwnedToken tokenAddress, bytes32 name) {
        // "tokenAddress" 的外部型別也是"address".
        tokenAddress.changeName(name);
    }

    function isTokenTransferOK(
        address currentOwner,
        address newOwner
    ) returns (bool ok) {
        // 檢查各種條件
        address tokenAddress = msg.sender;
        return (sha3(newOwner) & 0xff) == (bytes20(tokenAddress) & 0xff);
    }
}


相關文章