暂停库允许合约实现紧急停止机制。这在诸如出现大型错误时需要一个紧急开关以冻结所有交易的情况下非常有用。
强烈建议将拥有权库 与暂停库结合使用,以确保只有单个管理员用户有权暂停您的合约。
有关暂停库的实现详细信息,请参阅Sway Libs 文档 。
要使用暂停库,必须将 Sway Libs 添加到Forc.toml
文件中,然后将其导入到您的 Sway 项目中。要将 Sway Libs 作为项目的依赖项添加到Forc.toml
文件中,请参阅入门指南 。
要将暂停库导入到您的 Sway 智能合约中,请在您的 Sway 文件中添加以下内容:
use sway_libs::pausable::*;
Pausable
abi 暂停库有两种状态:
Paused
Unpaused
默认情况下,您的合约将从Unpaused
状态开始。要暂停您的合约,您可以调用_pause()
函数。下面的示例提供了一个使用 Pausable 库的基本可暂停合约,其中使用了 Pausable 库的Pausable
abi,但没有任何限制,如管理员。
use sway_libs::pausable::{_is_paused, _pause, _unpause, Pausable};
impl Pausable for Contract {
#[storage(write)]
fn pause() {
_pause();
}
#[storage(write)]
fn unpause() {
_unpause();
}
#[storage(read)]
fn is_paused() -> bool {
_is_paused()
}
}
在开发合约时,您可能希望将函数锁定到特定状态。为此,您可以调用require_paused()
或require_not_paused()
函数之一。下面的示例展示了这些函数的使用。
use sway_libs::pausable::require_paused;
#[storage(read)]
fn require_paused_state() {
require_paused();
// This comment will only ever be reached if the contract is in the paused state
}
use sway_libs::pausable::require_not_paused;
#[storage(read)]
fn require_not_paused_state() {
require_not_paused();
// This comment will only ever be reached if the contract is in the unpaused state
}
强烈建议将拥有权库 与暂停库结合使用,并将限制应用于pause()
和unpause()
函数。这将确保只有单个用户在紧急情况下才能暂停和取消暂停合约。如果不应用此限制,将允许任何用户阻碍合约的功能。
以下示例实现了Pausable
abi,并对其暂停/取消暂停函数应用了限制。在此示例中,合约的所有者必须在一个名为MyConstructor
的构造函数中设置。
use sway_libs::{
ownership::{
initialize_ownership,
only_owner,
},
pausable::{
_is_paused,
_pause,
_unpause,
Pausable,
},
};
abi MyConstructor {
#[storage(read, write)]
fn my_constructor(new_owner: Identity);
}
impl MyConstructor for Contract {
#[storage(read, write)]
fn my_constructor(new_owner: Identity) {
initialize_ownership(new_owner);
}
}
impl Pausable for Contract {
#[storage(write)]
fn pause() {
// Add the `only_owner()` check to ensure only the owner may unpause this contract.
only_owner();
_pause();
}
#[storage(write)]
fn unpause() {
// Add the `only_owner()` check to ensure only the owner may unpause this contract.
only_owner();
_unpause();
}
#[storage(read)]
fn is_paused() -> bool {
_is_paused()
}
}