Перейти к основному содержимому

Смарт-контракты

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 0000.005
Выпуск NFT~80 0000.005
Голосование в управлении~30 0000.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)?;