創(chuàng)建合約

2022-05-16 10:44 更新

合約可以通過以太坊交易“從外部”創(chuàng)建,也可以從 Solidity 合約內(nèi)部創(chuàng)建。

IDE,例如Remix,使用 UI 元素使創(chuàng)建過程無縫。

在以太坊上以編程方式創(chuàng)建合約的一種方法是通過 JavaScript API web3.js。它有一個(gè)名為web3.eth.Contract的函數(shù) 來促進(jìn)合約的創(chuàng)建。

當(dāng)一個(gè)合約被創(chuàng)建時(shí),它的構(gòu)造函數(shù)(一個(gè)用constructor關(guān)鍵字聲明的函數(shù))被執(zhí)行一次。

構(gòu)造函數(shù)是可選的。只允許一個(gè)構(gòu)造函數(shù),這意味著不支持重載。

構(gòu)造函數(shù)執(zhí)行后,合約的最終代碼存儲(chǔ)在區(qū)塊鏈上。此代碼包括所有公共和外部函數(shù)以及可通過函數(shù)調(diào)用從那里訪問的所有函數(shù)。部署的代碼不包括構(gòu)造函數(shù)代碼或僅從構(gòu)造函數(shù)調(diào)用的內(nèi)部函數(shù)。

在內(nèi)部,構(gòu)造函數(shù)參數(shù)在合約本身的代碼之后通過ABI 編碼傳遞,但如果您使用web3.js.

如果一個(gè)合約想要?jiǎng)?chuàng)建另一個(gè)合約,創(chuàng)建者必須知道創(chuàng)建的合約的源代碼(和二進(jìn)制文件)。這意味著循環(huán)創(chuàng)建依賴是不可能的。

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


contract OwnedToken {
    // `TokenCreator` is a contract type that is defined below.
    // It is fine to reference it as long as it is not used
    // to create a new contract.
    TokenCreator creator;
    address owner;
    bytes32 name;

    // This is the constructor which registers the
    // creator and the assigned name.
    constructor(bytes32 name_) {
        // State variables are accessed via their name
        // and not via e.g. `this.owner`. Functions can
        // be accessed directly or through `this.f`,
        // but the latter provides an external view
        // to the function. Especially in the constructor,
        // you should not access functions externally,
        // because the function does not exist yet.
        // See the next section for details.
        owner = msg.sender;

        // We perform an explicit type conversion from `address`
        // to `TokenCreator` and assume that the type of
        // the calling contract is `TokenCreator`, there is
        // no real way to verify that.
        // This does not create a new contract.
        creator = TokenCreator(msg.sender);
        name = name_;
    }

    function changeName(bytes32 newName) public {
        // Only the creator can alter the name.
        // We compare the contract based on its
        // address which can be retrieved by
        // explicit conversion to address.
        if (msg.sender == address(creator))
            name = newName;
    }

    function transfer(address newOwner) public {
        // Only the current owner can transfer the token.
        if (msg.sender != owner) return;

        // We ask the creator contract if the transfer
        // should proceed by using a function of the
        // `TokenCreator` contract defined below. If
        // the call fails (e.g. due to out-of-gas),
        // the execution also fails here.
        if (creator.isTokenTransferOK(owner, newOwner))
            owner = newOwner;
    }
}


contract TokenCreator {
    function createToken(bytes32 name)
        public
        returns (OwnedToken tokenAddress)
    {
        // Create a new `Token` contract and return its address.
        // From the JavaScript side, the return type
        // of this function is `address`, as this is
        // the closest type available in the ABI.
        return new OwnedToken(name);
    }

    function changeName(OwnedToken tokenAddress, bytes32 name) public {
        // Again, the external type of `tokenAddress` is
        // simply `address`.
        tokenAddress.changeName(name);
    }

    // Perform checks to determine if transferring a token to the
    // `OwnedToken` contract should proceed
    function isTokenTransferOK(address currentOwner, address newOwner)
        public
        pure
        returns (bool ok)
    {
        // Check an arbitrary condition to see if transfer should proceed
        return keccak256(abi.encodePacked(currentOwner, newOwner))[0] == 0x7f;
    }
}


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)