合同部署正在引发gas问题,而交易和发行在各种网络上有所不同



我刚刚为我的代币众筹编写了一个基于 ERC20 的合约,并在不同的网络上进行了测试,如 rinkeby、ropsten 甚至 testrpc。

当我在testrpc上编译我的代码时,它工作正常。当我在 rinkeby 上编译和部署我的合约时,它给了我错误,即在进行交易时超过 Gas 限制并且交易失败。当我在ropsten上编译和部署y合约时,它不会给我任何gas错误,但它需要非常低的gas来进行交易"31000 gas",之后它也使交易失败。

请指导我错在哪里,以及最好的解决方案是什么。

代币代码 :

 pragma solidity 0.4.17;
import "./MintableToken.sol";
import "./UpgradeableToken.sol";
/**
 *  Ethereum token.
 */
contract MyToken is MintableToken, UpgradeableToken {
  string public name = "Token";
  string public symbol = "TKN";
  uint256 public decimals = 8;
  uint256 public constant INITIAL_SUPPLY = 300000000 * (10**8);
  // supply upgrade owner as the contract creation account
  function MyToken() UpgradeableToken(msg.sender) {
    totalSupply = INITIAL_SUPPLY;
    balances[msg.sender] = INITIAL_SUPPLY;
  }
}

众筹合同 :

pragma solidity 0.4.17;
import './MyToken.sol';
import './math/SafeMath.sol';
import './Haltable.sol';
import './ownership/Ownable.sol';
/**
 * @title Crowdsale
 *  crowdsale contract based on Open Zeppelin and TokenMarket
 * This crowdsale is modified to have a presale time period
 * A whitelist function is added to allow discounts. There are
 * three tiers of tokens purchased per wei based on msg value.
 * A finalization function can be called by the owner to issue 
 * token reserves, close minting, and transfer token ownership 
 * away from the crowdsale and back to the owner.
 */
contract Crowdsale is Ownable, Haltable {
  using SafeMath for uint256;
  // The token being sold
  JobGoToken public token;
  // presale, start and end timestamps where investments are allowed
  uint256 public presaleStartTime;
  uint256 public startTime;
  uint256 public endTime;
  // How many distinct addresses have purchased
  uint public purchaserCount = 0;
  // address where funds are collected
  address public wallet;
  // how many token units a buyer gets per ether
  uint256 public baseRate = 2000;
  // how many token units a buyer gets per ether with tier 2 5% discount
  uint256 public tierTwoRate = 2100;
  // how many token units a buyer gets per ether with tier 3 10% discount
  uint256 public tierThreeRate = 2200;
  // how many token units a buyer gets per ether with a whitelisted 15% discount
  uint256 public whitelistRate = 2300;
  // the minimimum presale purchase amount in ether
  uint256 public tierOnePurchase = 75 * 10**8;
  // the second tier discount presale purchase amount in ether
  uint256 public tierTwoPurchase = 150 * 10**8;
  // the second tier discount presale purchase amount in ether
  uint256 public tierThreePurchase = 300 * 10**8;
  // amount of raised money in wei
  uint256 public weiRaised;
  // Total amount to be sold in ether
  uint256 public cap = 80000 * 10**18;
  // Total amount to be sold in the presale in. cap/2
  uint256 public presaleCap = 80000 * 10**18;
  // Is the contract finalized
  bool public isFinalized = false;
  // How much ETH each address has invested to this crowdsale
  mapping (address => uint256) public purchasedAmountOf;
  // How many tokens this crowdsale has credited for each investor address
  mapping (address => uint256) public tokenAmountOf;
  // Addresses of whitelisted presale investors.
  mapping (address => bool) public whitelist;
  /**
   * event for token purchase logging
   * @param purchaser who paid for the tokens
   * @param beneficiary who got the tokens
   * @param value weis paid for purchase
   * @param amount amount of tokens purchased
   */ 
  event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);
  // Address early participation whitelist status changed
  event Whitelisted(address addr, bool status);
  // Crowdsale end time has been changed
  event EndsAtChanged(uint newEndsAt);
  event Finalized();
  function Crowdsale(uint256 _presaleStartTime, uint256 _startTime, uint256 _endTime, address _wallet, address _token) {
    require(_startTime >= now);
    require(_presaleStartTime >= now && _presaleStartTime < _startTime);
    require(_endTime >= _startTime);
    require(_wallet != 0x0);
    require(_token != 0x0);
    token = MyToken(_token);
    wallet = _wallet;
    presaleStartTime = _presaleStartTime;
    startTime = _startTime;
    endTime = _endTime;
  }
  // fallback function can't accept ether
  function () {
   throw;
  }
  // default buy function
  function buy() public payable {
    buyTokens(msg.sender);
  }
  // low level token purchase function
  // owner may halt payments here
  function buyTokens(address beneficiary) stopInEmergency payable {
    require(beneficiary != 0x0);
    require(msg.value != 0);
    if(isPresale()) {
      require(validPrePurchase());
      buyPresale(beneficiary);
    } else {
      require(validPurchase());
      buySale(beneficiary);
    }
  }
  function buyPresale(address beneficiary) internal {
    uint256 weiAmount = msg.value;
    uint256 tokens = 0;
    // calculate discount
    if(whitelist[msg.sender]) {
      tokens = weiAmount.mul(whitelistRate);
    } else if(weiAmount < tierTwoPurchase) {
      // Not whitelisted so they must have sent over 75 ether 
      tokens = weiAmount.mul(baseRate);
    } else if(weiAmount < tierThreePurchase) {
      // Over 150 ether was sent
      tokens = weiAmount.mul(tierTwoRate);
    } else {
      // Over 300 ether was sent
      tokens = weiAmount.mul(tierThreeRate);
    }
    // update state
    weiRaised = weiRaised.add(weiAmount);
    // Update purchaser
    if(purchasedAmountOf[msg.sender] == 0) {
    purchaserCount++;
    }
    purchasedAmountOf[msg.sender] = purchasedAmountOf[msg.sender].add(msg.value);
    tokenAmountOf[msg.sender] = tokenAmountOf[msg.sender].add(tokens);
    token.mint(beneficiary, tokens);
    TokenPurchase(msg.sender, beneficiary, weiAmount, tokens);
    forwardFunds();
  }
  function buySale(address beneficiary) internal {
    uint256 weiAmount = msg.value;
    // calculate token amount to be created
    uint256 tokens = weiAmount.mul(baseRate);
    // update state
    weiRaised = weiRaised.add(weiAmount);
    // Update purchaser
    if(purchasedAmountOf[msg.sender] == 0) { 
      purchaserCount++;
    }
    purchasedAmountOf[msg.sender] = purchasedAmountOf[msg.sender].add(msg.value);
    tokenAmountOf[msg.sender] = tokenAmountOf[msg.sender].add(tokens);
    token.mint(beneficiary, tokens);
    TokenPurchase(msg.sender, beneficiary, weiAmount, tokens);
    forwardFunds();
  }
  /**
   * @dev Must be called after crowdsale ends, to do some extra finalization
   * work. Calls the contract's finalization function.
   */
  function finalize() onlyOwner {
    require(!isFinalized);
    require(hasEnded());
    finalization();
    Finalized();
    isFinalized = true;
  }
  /**
   * @dev Finalization logic. We take the expected sale cap of 80000 
   * ether and find the difference from the actual minted tokens.
   * The remaining balance and 40% of total supply are minted 
   * to the Token team multisig wallet.
   */
  function finalization() internal {
    // calculate token amount to be created
    // expected tokens sold
    uint256 piTokens =  300000000 * (10**8);
    // get the difference of sold and expected
    uint256 tokens = piTokens.sub(token.totalSupply());
    // issue tokens to the multisig wallet
    token.mint(wallet, tokens);
    token.finishMinting();
    token.transferOwnership(msg.sender);
    token.releaseTokenTransfer();
  }
  // send ether to the fund collection wallet
  // override to create custom fund forwarding mechanisms
  function forwardFunds() internal {
    wallet.transfer(msg.value);
  }
  // Allow the owner to update the presale whitelist
  function updateWhitelist(address _purchaser, bool _listed) onlyOwner {
    whitelist[_purchaser] = _listed;
    Whitelisted(_purchaser, _listed);
  }
  /**
   * Allow crowdsale owner to close early or extend the crowdsale.
   *
   * This is useful e.g. for a manual soft cap implementation:
   * - after X amount is reached determine manual closing
   *
   * This may put the crowdsale to an invalid state,
   * but we trust owners know what they are doing.
   *
   */
  function setEndsAt(uint time) onlyOwner {
    require(now < time);
    endTime = time;
    EndsAtChanged(endTime);
  }

  // @return true if the presale transaction can buy tokens
  function validPrePurchase() internal constant returns (bool) {
    // this asserts that the value is at least the lowest tier 
    // or the address has been whitelisted to purchase with less
    bool canPrePurchase = tierOnePurchase <= msg.value || whitelist[msg.sender];
    bool withinCap = weiRaised.add(msg.value) <= presaleCap;
    return canPrePurchase && withinCap;
  }
  // @return true if the transaction can buy tokens
  function validPurchase() internal constant returns (bool) {
    bool withinPeriod = now >= startTime && now <= endTime;
    bool withinCap = weiRaised.add(msg.value) <= cap;
    return withinPeriod && withinCap;
  }
  // @return true if crowdsale event has ended
  function hasEnded() public constant returns (bool) {
    bool capReached = weiRaised >= cap;
    return now > endTime || capReached;
  }
  // @return true if within presale time
  function isPresale() public constant returns (bool) {
    bool withinPresale = now >= presaleStartTime && now < startTime;
    return withinPresale;
  }
}

02_deploy_migrations:

var Token = artifacts.require('../contracts/MyToken.sol');
var Crowdsale = artifacts.require('../contracts/Crowdsale.sol');
module.exports = function(deployer) {
    Token.new().then(function(res) {
        deployer.deploy(Crowdsale, 1508861000, 1510402100, 1510402200, "0x9ff03cbbb57e6bc5ecfac92ce54b1fc58d6e7269", res.address);
        console.log("Token Address : " + res.address);
    });
}

开始时间不能是过去。

new Date(1508861000)
//Sun Jan 18 1970 12:07:41 GMT+0100 (Romance Standard Time)
new Date(1508861000000)
//Tue Oct 24 2017 18:03:20 GMT+0200 (Romance Daylight Time)

最新更新