Starknet 交易批量处理程序
你在学习Golang相关的知识吗?本文《Starknet 交易批量处理程序》,主要介绍的内容就涉及到,如果你想提升自己的开发能力,就不要错过这篇文章,大家要知道编程理论基础和实战操作都是不可或缺的哦!
抽象的
本文介绍了 metacube 中使用的交易批处理程序,用于即时发送玩家赚取的 nft。它解释了批处理程序基于参与者的可扩展架构,并提供了 go 中的详细实现。
所有代码片段都可以在关联的 github 存储库中找到。
建筑学
巴彻由两位主要演员组成:
- 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。请注意,为了更好的可读性,代码已被简化(完整代码):
// 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) } } }
runbuildactor 函数是 builder actor 的事件循环。它等待事务发送到批处理程序,并在批处理已满或达到超时时构建批处理事务。然后批量交易被发送到 sender actor。
发件人
现在让我们分析一下sender actor。请注意,为了更好的可读性,代码已被简化(完整代码):
// actual send actor event loop func (b *batcher) runsendactor(txndatapairchan <-chan txndatapair) { oldnonce := new(felt.felt).setuint64(0) for { // receive the batch transaction txndatapair, ok := <-txndatapairchan if !ok { ... } txn := txndatapair.txn data := txndatapair.data // get the current nonce of the sender account nonce, err := b.accnt.nonce( context.background(), rpc.blockid{tag: "latest"}, b.accnt.accountaddress, ) if err != nil { ... } // it might happen that the nonce is not directly updated if another transaction was sent just before. therefore, we manually increment it to make sure this new transaction is sent with the correct nonce if nonce.cmp(oldnonce) <= 0 { nonce.add(oldnonce, new(felt.felt).setuint64(1)) } txn.invoketxnv1.nonce = nonce // sign the transaction err = b.accnt.signinvoketransaction( context.background(), &txn.invoketxnv1, ) if err != nil { ... } // send the transaction to the starknet network resp, err := b.accnt.addinvoketransaction( context.background(), &txn, ) if err != nil { ... } // monitor the transaction status statusloop: for { // wait a bit before checking the status time.sleep(time.second * 5) // get the transaction status txstatus, err := b.accnt.gettransactionstatus( context.background(), resp.transactionhash, ) if err != nil { ... } // check the execution status switch txstatus.executionstatus { case rpc.txnexecutionstatussucceeded: oldnonce = nonce break statusloop case rpc.txnexecutionstatusreverted: // a reverted transaction consumes the nonce oldnonce = nonce ... break statusloop default: } // check the finality status switch txstatus.finalitystatus { case rpc.txnstatus_received: continue case rpc.txnstatus_accepted_on_l2, rpc.txnstatus_accepted_on_l1: oldnonce = nonce break statusloop case rpc.txnstatus_rejected: ... default: } // loop until the transaction status is determined } } }
runsendactor 函数是发送者 actor 的事件循环。它等待 builder 发送批量交易,对它们进行签名,将它们发送到 starknet 网络,并监控它们的状态。
关于费用估算的说明:可以在发送之前估算批量交易的费用成本。交易签名后可添加以下代码:
fee, err := b.accnt.EstimateFee( context.Background(), []rpc.BroadcastTxn{txn}, []rpc.SimulationFlag{}, rpc.WithBlockTag("latest"), ) if err != nil { ... }
这可能有助于确保在发送交易之前费用不会太高。如果估计费用高于预期,则可能还需要重新调整交易的最大费用字段。但请注意,当交易发生任何更改时,必须重新签名!
但是请注意,如果交易吞吐量相当高,您在估算费用时可能会遇到一些问题。这是因为当给定的交易刚刚被批准时,更新帐户的随机数会有一点延迟。因此,在估计下一笔交易的费用时,它可能会失败,认为随机数仍然是前一笔交易。因此,如果您仍然想估算费用,那么您可能需要在每笔交易之间提供一些睡眠以避免此类问题。
迈向通用批处理机
所提供的批处理程序专门用于从同一合约发送 nft。然而,该架构可以轻松适应发送任何类型的交易。
首先,发送到 batcher 的交易数据必须更加通用,因此包含更多信息。它们必须包含合约地址、入口点选择器和调用数据。然后必须调整 buildfunctioncall 函数来解析此信息。
还可以更进一步,将发件人帐户设为通用。这将需要更多的重构,因为必须针对每个发送者帐户对交易进行批处理。然而,它是可行的,并且可以实现更通用的批处理机。
但是,请记住,过早的优化是万恶之源。因此,如果您只需要发送 nft 或特定代币(例如 eth 或 strk),那么提供的批处理程序就足够了。
命令行工具
存储库代码可以用作 cli 工具来批量发送一堆 nft。该工具易于使用,阅读本文后您应该能够根据您的需要进行调整。请参阅 readme 了解更多信息。
结论
我希望这篇文章可以帮助您更好地了解metacube如何向其玩家发送nft。批处理程序是一个关键的基础设施组件,我们很高兴与社区分享它。如果您有任何问题或反馈,请随时发表评论或与我联系。感谢您的阅读!
理论要掌握,实操不能落!以上关于《Starknet 交易批量处理程序》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

- 上一篇
- Vue2 具名插槽展示失败,是我自己把页面弄混了?

- 下一篇
- 星云股份6.37亿元募资项目注册生效,将用于星云储能系统项目
-
- Golang · Go教程 | 14分钟前 |
- Debian下Tomcat备份恢复攻略
- 197浏览 收藏
-
- Golang · Go教程 | 2小时前 |
- Flutter在Debian官方支持揭秘
- 338浏览 收藏
-
- Golang · Go教程 | 4小时前 |
- Debian下Dumpcap流量整形实用指南
- 370浏览 收藏
-
- Golang · Go教程 | 5小时前 |
- DebianSyslog提升系统安全性指南
- 338浏览 收藏
-
- Golang · Go教程 | 5小时前 |
- Debian上Apache2的SEO优化配置指南
- 370浏览 收藏
-
- Golang · Go教程 | 5小时前 |
- Debian上Hadoop日志管理实用技巧
- 268浏览 收藏
-
- Golang · Go教程 | 15小时前 |
- Go语言time.Ticker与time.After使用差异及问题详解
- 103浏览 收藏
-
- Golang · Go教程 | 16小时前 |
- DebianSyslog在容器技术中的应用实战
- 186浏览 收藏
-
- Golang · Go教程 | 18小时前 |
- Debian系统FlutterSDK安装详细指南
- 380浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- AI Make Song
- AI Make Song是一款革命性的AI音乐生成平台,提供文本和歌词转音乐的双模式输入,支持多语言及商业友好版权体系。无论你是音乐爱好者、内容创作者还是广告从业者,都能在这里实现“用文字创造音乐”的梦想。平台已生成超百万首原创音乐,覆盖全球20个国家,用户满意度高达95%。
- 8次使用
-
- SongGenerator
- 探索SongGenerator.io,零门槛、全免费的AI音乐生成器。无需注册,通过简单文本输入即可生成多风格音乐,适用于内容创作者、音乐爱好者和教育工作者。日均生成量超10万次,全球50国家用户信赖。
- 7次使用
-
- BeArt AI换脸
- 探索BeArt AI换脸工具,免费在线使用,无需下载软件,即可对照片、视频和GIF进行高质量换脸。体验快速、流畅、无水印的换脸效果,适用于娱乐创作、影视制作、广告营销等多种场景。
- 6次使用
-
- 协启动
- SEO摘要协启动(XieQiDong Chatbot)是由深圳协启动传媒有限公司运营的AI智能服务平台,提供多模型支持的对话服务、文档处理和图像生成工具,旨在提升用户内容创作与信息处理效率。平台支持订阅制付费,适合个人及企业用户,满足日常聊天、文案生成、学习辅助等需求。
- 13次使用
-
- Brev AI
- 探索Brev AI,一个无需注册即可免费使用的AI音乐创作平台,提供多功能工具如音乐生成、去人声、歌词创作等,适用于内容创作、商业配乐和个人创作,满足您的音乐需求。
- 14次使用
-
- Golangmap实践及实现原理解析
- 2022-12-28 505浏览
-
- 试了下Golang实现try catch的方法
- 2022-12-27 502浏览
-
- Go语言中Slice常见陷阱与避免方法详解
- 2023-02-25 501浏览
-
- Golang中for循环遍历避坑指南
- 2023-05-12 501浏览
-
- Go语言中的RPC框架原理与应用
- 2023-06-01 501浏览