Remix, первый контракт и деплой

Самый быстрый способ запустить смарт-контракт — браузерная IDE Remix, без установки чего-либо.
«Hello, World» в Solidity — это не вывод в консоль, а переменная состояния, которую читает весь мир.

Remix — официальная браузерная среда для Solidity. В ней есть редактор, компилятор и встроенная тестовая сеть (Remix VM), где можно деплоить контракты без реальных денег. Это идеальная песочница для обучения: ничего ставить не нужно, всё работает в браузере.

Анатомия файла Solidity

Любой файл начинается с двух вещей: комментария с лицензией и директивы pragma, которая фиксирует версию компилятора.

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

contract Counter {
    // переменная состояния — живёт в storage
    uint256 public count;

    // функция, меняющая состояние
    function increment() public {
        count += 1; // в 0.8.x переполнение автоматически откатывается
    }

    // функция только для чтения — не тратит газ при вызове извне
    function get() public view returns (uint256) {
        return count;
    }
}

Разберём по частям. SPDX-License-Identifier — стандартный способ указать лицензию; компилятор предупредит, если её нет. pragma solidity ^0.8.24 говорит: «компилируй версией 0.8.24 или новее в пределах 0.8». Ключевое слово contract похоже на class в других языках. public у переменной автоматически создаёт геттер.

Цикл разработки в Remix

   ПИШЕШЬ КОД          КОМПИЛЯЦИЯ            ДЕПЛОЙ
   ==========         ===========          ========
   Counter.sol  ->  solc -> байт-код  ->  Remix VM
                    + ABI                  (тест-сеть)
                                              |
                                              v
                                       адрес контракта
                                              |
                          вызовы функций <-----+-----> чтение public
                          (тратят газ)               (бесплатно)

Как работает под капотом (EVM/газ)

Компилятор solc выдаёт две вещи: байт-код (то, что попадёт в блокчейн) и ABI — JSON-описание функций, по которому кошельки знают, как формировать вызовы. При деплое исполняется специальный конструкторный байт-код, который записывает в блокчейн runtime-код контракта. Деплой — самая дорогая операция, потому что вы платите за хранение всего кода. Вызов view-функции снаружи (через eth_call) газ не тратит, потому что не меняет состояние и не попадает в блок.

# Та же логика на Python: контракт как объект с состоянием
class Counter:
    def __init__(self):
        self.count = 0        # storage
    def increment(self):
        self.count += 1       # меняет состояние -> нужна транзакция
    def get(self):
        return self.count     # только чтение -> бесплатно

c = Counter()
c.increment()
c.increment()
print("count =", c.get())  # 2

«Та же логика на Python ▶». Питон-класс — хорошая ментальная модель контракта: поля это storage, методы — функции, но в Ethereum каждый вызов меняющего метода стоит газ.

Частые ошибки

  • Забыть pragma или указать несовместимую версию — компилятор не соберёт файл.
  • Деплоить на реальную сеть вместо Remix VM и потерять реальный ETH на тестах.
  • Ожидать, что view-функция изменит состояние — она физически не может писать в storage.

Best practices

  • Для продакшена фиксируйте точную версию (pragma solidity 0.8.24; без каретки), чтобы код собрался ровно тем компилятором, на котором его тестировали и аудитировали.
  • Всегда добавляйте SPDX-лицензию — это требование хорошего тона и часть верификации в эксплорерах.
  • Помечайте функции, которые ничего не меняют, как view или pure — это и документация, и защита от случайной записи.

Итоги

В Remix вы пишете, компилируете в байт-код и ABI, деплоите в тест-сеть и вызываете функции. Файл всегда начинается с лицензии и pragma. Дальше глубже разберём, какие типы данных есть в Solidity.

Проверьте себя
1. Что делает директива pragma solidity ^0.8.24;?
AИмпортирует библиотеку OpenZeppelin
BФиксирует диапазон версий компилятора (0.8.24 и новее в пределах 0.8)
CВключает оптимизатор газа
DДеплоит контракт в основную сеть
2. Почему вызов view-функции снаружи не тратит газ?
AПотому что она помечена public
BПотому что она не меняет состояние и выполняется через eth_call без включения в блок
CПотому что компилятор её удаляет
DГаз тратится всегда, утверждение неверно