Les ressources ont été chargées... Je charge...

Pratiques de quantification de l'échange DEX ((1) -- dYdX v4 Guide d'utilisation

Auteur:L'inventeur de la quantification - un petit rêve, Créé: 2024-12-24 17:09:32, Mis à jour: 2024-12-26 21:41:46

[TOC] Je vous en prie.

img

Préambule

Avec l'essor rapide des échanges décentralisés (DEX) dans le domaine des transactions cryptographiques, les traders quantifiés ont commencé à se tourner vers ces plateformes pour effectuer des transactions automatisées efficaces. Comme dYdX est l'une des plateformes de trading décentralisées les plus populaires, il offre des fonctionnalités de trading puissantes, prend en charge la négociation de contrats à terme sur les futures, et sa dernière version v4 optimise les performances et l'expérience utilisateur, ce qui en fait le choix préféré de nombreux traders quantifiés.

Cet article explique comment quantifier les pratiques de trading sur dYdX v4, y compris comment utiliser son API pour effectuer des transactions, obtenir des données de marché et gérer des comptes.

  • Échange de l'environnement de test
  • Demandez de l'information sur le marché
  • Informations sur les commandes, informations sur les stocks
  • Compte à rebours
  • Gestion de sous-comptes
  • Demande de méthode de nœud

Le système d'exploitation de l'appareil doit être configuré de manière à ce qu'il soit compatible avec le système d'exploitation.

  • Page d'applications du test dYdX

    img

  • avecdYdX v3Il y a aussi des récompenses, des récompenses.dYdXJe vous en prie, faites-moi confiance.

    img

Connexion, connexion et configuration du portefeuille

L'échange DEX, qui était basé sur le protocole dYdX v3, est désormais hors service.

https://dydx.trade/trade/ETH-USD

Après avoir ouvert la page de l'application, le bouton de connexion du portefeuille apparaît en haut à droite et le code de balayage connecte le portefeuille.

Si vous souhaitez vous familiariser avec les tests environnementaux, vous pouvez utiliser le testnet:

https://v4.testnet.dydx.exchange/trade/ETH-USD

Dans le même ordre d'idées, cliquez sur le bouton de connexion du portefeuille en haut à droite, sur le balayage du code de connexion du portefeuille, sur la confirmation de la signature. Une fois la connexion du portefeuille réussie, une adresse dydx v4 est générée automatiquement. Dans le coin supérieur droit de l'application, un menu apparaît.

  • Adresse du compte dYdX v4 L'adresse d'un compte dYdX v4 est dérivée de l'adresse d'un portefeuille.dydx1xxxxxxxxxxxxxxxxxxxxq2ge5jr4nzfeljxxxx, est l'adresse du début de dydx1. Cette adresse peut être consultée dans les explorateurs de la blockchain.

  • Le mot de passe Vous pouvez utiliser le bouton "Exporter mot de passe" dans le menu en haut à droite pour exporter le mot de passe de l'adresse actuelle dYdX. Vous devez configurer ce mot de passe lorsque vous ajoutez une bourse sur la plate-forme FMZ.

    Le mot-clé peut être configuré directement sur la plateforme FMZ, mais il peut également être conservé localement par l'administrateur, qui lit le contenu du fichier du mot-clé enregistré lors de l'utilisation d'un objet d'échange dydx v4.

Différences entre les réseaux d'accueil et de test

Les environnements de test diffèrent de certains environnements du réseau principal.

  • Les actifs des comptes sont répartis. Le réseau principal dispose d'un mécanisme de nettoyage des sous-comptes.subAccountNumber >= 128Si le sous-compte de l'ID n'est pas détenu, les actifs sont automatiquement effacés vers le sous-compte dont le numéro de compte est 0. Les tests ont révélé que le réseau de test n'avait pas ce mécanisme (ou que les conditions de déclenchement étaient différentes et qu'il n'y avait pas de déclenchement dans le réseau de test).
  • Certains noms de jetons. Dydx a été désigné sous une autre appellation.DYDXLe réseau de testDv4TNT
  • Configuration des adresses, telles que l'ID de la chaîne, l'adresse du nœud, l'adresse de l'indexateur, etc.; Il y a beaucoup de nœuds et de configurations, et voici l'un d'entre eux:
    • Le site officiel: L'adresse de l'index est:https://indexer.dydx.tradeIdentifiant de chaîne:dydx-mainnet-1Les points REST:https://dydx-dao-api.polkachu.com:443

    • Le réseau de test: L'adresse de l'index est:https://indexer.v4testnet.dydx.exchangeIdentifiant de chaîne:dydx-testnet-4Les points REST:https://dydx-testnet-api.polkachu.com

L'architecture du protocole dYdX v4

Le protocole dYdX v4 est basé sur l'écosystème cosmos.

  • L'indicateur est chargé des requêtes relatives à l'information sur le marché, aux informations sur les comptes et autres.
  • DYDX est un réseau de messagerie qui fournit des messages de commande, de retrait, de transfert, etc.

Indices

Le service d'indexation fournit le protocole REST et le protocole Websocket.

  • Protocole REST L'interface du protocole REST prend en charge les requêtes d'informations de marché, d'informations de compte, d'informations de stockage, d'informations d'ordre, etc., qui sont enveloppées dans l'API unifiée de la plate-forme FMZ.

  • Le protocole WebSocket Sur la plateforme FMZ, vous pouvez créer des connexions Websocket, des informations sur les marchés des abonnements, etc. à l'aide de la fonction Dial.

Attention à l'indicateur de dydx v4 avec tous les mêmes problèmes de transaction centralisée, les mises à jour de données ne sont pas si opportunes, par exemple parfois une requête immédiate après la commande, peut ne pas être une requête d'ordre.Sleep(n)Il est possible que vous ayez des problèmes de santé.

Voici un exemple d'utilisation de la fonction Dial pour créer une connexion Websocket API et souscrire des données minces:

function dYdXIndexerWSconnManager(streamingPoint) {
    var self = {}
    self.base = streamingPoint
    self.wsThread = null

    // 订阅
    self.CreateWsThread = function (msgSubscribe) {
        self.wsThread = threading.Thread(function (streamingPoint, msgSubscribe) {
            // 订单薄
            var orderBook = null 

            // 更新订单薄
            var updateOrderbook = function(orderbook, update) {
                // 更新 bids
                if (update.bids) {
                    update.bids.forEach(([price, size]) => {
                        const priceFloat = parseFloat(price)
                        const sizeFloat = parseFloat(size)

                        if (sizeFloat === 0) {
                            // 删除价格为 price 的买单
                            orderbook.bids = orderbook.bids.filter(bid => parseFloat(bid.price) !== priceFloat)
                        } else {
                            // 更新或新增买单
                            orderbook.bids = orderbook.bids.filter(bid => parseFloat(bid.price) !== priceFloat)
                            orderbook.bids.push({price: price, size: size})
                            // 按价格降序排序
                            orderbook.bids.sort((a, b) => parseFloat(b.price) - parseFloat(a.price))
                        }
                    })
                }

                // 更新 asks
                if (update.asks) {
                    update.asks.forEach(([price, size]) => {
                        const priceFloat = parseFloat(price)
                        const sizeFloat = parseFloat(size)

                        if (sizeFloat === 0) {
                            // 删除价格为 price 的卖单
                            orderbook.asks = orderbook.asks.filter(ask => parseFloat(ask.price) !== priceFloat)
                        } else {
                            // 更新或新增卖单
                            orderbook.asks = orderbook.asks.filter(ask => parseFloat(ask.price) !== priceFloat)
                            orderbook.asks.push({price: price, size: size})
                            // 按价格升序排序
                            orderbook.asks.sort((a, b) => parseFloat(a.price) - parseFloat(b.price))
                        }
                    })
                }

                return orderbook
            }

            var conn = Dial(`${streamingPoint}|reconnect=true&payload=${JSON.stringify(msgSubscribe)}`)
            if (!conn) {
                Log("createWsThread failed.")
                return
            }
            while (true) {
                var data = conn.read()
                if (data) {
                    var msg = null                    
                    try {
                        msg = JSON.parse(data)
                        if (msg["type"] == "subscribed") {
                            orderBook = msg["contents"]
                            threading.currentThread().postMessage(orderBook)
                        } else if (msg["type"] == "channel_data") {
                            orderBook = updateOrderbook(orderBook, msg["contents"])
                            threading.currentThread().postMessage(orderBook)
                        }
                    } catch (e) {
                        Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message)
                    }
                }
            }
        }, streamingPoint, msgSubscribe)
    }

    // 监听
    self.Peek = function () {
        return self.wsThread.peekMessage()
    }

    return self
}

function main() {
    // real : wss://indexer.dydx.trade/v4/ws
    // simulate : wss://indexer.v4testnet.dydx.exchange/v4/ws

    var symbol = "ETH-USD"
    var manager = dYdXIndexerWSconnManager("wss://indexer.dydx.trade/v4/ws")
    manager.CreateWsThread({"type": "subscribe", "channel": "v4_orderbook", "id": symbol})

    var redCode = "#FF0000"
    var greenCode = "#006400"
    while (true) {
        var depthTbl = {type: "table", title: symbol + " / depth", cols: ["level", "price", "amount"], rows: []}
        var depth = manager.Peek()
        if (depth) {
            for (var i = 0; i < depth.asks.length; i++) {
                if (i > 9) {
                    break
                }
                var ask = depth.asks[i]
                depthTbl.rows.push(["asks " + (i + 1) + greenCode, ask.price + greenCode, ask.size + greenCode])
            }
            depthTbl.rows.reverse()

            for (var i = 0; i < depth.bids.length; i++) {
                if (i > 9) {
                    break
                }
                var bid = depth.bids[i]
                depthTbl.rows.push(["bids " + (i + 1) + redCode, bid.price + redCode, bid.size + redCode])
            }
        }
        LogStatus(_D(), "\n`" + JSON.stringify(depthTbl) + "`")
    }
}

dYdX chaîne de diffusion de nouvelles

Les messages les plus couramment utilisés dans les transactions sont les messages de commande, de retrait et de virement.

  • Résumé de l'ordre

    {
      "@type": "/dydxprotocol.clob.MsgPlaceOrder",
      "order": {
        "orderId": {
          "subaccountId": {
            "owner": "xxx"
          },
          "clientId": xxx,
          "orderFlags": 64,
          "clobPairId": 1
        },
        "side": "SIDE_BUY",
        "quantums": "2000000",
        "subticks": "3500000000",
        "goodTilBlockTime": 1742295981
      }
    }
    
    • Liste des prix: La fonction de sous-commande enveloppée dans la plate-forme FMZ, les OrderFlags utilisés pour les commandes à prix limité, sont:ORDER_FLAGS_LONG_TERM = 64 # 长期订单La durée de validité de la commande la plus longue est de 90 jours (tous les types de commande sur Dydx v4 sont valables).

    • Liste des prix: La fonction d'envoi d'ordres enveloppée dans la plate-forme FMZ, les ordres de prix utilisés pour les ordres d'ordres, sont les suivants:ORDER_FLAGS_SHORT_TERM = 0 # 短期订单Le site Web de l'entreprise est disponible en anglais, français et anglais.

      // Recommander fixé au prix oracle - 5% ou moins pour VENDRE, prix oracle + 5% pour acheter

      Comme il ne s'agit pas d'une liste de prix réelle, on utilise le prix du prédicteur, plus un prix d'écart de 5% comme liste de prix. La durée de validité des ordres à court terme est également différente de celle des ordres à long terme. Les ordres à court terme utilisent une durée de validité élevée pour les blocs, et sont désactivés après avoir été réglés à la hauteur du bloc actuel + 10 blocs selon les recommandations de dydx v4.

    • Nom de la commande: Étant donné que l'opération de sous-commande est effectuée directement sur la chaîne, il n'y a pas d'ID d'ordre généré par l'index après la diffusion du message et il n'est pas possible d'utiliser l'ordre d'index comme valeur de retour de la fonction de sous-commande de la plate-forme. Afin d'assurer l'unicité de l'ID d'ordre et l'exactitude de la requête d'ordre, l'ID d'ordre retourné est constitué des informations suivantes:

      • Les échanges
      • Adresse actuelle du compte dydx
      • Numéro de sous-compte
      • clientId (généré au hasard)
      • clobPairId (identifiant de la variété de transaction)
      • ordreFlags
      • goodTilData (en millièmes de seconde)
  • Résumé de l'annonce

    {
      "@type": "/dydxprotocol.clob.MsgCancelOrder",
      "orderId": {
        "subaccountId": {
          "owner": "xxx"
        },
        "clientId": 2585872024,
        "orderFlags": 64,
        "clobPairId": 1
      },
      "goodTilBlockTime": 1742295981
    }
    

    L'ID de la commande doit être renvoyé à l'interface de commande de la plateforme FMZ.

  • Résumé du transfert

    {
      "@type": "/dydxprotocol.sending.MsgCreateTransfer",
      "transfer": {
        "sender": {
          "owner": "xxx"
        },
        "recipient": {
          "owner": "xxx",
          "number": 128
        },
        "amount": "10000000"
      }
    }
    

    De nombreux sous-comptes peuvent être créés sous l'adresse dydx v4 actuelle, dont le subAccountNumber 0 est le premier sous-compte créé automatiquement, le subAccountNumber est supérieur à 128 et l'ID du sous-compte est égal à 128 pour les transactions de variétés par lots, nécessitant un minimum d'actifs de 20 USD. Par exemple, il est possible d'utiliser le sous-compte N° 0 -> 128 ou le sous-compte N° 128 -> 0. Le détournement nécessite une consommation de Gas Fee.

FMZ plateforme dYdX v4 pratique

Le contenu ci-dessus explique brièvement quelques détails de l'emballage, puis nous allons pratiquer l'utilisation concrète, ici, en utilisant dYdX v4 réseau de test pour une démonstration, le réseau de test est en grande partie compatible avec le réseau principal, et il y a un robinet automatique qui peut prendre les actifs de test, l'opération de déploiement de l'hôte n'est plus décrite, créer des tests en direct sur FMZ.

1, configuration

Après avoir connecté l'application dYdX v4 avec le portefeuille de crypto-monnaie (je utilise ici le portefeuille imToken), l'actif de test est récupéré, puis le mot de passe du compte dYdX v4 actuel (dérivé du portefeuille) est exporté.

img

Configurer le mot de passe dans la plateforme FMZ, où nous utilisons la configuration de fichiers locaux (vous pouvez également le remplir directement et le configurer sur la plateforme, le mot de passe est sur la configuration post-chiffrement et non explicite).

  • 助记词文件:mnemonic.txt

    img

    Dans le répertoire des dossiers ID de disque virtuel sous le répertoire de l'administrateur, vous pouvez bien sûr les placer dans d'autres répertoires (des chemins spécifiques sont nécessaires lors de la configuration).

  • Configuration des échanges sur FMZ

    https://www.fmz.com/m/platforms/add

    Le texte de l'éditeur de mots-auxiliaires est rempli:file:///mnemonic.txtLe chemin réel est le suivant:托管者所在目录/logs/storage/594291

    img

2° Passer à la plateforme de test dydx v4

function main() {
    // 切换测试链的索引器地址
    exchange.SetBase("https://indexer.v4testnet.dydx.exchange")

    // 切换测试链的ChainId 
    exchange.IO("chainId", "dydx-testnet-4")

    // 切换测试链的REST节点地址
    exchange.IO("restApiBase", "https://dydx-testnet-api.polkachu.com")

    // 读取账户信息测试
    Log(exchange.GetAccount()) 
}

Lire l'information sur le compte du testnet:

{
	"Info": {
		"subaccounts": [{
			"address": "dydx1fzsndj35a26maujxff88q2ge5jr4nzfeljn2ez",
			"subaccountNumber": 0,
			"equity": "300.386228",
			"latestProcessedBlockHeight": "28193227",
			"freeCollateral": "300.386228",
			"openPerpetualPositions": {},
			"assetPositions": {
				"USDC": {
					"subaccountNumber": 0,
					"size": "300.386228",
					"symbol": "USDC",
					"side": "LONG",
					"assetId": "0"
				}
			},
			"marginEnabled": true,
			"updatedAtHeight": "28063818"
		}, {
			"address": "dydx1fzsndj35a26maujxff88q2ge5jr4nzfeljn2ez",
			"equity": "0",
			"freeCollateral": "0",
			"openPerpetualPositions": {},
			"marginEnabled": true,
			"subaccountNumber": 1,
			"assetPositions": {},
			"updatedAtHeight": "27770289",
			"latestProcessedBlockHeight": "28193227"
		}, {
			"equity": "0",
			"openPerpetualPositions": {},
			"marginEnabled": true,
			"updatedAtHeight": "28063818",
			"latestProcessedBlockHeight": "28193227",
			"subaccountNumber": 128,
			"freeCollateral": "0",
			"assetPositions": {},
			"address": "dydx1fzsndj35a26maujxff88q2ge5jr4nzfeljn2ez"
		}],
		"totalTradingRewards": "0.021744179376211564"
	},
	"Stocks": 0,
	"FrozenStocks": 0,
	"Balance": 300.386228,
	"FrozenBalance": 0,
	"Equity": 300.386228,
	"UPnL": 0
}

3 - Consultez les informations sur le marché

Pas de connexion au réseau de test, test avec le réseau principal

function main() {
    var markets = exchange.GetMarkets()
    if (!markets) {
        throw "get markets error"
    }
    var tbl = {type: "table", title: "test markets", cols: ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"], rows: []}
    for (var symbol in markets) {
        var market = markets[symbol]
        tbl.rows.push([symbol, market.Symbol, market.BaseAsset, market.QuoteAsset, market.TickSize, market.AmountSize, market.PricePrecision, market.AmountPrecision, market.MinQty, market.MaxQty, market.MinNotional, market.MaxNotional, market.CtVal])
    }
    LogStatus("`" + JSON.stringify(tbl) +  "`")
}

img

4ème ligne

function main() {
    // 切换测试链的索引器地址
    exchange.SetBase("https://indexer.v4testnet.dydx.exchange")

    // 切换测试链的ChainId 
    exchange.IO("chainId", "dydx-testnet-4")

    // 切换测试链的REST节点地址
    exchange.IO("restApiBase", "https://dydx-testnet-api.polkachu.com")

    // 限价单,挂单
    var idSell = exchange.CreateOrder("ETH_USD.swap", "sell", 4000, 0.002)
    var idBuy = exchange.CreateOrder("ETH_USD.swap", "buy", 3000, 0.003)

    // 市价单
    var idMarket = exchange.CreateOrder("ETH_USD.swap", "buy", -1, 0.01)

    Log("idSell:", idSell)
    Log("idBuy:", idBuy)
    Log("idMarket:", idMarket)
}

img

La page d'application dYdX v4 est ici:

img

5 Informations sur les commandes

Le réseau de test suspend deux commandes à l'avance, le test obtient la liste d'attente actuelle et annule la commande.

function main() {    
    // 切换测试链的索引器地址
    exchange.SetBase("https://indexer.v4testnet.dydx.exchange")

    // 切换测试链的ChainId 
    exchange.IO("chainId", "dydx-testnet-4")

    // 切换测试链的REST节点地址
    exchange.IO("restApiBase", "https://dydx-testnet-api.polkachu.com")

    var orders = exchange.GetOrders()
    Log("orders:", orders)
    for (var order of orders) {
        exchange.CancelOrder(order.Id, order)
        Sleep(2000)
    }

    var tbl = {type: "table", title: "test GetOrders", cols: ["Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], rows: []}
    for (var order of orders) {
        tbl.rows.push([order.Id, order.Price, order.Amount, order.DealAmount, order.AvgPrice, order.Status, order.Type, order.Offset, order.ContractType])
    }
    LogStatus("`" + JSON.stringify(tbl) +  "`")
}

img

6°) Rechercher des informations sur le stockage

function main() {
    // 切换测试链的索引器地址
    exchange.SetBase("https://indexer.v4testnet.dydx.exchange")

    // 切换测试链的ChainId 
    exchange.IO("chainId", "dydx-testnet-4")

    // 切换测试链的REST节点地址
    exchange.IO("restApiBase", "https://dydx-testnet-api.polkachu.com")

    var p1 = exchange.GetPositions("USD.swap")
    var p2 = exchange.GetPositions("ETH_USD.swap")
    var p3 = exchange.GetPositions()
    var p4 = exchange.GetPositions("SOL_USD.swap")

    var tbls = []
    for (var positions of [p1, p2, p3, p4]) {
        var tbl = {type: "table", title: "test GetPosition/GetPositions", cols: ["Symbol", "Amount", "Price", "FrozenAmount", "Type", "Profit", "Margin", "ContractType", "MarginLevel"], rows: []}
        for (var p of positions) {
            tbl.rows.push([p.Symbol, p.Amount, p.Price, p.FrozenAmount, p.Type, p.Profit, p.Margin, p.ContractType, p.MarginLevel])
        } 
        tbls.push(tbl)
    }

    LogStatus("`" + JSON.stringify(tbls) +  "`")
}

img

Gérer les sous-comptes

function main() {
    // 切换测试链的索引器地址
    exchange.SetBase("https://indexer.v4testnet.dydx.exchange")

    // 切换测试链的ChainId 
    exchange.IO("chainId", "dydx-testnet-4")

    // 切换测试链的REST节点地址
    exchange.IO("restApiBase", "https://dydx-testnet-api.polkachu.com")

    // subAccountNumber 0 -> 128 : 20 USDC , Gas Fee 为 adv4tnt 即 dydx token
    var ret = exchange.IO("transferUSDCToSubaccount", 0, 128, "adv4tnt", 20)  
    Log("ret:", ret)

    // 切换到子账号subAccountNumber 128 ,读取账户信息检查
    exchange.IO("subAccountNumber", 128)

    var account = exchange.GetAccount()
    Log("account:", account)
}

img

Le nombre de sous-accounts de 128 est remplacé par le nombre de sous-accounts que GetAccount renvoie:

{
	"Info": {
		"subaccounts": [{
			"subaccountNumber": 0,
			"assetPositions": {
				"USDC": {
					"size": "245.696892",
					"symbol": "USDC",
					"side": "LONG",
					"assetId": "0",
					"subaccountNumber": 0
				}
			},
			"updatedAtHeight": "28194977",
			"latestProcessedBlockHeight": "28195008",
			"address": "dydx1fzsndj35a26maujxff88q2ge5jr4nzfeljn2ez",
			"freeCollateral": "279.5022142346",
			"openPerpetualPositions": {
				"ETH-USD": {
					"closedAt": null,
					"size": "0.01",
					"maxSize": "0.01",
					"exitPrice": null,
					"unrealizedPnl": "-0.17677323",
					"subaccountNumber": 0,
					"status": "OPEN",
					"createdAt": "2024-12-26T03:36:09.264Z",
					"createdAtHeight": "28194494",
					"sumClose": "0",
					"netFunding": "0",
					"market": "ETH-USD",
					"side": "LONG",
					"entryPrice": "3467.2",
					"realizedPnl": "0",
					"sumOpen": "0.01"
				}
			},
			"marginEnabled": true,
			"equity": "280.19211877"
		}, {
			"openPerpetualPositions": {},
			"assetPositions": {},
			"marginEnabled": true,
			"latestProcessedBlockHeight": "28195008",
			"address": "dydx1fzsndj35a26maujxff88q2ge5jr4nzfeljn2ez",
			"subaccountNumber": 1,
			"equity": "0",
			"freeCollateral": "0",
			"updatedAtHeight": "27770289"
		}, {
			"openPerpetualPositions": {},
			"updatedAtHeight": "28194977",
			"latestProcessedBlockHeight": "28195008",
			"address": "dydx1fzsndj35a26maujxff88q2ge5jr4nzfeljn2ez",
			"subaccountNumber": 128,
			"assetPositions": {
				"USDC": {
					"assetId": "0",
					"subaccountNumber": 128,
					"size": "20",
					"symbol": "USDC",
					"side": "LONG"
				}
			},
			"marginEnabled": true,
			"equity": "20",
			"freeCollateral": "20"
		}],
		"totalTradingRewards": "0.021886899964446858"
	},
	"Stocks": 0,
	"FrozenStocks": 0,
	"Balance": 20,
	"FrozenBalance": 0,
	"Equity": 20,
	"UPnL": 0
}

Vous pouvez voir que le numéro de sous-compte est 128 et est converti en 20 USD.

8°, accéder à TxHash et appeler l'interface du nœud REST

Obtenir TxHash sur commande, tester les méthodes d'appel des nœuds REST par IO

Comment obtenir le TxHash de l'ordre, l'objet dydx cache TxHash et peut être consulté avec l'ID de l'ordre.

function main() {
    // 切换测试链的索引器地址
    exchange.SetBase("https://indexer.v4testnet.dydx.exchange")

    // 切换测试链的ChainId 
    exchange.IO("chainId", "dydx-testnet-4")

    // 切换测试链的REST节点地址
    exchange.IO("restApiBase", "https://dydx-testnet-api.polkachu.com")

    var id1 = exchange.CreateOrder("ETH_USD.swap", "buy", 3000, 0.002)
    var hash1 = exchange.IO("getTxHash", id1)
    Log("id1:", id1, "hash1:", hash1)

    var id2 = exchange.CreateOrder("ETH_USD.swap", "buy", 2900, 0.003)
    var hash2 = exchange.IO("getTxHash", id2)
    Log("id2:", id2, "hash2:", hash2)
    
    // 清空映射表可以使用:exchange.IO("getTxHash", "")
    var arr = [hash1, hash2]
    
    Sleep(10000)
    for (var txHash of arr) {
        // GET https://docs.cosmos.network   /cosmos/tx/v1beta1/txs/{hash}
        var ret = exchange.IO("api", "GET", "/cosmos/tx/v1beta1/txs/" + txHash)
        Log("ret:", ret)
    }
}

img

Les messages demandés par TxHash:

Le taux de changeexchange.IO"api", GET, /cosmos/tx/v1beta1/txs/ + txHash)

Le contenu est trop long et une partie de la démonstration est choisie:

{
	"tx_response": {
		"codespace": "",
		"code": 0,
		"logs": [],
		"info": "",
		"height": "28195603",
		"data": "xxx",
		"raw_log": "",
		"gas_wanted": "-1",
		"gas_used": "0",
		"tx": {
			"@type": "/cosmos.tx.v1beta1.Tx",
			"body": {
				"messages": [{
					"@type": "/dydxprotocol.clob.MsgPlaceOrder",
					"order": {
						"good_til_block_time": 1742961542,
						"condition_type": "CONDITION_TYPE_UNSPECIFIED",
						"order_id": {
							"clob_pair_id": 1,
							"subaccount_id": {
								"owner": "xxx",
								"number": 0
							},
							"client_id": 2999181974,
							"order_flags": 64
						},
						"side": "SIDE_BUY",
						"quantums": "3000000",
						"client_metadata": 0,
						"conditional_order_trigger_subticks": "0",
						"subticks": "2900000000",
						"time_in_force": "TIME_IN_FORCE_UNSPECIFIED",
						"reduce_only": false
					}
				}],
				"memo": "FMZ",
				"timeout_height": "0",
				"extension_options": [],
				"non_critical_extension_options": []
			},
      ...

La fin

Le test ci-dessus, basé sur le dernier hôte, nécessite le téléchargement du dernier hôte pour prendre en charge dYdX v4 DEX

Merci pour votre soutien et merci de lire.


Plus de