ERC-721 token 合约的扩展,用于支持 token 包装。

用户可以存入和提取 "底层 tokens",并收到相应数量的 "包装 tokens"。 这在与其他模块结合使用时非常有用。

用法

为了使 ERC721Wrapper 方法成为 "external",以便其他合约可以调用它们,您需要为您最终的合约自行实现它们,如下所示:

use openzeppelin_stylus::{
    token::erc721::{
        self,
        extensions::{wrapper, Erc721Wrapper, IErc721Wrapper},
        Erc721, IErc721,
    },
    utils::introspection::erc165::IErc165,
};

#[entrypoint]
#[storage]
struct Erc721WrapperExample {
    erc721: Erc721,
    erc721_wrapper: Erc721Wrapper,
}

#[public]
#[implements(IErc721<Error = erc721::Error>, IErc721Wrapper<Error = wrapper::Error>, IErc165)]
impl Erc721WrapperExample {
    #[constructor]
    fn constructor(&mut self, underlying_token: Address) {
        self.erc721_wrapper.constructor(underlying_token);
    }
}

#[public]
impl IErc721 for Erc721WrapperExample {
    type Error = erc721::Error;

    fn balance_of(&self, owner: Address) -> Result<U256, Self::Error> {
        self.erc721.balance_of(owner)
    }

    fn owner_of(&self, token_id: U256) -> Result<Address, Self::Error> {
        self.erc721.owner_of(token_id)
    }

    fn safe_transfer_from(
        &mut self,
        from: Address,
        to: Address,
        token_id: U256,
    ) -> Result<(), Self::Error> {
        self.erc721.safe_transfer_from(from, to, token_id)
    }

    fn safe_transfer_from_with_data(
        &mut self,
        from: Address,
        to: Address,
        token_id: U256,
        data: Bytes,
    ) -> Result<(), Self::Error> {
        self.erc721.safe_transfer_from_with_data(from, to, token_id, data)
    }

    fn transfer_from(
        &mut self,
        from: Address,
        to: Address,
        token_id: U256,
    ) -> Result<(), Self::Error> {
        self.erc721.transfer_from(from, to, token_id)
    }

    fn approve(
        &mut self,
        to: Address,
        token_id: U256,
    ) -> Result<(), Self::Error> {
        self.erc721.approve(to, token_id)
    }

    fn set_approval_for_all(
        &mut self,
        to: Address,
        approved: bool,
    ) -> Result<(), Self::Error> {
        self.erc721.set_approval_for_all(to, approved)
    }

    fn get_approved(&self, token_id: U256) -> Result<Address, Self::Error> {
        self.erc721.get_approved(token_id)
    }

    fn is_approved_for_all(&self, owner: Address, operator: Address) -> bool {
        self.erc721.is_approved_for_all(owner, operator)
    }
}

#[public]
impl IErc721Wrapper for Erc721WrapperExample {
    type Error = wrapper::Error;

    fn underlying(&self) -> Address {
        self.erc721_wrapper.underlying()
    }

    fn deposit_for(
        &mut self,
        account: Address,
        token_ids: Vec<U256>,
    ) -> Result<bool, Self::Error> {
        self.erc721_wrapper.deposit_for(account, token_ids, &mut self.erc721)
    }

    fn withdraw_to(
        &mut self,
        account: Address,
        token_ids: Vec<U256>,
    ) -> Result<bool, Self::Error> {
        self.erc721_wrapper.withdraw_to(account, token_ids, &mut self.erc721)
    }

    fn on_erc721_received(
        &mut self,
        operator: Address,
        from: Address,
        token_id: U256,
        data: Bytes,
    ) -> Result<B32, Self::Error> {
        self.erc721_wrapper.on_erc721_received(
            operator,
            from,
            token_id,
            &data,
            &mut self.erc721,
        )
    }
}

#[public]
impl IErc165 for Erc721WrapperExample {
    fn supports_interface(&self, interface_id: B32) -> bool {
        self.erc721.supports_interface(interface_id)
    }
}