Contrats Intelligents
Savitri Network fournit un environnement d'exécution de contrats intelligents natif avec des standards de jetons intégrés, la gouvernance et le support des oracles.
Environnement d'Exécution des Contrats
Les contrats s'exécutent dans un environnement isolé disposant de :
- Comptage de gaz : Chaque opération consomme du gaz pour prévenir les boucles infinies
- Emplacements de stockage : Stockage clé-valeur utilisant des adresses d'emplacement hachées par Keccak256
- Système d'événements : Les contrats émettent des événements pour les consommateurs externes
- Surveillance mémoire : Les limites mémoire de l'environnement d'exécution préviennent les attaques par déni de service
- Support de mise à niveau : Les contrats peuvent être mis à niveau via la gouvernance
Standards de Jetons
| Standard | Type | Équivalent | Description |
|---|---|---|---|
| SAVITRI-20 | Fongible | ERC-20 | Transferts de jetons, approbations, allocations |
| SAVITRI-721 | Non Fongible (NFT) | ERC-721 | Propriété unique de jeton, transferts, métadonnées |
| SAVITRI-1155 | Multi-Actifs | ERC-1155 | Opérations par lot, mélange fongible/non fongible |
Contrats Intégrés
Gouvernance
Système de propositions et de vote en chaîne :
- Créer des propositions avec titre, description et période de vote
- Voter pour ou contre
- Exécuter les propositions approuvées
- Spécialisation de proposition FL (Apprentissage Fédéré)
Voir Gouvernance pour plus de détails.
Oracle
Système d'alimentation en données externes :
- Enregistrer des fournisseurs d'oracles
- Demander et soumettre des données
- Vérification des preuves
- Validation des schémas
Voir Système Oracle pour plus de détails.
Interaction avec les Contrats via le SDK
Utilisation de 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?;
Utilisation de 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)?;
Modèle de Stockage
Les contrats utilisent un modèle de stockage basé sur des emplacements similaire à Ethereum :
- Emplacements 0-99 : Réservés au
BaseContract(propriétaire, métadonnées) - Emplacement 100+ : Stockage spécifique au contrat
Les adresses d'emplacement sont dérivées par hachage Keccak256 pour éviter les collisions :
balance_slot = keccak256(address || SLOT_BALANCES_BASE)
allowance_slot = keccak256(spender || keccak256(owner || SLOT_ALLOWANCES_BASE))
Toutes les valeurs sont stockées sous forme de tableaux de 32 octets (little-endian pour les types numériques).
Coûts en Gaz
| Opération | Coût en Gaz | Frais (SAVT) |
|---|---|---|
| Déploiement de contrat | Variable | 0,005 de base |
| Appel de contrat | Variable | 0,005 de base |
| Écriture stockage (SSTORE) | 20 000 | Inclus dans la base |
| Lecture stockage (SLOAD) | 200 | Inclus dans la base |
| Transfert de jeton | ~50 000 | 0,005 |
| Frappe NFT | ~80 000 | 0,005 |
| Vote de gouvernance | ~30 000 | 0,005 |
Déploiement de Contrat
Les contrats sont déployés via des transactions spéciales avec to = None et le bytecode du contrat dans le champ 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)?;