Assigning owner to upgradeable contract

When you deploy an upgradeable contract, per the documentation, the deployer is the owner of the contract so I can use onlyOwner modifier on certain functions. However, when I deployed the contract and called owner on the contract, the address was 0x. I fixed it by calling the __Ownable_init() function in my initializer. Here is the contract code

//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;
import "hardhat/console.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

contract Token is Initializable, OwnableUpgradeable {
  string public name;
  string public symbol;

  uint256 public totalSupply;

  mapping(address => uint256) balances;

  function initialize(string memory _name, string memory _symbol, uint256 _totalSupply) public initializer {
    name = _name;
    symbol = _symbol;
    totalSupply = _totalSupply;
    balances[msg.sender] = totalSupply;
    __Ownable_init();
  }
}

Although __Ownable_init works, I am not sure if that is the right solution to set the owner, it is nowhere in the documentation. Can someone tell me if I am doing anything wrong? I thought the owner will be set to the deployer address automatically.

1 Like

Hi @mmurthy,

Yes, that is how you initialize the owner.
See the documentation: https://docs.openzeppelin.com/contracts/4.x/upgradeable#usage

As we don't use constructors to initialize our upgradeable contracts we need to call the initialize function.

I have that init call, but I'm still getting 0x address as owner. Any ideas? Thanks!

import '@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol';
import '@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol';
import '@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol';
import '@openzeppelin/contracts/utils/Strings.sol';
import './Base64.sol';

contract Burger is 
    Initializable,
    ERC721Upgradeable,
    ERC721EnumerableUpgradeable,
    ERC721URIStorageUpgradeable,
    PausableUpgradeable,
    OwnableUpgradeable,
    ERC721BurnableUpgradeable,
    ReentrancyGuardUpgradeable
{

    using CountersUpgradeable for CountersUpgradeable.Counter;

    CountersUpgradeable.Counter private _tokenIdCounter;

    struct Burg {
            address recipientAddress;
            string name;
    }

    uint256 public price;

    function initialize() initializer public {
        __ERC721_init("Burger", "BURGCRED");
        __ERC721Enumerable_init();
        __ERC721URIStorage_init();
        __Pausable_init();
        __Ownable_init();
        __ERC721Burnable_init();

        price = 0.001 ether;
    }

I'm using that Ownable_init() function, but I'm still getting 0x address as owner. Help? Thank you!

import '@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol';
import '@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol';
import '@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol';
import '@openzeppelin/contracts/utils/Strings.sol';

contract Burger is 
    Initializable,
    ERC721Upgradeable,
    ERC721EnumerableUpgradeable,
    ERC721URIStorageUpgradeable,
    PausableUpgradeable,
    OwnableUpgradeable,
    ERC721BurnableUpgradeable,
    ReentrancyGuardUpgradeable
{

    using CountersUpgradeable for CountersUpgradeable.Counter;

    CountersUpgradeable.Counter private _tokenIdCounter;

    struct Burg {
            address recipientAddress;
            address providerAddress;
            string name;
    }

    uint256 public price;

    // constructor() initializer {}

    function initialize() initializer public {
        __ERC721_init("Burger", "BURG");
        __ERC721Enumerable_init();
        __ERC721URIStorage_init();
        __Pausable_init();
        __Ownable_init();
        __ERC721Burnable_init();

        price = 0.001 ether;
    }

In this case, ensure you are interacting with the proxy address rather than the implementation address. See Initialization of Upgradeable Contract Not Working - #2 by ericglau

1 Like