Construir Transacciones
Las transacciones permiten cambiar datos on-chain o disparar eventos. Generalmente, las transacciones siguen un flujo de cuatro pasos desde la construccion hasta la ejecucion on-chain: construir, firmar, enviar y esperar.
Metodos de Conveniencia
Sección titulada «Metodos de Conveniencia»El SDK de Rust proporciona varios metodos de alto nivel en el cliente Aptos que combinan multiples pasos en una sola llamada. Estos son la forma mas rapida de ejecutar una transaccion on-chain cuando no necesitas control detallado sobre cada paso.
sign_submit_and_wait
Sección titulada «sign_submit_and_wait»Construye, firma, envia y espera a que una transaccion se complete en una sola llamada. Este es el metodo mas comun para transacciones sencillas.
let payload = InputEntryFunctionData::new("0x1::aptos_account::transfer") .arg(recipient.address()) .arg(1_000_000u64) .build()?;
let response = aptos .sign_submit_and_wait(&sender, payload, None) .await?;
println!("Transaction succeeded: {}", response.data.success);El tercer argumento opcional es una duracion de timeout. Pasa None para usar el valor por defecto.
sign_and_submit
Sección titulada «sign_and_submit»Firma y envia una transaccion sin esperar confirmacion. Usa esto cuando quieras rastrear el resultado tu mismo o enviar y olvidar.
let payload = InputEntryFunctionData::new("0x1::aptos_account::transfer") .arg(recipient.address()) .arg(1_000_000u64) .build()?;
let pending = aptos.sign_and_submit(&sender, payload).await?;println!("Submitted transaction hash: {}", pending.hash);simulate_and_submit
Sección titulada «simulate_and_submit»Simula la transaccion primero para verificar que tendra exito, luego la envia. Esto es util para detectar errores antes de gastar gas.
let payload = InputEntryFunctionData::new("0x1::aptos_account::transfer") .arg(recipient.address()) .arg(1_000_000u64) .build()?;
let pending = aptos .simulate_and_submit(&sender, payload) .await?;transfer_apt
Sección titulada «transfer_apt»Un metodo de conveniencia disenado especificamente para transferir APT entre cuentas.
let response = aptos .transfer_apt(&sender, recipient.address(), 10_000_000) .await?;
println!("Transfer succeeded: {}", response.data.success);transfer_coin
Sección titulada «transfer_coin»Transfiere cualquier tipo de moneda especificando la etiqueta de tipo de la moneda como una cadena.
let response = aptos .transfer_coin( &sender, recipient.address(), "0x1::aptos_coin::AptosCoin", 10_000_000, ) .await?;
println!("Coin transfer succeeded: {}", response.data.success);Construir Payloads con InputEntryFunctionData
Sección titulada «Construir Payloads con InputEntryFunctionData»Todos los metodos de conveniencia anteriores (excepto transfer_apt y transfer_coin) aceptan un TransactionPayload construido a partir de InputEntryFunctionData. Este constructor te ofrece una API limpia y encadenable para construir llamadas a funciones entry:
use aptos_sdk::transaction::InputEntryFunctionData;
let payload = InputEntryFunctionData::new("0x1::aptos_account::transfer") .arg(recipient.address()) .arg(1_000_000u64) .build()?;Para llamar a una funcion generica que requiere argumentos de tipo, usa .type_arg():
let payload = InputEntryFunctionData::new("0x1::coin::transfer") .type_arg("0x1::aptos_coin::AptosCoin") .arg(recipient.address()) .arg(1_000_000u64) .build()?;Flujo de Transaccion Paso a Paso
Sección titulada «Flujo de Transaccion Paso a Paso»Cuando necesitas control total sobre cada etapa de una transaccion, como personalizar parametros de gas, inspeccionar la transaccion raw antes de firmar, o separar responsabilidades entre servicios, usa el enfoque paso a paso.
-
Construir el Payload
Comienza construyendo el payload de la transaccion. Esto define que funcion on-chain llamar y que argumentos pasar.
use aptos_sdk::transaction::InputEntryFunctionData;let payload = InputEntryFunctionData::new("0x1::aptos_account::transfer").arg(recipient.address()).arg(1_000_000u64).build()?;Si la funcion requiere argumentos de tipo (genericos), agregalos con
.type_arg():let payload = InputEntryFunctionData::new("0x1::coin::transfer").type_arg("0x1::aptos_coin::AptosCoin").arg(recipient.address()).arg(1_000_000u64).build()?; -
Construir la Transaccion Raw
Usa
TransactionBuilderpara ensamblar unaRawTransactioncon el remitente, numero de secuencia, payload, ID de cadena y parametros de gas opcionales.use aptos_sdk::transaction::TransactionBuilder;let chain_id = aptos.chain_id().await?;let sequence_number = aptos.get_sequence_number(sender.address()).await?;let raw_txn = TransactionBuilder::new().sender(sender.address()).sequence_number(sequence_number).payload(payload).chain_id(chain_id).max_gas_amount(100_000).gas_unit_price(100).expiration_from_now(600).build()?;El constructor requiere
sender,sequence_number,payloadychain_id. Los campos restantes tienen valores por defecto razonables:Campo Por defecto Descripcion max_gas_amount200,000 Unidades de gas maximas que la transaccion puede consumir gas_unit_price100 Precio por unidad de gas en octas expiration_from_now600 Segundos hasta que la transaccion expire -
Firmar la Transaccion
Firma la transaccion raw con la cuenta del remitente usando la funcion
sign_transaction.use aptos_sdk::transaction::sign_transaction;let signed_txn = sign_transaction(&raw_txn, &sender)?;Esto produce una
SignedTransactionque incluye tanto los datos de la transaccion raw como la firma criptografica. El SDK soporta la firma con tipos de cuenta Ed25519, Secp256k1 y Secp256r1. -
Enviar y Esperar
Envia la transaccion firmada a la red y espera a que se confirme on-chain.
let response = aptos.submit_and_wait(&signed_txn, None).await?;if response.data.success {println!("Transaction succeeded at version {}", response.data.version);} else {println!("Transaction failed: {}", response.data.vm_status);}El segundo argumento es un timeout opcional. Pasa
Nonepara usar el timeout por defecto, o proporciona unDurationpara un comportamiento personalizado.Si solo quieres enviar sin esperar, usa
submit_transactionen su lugar:let pending = aptos.submit_transaction(&signed_txn).await?;println!("Submitted hash: {}", pending.hash);
Helpers para Argumentos Move
Sección titulada «Helpers para Argumentos Move»El SDK proporciona funciones auxiliares para codificar tipos Move comunes como argumentos de transaccion. Estas son necesarias cuando una funcion Move espera un argumento String, Option<T> o vector<T>.
move_string
Sección titulada «move_string»Codifica un &str de Rust como un argumento Move String.
use aptos_sdk::transaction::move_string;
let payload = InputEntryFunctionData::new("0x1::my_module::set_name") .arg(move_string("Alice")) .build()?;move_some y move_none
Sección titulada «move_some y move_none»Codifican valores como tipos Move Option<T>. Usa move_some para envolver un valor en Some y move_none para None.
use aptos_sdk::transaction::{move_some, move_none};
// Pass Some(100u64)let payload = InputEntryFunctionData::new("0x1::my_module::set_optional_value") .arg(move_some(100u64)) .build()?;
// Pass Nonelet payload = InputEntryFunctionData::new("0x1::my_module::set_optional_value") .arg(move_none()) .build()?;move_vec
Sección titulada «move_vec»Codifica un slice de valores como un argumento Move vector<T>.
use aptos_sdk::transaction::move_vec;
let recipients = vec![alice.address(), bob.address(), carol.address()];
let payload = InputEntryFunctionData::new("0x1::my_module::batch_process") .arg(move_vec(&recipients)) .build()?;Constantes de Funciones Predefinidas
Sección titulada «Constantes de Funciones Predefinidas»El SDK incluye constantes para funciones on-chain de uso comun en el modulo functions. Estas previenen errores tipograficos en cadenas codificadas y hacen tu codigo mas legible.
| Constante | Valor |
|---|---|
functions::APT_TRANSFER | "0x1::aptos_account::transfer" |
functions::COIN_TRANSFER | "0x1::coin::transfer" |
functions::CREATE_ACCOUNT | "0x1::aptos_account::create_account" |
functions::REGISTER_COIN | "0x1::managed_coin::register" |
functions::PUBLISH_PACKAGE | "0x1::code::publish_package_txn" |
Usalas en cualquier lugar donde pasarias una cadena de identificador de funcion:
use aptos_sdk::transaction::{functions, InputEntryFunctionData};
let payload = InputEntryFunctionData::new(functions::APT_TRANSFER) .arg(recipient.address()) .arg(1_000_000u64) .build()?;Ejemplo Completo en Rust
Sección titulada «Ejemplo Completo en Rust»/// This example demonstrates the complete transaction lifecycle:/// building, signing, submitting, and waiting for an APT transfer.
use aptos_sdk::{Aptos, AptosConfig};use aptos_sdk::account::Ed25519Account;use aptos_sdk::transaction::{ functions, sign_transaction, InputEntryFunctionData, TransactionBuilder,};
#[tokio::main]async fn main() -> anyhow::Result<()> { // 0. Setup the client and test accounts let aptos = Aptos::new(AptosConfig::testnet())?;
let sender = Ed25519Account::generate(); let recipient = Ed25519Account::generate();
println!("Sender: {}", sender.address()); println!("Recipient: {}", recipient.address());
// Fund the sender account on testnet aptos.fund_account(sender.address(), 100_000_000).await?; println!("Funded sender account.");
// 1. Build the payload let payload = InputEntryFunctionData::new(functions::APT_TRANSFER) .arg(recipient.address()) .arg(10_000_000u64) .build()?;
// 2. Build the raw transaction let chain_id = aptos.chain_id().await?; let sequence_number = aptos.get_sequence_number(sender.address()).await?;
let raw_txn = TransactionBuilder::new() .sender(sender.address()) .sequence_number(sequence_number) .payload(payload) .chain_id(chain_id) .max_gas_amount(100_000) .gas_unit_price(100) .expiration_from_now(600) .build()?;
// 3. Sign the transaction let signed_txn = sign_transaction(&raw_txn, &sender)?;
// 4. Submit and wait for confirmation let response = aptos.submit_and_wait(&signed_txn, None).await?;
if response.data.success { println!( "Transaction succeeded at version {}", response.data.version ); } else { println!("Transaction failed: {}", response.data.vm_status); }
// Verify the recipient balance let balance = aptos.get_balance(recipient.address()).await?; println!("Recipient balance: {} octas", balance);
Ok(())}Explorar Funcionalidades Avanzadas de Transacciones
Sección titulada «Explorar Funcionalidades Avanzadas de Transacciones»Las transacciones soportan varias funcionalidades avanzadas para adaptarse a diferentes casos de uso:
- Simular Transacciones - Previsualiza costos y efectos de transacciones antes de confirmar on-chain.
- Transacciones Multi-Agente - Permite que multiples cuentas participen en una sola transaccion con firmas coordinadas.
- Patrocinar Transacciones - Permite que otra cuenta pague las tarifas de gas de una transaccion.
- Transacciones por Lotes - Envia multiples transacciones independientes rapidamente desde una sola cuenta.
- Transacciones de Script - Ejecuta bytecode de scripts Move personalizados para operaciones atomicas de un solo uso o multiples pasos.