{"content":{"title":"学习Move","body":"## 1. 面向Resource编程：\r\n\r\n   在用solidity智能合约语言做开发的时候，总有一种感觉，简单的加减就可以完成物权的交换，这类过于简单的开发模式给人的感觉，并不是把安全性放在第一位置，转而把逻辑放在第一位，下边代码是在solidity对资产的操作\r\n    \r\n```js\r\n uint256 fromBalance = _balances[from];\r\n _balances[from] = fromBalance - amount;\r\n_balances[to] += amount;\r\n```\r\n而在区块链上，安全性才是最重要的，但是在Move中，首先就规定了Resource是第一公民，在编程的时候是必须被首先考虑的被编程对象。这种开发思想，就告诉开发者要全心全意的去看待Resource，重视资产的安全性，下面代码是关于在SUI-Move中操作资产的，有点类似比特币的UTXO模型\r\n\r\n```js\r\n    struct Coin<phantom T> has key, store {\r\n        id: UID,\r\n        balance: Balance<T>\r\n    }\r\n     struct Balance<phantom T> has store {\r\n        value: u64\r\n    }\r\n    \r\n     public fun take<T>(\r\n        balance: &mut Balance<T>, value: u64, ctx: &mut TxContext,\r\n    ): Coin<T> {\r\n        Coin {\r\n            id: object::new(ctx),\r\n            balance: balance::split(balance, value)\r\n        }\r\n    }\r\n    \r\n```\r\n## 2. 组合型\r\n\r\n先来谈谈NFT的可组合型，在solidity中因为NFT都是在Map中解析数据，NFT很难做到可组合型，而Move语言则天然支持，Move的组合性是模块之间的组合，通过传递资源（即前文提到的resources）。关于组合性方面，Solidity和Move的区别非常明显，下边代码是关于SUI-MOVE实现Object之间的组合和拆分 (两个Object合成一个Object，在将组合的Object进行拆分成两个Object，在sui中一切都是Object，可以理解成NFT)\r\n\r\n```js\r\nstruct Foo has key,store {\r\n        id: UID,\r\n        bar: Bar,\r\n        run: Run,\r\n    }\r\n\r\n    struct Bar has key,store {\r\n        id: UID,\r\n        value: u64,\r\n    }\r\n\r\n    struct Run has key,store{\r\n        id: UID,\r\n        value: u64\r\n    }\r\n\r\n    public fun create(ctx: &mut TxContext){\r\n        let bar=Bar{\r\n            id: object::new(ctx),\r\n            value:0,\r\n        };\r\n        let run =Run{\r\n           id: object::new(ctx),\r\n            value:0,\r\n        };\r\n        let foo=Foo{\r\n            id: object::new(ctx),\r\n            bar,\r\n            run,\r\n        };\r\n        transfer::public_transfer(foo,tx_context::sender(ctx))\r\n     \r\n    }\r\n    public fun split(foo:Foo,ctx: &mut TxContext){\r\n        let Foo{\r\n            id,\r\n            bar,\r\n            run,\r\n        }=foo;\r\n        transfer::public_transfer(bar,tx_context::sender(ctx));\r\n        transfer::public_transfer(run,tx_context::sender(ctx));\r\n        object::delete(id)\r\n    }\r\n```\r\n在来谈谈智能合约的组合性\r\nSolidity 生态的智能合约的可组合性更像是基于 Interface 间通过消息传递进行的组合\r\n怎么理解他们之间的不同呢？以建造一个汽车工厂为例，Solidity 的做法是定义了这个工厂的生产标准以及流程，每一个想来造汽车的人都需要先造一个符合生产标准及流程的工厂，然后才能创造汽车。而 Move 的方式是工厂就只有一个，想要造汽车的人使用这一个工厂就能造出来大家都认可的汽车。\r\n这样带来的好处一方面是节省了合约占用的区块空间，我们不需要重复创造工厂了，另一方面的好处是优化升级变得容易，不会自缚手脚了。\r\n比如在以太坊上，当我们想扩展一些新的行为或者做一些实现上的优化，那我们需要重新定义过往的接口，同时也会影响旧的方法，像 ERC 721 和 ERC 721A， ERC 4907 这些优化和新的定义，是没有办法直接让过去所有使用了 ERC 721 的合约直接进行升级迭代的。\r\n而 Move 基于 Module 间的组合只需要对 Module 进行升级和优化，所有使用过这个Module的其他合约都会自动使用最新的版本。\r\n这种合约层面的可组合性和面向资源的编程带来的表现力与可扩展性是其他语言无法带来的。同时针对资源的定义也更贴近现实世界中各种资源的组合方式，比如乐高， 组装电脑的主机的各种配件。\r\nMove 这些特点带来的一个关键性的好处就是可以非常明确的将资源的定义和资源相关的行为进行拆分。\r\n就像一个物品，物品的本身定义只是决定了他以什么形态展示，具有那些属性，能够以什么方式被销毁。而他的所有权，是否可以进行转让等等相关的行为，完全有物品的所有人或者使用方来决定。\r\n这跟现实世界是高度相似的，当一个商品摆在货架上的时候，是可以被任何人购买的。而当商品放在保险柜里，就收到了其他规则的限制。\r\n## 3. 场景\r\n现在可以设想这种场景，假如我想在游戏中完成一次升级，现在缺少一种道具，但是由于某种原因(升级之后这个道具就没有价值/太贵/流动性太差等等)我并不想拥有这个道具的所有权，但是我想通过这次升级，我们来对于在ETH和SUI上我们应该怎么做\r\n在eth上我们可能先发起一个EIP提案定义出来某种interface,如ERC4607\r\n\r\n```js\r\ninterface IERC4907 {\r\n    // Logged when the user of an NFT is changed or expires is changed\r\n    /// @notice Emitted when the `user` of an NFT or the `expires` of the `user` is changed\r\n    /// The zero address for user indicates that there is no user address\r\n    event UpdateUser(uint256 indexed tokenId, address indexed user, uint64 expires);\r\n    /// @notice set the user and expires of an NFT\r\n    /// @dev The zero address indicates there is no user\r\n    /// Throws if `tokenId` is not valid NFT\r\n    /// @param user  The new user of the NFT\r\n    /// @param expires  UNIX timestamp, The new user could use the NFT before expires\r\n    function setUser(uint256 tokenId, address user, uint64 expires) external;\r\n    /// @notice Get the user address of an NFT\r\n    /// @dev The zero address indicates that there is no user or the user is expired\r\n    /// @param tokenId The NFT to get the user address for\r\n    /// @return The user address for this NFT\r\n    function userOf(uint256 tokenId) external view returns(address);\r\n    /// @notice Get the user expires of an NFT\r\n    /// @dev The zero value indicates that there is no user\r\n    /// @param tokenId The NFT to get the user expires for\r\n    /// @return The user expires for this NFT\r\n    function userExpires(uint256 tokenId) external view returns(uint256);\r\n}\r\n```\r\n需要租赁市场和游戏内的合约遵循某种规则，而且interface里边还可能存在一些作恶行为\r\n但是在SUI中只需要在租赁市场中提供某种提供可变借用的方法可以，这样NFT的所有权并不会改变\r\n\r\n```js\r\n      public fun get_nft_mut<Item: key+store>(safe: &mut SafePool<Item>, borrowed: &mut   Borrowed<Item>): &mut Item {\r\n        assert!(borrowed.active, EBorrowedNoActive);\r\n        return object_table::borrow_mut(&mut safe.nfts, borrowed.item_id)\r\n    }\r\n```\r\n这种设计模式给Gamefi的未来带来了新的活力\r\n\r\n文章引用：https://zhuanlan.zhihu.com/p/550581821"},"author":{"user":"https://learnblockchain.cn/people/9639","address":null},"history":"QmVUjzNKmKcnLdNYQ52GiC25MVT2FsqnXFRM1XxjgNvq4e","timestamp":1681290335,"version":1}