Day 13. Basic Syntax of Solidity – Inheritance/Instantiation –

In Solidity, there are two main methods to utilize the functionalities of other contracts. In this tutorial, we will explain these two methods: inheritance and instantiation.

TOC

Inheritance

Inheritance involves creating a parent-child relationship between two contracts, allowing the child to inherit functionalities from the parent. In other words, inheritance enables sharing functionalities between contracts. Through inheritance, functions and variables of the parent contract can be used in the child contract.

On Day 7, we had the following code, which uses inheritance. The line ‘MyToken is ERC20’ indicates that ‘MyToken’ inherits functionalities from ‘ERC20’ (with ERC20 being the parent and MyToken the child).

ERC20 defines various functionalities, one of which is the ‘mint’ function for issuing tokens. This function takes the address of the caller and the amount to be issued as arguments, meaning it issues tokens equivalent to the ‘initialSupply’ to the person who called the _mint function. This functionality is also available in MyToken (hence, MyToken can call the _mint function even though it’s not explicitly described in MyToken itself).

Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    constructor(string memory _name, string memory _symbol, uint256 initialSupply) ERC20(_name, _symbol) {
        _mint(msg.sender, initialSupply);
    }
}

ERC stands for Ethereum Request for Comments, a document proposing specifications for Ethereum. ERC20 sets the standard for tokens, defining basic functionalities like token transfer, balance checking, etc. Other commonly used standards include ERC721 (for NFTs) and ERC1155 (a mechanism to manage multiple types of tokens). An example implementation of ERC20 is the ERC20.sol in the openzeppelin library collection (the one imported in the above example). You can see the available functions, including the _mint function, at this link. Openzeppelin is one of the most widely used library collections.

Constructor

The “constructor” is a block that defines the initial processes to be executed when an instance is instantiated. In other words, it’s about the initial procedures when the instance is actualized (instantiation refers to when something is defined and used as a variable and becomes a physical entity).

In the mentioned example, the constructor takes three input variables (the token’s name, symbol, and issuance amount) as arguments and calls the _mint function.

* In the context of Ethereum, for instance, the name and symbol would correspond to “Ether” and “ETH”, respectively. The symbol is usually a three-letter alphabetic abbreviation.

When using a contract, you must provide the arguments defined in the constructor. Suppose you want to use the MyToken contract as a variable; in that case, you would need to pass the three variables mentioned earlier. The following code is an example of how to define a contract for use. Here, a variable of the MyToken type, as defined in the earlier example, is being declared.

In Solidity, contracts can be defined as variables in the following way: <ContractName> <VariableName> = new <ContractName>(constructor's defined arguments).

For instance:

Solidity
import "path/to/contract/MyToken.sol"; // Specify the path to MyToken.sol

contract TokenVillageToken {
  MyToken tokenVillage = new MyToken("TokenVillageToken", "TVT", 1000000000000000000);
  // Define the contract variable as <ContractName> <VariableName> = new <ContractName>(constructor's defined arguments)

  function getName() public view returns (string memory) {
    return tokenVillage.name(); // name() function from ERC20 returns the token's name
  }

  function getSymbol() public view returns (string memory) {
    return tokenVillage.symbol(); // symbol() function from ERC20 returns the token's symbol
  }
}

When the MyToken variable is defined, the constructor’s process is executed. In this case, “TokenVillageToken” is the name and “TVT” is the symbol of the token, and 1000000000000000000 units of the token are minted.

Contract Instantiation and Invocation

Instantiation

Instantiation refers to the act of generating an instance (a real entity) from a contract (a blueprint). If you want to use another contract within your own implemented contract, you first need to instantiate that contract. By instantiating it, you can access and use the functions and variables of the other contract.

The following example defines the variable newToken of the ERC20 type, which appeared in the previous example. During initialization in the constructor, the variable newToken is given the address of a token that has already been deployed. This allows the use of the already deployed contract within this contract (deployed = having an actual instance).

You can call it with the syntax <variable> = <desired contract>(contract's address).

Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract NewToken {
  ERC20 public newToken;

  constructor(address _newTokenAddress) {
      newToken = ERC20(_newTokenAddress);
  }

  function getNewTokenName() public view returns (string memory) {
      return newToken.name();
  }
}

The following image is an example of deploying the NewToken contract. In the textbox to the right of the “Deploy” button, enter the address 0xE73… of an already deployed ERC20 type contract, and then deploy it. As a result, NewToken is deployed. If you press getNewTokenName, the name of the already deployed token (TokenVillageToken) is displayed.

The following image is an example of deploying the NewToken contract. In the textbox to the right of the "Deploy" button, enter the address 0xE73... of an already deployed ERC20 type contract,

To use an analogy, instantiation in the context of a car would be like the car’s blueprint being the contract, and the car produced on the factory line being the instance. In Solidity, when you define and use a contract as a variable, you are instantiating and using it. Providing an address means calling a contract that has already been deployed (i.e., one that already has an address). ※ The term “instance” is also referred to as an “object.” These two terms are essentially synonymous.

Let's share this post !

Author of this article

After joining IBM in 2004, the author gained extensive experience in developing and maintaining distributed systems, primarily web-based, as an engineer and PM. Later, he founded his own company, designing and developing mobile applications and backend services. He is currently leading a Tech team at a venture company specializing in robo-advisory.

Comments

To comment

CAPTCHA


TOC