Resource
是一种特殊的结构体,可以在Move代码中定义和创建,也可以使用现有的 Resource
。因此,我们可以像使用任何其它数据(比如向量或结构体)那样来管理数字资产。
Resource
是Move的关键功能。它使Move变得独一无二,安全且强大。
Move 的主要功能是提供了自定义 Resource 类型。Resource 类型为安全的数字资产编码具提供了丰富的可编程性。 Resource 在Move语言中就是普通的值。它们可以作为数据结构被存储,作为参数被传递给函数,也可以从函数中返回。
Resource
是一种特殊的结构体,可以在Move代码中定义和创建,也可以使用现有的 Resource
。因此,我们可以像使用任何其它数据(比如向量或结构体)那样来管理数字资产。
Move 类型系统为 Resource 提供了特殊的安全保证。Resource 永远不能被复制,重用或丢弃。Resource 类型只能由定义该类型的模块创建或销毁。这些检查由 Move 虚拟机通过字节码校验强制执行。Move 虚拟机将拒绝运行任何尚未通过字节码校验的代码。
在开始使用 Resource
之前,我们需要了解 signer
类型以及这种类型存在的原因。
Signer 是一种原生的类似 Resource 的不可复制的类型,它包含了交易发送者的地址。
Signer 类型代表了发送者权限。换句话说,使用 signer
意味着可以访问发送者的地址和 Resource
。它与signature没有直接关系,就 Move VM 而言,它仅表示发送者。
Signer 只有一种 ability: Drop。 abilities 限制符分别是: Copy, Drop, Store 和 Key. Copy - 被修饰的值可以被复制。 Drop - 被修饰的值在作用域结束时可以被丢弃。 Key - 被修饰的值可以作为键值对全局状态进行访问。 Store - 被修饰的值可以被存储到全局状态。
Signer
是原生类型,使用前必须先创建。与vector
这样的原生类型不同,signer
不能直接在代码中创建,但是可以作为脚本参数传递:
script {
// signer is an owned value
fun main(account: signer) {
let _ = account;
}
}
Signer
参数无需手动将其传递到脚本中,客户端(CLI)会自动将它放入你的脚本中。而且,signer
自始至终都只是引用,虽然标准库中可以访问签名者的实际值,但使用此值的函数是私有的,无法在其他任何地方使用或传递 signer
值。
当前,约定俗成的 signer 类型的变量名是 account
原生类型离不开原生方法, signer
的原生方法包含在0x1::Signer
模块中。这个模块相对比较简单,具体可以参考 Diem 标准库 Signer
模块的实现:
module Std::Signer {
// Borrows the address of the signer
// Conceptually, you can think of the `signer` as being a struct wrapper arround an
// address
// ```
// struct Signer has drop { addr: address }
// ```
// `borrow_address` borrows this inner field
native public fun borrow_address(s: &signer): &address;
// Copies the address of the signer
public fun address_of(s: &signer): address {
*borrow_address(s)
}
spec address_of {
pragma opaque;
aborts_if false;
ensures result == spec_address_of(s);
}
/// Specification version of `Self::address_of`.
spec native fun spec_address_of(account: signer): address;
}
address_of
函数使用更方便,因为它使用了取值运算符来复制地址。
使用起来也非常简单:
script {
fun main(account: signer) {
let _ : address = 0x1::Signer::address_of(&account);
}
}
module M {
use 0x1::Signer;
// let's proxy Signer::address_of
public fun get_address(account: signer): address {
Signer::address_of(&account)
}
}
使用&signer作为函数的参数说明该函数正在使用发送者的地址。
引入signer
类型的原因之一是要明确显示哪些函数需要发送者权限,哪些不需要。因此,函数不能欺骗用户未经授权访问其 Resource。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!