Пишем смарт-контракт Ethereum — это просто: Часть 4 — визитка — наследование и модификаторы

В нашем четвертом уроке мы познакомимся с последними темами перед тем как приступить к написанию нашей собственной монеты!   Темы этого урока — наследование и модификаторы.

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

Представьте что вам потребовалось сменить адрес кошелька. Тогда вам придется и поменять адрес владельца визитки. А для этого нам потребуется дописать одну функцию. И чтобы ее не мог вызвать кто попало мы вначале ее кода сделаем проверку на адрес владельца.

Теперь весь код нашей визитки выглядит так:

У нас уже есть две функции, которые содержат одинаковый код проверки владельца. Сейчас у нас контракт довольно простой. Но на практике контракты значительно больше. Поэтому, возможно, в дальнейшем у нас будет больше функций с проверкой владельца. Чтобы каждый раз не писать эту проверку проще было бы вынести этот код куда-нибудь в одно место. Для этого используют модификаторы.

Чтобы к функции применить модификатор нужно после скобок поставить имя модификатора

Если в заголовке функции стоит модификатор, то функция выполняется внутри кода модификатора на месте где стоит символ «_».

Посмотрим как использовать модификатор на примере нашей визитки:

Мы видим что из функций setData и transferOwnership исчезла проверка на владельца. Но в заголовке у них появилось имя модификатора onlyOwner. Давайте посмотрим на код onlyOwner.

Он у нас состоит из двух строк. В первой проверяется является ли исполнитель владельцем. Если не является, то мы выйдем из функции. А если является то будет исполнена вторая строчка, в которой вместо магического символа «_» будет исполнен код функции которая сейчас выполняется с нашим модификатором.

Теперь, если нам потребуется написать функцию, которая может быть исполнена только владельцем контракта, то нам достаточно добавить onlyOwner к ее заголовку как это сделано в setData и tranferOwnership.

В пределах одного контракта мы решили проблему дублирования кода. А теперь представьте что у нас несколько контрактов. У всех у них есть функции с проверкой на владельца. Получается что в каждом контракте придется писать код модификатора. А хотелось бы опять же вынести весь дублирующий код в одно место. Тут нам на помощь приходит наследование.

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

Контракт A наследуется от контрактов B, C и D.

Рассмотрим на примере нашей визитки. Вынесем код, который отвечает за проверку владельца в контракт Ownable  и унаследуем от него нашу визитку.

Как видите код нашей визитки значительно упростился, а в заголовке появилось «is Ownable». Если вы заметили, то в коде визитке сейчас отсутствует конструктор. Его мы убрали потому как он содержал код сохранения владельца визитки. Этот код мы перенесли в Ownable. Стоит отметить что если и в контракте наследнике и в контракте предке есть конструктор, то сначала будет исполнен конструктор предка, а потом наследника. Т.е. в нашем случае сначала Ownable а потом BuisnessCard.

Теперь если у нас появятся другие контракты, которые требуют проверки доступа, то нам достаточно наследоваться от Ownable в котором мы уже написали все необходимое. Шаблон наследования от Ownable очень распространенная практика в написании смарт-контрактов.

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

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

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

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

  1. А не перепутано ли местонахождение «_», в псевдокоде модификатора и функции для него?
    modifier имя_модификатора() {
    код_модификаторы
    }
    function имя_функции() имя_модификатора {

    _;

    }
    Судя по дальнейшему описанию перепутано, а иначе какой смысл несет «_» в теле функции?

  2. И чтобы ее не !могу! вызвать кто попало мы вначале ее кода сделаем проверку на адрес владельца.

    • Чтобы к функции применить модификатор нужно !в после! скобок поставить имя модификатора

  3. modifier onlyOwner() public {
    require(msg.sender == owner);
    _;
    }
    Вот тут слово public вызывает ошибку компилятора в Remix
    (последний вариант визитки в этом уроке)
    если убираю то все норм.

    • в спецификации языка для модификаторов не указаны дополнительные модификаторы типа public, видимо у автора опечатка

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

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