以太坊应用层标准提案NFT之ERC-2981

一 什么是NFT 版税(Royalty)?

1.1 版税

版税指的是创作者或者拥有者允许其作品在被销售或者别人使用的使用的时候按照约定的比例收取一定的费用,作为创作者或者拥有者的收益。那么这种针对作品收取费用的方式就是版税。

1.2 NFT版税

指的是NFT的拥有者在市场通过出售或者租赁按照约定比例收取一定费用的。这种类型的版税在NFT艺术品和收藏品市场中非常常见。当NFT在次级市场上被转售时,原始创作者可以通过智能合约自动获得销售金额的一定百分比作为版税。这为艺术家和创作者提供了一种持续收益的机会,即使他们的作品已经初次出售。

二 ERC-2981标准提案规范

royaltyInfo

function royaltyInfo(uint256 _tokenId, uint256 _salePrice) external view returns (address receiver,uint256 royaltyAmount);

根据销售价格和tokenId计算NFT应该支付多少版税,以及支付给谁

三 ERC-2981手动实现

interface IERC2981 {

    struct RoyaltyInfo {
        address receiver;
        uint96 fraction;
    }

    /**
     * Return the royalty receiver and amount bv salePrice and tokenId
     * @param _tokenId the NFT asset id
     * @param _salePrice  the sale price of the NFT asset
     * @return receiver address of who should be sent the royalty payment
     * @return royaltyAmount the royalty payment amount
     */
    function royaltyInfo(uint256 _tokenId, uint256 _salePrice) external view returns (address receiver,uint256 royaltyAmount);
}
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import "./IERC2981.sol";
import "../ERC165/IERC165.sol";
import "../ERC165/ERC165.sol";
abstract contract ERC2981 is IERC2981 {

    uint256 private constant Fee_Denominator = 10000;

    RoyaltyInfo private _defaultRoyaltyInfo;

    // different royalty against the different token
    mapping(uint256 tokenId => RoyaltyInfo) private _tokenRoyaltyInfo;

    error ERC2981InvalidDefaultRoyalty(uint256 numerator, uint256 denominator);

    error ERC2981InvalidDefaultRoyaltyReceiver(address receiver);

    error ERC2981InvalidTokenRoyalty(uint256 tokenId, uint256 numerator, uint256 denominator);

    error ERC2981InvalidTokenRoyaltyReceiver(uint256 tokenId, address receiver);

    function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual returns (address, uint256) {
        RoyaltyInfo memory royalty = _tokenRoyaltyInfo[tokenId];

        if (royalty.receiver == address(0)) {
            royalty = _defaultRoyaltyInfo;
        }

        uint256 royaltyAmount = (salePrice * royalty.fraction) / Fee_Denominator;

        return (royalty.receiver, royaltyAmount);
    }

    /**
     * Set default royalty
     * @param receiver address of who accept the royalty
     * @param feeNumerator numerator of calculating the royalty
     */
    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
        if (feeNumerator > Fee_Denominator) {
            // Royalty fee will exceed the sale price
            revert ERC2981InvalidDefaultRoyalty(feeNumerator, denominator);
        }
        if (receiver == address(0)) {
            revert ERC2981InvalidDefaultRoyaltyReceiver(address(0));
        }

        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Removes default royalty information.
     */
    function _deleteDefaultRoyalty() internal virtual {
        delete _defaultRoyaltyInfo;
    }

    /**
     * @dev Sets the royalty information for a specific token id, overriding the global default.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual {
        if (feeNumerator > Fee_Denominator) {
            // Royalty fee will exceed the sale price
            revert ERC2981InvalidTokenRoyalty(tokenId, feeNumerator, Fee_Denominator);
        }
        if (receiver == address(0)) {
            revert ERC2981InvalidTokenRoyaltyReceiver(tokenId, address(0));
        }

        _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Resets royalty information for the token id back to the global default.
     */
    function _resetTokenRoyalty(uint256 tokenId) internal virtual {
        delete _tokenRoyaltyInfo[tokenId];
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莫言静好、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值