Working with Factory contract: what is the "appContractAddress"?

Hi there :slight_smile:

I was playing with

Factory.sol

to try to create new contract instances via a factory method. However, I wasn’t able to bring this to work without any REVERT.

The base question is probably: what exactly is the contract address in the factory-initializer?

I have the following basic contract:

pragma solidity ^0.5.0;

import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "@openzeppelin/upgrades/contracts/application/App.sol";

contract Counter is Initializable {
    uint256 public value;

    function initialize(uint256 initialValue) public initializer {
        value = initialValue;
    }

    function increase() public {
        value++;
    }

    function getValue() public returns (uint256) {
        return value;
    }
}

And the factory contract:

pragma solidity ^0.5.0;

import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "@openzeppelin/upgrades/contracts/application/App.sol";

contract Factory is Initializable {

  App public app;
  
  function initialize(address _appContractAddress) public initializer {
    app = App(_appContractAddress);
  }

  function createCounter() public returns (address proxy) {
    address admin = msg.sender;
    return address(
        app.create(
            "FactoryTest",
            "Counter",
            admin,
            abi.encodeWithSignature("initialize(uint256)", 123)
        )
    );
  }
}

Dependencies:

  "dependencies": {
    "@openzeppelin/contracts-ethereum-package": "^2.4.0",
    "@openzeppelin/upgrades": "^2.6.0"
  }

What I did:

oz push --network development
oz create --network development   

Then I created an instance of Factory, calling the initialize-Method passing the contract address from the Counter-contract that I found in .openzeppelin/dev-xxx.json under:

{
  "contracts": {
    "Counter": {
      "address": "0x26B847feFD5bE17Bbf223a934f5Bb4518f9Ac162",
      "constructorCode": "60806040523480156100115760006000fd5b50610017565b610295806100266000396000f3fe",

In Terminal I create the Factory instance:

:spades: oz create

Nothing to compile, all contracts are up to date.

? Pick a contract to instantiate Factory

Using session with network development, sender address 0x6c32Ee3d8DCD2a88142c6bA35FC97cE92904F086, timeout 3600 seconds

All contracts are up to date
? Do you want to call a function on the instance after creating it? Yes
? Select which function * initialize(_appContractAddress: address)
? _appContractAddress (address): 0x26B847feFD5bE17Bbf223a934f5Bb4518f9Ac162
✓ Setting everything up to create contract instances
✓ Instance created at 0xED279ED92425f6fe86fAd66D414d8E601a72E558
0xED279ED92425f6fe86fAd66D414d8E601a72E558

Now I tried to execute the createCounter-function:

:spades: oz send-tx
Using session with network development, sender address 0x6c32Ee3d8DCD2a88142c6bA35FC97cE92904F086, timeout 3600 seconds
? Pick an instance Factory at 0xED279ED92425f6fe86fAd66D414d8E601a72E558
? Select which function createCounter()
:heavy_multiplication_x: Calling: ‘createCounter’ with no arguments

Result:

Error while trying to send transaction to 0xED279ED92425f6fe86fAd66D414d8E601a72E558. Error: Returned error: VM Exception while processing transaction: revert

What do I wrong here?

1 Like

Okay, I can answer by myself :slight_smile:

Looking at the example in the package mentioned above ion my question, there was a slightly issue how I set up the contracts. I just forgot to oz publish them.

After this, under .openzeppelin/dev-xxx.json we’ll find not only the contract addresses for Factory and Counter (in my example), but also the address for the app-contract. This is the final address that needs to get passed into the Factory:

  "manifestVersion": "2.2",
  "version": "1.0.0",
  "app": {
    "address": "0xFc2f3B7370FB90f256AA160147F4d7c742F1bB2C"
  },
  "package": {
    "address": "0x58422bec359B909f58BC064E61ea0a86b0d5DC1B"
  },
  "provider": {
    "address": "0x3F235B10b1A670B401f8f63Bb873b98d7EcB646D"
  },

Using 0xFc2f3B7370FB90f256AA160147F4d7c742F1bB2C as parameter for the initialize-method in Factory contract in this example helps a lot to make the factory really working :slight_smile:

2 Likes