1

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.

0

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.