I am a kinda newbie to this, so please excuse my questions.


I am creating a simple ICO using a simple smart contract. I want to set a limit for people to send ETH to this smart contract using the revert(); keyword and to make sure that a single user doesn't buy all my tokens.

For this, I also made sure that only between 0.1 ETH and 2 ETH could be sent per transaction, but my worry is that the same wallet address/user will repeat the process and eventually send more than 2 ETH.

Below is a good example of a real scenario:

  1. Mr A sends 2 ETH once, and the contract should revert it if he tries to send again.
  2. Mr B decides to send 0.9 ETH first. Then again, he decides to send 1.1 ETH later. In this case, the contract should allow it, since only a maximum of 2 ETH per wallet address is allowed. But again if he tries to send more, the contract should revert it.

How do I do this?


I also want to include a code where only a maximum of 150 ETH can be sent to this smart contract or that's the maximum that this smart contract can store, otherwise, it will revert transactions whenever users try to send more.

How do I do this also?


pragma solidity ^0.4.24; 

contract CrowdSale{

    address public owner;

    constructor() public {
        owner = msg.sender;

    function transfer(address to, uint256 amount) public {
        require(msg.sender == owner);

    mapping (address => uint) balances;

    function () external payable {
        if(msg.value < 100000000000000000) {
            revert("Minimum contribution: 0.1 BNB"); 
        else if(msg.value > 2000000000000000000) {
            revert("Maximum contribution: 2 BNB"); 
        balances[msg.sender] += msg.value;

    function balanceOf() external view returns(uint) {
        return address(this).balance;


I am also not sure if I should upgrade to a newer solidity version of the code, since it's showing that it has bugs when I click "!" next to the code in the etherscan.io. Also, I am a bit confused if I should use function () external payable instead of function () public payable

  • There’s no way to stop more ETH from getting added to your contract’s balance. When someone self-destructs their contract, they can send its ETH to yours and your code would never get activated. Same thing when a miner sends block rewards to your contract; your code never runs. Dec 11, 2021 at 5:08

1 Answer 1


You're already tracking balances of user all you need is a check

to check total balance of user

require(balances[msg.sender] < 2000000000000000000, "you have exceeded your purchase limit");

to check if current amount + current amount is greater than max

require(balances[msg.sender]+msg.value < 2000000000000000000, "this call exceeds you purchase limit");

to let users know how much more they can buy you can create another solidity function

   function getRemaining() public view returns(uint remaining){
       remaining = 2000000000000000000 - balances[msg.sender];

Answer for your seconds question will be subjective and fall out of stack overflow standards but you should update to latest versions if you don't have some solid requirements to stick to old versions like working on legacy programs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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