Пишем смарт-контракт Ethereum — это просто: Часть 3 — визитка — address, конструктор, переменная msg

Продолжаем наши уроки по написанию смарт-контрактов. Предыдущий урок можно почитать тут, а полный список уроков тут..

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

  • переменная msg
  • конструктор контракта
  • тип address
  • исключение throw

Код нашей визитки из предыдущего урока:

Напомню — методом getData мы можем получить значение, записанное ранее на визитке. А метод setData позволял изменить значение.

После того как смарт-контракт будет создан внутри сети Ethereum он будет доступен любому человеку в сети. Это значит что любой участник сети Ethereum может выполнить как функцию getData так и функцию setData. Таким образом мы имеем опасность того что другой пользователь вызвав функцию setData изменит данные на нашей визитке. А мы бы хотели чтобы менять их мог только владелец визитки. Давайте решим эту проблему!

Внутри контракта нам доступна глобальная переменная msg. Это структура с несколькими полями. С этими полями мы будем знакомится по мере необходимости. Сейчас мы познакомимся с полем sender. Итак msg.sender  — это адрес того, кто выполняет контракт в данный момент. Того кто вызвал функцию. Тип этого поля address.

Таким образом для того чтобы запретить менять данные визитки посторонним лицам контракту достаточно проверить — является ли адрес того кто выполняет контракт в данный момент адресом владельца визитки. Т.е. если msg.sender равен адресу владельца визитки то мы выполняем setData. В противном случае сообщаем об ошибке.

И тут возникает вопрос. Как получить адрес владельца визитки? При создании контракта вызывается специальная функция — конструктор. Она имеет такое же название как и сам контракт и ничего не возвращает.

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

Поправим наш контракт:

Теперь наш контракт содержит переменную owner в которую конструктор сохраняет адрес создателя-владельца визитки. А в функции setData e у нас появилось условие:

Незнакомое нам слово throw заставляет контракт прекратить работу. В последних версиях solidity не рекомендуется использовать throw. А для проверки какого-либо условия прекращения работы функции рекомендуют использовать конструкцию require(условие). Если условие не выполняется то функция останавливается. Между способами остановки работы функции есть существенная разница, но мы ее пока рассматривать не будем. Просто перепишем наш код с require.

Давайте теперь проверим работу нашего контракта. Создайте контракт в сети Ethereum (см. урок 1). Обратите внимание на поле Account.

Поле account это адрес вашего аккаунта. Именно от его имени вы в данный момент работаете и именно от его имени был создан контракт. Если вы сейчас вызовите setData с какими либо данными (например: «email», «cromlehg@gmail.com») то данные внутри контакта успешно поменяются.

В целях тестирования Remix позволяет сменить адрес аккаунта. В выпадающем списке account выберите любой другой адрес. А теперь попробуйте вызвать setData и вы получите сообщение об ошибке — исключение. Контракт не позволил нам изменить данные потому что адрес владельца визитки другой.

Статус последней операции remix отображает в консоле.

Итак, мы в этом уроке узнали как получить адрес того кто выполняет контракт в данный момент. Узнали что такое конструктор. И что самое важное — научились ограничивать доступ к функциям контракта и тестировать!

На этом пока все. Продолжение читать тут. Предыдущий урок тут.

Если у вас возникли вопросы то можете смело писать на электронную почту (раздел «контакты«). Также приветствуется критика.

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

Полный список уроков тут.

  1. а тут есть какая то связь в том что имя контракта и имя функции одинаковые (BusinessCard)?

    • вопрос снят, возник другой вопрос, какие свойства у функции конструктора?

    • Что имеете в виду под свойствами? Модификаторы, аргументы или что?

    • ну я как понял, конструктор выполняется только один раз. Может еще у него какие особенности есть?

    • Вам лучше задавать вопросы в нашей группе в телеграмме — так будет быстрее — https://t.me/blockchainwitness .
      Конструктор это функция которая:

      • Имеет тоже имя, что и имя класса
      • Выполняется при создании контракта
      • Вызывает родительские конструкторы перед тем как выполнить свой код
  2. Ошибка в коде:
    function setData(string key, string value) public {
    require(msg.sender != owner);
    throw;
    data[keccak256(key)] = value;
    }

    Судя по тексту далее — require наверное надо поменять на if вероятно не хватает фигурных скобок, но я еще не все прочитал)))

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *