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?
Edit:
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
.createCampaign("100")
.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(
campaignInterface,
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
requests
in the tests, could you put in the call torequests
too?