首頁 後端開發 Golang Starknet 交易批量處理程序

Starknet 交易批量處理程序

Dec 31, 2024 pm 05:54 PM

抽象的

本文介紹了 Metacube 中使用的交易批次程序,用於即時發送玩家賺取的 NFT。它解釋了批次程式基於參與者的可擴展架構,並提供了 Go 中的詳細實作。

所有程式碼片段都可以在關聯的 GitHub 儲存庫中找到。

建築學

A Starknet transactions batcher

巴徹由兩位主要演員組成:

  • Builder 接收交易,將它們批次成單一多重呼叫交易,並將其傳送給 Sender actor。
  • 發送者使用適當的字段(隨機數、最大費用等)完成交易,對其進行簽名,將其發送到 Starknet 網絡,並監控其狀態。

這種參與者分離可以實現可擴展且高效的批次程序。建構器在發送者發送交易時準備交易,從而實現連續且高效的交易流。

執行

以下實作特定於 Go,但這些概念可以輕鬆適應其他語言,因為功能保持不變。

此外,請注意,此實作特定於從同一合約發送 NFT。然而,本文後面提到了一種更通用的方法。

最後,程式碼是基於Nethermind開發的starknet.go函式庫。

批次處理機

讓我們從 Batcher 本身開始:

type Batcher struct {
    accnt           *account.Account
    contractAddress *felt.Felt
    maxSize         int
    inChan          <-chan []string
    failChan        chan<- []string
}
登入後複製
登入後複製

帳戶(accnt)是持有NFT的帳戶,它將用於簽署轉移NFT的交易。這些 NFT 是同一合約的一部分,因此有合約地址欄位。 maxSize 欄位是批次的最大大小,inChan 是將交易傳送到 Batcher 的通道。 failChan 用於發回發送失敗的交易。

請注意,在這個實作中,後面所說的交易資料([]string)是一個由兩個元素組成的陣列:接收者位址和 NFT ID。

Batcher 同時執行 Builder 和 Sender Actor:

type TxnDataPair struct {
    Txn  rpc.BroadcastInvokev1Txn
    Data [][]string
}

func (b *Batcher) Run() {
    txnDataPairChan := make(chan TxnDataPair)

    go b.runBuildActor(txnDataPairChan)
    go b.runSendActor(txnDataPairChan)
}
登入後複製
登入後複製

定義的通道 txnDataPairChan 將交易資料對從 Builder 傳送到 Sender。每個交易資料對都包含大量交易,每個交易的資料都嵌入其中。每筆交易的資料都與大量交易一起發送,以便失敗的交​​易可以發送回實例化 Batcher 的實體。

建設者

讓我們來分析一下Build actor。請注意,為了更好的可讀性,程式碼已被簡化(完整程式碼):

type Batcher struct {
    accnt           *account.Account
    contractAddress *felt.Felt
    maxSize         int
    inChan          <-chan []string
    failChan        chan<- []string
}
登入後複製
登入後複製

runBuildActor 函數是 Builder actor 的事件循環。它等待事務發送到批次程序,並在批次已滿或達到逾時時建置批次事務。然後批量交易被發送到 Sender actor。

寄件人

現在讓我們來分析一下Sender actor。請注意,為了更好的可讀性,程式碼已被簡化(完整程式碼):

type TxnDataPair struct {
    Txn  rpc.BroadcastInvokev1Txn
    Data [][]string
}

func (b *Batcher) Run() {
    txnDataPairChan := make(chan TxnDataPair)

    go b.runBuildActor(txnDataPairChan)
    go b.runSendActor(txnDataPairChan)
}
登入後複製
登入後複製

runSendActor 函數是傳送者 Actor 的事件循環。它等待 Builder 發送批量交易,對它們進行簽名,將它們發送到 Starknet 網絡,並監控它們的狀態。

關於費用估算的說明:可以在發送之前估算批量交易的費用成本。交易簽名後可加入以下程式碼:

// This function builds a function call from the transaction data.
func (b *Batcher) buildFunctionCall(data []string) (*rpc.FunctionCall, error) {
    // Parse the recipient address
    toAddressInFelt, err := utils.HexToFelt(data[0])
    if err != nil {
        ...
    }

    // Parse the NFT ID
    nftID, err := strconv.Atoi(data[1])
    if err != nil {
        ...
    }

    // The entry point is a standard ERC721 function
    // https://docs.openzeppelin.com/contracts-cairo/0.20.0/erc721
    return &rpc.FunctionCall{
        ContractAddress: b.contractAddress,
        EntryPointSelector: utils.GetSelectorFromNameFelt(
            "safe_transfer_from",
        ),
        Calldata: []*felt.Felt{
            b.accnt.AccountAddress, // from
            toAddressInFelt, // to
            new(felt.Felt).SetUint64(uint64(nftID)), // NFT ID
            new(felt.Felt).SetUint64(0), // data -> None
            new(felt.Felt).SetUint64(0), // extra data -> None
        },
    }, nil
}

// This function builds the batch transaction from the function calls.
func (b *Batcher) buildBatchTransaction(functionCalls []rpc.FunctionCall) (rpc.BroadcastInvokev1Txn, error) {
    // Format the calldata (i.e., the function calls)
    calldata, err := b.accnt.FmtCalldata(functionCalls)
    if err != nil {
        ...
    }

    return rpc.BroadcastInvokev1Txn{
        InvokeTxnV1: rpc.InvokeTxnV1{
            MaxFee:        new(felt.Felt).SetUint64(MAX_FEE),
            Version:       rpc.TransactionV1,
            Nonce:         new(felt.Felt).SetUint64(0), // Will be set by the send actor
            Type:          rpc.TransactionType_Invoke,
            SenderAddress: b.accnt.AccountAddress,
            Calldata:      calldata,
        },
    }, nil
}

// Actual Build actor event loop
func (b *Batcher) runBuildActor(txnDataPairChan chan<- TxnDataPair) {
    size := 0
    functionCalls := make([]rpc.FunctionCall, 0, b.maxSize)
    currentData := make([][]string, 0, b.maxSize)

    for {
        // Boolean to trigger the batch building
        trigger := false

        select {
        // Receive new transaction data
        case data, ok := <-b.inChan:
            if !ok {
                ...
            }

            functionCall, err := b.buildFunctionCall(data)
            if err != nil {
                ...
            }

            functionCalls = append(functionCalls, *functionCall)
            size++
            currentData = append(currentData, data)

            if size >= b.maxSize {
                // The batch is full, trigger the building
                trigger = true
            }

        // We don't want a smaller batch to wait indefinitely to be full, so we set a timeout to trigger the building even if the batch is not full
        case <-time.After(WAITING_TIME):
            if size > 0 {
                trigger = true
            }
        }

        if trigger {
            builtTxn, err := b.buildBatchTransaction(functionCalls)
            if err != nil {
                ...
            } else {
                // Send the batch transaction to the Sender
                txnDataPairChan <- TxnDataPair{
                    Txn:  builtTxn,
                    Data: currentData,
                }
            }

            // Reset variables
            size = 0
            functionCalls = make([]rpc.FunctionCall, 0, b.maxSize)
            currentData = make([][]string, 0, b.maxSize)
        }
    }
}
登入後複製

這可能有助於確保在發送交易之前費用不會太高。如果估計費用高於預期,則可能還需要重新調整交易的最大費用欄位。但請注意,當交易發生任何更改時,必須重新簽名!

但請注意,如果交易吞吐量相當高,您在估算費用時可能會遇到一些問題。這是因為當給定的交易剛剛被批准時,更新帳戶的隨機數字會有一點延遲。因此,在估計下一筆交易的費用時,它可能會失敗,認為隨機數字仍然是前一筆交易。因此,如果您仍然想估算費用,那麼您可能需要在每筆交易之間提供一些睡眠以避免此類問題。

邁向通用批次處理機

所提供的批次程式專門用於從同一合約發送 NFT。然而,該架構可以輕鬆適應發送任何類型的交易。

首先,發送到 Batcher 的交易資料必須更加通用,因此包含更多資訊。它們必須包含合約位址、入口點選擇器和呼叫資料。然後必須調整 buildFunctionCall 函數來解析此資訊。

還可以更進一步,將寄件者帳戶設為通用。這將需要更多的重構,因為必須針對每個發送者帳戶對交易進行批次處理。然而,它是可行的,並且可以實現更通用的批次機。

但是,請記住,過早的最佳化是萬惡之源。因此,如果您只需要發送 NFT 或特定代幣(例如 ETH 或 STRK),那麼提供的批次程式就足夠了。

命令列工具

儲存庫程式碼可以用作 CLI 工具來批次發送一堆 NFT。該工具易於使用,閱讀本文後您應該能夠根據您的需求進行調整。請參閱 README 以了解更多資訊。

結論

我希望這篇文章可以幫助您更好地了解Metacube如何向其玩家發送NFT。批次程序是一個關鍵的基礎設施組件,我們很高興與社區分享它。如果您有任何問題或回饋,請隨時發表評論或與我聯繫。感謝您的閱讀!

以上是Starknet 交易批量處理程序的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Golang的目的:建立高效且可擴展的系統 Golang的目的:建立高效且可擴展的系統 Apr 09, 2025 pm 05:17 PM

Go語言在構建高效且可擴展的系統中表現出色,其優勢包括:1.高性能:編譯成機器碼,運行速度快;2.並發編程:通過goroutines和channels簡化多任務處理;3.簡潔性:語法簡潔,降低學習和維護成本;4.跨平台:支持跨平台編譯,方便部署。

Golang和C:並發與原始速度 Golang和C:並發與原始速度 Apr 21, 2025 am 12:16 AM

Golang在並發性上優於C ,而C 在原始速度上優於Golang。 1)Golang通過goroutine和channel實現高效並發,適合處理大量並發任務。 2)C 通過編譯器優化和標準庫,提供接近硬件的高性能,適合需要極致優化的應用。

表演競賽:Golang vs.C 表演競賽:Golang vs.C Apr 16, 2025 am 12:07 AM

Golang和C 在性能競賽中的表現各有優勢:1)Golang適合高並發和快速開發,2)C 提供更高性能和細粒度控制。選擇應基於項目需求和團隊技術棧。

Golang vs. Python:性能和可伸縮性 Golang vs. Python:性能和可伸縮性 Apr 19, 2025 am 12:18 AM

Golang在性能和可擴展性方面優於Python。 1)Golang的編譯型特性和高效並發模型使其在高並發場景下表現出色。 2)Python作為解釋型語言,執行速度較慢,但通過工具如Cython可優化性能。

Golang vs. Python:主要差異和相似之處 Golang vs. Python:主要差異和相似之處 Apr 17, 2025 am 12:15 AM

Golang和Python各有优势:Golang适合高性能和并发编程,Python适用于数据科学和Web开发。Golang以其并发模型和高效性能著称,Python则以简洁语法和丰富库生态系统著称。

C和Golang:表演至關重要時 C和Golang:表演至關重要時 Apr 13, 2025 am 12:11 AM

C 更適合需要直接控制硬件資源和高性能優化的場景,而Golang更適合需要快速開發和高並發處理的場景。 1.C 的優勢在於其接近硬件的特性和高度的優化能力,適合遊戲開發等高性能需求。 2.Golang的優勢在於其簡潔的語法和天然的並發支持,適合高並發服務開發。

Golang的影響:速度,效率和簡單性 Golang的影響:速度,效率和簡單性 Apr 14, 2025 am 12:11 AM

goimpactsdevelopmentpositationality throughspeed,效率和模擬性。 1)速度:gocompilesquicklyandrunseff,IdealforlargeProjects.2)效率:效率:ITScomprehenSevestAndardArdardArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdEcceSteral Depentencies,增強的Depleflovelmentimency.3)簡單性。

Golang和C:性能的權衡 Golang和C:性能的權衡 Apr 17, 2025 am 12:18 AM

Golang和C 在性能上的差異主要體現在內存管理、編譯優化和運行時效率等方面。 1)Golang的垃圾回收機制方便但可能影響性能,2)C 的手動內存管理和編譯器優化在遞歸計算中表現更為高效。

See all articles