Saltar al contenido principal

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étodoTipoDescripción
.from(address)StringDirección del remitente (se rellena automáticamente desde la billetera si se omite)
.to(address)StringDirección del destinatario
.value(amount)u128Monto de transferencia en la unidad más pequeña

Campos Opcionales

MétodoTipoPredeterminadoDescripción
.nonce(n)u640Nonce de la transacción (obtener con get_nonce())
.fee(f)u128NingunoComisión de la transacción
.data(bytes)Vec<u8>NingunoCarga ú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 LegibleValor en Bruto
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

Referencia de Comisiones

Tipo de TransacciónComisión (SAVT)Valor en Bruto
Transferencia normal0.0011_000_000_000_000_000
Llamada a contrato0.0055_000_000_000_000_000
Datos IoT0.0000550_000_000_000_000