ERC-1155 可暂停的
具有可暂停的 token 转移、铸造和燃烧的 ERC-1155 token。
适用于诸如在评估期结束前阻止交易,或者在发生大型错误时使用紧急开关来冻结所有 token 转移等情况。
用法
use openzeppelin_stylus::{
token::erc1155::{self, Erc1155, IErc1155},
utils::{introspection::erc165::IErc165, pausable, IPausable, Pausable},
};
#[derive(SolidityError, Debug)]
enum Error {
InsufficientBalance(erc1155::ERC1155InsufficientBalance),
InvalidSender(erc1155::ERC1155InvalidSender),
InvalidReceiver(erc1155::ERC1155InvalidReceiver),
InvalidReceiverWithReason(erc1155::InvalidReceiverWithReason),
MissingApprovalForAll(erc1155::ERC1155MissingApprovalForAll),
InvalidApprover(erc1155::ERC1155InvalidApprover),
InvalidOperator(erc1155::ERC1155InvalidOperator),
InvalidArrayLength(erc1155::ERC1155InvalidArrayLength),
EnforcedPause(pausable::EnforcedPause),
ExpectedPause(pausable::ExpectedPause),
}
impl From<erc1155::Error> for Error {
fn from(value: erc1155::Error) -> Self {
match value {
erc1155::Error::InsufficientBalance(e) => {
Error::InsufficientBalance(e)
}
erc1155::Error::InvalidSender(e) => Error::InvalidSender(e),
erc1155::Error::InvalidReceiver(e) => Error::InvalidReceiver(e),
erc1155::Error::InvalidReceiverWithReason(e) => {
Error::InvalidReceiverWithReason(e)
}
erc1155::Error::MissingApprovalForAll(e) => {
Error::MissingApprovalForAll(e)
}
erc1155::Error::InvalidApprover(e) => Error::InvalidApprover(e),
erc1155::Error::InvalidOperator(e) => Error::InvalidOperator(e),
erc1155::Error::InvalidArrayLength(e) => {
Error::InvalidArrayLength(e)
}
}
}
}
impl From<pausable::Error> for Error {
fn from(value: pausable::Error) -> Self {
match value {
pausable::Error::EnforcedPause(e) => Error::EnforcedPause(e),
pausable::Error::ExpectedPause(e) => Error::ExpectedPause(e),
}
}
}
#[entrypoint]
#[storage]
struct Erc1155Example {
erc1155: Erc1155,
pausable: Pausable,
}
#[public]
#[implements(IErc1155<Error = Error>, IPausable)]
impl Erc1155Example {
fn mint(
&mut self,
to: Address,
token_id: U256,
amount: U256,
data: Bytes,
) -> Result<(), Error> {
// ...
self.pausable.when_not_paused()?;
// ...
self.erc1155._mint(to, token_id, amount, &data)?;
Ok(())
}
fn mint_batch(
&mut self,
to: Address,
token_ids: Vec<U256>,
amounts: Vec<U256>,
data: Bytes,
) -> Result<(), Error> {
// ...
self.pausable.when_not_paused()?;
// ...
self.erc1155._mint_batch(to, token_ids, amounts, &data)?;
Ok(())
}
}
#[public]
impl IPausable for Erc1155Example {
fn paused(&self) -> bool {
self.pausable.paused()
}
}
#[public]
impl IErc1155 for Erc1155Example {
type Error = Error;
fn safe_transfer_from(
&mut self,
from: Address,
to: Address,
id: U256,
value: U256,
data: Bytes,
) -> Result<(), Self::Error> {
// ...
self.pausable.when_not_paused()?;
// ...
self.erc1155.safe_transfer_from(from, to, id, value, data)?;
Ok(())
}
fn safe_batch_transfer_from(
&mut self,
from: Address,
to: Address,
ids: Vec<U256>,
values: Vec<U256>,
data: Bytes,
) -> Result<(), Self::Error> {
// ...
self.pausable.when_not_paused()?;
// ...
self.erc1155.safe_batch_transfer_from(from, to, ids, values, data)?;
Ok(())
}
fn balance_of(&self, account: Address, id: U256) -> U256 {
self.erc1155.balance_of(account, id)
}
fn balance_of_batch(
&self,
accounts: Vec<Address>,
ids: Vec<U256>,
) -> Result<Vec<U256>, Self::Error> {
Ok(self.erc1155.balance_of_batch(accounts, ids)?)
}
fn set_approval_for_all(
&mut self,
operator: Address,
approved: bool,
) -> Result<(), Self::Error> {
Ok(self.erc1155.set_approval_for_all(operator, approved)?)
}
fn is_approved_for_all(&self, account: Address, operator: Address) -> bool {
self.erc1155.is_approved_for_all(account, operator)
}
}
#[public]
impl IErc165 for Erc1155Example {
fn supports_interface(&self, interface_id: B32) -> bool {
self.erc1155.supports_interface(interface_id)
}
}