Начинаем с основ · урок 9

Чтение и изменение состояния

Разберитесь, почему чтение данных smart contract и изменение его состояния работают по-разному.

В прошлом уроке мы развернули smart contract и получили его blockchain-адрес.

Теперь с контрактом можно взаимодействовать.

Но взаимодействия бывают двух принципиально разных типов:

прочитать существующие данные

и

изменить состояние блокчейна

Это различие будет встречаться практически во всём Solidity.

Что такое состояние контракта

Состояние — это данные, которые контракт хранит в блокчейне.

Например:

text
1guildScore = 100
2members = 12
3paused = false

После успешной транзакции эти значения могут измениться и сохраниться для следующих вызовов.

Чтение: узнать текущее значение

Иногда пользователю нужно только узнать текущее значение.

Например: какой сейчас guildScore?

Такой запрос ничего не меняет:

1До:
2guildScore = 100
3
4Читаем значение
5
6После:
7guildScore = 100

Мы просто получили уже существующие данные.

Через приложение такие запросы обычно можно выполнить без отправки пользовательской транзакции.

Упрощённо:

1Приложение
2 ↓
3Запрос на чтение
4 ↓
5Blockchain node
6 ↓
7Текущее значение

Поскольку состояние не изменяется, новую запись в блокчейн создавать не требуется.

Изменение: сохранить новое значение

Теперь представим другое действие: увеличить guildScore на 10.

До:

1guildScore = 100

После успешного выполнения:

1guildScore = 110

Это уже изменение общего состояния блокчейна.

Поэтому требуется транзакция:

1Пользователь
2 ↓
3Подписывает транзакцию
4 ↓
5Сеть выполняет код
6 ↓
7Состояние изменяется

Такое действие может потребовать gas и должно быть подтверждено сетью.

Блокчейн хранит общее состояние, с которым должны согласиться участники сети.

Если мы только спрашиваем: какое значение уже хранится? — ничего нового сохранять не нужно.

Но если мы говорим: измени значение со 100 на 110 — сеть должна выполнить операцию и зафиксировать новое состояние.

Поэтому:

1Чтение → получить существующие данные
2
3Изменение → выполнить транзакцию и сохранить новое состояние

Пример с guildScore

Представим smart contract с числом:

solidity
1uint256 public guildScore = 100;

Пользователь может захотеть просто узнать:

1guildScore?

Ответ:

1100

Состояние не изменилось.

Но если контракт предоставляет действие:

1addScore(10)

то после успешной транзакции значение может стать:

1110

Теперь состояние изменилось.

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

Blockchain node может выполнить функцию локально, чтобы вычислить ответ.

Разница в другом: результат такого чтения не записывает новое состояние в блокчейн.

Функции чтения и изменения

Позже в Solidity вы встретите функции с ключевыми словами view и pure.

Они связаны с операциями, которые не изменяют состояние. Пока запоминать точные правила не нужно.

Если функция меняет state variable, например:

solidity
1members = members + 1;

результат должен стать частью общего состояния. Поэтому пользователь отправляет транзакцию.

Она:

  1. 1.подписывается;
  2. 2.отправляется в сеть;
  3. 3.выполняется;
  4. 4.может использовать gas;
  5. 5.после успеха изменяет состояние.

Запомните простое правило:

Хочу узнать → чтение.

Хочу изменить → транзакция.

Например:

1Узнать баланс → чтение
2Узнать guildScore → чтение
3Посмотреть owner → чтение
4
5Изменить guildScore → транзакция
6Зарегистрировать участника → транзакция
7Отправить ETH → транзакция

Как это выглядит в dApp

В dApp это может выглядеть очень по-разному.

Кнопка «Показать мой баланс» может сразу получить данные.

А действие «Join Guild» может открыть кошелёк и попросить подтвердить транзакцию.

Поэтому некоторые кнопки blockchain-приложения работают мгновенно, а другие вызывают MetaMask или другой кошелёк.

В основном курсе вы будете создавать и те, и другие функции.

Одни будут только возвращать данные. Другие будут изменять состояние контракта.

Например:

solidity
1function getScore() public view returns (uint256) {
2 return guildScore;
3}

только читает состояние.

А функция вида:

solidity
1function increaseScore() public {
2 guildScore += 1;
3}

изменяет его.

Пока не нужно запоминать синтаксис. Главное — понять разницу между двумя действиями.

Чтение получает уже существующие данные и не сохраняет новое состояние.

Изменение состояния требует blockchain-транзакции.

Именно поэтому чтение и запись в smart contracts имеют разную стоимость и разный пользовательский flow.

Задание

Разделите чтение и изменение состояния.

Расположите действия в правильной последовательности для изменения состояния smart contract.

Один из блоков относится только к чтению данных и не должен входить в этот путь.

Схема

Расположите действия для изменения состояния smart contract. Один блок относится только к чтению.

Добавьте первый блок
Доступные блоки

Войдите, чтобы сохранить прохождение.