首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >合同本身能复制吗?[合同创建的通知参考(不能创建派生或相同合同的实例)]

合同本身能复制吗?[合同创建的通知参考(不能创建派生或相同合同的实例)]
EN

Ethereum用户
提问于 2016-10-04 00:24:19
回答 4查看 1.3K关注 0票数 4

我有一个契约,我希望能够创建一个相同合同的副本,然后让子项目能够从父协议中检索数据。当我试图编译以下内容时,这是我要做的内容的简化版本:

代码语言:javascript
复制
contract Example {

    uint256 num;
    address parent;

    function Example(uint256 _num, address _parent) {
        num = _num;
        parent = _parent;
    }

    function createChild() {
        uint256 childNum = num + 1;
        Example child = new Example(childNum, this);
    }

    function getNumber() constant returns (uint256) {
        return num;
    }

    function getParentNumber() constant returns (uint256) {
        Example e = Example(parent);
        return e.getNumber();
    }

}

可以理解的是,...the solidity编译器抱怨:

代码语言:javascript
复制
example.sol:15:25: Error: Circular reference for contract creation (cannot create instance of derived or same contract).
        Example child = new Example(childNum, this);

这与文档所说的发生的情况相匹配:http://solidity.readthedocs.io/en/develop/contracts.html#multiple-inheritance-and-linearization

所以我不能那样做是有道理的。但是,是否有一种(最好是干净的)方法来完成一项合同,用与其本身相同的代码创建一个契约,然后调用该契约上的方法并获取数据?

EN

回答 4

Ethereum用户

发布于 2016-10-04 21:39:51

(有5,000万美元的缺陷)是一个很好的例子,说明合同能够使用工厂创建自己的副本。

这是工厂的合同:

代码语言:javascript
复制
contract DAO_Creator {
    function createDAO(
        address _curator,
        uint _proposalDeposit,
        uint _minTokensToCreate,
        uint _closingTime
    ) returns (DAO _newDAO) {

        return new DAO(
            _curator,
            DAO_Creator(this),
            _proposalDeposit,
            _minTokensToCreate,
            _closingTime,
            msg.sender
        );
    }
}

下面是创建新的子DAOs的代码:

代码语言:javascript
复制
contract DAO is DAOInterface, Token, TokenCreation {

    ...
    function splitDAO(
        uint _proposalID,
        address _newCurator
    ) noEther onlyTokenholders returns (bool _success) {
        ...
        p.splitData[0].newDAO = createNewDAO(_newCurator);
        ...
    }

    ...
    function createNewDAO(address _newCurator) internal returns (DAO _newDAO) {
        NewCurator(_newCurator);
        return daoCreator.createDAO(_newCurator, 0, 0, now + splitExecutionPeriod);
    }
    ...
}

有一种方法可以通过父契约的splitDAO(...)方法将以太和令牌从父契约转移到子契约(这是DAO黑客利用的)。

您应该能够设计您的合同,以便在引用父合同的子合同中执行方法。

票数 4
EN

Ethereum用户

发布于 2018-05-16 03:00:47

我写了一篇关于如何在媒体上解决这个问题的文章。

https://medium.com/@kylebryant_28277/subverting-the-circular-reference-error-in-solidity-f7167bf9fdb

基本上,您需要创建两个新契约,一个创建您想要的类型的新契约,另一个创建该契约的抽象契约。我把这叫做制造商和供应商的合同。读一读:)!

代码语言:javascript
复制
pragma solidity ^0.4.17;

contract VotethComment {

    string public comment;
    string public nickname;
    address public author;
    address[] public votethComments;
    address votethCommentMaker;

    constructor(string _comment, string _nickname, address _author, address _votethCommentMaker) public {
        comment = _comment;
        nickname = _nickname;
        author = _author;
        votethCommentMaker = _votethCommentMaker;
    }

    function addComment(string _comment, string _nickname) public {
        VotethCommentSupplier votethCommentSupplier = VotethCommentSupplier(votethCommentMaker);
        votethComments.push(votethCommentSupplier.makeComment(_comment, _nickname, msg.sender));
    }
}

contract VotethCommentSupplier {
   function makeComment(string _comment, string _nickname, address _author) public returns(address);
}

contract VotethCommentMaker {
    function makeComment(string _comment, string _nickname, address _author) public returns(address) {
        return new VotethComment(_comment, _nickname, _author, this);
    }
}
票数 1
EN

Ethereum用户

发布于 2018-08-28 12:50:36

你可以做这样的事。

代码语言:javascript
复制
contract ObjectFactory{

    function createObject() returns(address){
        Object subObject = new Object();
        return subObject;
    }

}    
contract Object{
    function createSubObject(ObjectFactory factory) returns(address) {
        address objectAddress = factory.createObject();
        return ObjectAddress; 
    }
}

此代码将使对象契约创建类型为Object的子合同,ObjectAddress将返回新创建对象的地址。

请注意,可以将ObjectFactory factory视为正常地址。

票数 1
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/9000

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档