Blockchain Types

Icon Link区块链类型

Sway 从根本上讲是一种区块链语言,它提供了一系列针对区块链使用场景定制的类型。

这些类型通过标准库(lib-std Icon Link)提供,既增加了类型安全性,又使开发者的意图更加清晰。

Icon LinkAddress 类型

Address 类型是原始 b256 类型的类型安全封装。与 EVM 不同,地址 永远不会 指代已部署的智能合约(参见下文的 ContractId 类型)。Address 可能是公钥的哈希值(如果你来自 EVM,则有效地是一个外部拥有的账户 Icon Link),也可能是 断言 的哈希值。地址拥有 UTXOs。

Address 的实现如下。

pub struct Address {
value: b256,
}

b256Address 类型之间进行转换必须显式进行:

let my_number: b256 = 0x000000000000000000000000000000000000000000000000000000000000002A;
let my_address: Address = Address::from(my_number);
let forty_two: b256 = my_address.into();

Icon LinkContractId 类型

ContractId 类型是原始 b256 类型的类型安全封装。合约的 ID 是一个唯一的、确定性的标识符,类似于 EVM 中合约的地址。合约不能拥有 UTXOs,但可以拥有资产。

ContractId 的实现如下。

pub struct ContractId {
value: b256,
}

b256ContractId 类型之间进行转换必须显式进行:

let my_number: b256 = 0x000000000000000000000000000000000000000000000000000000000000002A;
let my_contract_id: ContractId = ContractId::from(my_number);
let forty_two: b256 = my_contract_id.into();

Icon Link获取合约的 ContractId

在内部环境中获取合约的 ContractId 使用 ContractId::this() 函数:

impl MyContract for Contract {
fn foo() {
let this_contract_id: ContractId = ContractId::this();
}
}

Icon LinkIdentity 类型

Identity 类型是一个枚举类型,允许处理 AddressContractId 类型。这在接受两种类型的情况下非常有用,例如从已识别的发送方接收资金,但不关心发送方是地址还是合约。

Identity 的实现如下。

pub enum Identity {
    Address: Address,
    ContractId: ContractId,
}

将类型转换为 Identity 必须显式进行:

let raw_address: b256 = 0xddec0e7e6a9a4a4e3e57d08d080d71a299c628a46bc609aab4627695679421ca;
let my_identity: Identity = Identity::Address(Address::from(raw_address));

match 语句可以用于返回 AddressContractId,并处理它们的执行方式不同的情况。

let my_contract_id: ContractId = match my_identity {
    Identity::ContractId(identity) => identity,
    _ => revert(0),
};
match my_identity {
    Identity::Address(address) => takes_address(address),
    Identity::ContractId(contract_id) => takes_contract_id(contract_id),
};

Identity 的一个常见用例是用于访问控制。Identity 的独特使用方式允许同时包含 ContractIdAddress 的访问控制。

let sender = msg_sender().unwrap();
require(
    sender == storage
        .owner
        .read(),
    MyError::UnauthorizedUser(sender),
);