Guía de solución de problemas de API REST para intercambios

La guía Integración con un Exchange explica cómo integrar el token BXR en una plataforma de Exchange utilizando los SDK disponibles. También es posible realizar esta integración usando la REST API pero el procedimiento es significativamente más complicado.

Esta página no pretende repetir el contenido de la guía Integración con un Exchange usando REST, sino que muestra cómo solucionar los problemas más comunes que se encuentran al usar esta API en el desarrollo de un Exchange.

Siéntase libre de saltar directamente a la sección de su interés.

Recibir transacciones

Filtrado (por altura de bloque y más)

Utilice el extremo /transactions/confirmed para recuperar cualquier grupo de transacciones confirmadas. Entre otras opciones de filtrado, los siguientes parámetros suelen ser útiles para restringir las búsquedas:

:header: “Parameter”, “Type”, “Effect” :delim: ; :widths: 25 15 60

tipo; entero; Recuperar solo transacciones de este tipo. El código para TransferTransaction es 16724 (0x4154).

dirección del destinatario; cadena; “La dirección que recibe la transacción. Compare con dirección que devuelve todas las transacciones relacionadas con la dirección dada (como remitente

destinatario o cosignatario).

Esto podría ser Base32 Dirección o espacio de nombres. Si el bit 0 del byte 0 no está establecido (p. ej.

0x90)

entonces es una dirección; de lo contrario

(p. ej.

0x91) representa una identificación de espacio de nombres que comienza en el byte 1”.

desdeAltura; cadena; La altura del bloque inicial a buscar.

a la Altura; cadena; La altura del bloque final a buscar.

incrustado; booleano; “Use true para buscar automáticamente dentro de las transacciones agregadas. Los datos devueltos por una transacción independiente y una transacción incrustada (una dentro de un agregado) es ligeramente diferente (Consulte la siguiente sección).

Use false para buscar manualmente transacciones agregadas (por ejemplo

tipos 0x4141 y 0x4241) y analizarlas.

Caution: Does not work when combined with address

only with recipientAddress.”

Aquí hay una consulta de ejemplo a un :término:`NODE_URL`:

NODE_URL
  /transactions/confirmed
    ?recipientAddress=TAOXUJOTTW3W5XTBQMQEX3SQNA6MCUVGXLXR3TA
    &type=16724
    &fromHeight=70000
    &toHeight=80000
    &embedded=true

Esta consulta devuelve la lista de todas las transacciones de transferencia enviadas a la dirección TAOXU..., que ocurrieron entre la altura del bloque 70000 y 80000, incluidas las transacciones incrustadas dentro otras transacciones.

La siguiente sección explica cómo analizar la lista resultante.

Análisis de transacciones incrustadas

|nombre en clave| admite agregate-transaction, es decir, transacciones dentro de otras transacciones. En su mayor parte, no importa si una transacción es independiente o incrustada dentro de otra, pero existen algunas diferencias que pueden resultar confusas al analizar las transacciones entrantes. Esta sección los explica.

Note

Siempre puede recibir transacciones incrustadas, incluso si nunca crea ninguna usted mismo. ¡Asegúrate de entender cómo analizarlos!

Como se muestra en la documentación del punto final /transactions/confirmed, una consulta exitosa devuelve una matriz de datos que incluye transacciones y metadatos (esta matriz está paginada, así que preste atención a los parámetros y valores de retorno pageSize y pageNumber). Cada una de las transacciones devueltas puede coincidir con un esquema diferente según el tipo de transacción, por lo que se debe verificar el campo tipo de cada transacción.

Además, el contenido de los metadatos también es diferente cuando la transacción está incrustada dentro de una agregada-transacción.

Esto es especialmente importante cuando se usa el parámetro embedded=true ya que algunas de las transacciones devueltas pueden ser transacciones incrustadas mientras que otras pueden ser transacciones regulares y los esquemas involucrados son diferentes.

Por ejemplo, la consulta de ejemplo anterior, que filtra por type=16724 (transacciones de transferencia), en realidad devuelve los objetos TransferTransactionDTO y EmbeddedTransferTransactionDTO debido al parámetro embedded=true. Los metadatos adjuntos también varían entre TransactionMetaDTO y EmbeddedTransactionMetaDTO.

Estas son las principales diferencias a tener en cuenta:

Metadata

Property

Regular

Embedded

Schema

TransactionMetaDTO

EmbeddedTransactionMetaDTO

index

Transaction index within the block

Transaction index within the aggregate transaction.

hash

Transaction Hash

-

aggregateHash

-

Hash of the containing aggregate transaction.

Transaction

Property

Regular

Embedded

Schema

TransferTransactionDTO

EmbeddedTransferTransactionDTO

size

Transaction size in bytes

-

signature

Signature generated by the signer

-

maxFee

Maximum fee to pay for the transaction

-

deadline

Number of blocks before the transaction expires

-

Los 4 campos anteriores faltan en la transacción incrustada porque pertenecen a la transacción agregada contenedora. Para acceder a ellos, recupere primero la transacción agregada utilizando el extremo /transactions/confirmed/{transactionId} y ``aggregateHash `` como Id.

Si no está interesado en ninguno de los campos enumerados anteriormente, puede tratar con seguridad las transacciones de transferencia regulares e integradas de la misma manera, ya que comparten el resto de propiedades.

resolución de alias

Tokens ID y addresses son largas cadenas aleatorias que son engorrosas de usar. Para mayor comodidad, |nombre en clave| proporciona espacios de nombres, que son cadenas de texto proporcionadas por el usuario (alias) que se pueden usar en lugar de direcciones o identificadores de token. Un espacio de nombres siempre se puede resolver en la dirección real o el identificador de token que representa.

El ejemplo más común es bitxor (ID de espacio de nombres 0xEE905A59E4F6DB7D) que es un alias para la moneda nativa de Bitxor (ID de token 0x3D1FE6EDC7F9611E).

Note

El token ID 0x3D1FE6EDC7F9611E y 0xEE905A59E4F6DB7D siempre se pueden tratar de forma segura como equivalentes.

Puede encontrar transacciones usando uno u otro dependiendo de si se crearon usando directamente la ID del token o el espacio de nombres.

bitxor es un espacio de nombres que no caduca, por lo que la equivalencia anterior siempre se mantiene. Sin embargo, los espacios de nombres regulares se alquilan por un período de tiempo limitado, y esto plantea un problema al resolverlos porque después de la expiración, un espacio de nombres puede volver a alquilarse y tener un alias con un token o dirección diferente.

Por lo tanto, para resolver correctamente un espacio de nombres encontrado en una transacción, se debe tener en cuenta la altura del bloque que incluía la transacción.

Esto es muy fácil de hacer porque todos los bloques que incluyen un espacio de nombres también incluyen una declaración de resolución de tokens o una declaración de resolución de direcciones que contiene el espacio de nombres resuelto. Simplemente use /statements/solutions/token y /statements/solutions/address puntos finales para recuperar todas las declaraciones de un bloque determinado y luego ubicar el ID de espacio de nombres no resuelto que le interesa.

Ejemplo usando TESTNET:

  • NODE_URL/transactions/confirmed?height=211972 recupera todas las transacciones incluidas en el bloque 211972.

    "transaction": {
       "size": 176,
       "signature": "35DC5689...",
       "signerPublicKey": "B49D1910...",
       "version": 1,
       "network": 152,
       "type": 16724,
       "maxFee": "100000",
       "deadline": "8530382295",
       "recipientAddress": "981D7A25D39DB76EDE6183204BEE50683CC152A6BAEF1DCC",
       "tokens": [
          {
          "id": "E374D0B5E061EE92",
          "amount": "1"
          }
       ]
    }
    

Sin embargo, la identificación del token 0xE374D0B5E061EE92 no existe (/tokens/E374D0B5E061EE92 devolvería un error ResourceNotFound). Además, el bit más alto que se establece indica que en realidad se trata de un espacio de nombres.

  • Puede verificar el alias actual de este espacio de nombres consultando /namespaces/E374D0B5E061EE92, pero en realidad desea conocer el ID del token con alias en el momento en que se confirmó la transacción.

  • Para hacer esto, verifique la tokensolutionstatement del bloque en /statements/solutions/token?height=211972:

    {
      "statement": {
        "height": "211972",
        "unresolved": "E374D0B5E061EE92",
        "resolutionEntries": [
          {
            "source": {
              "primaryId": 1,
              "secondaryId": 0
            },
            "resolved": "0DDE03C044AF95D4"
          }
        ]
      },
      "id": "60DEDC83EA7C4338C56C4FB6"
    }
    

Aquí puede ver el ID del token resuelto, 0x0DDE03C044AF95D4, que es un ID válido y se puede consultar con /tokens/0DDE03C044AF95D4.

Envío de transacciones

Las transacciones se anuncian a la red a través del extremo /transactions que acepta una cadena hexadecimal que representa la carga útil de la transacción. El proceso para construir esta carga útil se explica bastante extensamente en la guía Definición de una transacción.

Las siguientes secciones tienen como objetivo aclarar los puntos que los usuarios de la API han considerado más confusos.

Plazo de transacción

No se permite que las transacciones permanezcan sin confirmar en la red para siempre, ya que esto supondría una carga significativa para los recursos de la red. En cambio, todas las transacciones tienen una fecha límite y se eliminan automáticamente cuando llega la fecha límite.

Los usuarios son libres de utilizar cualquier fecha límite que deseen para sus transacciones, entre ahora y 6h en el futuro (48h para transacciones agregadas-vinculadas). Las transacciones anunciadas con una fecha límite fuera de esta ventana serán rechazadas con un error de fecha límite no válida.

Los plazos se dan en milisegundos desde la creación del bloque de génesis.

El momento en que se creó el genesis block se puede encontrar en la propiedad network.epochAdjustment de /network/properties punto final. Este es el número de segundos transcurridos desde la época de UNIX y siempre es 1615853185 para MAINNET.

En otras palabras, debe restar el ajuste de época de un tiempo de Unix para obtener una fecha límite. Por lo tanto, una fecha límite de 2 horas en el futuro, que es la fecha límite predeterminada proporcionada por el SDK, se puede calcular como:

currentTime = now(); // Seconds since the UNIX epoch
deadline = (currentTime + 7200 - epochAdjustment) * 1000;

Esta fecha límite ahora se puede usar al crear la transacción y vencerá dentro de 2 horas (7200 segundos).

Tarifa de transacción

El Fee efectivo que una transacción debe pagar para ser anunciada es el tamaño de la transacción (en bytes) multiplicado por un multiplicador de tarifas elegido por el nodo que confirma la transacción.

Dado que este multiplicador se desconoce al hacer el anuncio, las transacciones definen la tarifa máxima que están dispuestas a pagar.

Además, los nodos pueden definir una tarifa mínima por debajo de la cual las transacciones simplemente se ignoran.

Como consecuencia, elegir la tarifa máxima correcta para una transacción es muy importante: un número demasiado bajo y la transacción no será confirmada por ningún nodo y eventualmente vencerá. Sin embargo, las tarifas máximas demasiado altas incurrirán en gastos innecesarios.

Para ayudar a elegir la cantidad correcta, el punto final /network/fees/transaction proporciona algunas estadísticas sobre las tarifas efectivas pagadas por las últimas 60 cuadras. Los datos devueltos son:

Property

Meaning

más alto

Mayor multiplicador de tarifas utilizado en los últimos 60 bloques.

Mediana

El valor medio de los multiplicadores de tarifas utilizados en los últimos 60 bloques. Consulte la sección Multiplicador dinámico de tarifa para obtener más detalles.

Significar

El valor promedio de los multiplicadores de tarifas utilizados en los últimos 60 bloques.

más bajo

El multiplicador de tarifas más pequeño utilizado en los últimos 60 bloques.

mínimo

El multiplicador de tarifa mínima aceptado por el nodo que se consulta.

Una buena regla general es usar el medianFeeMultiplier. Esto generalmente proporciona una confirmación oportuna de las transacciones sin incurrir en el pago de tarifas excesivas.