Construcción y Envío de Transacciones
El TransactionBuilder proporciona una API fluida para construir, firmar y enviar transacciones a Savitri Network.
Transferencia 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")?;
// Obtener el nonce actual
let nonce = client.get_nonce(wallet.address()).await?;
// Construir y firmar
let signed_tx = TransactionBuilder::new()
.to("recipient_address_64hex")
.value(1_000_000_000_000_000_000) // 1 SAVT (18 decimals)
.nonce(nonce)
.fee(1_000_000_000_000_000) // 0.001 SAVT fee
.build_and_sign(&wallet)?;
// Enviar
let result = client.send_raw_transaction(&serialize_tx(&signed_tx)).await?;
println!("TX hash: {}", result.tx_hash);
Ok(())
}
API del Constructor
Campos Requeridos
| Método | Tipo | Descripción |
|---|---|---|
.from(address) | String | Dirección del remitente (se rellena automáticamente desde la billetera si se omite) |
.to(address) | String | Dirección del destinatario |
.value(amount) | u128 | Monto de transferencia en la unidad más pequeña |
Campos Opcionales
| Método | Tipo | Predeterminado | Descripción |
|---|---|---|---|
.nonce(n) | u64 | 0 | Nonce de la transacción (obtener con get_nonce()) |
.fee(f) | u128 | Ninguno | Comisión de la transacción |
.data(bytes) | Vec<u8> | Ninguno | Carga útil para llamadas a contratos |
Construir sin Firmar
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
Construir y Firmar
let signed = TransactionBuilder::new()
.to("recipient_address")
.value(1000)
.nonce(5)
.fee(100)
.build_and_sign(&wallet)?;
// signed.transaction -- la UnsignedTransaction
// signed.public_key -- clave pública ed25519 de 32 bytes
// signed.signature -- firma ed25519 de 64 bytes
Si no se llama a .from(), se usa automáticamente la dirección de la billetera.
Llamadas a Oráculo
let signed = TransactionBuilder::new()
.oracle_call(
"oracle_contract_address",
"request_data",
b"temperature_sensor_01",
)
.value(0)
.nonce(nonce)
.build_and_sign(&wallet)?;
Llamadas de Gobernanza
Votar en una Propuesta
use savitri_sdk::GovernanceAction;
let signed = TransactionBuilder::new()
.governance_call(
"governance_contract_address",
proposal_id, // u64
GovernanceAction::Vote(true), // true = a favor, false = en contra
)
.nonce(nonce)
.build_and_sign(&wallet)?;
Ejecutar una Propuesta Aprobada
let signed = TransactionBuilder::new()
.governance_call(
"governance_contract_address",
proposal_id,
GovernanceAction::Execute,
)
.nonce(nonce)
.build_and_sign(&wallet)?;
Crear una Propuesta FL
let signed = TransactionBuilder::new()
.create_fl_proposal(
"governance_contract_address",
"Upgrade model v2", // title
"Replace BERT with GPT-4", // description
604800, // voting period in seconds (7 days)
)
.nonce(nonce)
.build_and_sign(&wallet)?;
Formato de Firma de Transacciones
El mensaje de firma se construye como:
from_hex_bytes || to_hex_bytes || amount_le_u64 || nonce_le_u64 || fee_le_u128
Luego se aplica SHA-256 y el hash se firma con Ed25519.
Este formato coincide con la verificación del lado del servidor en savitri-rpc.
Cantidades y Decimales
Todas las cantidades usan 18 decimales:
| Cantidad Legible | Valor en Bruto |
|---|---|
| 1 SAVT | 1_000_000_000_000_000_000 |
| 0.1 SAVT | 100_000_000_000_000_000 |
| 0.001 SAVT | 1_000_000_000_000_000 |
| 0.00001 SAVT | 10_000_000_000_000 |
Referencia de Comisiones
| Tipo de Transacción | Comisión (SAVT) | Valor en Bruto |
|---|---|---|
| Transferencia normal | 0.001 | 1_000_000_000_000_000 |
| Llamada a contrato | 0.005 | 5_000_000_000_000_000 |
| Datos IoT | 0.00005 | 50_000_000_000_000 |