Search code examples
soliditysmartcontractsdecentralized-applications

What is the point of inheriting from ERC271 contract?


I have just started Solidity. For this question, I think it's useful if I first state my understanding of inheritance: If Contract B inherits from Contract A (ie. in contractB.sol we have

contract B is A {...
}

then Contract B will have access to functions from contract A.

Also, from my understanding, if I want to use some functions from another contract by someone else, I would have the following in my code:

contract someoneElsesInterface {
     function someFunction() returns(something) }

contract myContract {
     someoneElsesInterface someoneElsesContract = someonElsesInterface(address);
     value = someoneElsesContract.someFunction();
}

My confusion arises when trying to implement the ERC721 standard. First, I must save the erc721.sol file in my directory; the file contains

contract ERC721 {
  event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
  event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);

  function balanceOf(address _owner) external view returns (uint256);
  function ownerOf(uint256 _tokenId) external view returns (address);
  function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
  function approve(address _approved, uint256 _tokenId) external payable;
}

And then in a separate file, I must inherit from the ERC721 contract and then define the content of the four functions balanceOf, ownerOf, transferFrom, approve; as well as emitting the Transfer and Approve events. So the following:

contract myContract is ERC721 {
     function balanceOf...
     function ownerOf...
     function transferrFrom...
     ...
}

This is what I don't understand: Why is ERC721 not inheriting from myContract, since we are defining functions in myContract and just stating the function name and returns in ERC721 like my example above? What even is the point of the ERC721 contract and having myContract inherit from ERC721, when we already defined all the function content in myContract? When working from on the front end, do I call the functions from myContract or from ERC721?

I hope my question is clear, if not I can clarify in comments. Thank you in advance for the replies.


Solution

  • First of all, you don't inherit an interface, but you implement it. In an interface contract, you don't define, you declare. You declare functionality, inputs, and outputs.

    An interface can't inherit from a concrete (actual) contract. Only interfaces can inherit each other. If you think about it, concrete contracts contain more information than interfaces, how can an interface inherit from a concrete contract?

    Generally speaking interfaces are contracts between user and program, and this is also true for Solidity. They guarantee a certain functionality to users. By implementing ERC721, you are declaring that your contract is ERC721 compatible. Because of this, the user does not need to know about your contract's implementation details, instead, they can call your contract using the ERC721 interface.

    Consider following:

    ContractA { ... }
    

    vs

    ContractB is ERC721 { ... }
    

    Let's say both contracts are implementing ERC721 functionality.

    To be able to call ContractA for ERC721 interaction, I have to import its ABI and verify that it is compatible. For example, I would call it like:

    ContractA(ADDRESS_OF_CONTRACT_A).safeTransferFrom(...)
    

    On the other hand to call ContractB, only thing I need is ERC721 ABI, I don't need to know about ContractB. So I can do:

    ERC721(ADDRESS_OF_CONTRACT_B).safeTransferFrom(...)
    

    Before I end, I would like to emphasize that your question is not actually about Solidity or smart contracts, but it is about object-oriented programming, inheritance, and interfaces. I recommend you to read about it more to have a better understanding of the concept.