Move Resource 创建和移动
首先,让我们创建模块:
// modules/Collection.move module Collection { struct Item has store { // we'll think of the properties later } struct Collection has key { items: vector<Item> } }
一个模块里最主要的 Resource 通常跟模块取相同的名称(例如这里的 Collection)。遵循这个惯例,你的模块将易于阅读和使用。
创建和移动
我们定义了一个 Resource 结构体T
,该结构体将保存一个向量,向量里面存放Item
类型的元素。现在,让我们看看如何创建新集合以及如何在 account 下存储 Resource。Resource 将永久保存在发送者的地址下,没有人可以从所有者那里修改或取走此 Resource。
// modules/Collection.move module Collection { use 0x1::Vector; struct Item has store {} struct Collection has key { items: vector<Item> } /// note that &signer type is passed here! public fun start_collection(account: &signer) { move_to<Collection>(account, Collection { items: Vector::empty<Collection>() }) } }
还记得 signer
吗?现在,你将了解它的运作方式!移动 Resource 到 account 需要使用内建函数 move_to,需要 signer 作为第一个参数,T 作为第二个参数。move_to 函数的签名可以表示为:
native fun move_to<T: key>(account: &signer, value: T);
总结一下上面所学的内容:
- 你只能将 Resource 放在自己的帐户下。你无权访问另一个帐户的
signer
值,因此无法放置 Resource 到其它账户。 - 一个地址下最多只能存储一个同一类型的 Resource。两次执行相同的操作是不行的,比如第二次尝试创建已有 Resource 将会导致失败。
查看 Resource 是否存在
Move 提供 exists
函数来查看某 Resource 是否存在于给定地址下,函数签名如下:
native fun exists<T: key>(addr: address): bool;
通过使用泛型,此函数成为独立于类型的函数,你可以使用任何 Resource 类型来检查其是否存在于给定地址下。实际上,任何人都可以检查给定地址处是否存在 Resource。但是检查是否存在并不意味着能获取储 Resource !
让我们编写一个函数来检查用户是否已经拥有 resource T:
// modules/Collection.move module Collection { struct Item has store, drop {} struct Collection has store, key { items: Item } // ... skipped ... /// this function will check if resource exists at address public fun exists_at(at: address): bool { exists<Collection>(at) } }
现在你已经知道了如何创建 Resource,如何将其移动到发送者账户下以及如何检查 Resource 是否已经存在,现在是时候学习如何访问和修改 Resource 了。
Move 有两个内建函数用来读取和修改 Resource。它们的功能就像名字一样:borrow_global 和 borrow_global_mut。不可变借用 borrow_global在 ...