Sway 从根本上讲是一种区块链语言,它提供了一系列针对区块链使用场景定制的类型。
这些类型通过标准库(lib-std
)提供,既增加了类型安全性,又使开发者的意图更加清晰。
Address
类型 Address
类型是原始 b256
类型的类型安全封装。与 EVM 不同,地址 永远不会 指代已部署的智能合约(参见下文的 ContractId
类型)。Address
可能是公钥的哈希值(如果你来自 EVM,则有效地是一个外部拥有的账户 ),也可能是 断言 的哈希值。地址拥有 UTXOs。
Address
的实现如下。
pub struct Address {
value: b256,
}
在 b256
和 Address
类型之间进行转换必须显式进行:
let my_number: b256 = 0x000000000000000000000000000000000000000000000000000000000000002A;
let my_address: Address = Address::from(my_number);
let forty_two: b256 = my_address.into();
ContractId
类型 ContractId
类型是原始 b256
类型的类型安全封装。合约的 ID 是一个唯一的、确定性的标识符,类似于 EVM 中合约的地址。合约不能拥有 UTXOs,但可以拥有资产。
ContractId
的实现如下。
pub struct ContractId {
value: b256,
}
在 b256
和 ContractId
类型之间进行转换必须显式进行:
let my_number: b256 = 0x000000000000000000000000000000000000000000000000000000000000002A;
let my_contract_id: ContractId = ContractId::from(my_number);
let forty_two: b256 = my_contract_id.into();
ContractId
在内部环境中获取合约的 ContractId
使用 ContractId::this()
函数:
impl MyContract for Contract {
fn foo() {
let this_contract_id: ContractId = ContractId::this();
}
}
Identity
类型 Identity
类型是一个枚举类型,允许处理 Address
和 ContractId
类型。这在接受两种类型的情况下非常有用,例如从已识别的发送方接收资金,但不关心发送方是地址还是合约。
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
语句可以用于返回 Address
或 ContractId
,并处理它们的执行方式不同的情况。
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
的独特使用方式允许同时包含 ContractId
和 Address
的访问控制。
let sender = msg_sender().unwrap();
require(
sender == storage
.owner
.read(),
MyError::UnauthorizedUser(sender),
);