Как установить контроль доступа для смарт-контрактов

Как установить контроль доступа для смарт-контрактов

14 февраля 2023 г.

Когда кто-то пытается провести различие между Web2 и Web3, ключевой ценностью, которая различает их, является концепция собственности.

Проще говоря, то, что вы создаете, принадлежит вам и может монетизироваться. Как и должно быть. Ни меньше, ни больше. Фактически, в тот день, когда вы отчеканите свой первый NFT, вы сделаете это в Web3 как владелец благодаря неизменности блокчейна. Во всяком случае, ощущение защищенности бесценно.

Говоря об этом, эта концепция владения так же важна для смарт-контрактов в отношении доступных функций и разрешенного изменения состояния.

Ваш первый взгляд на право собственности с помощью смарт-контрактов

Итак, какое значение имеет то, что вы «владеете» написанным вами смарт-контрактом?

Подумайте об этом: если бы у вас был велосипед, вы бы не стали вести записи о владении им? На случай, если кто-то украл и использовал его в гнусных целях? Конечно, нет.

Это по той же причине, по которой вы хотели бы доказать свое право собственности на NFT или смарт-контракт. Ну, кто-то может просто получить несанкционированный доступ и извлечь из этого финансовую выгоду, верно?

Допустим, вы работаете с Dunzo и написали этот смарт-контракт, в котором вы можете установить цену пакета плюс стоимость доставки, а также указать, был ли он оплачен покупателем или нет.

Dunzo package delivery smart contract

В идеальном сценарии вы можете установить имя покупателя, общую стоимость посылки и доставки на определенную сумму и установить для setPackageDelivered значение true. Конечно, после того, как вы доставите посылку.

Но, как мы все знаем, ничто никогда не идет по плану.

Что, если бы у покупателя был доступ к функциям контракта и возможность сбросить значение packageDelivered на false или изменить значение packageDeliveryPrice на меньшее? Они могут не только платить меньше за продукт, но и вообще ничего не платить.

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

Почему так важна настройка правильного контроля доступа в смарт-контракте

Теперь давайте развернем этот смарт-контракт и посмотрим, насколько легко злоумышленник может изменить значения в переменных состояния.

Dunzo package delivery smart contract

Имея доступ к функциям setPrice и setPackageDelivered, любой может вносить изменения, которые могут привести к финансовым потерям для доставки Dunzo.

Если Дунзо установил первоначальную цену товара на уровне 5 ETH, теперь покупатель может изменить это значение на 3 ETH. Конечно, поскольку клиент также может получить доступ к функции setPackageDelivered и изменить логическое значение на false, он может получить еще одну доставку того же товара. Так что в любом случае Дунзо рискует потерять деньги и может даже не осознавать этого, пока не станет слишком поздно.

Например, предположим, что доставляемый продукт стоит 5 ETH, как показано ниже:

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

Мы даже можем изменить статус setPackageDelivered с true на false. Даже если посылка уже доставлена ​​клиенту.

Как вы можете заметить, важно различать владельца и других пользователей указанного смарт-контракта. Итак, давайте рассмотрим 4 исправления, которые настроят правильный контроль доступа для этого смарт-контракта и в результате обеспечат его безопасность.

4 способа безопасной настройки контроля доступа для вашего смарт-контракта

Итак, как можно отличить владельца от других пользователей при написании смарт-контрактов?

Очевидно, что это необходимо из-за финансовых потерь, которые могут быть понесены в случае игнорирования.

Способ 1. Используйте оператор require

Как видно из приведенного ниже кода, новый владелец переменной состояния типа адреса был добавлен вместе с оператором «require». В конструкторе переменная состояния владельца хранит адрес, который используется при развертывании контракта. Как вы знаете, конструкторы в смарт-контрактах вызываются только один раз, поэтому адрес изменить нельзя.

dunzo Delivery smart contract with ‘require’ statement

Теперь, когда вы вызываете функцию setPrice с меньшим значением и другим адресом, транзакция возвращается в исходное состояние, как в сообщении ниже:

Revert error

Как видите, причина, указанная в контракте, связана с сообщением об ошибке, которое мы добавили в оператор «require». При этом никто, кроме владельца контракта — в данном случае Дунзо — не может изменить условия продажи.

Способ 2. Используйте модификатор функции

Как ни просто добавить оператор «require» с правильным условием, модификатор представляет собой блок кода, который можно использовать многократно. Это, безусловно, имеет гораздо больше смысла, чем написание многочисленных операторов «require» для такой проверки.

В приведенном ранее коде только функция setPrice защищена оператором «require», но здесь ничего не сделано для функции setPackageDelivered. Использование модификатора должно помочь, как показано в коде Solidity ниже:

Dunzo smart contract with onlyOwner modifier

Теперь, если вы попытаетесь получить доступ к функциям setPrice или setPackageDelivered, вы получите то же сообщение об ошибке, что и ранее, как показано ниже:

Revert error

Способ 3. Принадлежность

Это исправление требует использования смарт-контракта Ownable, предоставленного OpenZeppelin. Сначала вам нужно импортировать смарт-контракт Ownable, а затем добавить модификатор onlyOwner к функциям, которые вы хотите защитить. Итак, как показано ниже, обе функции setPrice и setPackageDelivered имеют приведенный ниже модификатор onlyOwner.

Теперь, поскольку смарт-контракт dunzoDelivery будет использовать некоторые функции из Ownable.sol, к имени контракта также добавляется «принадлежит».

Using the Ownable.sol smart contract

Тем не менее, есть две другие функции, к которым можно получить доступ при использовании смарт-контракта Ownable: отказ от владения и передача владения. Хотя учетная запись, которая использовалась для развертывания контракта, обычно считается владельцем, ее можно изменить с помощью этих функций.

Помимо адреса владельца и других сведений о соглашении, вы можете увидеть функции renounceOwnership и transferOwnership для использования ниже:

Как и ожидалось, когда вы пытаетесь вызвать функцию setPrice, используя другой адрес, транзакция не пройдет. Вместо этого он возвращается в исходное состояние по следующей причине:

Revert error using Ownable

Использование смарт-контракта Ownable хорошо, если вам нужен только один владелец среди других пользователей. Если вам нужна дополнительная иерархия, следует использовать смарт-контракт AccessControl.sol.

Способ 4. Контроль доступа

Это последнее исправление требует доступа к смарт-контракту AccessControl от Open Zeppelin.

Для начала вам нужно добавить гиперссылку контроля доступа в оператор импорта, а также добавить «is AccessControl» в оператор контракта.

Как упоминалось ранее, этот смарт-контракт позволяет вам добавлять ряд ролей в иерархию, которые вы должны объявить, как в первых двух строках смарт-контракта, показанных ниже:

Using the AccessControl smart contract

В этом контракте есть две роли, а именно Dunzo и Customer. Теперь, когда вы развертываете контракт, вам нужно будет назначить вышеупомянутые объявленные роли указанным адресам, чтобы определить, кто и к чему может получить доступ. Кроме того, в функции setPrice и setPackageDelivered добавлены два оператора «require».

Как вы можете заметить, только учетная запись, которой была назначена роль Dunzo, сможет изменить условия продажи, упомянутые во время развертывания, но не какие-либо другие. Тем не менее, вы можете назначить ряд ролей с разными уровнями доступа к функциям смарт-контракта с помощью AccessControl.sol, в то время как Ownable.sol не будет вдаваться в такие подробности.

Примечание о других исправлениях контроля доступа для смарт-контрактов Ethereum

Это не единственные доступные решения для реализации контроля доступа в смарт-контрактах. RBAC.sol и WhitelistCrowdSale.sol также был доступен в прошлом. и который также может связывать роли с адресами, как AccessControl.sol и Ownable.sol.

Итак, если вы хотите получить полное представление об эволюции реализации контроля доступа, вам стоит потратить время на изучение кода этих двух смарт-контрактов.

Также опубликовано здесь

Основное изображение для этой статьи было создано с помощью генератора изображений HackerNoon AI Image Generator через приглашение «отказано в доступе к биометрическому сканированию».


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE