Bitget App
Trade smarter
行情交易合约跟单策略理财Web3

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

我们越来越接近目标了。

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

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

至此,我们实现了目标!

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

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

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

0

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

PoolX:质押赚新币
CEC、QTLX、GDV等热门新币火热进行中!
立即质押!

你也可能喜欢

REEFUSDT 现已上线合约交易

Bitget 已于2024年9月20日(UTC+8)上线 REEFUSDT 合约交易,最大杠杆为50倍。 欢迎通过我们的官方网站或 Bitget APP 开始合约交易。 REEF U本位永续合约: 合约参数 详情 上线时间 2024年9月20日 18:30(UTC+8) 合约标的 REEF 结算资产 USDT 最小变动价位 0.000001 最高杠杆倍数 50x 资金费用结算频率 每八个小时 交易时间 7*24 根据市场风险状况,Bitget可能调整包括最小变动价格、最高杠杆倍数、维持保证金率等重要合约参数; 【合约】 Bitget 的合约包括:U本位合约、币本位合约和 USDC 合约。 合

Bitget Announcement2024/09/20 10:35

MetaCene (MAK):释放虚拟世界的真正价值

什么是 MetaCene(MAK)? MetaCene (MAK) 是一款边玩边赚的游戏,它提供了一个创新的经济生态系统,玩家可以通过各种游戏内活动赚取加密货币和 NFT。MetaCene 为玩家提供了丰富、身临其境的游戏体验,游戏背景设定在一个未来世界,玩家可以参与各种活动,如探索、战斗和交易。玩家还可以获得游戏内资产,这些资产可用于或交易为现实世界的价值。游戏的经济围绕 NFT 和两个主要代币建立:MUD 和 MAK。 谁创立了 MetaCene (MAK)? MetaCene 由游戏和区块链技术专家团队开发。游戏的创造者在游戏行业经验丰富,对如何设计引人入胜的游戏玩法并将其与 DeFi

Bitget Academy2024/09/20 09:46