El constructor del contrato zeppelinSales esperaba 3 argumentos, recibió 0

Estoy tratando de implementar un contrato de Crowdsale, pero cuando hago "truffle migrate --network ropsten" obtengo estos errores:

Running migration: 1_initial_migration.js Deploying Migrations... ... 0xf8166f59ad6440ba56504956e5c54f7af17a30d6a6c64af6dd142808084e674d Migrations: 0x2be64f6a5ccb337d6106b343574eaa6a60b3f75d Saving successful migration to network... ... 0x6626bb628643554f06569c1a7b970b6d096242104b3ce711b69aff411530ab07 Saving artifacts... Running migration: 2_deploy_contracts.js Deploying zeppelinSales... Error encountered, bailing . Estado de la red desconocido. Revise las transacciones exitosas manualmente. Error: el constructor del contrato zeppelinSales esperaba 3 argumentos, recibió 0 en /usr/local/lib/node_modules/truffle/build/webpack:/packages/truffle-contract/contract.js:390:1 en new Promise () en /usr/ local/lib/node_modules/truffle/build/webpack:/packages/truffle-contract/contract.js:374:1 at at process._tickCallback (internal/process/next_tick.js:188:7)

Aquí está mi zeppelinSales.sol:

pragma solidity ^0.4.24;
import "zeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "zeppelin-solidity/contracts/math/SafeMath.sol";
import "zeppelin-solidity/contracts/token/ERC20/SafeERC20.sol";


/**
 * @title Crowdsale
 * @dev Crowdsale is a base contract for managing a token crowdsale,
 * allowing investors to purchase tokens with ether. This contract     implements
 * such functionality in its most fundamental form and can be extended to provide additional
 * functionality and/or custom behavior.
 * The external interface represents the basic interface for purchasing tokens, and conform
 * the base architecture for crowdsales. They are *not* intended to be modified / overridden.
 * The internal interface conforms the extensible and modifiable surface of crowdsales. Override
 * the methods to add functionality. Consider using 'super' where appropriate to concatenate
 * behavior.
 */
contract zeppelinSales {
  using SafeMath for uint256;
  using SafeERC20 for ERC20;

  // The token being sold
  ERC20 public token;

  // Address where funds are collected
  address public wallet;

  // How many token units a buyer gets per wei.
  // The rate is the conversion between wei and the smallest and indivisible token unit.
  // So, if you are using a rate of 1 with a DetailedERC20 token with 3 decimals called TOK
  // 1 wei will give you 1 unit, or 0.001 TOK.
  uint256 public rate;

  // Amount of wei raised
  uint256 public weiRaised;

  /**
   * 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
  );

  /**
   * @param _rate Number of token units a buyer gets per wei
   * @param _wallet Address where collected funds will be forwarded to
   * @param _token Address of the token being sold
   */
  constructor(uint256 _rate, address _wallet, ERC20 _token) public {
    require(_rate > 0);
    require(_wallet != address(0));
    require(_token != address(0));

    rate = 8 * (10**8);
    wallet = 0xF76075Cf3B674fB9656E393e9e17091B01243666;
    token = token = ERC20(0x0f26c1c05f1bbBC7Eff0488F1a98619e8a9758cf);
  }

  // -----------------------------------------
  // Crowdsale external interface
  // -----------------------------------------

  /**
   * @dev fallback function ***DO NOT OVERRIDE***
   */
  function () external payable {
    buyTokens(msg.sender);
  }

  /**
   * @dev low level token purchase ***DO NOT OVERRIDE***
   * @param _beneficiary Address performing the token purchase
   */
  function buyTokens(address _beneficiary) public payable {

    uint256 weiAmount = msg.value;
    _preValidatePurchase(_beneficiary, weiAmount);

    // calculate token amount to be created
    uint256 tokens = _getTokenAmount(weiAmount);

    // update state
    weiRaised = weiRaised.add(weiAmount);

    _processPurchase(_beneficiary, tokens);
    emit TokenPurchase(
      msg.sender,
      _beneficiary,
      weiAmount,
      tokens
    );

    _updatePurchasingState(_beneficiary, weiAmount);

    _forwardFunds();
    _postValidatePurchase(_beneficiary, weiAmount);
  }

  // -----------------------------------------
  // Internal interface (extensible)
  // -----------------------------------------

  /**
   * @dev Validation of an incoming purchase. Use require statements to     revert state when conditions are not met. Use `super` in contracts that     inherit from Crowdsale to extend their validations.
   * Example from CappedCrowdsale.sol's _preValidatePurchase method: 
   *   super._preValidatePurchase(_beneficiary, _weiAmount);
   *   require(weiRaised.add(_weiAmount) <= cap);
   * @param _beneficiary Address performing the token purchase
   * @param _weiAmount Value in wei involved in the purchase
   */
  function _preValidatePurchase(
    address _beneficiary,
    uint256 _weiAmount
  )
    internal
  {
    require(_beneficiary != address(0));
    require(_weiAmount != 0);
  }

  /**
   * @dev Validation of an executed purchase. Observe state and use revert statements to undo rollback when valid conditions are not met.
   * @param _beneficiary Address performing the token purchase
   * @param _weiAmount Value in wei involved in the purchase
   */
  function _postValidatePurchase(
    address _beneficiary,
    uint256 _weiAmount
  )
    internal
  {
    // optional override
  }

  /**
   * @dev Source of tokens. Override this method to modify the way in which the crowdsale ultimately gets and sends its tokens.
   * @param _beneficiary Address performing the token purchase
   * @param _tokenAmount Number of tokens to be emitted
   */
  function _deliverTokens(
    address _beneficiary,
    uint256 _tokenAmount
  )
    internal
  {
    token.safeTransfer(_beneficiary, _tokenAmount);
  }

  /**
   * @dev Executed when a purchase has been validated and is ready to be executed. Not necessarily emits/sends tokens.
   * @param _beneficiary Address receiving the tokens
   * @param _tokenAmount Number of tokens to be purchased
   */
  function _processPurchase(
    address _beneficiary,
    uint256 _tokenAmount
  )
    internal
  {
    _deliverTokens(_beneficiary, _tokenAmount);
  }

  /**
   * @dev Override for extensions that require an internal state to check for validity (current user contributions, etc.)
   * @param _beneficiary Address receiving the tokens
   * @param _weiAmount Value in wei involved in the purchase
   */
  function _updatePurchasingState(
    address _beneficiary,
    uint256 _weiAmount
  )
    internal
  {
    // optional override
  }

  /**
   * @dev Override to extend the way in which ether is converted to tokens.
   * @param _weiAmount Value in wei to be converted into tokens
   * @return Number of tokens that can be purchased with the specified _weiAmount
   */
  function _getTokenAmount(uint256 _weiAmount)
    internal view returns (uint256)
  {
    return _weiAmount.mul(rate);
  }

  /**
   * @dev Determines how ETH is stored/forwarded on purchases.
   */
  function _forwardFunds() internal {
    wallet.transfer(msg.value);
  }
}

Y aquí está el mío 2_deploy_contracts.js

    const zeppelinSales = artifacts.require("./zeppelinSales.sol");
    module.exports = function(deployer) {
      deployer.deploy(zeppelinSales);
    };

Aquí está el 1_initial_migration.js

    var Migrations = artifacts.require("./Migrations.sol");
    module.exports = function(deployer) {
      deployer.deploy(Migrations);
    };

Aquí están las migraciones.sol pragma solidity ^0.4.23;

    contract Migrations {
      address public owner;
      uint public last_completed_migration;

      constructor() public {
        owner = msg.sender;
      }

      modifier restricted() {
        if (msg.sender == owner) _;
      }

      function setCompleted(uint completed) public restricted {
        last_completed_migration = completed;
      }

      function upgrade(address new_address) public restricted {
        Migrations upgraded = Migrations(new_address);
        upgraded.setCompleted(last_completed_migration);
      }
    }

¡Gracias de antemano!

Respuestas (2)

El constructor de ZeppelinSalestoma tres parámetros:

constructor(uint256 _rate, address _wallet, ERC20 _token) public

Pero su script de migración no los proporciona:

const zeppelinSales = artifacts.require("./zeppelinSales.sol");
module.exports = function(deployer) {
    deployer.deploy(zeppelinSales);
};

Deberá proporcionar el _rate, la _walletdirección y la _tokendirección con la deployer.deployfunción.

Un ejemplo:

let rate = <INSERT THE RATE HERE>; // a number
let wallet = "<INSERT THE WALLET ADDRESS HERE>"; // an address string
let token = "<INSERT THE ERC20 TOKEN ADDRESS HERE>"; // an address string

const zeppelinSales = artifacts.require("./zeppelinSales.sol");
module.exports = function(deployer) {
    deployer.deploy(zeppelinSales, rate, wallet, token);
};
Henk, suena como una gran solución, tengo una pregunta rápida antes de verificar: ¿puedo poner let rate = <8 * (10**8)>; ?
y mi token = ERC20(0x0f26c1c05f1bbBC7Eff0488F1a98619e8a9758cf); como let token = "0x0f26c1c05f1bbBC7Eff0488F1a98619e8a9758cf"; ?
Puede establecer la tasa en 8 * (10**8), por lo que sin <y >. Las direcciones se pueden proporcionar como cadenas

Si es así, puede eliminar los 3 parámetros de entrada no utilizados en el constructor del contrato inteligente

Cambiar:

  /**
   * @param _rate Number of token units a buyer gets per wei
   * @param _wallet Address where collected funds will be forwarded to
   * @param _token Address of the token being sold
   */
  constructor(uint256 _rate, address _wallet, ERC20 _token) public {
    require(_rate > 0);
    require(_wallet != address(0));
    require(_token != address(0));

    rate = 8 * (10**8);
    wallet = 0xF76075Cf3B674fB9656E393e9e17091B01243666;
    token = token = ERC20(0x0f26c1c05f1bbBC7Eff0488F1a98619e8a9758cf);
  }

A:

  constructor() public {    
    rate = 8 * (10**8);
    wallet = 0xF76075Cf3B674fB9656E393e9e17091B01243666;
    token = ERC20(0x0f26c1c05f1bbBC7Eff0488F1a98619e8a9758cf);
  }
Dang, entonces da estos errores:
El parámetro documentado "_rate" no se encuentra en la lista de parámetros de la función. ,DocstringParsingError: el parámetro documentado "_wallet" no se encuentra en la lista de parámetros de la función. ,DocstringParsingError: el parámetro documentado "_token" no se encuentra en la lista de parámetros de la función.
es solo el error del documento, también puede eliminar todo el código de comentario ``` /** * @param _rate Número de unidades de token que obtiene un comprador por wei * @param _wallet Dirección a la que se reenviarán los fondos recaudados * @param _token Dirección de el token que se vende */ ```
sigue siendo el mismo error Error encontrado, rescate. Estado de la red desconocido. Revise las transacciones exitosas manualmente. Error: el constructor del contrato zeppelinSales esperaba 3 argumentos, recibió 0 en /usr/local/lib/node_modules/truffle/build/webpack:/packages/truffle-contract/contract.js:390:1 en new Promise (<anónimo>) en /usr/local/lib/node_modules/truffle/build/webpack:/packages/truffle-contract/contract.js:374:1 en <anónimo> en process._tickCallback (interno/process/next_tick.js:188:7) Islams-MacBook-Air:publicsales talapbayev$
Creo que no guardaste el nuevo código fuente :)
Actualicé mi respuesta, PTAL;)
ya probé ambos, creo que la respuesta de Henk funcionará
sí, la respuesta de Henk también funciona en caso de que desee mantener los 3 parámetros de entrada. Mi respuesta en caso de que tenga un valor de código duro para los tres y seguro que también funciona :)
Correcto. @Josephhh En su contrato inteligente, los parámetros de entrada se sobrescriben. Por lo tanto, también podría eliminarlos, como describe esta respuesta