2

I'm building a dapp using Solidity and Truffle. But when testing, I get the following error when I try to execute createPost (using js tests):

Error: Returned error: VM Exception while processing transaction: revert

Please look at the following codes.

campaign contract:

contract Campaign {
  uint256 currentIndex;
 
  struct CampaignStruct {
    uint256 id;
    address user;
    string title;
    bool isExist;
  }
  struct CampaignInputStruct {
    string title;
  }
  CampaignStruct[] private campaigns;

  // ...

  constructor() {
    currentIndex = campaigns.length;
  }

  /// @notice Check if campaign exists
  function isCampaignExists(uint256 index) public view returns (bool) {
    if (campaigns[index].isExist) {
      return true;
    } else {
      return false;
    }
  }

  function createCampaign(
    CampaignInputStruct memory _input,
  ) public returns (bool) {
    // Code for create a campaign
    // ...
    currentIndex++;
    return true;
  }
}

Post contract:

import "./Campaign.sol";

contract Post is Campaign {
  uint256 currentPostIndex;

  struct PostStruct {
    uint256 id;
    address user;
    string title;
    string body;
    uint256 campaignId; // THIS IS IMPORTANT
  }
  struct PostInputStruct {
    string title;
    string body;
    uint256 campaignId;
  }

  PostStruct[] private posts;

  modifier onlyValidPostInput(PostInputStruct memory _input) {
    /// ... 
    uint256 campaignId = uint256(_input.campaignId);
    bool isExist = isCampaignExists(campaignId); /// I THINK THE PROBLEM IS HERE
    if(VALIDATION){
      /// INVALID DATA
    }
    _;
  }

  constructor() {
    currentPostIndex = posts.length;
  }

  function createPost(PostInputStruct memory _input)
    external
    onlyValidPostInput(_input)
    returns (bool)
  {
    // Codes for create a post
    currentPostIndex++;
    return true;
  }
}

Why need to call isCampaignExists before createPost? Because I need to know if campaignId is valid or not.

Problem: Apparently, the problem is with isCampaignExists. The strange thing is that this function works well in Campaign contract tests.

Milad Jafari
  • 1,135
  • 1
  • 11
  • 28

1 Answers1

0

Parent contracts can either be called directly or by using the super keyword.

Note that once keyword super is used, all of the immediate parent contracts are called.

Refer to the following example:

contract A {
    event Log(string message);

    function foo() public virtual {
        emit Log("A.foo called");
    }

    function bar() public virtual {
        emit Log("A.bar called");
    }
}
    
contract B is A {
    function foo() public virtual override {
        emit Log("B.foo called");
        A.foo();
    }

    function bar() public virtual override {
        emit Log("B.bar called");
        super.bar();
    }
}

Example taken from https://solidity-by-example.org/super/.

So, the following should eliminate your inheritance problem: bool isExist = Campaign.isCampaignExists(campaignId);

norym
  • 602
  • 2
  • 8
  • 18