How to set Ownership during deployment

Hello Everyone,

I have a question on the usage of contracts-upgradable. I moved my contracts to @openzeppelin/contracts-upgradeable@solc-0.7. I adjusted my import statements as well as moved my constructor code to initialize. I am having problem with the ownership of the contracts during deployment. Here is the general structure of one contract. There is no constructor so I did not add any initialize function using the Initialiazable.

contract ThisContract is OwnableUpgradeable {

OtherContract otherContract ;

 // no constructor
 // no initialize
    ....

 function setOtherContract(OtherContract _otherContract) public onlyOwner {
    otherContract = _otherContract;
  }

   ...
}

After ThisContract is deployed I placed a console.log for its owner() in the deployment script. It shows zero-address. Therefore, thisContract.setOtherContract(otherContract) fails with ownership error as well.

How do you assign the initial ownership during deployment? Is it not automatically getting it as it is doing in the non-upgradable version? Also, once this is set properly the deploymentAccount could just call transferOwnership for the final owner. Am I correct?

By the way, although I am using upgradable contracts I am still using my normal deployment script for now. So, there is no proxy as of now? Can these upgradable contracts be deployed as such? Maybe this is my problem.

Thank you.

Regards,
Nihat

1 Like

Hi @ngurmen,

You need to call __Ownable_init() to initialize the owner in your initialize function.

When you deploy your contract you also need to call the initialize function. You can do this using the Upgrade Plugins.

If you were to deploy a contract with an initialize function without using the Upgrades Plugins (e.g. as a regular, non-upgradeable contract), you should ensure that you deploy and call initialize in the same transaction, as any account can call initialize.

Please see the documentation for how to use OpenZeppelin Contracts Upgradeable:
https://docs.openzeppelin.com/contracts/3.x/upgradeable

You can follow these step by step tutorials to deploy an upgradeable contract.

1 Like

Thank you for your help. Regards, Nihat

1 Like

I thought I understood it… :slight_smile: Could you please shed some light for me? I am still getting zero-address for the owner of the contract. What am I missing? Please note that I’m deploying without the Upgrades Plugins as an intermediate step. [PS: using upgrades plugin worked fine. I would still appreciate an explanation if one has why the below is not working.]

I have the following contract:

import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

contract Contract1 is Initializable, OwnableUpgradeable {
    // storage
    function initialize() public initializer {
        __Ownable_init();  // here I tried with or without super
    }
    // other functions
}

In the deployment script I have:

const accounts = await hre.ethers.getSigners();
const deploymentAccount = accounts[0].address;
console.log("Deployment Account:", deploymentAccount);
const Contract1 = await hre.ethers.getContractFactory("Contract1");
const contract1 = await Contract1.deploy();
await contract1.deployed();
console.log("Contract1 deployed to:", contract1.address);
await contract1.initialize();
console.log("Contract1 initialized.");
console.log("Contract1 owner:", await contract1.owner());

I get the following output:

Compiling 21 files with 0.7.6
Compilation finished successfully
Deployment Account: 0x...
Contract1 deployed to: 0x...
Contract1 initialized.
Contract1 owner: 0x0000000000000000000000000000000000000000
1 Like

Hi @ngurmen,

Can you try the following deploy script (based on https://docs.openzeppelin.com/learn/deploying-and-interacting)

// scripts/deploy.js
async function main() {

    const accounts = await ethers.provider.listAccounts();
    console.log("Accounts[0]:", accounts[0]);

    // We get the contract to deploy
    const Contract1 = await ethers.getContractFactory("Contract1");
    console.log("Deploying Contract1...");
    const contract1 = await Contract1.deploy();
    await contract1.deployed();
    console.log("Contract1 deployed to:", contract1.address);
    await contract1.initialize();
    console.log("Contract1 initialized.");
    console.log("Contract1 owner:", await contract1.owner());
  }
  
  main()
    .then(() => process.exit(0))
    .catch(error => {
      console.error(error);
      process.exit(1);
    });

I get the following as expected:

$ npx hardhat run scripts/deploy.js
Accounts[0]: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
Deploying Contract1...
Contract1 deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3
Contract1 initialized.
Contract1 owner: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
1 Like

Thank you for your clarification. It took me a while to get back due to weather events here in the States.

1 Like

Hi @ngurmen,

I hope you managed to stay warm and have drinkable water. Stay safe.