首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不能与Crowdsale合同交互

不能与Crowdsale合同交互
EN

Ethereum用户
提问于 2017-11-22 23:52:11
回答 1查看 239关注 0票数 1

我正在测试Crowdsale合同(C),它发送已经部署的合同(T)的令牌。这个想法是从T向C发送大量的令牌,然后将它们卖给以太,但是没有什么效果,C甚至没有收到以太。这是Crowdsale合同:

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

contract ForeignToken {
    function balanceOf(address _owner) constant returns (uint256);
    function transfer(address _to, uint256 _value) returns (bool);
}

library SafeMath {
  function mul(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a * b;
    assert(a == 0 || c / a == b);
    return c;
  }

  function div(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a / b;
    return c;
  }

  function sub(uint256 a, uint256 b) internal constant returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  function add(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
  }
}

contract Token { 
    function issue(address _recipient, uint256 _value) returns (bool success);
    function totalSupply() constant returns (uint256 supply);
    function unlock() returns (bool success);
}

contract TokenCrowdsale {

    using SafeMath for uint256;

    // Crowdsale details
    address public beneficiary;                     
    address public creator;                         
    address public confirmedBy;                     
    uint256 public maxSupply = 15000000e8;    
    uint256 public minAcceptedAmount = 10 finney;   
    bool public purchasingAllowed = false;


    // Eth to token rate
    uint256 public rate = 2000;

    enum Stages {
        PreSale,
        InProgress,
        Ended,
        Withdrawn
    }

    Stages public stage = Stages.PreSale;

    // deployed token
    Token public deplToken;

    // Invested balances
    mapping (address => uint256) balances;

    /**
    * Throw if at stage other than current stage
    * 
    * @param _stage expected stage to test for
    */
    modifier atStage(Stages _stage) {
        require(stage == _stage);
        _;
    }

    /**
    * Throw if sender is not beneficiary
    */
    modifier onlyBeneficiary() {
        require(beneficiary == msg.sender);
        _;
    }

    /** 
    * Get balance of `_investor` 
    * 
    * @param _investor The address from which the balance will be retrieved
    * @return The balance
    */
    function balanceOf(address _investor) constant returns (uint256 balance) {
        return balances[_investor];
    }


    function enablePurchasing() onlyBeneficiary atStage(Stages.PreSale) {
        purchasingAllowed = true;
        stage = Stages.InProgress;
    }

    function disablePurchasing() onlyBeneficiary atStage(Stages.InProgress) {
        purchasingAllowed = false;
        stage = Stages.Ended;
    }

    function enableNewPurchasing() onlyBeneficiary atStage(Stages.Withdrawn) {
        purchasingAllowed = true;
        stage = Stages.InProgress;
    }

    /**
    * Constructor
    *
    * @param _tokenAddress The address of the token contact
    * @param _beneficiary  The address of the wallet for the beneficiary  
    * @param _creator      The address of the wallet for the creator 
    */
    function TokenCrowdsale(address _tokenAddress, address _beneficiary, address _creator) {
        deplToken = Token(_tokenAddress);
        beneficiary = _beneficiary;
        creator = _creator;
    }

    /**
    * For testing purposes
    *
    * @return The beneficiary address
    */
    function confirmBeneficiary() onlyBeneficiary {
        confirmedBy = msg.sender;
    }


    /**
    * Transfer raised amount to the beneficiary address
    */
    function withdraw() onlyBeneficiary atStage(Stages.Ended) {
        uint256 ethBalance = this.balance;
        beneficiary.transfer(ethBalance);
        stage = Stages.Withdrawn;
    }

    /**
    * Receives Eth and issue tokens to the sender
    */
    function () payable atStage(Stages.InProgress) {

        require(purchasingAllowed);

        address investor = msg.sender;
        uint256 received = (msg.value).div(10e8);

        // Enforce min amount
        require(received >= minAcceptedAmount);
        uint256 tokens = (received).mul(rate);

        require(tokens > 0);

        require(deplToken.issue(investor, tokens));

        balances[investor] = balances[investor].add(received);
        //raised += received;

        // Check totalSupply raised
        if (deplToken.totalSupply() >= maxSupply) {
            stage = Stages.Ended;
        }
    }

    function withdrawForeignTokens(address _tokenContract) onlyBeneficiary public returns (bool) {
        ForeignToken token = ForeignToken(_tokenContract);
        uint256 amount = token.balanceOf(address(this));
        return token.transfer(beneficiary, amount);
    }
}

任何帮助都很感谢,谢谢。

编辑:根据注释中的建议,我成功地收到了Crowdsale合同上的ETH,但它没有发出令牌。下面是代码:

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

contract ForeignToken {
    function balanceOf(address _owner) constant returns (uint256);
    function transfer(address _to, uint256 _value) returns (bool);
}

library SafeMath {
  function mul(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a * b;
    assert(a == 0 || c / a == b);
    return c;
  }

  function div(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a / b;
    return c;
  }

  function sub(uint256 a, uint256 b) internal constant returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  function add(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
  }
}

contract Token { 
    function issue(address _recipient, uint256 _value) returns (bool success);
    function totalSupply() constant returns (uint256 supply);
    function unlock() returns (bool success);
}

contract TokenCrowdsale {

    using SafeMath for uint256;

    // Crowdsale details
    address public beneficiary;                     
    address public creator;                         
    address public confirmedBy;                     
    uint256 public maxSupply = 15000000e8;    
    uint256 public minAcceptedAmount = 10 finney;
    bool public purchasingAllowed = false;
    uint256 public totalSupply = 0;

    // Eth to token rate
    uint256 public rate = 2000;

    enum Stages {
        PreSale,
        InProgress,
        Ended,
        Withdrawn
    }

    Stages public stage = Stages.PreSale;

    // deployed token
    Token public deplToken;

    // Invested balances
    mapping (address => uint256) balances;

    /**
    * Throw if at stage other than current stage
    * 
    * @param _stage expected stage to test for
    */
    modifier atStage(Stages _stage) {
        require(stage == _stage);
        _;
    }

    /**
    * Throw if sender is not beneficiary
    */
    modifier onlyBeneficiary() {
        require(beneficiary == msg.sender);
        _;
    }

    /** 
    * Get balance of `_investor` 
    * 
    * @param _investor The address from which the balance will be retrieved
    * @return The balance
    */
    function balanceOf(address _investor) constant returns (uint256 balance) {
        return balances[_investor];
    }


    function enablePurchasing() onlyBeneficiary atStage(Stages.PreSale) {
        purchasingAllowed = true;
        stage = Stages.InProgress;
    }

    function disablePurchasing() onlyBeneficiary atStage(Stages.InProgress) {
        purchasingAllowed = false;
        stage = Stages.Ended;
    }

    function enableNewPurchasing() onlyBeneficiary atStage(Stages.Withdrawn) {
        purchasingAllowed = true;
        stage = Stages.InProgress;
    }

    /**
    * Constructor
    *
    * @param _tokenAddress The address of the token contact
    * @param _beneficiary  The address of the wallet for the beneficiary  
    * @param _creator      The address of the wallet for the creator 
    */
    function TokenCrowdsale(address _tokenAddress, address _beneficiary, address _creator) {
        deplToken = Token(_tokenAddress);
        beneficiary = _beneficiary;
        creator = _creator;
    }

    /**
    * For testing purposes
    *
    * @return The beneficiary address
    */
    function confirmBeneficiary() onlyBeneficiary {
        confirmedBy = msg.sender;
    }


    /**
    * Transfer raised amount to the beneficiary address
    */
    function withdraw() onlyBeneficiary atStage(Stages.Ended) {
        uint256 ethBalance = this.balance;
        beneficiary.transfer(ethBalance);
        stage = Stages.Withdrawn;
    }

    /**
    * Receives Eth and issue tokens to the sender
    */
    function () payable atStage(Stages.InProgress) {
        require(purchasingAllowed);

        if (msg.value >= 10 finney) {
            address investor = msg.sender;
            uint256 received = (msg.value).div(10e8);
            uint256 tokens = (received).mul(rate);
            balances[investor] = balances[investor].add(tokens);
            totalSupply = (totalSupply).add(tokens);
        }

        if (totalSupply >= maxSupply) {
            purchasingAllowed = false;
            stage = Stages.Ended;
        }

    }

    function withdrawForeignTokens(address _tokenContract) onlyBeneficiary public returns (bool) {
        ForeignToken token = ForeignToken(_tokenContract);
        uint256 amount = token.balanceOf(address(this));
        return token.transfer(beneficiary, amount);
    }
}

如您所见,我用"if“迭代更改了回退函数中的"require”。

EN

回答 1

Ethereum用户

回答已采纳

发布于 2017-11-23 22:40:22

遵循这些建议,做更多的研究,我找到了解决办法。首先,我改变了

代码语言:javascript
复制
contract Token {}

代码语言:javascript
复制
interface Token {}

我还添加了一个事件,然后由fallback函数调用该事件来发送令牌:

代码语言:javascript
复制
event sendTokens(address indexed to, uint256 value);

最后,我清理了未使用变量的代码,并添加了一些与我的问题无关的其他函数,但是对于管理众包很有用。下面是最后的工作代码:

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

contract ForeignToken {
    function balanceOf(address _owner) constant returns (uint256);
    function transfer(address _to, uint256 _value) returns (bool);
}

library SafeMath {
  function mul(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a * b;
    assert(a == 0 || c / a == b);
    return c;
  }

  function div(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a / b;
    return c;
  }

  function sub(uint256 a, uint256 b) internal constant returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  function add(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
  }
}

interface Token { 
    function transfer(address _to, uint256 _value) returns (bool);
    function totalSupply() constant returns (uint256 supply);
    function balanceOf(address _owner) constant returns (uint256 balance);
}

contract TokenCrowdsale {

    using SafeMath for uint256;

    // Crowdsale details
    address public beneficiary;                     
    address public creator;                         
    address public confirmedBy;                     
    uint256 public maxSupply = 15000000e8;    
    bool public purchasingAllowed = false;
    uint256 public totalSupplied = 0;

    // Eth to token rate
    uint256 public rate = 2000;

    enum Stages {
        PreSale, //0
        InProgress, //1
        Ended, //2 
        Withdrawn //3
    }

    Stages public stage = Stages.PreSale;

    // deployed token
    Token public deplToken;

    // Invested balances
    mapping (address => uint256) balances;

    /**
    * Throw if at stage other than current stage
    * 
    * @param _stage expected stage to test for
    */
    modifier atStage(Stages _stage) {
        require(stage == _stage);
        _;
    }

    /**
    * Throw if sender is not beneficiary
    */
    modifier onlyBeneficiary() {
        require(beneficiary == msg.sender);
        _;
    }

    /** 
    * Get balance of `_investor` 
    * 
    * @param _investor The address from which the balance will be retrieved
    * @return The balance
    */
    function balanceOf(address _investor) constant returns (uint256 balance) {
        return balances[_investor];
    }


    function enablePurchasing() onlyBeneficiary atStage(Stages.PreSale) {
        purchasingAllowed = true;
        stage = Stages.InProgress;
    }

    function disablePurchasing() onlyBeneficiary atStage(Stages.InProgress) {
        purchasingAllowed = false;
        stage = Stages.Ended;
    }

    function enableNewPurchasing() onlyBeneficiary atStage(Stages.Withdrawn) {
        purchasingAllowed = true;
        stage = Stages.InProgress;
    }

    /**
    * Constructor
    *
    * @param _tokenAddress The address of the token contact
    * @param _beneficiary  The address of the wallet for the beneficiary  
    * @param _creator      The address of the wallet for the creator 
    */
    function TokenCrowdsale(address _tokenAddress, address _beneficiary, address _creator) {
        deplToken = Token(_tokenAddress);
        beneficiary = _beneficiary;
        creator = _creator;
    }

    /**
    * For testing purposes
    *
    * @return The beneficiary address
    */
    function confirmBeneficiary() onlyBeneficiary {
        confirmedBy = msg.sender;
    }


    event sendTokens(address indexed to, uint256 value);


    /**
    * Transfer raised amount to the beneficiary address
    */
    function withdraw() onlyBeneficiary atStage(Stages.Ended) {
        uint256 ethBalance = this.balance;
        beneficiary.transfer(ethBalance);
        stage = Stages.Withdrawn;
    }

    /**
    * Receives Eth and issue tokens to the sender
    */
    function () payable atStage(Stages.InProgress) {

        require(purchasingAllowed);
        if (msg.value == 0) { return; }
        uint256 weiAmount = msg.value;
        address investor = msg.sender;
        uint256 received = weiAmount.div(10e7);
        uint256 tokens = (received).mul(rate);

        if (msg.value >= 10 finney) {
            uint256 bonusToken = (tokens.div(100)).mul(20);
            tokens = tokens.add(bonusToken);
        }

        sendTokens(msg.sender, tokens);
        deplToken.transfer(investor, tokens);
        totalSupplied = (totalSupplied).add(tokens);

        if (totalSupplied >= maxSupply) {
            purchasingAllowed = false;
            stage = Stages.Ended;
        }

    }


    function tokensAvailable() constant returns (uint256) {
        return deplToken.balanceOf(this);
    }


    function withdrawForeignTokens(address _tokenContract) onlyBeneficiary public returns (bool) {
        ForeignToken token = ForeignToken(_tokenContract);
        uint256 amount = token.balanceOf(address(this));
        return token.transfer(beneficiary, amount);
    }
}

我不确定“接口令牌”或“事件sendTokens”是否是解决方案,但它现在正在工作;我可以发送以太并接收已部署的令牌。我已经回答了我自己的问题,所以如果其他人需要这样的东西,它将留在这里作为解决方案。谢谢

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

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

复制
相关文章

相似问题

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