Die Ressourcen sind geladen. Beförderung...

DEX-Börsen Quantitative Praxis ((1)-- dYdX v4 Benutzerhandbuch

Schriftsteller:Die Erfinder quantifizieren - Kleine Träume, Erstellt: 2024-12-24 17:09:32, aktualisiert: 2024-12-26 21:41:46

[TOC]

img

Vorwort

Mit dem rasanten Aufstieg dezentraler Börsen (DEX) in der Kryptowährungsbranche begannen Quantitative Händler, sich auf diese Plattformen zu wenden, um effizient und automatisiert zu handeln. Als eine der beliebtesten dezentralen Handelsplattformen bietet dYdX leistungsstarke Handelsfunktionen und unterstützt den Handel mit Futures Forever Contracts.

Dieser Artikel beschreibt, wie man quantitative Handelspraktiken auf dYdX v4 durchführt, einschließlich der Verwendung der API, um zu handeln, Marktdaten zu erhalten und Konten zu verwalten.

  • Testumgebungswechsel
  • Marktinformationsanfragen
  • Bestellinformationen, Lagerinformationen
  • Nachfolgender Deal
  • Verwalten von Unterkonten
  • Anfrage für die Methode

dYdX v4 DEX

  • dYdX Testing Web App Seite

    img

  • unddYdX v3Und es gibt auch Belohnungen, Belohnungen.dYdXIch bin ein großer Freund von Ihnen.

    img

Anschlüsse, Anmeldungen und Profi-Informationen

Die DEX-Börse für den vorherigen dYdX v3-Protokoll ist abgesperrt. Die App-Adresse für die dYdX v4-App lautet:

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

Wenn Sie die App-Seite öffnen, finden Sie oben rechts eine Schaltfläche zum Anschließen einer Brieftasche und einen Scancode zum Anschließen einer Brieftasche.

Wenn Sie sich mit Testnetz-Umgebungstests vertraut machen möchten, können Sie Testnetz verwenden:

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

In der oberen rechten Ecke klickt man auf die Schaltfläche "Connect Wallet", "Scan Code Connect Wallet", "Signature Verification". Nach erfolgreicher Verbindung erzeugt die Wallet automatisch eine Dydx v4-Adresse, die in der oberen rechten Ecke der App-Seite angezeigt wird.

  • dYdX v4 Kontoadresse Die dYdX v4-Kontoadresse ist von der Wallet-Adresse abgeleitet und sieht so aus:dydx1xxxxxxxxxxxxxxxxxxxxq2ge5jr4nzfeljxxxx, ist die Adresse, an der dydx1 beginnt. Diese Adresse kann in Blockchain Explorers abgerufen werden.

  • Hilfsbegriff Mit dem "Export Passwort" Klick in der oberen rechten Ecke des Menüs können Sie die Passwörter des aktuellen dYdX-Adresskontos exportieren.

    Die Hilfswörter können direkt in der FMZ-Plattform konfiguriert werden, aber auch lokal für Administratoren gespeichert werden.

Unterschiede zwischen Hauptnetz und Testnetz

Die Testnetz-Umgebung unterscheidet sich in einigen Punkten von der Hauptnetz-Umgebung.

  • Die Vermögensverteilung der Unterkonten. Das Hauptnetzwerk verfügt über eine Sub-Account-Reinigung.subAccountNumber >= 128Wenn das Subkonto der ID nicht auf Lager ist, werden die Vermögenswerte automatisch auf das Subkonto mit der SubAccountNumber 0 gelöscht. In Tests wurde festgestellt, dass das Testnetz keinen solchen Mechanismus hat (oder die Auslöserbedingungen sind unterschiedlich und es wurde kein Auslöser im Testnetz gefunden).
  • Einige Token-Namen. Der ursprüngliche Token Dydx wurde anders benannt:DYDXTestnetzDv4TNT
  • Adresskonfigurationen, wie z.B. Kette-ID, Knoten-Adresse, Index-Adresse usw.; Es gibt viele Knoten und Konfigurationen, hier eine davon:
    • Hauptseite: Die Indexadresse ist:https://indexer.dydx.tradeDie Kette-ID:dydx-mainnet-1REST-Knoten:https://dydx-dao-api.polkachu.com:443

    • Testnetz: Die Indexadresse ist:https://indexer.v4testnet.dydx.exchangeDie Kette-ID:dydx-testnet-4REST-Knoten:https://dydx-testnet-api.polkachu.com

dYdX v4 Protokollarchitektur

Die dYdX v4 Protokolle basieren auf der Cosmos Ökosystementwicklung.

  • Der Index ist für Anfragen wie Marktinformationen, Kontoinformationen und andere zuständig.
  • Dydx-Blockchain-Bestellnachrichten, Rücktrittsnachrichten, Überweisungsnachrichten usw.

Index

Der Indexdienst verfügt über den REST-Protokoll und den Websocket-Protokoll.

  • REST-Protokoll Die REST-Protokoll-Schnittstelle unterstützt Abfragen von Marktinformationen, Kontoinformationen, Lagerinformationen, Bestellinformationen, die in der FMZ-Plattform als plattformuniforme API-Schnittstelle verpackt sind.

  • WebSocket-Protokoll Auf der FMZ-Plattform können Sie mit der Dial-Funktion Websocket-Verbindungen, Abonnements und andere Informationen erstellen.

Ein Problem, auf das sich die Dialoge von Dydx v4 bei zentralisierten Transaktionen konzentrieren, ist, dass die Daten nicht so rechtzeitig aktualisiert werden, zum Beispiel manchmal sofort nach der Bestellung abgerufen werden.Sleep(n)(Wartet ein paar Sekunden und fragt nach.)

Hier ist ein Beispiel, wie man mit der Dial-Funktion eine Websocket-API-Verbindung erstellt, um dünne Daten zu bestellen:

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-Kettenknoten Nachrichten übertragen

Die am häufigsten verwendeten in den Transaktionen sind Bestellmeldungen, Widerrufsmeldungen und Überweisungsmeldungen.

  • Bestellungsnachrichten

    {
      "@type": "/dydxprotocol.clob.MsgPlaceOrder",
      "order": {
        "orderId": {
          "subaccountId": {
            "owner": "xxx"
          },
          "clientId": xxx,
          "orderFlags": 64,
          "clobPairId": 1
        },
        "side": "SIDE_BUY",
        "quantums": "2000000",
        "subticks": "3500000000",
        "goodTilBlockTime": 1742295981
      }
    }
    
    • Preisbeschränkung: Die auf der FMZ-Plattform verpackte Auftragsfunktion und die OrderFlags für limitierte Bestellungen werden als:ORDER_FLAGS_LONG_TERM = 64 # 长期订单Die längste Bestelldauer, also 90 Tage, wird verwendet (alle Bestelltypen auf Dydx v4 sind gültig).

    • Preisliste: Die auf der FMZ-Plattform verpackte Auftragsfunktion und die Orderflags, die für Marktpreis-Aufträge verwendet werden, werden als:ORDER_FLAGS_SHORT_TERM = 0 # 短期订单Das ist eine sehr schwierige Sache, aber es gibt viele Möglichkeiten, wie man das tun kann.

      // empfehlen Sie auf Oracle Preis - 5% oder niedriger für SELL, Oracle Preis + 5% für BUY

      Da es sich nicht um eine echte Marktliste handelt, wird der Preis des Predictors und der Preis minus 5% als Marktliste verwendet. Die Gültigkeitsspanne für kurzfristige Aufträge unterscheidet sich auch von der für langfristige Aufträge. Kurzfristige Aufträge haben eine hohe Gültigkeitsspanne für Blöcke, die nach den Empfehlungen von Dydx v4 auf den aktuellen Block + 10 Blockhöhen gesetzt ist.

    • Bestell-ID: Da die Auftragsoperation direkt auf der Kette durchgeführt wird, gibt es keine Index-generierte Auftrags-ID nach der Nachrichtenausstrahlung und kann keine Index-Auftrags-Wert als Rückgabe der Plattform-Auftragsfunktion verwendet werden. Um die Einzigartigkeit der Auftrags-ID und die Richtigkeit der Auftragssuche zu gewährleisten, besteht die zurückgegebene Auftrags-ID aus der folgenden Information:

      • Die Transaktion stimmt
      • Die aktuelle Adresse für das DYDX-Konto
      • Unterkonto-Nummer
      • ClientId (zufällig erzeugt)
      • clobPairId (Transaktionsart-ID)
      • AnordnungFlaggen
      • goodTilData ((Millisekunden))
  • Abzug der Nachrichten

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

    Die Bestell-ID, die in der FMZ-Plattform hinterlegt werden muss, wird von der Anschluss-Schnittstelle zurückgegeben.

  • Überweisungsnachrichten

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

    Derzeit können viele Unterkonten unter der Dydx v4-Adresse erstellt werden, wobei die SubAccountNumber 0 die erste automatisch erstellte Unterkonto ist, die SubAccountNumber höher ist als die SubaccountID, die 128 entspricht. Beispielsweise kann man von SubAccountNumber 0 -> 128 oder von SubAccountNumber 128 -> 0 abrufen.

FMZ-Plattform dYdX v4 Praxis

Die oben beschriebenen Informationen beschreiben einige Packungsdetails. Im Folgenden werden wir die praktischen Anwendungen demonstrieren. Hier wird mit einem Testnetz von dYdX v4 gezeigt, das im Wesentlichen mit dem Hauptnetz übereinstimmt und einen automatischen Wasserhahn hat, der die Testwerte abrufen kann.

1, Konfiguration

Nach erfolgreicher Verbindung der dYdX v4 App mit der Kryptowährungsgeldbörse (imToken-Geldbörse, die ich hier verwende) wird der Testvermögen übernommen und der aktuelle dYdX v4-Account (aus der Geldbörse abgeleitet) ausgeführt.

img

Konfigurieren Sie das Befehlswort auf der FMZ-Plattform, wo wir es mit der lokalen Dateikonfiguration konfigurieren (auch direkt ausfüllen und auf die Plattform konfigurieren können, das Befehlswort ist nach der Konfiguration verschlüsselt und nicht offen).

  • 助记词文件:mnemonic.txt

    img

    Sie können sie natürlich auch in andere Verzeichnisse (wenn Sie einen bestimmten Pfad benötigen, wenn Sie sie konfigurieren) platzieren.

  • Konfigurieren Sie die Börse auf FMZ

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

    Das ist ein sehr schwieriges Thema, aber es gibt viele Möglichkeiten.file:///mnemonic.txtDer praktische Weg ist folgender:托管者所在目录/logs/storage/594291

    img

2. Wechseln Sie zum Dydx v4 Testnetz

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()) 
}

Sie können die Testnetz-Kontoinformationen hier lesen:

{
	"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. Nachfrage nach Marktinformationen

Test mit dem Hauptnetz ohne Testnetz.

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. Nach unten

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

Die Seite der dYdX v4 App:

img

5. Bestellinformationen

Das Testnetz hängt zwei Bestellungen im Voraus auf, erhält die aktuelle Bestellung und widerruft die Bestellung.

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. Nachfragen nach Informationen

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

7. Unterkontoverwaltung

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

Die Daten, die GetAccount zurückgibt:

{
	"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
}

Sie können sehen, dass die SubAccountNumber 128 für das Subkonto ist, das in 20 USDC umgerechnet wurde.

8. Erhalten Sie TxHash und rufen Sie die REST-Node-Schnittstelle an

Erhalten von TxHash, Testmethoden für IO-REST-Nodes auf Bestellung

Wie man den TxHash eines Auftrags erhält, wird der Exchange-Objekt dydx von TxHash gespeichert und kann mit der Order-ID abgerufen werden.

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

Nachrichten, die von TxHash gesucht wurden:

VAR RET =exchange.IO(Api, GET, /cosmos/tx/v1beta1/txs/ + txHash)

Der Inhalt ist zu lang, und ein ausgewählter Teil zeigt:

{
	"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": []
			},
      ...

Das Ende

Der Test basiert auf dem neuesten Host, der für die Unterstützung von dYdX v4 DEX heruntergeladen werden muss

Danke für die Unterstützung und danke fürs Lesen.


Mehr