Saltar al contenido principal

Entorno de Ejecución de Contratos

El entorno de ejecución de contratos de Savitri ejecuta contratos inteligentes en un entorno aislado (sandbox) con medición de gas, aislamiento de almacenamiento y emisión de eventos.

Flujo de Ejecución

Contract Call TX arrives


BaseContract validation
│ check paused, owner, reserved slots

Gas Meter initialization
│ gas_limit from TX fee

ContractStorage setup
│ load contract state, init cache

Function dispatch
│ match function_selector → handler

Execution (with gas tracking)
│ SLOAD, SSTORE, events, calls

Result
├── Success → commit storage, emit events
└── Failure → revert all changes

BaseContract

Todos los contratos extienden BaseContract. Las ranuras 0-99 están reservadas:

RanuraCampoTamañoDescripción
0owner32 bytesDirección del propietario del contrato
1versionu64Versión del contrato
2governance_hookboolIntegración de gobernanza habilitada
3fee_hookboolLógica de tarifa personalizada habilitada
4pausedboolEstado de pausa del contrato
5-99Reservado-Uso futuro

Funciones de BaseContract

FunciónAccesoDescripción
owner()PúblicoObtener el propietario del contrato
transfer_ownership(new_owner)Solo propietarioTransferir propiedad
version()PúblicoObtener versión del contrato
upgrade(new_version)Solo propietarioActualizar contrato
pause()Solo propietarioPausar todas las operaciones
unpause()Solo propietarioReanudar operaciones

Medición de Gas

Costos de Gas

OperaciónGasDescripción
SLOAD100Lectura de almacenamiento
SSTORE (nuevo)20,000Escritura en almacenamiento (ranura vacía)
SSTORE (actualizar)5,000Escritura en almacenamiento (ranura existente)
CALL2,300Llamada entre contratos
CREATE32,000Despliegue de contrato
TRANSFER300Transferencia de tokens
LOG375Emisión de evento (base)
LOG_TOPIC375Por tema adicional
LOG_DATA8Por byte de datos de evento
CALLDATA16Por byte de datos de llamada

Contabilidad por Lotes

El medidor de gas usa contabilidad por lotes (100 operaciones por lote) para reducir la sobrecarga. El gas se confirma en lotes en lugar de por operación.

Límite de Gas

El límite de gas se deriva de la tarifa de transacción:

gas_limit = tx.fee / gas_price

Si el gas se agota durante la ejecución, toda la transacción se revierte.

Almacenamiento de Contratos

Modelo Basado en Ranuras

Cada contrato tiene un almacén independiente de clave-valor donde las claves son números de ranura u64 y los valores son arreglos de 32 bytes.

Derivación de Ranuras

Para mapeos, las ranuras se derivan mediante Keccak256 para prevenir colisiones:

// Simple value
slot = FIXED_SLOT_NUMBER

// Mapping (address → value)
slot = keccak256(address || base_slot)[0..8] as u64

// Nested mapping (address → address → value)
inner = keccak256(outer_key || base_slot)
slot = keccak256(inner_key || inner)[0..8] as u64

Árbol de Merkle

El almacenamiento de contratos mantiene un árbol de Merkle para la generación de pruebas de estado.

Sistema de Eventos

Los contratos emiten eventos para consumidores externos:

pub struct CustomEvent {
pub event_type: String, // e.g., "Transfer", "Approval"
pub topics: Vec<Vec<u8>>, // indexed fields
pub data: Vec<u8>, // non-indexed data
}

Eventos estándar (desde BaseContract):

  • OwnershipTransferred(old_owner, new_owner)
  • ContractUpgraded(old_version, new_version)
  • Paused(by)
  • Unpaused(by)

Despliegue de Contratos

1. Create DeployTransaction (to = None, data = bytecode)
2. Assign contract address (derived from deployer + nonce)
3. Initialize BaseContract (set owner, version)
4. Run contract constructor (initialize function)
5. Store ContractInfo in CF_CONTRACTS
6. Emit ContractDeployed event

Llamadas a Contratos

1. Parse function_selector from TX data
2. Load contract from CF_CONTRACTS
3. Check BaseContract state (not paused, etc.)
4. Initialize GasMeter with gas_limit
5. Execute function with ContractStorage
6. If success: commit storage changes, deduct gas
7. If failure: revert all changes

Intérprete EVM

El módulo evm_interpreter proporciona ejecución básica de bytecode EVM para compatibilidad con contratos de Ethereum. Esto permite desplegar contratos compilados con Solidity en Savitri.

Monitoreo de Memoria

El memory_monitor rastrea el uso de memoria en tiempo de ejecución para prevenir ataques DoS:

  • Límites de memoria por contrato
  • Seguimiento de asignaciones
  • Terminación automática si se superan los límites

Ejecución Paralela

El módulo parallel habilita la ejecución paralela de contratos para transacciones independientes:

  • Análisis de dependencias entre transacciones
  • Detección de conflictos en ranuras de almacenamiento
  • Ejecución paralela de transacciones sin conflictos
  • Respaldo serial para transacciones conflictivas

Trazado de Contratos

El módulo tracing proporciona trazas de ejecución para depuración:

  • Registro de ejecución paso a paso
  • Seguimiento de lecturas/escrituras en almacenamiento
  • Consumo de gas por operación
  • Registro de emisión de eventos