Burning an token - owner only

Hi all,

I am very very new to this field and am trying to create a burnable token.
Leaving my code below:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract COToken is ERC721URIStorage {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    constructor() ERC721("COIN", "CO") {}

    function createNFT(address owner, string memory tokenURI)
        public
        returns (uint256)
    {
        _tokenIds.increment();
        uint256 newItemId = _tokenIds.current();
        _mint(owner, newItemId);
        _setTokenURI(newItemId, tokenURI);
        return newItemId;
    }

    function burn(uint256 tokenid)
        public
        returns (uint256)
    {
        require(msg.sender == ownerOf(tokenid));
        _burn(tokenid);
        return tokenid;

    }
    
}   

As you can see - I have created a createNFT function which enables to both mint and attach a tokenURI to a new token. More importantly, however, my question concerns the ‘burn’ function. I note that the in-built _burn function is ‘internal’ and doesn’t appear on the remix buttons, and thus call it through this function so that it does - I want this burn function to require someone to be the owner of a given token in order to burn it. I am pretty clueless as to if someone who is not the token owner could backdoor into the original “_burn” function once the contract is deployed and essentially burn the token without being the owner.

Tl;dr - _burn is an internal function. I call it within the contract through my function “burn” - is there a way for someone to call the _burn function by a means other than through my “burn” function and thus burn a token without being the owner.

I am terribly sorry if none of the above makes sense. Still getting to grips with this new area and I’m a slow learner.

Thank you so much for your time!

Hi ctsgs, welcome to Open Zeppelin!

For completeness, let’s go down the trail as you have.

If you look at the contracts you imported, you will find the _burn function.

It is internal. Read about function types here https://medium.com/@yangnana11/solidity-function-types-4ad4e5de6d56

So what does “internal” actually mean? It’s available to the contract address and derived contracts. Meaning that for a contract to call it directly, they would need to be at the contract address “deriving” that contract. If the call was from a different contract address, it would be an external call.

So to answer your question, not one outside the contract can call that _burn function. They need to use the burn function as you are thinking.

1 Like

Extremely useful - thank you very much

So just to confirm (and more as a general knowledge kind of question) - if I inherit another contract and within that inherited contract there is a ‘private’ function - I can’t call that function from the new contract. However, if internal, I can call the function from the new contact, and once deployed the only way to interact with that internal function from the inherited contract is through my newly created function in the new contract.

I guess the implication of this is - if I don’t call an internal function from an inherited contract, and then deploy the contract , there is no way for someone else on the blockchain to interact with that internal function at all.

Am I right in these assumptions?

Thank you!

Yes exactly. Internal functions are only available within your own code, and not to other contracts on chain.