/// Note: the ERC-165 identifier for this interface is 0xded6338b
interfaceIERC5023isIERC165{/// @dev 当代币被共享、重新铸造并给予非函数调用者的其他钱包时,会发出此事件
eventShare(addressindexedfrom,addressindexedto,uint256indexedtokenId,uint256derivedFromtokenId);/// @dev 共享,重新铸造现有代币,为新铸造的代币提供一个新的代币 ID,将原始代币保留在函数调用者的手中,并将新铸造的代币转移给接收者,该接收者应为与函数调用者不同的地址。
functionshare(addressto,uint256tokenIdToBeShared)externalreturns(uint256newTokenId);}
当成功调用函数方法 share 并且在给定代币 ID 的基础上铸造新代币并将其转移给接收者时,预计会发出 Share 事件。
假设 Bob 与 Alice 合作完成一个项目。Bob 获得一个独特的 NFT,表明他为该项目做出了努力,但 Bob 认为他的成就不完全是他自己的功劳。Bob 希望与 Alice 共享他的代币,以表明 Alice 也应该因对他们的项目所做的努力而获得认可。Bob 通过调用合约上的 Share 方法来启动代币共享,该合约具有他的代币,并通过传递地址和代币 ID 参数来指示他希望共享他的哪个代币以及共享给谁。为 Alice 铸造了一个新代币,并启动了一个 Share 事件,以通过记录将代币 ID 共享给谁的地址以及这个新代币源自哪个代币 ID 来传达是 Bob 将他的代币共享给了 Alice。
随着时间的推移,可以从 Share 事件信息中形成树状结构。如果 Bob 共享给 Alice,而 Alice 进一步共享给 Charlie,并且 Alice 也共享给 David,则从共享活动中形成一个基本的树结构。此共享事件数据稍后可用于获得有关代币所代表的共享活动的更多信息。
B -> A -> C
\
> D
这些树结构可以进一步聚合和折叠成网络表示,例如,基于谁在一段时间内共享给谁的社交图。例如,如果 Bob 将一个代币共享给 Alice,而 Alice 将一个不同的代币共享给 Charlie,并且 Bob 将一个代币共享给 Charlie,则所有这些参与者之间会通过共享活动形成连接。
// SPDX-License-Identifier: CC0-1.0
pragmasolidity^0.8.0;import"./IERC5023.sol";import"@openzeppelin/contracts/token/ERC721/IERC721.sol";import"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";import"@openzeppelin/contracts/utils/Address.sol";import"@openzeppelin/contracts/utils/Context.sol";import"@openzeppelin/contracts/utils/Strings.sol";import"@openzeppelin/contracts/utils/introspection/ERC165.sol";import"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";import"@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";import"@openzeppelin/contracts/access/Ownable.sol";contractShareableERC721isERC721URIStorage,Ownable,IERC5023/* EIP165 */{stringbaseURI;uint256internal_currentIndex;constructor(stringmemory_name,stringmemory_symbol)ERC721(_name,_symbol){}functionmint(addressaccount,uint256tokenId)externalonlyOwner{_mint(account,tokenId);}functionsetTokenURI(uint256tokenId,stringmemorytokenURI)external{_setTokenURI(tokenId,tokenURI);}functionsetBaseURI(stringmemorybaseURI_)external{baseURI=baseURI_;}function_baseURI()internalviewoverridereturns(stringmemory){returnbaseURI;}functionshare(addressto,uint256tokenIdToBeShared)externalreturns(uint256newTokenId){require(to!=address(0),"ERC721: mint to the zero address");require(_exists(tokenIdToBeShared),"ShareableERC721: token to be shared must exist");require(msg.sender==ownerOf(tokenIdToBeShared),"Method caller must be the owner of token");stringmemory_tokenURI=tokenURI(tokenIdToBeShared);_mint(to,_currentIndex);_setTokenURI(_currentIndex,_tokenURI);emitShare(msg.sender,to,_currentIndex,tokenIdToBeShared);return_currentIndex;}functiontransferFrom(addressfrom,addressto,uint256tokenId)publicvirtualoverride{revert('In this reference implementation tokens are not transferrable');}functionsafeTransferFrom(addressfrom,addressto,uint256tokenId)publicvirtualoverride{revert('In this reference implementation tokens are not transferrable');}}