I am new to Solidity and am trying to add a struct containing a mapping to an array. However, this fails. When I run this on Remix I get a message transact to CampaignFactory.createCampaign pending ... and this goes on forever. When I try calling this contract via my JS test file I get an error Error happened while trying to execute a function inside a smart contract. The following is my code:-
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
contract CampaignFactory{
address payable [] public deployedCampaigns;
function createCampaign(uint minimum) public{
address newCampaign = address(new Campaign(minimum,msg.sender));
deployedCampaigns.push(payable(newCampaign));
}
function getDeployedCampaigns()public view returns (address payable [] memory){
return deployedCampaigns;
}
}
contract Campaign{
struct Request{
string description;
uint value;
address payable recipient;
bool complete;
uint approvalCount;
mapping(address=>bool) approvals;
}
Request[] public requests;
address public manager;
uint public minimumContribution;
mapping (address=>bool) public approvers;
uint public approversCount;
modifier restricted(){
require(msg.sender==manager);
_;
}
constructor(uint minimum, address creator){
manager = creator;
minimumContribution = minimum;
}
function contribute() public payable {
require(msg.value > minimumContribution);
approvers[msg.sender] = true;
approversCount++;
}
function createRequest(string memory description, uint value, address recipient) public restricted{
Request storage newRequest = requests.push();
newRequest.description = description;
newRequest.value = value;
newRequest.recipient = payable (recipient);
newRequest.complete = false;
newRequest.approvalCount = 0;
}
function approveRequest(uint index) public{
Request storage request = requests[index];
require(approvers[msg.sender]);
require(!request.approvals[msg.sender]);
request.approvals[msg.sender] = true;
request.approvalCount++;
}
function finalizeRequest(uint index) public restricted payable {
Request storage request = requests[index];
require(!request.complete);
require(request.approvalCount>approversCount/2);
request.recipient.transfer(request.value);
request.complete = true;
}
}
I also tried an alternative way that was something like this:-
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
contract CampaignFactory {
address payable[] public deployedCampaigns;
function createCampaign(uint minimum) public {
address newCampaign = address(new Campaign(minimum, msg.sender));
deployedCampaigns.push(payable(newCampaign));
}
function getDeployedCampaigns() public view returns (address payable[] memory) {
return deployedCampaigns;
}
}
contract Campaign {
struct Request {
string description;
uint value;
address recipient;
bool complete;
uint approvalCount;
mapping(address => bool) approvals;
}
uint requestNum;
Request[] public requests;
address public manager;
uint public minimumContribution;
mapping(address => bool) public approvers;
uint public approversCount;
modifier restricted() {
require(msg.sender == manager, "Only manager can call this function");
_;
}
constructor (uint minimum, address creator) {
manager = creator;
minimumContribution = minimum;
}
function contribute() public payable {
require(msg.value > minimumContribution);
approvers[msg.sender] = true;
approversCount++;
}
event RequestCreated(string description, uint value, address recipient);
function createRequest(string memory description, uint value, address recipient) public restricted {
Request storage newRequest = requests[requestNum];
newRequest.description = description;
newRequest.value = value;
newRequest.recipient = recipient;
newRequest.complete = false;
newRequest.approvalCount = 0;
requestNum++;
emit RequestCreated(description, value, recipient);
}
function approveRequest(uint index) public {
Request storage request = requests[index];
require(approvers[msg.sender]);
require(!request.approvals[msg.sender]);
request.approvals[msg.sender] = true;
request.approvalCount++;
}
function finalizeRequest(uint index) public restricted {
Request storage request = requests[index];
require(request.approvalCount > (approversCount / 2));
require(!request.complete);
payable(request.recipient).transfer(request.value);
request.complete = true;
}
function getSummary() public view returns (
uint, uint, uint, uint, address
) {
return (
minimumContribution,
address(this).balance,
requests.length,
approversCount,
manager
);
}
function getRequest(uint index) public view returns (string memory description, uint value, address recipient, bool complete, uint approvalCount) {
Request storage request = requests[index];
return (
request.description,
request.value,
request.recipient,
request.complete,
request.approvalCount
);
}
function getRequestsCount() public view returns (uint) {
return requests.length;
}
}
But even this gives the same result. Please help. Thank you in advance.