1

i'm following a tutorial but now it is old, because was written more then 1 year ago, with 0.4.24 pragma and i also want upgrade this code. I got this error and i'm pretty sure to know why: view and pure cannot modify variables. But my question is: how do i must write this function to do it's job?

Here is my code:

pragma solidity 0.5.0;

import "https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/master/contracts/crowdsale/Crowdsale.sol";
import "https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/master/contracts/crowdsale/emission/MintedCrowdsale.sol";
import "https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/master/contracts/crowdsale/validation/CappedCrowdsale.sol";
import "https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/master/contracts/crowdsale/validation/TimedCrowdsale.sol";


contract IPPCrowdsale is Crowdsale, MintedCrowdsale, CappedCrowdsale, TimedCrowdsale {


    uint256 public investorMinCap = 100000000000000; 
    uint256 public investorMaxCap = 100000000000000000000; 
    mapping(address => uint256) public contributions;


    constructor (uint256 rate, address payable wallet, IERC20 token, uint256 cap, uint256 openingTime, uint256 closingTime)
    Crowdsale(rate, wallet, token) 
    CappedCrowdsale(cap) 
    TimedCrowdsale(openingTime,closingTime)
    public
    {

    }

  function _preValidatePurchase(address beneficiary,uint256 weiAmount) internal view 
  {
    super._preValidatePurchase(beneficiary, weiAmount);
    uint256 _existingContribution = contributions[beneficiary];
    uint256 _newContribution = _existingContribution.add(weiAmount);
    require(_newContribution >= investorMinCap && _newContribution <= investorMaxCap);
    contributions[beneficiary] = _newContribution;
  }    



}

The function is the last one: _preValidatePurchase

1

As you said view and pure function can't modify state so in order to update contributions you have to write another function.

Quoting comments Crowdsale.sol of _preValidatePurchase

@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.

this function is marked as view because it just performs checks not the state update.

I would do something like

function _preValidatePurchase(address beneficiary,uint256 weiAmount) internal view
  {
    super._preValidatePurchase(beneficiary, weiAmount);
    // custom validations here
  }    

function validPurchase (address beneficiary,uint256 weiAmount) public 
{
    _preValidatePurchase(beneficiary, weiAmount);
    uint256 _existingContribution = contributions[beneficiary];
    uint256 _newContribution = _existingContribution.add(weiAmount);
    require(_newContribution >= investorMinCap && _newContribution <= investorMaxCap);
    contributions[beneficiary] = _newContribution;
}
  • Thanks for your answer and for the example. Could i ask why you made a public function (validPurchase)? Can i declare it as internal? What i suppose to do is check if a contribution is more than MinCap and less then MaxCap. – Crowdsale Guy Jun 15 at 9:11
  • I made it public for the example, you can make internal. In fact you may put the require(_newContribution >... ); inside _preValidatePurchase – Crema Jun 15 at 13:09
  • I cannot put the require(_newContribution >... ); inside _preValidatePurchase because _newContribution is not declared yet... or am i wrong? – Crowdsale Guy Jun 15 at 14:20

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.