Сетка BlockFirst
Картинка BlockFirst
Link
Иконка копировать
Иконка скопированно

Solidity Tutorial: Everything About Constructors

This article discusses constructors in the Solidity language: how they work, why they are needed, how they are used to initialize variables, and how to apply them in the context of inheritance. It also explains the difference between constructors in older and newer versions of Solidity.

16.06.2025
Начинающий уровень
Автор BlockFirst
Share
Иконка поделиться
Link
Иконка копировать
Иконка скопировано
ARTICLE BELOW
Картинка
Превью BlockFirst

contract Animal {

uint feet;
bool canSwim;

constructor(uint _feet, bool _canSwim) {
feet = _feet;
canSwim = _canSwim;
}
}// how to derive from Animal while passing constructors arguments?
contract Lion {

}

pragma solidity 0.5.0;

contract C {
constructor() internal {}
}contract D {

function tryDeploying() public {
C c = new C();
}

}

contract Animal {

string name;
uint feet;
bool canSwim;

constructor(string memory _name, uint _feet, bool _canSwim) {
name = _name;
feet = _feet;
canSwim = _canSwim;
}
}contract Lion is Animal {

constructor(string memory _name)
Animal(_name, 4, true)
{
// ...
}
}

contract Lion is Animal(4, true) {
}

Превью BlockFirst

You cannot call external functions inside a constructor because the contract’s functions do not yet exist (the contract hasn’t been deployed). Constructors cannot be declared in interfaces.

What Not to Do (and Avoid) with Constructors!

If the constructor is non-payable, the creation code contains 8 low-level instructions (in EVM assembly) that check whether Ether was sent to the contract during deployment. If Ether was sent, the check fails and the contract deployment is reverted. If the constructor is declared as payable, these 8 instructions are absent in the EVM code.
You can see an example here: https://blog.openzeppelin.com/deconstructing-a-solidity-contract-part-ii-creation-vs-runtime-6b9d60ecb44c/

If the constructor is non-payable, the creation code contains 8 low-level instructions (in EVM assembly) that check whether Ether was sent to the contract during deployment. If Ether was sent, the check fails and the contract deployment is reverted.

If you try to send Ether when deploying a contract with a non-payable constructor, an exception will occur and the operation will revert. The difference between payable and non-payable constructors is also reflected in the contract’s creation code.

Constructors can accept Ether. In this case, they must be marked with the payable keyword. In the Remix environment, the Deploy button will change color (turn red) if the constructor accepts Ether.

Payable Constructor

Note: Specifying arguments in both places—inheritance list and the derived contract’s constructor—will cause an error.
Note 2: If the derived contract does not provide arguments for all base contracts’ constructors, it will be considered abstract.

This method is used when the base contract’s constructor arguments depend on the derived contract’s constructor arguments. To illustrate, let’s add another state variable to our Animal contract.

Through the derived contract’s constructor, acting like a “modifier”

If the base contract has arguments, derived contracts must specify all those arguments. This can be done in two ways:

Note: Before Solidity version 0.4.22, constructors were defined as functions with the same name as the contract (similar to Java?). This syntax became deprecated and is no longer allowed starting from version 0.5.0.

In Solidity, a constructor is defined using the keyword constructor(), followed by parentheses. Note that the function keyword is not required since it is a special function.

OpenZeppelin explains this idea more precisely in the second part of their article series called “Deconstructing a Solidity Contract”:

The constructor code is part of the creation code, not the runtime code.

In the case of Solidity, the code defined inside the constructor is executed only once — when the contract is created and deployed on the network. An important point to mention: the bytecode deployed on the network does not include the constructor code, since the constructor code runs only once — during contract deployment.

This method is more convenient if the constructor arguments are constants that define the contract’s behavior or describe it. A great example is creating a standard ERC20 contract.

This is useful if the values are known beforehand and can be hardcoded in the code.

Directly in the inheritance list

Earlier, we mentioned that a constructor can accept arguments, being defined with parameters just like functions. But what if contract B inherits from another contract A, which has a constructor argument? Let’s look at an example.

Answer: If a contract is not intended to be created directly but only to be inherited, it’s safer to use an internal constructor (i.e., define the contract as abstract! 😉). This prevents the contract from being deployed directly.
An internal constructor / abstract contract allows the child contract that inherits from it to set some default deployment logic (specific to the abstract contract). This deployment logic can be dynamic if the constructor has parameters.
  1. The next part of our article will be dedicated to this topic.

Continuing the topic of constructor visibility differences, the question arises: If a contract is meant for inheritance, should its constructor be defined as internal or public? (i.e., should the contract be abstract or not?)

A final note on “internal constructors” (i.e., abstract contracts)

If you’re writing contracts with Solidity compiler version above 0.7.0, you no longer need to worry about constructors being internal. In fact, all you need to do is:
  • remove the internal keyword from the constructor, and
  • define your contract as abstract (abstract).

Constructor Parameters and Inheritance

Starting from Solidity 0.7.0

Similarly, contracts with internal constructors cannot be instantiated directly inside other contracts. The code snippet below will not compile.

Before Solidity version 0.7.0, contract constructors could have one of two visibility modifiers: public (default) or internal. The main difference is simple: a contract with a constructor defined as internal cannot be deployed. That is, if a contract’s constructor has internal visibility, you won’t be able to deploy that contract at all—
  • Neither directly,
  • Nor through another contract.

Before Solidity version 0.7.0

Similar to class creation in other programming languages, if a contract does not specify a constructor, a default constructor is used — an empty one, equivalent to constructor() {}.

Constructors are optional

Constructors are a common concept in object-oriented programming (OOP). In many programming languages, when defining classes, you can also define a "magic" method that runs once — at the moment a new instance of the object is created.

How to define a constructor in Solidity?

Introduction

This article is dedicated to constructors — functions in Solidity that execute only once, when the contract is deployed on the Ethereum network.

contract Example { constructor() {
// code running when contract deployed...
}}

Share
Иконка поделиться
Link
Иконка копировать
Иконка скопированно
Back to blog
Кнопка назад
Original article
кнопка вперед
Share
Иконка поделиться
Link
Иконка копировать
Иконка скопировано
Назад в блог
Кнопка назад
Оригинал статьи
кнопка вперед
сетка BlockFirst
сетка BlockFirst
сетка BlockFirst

For requests from users

hello@blockfirst.io

Icon mail

For business inquiries

business@blockfirst.io

Icon mail

Telegram for quick replies

Icon mail

company

Community

media

By signing up for the newsletter, you can be sure we won't spam you :)

News. Specials. Announcements

To top
© 2025-2026 BlockFirst. All rights reserved.
Сетка BlockFirst
hello@blockfirst.io
For commercial offers
Company
Telegram bot for quick replies
Кнопка копировать
Скопировано