Bitget App
交易“智”变
行情交易合约跟单BOT理财Web3
深入解析MUD引擎的存储架构

深入解析MUD引擎的存储架构

MarsBitMarsBit2024/03/16 06:15
作者:alvarius

MUD引擎解决了游戏开发中的难题,通过泛型事件机制实现自动同步状态。它能接受任意类型数组并返回紧凑打包字节,无需自定义getter、event和reducer。通过代码生成,MUD能为您生成具有类型信息的读写库,每次写入操作都会自动同步。经过OpenZeppelin的审计,稳定版2.0.0即将发布。 摘要由 Mars AI 生成 本摘要由 Mars AI 模型生成,其生成内容的准确性、完整性还处于迭代更新阶段。

三年前,当我们开始开发全链上游戏时,开发体验还非常糟糕。因此,我们创建了MUD引擎,以减少开发过程中遇到的各种难题。

接下来,我将详细介绍我们是如何在开发过程中逐步完善,并最终实现了当前的存储架构。

深入解析MUD引擎的存储架构 image 0

回看2021年(即MUD成立的前一年),我们按照当时的“最佳实践”在自定义的结构体(custom struct)、映射(mapping)和数组(array)中保存链上状态,通过自定义的查看函数(view function)来获取状态,对每一次状态变化编写自定义的事件(custom event),并在客户端和索引器上实现自定义事件处理的reducer函数。

深入解析MUD引擎的存储架构 image 1

这种方法对于小规模的链上应用是可行的,但是全链游戏需要与客户端同步大量的状态数据。很快,我们发现自己大部分时间都在处理数据模型的变更,并通过他们自定义的网络堆栈来实现这些变更,而不是将精力集中在游戏机制的开发上。

深入解析MUD引擎的存储架构 image 2

当开发过程中遇到的困难和挑战变得难以忍受时,我们决定暂停一下,重新思考理想中的开发体验应该是什么样的。

我们唯一的愿望是在智能合约上设置一个状态变量,并且能够自动地与客户端同步,不用自定义getter、 event和reducer,只需简单地读写状态。

深入解析MUD引擎的存储架构 image 3

解决方案的第一步是实现一种泛型事件(generic event),他能在每次状态变更时被触发,使得索引器或客户端能够自动同步链上的状态。

深入解析MUD引擎的存储架构 image 4

但问题是,在Solidity中并没有现成的“泛型事件”。不过,我们还是找到了替代方案。

本质上,类型(Type)不过是对字节(Byte)的一层封装。因此,我们通过使用原始字节(raw byte)作为事件数据,实现了一种能够覆盖所有状态变更的通用事件机制。

深入解析MUD引擎的存储架构 image 5

接下来,我们需要一个能够在每次状态变化时触发事件的泛型库(generic library),从而避免自定义setter函数的需求。

深入解析MUD引擎的存储架构 image 6

虽然Solidity并没有提供这样的泛型库,但我们采用了类似的策略来实现这一目标。我们没有使用泛型类型(generic type),而是选用了所有类型(type)的共同基础——字节,作为函数签名的参数。

深入解析MUD引擎的存储架构 image 7

这带来了一个新的挑战:如何将各种类型的数据转换成字节,再传递给这个库呢?最直接的方法是使用Solidity内置的 abi.encode 函数。然而,它因为到处添加填充而不适用于存储编码后的值。

深入解析MUD引擎的存储架构 image 8

一个更好的选择是使用 abi.encodePacked 函数,它能够紧凑地打包数据,避免了冗余填充。不过这个方法不能应用于数组(array)类型。

深入解析MUD引擎的存储架构 image 9

为此,我们不得不在Solidity中自行实现数组的紧凑编码方法。这种方法类似于提案中的abi.encodeTightlyPacked(https://github.com/ethereum/solidity/issues/8441…)。

深入解析MUD引擎的存储架构 image 10

深入一步,我们如何实现一个Solidity函数,使其能够接受任何类型的数组并返回其紧凑打包的字节形式呢?我们首先为所有基本类型数组的共同基础——bytes32[] 实现打包逻辑。

深入解析MUD引擎的存储架构 image 11

然后,我们为Solidity支持的98种基本类型数组(如uint8[], uint16[], ..., bytes32[])各添加了一个特定的处理逻辑。这样,我们便拥有了一个能接受任意基本类型数组并返回其紧凑打包字节的函数。

我们越来越接近目标了。

深入解析MUD引擎的存储架构 image 12

最后的挑战是如何从存储中读取并解码这些值。我们需要一个类似于 abi.decode 的函数,但是要适用于我们自定义的紧凑编码方式:一个能够根据给定的编码字节和一个“模式(schema)”来返回解码值及其原类型的函数。

深入解析MUD引擎的存储架构 image 13

由于Solidity不支持通用返回类型,我们也无法像之前一样将其转化为通用类型。于是,我们转而采用了代码生成的方式。您只需要在一个配置文件中定义您的数据结构,MUD就能为你生成具有类型信息的读写库。

深入解析MUD引擎的存储架构 image 14

至此,我们实现了目标!

无需任何自定义的getter、event和reducer。只需简单地进行读写操作。每一次状态的写入操作都会触发一个事件,该事件用于自动将链上状态同步至索引器和客户端。

深入解析MUD引擎的存储架构 image 15

虽然Solidity本身不支持泛型类型,但通过一些巧妙的技巧,我们仍能实现理想中的开发体验。

深入解析MUD引擎的存储架构 image 16

我们投入大量时间开发MUD引擎,旨在提升构建可扩展的全链上应用的开发体验。如今,MUD已通过OpenZeppelin的全面审计,稳定版2.0.0即将发布。

0

免责声明:文章中的所有内容仅代表作者的观点,与本平台无关。用户不应以本文作为投资决策的参考。

PoolX:锁仓获得新代币空投
不要错过热门新币,且APR 高达 10%+
立即参与!

你也可能喜欢

Thesis分拆项目Acre斩获400万美元融资,比特币质押赛道估值突破9000万美元

在数字货币领域,每一次重大的融资事件和市场估值的变化都牵动着投资者和从业者的心。近日,Thesis分拆项目Acre成功斩获400万美元融资,与此同时,比特币质押赛道的估值突破了9000万美元。这一消息犹如一颗重磅炸弹,在币圈引起了广泛的

币界网2025/02/21 13:24

矿工投降潮背后:算力战升级触发比特币“人为熊市”

近期,比特币市场掀起了一股不小的波澜,矿工投降潮成为了行业内热议的话题。比特币作为加密货币领域的龙头,其市场动态一直备受关注。而此次矿工投降潮的出现,更是引发了市场参与者的高度警觉。这一现象不仅反映了比特币市场当前的复

币界网2025/02/21 13:16

特朗普加密政策摇摆,比特币“10万关口”遭政治博弈狙击?

近期,比特币市场再次成为全球金融领域的焦点,其价格一路攀升,不断逼近“10万关口”。这一关键价位的临近引发了市场的广泛关注和热议,投资者们翘首以盼,期待着比特币能够创造新的历史。比特币作为加密货币的代表,其价格的波动不仅影响

币界网2025/02/21 13:12

Mt.Gox 90亿美元比特币还款启动,幕后操盘手借利空“砸盘”?

Mt.Gox曾经是全球最大的比特币交易平台,在2014年却因被盗约85万枚比特币而宣告破产,这一事件成为了比特币发展史上的重大挫折,严重打击了投资者对加密货币市场的信心。如今,时隔多年,Mt.Gox的90亿美元比特币还款计划正式启动,这一消息

币界网2025/02/21 13:02