Стандарт мульти-токенов ERC-1155
Введение
Стандартный интерфейс для контрактов, управляющих несколькими типами токенов. Один развернутый контракт может включать любую комбинацию взаимозаменяемых токенов, невзаимозаменяемых токенов или других конфигураций (например, полувзаимозаменяемых токенов).
Что подразумевается под стандартом мульти-токенов?
Идея проста и заключается в создании интерфейса смарт-контракта, который может представлять и контролировать любое количество типов взаимозаменяемых и невзаимозаменяемых токенов. Таким образом, токен ERC-1155 может выполнять те же функции, что и токены ERC-20 и ERC-721, и даже обоих одновременно. Он улучшает функциональность стандартов ERC-20 и ERC-721, делая ее более эффективной и исправляя очевидные ошибки реализации.
Токен ERC-1155 полностью описан в EIP-1155 (opens in a new tab).
Предварительные требования
Для лучшего понимания этой страницы мы рекомендуем сначала прочитать о стандартах токенов, ERC-20 и ERC-721.
Функции и особенности ERC-1155:
- Пакетный перевод: перевод нескольких активов за один вызов.
- Пакетный баланс: получение балансов нескольких активов за один вызов.
- Пакетное одобрение: одобрить все токены для адреса.
- Хуки: хук получения токенов.
- Поддержка NFT: если предложение равно 1, токен рассматривается как NFT.
- Правила безопасного перевода: набор правил для безопасного перевода.
Пакетные переводы
Пакетный перевод работает очень похоже на обычные переводы ERC-20. Давайте посмотрим на обычную функцию transferFrom в ERC-20:
// ERC-20
function transferFrom(address from, address to, uint256 value) external returns (bool);
// ERC-1155
function safeBatchTransferFrom(
address _from,
address _to,
uint256[] calldata _ids,
uint256[] calldata _values,
bytes calldata _data
) external;
Единственное отличие в ERC-1155 заключается в том, что мы передаем значения в виде массива, а также передаем массив идентификаторов (id). Например, при заданных ids=[3, 6, 13] и values=[100, 200, 5] в результате будут выполнены следующие переводы:
- Перевод 100 токенов с id 3 от
_fromк_to. - Перевод 200 токенов с id 6 от
_fromк_to. - Перевод 5 токенов с id 13 от
_fromк_to.
В ERC-1155 у нас есть только transferFrom, но нет transfer. Чтобы использовать ее как обычную transfer, просто установите в качестве адреса отправителя (from) адрес, вызывающий функцию.
Пакетный баланс
Соответствующий вызов balanceOf в ERC-20 также имеет свою партнерскую функцию с поддержкой пакетной обработки. Напомним, что это версия ERC-20:
// ERC-20
function balanceOf(address owner) external view returns (uint256);
// ERC-1155
function balanceOfBatch(
address[] calldata _owners,
uint256[] calldata _ids
) external view returns (uint256[] memory);
Еще проще с вызовом баланса: мы можем получить несколько балансов за один вызов. Мы передаем массив владельцев, за которым следует массив идентификаторов токенов.
Например, при заданных _ids=[3, 6, 13] и _owners=[0xbeef..., 0x1337..., 0x1111...] возвращаемое значение будет следующим:
[
balanceOf(0xbeef...),
balanceOf(0x1337...),
balanceOf(0x1111...)
]
Пакетное одобрение
// ERC-1155
function setApprovalForAll(
address _operator,
bool _approved
) external;
function isApprovedForAll(
address _owner,
address _operator
) external view returns (bool);
Одобрения немного отличаются от ERC-20. Вместо того чтобы одобрить конкретные суммы, вы устанавливаете оператора как одобренного или неодобренного с помощью setApprovalForAll.
Чтение текущего статуса можно выполнить с помощью isApprovedForAll. Как видите, это операция по принципу «все или ничего». Вы не можете определить, сколько токенов одобрить или даже какой класс токенов.
Это намеренно разработано с учетом простоты. Вы можете одобрить только все для одного адреса.
Хук получения
function onERC1155BatchReceived(
address _operator,
address _from,
uint256[] calldata _ids,
uint256[] calldata _values,
bytes calldata _data
) external returns(bytes4);
Учитывая поддержку EIP-165 (opens in a new tab), ERC-1155 поддерживает хуки получения только для смарт-контрактов. Функция хука должна возвращать магическое предопределенное значение bytes4, которое задается как:
bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))
Когда принимающий контракт возвращает это значение, предполагается, что контракт принимает перевод и знает, как обращаться с токенами ERC-1155. Отлично, больше никаких застрявших токенов в контракте!
Поддержка NFT
Когда предложение равно всего одному, токен по сути является невзаимозаменяемым токеном (NFT). И, как это принято в стандарте ERC-721, вы можете определить URL-адрес для метаданных. Этот URL-адрес может быть прочитан и изменен клиентами, см. здесь (opens in a new tab).
Правило безопасного перевода
В предыдущих объяснениях мы уже затронули несколько правил безопасного перевода. Но давайте рассмотрим самые важные из них:
- Вызывающая сторона должна быть одобрена для расходования токенов для адреса
_from, либо вызывающая сторона должна совпадать с_from. - Вызов перевода должен откатиться, если:
- Адрес
_toравен 0. - Длина
_idsне совпадает с длиной_values. - Любой из балансов держателей для токенов в
_idsменьше соответствующих сумм в_values, отправляемых получателю. - Происходит любая другая ошибка.
- Адрес
Примечание: все пакетные функции, включая хук, также существуют в версиях без пакетной обработки. Это сделано для экономии газа, учитывая, что перевод только одного актива, вероятно, по-прежнему будет наиболее часто используемым способом. Мы опустили их для простоты объяснений, включая правила безопасного перевода. Названия идентичны, просто удалите слово «Batch».