在这周,NFT 租赁市场 Double Protocol 提交的可租赁 NFT 标准“EIP-4907”通过了以太坊开发团队的最终审核,成为第 30 个 ERC 标准“Final”的状态。
让我们一起来阅读这极简的源代码,来缕清其他是如何实现NFT租赁的?
NFT 的爆发毋庸置疑,而伴随普及引发了对其资产实用性的需求,尤其是在元宇宙和边玩边赚 (P2E) 的场景下,仅仅单纯的资产所有权并不足以支撑更多的应用玩法的诞生。
一直的痛点是供给不平衡,导致的好项目少,浮于金融玩法的韭菜项目多,既然如今web3有大量web2行业精英在涌入,也必然需要快速的新标准推出,来将创造力的供给释放。
NFT流动性的紧缺,使得他风风火火的同时也备受诟病,他之前产权一体化的金融化操作,市场各类安全问题欺诈、剽窃、钓鱼、跑路、资产被盗层出不穷。
而Eip-4907,想要解决的就是分离NFT的资产价值和使用价值,释放出NFT的市场流动性
他作为 ERC-721 的扩展, EIP-4907 增加了一个变量UserInfo,让应用可以查询此NFT当前被租出去的目标地址“user”和出租时间”expires"。如果发现已经超出出租时间,则租赁关系宣告失效。
代码极为简单仅有72行,使用这个标准,就是在原来的ERC721之上新增
1个事件(用于通知链下应用称为事件)
3个方法(用于实现链上数据管理功能)
分别是
UpdateUser 事件:当NFT转移,租赁校色设置时,发出租赁用户改变的通知
setUser 方法:NFT所有者授权者可用,设置此NFTID的出租用户和过期时间
userOf 方法:任何人可用,查询此NFTID的出租用户
userExpires 方法:任何人可用,查询此NFTID的过期时间
理解ERC标准协议的最佳方式就是理解他管理数据的最底层数据结构
例如:前文【源码解读】你买的NFT到底是什么?
其实NFT只是通过2个映射(_owners,_balances),即一种字典形式的key-value对应关系的存储结构去记录数据
mapping(uint256 => address) _owners;// 记录每一个NFTID当前对应的所有者地址mapping(address => uint256) _balances; //记录了当前所有者总计持有的NFT数量
而Eip-4907则是新增了一个数据对象UserInfo 在所有权的概念之外增加“用户”的维度
struct UserInfo {address user; // 用户地址uint64 expires; //用户到期时间}
数据结构简单,就意味着管理的方法实现也非常简单
设置用户仅有3个步骤
【审计】此交易的发起者其是否持有此NFTid或是有Approved自动扣款权利
【设置】设置UserInfo中用户的用户地址和到期时间
【通知】发出设置成功的UpdateUser事件
function setUser(uint256 tokenId, address user, uint64 expires) public virtual{require(_isApprovedOrOwner(msg.sender, tokenId),"ERC721: transfer caller is not owner nor approved");UserInfo storage info = _users[tokenId];//新增存储登记信息info.user = user;info.expires = expires;emit UpdateUser(tokenId,user,expires); //发出事件通知链下应用}
媒体处处宣传的超时自动失效,而无需二次链上交易登记失效节约gas的逻辑就在这了。
查询的逻辑很简单,按指定的NFTID查询 _users的user信息即可,但他增加了,if判断,当前块的时间block.timestamp 是否会超过设置的过期时间expires,所以此查询仅在时间内有效。
function userOf(uint256 tokenId)public view virtual returns(address){if( uint256(_users[tokenId].expires) >= block.timestamp){return _users[tokenId].user;};//执行此函数,在未到期的情况下,返回此ID的当前用户地址else{return address(0);}//到期情况下,则返回0地址,意未占用}
此处无需类似user查询时候判断是否过期,因为得知上一次过期时间,也是加快NFT用户使用率的一种方式。
function userExpires(uint256 tokenId) public view virtual returns(uint256){return _users[tokenId].expires;//执行此函数,返回此ID的用户过期时间}
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);// 发出事件通知已删除}}
总结
没想到吧,这么快就代码讲完了,因为确实他写完了,对的,不像是之前的通过限制转移权的方法EIP-5058,见前文【EIP-5058 能否防止NFT项目方提桶跑路?】
其实他EIP-4907只是多了个变量,并称之为租赁用户而已,可以声明,但是其他应用认不认就是另一码事了,毕竟其强制性有限,转移就能强行终止出租授权
当然你或许会问,为什么这么简单反而火速成为了难得一见,且每次都能掀起一番波浪的Final标准呢?
这也就是web3的哲学:越简单,越优雅,剩下的交给共识。
我个人认可这样的哲学与趋势
web3过去爆发或是得益于金融操作,但是好的生态不能只是金融价值,还需要更有商业价值,需要更广大的用户融入于生活生产形成价值闭环,货币终究只是手段而不是目的本身
引用:
https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4907.md
写在最后:
【解密】OpenSea免费创造的NFT都没上链竟能出现在我的钱包里?
欢迎各位同学从后台提交有趣的合约或交易哈希。
关注十四,用技术的眼光发现价值。
看到这里,帅气的你不点个赞吗?