I am following kind of an outdated tutorial and trying to adapt it to the more recent changes in Solidity and other packages. Following one of my changes, I am running into a problem that I can't find an answer to.

The relevant part of my contract looks like this:

contract Campaign {
    struct Request {
        string description;
        uint value;
        address payable recipient;
        bool complete;
        mapping (address => bool) approvals;
        uint approvalCount;
    address public manager;
    uint numRequests;
    mapping (uint => Request) requests;
    modifier restrictedToManager() {
        require(msg.sender == manager);
    constructor(uint minimum, address creator) {
        manager = creator;
        minimumContribution = minimum;
    function createRequest(string calldata description, uint value, address payable recipient) public restrictedToManager {
        // get last index of requests from storage
       Request storage newRequest = requests[numRequests];
       // increase requests counter
       numRequests ++;
       // add information about new request
       newRequest.description = description;
       newRequest.value = value;
       newRequest.recipient = recipient;
       newRequest.approvalCount = 0;

Now I am testing the contract locally using the ganache provider. In one of the tests, I want to call the createRequest method and then check if the request has been created. With the code I pasted above, this does not work because the property requests has not been set public so I can't run the getter function.

However, once I change that line to mapping (uint => Request) public requests and try to test again, the transaction immediately runs out of gas when running the beforeEach hook for the first time, even with a limit of 1.000.000

To be clear, I use the beforeEach hook to deploy the contract.

How can it be that this simple change results in such a big change in gas fees?


Find below a snippet of the beforeEach hook inside of my Campaign.test.js This is where the transaction runs out of gas.

The factory contract is a higher level contract that handles deployments of the campaign contract

beforeEach(async () => {
  // get accounts
  accounts = await web3.eth.getAccounts();

  // deploy factory contract
  factory = await new web3.eth.Contract(factoryInterface)
    .deploy({ data: factoryBytecode })
    .send({ from: accounts[0], gas: "1000000" });

  // create campaign from factory contract
  await factory.methods
    .send({ from: accounts[0], gas: "1000000" });

  // assign first element out of the response array to campaignAddress
  [campaignAddress] = await factory.methods.getDeployedCampaigns().call();
  // get javascript represenation of the deployed campaign contract
  campaign = await new web3.eth.Contract(
    campaignAddress // add address as second argument to get already deployed contract

call to requests getter method

it("allows a manager to make a payment request", async () => {
    await campaign.methods
      .createRequest("Test description", "1000", accounts[1])
      .send({ from: accounts[0], gas: "1000000" });
    const request = await campaign.methods.requests(0).call();
    assert.strictEqual("Test description", request.description);

I do get the code to work if I simply increase the gas to 3.000.000. I am primarily interested in where the increase in gas fees is coming from instead of how to make the code work

  • Hi! It would be helpful if you could add a code snippet with the test you're running too. Also, are you using Truffle? If you could update the question with these, that would be great! Mar 18, 2021 at 16:44
  • Sure, check the edit. I am not using Truffle for testing, I'm using mocha
    – Philipp K
    Mar 18, 2021 at 16:50
  • I'm not seeing a call to requests in the tests, could you put in the call to requests too? Mar 18, 2021 at 16:53
  • according to the output thats not even the issues' source but i added it
    – Philipp K
    Mar 18, 2021 at 16:59
  • ah! What is the issue's source according to the output? Mar 18, 2021 at 17:00

1 Answer 1


I deployed the contract in remix with different solc versions.

Solc Private Public
0.8.2 439,788 609,500
0.7.6 312,372 440,476
0.6.12 308,678 436,781

There's a notable increment 160k in 0.8, but in previous version was similar 140k.

Since requests returns a structure making it public requires the serialization of the structure that doesn't exists when it is private.

Another important contributor to gas increment is the use of string, replacing it with bytes32 may work in some cases.

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.