Aller au contenu principal

Construire et Envoyer des Transactions

Le TransactionBuilder fournit une API fluide pour construire, signer et soumettre des transactions au réseau Savitri.

Transfert Simple

use savitri_sdk::{Wallet, TransactionBuilder, RpcClient};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
let client = RpcClient::from_url("http://localhost:8545")?;
let wallet = Wallet::from_private_key_hex("your_private_key_hex")?;

// Obtenir le nonce actuel
let nonce = client.get_nonce(wallet.address()).await?;

// Construire et signer
let signed_tx = TransactionBuilder::new()
.to("recipient_address_64hex")
.value(1_000_000_000_000_000_000) // 1 SAVT (18 décimales)
.nonce(nonce)
.fee(1_000_000_000_000_000) // 0.001 SAVT de frais
.build_and_sign(&wallet)?;

// Soumettre
let result = client.send_raw_transaction(&serialize_tx(&signed_tx)).await?;
println!("Hash TX : {}", result.tx_hash);

Ok(())
}

API du Constructeur

Champs Obligatoires

MéthodeTypeDescription
.from(address)StringAdresse de l'expéditeur (remplie automatiquement depuis le portefeuille si omise)
.to(address)StringAdresse du destinataire
.value(amount)u128Montant du transfert en plus petite unité

Champs Optionnels

MéthodeTypeDéfautDescription
.nonce(n)u640Nonce de transaction (obtenir via get_nonce())
.fee(f)u128AucunFrais de transaction
.data(bytes)Vec<u8>AucunCharge utile pour les appels de contrat

Construire sans Signer

let unsigned = TransactionBuilder::new()
.from("sender_address")
.to("recipient_address")
.value(1000)
.nonce(5)
.build()?;

// unsigned.from, unsigned.to, unsigned.value, unsigned.nonce, unsigned.fee, unsigned.data

Construire et Signer

let signed = TransactionBuilder::new()
.to("recipient_address")
.value(1000)
.nonce(5)
.fee(100)
.build_and_sign(&wallet)?;

// signed.transaction -- l'UnsignedTransaction
// signed.public_key -- clé publique ed25519 de 32 octets
// signed.signature -- signature ed25519 de 64 octets

Si .from() n'est pas appelé, l'adresse du portefeuille est utilisée automatiquement.

Appels Oracle

let signed = TransactionBuilder::new()
.oracle_call(
"oracle_contract_address",
"request_data",
b"temperature_sensor_01",
)
.value(0)
.nonce(nonce)
.build_and_sign(&wallet)?;

Appels de Gouvernance

Voter sur une Proposition

use savitri_sdk::GovernanceAction;

let signed = TransactionBuilder::new()
.governance_call(
"governance_contract_address",
proposal_id, // u64
GovernanceAction::Vote(true), // true = soutien, false = opposition
)
.nonce(nonce)
.build_and_sign(&wallet)?;

Exécuter une Proposition Approuvée

let signed = TransactionBuilder::new()
.governance_call(
"governance_contract_address",
proposal_id,
GovernanceAction::Execute,
)
.nonce(nonce)
.build_and_sign(&wallet)?;

Créer une Proposition FL

let signed = TransactionBuilder::new()
.create_fl_proposal(
"governance_contract_address",
"Upgrade model v2", // titre
"Replace BERT with GPT-4", // description
604800, // période de vote en secondes (7 jours)
)
.nonce(nonce)
.build_and_sign(&wallet)?;

Format de Signature des Transactions

Le message de signature est construit comme suit :

from_hex_bytes || to_hex_bytes || amount_le_u64 || nonce_le_u64 || fee_le_u128

Puis haché avec SHA-256, et le hash est signé avec Ed25519.

Ce format correspond à la vérification côté serveur dans savitri-rpc.

Montants et Décimales

Tous les montants utilisent 18 décimales :

Montant HumainValeur Brute
1 SAVT1_000_000_000_000_000_000
0.1 SAVT100_000_000_000_000_000
0.001 SAVT1_000_000_000_000_000
0.00001 SAVT10_000_000_000_000

Référence des Frais

Type de TransactionFrais (SAVT)Valeur Brute
Transfert normal0.0011_000_000_000_000_000
Appel de contrat0.0055_000_000_000_000_000
Données IoT0.0000550_000_000_000_000