Перейти до основного вмісту
Change page

Анатомія смарт-контрактів

Смарт-контракт — це програма, яка працює за певною адресою в мережі Етеріум. Вони складаються з даних і функцій, які можуть виконуватися після отримання транзакції. Ось огляд того, з чого складається смарт-контракт.

Передумови

Спочатку переконайтеся, що ви прочитали про смарт-контракти. Цей документ передбачає, що ви вже знайомі з такими мовами програмування, як JavaScript або Python.

Дані

Будь-які дані контракту мають бути призначені до певного місця: до storage або memory. Змінювати сховище в смарт-контракті дорого, тому вам потрібно ретельно обміркувати, де мають зберігатися ваші дані.

Сховище

Постійні дані називаються сховищем і представлені змінними стану. Ці значення зберігаються в блокчейні назавжди. Вам потрібно оголосити тип, щоб під час компіляції контракт міг відстежувати, скільки місця в сховищі блокчейну йому потрібно.

// Приклад Solidity
contract SimpleStorage {
    uint storedData; // Змінна стану
    // ...
}
# Приклад Vyper
storedData: int128

Якщо ви вже програмували об'єктно-орієнтованими мовами, ви, ймовірно, знайомі з більшістю типів. Однак тип address буде для вас новим, якщо ви новачок у розробці для Етеріуму.

Тип address може містити адресу Етеріуму, яка дорівнює 20 байтам або 160 бітам. Вона повертається в шістнадцятковому форматі з префіксом 0x.

Інші типи включають:

  • логічні значення (boolean)
  • цілі числа (integer)
  • числа з фіксованою комою
  • масиви байтів фіксованого розміру
  • масиви байтів динамічного розміру
  • раціональні та цілочисельні літерали
  • рядкові літерали
  • шістнадцяткові літерали
  • перелічення (enums)

Для детальнішого пояснення перегляньте документацію:

Пам'ять

Значення, які зберігаються лише протягом часу виконання функції контракту, називаються змінними пам'яті. Оскільки вони не зберігаються в блокчейні назавжди, їх використання обходиться значно дешевше.

Дізнайтеся більше про те, як віртуальна машина Етеріуму (EVM) зберігає дані (сховище, пам'ять і стек), у документації Solidity (opens in a new tab).

Змінні середовища

Окрім змінних, які ви визначаєте у своєму контракті, існують спеціальні глобальні змінні. Вони переважно використовуються для надання інформації про блокчейн або поточну транзакцію.

Приклади:

ВластивістьЗмінна стануОпис
block.timestampuint256Часова мітка епохи поточного блоку
msg.senderaddressВідправник повідомлення (поточного виклику)

Функції

Найпростіше кажучи, функції можуть отримувати або встановлювати інформацію у відповідь на вхідні транзакції.

Існує два типи викликів функцій:

  • internal — вони не створюють виклик EVM
    • Внутрішні функції та змінні стану доступні лише внутрішньо (тобто з поточного контракту або контрактів, що успадковуються від нього)
  • external — вони створюють виклик EVM
    • Зовнішні функції є частиною інтерфейсу контракту, що означає, що їх можна викликати з інших контрактів та через транзакції. Зовнішню функцію f не можна викликати внутрішньо (тобто f() не працює, але this.f() працює).

Вони також можуть бути public або private

  • Функції public можна викликати внутрішньо з самого контракту або зовні через повідомлення
  • Функції private видимі лише для контракту, в якому вони визначені, і не видимі в похідних контрактах

Як функції, так і змінні стану можуть бути публічними (public) або приватними (private)

Ось функція для оновлення змінної стану в контракті:

// Приклад Solidity
function update_name(string value) public {
    dapp_name = value;
}
  • Параметр value типу string передається у функцію: update_name
  • Вона оголошена як public, що означає, що будь-хто може отримати до неї доступ
  • Вона не оголошена як view, тому може змінювати стан контракту

Функції перегляду

Ці функції гарантують, що не змінюватимуть стан даних контракту. Поширеними прикладами є функції-геттери (getter) — ви можете використовувати їх, наприклад, для отримання балансу користувача.

// Приклад Solidity
function balanceOf(address _owner) public view returns (uint256 _balance) {
    return ownerPizzaCount[_owner];
}
dappName: public(string)

@view
@public
def readName() -> string:
  return dappName

Що вважається зміною стану:

  1. Запис у змінні стану.
  2. Генерування подій (opens in a new tab).
  3. Створення інших контрактів (opens in a new tab).
  4. Використання selfdestruct.
  5. Відправлення етеру через виклики.
  6. Виклик будь-якої функції, не позначеної як view або pure.
  7. Використання низькорівневих викликів.
  8. Використання вбудованого асемблера, який містить певні коди операцій (opcodes).

Функції-конструктори

Функції constructor виконуються лише один раз під час першого розгортання контракту. Як і constructor у багатьох об'єктно-орієнтованих мовах програмування, ці функції часто ініціалізують змінні стану їхніми заданими значеннями.

# Приклад Vyper

@external
def __init__(_beneficiary: address, _bidding_time: uint256):
    self.beneficiary = _beneficiary
    self.auctionStart = block.timestamp
    self.auctionEnd = self.auctionStart + _bidding_time

Вбудовані функції

Окрім змінних і функцій, які ви визначаєте у своєму контракті, існують спеціальні вбудовані функції. Найочевидніший приклад:

  • address.send() — Solidity
  • send(address) — Vyper

Вони дозволяють контрактам надсилати ETH на інші акаунти.

Написання функцій

Вашій функції потрібні:

  • змінна параметра та тип (якщо вона приймає параметри)
  • оголошення internal/external
  • оголошення pure/view/payable
  • тип повернення (якщо вона повертає значення)

Повний контракт може виглядати приблизно так. Тут функція constructor надає початкове значення для змінної dapp_name.

Події та логи

Події дозволяють вашому смарт-контракту взаємодіяти з фронтендом або іншими програмами, що підписані на них. Щойно транзакція перевіряється та додається в блок, смарт-контракти можуть генерувати події та логувати інформацію, яку фронтенд потім може обробляти та використовувати.

Приклади з анотаціями

Ось кілька прикладів, написаних мовою Solidity. Якщо ви хочете поекспериментувати з кодом, ви можете взаємодіяти з ними в Remix (opens in a new tab).

Hello world

Токен

Унікальний цифровий актив

Додаткові матеріали

Перегляньте документацію Solidity та Vyper для повнішого огляду смарт-контрактів: