Ончейн-транзакции: должны ли перечисляемые структуры данных использоваться только внутри сети?

Ончейн-транзакции: должны ли перечисляемые структуры данных использоваться только внутри сети?

10 марта 2022 г.

По мере того, как время идет, все больше разработчиков Solidity загрязняют руки стандартами ERC721 и ERC1155, они начинают уделять больше внимания тому, насколько важны неизменяемость и данные в цепочке.


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


Смарт-контракты все чаще зацикливаются на элементах в цикле for во время транзакций или во время передачи. Однако перечисляемые структуры данных предназначены для обнаружения в цепочке, а не для внешнего использования. Варианты использования структур данных, таких как EnumerableSet, вытекают из его полезности, когда дело доходит до обнаружения в цепочке другими протоколами «дешевым» способом. Это означает, что другие протоколы могут легко и дешево перебирать NFT учетной записи.


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


Если мы подумаем об учетной записи, содержащей несколько NFT, и итерации, включающей пару транзакций (вспомните упомянутую нами итерацию цикла for), шансы на то, что эта функция исчерпает газ, возрастут, даже для оффчейн. читать.


Если мы вернемся к основам, даже если функция объявлена ​​как «виртуальная», это будет только функция «свободного чтения», когда элементы не передаются. Если у пользователя есть, скажем, 10 элементов, будет довольно дорого проверять список идентификаторов и просматривать каждый из идентификаторов, что увеличивает количество внешних вызовов из контракта протокола.


Как решить эту проблему


  1. Создайте функцию, которая перечисляет идентификаторы токенов учетной записи.

  1. Вызвать эту функцию вне цепочки

  1. Передайте идентификаторы токенов функции, которая в них нуждается, и подтвердите право собственности в этой функции.

```javascript


функция useTokenIds(


реестр адресов,


uint256[] токены calldata


) внешний {


адрес отправителя = msg.sender;


идентификатор токена uint256;


for (uint256 i; i < tokenIds.length; i++){


tokenId = tokenIds[i];


требовать(


IERC721(registry).ownerOf(tokenIds[i]) == отправитель,


«не владелец этих токенов»


_doSomethingWithThisTokenId(реестр, tokenId, отправитель)


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


Можно использовать TheGraph также для индексации всех элементов пользователя или даже API некоторых торговых площадок, таких как OpenSea.


EIP721 сообщает об этом прямо в EIP:


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



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