ERC4907:租赁中介,让你的NFT租赁像租房一样简单

2 篇文章 0 订阅
1 篇文章 0 订阅

Hello ~ 大家好,首先感谢大家对本系列前两篇文章 👇👇👇 的喜爱,不知读者们都学废(不是,是学会)了吗?

ERC20:从入门到飞起,妈妈再也不用担心我不会写Token合约了

ERC721:全生命周期精析,妈妈再也不用担心我不会玩NFT合约啦

ERC1155: 批发小能手,妈妈再也不用担心网络拥堵造成的gas费飙升啦|猿创征文

今天主要想跟大家聊的是 ERC4907,于昨日(6月29日)新鲜过审。本文将基于官方给出的参考实现代码对ERC4907中的 UpdateUser 事件,和 setUser、userOf、userExpires三个接口展开详细介绍。由于篇幅有限,文章内容只能尽量做到通俗易懂,但其中不可避免地可能涉及一些新手不友好的概念,您可以查阅相关博客做进一步了解,本系列博客也会不断扩充、提升及优化,尽量做到不留死角,人人都能上手Solidity标准开发。

———————————————————————— 分割线 ————————————————————————

0. ERC 是什么鬼?

ERC 全称 Ethereum Request For Comment (以太坊意见征求稿), 是以太坊上应用级的开发标准和协议(application-level standards and conventions),为以太坊开发人员提供了实施标准,开发人员可以使用这些标准来构建智能合约。

ERC 的雏形是开发人员提交的EIP(Ethereum Improvement Proposals),即新的ERC标准提案,一旦其得到以太坊委员会的批准并最终确定,新的ERC便由此诞生。

1. 初识ERC4907 

ERC4907 是 ERC721 的扩展,新增了赋予 NFT 使用权的角色权限,能在为 Owner 保留所有权的同时拆分其持有 NFT 的使用权,可用于 Decentraland、STEPN 等项目中 NFT 资产的租赁场景。

2. 一个重要的数据结构及映射

数据结构 UserInfo 中包含两个关键变量:user 和 expires。user 用于存放具备 NFT 使用权的用户地址,expires 则保存使用权的到期时间。

数据结构 UserInfo 将作为映射 _users 的 value ,NFT 的 id 是该映射中的 key。

struct UserInfo {
    address user;   // address of user role
    uint64 expires; // unix timestamp, user expires
}

mapping (uint256  => UserInfo) internal _users;

3. 一个唯一的事件

事件 UpdateUser 共接收三个参数:NFT id 、被赋予使用权的用户地址 和 使用权的到期时间,该事件将在 NFT 用户使用权发生变更时被触发。

// Logged when the user of a NFT is changed or expires is changed
/// @notice Emitted when the `user` of an NFT or the `expires` of the `user` is changed
/// The zero address for user indicates that there is no user address

event UpdateUser(uint256 indexed tokenId, address indexed user, uint64 expires);

4. 使用权赋予接口

接口 setUser 接收三个参数:NFT id 、被赋予使用权的用户地址 和 使用权的到期时间,用于赋予(更新)传入地址对特定NFT在指定时间前的使用权限。

该接口首先要求调用者是传入 NFT 的 owner 或具备操作该 NFT 的权限,然后将传入的用户地址和到期时间存入数据结构 UserInfo ,并将该数据结构作为 _users 映射中键 NFT id 的值进行存储,最后触发事件 UpdateUser 。

/// @notice set the user and expires of a NFT
/// @dev The zero address indicates there is no user
/// Throws if `tokenId` is not valid NFT
/// @param user  The new user of the NFT
/// @param expires  UNIX timestamp, The new user could use the NFT before expires

function setUser(uint256 tokenId, address user, uint64 expires) public virtual{
    require(_isApprovedOrOwner(msg.sender, tokenId), "ERC4907: transfer caller is not owner nor approved");
    UserInfo storage info =  _users[tokenId];
    info.user = user;
    info.expires = expires;
    emit UpdateUser(tokenId, user, expires);
}

5.  使用权查询接口

接口 userOf 用于查询指定 NFT 的使用者地址。该接口接收 NFT id 作为参数,首先通过映射 _users 找到数据结构中使用权的到期时间,并将其与当前区块时间进行对比,若大于当前区块时间,则返回数据结构中的使用者地址,否则返回 0 地址。

/// @notice Get the user address of an NFT
/// @dev The zero address indicates that there is no user or the user is expired
/// @param tokenId The NFT to get the user address for
/// @return The user address for this NFT

function userOf(uint256 tokenId) public view virtual returns(address){
    if( uint256(_users[tokenId].expires) >=  block.timestamp){
        return  _users[tokenId].user;
    }
    else{
        return address(0);
    }
}

6.  使用期限查询接口

接口 userExpires 用于查询指定 NFT 使用权的到期时间。该接口接收 NFT id 作为参数,并将其作为键,在映射 _users 中找到数据结构,并返回数据结构中的到期时间。

/// @notice Get the user expires of an NFT
/// @dev The zero value indicates that there is no user
/// @param tokenId The NFT to get the user expires for
/// @return The user expires for this NFT

function userExpires(uint256 tokenId) public view virtual returns(uint256){
    return _users[tokenId].expires;
}

7. NFT 所有权转移前的特殊操作

官方给出的参考实现代码中,还给出了一个 _beforeTokenTransfer 内部接口,用于在进行 NFT 所有权转移前清空该 NFT 的使用权。

该内部接口接收 NFT 转出地址、转入地址和 id 三个参数,首先调用继承来的同名函数,然后进行两个条件判断:一是转出地址不等于转入地址,二是转入地址不为 0 地址。在满足条件的情况下删除 _users 中键为传入 NFT id 的映射,并触发使用权更新事件 UpdateUser,将使用权声明为 0 地址并将过期时间置 0 。

function _beforeTokenTransfer(
    address from,
    address to,
    uint256 tokenId
) internal virtual override{
    super._beforeTokenTransfer(from, to, tokenId);

    if (from != to && _users[tokenId].user != address(0)) {
        delete _users[tokenId];
        emit UpdateUser(tokenId, address(0), 0);
    }
}

至此,ERC4907 的接口都已介绍完毕,你学会了嘛~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一个可爱的小朋友

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

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

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

打赏作者

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

抵扣说明:

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

余额充值