Logo
Nuevos usuarios de RPC: 35% de descuento el primer mesVer oferta
OnFinality Learn
Guías de red y protocolo13 min de lectura

Resolver transacciones de Sui por digest y checkpoint

Resuelve un digest de transacción de Sui con sui_getTransactionBlock, lee su checkpoint e inclusionProof, y concílialo con el checkpoint certificado.

TL;DR

En Sui, una transacción se identifica mediante un digest en base58, y solo se vuelve final cuando se confirma dentro de un checkpoint certificado identificado por un número de secuencia que aumenta monótonamente. El método sui_getTransactionBlock toma ese digest más opciones como showEffects y showObjectChanges, y devuelve el bloque de transacción junto con un campo checkpoint y un inclusionProof. Luego puedes usar el número de secuencia del checkpoint devuelto para leer el checkpoint y confirmar que el digest aparece en sus transacciones. Este artículo separa el comportamiento documentado del protocolo del comportamiento específico del proveedor, ofrece ejemplos ejecutables en Node.js tanto para la ruta de éxito como para la de no encontrado, y proporciona una tabla de resultados que puedes completar con tu propio endpoint.

Identidad de transacción en Sui: digest frente a número de secuencia de checkpoint

Sui separa dos identificadores que son fáciles de confundir. Una transacción se identifica mediante un digest en base58, que los exploradores suelen etiquetar como "Tx hash"; este es el valor que pegas en un cuadro de búsqueda. Un checkpoint se identifica mediante un número de secuencia que aumenta monótonamente, y es el contenedor en el que se confirman una o más transacciones. El digest responde "qué transacción", mientras que el número de secuencia del checkpoint responde "dónde y cuándo se registró". (consulta la documentación de conceptos de checkpoints de Sui)

La documentación de conceptos de checkpoint de Sui describe los checkpoints como la unidad de compromiso: las transacciones se ordenan, se agrupan y se certifican, y la certificación es lo que hace duradera la inclusión. Por eso, "confirmado" en Sui debe leerse como "incluido en un checkpoint que ha sido certificado", no simplemente "el nodo aceptó mi envío". La ejecución provisional puede ocurrir antes de la certificación, y una transacción que se ha ejecutado pero aún no está en un checkpoint certificado todavía no es final en el mismo sentido.

Esta distinción impulsa todo el flujo de resolución. Resuelves por digest, lees el campo checkpoint de la respuesta y luego concilias ese número de secuencia con el checkpoint mismo. Para una orientación más amplia sobre la red y sus endpoints, consulta la página de la red Sui.

  • Digest: identificador de transacción en base58, la clave de búsqueda para sui_getTransactionBlock.
  • Número de secuencia de checkpoint: entero que aumenta monótonamente e identifica el contenedor confirmado.
  • Certificación: la propiedad que hace duradera la inclusión en el checkpoint, según la documentación de conceptos de checkpoint de Sui.
  • Ejecución provisional: ejecución que puede preceder a la inclusión certificada y no debe tratarse como final.

Qué acepta y devuelve sui_getTransactionBlock

La referencia de la API JSON-RPC de Sui documenta que sui_getTransactionBlock toma un digest más un objeto de opciones. Las opciones controlan qué partes del bloque de transacción se rellenan: showEffects, showInput, showEvents, showObjectChanges y showBalanceChanges. Los campos que corresponden a una opción solo están presentes cuando esa opción está activada, por lo que la forma de la respuesta es en parte función de tu solicitud.

La respuesta incluye el digest, un campo checkpoint, timestampMs y el cuerpo de la transacción, además de effects, events y objectChanges cuando se solicitan. El campo checkpoint lleva el número de secuencia del checkpoint que confirmó la transacción, y la respuesta también incluye un inclusionProof cuyo digest es el digest de la transacción. Trata el campo checkpoint como el puente hacia la ruta de lectura del checkpoint.

Como las opciones cambian la carga útil, también cambian el tamaño de la respuesta y el trabajo que hace el nodo para ensamblarla. Solicitar todo en cada llamada es cómodo pero más pesado; solicita solo las opciones que realmente consumes. El artículo sobre efectos de transacción y cambios de objetos cubre la interpretación de effects y objectChanges una vez que los tienes.

  • showEffects: rellena effects, incluido el estado y el gas utilizado.
  • showInput: rellena la entrada de la transacción, incluidos el remitente y los datos de gas.
  • showEvents: rellena los eventos emitidos.
  • showObjectChanges: rellena los resúmenes de objetos creados, mutados y eliminados.
  • showBalanceChanges: rellena los deltas de saldo por dirección y tipo de moneda.

Resolver un digest con un ejemplo ejecutable en Node.js

El siguiente ejemplo usa el cliente @mysten/sui para resolver un digest con effects y objectChanges, y luego imprime el número de secuencia del checkpoint y el digest del inclusionProof. Es deliberadamente pequeño para que puedas pegarlo en un archivo temporal y apuntarlo al endpoint que uses. La biblioteca cliente es un envoltorio de conveniencia; la llamada subyacente es el mismo método JSON-RPC documentado en la referencia de la API de Sui.

Ejecútalo con un digest real de un explorador o de tu propio envío. Si prefieres JSON-RPC sin procesar, la misma solicitud se puede enviar mediante fetch con un sobre JSON-RPC 2.0, que la especificación JSON-RPC 2.0 define como un campo jsonrpc de versión, un method, params y un id.

import { SuiClient, getFullnodeUrl } from '@mysten/sui/client';

const client = new SuiClient({ url: getFullnodeUrl('mainnet') });

async function resolve(digest) {
  const tx = await client.getTransactionBlock({
    digest,
    options: {
      showEffects: true,
      showInput: true,
      showObjectChanges: true,
    },
  });

  console.log('digest        :', tx.digest);
  console.log('checkpoint    :', tx.checkpoint);
  console.log('timestampMs   :', tx.timestampMs);
  console.log('status        :', tx.effects?.status?.status);
  console.log('inclusionProof:', tx.inclusionProof?.digest);
  console.log('objectChanges :', tx.objectChanges?.length ?? 0);
  return tx;
}

resolve(process.argv[2]).catch((err) => {
  console.error('resolve failed:', err.message);
  process.exitCode = 1;
});

Conciliar el digest con su checkpoint

Una vez que tengas el número de secuencia del checkpoint, lee el checkpoint y confirma que el digest de la transacción aparece en su lista de transacciones. Este es el paso de conciliación: convierte "el nodo me dijo un número de checkpoint" en "observé el digest dentro de ese checkpoint". La documentación de conceptos de checkpoint de Sui explica que los checkpoints son la unidad de compromiso, por lo que esta comprobación es la prueba de inclusión significativa.

El método heredado sui_getCheckpoint está documentado como obsoleto en favor de la ruta de lectura de checkpoints, así que verifica el nombre del método actual en la documentación de Sui antes de codificarlo de forma fija. El soporte del proveedor para un método dado está documentado / varía según el proveedor, así que confirma la disponibilidad en el endpoint que uses en lugar de asumir paridad entre todos los nodos.

El siguiente ejemplo lee el checkpoint y comprueba la pertenencia. Usa el mismo cliente y asume que ya tienes un número de secuencia de checkpoint del paso anterior.

import { SuiClient, getFullnodeUrl } from '@mysten/sui/client';

const client = new SuiClient({ url: getFullnodeUrl('mainnet') });

async function reconcile(digest, checkpointSeq) {
  const cp = await client.getCheckpoint({ id: String(checkpointSeq) });

  const digests = (cp.transactions ?? []).map((t) =>
    typeof t === 'string' ? t : t.digest,
  );

  const included = digests.includes(digest);
  console.log('checkpoint seq :', cp.sequenceNumber);
  console.log('tx count       :', digests.length);
  console.log('included       :', included);
  return included;
}

reconcile(process.argv[2], process.argv[3]).catch((err) => {
  console.error('reconcile failed:', err.message);
  process.exitCode = 1;
});

Resolución por digest frente a enumeración por checkpoint y cursor

Resolver por digest y enumerar por checkpoint o cursor responden a preguntas diferentes. sui_getTransactionBlock es una búsqueda puntual: ya conoces el digest y quieres sus detalles y su checkpoint. suix_queryTransactionBlocks es una enumeración: quieres una página de transacciones filtradas por criterios, recorrida hacia adelante con un cursor. Elegir la incorrecta lleva a código incómodo, como paginar entre miles de transacciones para encontrar una cuyo digest ya tienes.

Usa la resolución por digest cuando tengas una transacción específica que inspeccionar, cuando estés conciliando un hash reportado por un usuario o cuando estés confirmando la inclusión de un único envío. Usa lecturas de checkpoint cuando quieras todo lo confirmado en un contenedor conocido. Usa la enumeración por cursor cuando estés construyendo un feed, rellenando historial o escaneando por filtro. El artículo sobre paginación por cursor de queryTransactionBlocks cubre la ruta de enumeración en detalle, y el artículo sobre flujo de checkpoints y servicio de ledger cubre el consumo de checkpoints como flujo.

  • Búsqueda puntual por digest: sui_getTransactionBlock, ideal para una transacción conocida.
  • Lectura de contenedor: ruta de lectura de checkpoint, ideal para todo lo que hay en un checkpoint conocido.
  • Enumeración filtrada: suix_queryTransactionBlocks con un cursor, ideal para feeds y rellenos.
  • Streaming: flujo de checkpoints, ideal para ingesta continua.

Sondear una transacción recién enviada con un límite

Una transacción recién enviada puede devolver no encontrada hasta que un checkpoint la incluya. Esto es esperado, no necesariamente un error: el digest existe desde el momento en que se envía la transacción, pero el nodo puede no ser capaz todavía de resolverlo en un bloque de transacción confirmado. El patrón correcto es sondear por digest con un límite, retrocediendo entre intentos y rindiéndose tras una fecha límite en lugar de repetir indefinidamente.

Limita el sondeo con un número máximo de intentos y un retraso, y trata un no encontrado persistente como una señal para revisar la cadena del digest, la red y el endpoint. Si la transacción se envió a una red diferente de la que estás consultando, nunca se resolverá en la red equivocada. La guía de RPC de Sui es un complemento útil para la selección de endpoints y la disponibilidad de métodos.

  • Sondea con un retraso fijo y un número máximo de intentos.
  • Trata el no encontrado como provisional hasta la fecha límite, luego investiga.
  • Confirma que el digest es el valor base58 completo, no una etiqueta truncada del explorador.
  • Confirma que la red y el endpoint coinciden con el destino del envío.

Manejar el caso de no encontrado para un digest desconocido

Un digest inventado debería producir un error de no encontrado en lugar de un bloque de transacción. Esta es la prueba negativa que demuestra que tu código de resolución distingue una transacción real de una fabricada. La especificación JSON-RPC 2.0 define la semántica de errores para fallos de método, por lo que una solicitud bien formada para un digest desconocido devuelve un objeto de error en lugar de una carga útil de éxito.

El siguiente ejemplo envuelve la llamada de resolución e imprime un mensaje claro para la ruta de no encontrado. Ejecútalo con un digest deliberadamente inválido para confirmar que tu manejo de errores se comporta como se espera antes de confiar en él en producción.

import { SuiClient, getFullnodeUrl } from '@mysten/sui/client';

const client = new SuiClient({ url: getFullnodeUrl('mainnet') });

async function tryResolve(digest) {
  try {
    const tx = await client.getTransactionBlock({
      digest,
      options: { showEffects: true },
    });
    console.log('resolved:', tx.digest, 'checkpoint:', tx.checkpoint);
    return tx;
  } catch (err) {
    console.log('not found or error for', digest);
    console.log('message:', err.message);
    return null;
  }
}

// A fabricated digest should not resolve.
tryResolve('0x' + '0'.repeat(64));

Tabla de resultados para medición verificada por el lector

La siguiente tabla es una plantilla, no un conjunto de números publicados. Complétala con tu propio endpoint y tus propios digests para que los valores reflejen el entorno que realmente operas. Registra el digest, el número de secuencia del checkpoint, el timestampMs, si el digest apareció en las transacciones del checkpoint y el estado final.

Como el comportamiento del proveedor está documentado / varía según el proveedor, tu tabla puede diferir de la de otra persona en un endpoint diferente. Ese es el punto: la tabla hace visible y reproducible la variación en lugar de afirmarla. Guarda las respuestas sin procesar junto a la tabla para que puedas volver a comprobar cualquier fila más adelante.

  • digest: el digest de transacción completo en base58 que resolviste.
  • secuencia de checkpoint: el campo checkpoint devuelto por sui_getTransactionBlock.
  • timestampMs: el timestampMs devuelto con el bloque de transacción.
  • incluido-en-checkpoint: sí o no, del paso de conciliación.
  • estado: el estado de effects, como success o failure.
  • endpoint: la URL de RPC que consultaste, para que las filas sean atribuibles.

Limitaciones, compensaciones y variación entre proveedores

Aplican varias limitaciones honestas. El digest debe ser el valor base58 completo; un digest truncado o mal copiado no se resolverá. Las opciones cambian el tamaño de la carga útil y el costo de ensamblar la respuesta, por lo que solicitar todas las opciones en cada llamada es una compensación entre comodidad y sobrecarga. El campo checkpoint puede ser null para una transacción que aún no está certificada, por lo que el paso de conciliación importa en lugar de confiar solo en el campo.

La disponibilidad de métodos está documentada / varía según el proveedor. El método heredado sui_getCheckpoint está documentado como obsoleto en favor de la ruta de lectura de checkpoints, así que verifica el nombre del método actual en la documentación de Sui antes de depender de él. Nada de esto sustituye la lectura de las fuentes primarias: la referencia de la API JSON-RPC de Sui para la semántica de métodos y la documentación de conceptos de checkpoint de Sui para la semántica de compromiso.

Para el razonamiento a nivel de objeto que a menudo acompaña a la resolución de transacciones, como el versionado y el ordenamiento, consulta el artículo sobre versiones de objetos y ordenamiento Lamport.

  • Se requiere el digest base58 completo; los valores truncados fallan.
  • Las opciones aumentan el tamaño de la carga útil y el costo de ensamblaje.
  • checkpoint puede ser null antes de la certificación.
  • Los métodos obsoletos pueden eliminarse; verifica los nombres actuales.
  • El soporte del proveedor varía; confírmalo en tu endpoint.

Solución de problemas de digest, checkpoint y errores de método

Digest no encontrado es el síntoma más común. Comprueba que el digest es el valor base58 completo, que estás consultando la red donde se envió la transacción y que ha pasado suficiente tiempo para que un checkpoint la incluya. Si persiste más allá de tu fecha límite de sondeo, trátalo como un fallo real de resolución en lugar de un artefacto de temporización.

Un checkpoint null significa que la transacción aún no está certificada en un checkpoint. No trates un checkpoint null como una resolución final exitosa; vuelve a sondear con un límite o concilia más tarde. Un nombre de método incorrecto, especialmente en torno al método de checkpoint obsoleto, produce un error de método no encontrado; verifica el nombre actual en la documentación de Sui y confirma que tu proveedor lo soporta.

Para preguntas a nivel de endpoint y disponibilidad de métodos, la guía de RPC de Sui y las páginas del servicio de API son los puntos de partida correctos.

  • Digest no encontrado: verifica el valor base58 completo, la red y el tiempo transcurrido.
  • Checkpoint null: aún no certificado; sondea con un límite o concilia más tarde.
  • Nombre de método incorrecto: verifica en la documentación de Sui; confirma el soporte del proveedor.
  • Carga útil inesperada: comprueba qué opciones configuraste.
  • Fallo persistente: captura el objeto de error JSON-RPC sin procesar para soporte.

Próximos pasos y lecturas relacionadas

Con la resolución por digest y la conciliación de checkpoints en su lugar, los siguientes pasos naturales son la enumeración, el streaming y la interpretación de effects. El artículo sobre paginación por cursor de queryTransactionBlocks cubre la paginación de transacciones, el artículo sobre flujo de checkpoints y servicio de ledger cubre la ingesta continua, y el artículo sobre efectos de transacción y cambios de objetos cubre la lectura de lo que hizo una transacción.

Para la selección de endpoints y la planificación de capacidad, revisa los precios de RPC y la descripción general del servicio de API, y explora el centro de aprendizaje de OnFinality para guías adyacentes. La página de la red Sui es el punto de entrada para detalles específicos de la red.

  • Enumera con cursores cuando necesites feeds o rellenos.
  • Transmite checkpoints cuando necesites ingesta continua.
  • Analiza effects y cambios de objetos para entender los resultados.
  • Revisa las páginas de precios y servicio de API antes de escalar.

Nunca te preocupes por la infraestructura nuevamente

OnFinality elimina la carga pesada de DevOps para que puedas construir de forma más inteligente y rápida.

Comenzar