Alert Source Discuss
⚠️ Draft Standards Track: ERC

ERC-7564: 合约钱包管理 NFT

专注于智能合约钱包内的 NFT 管理,提供增强的交易灵活性和安全性

Authors Xiang (@wenzhenxiang), Ben77 (@ben2077), Mingshi S. (@newnewsms)
Created 2023-11-21
Discussion Link https://ethereum-magicians.org/t/erc-draft-contract-wallet-management-nft/16702
Requires EIP-165

摘要

本提案介绍了一种基于智能合约钱包的方法来管理 NFT,重点是利用智能合约钱包的可编程特性进行 NFT 资产管理。此外,它还引入了诸如 nftApprovenftSetApprovalForOneAllnftSetApprovalForAllAllnftGetApprovednftIsApprovedForOneAllnftIsApprovedForAllAllnftTransfer 等函数,这些函数提供了对 NFT 交易的增强控制。这种方法旨在通过利用智能合约钱包的内置功能来增强 NFT 管理,从而为管理 token 交易提供一种更具适应性、安全性和效率的方法。

动机

外部拥有账户 (EOA) 钱包没有状态和代码存储,而智能合约钱包有。

账户抽象 (AA) 是智能合约钱包的一个发展方向,它围绕抽象账户展开。这个 ERC 也可以是基于 ERC-4337 的扩展,或者作为钱包的插件。

智能合约钱包允许用户自己的账户拥有状态和代码,从而为钱包带来可编程性。我们认为有更多的方向可以扩展。例如,nft 资产管理、nft 交易的功能扩展等。

本 ERC 的智能合约钱包接口用于 nft 资产管理和 nft 资产授权。它支持 simplenft ERC-X,并且 ERC-721 向后兼容 ERC-X,因此它可以兼容现有市场中所有 nft 的管理。

该提案旨在实现以下目标:

  1. NFT 资产由钱包本身分配和管理,例如 approve 功能,这些功能由用户的合约钱包配置,而不是由 nft 资产合约控制,以避免一些现有的 ERC-721 合约风险。
  2. 添加 nftTransfer 函数,该交易由非智能钱包本身发起。
  3. 添加 nftApprovenftSetApprovalForOneAllnftSetApprovalForAllAllnftGetApprovednftIsApprovedForOneAllnftIsApprovedForAllAll 函数。用户钱包本身支持 approve 并为 One nft、一个 nft 智能合约的所有 nft 资产、所有 nft 资产提供 approve。
  4. 用户钱包可以选择批量 approve 和批量 transfer。
  5. 用户可以选择在他们的 nftTransfer 之前和之后添加 hook 函数,以增加用户的更多可玩性。
  6. 用户可以选择实现 nftReceive 函数。

规范

本文档中使用的关键词“必须(MUST)”、“禁止(MUST NOT)”、“必需(REQUIRED)”、“应该(SHALL)”、“不应该(SHALL NOT)”、“应当(SHOULD)”、“不应当(SHOULD NOT)”、“推荐(RECOMMENDED)”、“不推荐(NOT RECOMMENDED)”、“可以(MAY)”和“可选(OPTIONAL)”应按照 RFC 2119 和 RFC 8174 中的描述进行解释。

兼容合约必须实现 ERC-165 接口


/// @title ERC-7564
/// @dev See https://eips.ethereum.org/EIPS/eip-7564
/// @dev Note: the ERC-165 identifier for this interface is 
pragma solidity ^0.8.20;

interface IERC7564{

    /**
     * @notice Used to notify listeners that owner has granted approval to the user to manage one nft.
     * @param _asset Address of the nft
     * @param _owner Address of the account that has granted the approval for nft‘s assets
     * @param _operator Address of the operator
     * @param _tokenId The unique identifier of the NFT
     */
    event NftApproval(
        address indexed _asset,
        address indexed _owner, 
        address indexed _operator, 
        uint256 _tokenId
    );

    /**
     * @notice Used to notify listeners that owner has granted approval to the operator to manage all nft of one asset contract.
     * @param _asset Address of the nft
     * @param _owner Address of the account that has granted the approval for nft‘s assets
     * @param _operator Address of the operator
     * @param _approved approve all nft of one asset contract
     */
    event NftApprovalForOneAll(
        address indexed _asset,
        address indexed _owner, 
        address indexed _operator,
        bool _approved
    );

    /**
     * @notice Used to notify listeners that owner has granted approval to the operator to manage all nft .
     * @param _owner Address of the account that has granted the approval for nft‘s assets
     * @param _operator Address of the operator
     * @param _approved approve all nft
     */
    event NftApprovalForAllAll(
        address indexed _owner, 
        address indexed _operator,
        bool _approved
    );

    /**
     * @notice Approve nft
     * @dev Allows operator address to withdraw from your wallet one nft.
     * @dev Emits an {nftApproval} event.
     * @param _asset Address of the nft
     * @param _operator Address of the operator
     * @param _tokenId The unique identifier of the NFT
     */
    function nftApprove(address _asset, address _operator, uint256 _tokenId) external;

   

    /**
     * @notice Approve all nft of one asset
     * @dev Allows operator address to withdraw from your wallet all nft.
     * @dev Emits an {nftApprovalForOneAll} event.
    * @param _asset Address of the nft
     * @param _operator Address of the operator
     * @param _approved Approved all nfts of one asset
     */
    function nftSetApprovalForOneAll(address _asset, address _operator, bool _approved) external;


     /**
     * @notice Approve all nft
     * @dev Allows operator address to withdraw from your wallet all nft.
     * @dev Emits an {nftApprovalForAllAll} event.
     * @param _operator Address of the operator
     * @param _approved Approved all nfts
     */
    function nftSetApprovalForAllAll(address _operator, bool _approved) external;

    /**
     * @notice read operator approved
     * @param _asset Address of the nft
     * @param _operator Address of the operator
     * @param _tokenId The unique identifier of the NFT
     * @return _approved Whether to approved operator one nft
     */
    function nftGetApproved(address _asset, address _operator, uint256 _tokenId) 
        external
        view
        returns (bool _approved);

    /**
     * @notice read operator approved
     * @param _asset Address of the nft
     * @param _operator Address of the operator
     * @return _approved Whether to approved operator all nfts of this one asset
     */
    function nftIsApprovedForOneAll(address _asset, address _operator) 
        external
        view
        returns (bool _approved);

    /**
     * @notice read operator approved
     * @param _operator Address of the operator
     * @return _approved Whether to approved operator all nfts
     */
    function nftIsApprovedForAllAll(address _operator) 
        external
        view
        returns (bool _approved);

    /**
     * @notice Transfer nft
     * @dev must call nft asset transfer() inside the function
     * @dev If the caller is not wallet self, must verify the approve and update
     * @param _asset Address of the nft
     * @param _to Address of the receive
     * @param _tokenId The transaction amount
     * @return _success The bool value returns whether the transfer is successful
     */
    function nftTransfer(address _asset, address _to, uint256 _tokenId) 
        external 
        returns (bool _success); 


}

理由

本提案中的关键技术决策是:

改进的 Approve 机制

  • 当前 vs. 提议: 在现有的 ERC-721 系统中,外部拥有账户 (EOA) 直接与 nft 合约交互以进行 approve。本提案中新的 nftApprovenftSetApprovalForOneAllnftSetApprovalForAllAllnftGetApprovednftIsApprovedForOneAllnftIsApprovedForAllAll 函数能够在钱包合约中实现对 nft 使用的更精确控制,这是对传统方法的一个重大改进。
  • 增强的安全性: 这种机制通过将 approval 控制转移到用户的智能合约钱包来降低 nft 过度 approval 等风险。
  • 可编程性: 用户可以设置高级 approval 策略,例如有条件或限时的 approval, nftSetApprovalForAllAll 函数专门允许对所有 nfts 进行通用设置。这些在传统的 ERC-721 nfts 中是不可能的。

优化的 Transfer 流程

  • 效率和安全性: nftTransfer 函数简化了 nft transfer 流程,使交易更高效、更安全。
  • 灵活性: 允许在 transfer 前后集成自定义逻辑(hooks),从而实现额外的安全检查或根据用户需求定制的特定操作。

支持批量操作

  • 提高效率: 用户可以同时处理多个 approvetransfer 操作,从而显著提高交易效率。
  • 增强的用户体验: 简化了对大量资产的管理,改善了拥有大型投资组合的用户的整体体验。

向后兼容性

此 ERC 可以用作 ERC-4337 的扩展,并且与 ERC-4337 向后兼容。

安全注意事项

未发现安全方面的考虑。

版权

版权和相关权利通过 CC0 放弃。

Citation

Please cite this document as:

Xiang (@wenzhenxiang), Ben77 (@ben2077), Mingshi S. (@newnewsms), "ERC-7564: 合约钱包管理 NFT [DRAFT]," Ethereum Improvement Proposals, no. 7564, November 2023. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7564.