0

I have a contract in which I must import ~100k ETH addresses into a map. Whenever I try to do that on Ropsten network (via Infura), I receive the error:

Error: exceeds block gas limit

If I try to do it on Ganache, the RPC client crashes:

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory

What other tools could I use to avoid these congestions? Can these errors occur on mainnet as well?


I must create a voting system and restrict the access of voting to only 100k people. Thus I must somehow import the addresses of those people into contract:

// SPDX-License-Identifier: ISC
pragma solidity >=0.8.0;

contract Vot {

  // Key can have three states:
  //
  // 0 -> not assigned
  // 1 -> assigned, address can vote
  // 2 -> assigned, address cannot vote
  mapping (address=>uint8) private _votersWhichCanVote;
  
  // Stores the votes with the voters in list.
  // Did it likewise to have O(1) complexity for votes retrieval.
  int8[] private _votes;
  address[] private _voters;
 
 
  address private _owner;
  constructor() {
    _owner = msg.sender;
  }
  
  // Import voters without overwriting existing ones.
  // Only contract creator may call it.
  function importVoters(address[] memory voters) public {
    require(msg.sender == _owner);
    
    for(uint256 i=0; i<voters.length; i++) {
      if(_votersWhichCanVote[voters[i]] == 0) {
        _votersWhichCanVote[voters[i]] = 1;
      }
    }
  }
  
  // One user votes.
  // Sender must be present in _votersWhichCanVote.
  function setVote(int8 choice) public {
    require(_votersWhichCanVote[msg.sender] == 1);
    
    _voters.push(msg.sender);
    _votes.push(choice);
    _votersWhichCanVote[msg.sender] = 2;
  }
  
  function getVotes() public view returns(int8[] memory) {
    return _votes;
  }
  
  function getVoters() public view returns(address[] memory) {
    return _voters;
  }
  
  function iCanVote() public view returns(bool) {
    return _votersWhichCanVote[msg.sender] == 1;
  }
  
  function iHaveVoted() public view returns(bool) {
    return _votersWhichCanVote[msg.sender] == 2;
  }
}

The only solution seems to be batch inserts?

5
  • Wow that is too much data!!! How are u adding those addresses ? Show some solidity and web3js/etherjs code :)
    – Majd TL
    Nov 8, 2021 at 15:12
  • 1
    There is a 24kb maximum transaction size, so i is unlikely that 100k addresses will fit in a single transaction. What's the purpose of 100k addresses? If you explain the problem we can suggest a better solution.
    – Ismael
    Nov 8, 2021 at 16:08
  • Thank you for replies. I've updated the question with context Nov 9, 2021 at 10:18
  • 1
    Have you considered other solutions, like a Merkle tree ? This describe a problem pretty close to yours : thecibrax.com/using-merkle-trees-for-bulk-transfers-in-ethereum Nov 9, 2021 at 10:26
  • yes as DrGorilla said use merkle trees and check if the voter address is part of that tree :)
    – Majd TL
    Nov 9, 2021 at 11:41

1 Answer 1

1

You simply have so much addresses to import that your transaction exceed the block gas limit.

On a testnet, you can circumvent this by adding the addresses in multiple small transactions, each lower than the block gas limit.

However, on mainnet no matter how you do it, it will cost you several thousands dollars do import all of those. One full Ethereum block cost about 22000$ in transaction cost today. You probably have many full blocks to pay for with what you want to do.

3
  • 1
    why heck your brilliant answers are not being upvoting and marked? How do I believe the most "programming" field people doesn't know what is SE upvote?
    – T.Todua
    Dec 2, 2021 at 12:20
  • 1
    @T.Todua Thanks I appreciate it. Believe it or not, most bounties in this StackExchange are never awarded and are just lost, even when there are good answers.
    – Undead8
    Dec 2, 2021 at 19:47
  • While it states valuable facts, I did not mark it as solution because it's not a solution. Jan 15, 2022 at 19:07

Your Answer

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

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