前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >3.MOVE从入门到实战-可编程Resource-发送者和签署者

3.MOVE从入门到实战-可编程Resource-发送者和签署者

作者头像
Tiny熊
发布2022-11-07 11:10:47
2370
发布2022-11-07 11:10:47
举报
文章被收录于专栏:深入浅出区块链技术

本文作者:木头[1]

Resource 是Move[2]的关键功能。它使 Move 变得独一无二,安全且强大。

Move 的主要功能是提供了自定义 Resource 类型。Resource 类型为安全的数字资产编码具提供了丰富的可编程性。Resource 在 Move 语言中就是普通的值。它们可以作为数据结构被存储,作为参数被传递给函数,也可以从函数中返回。

Resource 是一种特殊的结构体,可以在 Move 代码中定义和创建,也可以使用现有的 Resource。因此,我们可以像使用任何其它数据(比如向量或结构体)那样来管理数字资产。

Move 类型系统为 Resource 提供了特殊的安全保证。Resource 永远不能被复制,重用或丢弃。Resource 类型只能由定义该类型的模块创建或销毁。这些检查由 Move 虚拟机通过字节码校验强制执行。Move 虚拟机将拒绝运行任何尚未通过字节码校验的代码。

发送者作为 Signer

在开始使用 Resource 之前,我们需要了解 signer 类型以及这种类型存在的原因。

Signer 是一种原生的类似 Resource 的不可复制的类型,它包含了交易发送者的地址。

Signer 类型代表了发送者权限。换句话说,使用 signer 意味着可以访问发送者的地址和 Resource。它与 signature 没有直接关系,就 Move VM 而言,它仅表示发送者。

Signer 只有一种 ability:Drop。abilities 限制符分别是: Copy, Drop, Store 和 Key. Copy - 被修饰的值可以被复制。Drop - 被修饰的值在作用域结束时可以被丢弃。Key - 被修饰的值可以作为键值对全局状态进行访问。Store - 被修饰的值可以被存储到全局状态。

脚本的 Signer

Signer 是原生类型,使用前必须先创建。与vector 这样的原生类型不同,signer 不能直接在代码中创建,但是可以作为脚本参数传递:

代码语言:javascript
复制
script {
    // signer is an owned value
    fun main(account: signer) {
        let _ = account;
    }
}

Signer 参数无需手动将其传递到脚本中,客户端(CLI)会自动将它放入你的脚本中。而且,signer 自始至终都只是引用,虽然标准库中可以访问签名者的实际值,但使用此值的函数是私有的,无法在其他任何地方使用或传递 signer 值。

当前,约定俗成的 signer 类型的变量名是 account

标准库中的 Signer 模块

原生类型离不开原生方法, signer 的原生方法包含在0x1::Signer模块中。这个模块相对比较简单,具体可以参考 Diem 标准库 [3]Signer 模块的实现:

代码语言:javascript
复制
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函数使用更方便,因为它使用了取值运算符来复制地址。

使用起来也非常简单:

代码语言:javascript
复制
script {
    fun main(account: signer) {
        let _ : address = 0x1::Signer::address_of(&account);
    }
}

模块中的 Signer

代码语言:javascript
复制
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。

参考资料

[1]

木头: https://learnblockchain.cn/people/3015

[2]

Move: https://learnblockchain.cn/article/4777

[3]

Diem 标准库 : https://github.com/diem/diem/blob/latest/language/move-stdlib/modules/Signer.move

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-09-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 深入浅出区块链技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 发送者作为 Signer
  • 脚本的 Signer
  • 标准库中的 Signer 模块
  • 模块中的 Signer
    • 参考资料
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档