原文作者: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)。
如果你查看代码库(repository),你会看到MUD有一个基于React的前端和一个基于Foundry的后端。使用的包管理器是pnpm。
在以前的Dapps开发中,我感觉后端(智能合约)和前端经常是分开工作的。相反在使用MUD开发时,这两部分被很好地统一起来。
这一点在本地开发的过程中优势十分明显,只需一个dev命令,就可以部署智能合约并直接启动前端界面。
比如,假设你在智能合约中修改了一个函数的名称。通常情况下,前端需要重新链接到新部署的地址,并且还需要检索并应用ABI。
而在MUD中,前端可以在部署后直接访问最新的地址和ABI,使得开发者可以始终在界面中测试合约的当前状态。
这的确很方便,不是吗?
通过在配置中定义表(table)的列(columns),就可以自动生成一个智能合约。请看下面的配置(config):
tables: {
MyTable: {
schema: {
foo: "uint256",
bar: "bool",
},
},
}
只要输入这些代码,就可以自动创建一个智能合约。
智能合约通常提供两个主要的功能:“存储”和“逻辑”。在MUD中,这两个功能是完全分开的。而存储合约就是刚才提到可以自动生成的那部分。
为了更好地理解,你可以把他想象成类似于Rails或Laravel(PHP)中的迁移(migrations)。
这个特性的优点不仅在于提高了表定义的可读性,更使得你不再需要不断思考如何调用这些函数(getters)的问题。
例如,如果有一个叫做owner的变量,可能不清楚应该采用以下哪种方式获取他:
address public owner
,
通过 function getOwner()
, 或者
通过 event OwnerChanged
;
但有了自动生成,你就不用再担心这些问题了。
因为有一些函数已经准备好从前端获取智能合约的值,因此你不再需要担心这些问题。
当你用MUD部署一个合约时,会生成一个叫做“World”的智能合约。事实上,这是唯一一个需要从前端执行的合约。
在传统的应用中,你会部署许多个合约,并在前端定义他们的所有地址,以便选择和发起交易。在MUD中,这被简化为只需要一个合约。
当你创建一个叫做“System”的逻辑合约时,会自动生成一个接口。
interface IIncrementSystem {
function increment() external returns (uint32);
}
下面World函数的接口,也就是“IWorld”,你可以看到他直接继承了你创建的所有System的接口。
interface IWorld is IIncrementSystem, IBaseWorld, IAddSystem {
}
所有的逻辑都是通过World函数执行的。因此,前端需要执行的唯一合约就是这个单一的World合约。
我还没有使用过这个功能,但这看起来像通过创建一个命名空间(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”两个不同的应用。
我想提到的最后一个特性是一个叫做乐观渲染(Optimistic Rendering)的前端功能。
看看下面这个动图。
通过MUD,你可以在创建游戏时进行超快速的屏幕动画绘制。不管你怎么看,角色的移动速度显然都比交易速度更快,尽管所有的角色移动都要被记录在链上。
这种机制被称为乐观渲染(Optimistic Rendering)。他的运行机制如下:
发送一个交易;
在前段直接移动角色;
检索交易结果。如果发生错误,将角色返回到原来的位置;
这类似于Optimistic Rollup。你乐观地行动,但如果发生错误,你就回退。
此外这个特性只需要几行代码就可以实现,这太棒了。
但是,当然,有一个风险,那就是回退可能会导致游戏画面出现错误,所以是否使用他取决于具体的使用场景。(另外,我觉得动图中的移动速度很快,可能是因为他在本地部署或其他什么原因。)
到目前为止,我一直在强调MUD的优点,但是从这里开始,让我们来谈谈他面临的挑战。
在MUD的教程中,私钥是写在.env文件中的。这肯定是不行的。
虽然可以从MetaMask等钱包执行交易,但是当游戏中出现大量交易时,可能就会出现用户体验问题。这或许需要一个专门为MUD设计的钱包。
随着AA(账户抽象)的普及,钱包开发也变得更加活跃,所以让我们希望这个问题能够尽快解决。
MUD是一个厚重的框架,我无法想象将其与其他合约进行集成时的景象。我认为至少可以集成ERC20或ERC721,但是如果你想要重用现有的合约进行开发,那可能需要花费更多的时间。
最好能有更多使用MUD创建的合约的实例。
审计将如何进行?自动生成的部分似乎没有问题,但是对于其他部分,一些形式的审查或审计将是必不可少的。审计公司可能也需要预先了解MUD的相关知识。
然而,考虑到DeFi中的黑客事件数量,我相信一个有效的智能合约框架是必要的。如果MUD能够真正地提高安全性,那就太好了。
MUD还不完善,还有很多问题需要解决,但我依然觉得这是一个非常有前途的框架。我认为开发这个框架的Lattice团队拥有相当强大的开发能力。
而且,随着MUD的诞生,我主观地预测其他类似的智能合约框架也会紧接着出现。
我将继续关注MUD和AW社区的动态。
参考资料:
MUD官网: https://mud.dev/
Ethereum navi: https://ethereumnavi.com/2022/11/19/lattice-mud/
AW house: https://twitter.com/AW_house