Doubt regarding imports of contracts. ERC721

Hi, I need to generate a contract to tokenise vehicles.
The issue is that I am not clear which contracts I should import from OpenZeppelin.
The customer wants the tokens to be burnable.
I understand that for that I must import this contract that serves for that purpose.
import “@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol”;

If I import ERC721, I am importing ERC721BurnableUpgradeable and all the other contracts? what is better, import only the contracts I need? in case of importing only ERC721BurnableUpgradeable, which one should I import in addition?

Thank you very much!

If I import ERC721, I am importing ERC721BurnableUpgradeable and all the other contracts?

Please take a look at docs on syntax and semantics of imports in Solidity.

If you do import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol", you are importing everything defined at the top level in that particular file. In this case the file contains only ERC721BurnableUpgradeable and that’s the only thing you are bringing into your namespace. If there were any other contracts, libraries, structs, enums, free functions, etc. in that file, they would get imported too. This not transitive though. You are not importing anything from other files that this file itself imports.

what is better, import only the contracts I need?

I highly recommend importing only the names you need. This makes it much easier for other people to understand your contract because it’s clear where every name comes from:

import {ERC721BurnableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol";

With ERC721BurnableUpgradeable it’s kinda obvious that it comes from ERC721BurnableUpgradeable.sol but often a file contains multiple things that do not share its name.

in case of importing only ERC721BurnableUpgradeable, which one should I import in addition?

Well, if your code compiles then you don’t need to import anything else. If it does not and you’re missing some imports, you obviously need to add them.

After rereading your post I see that I might have misunderstood your question.

If you’re just asking if you can use ERC721Burnable without also importing ERC721 in your token then the answer is yes. ERC721Burnable already imports ERC721 and inherits from it so it’s a complete token implementation by itself. If you use ERC721 instead, you’re just using the default implementation with no extra features and these extensions are not automatically included.

You can take a look at how OpenZeppelin’s own ERC721PresetMinterPauserAutoIdUpgradeable.sol does it. It inherits only from the extension tokens and not from ERC721Upgradeable itself (BTW, keep in mind the multiple inheritance gotcha if you’re ever planning to do it yourself). It does actually import ERC721Upgradeable.sol but it’s only because it needs to be able to refer to it to override one of its methods.

1 Like