交換所に関する REST API トラブルシューティング

この 交換所の統合 ガイドでは available SDKs を使用して XYM トークンを取引所プラットフォームに統合する方法を説明します。また REST API を使用して統合することも可能ですが、手順は かなり複雑化する でしょう。

This page does not aim at repeating the content of the 交換所の統合 guide using REST, instead, it shows how to fix the most common problems encountered when using this API in the development of an Exchange.

読みたいセクションへ直接移動してください。

トランザクションの受信

フィルタリング (ブロック高やその他)

Use the /transactions/confirmed endpoint to retrieve any group of confirmed transactions. Among other filtering options, the following parameters are typically useful for narrowing down searches:

パラメタ

タイプ

影響

type

integer

このトランザクションタイプだけを取得します。 TransferTransaction のコードは 16724 (0x4154) です。

recipientAddress

string

The address receiving the transaction. Compare with address which returns all transactions involving the given address (as sender, recipient or cosigner).

This might either be a Base32 アドレス or a ネームスペース. If the bit 0 of byte 0 is not set (e.g. 0x90) then it is an address, otherwise (e.g. 0x91) it represents a namespace id which starts at byte 1.

fromHeight

string

検索する開始ブロック高

toHeight

string

検索する終了ブロック高

embedded

boolean

Use true to automatically search inside aggregate transactions. The data returned by a standalone transaction and an embedded transaction (one inside an aggregate) is slightly different (Check the next section).

Use false to manually search for aggregate transactions (e.g. types 0x4141 and 0x4241) and parse them.

Caution: Does not work when combined with address, only with recipientAddress.

Here is an example query to a NODE_URL:

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

This query returns the list of all transfer transactions sent to address TAOXU..., that happened between block height 70000 and 80000, including transactions embedded inside other transactions.

The next section explains how to parse the resulting list.

埋め込みトランザクションのパース

Symbol supports アグリゲートトランザクション, i.e., transactions inside other transactions. For the most part it does not matter if a transaction is standalone or embedded inside another one, but there are a few differences which might be confusing when parsing incoming transactions. This section explains them.

注釈

You can always receive embedded transactions, even if you never create any yourself. Make sure you understand how to parse them!

As shown in the /transactions/confirmed endpoint documentation, a successfull query returns a data array including transactions and metadata (this array is paginated so pay attention to the pageSize and pageNumber parameters and return values). Each one of the returned transactions can match a different schema depending on the transaction's type, so the type field of each transaction must be checked.

Moreover, the metadata content is also different when the transaction is embedded inside an アグリゲートトランザクション.

This is specially important when using the embedded=true parameter since some of the returned transactions might be embedded transactions whereas some other might be regular transactions, and the involved schemas are different.

For example the above sample query, which filters by type=16724 (transfer transactions), actually returns both TransferTransactionDTO and EmbeddedTransferTransactionDTO objects because of the embedded=true parameter. The attached metadata also varies between TransactionMetaDTO and EmbeddedTransactionMetaDTO.

These are the main differences to keep in mind:

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

署名者により生成された署名。

-

maxFee

トランザクションの最大支払い手数料

-

deadline

Number of blocks before the transaction expires

-

The above 4 fields are missing from the embedded transaction because they belong to the containing aggregate transaction. To access them recover first the aggregate transaction using the /transactions/confirmed/{transactionId} endpoint and aggregateHash as Id.

If you are not interested in any of the fields listed above you can safely treat regular and embedded transfer transactions the same way, since they share the rest of properties.

エイリアスの解決

Mosaics IDs and addresses are long random strings which are cumbersome to use. For convenience, Symbol provides namespaces, which are user-provided text strings (aliases) that can be used instead of addresses or mosaic IDs. A namespace can always be resolved into the actual address or mosaic ID that it represents.

The most common example is symbol.xym (Namespace ID 0xE74B99BA41F4AFEE) which is an alias for Symbol's native currency (Mosaic ID 0x6BED913FA20223F8).

注釈

Mosaic ID 0x6BED913FA20223F8 and 0xE74B99BA41F4AFEE can always be safely treated as equivalent.

You might find transactions using one or the other depending on whether they were created using directly the mosaic ID or the namespace.

symbol.xym is a namespace which does not expire so the above equivalence always holds. However, regular namespaces are rented for a limited amount of time, and this poses a problem when resolving them because after expiration a namespace might get rented again and be aliased to a different mosaic or address.

Therefore, to correctly resolve a namespace found in a transaction, the block height that included the transaction must be taken into account.

This is very easy to do because all blocks which include a namespace also include either a MosaicResolutionStatement or an AddressResolutionStatement containing the resolved namespace. Just use the /statements/resolutions/mosaic and /statements/resolutions/address endpoints to retrieve all statements for a given block, and then locate the unresolved namespace ID you are interested in.

TESTNET を用いた例:

  • NODE_URL/transactions/confirmed?height=211972 retrieves all transactions included in block 211972.

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

    However, the mosaic ID 0xE374D0B5E061EE92 does not exist (/mosaics/E374D0B5E061EE92 would return a ResourceNotFound error). Besides, the highest bit being set indicates this is actually a namespace.

  • You could check the current alias of this namespace by querying /namespaces/E374D0B5E061EE92, but you actually want to know the aliased mosaic ID at the time the transaction was confirmed.

  • You do this by checking the block's MosaicResolutionStatement at /statements/resolutions/mosaic?height=211972:

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

    Here you can see the resolved mosaic ID, 0x0DDE03C044AF95D4 which is a valid ID and can be queried with /mosaics/0DDE03C044AF95D4.

Sending transactions

Transactions are announced to the network through the /transactions endpoint which accepts an hexadecimal string representing the transaction's payload. The process to build this payload is explained fairly extensively in the トランザクションの定義 guide.

The following sections aim at clarifying the points which have been deemed the most confusing by users of the API.

トランザクション期限

Transactions are not allowed to remain unconfirmed in the network forever, as this would pose a significant strain on the network's resources. Instead, all transactions have a deadline, and are automatically disposed of when the deadline arrives.

Users are free to use any deadline they want for their transactions, between now and 6h into the future (48h for アグリゲートボンド transactions). Transactions announced with a deadline outside this window will be rejected with an invalid deadline error.

Deadlines are given in milliseconds since the creation of the nemesis block.

The moment when the nemesis block was created can be found in the network.epochAdjustment property of the /network/properties endpoint. This is the number of seconds elapsed since the UNIX epoch and it is always 1615853185 for MAINNET.

In other words, you need to substract the epoch adjustment from a Unix time to obtain a deadline. Therefore, a deadline 2h into the future, which is the default deadline provided by the SDK, can be calculated as:

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

This deadline can now be used when building the transaction, and it will expire 2h from now (7200 seconds).

トランザクション手数料

The effective Fee a transaction must pay to be announced is the transaction size (in bytes) times a fee multiplier chosen by the node that confirms the transaction.

Since this multiplier is unknown when making the announcement, transactions define the maximum fee they are willing to pay.

Moreover, nodes can define a minimum fee below which transactions are just ignored.

結論として、トランザクションに適切な最大手数料を選択することは非常に重要です: 手数料が少なすぎると、トランザクションはどのノードによっても承認されず、最終的には期限切れになります。しかし、最大手数料が高すぎると、不必要なコストが発生します。

To help choose the right amount, the /network/fees/transaction endpoint provides some statistics regarding the effective fees paid by the last 60 blocks. The returned data is:

Property

意味

最高

直近 60 ブロックで使用された最大の手数料乗数。

頻出

The median value of the fee multipliers used in the last 60 blocks. See the 動的手数料乗数 section for more details.

平均

The average value of the fee multipliers used in the last 60 blocks.

最低

直近 60 ブロックで使用された最小の手数料乗数。

最小

The minimum fee multiplier accepted by the node being queried.

注意

minFeeMultiplier refers to the node being queried, whereas the rest of properties refer to the whole network.

A good rule of thumb is to use the medianFeeMultiplier. This typically provides timely confirmation of transactions without incurring in excessive fees being paid.