Upgradeable ERC721

I’ve been able to replicate the SimpleERC721 code example from above with Remix, therefore I will try to keep it as close to that as possible while trying to get that contract to complie with ZepplinOS and Embark.
I’m using solc 0.5.13

ZeppelinOS:
I change the code to import from @openzeppelin/contracts
oz push gives the following error:

- Contract SimpleERC721 has an explicit constructor. Change it to an initializer function. See https://docs.openzeppelin.com/sdk/2.5/writing_contracts.html#initializers.
One or more contracts have validation errors. Please review the items listed above and fix them, or run this command again with the --force option.

oz push --force works and I can compile and submit to ganache cli

Proper way to handle this with upgradeable contracts, thanks @abcoathup:

Embark:
Using the exact same code that ran on Remix, pulling the same repo From Github, this is the error from the Embark console:

change: contracts/SimpleERC721.sol

embark-solc:

assuming Context to be an interface

assuming MinterRole to be an interface

assuming ERC165 to be an interface

assuming IERC165 to be an interface

assuming ERC721MetadataMintable to be an interface

assuming IERC721 to be an interface

assuming IERC721Enumerable to be an interface

assuming IERC721Metadata to be an interface

assuming IERC721Receiver to be an interface

To get more details on interface Smart contracts, go here: https://embark.status.im/docs/troubleshooting.html#Assuming-Contract-to-be-an-interface

deploying contracts

Executing pre-deploy actions...

Pre-deploy actions done. Deploying contracts

[ERC721Full]: Error: attempted to deploy ERC721Full without specifying parameters. check if there are any params defined for this contract in this environment in the contracts configuration file

[ERC721Metadata]: Error: attempted to deploy ERC721Metadata without specifying parameters. check if there are any params defined for this contract in this environment in the contracts configuration file

[SimpleERC721]: Failing call, this could be because of invalid inputs or function guards that may have been triggered, or an unknown error.

deploying SafeMath with 82470 gas at the price of 1 Wei, estimated cost: 82470 Wei (txHash: 0x0c42958f6240833872d389d1c2644a20530399fc3ce8731d2c0ca963e3e54719)

deploying Counters with 81887 gas at the price of 1 Wei, estimated cost: 81887 Wei (txHash: 0x3e3066dc0eb095a044591410a599a297ebe9729d705b33a99aad2966031f0769)

deploying Roles with 78968 gas at the price of 1 Wei, estimated cost: 78968 Wei (txHash: 0x6197f331403e84deba9aeec1087c077c5bf0ec0b625b4de502bfe5620b7f0fc8)

deploying Address with 84189 gas at the price of 1 Wei, estimated cost: 84189 Wei (txHash: 0x17e79b6fc897b91371f2fbb9ad865ed2264fa674aa0ca1f7d00b987d6331808b)

[ERC721]: Failing call, this could be because of invalid inputs or function guards that may have been triggered, or an unknown error.

[ERC721Enumerable]: Failing call, this could be because of invalid inputs or function guards that may have been triggered, or an unknown error.

SafeMath deployed at 0x5Ab333bdE4378939eCE590705D5524e436956a69 using 76654 gas (txHash: 0x0c42958f6240833872d389d1c2644a20530399fc3ce8731d2c0ca963e3e54719)

Roles deployed at 0x229C4CB3071DC0458fA87eEa31AC73Ad5257Bf3a using 76590 gas (txHash: 0x6197f331403e84deba9aeec1087c077c5bf0ec0b625b4de502bfe5620b7f0fc8)

Counters deployed at 0x1EC4B2Bc96FB8C24De8b73719A7E982B7EF2fd7b using 76654 gas (txHash: 0x3e3066dc0eb095a044591410a599a297ebe9729d705b33a99aad2966031f0769)

Address deployed at 0x34B645744Fd871CeBE2a3bA0493528F5F83c1abe using 76654 gas (txHash: 0x17e79b6fc897b91371f2fbb9ad865ed2264fa674aa0ca1f7d00b987d6331808b)

Error deploying contracts. Please fix errors to continue.

Error deploying contracts. Please fix errors to continue.
1 Like

Hi @lucianstroie,

OpenZeppelin SDK (previously ZeppelinOS) creates upgradeable contracts.
I recommend using the latest version which is OpenZeppelin SDK 2.6

If you are using OpenZeppelin SDK and upgradeable contracts you need to use @openzeppelin/contracts-ethereum-package rather than @openzeppelin/contracts.

https://docs.openzeppelin.com/sdk/2.5/linking
NOTE: Make sure you install @openzeppelin/contracts-ethereum-package and not the vanilla @openzeppelin/contracts. The latter is set up for general usage, while @openzeppelin/contracts-ethereum-package is tailored for being used with the OpenZeppelin SDK. This means that its contracts are already set up to be upgradeable.

I recently created an issue to add a warning to users when they create a contract importing @openzeppelin/contracts: OpenZeppelin/openzeppelin-sdk#1297 .
There is also a plan to remove this requirement to use the Contracts Ethereum Package version: Planning the demise of OpenZeppelin Contracts’ evil twin.

Also with upgradeable contracts we need to use initializers rather than constructors.

https://docs.openzeppelin.com/sdk/2.5/writing-contracts
You can use your Solidity contracts in the OpenZeppelin SDK without any modifications, except for their constructors. Due to a requirement of the proxy-based upgradeability system, no constructors can be used in upgradeable contracts.

An example upgradeable ERC721 is as follows:

Simple721Token.sol

When the contract is created (openzeppelin create) need to ensure it is initialized passing in the address to have the minter role.

Tokens can then be minted by calling (openzeppelin send-tx) mintWithTokenURI

pragma solidity ^0.5.0;

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

import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC721/ERC721Full.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC721/ERC721Mintable.sol";

contract Simple721Token is Initializable, ERC721Full, ERC721Mintable {

    function initialize(address sender) public initializer {
        ERC721.initialize();
        ERC721Metadata.initialize("Simple721Token", "721");
        ERC721Enumerable.initialize();
        ERC721Mintable.initialize(sender);
    }
}

Hi @lucianstroie,

I wanted to check how you were getting on with this?

Hey @lucianstroie! Starting with 2.7 RC, the OpenZeppelin CLI will warn if you try to use the vanilla @openzeppelin/contracts instead of @openzeppelin/contracts-ethereum-package. This is temporary though, as we are working on unifying both of them. Give the new RC a try and let us know what you think!

Hi @lucianstroie,

The CLI now supports deploying regular (non-upgradeable) contracts in the release candidate of OpenZeppelin CLI 2.8

Would appreciate if you could give the release candidate a try and let us know what you think!