Смарт-контракты
Savitri Network предоставляет нативную среду выполнения смарт-контрактов со встроенными стандартами токенов, механизмами управления и поддержкой оракулов.
Среда выполнения контрактов
Контракты выполняются в изолированной среде с:
- Измерением газа: каждая операция потребляет газ для предотвращения бесконечных циклов
- Слотами хранилища: хранилище типа ключ-значение с адресами слотов, хешированными через Keccak256
- Системой событий: контракты генерируют события для внешних потребителей
- Мониторингом памяти: ограничения памяти среды выполнения предотвращают DoS-атаки
- Поддержкой обновлений: контракты могут обновляться через систему управления
Стандарты токенов
| Стандарт | Тип | Аналог | Описание |
|---|---|---|---|
| SAVITRI-20 | Взаимозаменяемый | ERC-20 | Переводы токенов, одобрения, лимиты |
| SAVITRI-721 | Невзаимозаменяемый (NFT) | ERC-721 | Уникальное владение токенами, переводы, метаданные |
| SAVITRI-1155 | Мультиактив | ERC-1155 | Пакетные операции, смешанные взаимозаменяемые/невзаимозаменяемые токены |
Встроенные контракты
Управление
Система предложений и голосования на блокчейне:
- Создание предложений с названием, описанием и периодом голосования
- Голосование «за» или «против»
- Исполнение утверждённых предложений
- Специализация FL (Федеративное обучение) для предложений
Подробнее см. в разделе Управление.
Оракул
Система внешних источников данных:
- Регистрация провайдеров оракулов
- Запрос и отправка данных
- Верификация доказательств
- Проверка схем данных
Подробнее см. в разделе Система оракулов.
Взаимодействие с контрактами через SDK
Использование ContractClient
use savitri_sdk::{ContractClient, Wallet, RpcClient};
let wallet = Wallet::from_private_key_hex("your_key")?;
let contract = ContractClient::from_url_and_wallet("http://localhost:8545", wallet)?;
// Call a contract function
let tx_hash = contract.call_contract(
&"contract_address".to_string(),
b"transfer",
&encoded_args,
Some(0),
).await?;
Использование TransactionBuilder
use savitri_sdk::TransactionBuilder;
let tx = TransactionBuilder::new()
.to("contract_address")
.data(call_data) // function selector + encoded args
.value(0)
.nonce(nonce)
.fee(5_000_000_000_000_000) // 0.005 SAVT contract fee
.build_and_sign(&wallet)?;
Модель хранилища
Контракты используют модель хранилища на основе слотов, аналогичную Ethereum:
- Слоты 0–99: зарезервированы для
BaseContract(владелец, метаданные) - Слот 100+: хранилище, специфичное для контракта
Адреса слотов вычисляются с помощью хеширования Keccak256 для предотвращения коллизий:
balance_slot = keccak256(address || SLOT_BALANCES_BASE)
allowance_slot = keccak256(spender || keccak256(owner || SLOT_ALLOWANCES_BASE))
Все значения хранятся в виде 32-байтовых массивов (little-endian для числовых типов).
Стоимость газа
| Операция | Стоимость газа | Комиссия (SAVT) |
|---|---|---|
| Развёртывание контракта | Переменная | 0.005 базовая |
| Вызов контракта | Переменная | 0.005 базовая |
| Запись в хранилище (SSTORE) | 20 000 | Включена в базовую |
| Чтение хранилища (SLOAD) | 200 | Включена в базовую |
| Перевод токена | ~50 000 | 0.005 |
| Выпуск NFT | ~80 000 | 0.005 |
| Голосование в управлении | ~30 000 | 0.005 |
Развёртывание контрактов
Контракты развёртываются через специальные транзакции с to = None и байткодом контракта в поле data:
let deploy_tx = TransactionBuilder::new()
// No .to() -- indicates contract deployment
.data(contract_bytecode)
.value(0)
.nonce(nonce)
.fee(5_000_000_000_000_000)
.build_and_sign(&wallet)?;