Добро пожаловать в главу 4.
В этой главе мы будем постепенно создавать более сложную логику для нашего исследования смарт-контракта, понимать его и писать локальные тесты с помощью TypeScript.
Полученный код главы 4 доступен в this repository.
Давайте вернемся к кодексу контракта, который мы запрограммировали в предыдущей главе. Мы продолжим строительство в дополнение к этому контракту.
Позвольте мне подробнее рассказать о нашем плане во время этого урока. Мы собираемся переписать наш контракт, чтобы он был следующей логикой:
Он получит сообщение с определенной командой (команды должны быть указаны для определения того, какая часть функциональности нашего контракта должна быть выполнена в соответствии с данными, полученными в сообщении)
На основе этой конкретной команды она увеличивает количество, которое хранится в нашем хранилище c4.
Он предоставляет метод геттера, который возвращает текущее значение счетчика и адрес, который отправил сообщение с кодом операции приращения.
Мы уже знакомы с концепциями методов хранения и получения данных, поэтому это не будет проблемой, а скорее хорошей практикой для наших навыков.
Тем не менее, концепция команд является новой. Команды также называются операционными кодами или, вкратце, операционными кодами. Операционные коды обычно хранятся в самом начале среза in_msg_body, который передается в функцию recv_internal. Операционный код - это просто целое число, которое мы используем для указания определенного логического блока. Это стандарт, но операционные коды не появляются там - вы должны передать их, как только вы составляете сообщение, прежде чем отправить его.
Важно отметить, что когда мы читаем данные, мы должны делать это в том же порядке, в котором мы их там написали. Чтобы убедиться, что get_data() работает должным образом при первом запуске, мы вернемся к концепции исходных данных, поэтому мы храним определенное значение в хранилище c4 с самого момента развертывания контракта.
Операционный код
Как я уже упоминал ранее, мы поместим код операции в самом начале in_msg_body, так что давайте напишем код, который будет читать его оттуда:
В FunC для некоторых переменных мы должны указать количество битов, которые выделяются в памяти для хранения переменных. Вот почему мы должны установить 32 в методе ~load_uint(32), это означает, что это целое число будет иметь максимальный размер 32 бита.
Код операции, который мы будем использовать для приукременения значения счетчика, будет 1. Так просто. Давайте завернем нашу логику в оператор if, который проверяет, что код операции равен 1:
Логика счетчика
Наша локальная структура хранения будет следующей:
- Counter_value - целое число
- Sender_address - срез, адрес кошелька, который отправил команду increment в последний раз
В нашей функции recv_internal мы предполагаем, что в локальном хранилище уже хранятся эти данные, поэтому мы просто читаем их. Нам не нужно читать предыдущего последнего отправителя, потому что, когда мы сохраняем значения обратно в хранилище - мы уже собираемся использовать новое значение для этого - sender_address текущего сообщения.
Как только мы получим значение счетчика, мы хотим увеличить его. Последним шагом будет просто сохранение данных в том же порядке, в котором мы их читаем:
Вы можете заметить, что теперь, когда мы возвращаем более одного значения, мы также обертываем ожидаемый результат в определение функции в круглые скобки, а также возвращаемый результат.
Давайте посмотрим, как выглядит наш окончательный код:
Вы можете просто проверить, правильно ли компилируется наш контракт, запустив yarn compile.
На следующем уроке мы собираемся обновить наши тесты для смарт-контракта, чтобы это помогло нам в проверке поведения контракта.