2

Here is my smart contract source code.

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

contract CampaignFactory {
  address[] public deployedCampaigns;

  function createCampaign(uint minimum) public {
     Campaign newCompaign  = new Campaign(minimum, msg.sender);
     deployedCampaigns.push(address(newCompaign));
  }

  function getDeployedCampaigns() public view returns(address[] memory){
     return deployedCampaigns;
  }

}

contract Campaign {

  struct Request {
    string description;
    uint amount;
    address recipient;
    bool complete;
    uint approvalCount;
    mapping (address => bool) approvals;
  }
  mapping(address => bool) approvers;
  uint approversCount;
  Request[] requests;

  address public manager;
  uint public minimumContribution;

  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 amount, address recipient) public 
   restricted{

     Request storage newRequest = requests.push();
     newRequest.description = description;
     newRequest.amount = amount;
     newRequest.recipient = recipient;
     newRequest.complete = false;
     newRequest.approvalCount = 0;    
  }
  ...
}

Truffle javascript test code :

const {assert} = require('chai');
const Web3 = require('web3');
const ganache = require('ganache-cli');
const web3 = new Web3(ganache.provider());

const CampaignFactory = artifacts.require('./CampaignFactory');
const Campaign = artifacts.require('./Campaign');

contract('CampaignFactory', (accounts) => {
  let factory;
  let campaign;
  let campaignAddress;

  before( async () => {
    factory = await CampaignFactory.deployed();   

    // We create a campaign instance but not get a reference to the campaign instance.
    // Remember that anytime we send a transaction we get absolutely no result back except for 
    // a transaction receipt
    const childContractTx = await factory.createCampaign(web3.utils.toWei('0.02', 'ether'));
    campaignAddress = childContractTx.receipt.to;        
    campaign = await Campaign.at(campaignAddress);     
  })
  describe('CampaignFactory deployment', async () =>{
    it('successfully deployed', async () => {
      const address = await factory.address 
      assert.notEqual(address, '')
      assert.notEqual(address, null)
      assert.notEqual(address, undefined)
      assert.notEqual(address, 0x0)
    })

    it('successfully created a campaign', async ()=> {
      const address = await campaign.address;     
      assert.notEqual(address, '')
      assert.notEqual(address, null)
      assert.notEqual(address, undefined)
      assert.notEqual(address, 0x0)      
    })

  })
  describe('Campaign', async ()=> {    
    it('contribute', async ()=> {                   
      const manager = await campaign.manager();
      console.log("manager", manager)
      assert.equal(accounts[0], manager);
    })
  })
}

The below is the result of test : enter image description here

The "Campaign" instance was created and deployed by CampaignFactory. "manager" is a public state variable of "Campaign" smart contract. So I tried to read it through its default getter. But it was failed. What's wrong with me?

1 Answer 1

0

The problem is in this line:

campaignAddress = childContractTx.receipt.to; 

the transaction of the following line is executing the function createCampaign of the factory smart contract

 const childContractTx = await factory.createCampaign(web3.utils.toWei('0.02', 'ether'));

so the value of childContractTx.receipt.to is the address of factory contract and not the campaign contract address

you should use something like this:

campaignAddress = await factory.deployedCampaigns(0);
campaign = await Campaign.at(campaignAddress); 

since the function createCampaign is storing the address in the array: deployedCampaigns

in this line of your smart contract:

deployedCampaigns.push(address(newCompaign));

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.