MUD引擎开发初体验

原文作者:yamapyblack

原文链接:https://mirror.xyz/yamapyblack.eth/hodgVZ1_4S6rEXH1CmMHFKAi3JcB_vPpyNBsCQ_bKdI

原文标题:First Experience with the Solidity Framework ‘MUD’

译者序:“本文来自AW黑客松Autonomous Game of Life团队成员@yamapyblack在使用MUD进行开发后的个人体验。文章虽然涉及了一些技术细节,但普通读者依然可以借此粗略了解MUD引擎的优势与不足。”

我很荣幸能能够成为“ETHGlobalAW”Autonomous World黑客松的决赛选手!

在这次黑客松中,我第一次使用了基于Solidity语言的开发框架MUD。MUD是由Lattice开发的一个框架,非常适合用于自主世界(AW)。但其潜力不仅限于此,他甚至还可以被用于DeFi等其他应用。

对于那些想了解MUD到底如何的人,我将在本文中介绍他的特点,并分享我的个人感受。

MUD官网: https://mud.dev/

请注意:我使用的MUD v2是一个在官方网站上明确注明的alpha版本。由于他还在开发中,使用他需要自担风险。而且,我是一个MUD的初学者,并不能完全保证本文内容的准确性。请自行进行研究(DYOR)。

01.将前端与后端(智能合约)整合到一起的开发框架

如果你查看代码库(repository),你会看到MUD有一个基于React的前端和一个基于Foundry的后端。使用的包管理器是pnpm。

在以前的Dapps开发中,我感觉后端(智能合约)和前端经常是分开工作的。相反在使用MUD开发时,这两部分被很好地统一起来。

这一点在本地开发的过程中优势十分明显,只需一个dev命令,就可以部署智能合约并直接启动前端界面。

比如,假设你在智能合约中修改了一个函数的名称。通常情况下,前端需要重新链接到新部署的地址,并且还需要检索并应用ABI。

而在MUD中,前端可以在部署后直接访问最新的地址和ABI,使得开发者可以始终在界面中测试合约的当前状态。

这的确很方便,不是吗?

02.根据表定义自动生成智能合约

通过在配置中定义表(table)的列(columns),就可以自动生成一个智能合约。请看下面的配置(config):

tables: {
  MyTable: {
    schema: {
      foo: "uint256",
      bar: "bool",
    },
  },
}

只要输入这些代码,就可以自动创建一个智能合约。

智能合约通常提供两个主要的功能:“存储”和“逻辑”。在MUD中,这两个功能是完全分开的。而存储合约就是刚才提到可以自动生成的那部分。

为了更好地理解,你可以把他想象成类似于Rails或Laravel(PHP)中的迁移(migrations)。

这个特性的优点不仅在于提高了表定义的可读性,更使得你不再需要不断思考如何调用这些函数(getters)的问题。

例如,如果有一个叫做owner的变量,可能不清楚应该采用以下哪种方式获取他:

  • address public owner,

  • 通过 function getOwner(), 或者

  • 通过 event OwnerChanged

但有了自动生成,你就不用再担心这些问题了。

因为有一些函数已经准备好从前端获取智能合约的值,因此你不再需要担心这些问题。

03.单一的World合约

当你用MUD部署一个合约时,会生成一个叫做“World”的智能合约。事实上,这是唯一一个需要从前端执行的合约。

在传统的应用中,你会部署许多个合约,并在前端定义他们的所有地址,以便选择和发起交易。在MUD中,这被简化为只需要一个合约。

当你创建一个叫做“System”的逻辑合约时,会自动生成一个接口。

interface IIncrementSystem {
  function increment() external returns (uint32);
}

下面World函数的接口,也就是“IWorld”,你可以看到他直接继承了你创建的所有System的接口。

interface IWorld is IIncrementSystem, IBaseWorld, IAddSystem {
}

所有的逻辑都是通过World函数执行的。因此,前端需要执行的唯一合约就是这个单一的World合约。

04.命名空间和访问控制

我还没有使用过这个功能,但这看起来像通过创建一个命名空间(Namespace,本质上是一个目录),你可以对存储实现访问控制。访问控制指的是像“OnlyOwner”这样的功能(注:也就是该函数只能通过管理员地址进行调用)。

你可以在一个World合约中创建多个服务。

root
|-- mudswap <- Namespace
    | Balance <- Table
    | Pool <- Table
    | Transfer <- System
|-- Tetris <- Namespace
    | Board <- Table
    | Move <- System
    | Drop <- System
    | Score <- Table
| Win <- System

上面这个实例,展示了如何在同一个World合约中分别创建“mudswap”和“Tetris”两个不同的应用。

05.乐观渲染(Optimistic Rendering)

我想提到的最后一个特性是一个叫做乐观渲染(Optimistic Rendering)的前端功能。

看看下面这个动图。

通过MUD,你可以在创建游戏时进行超快速的屏幕动画绘制。不管你怎么看,角色的移动速度显然都比交易速度更快,尽管所有的角色移动都要被记录在链上。

这种机制被称为乐观渲染(Optimistic Rendering)。他的运行机制如下:

  • 发送一个交易;

  • 在前段直接移动角色;

  • 检索交易结果。如果发生错误,将角色返回到原来的位置;

这类似于Optimistic Rollup。你乐观地行动,但如果发生错误,你就回退。

此外这个特性只需要几行代码就可以实现,这太棒了。

但是,当然,有一个风险,那就是回退可能会导致游戏画面出现错误,所以是否使用他取决于具体的使用场景。(另外,我觉得动图中的移动速度很快,可能是因为他在本地部署或其他什么原因。)

06.MUD的问题

到目前为止,我一直在强调MUD的优点,但是从这里开始,让我们来谈谈他面临的挑战。

(1)私钥管理

在MUD的教程中,私钥是写在.env文件中的。这肯定是不行的。

虽然可以从MetaMask等钱包执行交易,但是当游戏中出现大量交易时,可能就会出现用户体验问题。这或许需要一个专门为MUD设计的钱包。

随着AA(账户抽象)的普及,钱包开发也变得更加活跃,所以让我们希望这个问题能够尽快解决。

(2)与现有合约的集成

MUD是一个厚重的框架,我无法想象将其与其他合约进行集成时的景象。我认为至少可以集成ERC20或ERC721,但是如果你想要重用现有的合约进行开发,那可能需要花费更多的时间。

最好能有更多使用MUD创建的合约的实例。

(3)审计与安全

审计将如何进行?自动生成的部分似乎没有问题,但是对于其他部分,一些形式的审查或审计将是必不可少的。审计公司可能也需要预先了解MUD的相关知识。

然而,考虑到DeFi中的黑客事件数量,我相信一个有效的智能合约框架是必要的。如果MUD能够真正地提高安全性,那就太好了。

07.结论

MUD还不完善,还有很多问题需要解决,但我依然觉得这是一个非常有前途的框架。我认为开发这个框架的Lattice团队拥有相当强大的开发能力。

而且,随着MUD的诞生,我主观地预测其他类似的智能合约框架也会紧接着出现。

我将继续关注MUD和AW社区的动态。

参考资料:

Subscribe to FunBlocks
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.