Русский
English
RU
Сетка BlockFirst
Картинка BlockFirst
Ссылка
Иконка копировать
Иконка скопированно

Учебник по Solidity: всё о конструкторах

В этой статье рассматриваются конструкторы в языке Solidity: как они работают, зачем нужны, как используются для инициализации переменных и как их применять в контексте наследования. Также объясняется разница между конструкторами в старых и новых версиях Solidity.

16.06.2025
Перевод
Начинающий уровень
Автор BlockFirst
Поделиться
Иконка поделиться
Ссылка
Иконка копировать
Иконка скопировано
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

Вы не можете вызывать внешние функции внутри конструктора, потому что функции контракта ещё не существуют (контракт ещё не развернут). Конструкторы не могут быть объявлены в интерфейсе.

Чего нельзя и не стоит делать с конструкторами!

Если конструктор неплатёПример можно посмотреть здесь: https://blog.openzeppelin.com/deconstructing-a-solidity-contract-part-ii-creation-vs-runtime-6b9d60ecb44c/ жеспособный, код создания содержит 8 низкоуровневых инструкций (в ассемблере EVM), которые проверяют, был ли отправлен эфир на контракт после его развертывания. Если эфир был отправлен, проверка не проходит, и контракт откатывается. Если конструктор объявлен как payable, эти 8 инструкций в EVM отсутствуют.

Если конструктор неплатёжеспособный, код создания содержит 8 низкоуровневых инструкций (в ассемблере EVM), которые проверяют, был ли отправлен эфир на контракт после его развертывания. Если эфир был отправлен, проверка не проходит, и контракт откатывается.

Если при развертывании контракта с неплатёжеспособным конструктором попытаться отправить эфир, возникнет исключение, и операция откатится (revert). Различие между платёжеспособным и неплатёжеспособным конструктором отражается и в коде создания контракта.

Конструкторы могут принимать эфиры. В этом случае они должны быть помечены ключевым словом payable. В среде Remix кнопка Deploy изменит цвет (будет красной), если конструктор принимает эфир.

Платёжеспособный (payable) конструктор

Примечание: указание аргументов одновременно в двух местах (в списке наследования и в конструкторе производного контракта) приведёт к ошибке. Примечание 2: если производный контракт не укажет аргументы для всех конструкторов своих базовых контрактов, он будет считаться абстрактным.

Этот способ используется, если аргументы конструктора базового контракта зависят от аргументов конструктора производного контракта. Для иллюстрации давайте добавим ещё одну переменную состояния в наш контракт Animal.

Через конструктор производного контракта, как «модификатор»

Если базовый контракт имеет аргументы, производные контракты должны указать все эти аргументы. Это можно сделать двумя способами:

Примечание: До версии 0.4.22 в Solidity конструкторы определялись как функции с тем же именем, что и у контракта (похоже на Java?). Этот синтаксис был устаревшим и больше не допускается начиная с версии 0.5.0.

В Solidity конструктор определяется с помощью ключевого слова constructor(), за которым следуют круглые скобки. Обратите внимание, что использовать ключевое слово function не требуется, так как это специальная функция.

OpenZeppelin более точно объясняет эту идею во второй части своей серии статей под названием «Деконструкция контракта на Solidity»:

Код конструктора является частью кода создания (creation code), а не частью кода выполнения (runtime code).

В случае с Solidity код, определённый внутри конструктора, будет выполнен только один раз — при создании и развертывании контракта в сети.
Важный момент, который стоит упомянуть: Байткод, развернутый в сети, не содержит кода конструктора, поскольку код конструктора выполняется только один раз — при развертывании контракта.

Этот способ удобнее, если аргументы конструктора являются константами и определяют поведение контракта или описывают его. Отличным примером является создание стандартного контракта ERC20.

Это полезно, если значения известны заранее и могут быть захардкожены в коде.

Напрямую в списке наследования

Ранее мы уже упоминали, что конструктор может принимать аргументы, определяясь с параметрами, как и функции. Но что если контракт B наследуется от другого контракта A, у которого есть аргумент конструктора? Давайте рассмотрим это на примере.

Ответ: если контракт не предназначен для непосредственного создания, а должен лишь наследоваться, безопаснее использовать internal конструктор (= определить контракт как абстрактный! 😉). Это предотвратит прямое создание контракта.
  1. Internal конструктор / абстрактный контракт позволяет дочернему контракту, который от него наследуется, задать некоторую логику по умолчанию при развертывании (специфичную для абстрактного контракта). Эта логика развертывания может быть динамической, если объявить конструктор с параметрами. Именно этой теме будет посвящена следующая часть нашей статьи.

Продолжая тему различий в видимости конструкторов, возникает вопрос: Если контракт предназначен для наследования, должен ли конструктор быть определён как internal или public? (= контракт должен быть абстрактным или нет?)

Заключительное замечание по «internal конструкторам» (= абстрактным контрактам)

Если вы пишете контракты с компилятором Solidity версии выше 0.7.0, вам больше не нужно беспокоиться о конструкторах с internal. На самом деле, вам нужно всего лишь:
  1. убрать ключевое слово internal из конструктора, и
  2. определить ваш контракт как абстрактный (abstract).

Параметры конструкторов и наследование

Начиная с Solidity 0.7.0

Аналогично, контракты с конструкторами internal не могут быть созданы напрямую внутри других контрактов. Приведённый ниже фрагмент кода не скомпилируется.

До версии Solidity 0.7.0 конструкторы контрактов могли иметь одну из двух модификаторов видимости: public (по умолчанию) или internal. Основное различие между ними простое: Контракт с конструктором, определённым как internal, не может быть развернут. То есть, если конструктор у контракта имеет видимость internal, вы не сможете развернуть такой контракт вообще:
  • Ни напрямую,
  • Ни через другой контракт.

До версии Solidity 0.7.0

Аналогично созданию класса в других языках программирования. Если в контракте не указан конструктор, будет использоваться конструктор по умолчанию — пустой, эквивалентный constructor() {}.

Конструкторы являются необязательными

Конструкторы — это распространённое понятие в объектно-ориентированном программировании (ООП). Во многих языках программирования при определении классов можно также определить «магический» метод, который будет выполняться один раз — в момент создания нового экземпляра объекта.

Как определить конструктор в Solidity?

Введение

Эта статья посвящена конструкторам — функциям в Solidity, которые выполняются только один раз, при развертывании контракта в сети Ethereum.

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

(Перевод)
Виталий Дорожко
Автор
Поделиться
Иконка поделиться
Ссылка
Иконка копировать
Иконка скопированно
Назад в блог
Кнопка назад
Оригинал статьи
кнопка вперед
Поделиться
Иконка поделиться
Ссылка
Иконка копировать
Иконка скопировано
Назад в блог
Кнопка назад
Оригинал статьи
кнопка вперед
сетка BlockFirst
сетка BlockFirst
сетка BlockFirst

Для запросов от пользователей

hello@blockfirst.io

Icon mail

Для бизнес запросов

business@blockfirst.io

Icon mail

Телеграм для быстрых ответов

Icon mail

компания

Сообщество

медиа

Подписываясь на рассылку, вы можете быть уверены, что мы не будем спамить Вам :)

Новости. Скидки. Анонсы

В начало
© 2025-2026 BlockFirst. Все права защищены.
Сетка BlockFirst
hello@blockfirst.io
Для коммерческих предложений
Компания
Телеграм для быстрых ответов
Кнопка копировать
Скопировано