Sway编程语言-更新中(The Sway Programming Language-Updatin
  • Sway编程语言(The Sway Programming Language)
  • 1. 导言(Introduction)
    • 1.1 安装(Installation)
    • 1.2 Sway快速入门 (Sway Quickstart)
    • 1.3 Fuel工具链 (The Fuel Toolchain)
    • 1.4 一个Forc项目 (A Forc Project)
    • 1.5 标准库 (Standard Library)
  • 2. 示例(Example)
    • 2.1计数器(Counter)
    • 2.2子货币(Subcurrency)
    • 2.3 FizzBuzz
    • 2.4 钱包智能合约(Wallet Smart Contract)
  • 3.Sway编程类型(Sway Program Types)
    • 3.1 合约(Contracts)
    • 3.2 库 (Libraries)
    • 3.3 脚本(Scripts)
    • 3.4 谓词 (Predicates)
  • 4. Sway语言基础 (Sway Language basics)
    • 4.1 变量 (Variables)
    • 4.2 内置类型(Built-in Types)
    • 4.3 常用库类型(Commonly Used Library Types)
    • 4.4 区块链类 (Blockchain Types)
    • 4.5 函数 (Functions)
    • 4.6 结构、元祖和穷举 (Structs, Tuples, and Enums)
    • 4.7 方法和关联函数 (Methods and Associated Functions)
    • 4.8 注释和日志 (Comments and Logging)
    • 4.9 控制流 (Control Flow)
  • 5. 用Sway部署区块链 (Blockchain Development with Sway)
    • 5.1 哈希和加密学 (Hashing and Cryptography)
    • 5.2 合约存储(Contract Storage)
    • 5.3 函数纯度 (Function Purity)
    • 5.4 标识符(Identifiers)
    • 5.5 原生资产(Native Assets)
    • 5.6 访问控制 (Access Control)
    • 5.7 调用合约(Calling Contracts)
  • 6. 高级概念 (Advanced Concepts)
    • 6.1 高级类型 (Advanced Types)
    • 6.2 通用类型 (Generic Types)
    • 6.3 特征 (Traits)
    • 6.4 集 (Assembly)
  • 7. 一般集聚 (Common Collections)
    • 7.1 堆上的向量(Vectors on the Heap)
    • 7.2 存储向量 (Storage Vectors)
    • 7.3 存储映射 (Storage Maps)
  • 8.测试(Testing)
    • 8.1 单元测试(Unit Testing)
    • 8.2 用Rust来测试 (Testing with Rust)
  • 9.应用前端开发 (Application Frontend Development)
    • 9.1 TypeScript SDK
  • 10.Sway应用(Sway Reference)
    • 10.1 编译器内部函数(Compiler Intrinsics)
    • 10.2 属性(Attributes)
    • 10.3 风格向导(Style Guide)
    • 10.4 已知各类问题(Known Issues and Workarounds)
    • 10.5 与Solidity的不同之处 (Differences From Solidity)
    • 10.6 与Rust的不同之处 (Differences From Rust)
    • 10.7 向Sway贡献 (Contributing To Sway)
  • 11. Forc引用 (Forc Reference)
    • 11.1清单参考 (Manifest Reference)
    • 11.2 工作区(Workspaces)
    • 11.3 依赖(Dependencies)
    • 11.4 命令(Commands)
      • 11.4.1 forc-addr2line
      • 11.4.2 forc-build
      • 11.4.3 forc-check
Powered by GitBook
On this page
  • msg_sender
  • 合约所有权 (Contract Ownership)
  1. 5. 用Sway部署区块链 (Blockchain Development with Sway)

5.6 访问控制 (Access Control)

Smart contracts require the ability to restrict access to and identify certain users or contracts. Unlike account-based blockchains, transactions in UTXO-based blockchains (i.e. Fuel) do not necessarily have a unique transaction sender. Additional logic is needed to handle this difference, and is provided by the standard library.

智能合约要求能够限制对某些用户或合约的访问及其识别。与基于账户的区块链不同,基于UTXO的区块链(即Fuel)中的交易不一定有一个唯一的交易发送者。需要额外的逻辑来处理这种差异,并由标准库提供。

msg_sender

To deliver an experience akin to the EVM's access control, the std library provides a msg_sender function, which identifies a unique caller based upon the call and/or transaction input data.

为了提供类似于EVM访问控制的体验,std库提供了一个msg_sender函数,它根据调用和/或交易输入数据识别一个独特的调用者。

contract;

use std::auth::msg_sender;

abi MyOwnedContract {
    fn receive(field_1: u64) -> bool;
}

const OWNER = Address::from(0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c);

impl MyOwnedContract for Contract {
    fn receive(field_1: u64) -> bool {
        let sender = msg_sender().unwrap();
        if let Identity::Address(addr) = sender {
            assert(addr == OWNER);
        } else {
            revert(0);
        }

        true
    }
}

The msg_sender function works as follows: msg_sender函数的工作原理如下:

  • If the caller is a contract, then Result::Ok(Sender) is returned with the ContractId sender variant. 如果调用者是一个合约,那么Result::Ok(Sender)将被返回,并带有ContractId的发送者变量。

  • If the caller is external (i.e. from a script), then all coin input owners in the transaction are checked. If all owners are the same, then Result::Ok(Sender) is returned with the Address sender variant. 如果调用者是外部的(即来自脚本),那么将检查交易中所有代币输入的所有者。如果所有所有者都是相同的,那么Result::Ok(Sender)将以Address发件人变量返回。

  • If the caller is external and coin input owners are different, then the caller cannot be determined and a Result::Err(AuthError) is returned. 如果调用者是外部的,而代币输入所有者是不同的,那么调用者就无法确定,并返回`Result::Err(AuthError)'。

合约所有权 (Contract Ownership)

Many contracts require some form of ownership for access control. To accomplish this, it is recommended that a storage variable of type Option<Identity> is used to keep track of the owner. This allows setting and revoking ownership using the variants Some(..) and None respectively. This is better, safer, and more readable than using the Identity type directly where revoking ownership has to be done using some magic value such as std::constants::ZERO_B256 or otherwise.

许多合约需要某种形式的所有权来进行访问控制。为了达到这个目的,建议使用一个Option<Identity>类型的存储变量来跟踪所有者。这允许使用变体Some(..)和None分别设置和撤销所有权。这比直接使用Identity类型更好、更安全、更易读,在那里,撤销所有权必须使用一些“魔法”值,如std::constants::ZERO_B256或其他。

The following is an example of how to properly set ownership of a contract: 下面是一个如何正确设置合约所有权的例子:

    #[storage(write)]
    fn set_owner(identity: Identity) {
        storage.owner.write(Option::Some(identity));
    }

The following is an example of how to properly revoke ownership of a contract: 下面是一个如何正确撤销合约所有权的例子:

    #[storage(write)]
    fn revoke_ownership() {
        storage.owner.write(Option::None);
    }
Previous5.5 原生资产(Native Assets)Next5.7 调用合约(Calling Contracts)

Last updated 1 year ago