作者:Overmind_xyz
学习一门新语言的最好方法是从熟悉的翻译过来。在NFTango任务结束后,我们将它翻译成了Solidity。
复制NFT平台的使用案例,以及内部功能的执行,1个Move合约变成了3个Solidity合约。虽然这并不一定表明Move比Solidity更高效,但它与这些语言在区块链上的存储和处理数据的方法截然不同。本文展示了突出比较点的代码片段,但你可以在这里找到Move和Solidity的完整代码。
合约结构
NFToken.sol只是调用OpenZeppelin中的ERC721实现。这作为将铸造和用于测试我们的NFTango平台的NFT。这在Move中不是必需的,因为Move将NFT视为对象,在Move术语中是一种资源,可以在一行代码中创建,铸造和转移由功能和定义的模块函数控制。 Solidity是面向合约的,为了模拟NFT,我们需要使用已经部署的合约或创建我们自己的NFT合约,这是更好的选择,因为我们可以控制合约。 Move是面向资源的,token.move模块被视为具有某些功能的对象,而不是在合约中实现的标准。这种差异代表了从Soldity背景学习Move时需要的心态转变。
Solidity是以合约为中心的。Move以资源为中心,侧重于这些资源的所有权和安全转移。
NFTango.sol 合约定义了 NFTangoStore 对象的结构以及一些断言和 getter/setter 函数。NFTangoManager 合约负责创建和游戏逻辑。本质上,NFTango.sol 合约封装了一个对象,并公开了操纵对象状态的方法,而 NFTangoManager 是控制中心。将 NFTango 合约视为 Move 资源,将 Manager 合约视为 Move 资源帐户和模块。
资源和资源帐户
从技术上讲,我们可以将NFTangoStore对象直接移动到NFTangoManager.sol合约中,然后我们可以放弃整个NFTango.sol合约。事实上,Move合约已经将所有内容放在一起,那么为什么我们在Solidity中将其分开呢?
看看Move合约中的init_game函数,我们发现,为了开始游戏,有三件事发生:
- 我们通过哈希随机种子短语和游戏创建者的地址(签名者)来创建资源帐户。
- 游戏的创建者向该功能支付NFT。
- 该函数从NFT令牌数据中生成NFTangoStore资源,将NFT移动到资源帐户中,并将NFTangoStore源移动到游戏创建者的地址下。
当第二个玩家加入游戏时,他们会通过查找游戏创建者地址下的NFTangoStore资源来加入游戏。 NFTangoStore资源管理每个创建者的游戏状态,而资源帐户处理NFT。这是Move中非常常见的框架设置-用户地址存储其各自的状态,而资源帐户处理交互。
在Solidity的合约中心世界中,也可以通过编程生成合约。这些类型的合约被称为Factories或Managers。因此,我们有一个NFTangoManager合约,每次调用init_game时都会生成NFTango游戏。尽管如此,我们仍然可以在Manager合约中维护一个地址到NFTangoStore对象的映射,那么为什么将NFTangoStore对象封装在NFTango合约中呢?简而言之,我们想模拟一个Move资源帐户,即使是不完美的模拟。
在Move中,资源是在模块中定义的。这个模块将包含结构体的字段、结构体所拥有的能力以及与结构体相关的函数。所有这些组合在一起形成资源。另一方面,资源帐户能够持有、管理和转移这些资源。请注意,NFT数据存储在NFTangoStore对象中,但实际上移动到资源帐户中。在Manager中,我们维护游戏创建者地址到NFTango.sol对象的映射,因为Solidity不是以x资源在y地址下存储东西的方式存储的,而是以管理合约下整体状态的形式存储的。
其次,如果我们试图让NFTango.sol控制NFT转移,我们需要在NFTangoManager.sol中添加一个功能,让用户支付NFTango.sol合约。这款游戏的玩家仍然认可经理合约来控制他们的NFT,而不是NFTango.sol合约。同样,当支付获胜玩家时,NFTango合约必须批准经理合约才能进行转移。总之,权力最终掌握在经理合约手中。移动资源账户能够更加独立地处理NFT,因为我们可以将账户的签名能力作为值存储在NFTangoStore中,并更容易地以资源账户的名义发起转移。我们将在第2部分——所有权和能力中深入探讨。
全局存储
上述操作差异也暗示了Move和Solidity访问其全局数据的差异。在不深入了解Merkle树和根哈希的情况下,Solidity通过合约地址存储所有内容。NFTangoManager存储所有现有的NFTango合约,这些合约反过来存储单个游戏状态。在Move中,NFTangoStore被创建并立即移动到游戏创建者地址下,以跟踪单个游戏状态。集中式与分散式的存储方法意味着访问全局变量意味着Move中许多新功能可以访问全局数据。
assert_nftango_store_exists函数很好地说明了不同的存储哲学。
在 nftango.move 文件中
assert!(exists<NFTangoStore>(account_address), error::invalid_state(ERROR_NFTANGO_STORE_DOES_NOT_EXIST));
在NFTangoManager.sol文件中
require(address(Games[creator]) != address(0), CODE_1);
如图所示,NFTangoStore资源存储在全局存储中,我们可以通过“exists”调用并输入特定用户的地址直接检查其是否存在。在Solidity中,检查NFTango合约是否存在并不容易,需要通过NFTangoManager合约中的集中映射进行跟踪。事实上,Solidity倾向于将所有内容初始化为零,而不是允许存在空状态。
最后,在 Move 中抛出错误时,还有一个额外的好处,Move 有一个错误库,可以将错误代码打包成错误类别,就像 HTTP 错误按百位数排序一样——400s 表示客户端错误,500s 表示服务器错误。
总之……
Solidity围绕合约展开。将包中的东西移动到资源中,并将其移动到不同的用户或资源帐户。Solidity将资产转移和交互集中到声明合约中,而Move中的资产交互由类型能力、全局存储和资源帐户处理。
以上内容均转载自互联网,不代表AptosNews立场,不是投资建议,投资有风险,入市需谨慎,如遇侵权请联系管理员删除。