4

I grab the smart contract example code from Zeppelin-Solidity GitHub https://github.com/OpenZeppelin/zeppelin-solidity

I create and deploy the SimpleToken using EXACTLY the same code from the Zeppelin example on Remix (remix.ethereum.org). Deploy success and verify success in Rinkeby test network.

  • Token Name = TestMyToken
  • Token Symbol = TMT
  • Token Decimals = 18 Token
  • Contract Address = 0x6Ca65510ec3F91b591027EDc60ea119d0984844a

Next I use EXACTLY the same Crowdsale.sol from Zeppelin example to test and learn.

Enter the following to create the Crowdsale contract using Remix

1500,"0xbb3937D3cd7c391e373df560c94f73098499A4E2", "0x6Ca65510ec3F91b591027EDc60ea119d0984844a"

Deploy success and verify success in Rinkeby test network.

Crowdsales smart contract address: 0xf8D5ce2E1721c8e6914a623e6444ecA584119b41

  • I log into MyEtherWallet and choose Rinkeby (Etherscan.io) network
  • Click on the Contract
  • Paste the Crowdsales smart contract address
  • Paste the ABI code from the Crowdsales smart contract address
  • I can see the functions
  • Select buyTokenfunction
  • Enter 0.1 Ether to test buy
  • MetaMask show error "Transaction error. Exception thrown in contract code" also the Gas Limit showing EXTREMELY High 6,915,218

I do not know what have I done wrong.

  1. Why Gas limits is so high?
  2. What function cause the thrown?

Please help and advise.

enter image description here

Below is the Token Contract Code:(Exactly same as Zeppelin sample but removed comments line)

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

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

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

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

contract ERC20Basic {
    function totalSupply() public view returns (uint256);
    function balanceOf(address who) public view returns (uint256);
    function transfer(address to, uint256 value) public returns (bool);
    event Transfer(address indexed from, address indexed to, uint256 value);
}

contract ERC20 is ERC20Basic {
    function allowance(address owner, address spender) public view returns (uint256);
    function transferFrom(address from, address to, uint256 value) public returns (bool);
    function approve(address spender, uint256 value) public returns (bool);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

contract BasicToken is ERC20Basic {
    using SafeMath for uint256;
    mapping(address => uint256) balances;
    uint256 totalSupply_;

    function totalSupply() public view returns (uint256) {
       return totalSupply_;
    }

    function transfer(address _to, uint256 _value) public returns (bool) {
       require(_to != address(0));
       require(_value <= balances[msg.sender]);
       balances[msg.sender] = balances[msg.sender].sub(_value);
       balances[_to] = balances[_to].add(_value);
       Transfer(msg.sender, _to, _value);
       return true;
    }

    function balanceOf(address _owner) public view returns (uint256 balance) {
       return balances[_owner];
    }
}

contract StandardToken is ERC20, BasicToken {
    mapping (address => mapping (address => uint256)) internal allowed;
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
       require(_to != address(0));
       require(_value <= balances[_from]);
       require(_value <= allowed[_from][msg.sender]);
       balances[_from] = balances[_from].sub(_value);
       balances[_to] = balances[_to].add(_value);
       allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
       Transfer(_from, _to, _value);
       return true;
}

    function approve(address _spender, uint256 _value) public returns (bool) {
        allowed[msg.sender][_spender] = _value;
        Approval(msg.sender, _spender, _value);
        return true;
    }

    function allowance(address _owner, address _spender) public view returns (uint256) {
        return allowed[_owner][_spender];
    }

    function increaseApproval(address _spender, uint _addedValue) public returns (bool) {
        allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
        Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
        return true;
    }

    function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) {
       uint oldValue = allowed[msg.sender][_spender];
       if (_subtractedValue > oldValue) {
           allowed[msg.sender][_spender] = 0;
       } else {
           allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
       }
       Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
       return true;
    }
}

contract TestMyToken is StandardToken {
    string public constant name = "TestMyToken"; 
    string public constant symbol = "TMT";
    uint8 public constant decimals = 18;
    uint256 public constant INITIAL_SUPPLY = 1000000 * (10 ** uint256(decimals));

    function TestMyToken() public {
        totalSupply_ = INITIAL_SUPPLY;
        balances[msg.sender] = INITIAL_SUPPLY;
        Transfer(0x0, msg.sender, INITIAL_SUPPLY);
    }
}

Below is the Crowdsale Contract code: (Exactly same as Zeppelin sample but removed comments line)

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

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

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

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

contract ERC20Basic {
    function totalSupply() public view returns (uint256);
    function balanceOf(address who) public view returns (uint256);
    function transfer(address to, uint256 value) public returns (bool);
    event Transfer(address indexed from, address indexed to, uint256 value);
}

contract ERC20 is ERC20Basic {
    function allowance(address owner, address spender) public view returns (uint256);
    function transferFrom(address from, address to, uint256 value) public returns (bool);
    function approve(address spender, uint256 value) public returns (bool);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

contract Crowdsale {
    using SafeMath for uint256;
    ERC20 public token;
    address public wallet;
    uint256 public rate;
    uint256 public weiRaised;

    event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);

    function Crowdsale(uint256 _rate, address _wallet, ERC20 _token) public {
       require(_rate > 0);
       require(_wallet != address(0));
       require(_token != address(0));
       rate = _rate;
       wallet = _wallet;
       token = _token;
    }

    function () external payable {
       buyTokens(msg.sender);
    }

    function buyTokens(address _beneficiary) public payable {
       uint256 weiAmount = msg.value;
       _preValidatePurchase(_beneficiary, weiAmount);
       uint256 tokens = _getTokenAmount(weiAmount);
       weiRaised = weiRaised.add(weiAmount);
       _processPurchase(_beneficiary, tokens);
       TokenPurchase(msg.sender, _beneficiary, weiAmount, tokens);
       _updatePurchasingState(_beneficiary, weiAmount);
       _forwardFunds();
       _postValidatePurchase(_beneficiary, weiAmount);
    }

    function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal {
       require(_beneficiary != address(0));
       require(_weiAmount != 0);
    }

    function _postValidatePurchase(address _beneficiary, uint256 _weiAmount) internal {
       // optional override
    }

    function _deliverTokens(address _beneficiary, uint256 _tokenAmount) internal {
       token.transfer(_beneficiary, _tokenAmount);
    }

    function _processPurchase(address _beneficiary, uint256 _tokenAmount) internal {
       _deliverTokens(_beneficiary, _tokenAmount);
    }

    function _updatePurchasingState(address _beneficiary, uint256 _weiAmount) internal {
       // optional override
    }

    function _getTokenAmount(uint256 _weiAmount) internal view returns (uint256) {
       return _weiAmount.mul(rate);
    }

    function _forwardFunds() internal {
       wallet.transfer(msg.value);
    }
}
1

In buy function you are transferring calculated amount of tokens tokens from crowdsale contract to token beneficiary. But your crowdsale contract has no tokens on it's balance, so this call token.transfer(_beneficiary, _tokenAmount); in line 162 throws an error.

To get this work you should transfer appropriate amount of tokens to crowdsale contract to it so it would be able to send them to investors.

  • Yes, it works now after I follow your instruction to send some tokens to the Crowdsales smart contract. Thank you for your help. – David Evony Mar 22 '18 at 14:54
1

Other than transferring token to the Crowdsale contract, you can also use AllowanceCrowdsale at the first place. It keeps the tokens stay in your wallet, but you need to run a approve() from the wallet to contract first.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.