Contratos Inteligentes
Savitri Network proporciona un entorno de ejecución nativo de contratos inteligentes con estándares de tokens integrados, gobernanza y soporte de oráculos.
Entorno de Ejecución de Contratos
Los contratos se ejecutan en un entorno aislado (sandbox) con:
- Medición de gas: Cada operación consume gas para prevenir bucles infinitos
- Ranuras de almacenamiento: Almacenamiento clave-valor usando direcciones de ranura con hash Keccak256
- Sistema de eventos: Los contratos emiten eventos para consumidores externos
- Monitoreo de memoria: Los límites de memoria en tiempo de ejecución previenen ataques DoS
- Soporte de actualizaciones: Los contratos pueden actualizarse mediante gobernanza
Estándares de Tokens
| Estándar | Tipo | Equivalente | Descripción |
|---|---|---|---|
| SAVITRI-20 | Fungible | ERC-20 | Transferencias, aprobaciones y asignaciones de tokens |
| SAVITRI-721 | No Fungible (NFT) | ERC-721 | Propiedad única de tokens, transferencias y metadatos |
| SAVITRI-1155 | Multi-Activo | ERC-1155 | Operaciones por lote, mezcla de fungibles/no fungibles |
Contratos Integrados
Gobernanza
Sistema de propuestas y votaciones en cadena:
- Crear propuestas con título, descripción y período de votación
- Votar a favor o en contra
- Ejecutar propuestas aprobadas
- Especialización de propuestas de Aprendizaje Federado (FL)
Consulta Gobernanza para más detalles.
Oráculo
Sistema de fuentes de datos externas:
- Registrar proveedores de oráculos
- Solicitar y enviar datos
- Verificación de pruebas
- Validación de esquemas
Consulta Sistema de Oráculos para más detalles.
Interacción con Contratos mediante el SDK
Usando 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?;
Usando 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)?;
Modelo de Almacenamiento
Los contratos utilizan un modelo de almacenamiento basado en ranuras similar al de Ethereum:
- Ranuras 0-99: Reservadas para
BaseContract(propietario, metadatos) - Ranura 100+: Almacenamiento específico del contrato
Las direcciones de ranura se derivan mediante hash Keccak256 para evitar colisiones:
balance_slot = keccak256(address || SLOT_BALANCES_BASE)
allowance_slot = keccak256(spender || keccak256(owner || SLOT_ALLOWANCES_BASE))
Todos los valores se almacenan como arreglos de 32 bytes (little-endian para tipos numéricos).
Costos de Gas
| Operación | Costo de Gas | Tarifa (SAVT) |
|---|---|---|
| Despliegue de contrato | Variable | 0.005 base |
| Llamada a contrato | Variable | 0.005 base |
| Escritura en almacenamiento (SSTORE) | 20,000 | Incluido en base |
| Lectura de almacenamiento (SLOAD) | 200 | Incluido en base |
| Transferencia de tokens | ~50,000 | 0.005 |
| Acuñación de NFT | ~80,000 | 0.005 |
| Voto de gobernanza | ~30,000 | 0.005 |
Despliegue de Contratos
Los contratos se despliegan mediante transacciones especiales con to = None y el bytecode del contrato en el campo 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)?;