SAVITRI-1155: Стандарт мультиактивных токенов
SAVITRI-1155 (SMA — Savitri Multi Asset) — стандарт мультиактивных токенов для Savitri Network, аналог ERC-1155 в Ethereum. Он поддерживает как взаимозаменяемые, так и невзаимозаменяемые токены в рамках одного контракта с эффективными пакетными операциями.
Интерфейс
| Функция | Параметры | Возвращает | Описание |
|---|---|---|---|
balance_of | owner, id | u128 | Баланс конкретного токена для владельца |
balance_of_batch | owners[], ids[] | u128[] | Пакетный запрос баланса |
safe_transfer_from | from, to, id, amount, data | Result | Перевод токенов |
safe_batch_transfer_from | from, to, ids[], amounts[], data | Result | Пакетный перевод |
set_approval_for_all | operator, approved | Result | Одобрить оператора для всех токенов |
is_approved_for_all | owner, operator | bool | Проверить одобрение оператора |
Схема хранилища
Хранилище балансов (слот 100+)
Вложенный маппинг: balances[owner][id]
hash1 = keccak256(owner || 100)
hash2 = keccak256(id || hash1)
slot = first 8 bytes of hash2 as u64
Хранилище одобрений операторов (слот 200+)
Вложенный маппинг: operator_approvals[owner][operator]
hash1 = keccak256(owner || 200)
hash2 = keccak256(operator || hash1)
slot = first 8 bytes of hash2 as u64
Данная схема обеспечивает:
- Равномерное распределение: Keccak256 гарантирует равномерное распределение слотов
- Отсутствие коллизий: пренебрежимо малая вероятность коллизий
- Эффективные пакетные запросы: каждый слот вычисляется независимо
- Кеш-дружественность: ContractStorage кеширует чтения
Использование
Одиночный перевод
use savitri_contracts::contracts::standards::savitri1155::SAVITRI1155;
SAVITRI1155::safe_transfer_from(
&mut contract_storage,
&storage,
&from, // [u8; 32]
&to, // [u8; 32]
1, // token id
100, // amount
&[], // data
&mut event_system,
Some(&mut gas_meter),
)?;
Пакетный перевод
SAVITRI1155::safe_batch_transfer_from(
&mut contract_storage,
&storage,
&from,
&to,
&[1, 2, 3], // token ids
&[100, 50, 1], // amounts
&[], // data
&mut event_system,
Some(&mut gas_meter),
)?;
Пакетный запрос баланса
let balances = SAVITRI1155::balance_of_batch(
&contract_storage,
&storage,
&[owner1, owner2, owner3],
&[token_id_1, token_id_2, token_id_3],
)?;
Одобрение оператора
// Approve an operator for all tokens
SAVITRI1155::set_approval_for_all(
&mut contract_storage,
&storage,
&owner,
&operator,
true, // approved
&mut event_system,
Some(&mut gas_meter),
)?;
// Check approval
let approved = SAVITRI1155::is_approved_for_all(
&contract_storage,
&storage,
&owner,
&operator,
)?;
События
| Событие | Поля | Описание |
|---|---|---|
TransferSingle | operator, from, to, id, amount | Перевод одного токена |
TransferBatch | operator, from, to, ids[], amounts[] | Пакетный перевод |
ApprovalForAll | owner, operator, approved | Изменение одобрения оператора |
Варианты применения
| Сценарий | Тип токена | Пример |
|---|---|---|
| Внутриигровая валюта | Взаимозаменяемый (id=1) | 1000 золотых монет |
| Уникальные предметы | Невзаимозаменяемый (amount=1) | Легендарный меч #42 |
| Полувзаимозаменяемый | Ограниченный выпуск | 50 копий редкой карты |
| Награды | Взаимозаменяемый | Токены вознаграждения PoU |
| Сертификаты | Невзаимозаменяемый | Сертификат валидатора |
Оптимизация пакетных операций
Реализация SAVITRI-1155 оптимизирует пакетные операции следующим образом:
- Предварительное вычисление всех слотов перед чтением хранилища
- Использование кеша ContractStorage для исключения повторных обращений к БД
- Независимое вычисление слотов с возможностью параллельного чтения в будущем
- Минимизация декодирования адресов за счёт повторного использования декодированных адресов в операциях