pragmasolidity^0.8.0;/**
* @title INameRegistry
* @dev Interface for the NameRegistry smart contract.
* This interface allows interaction with a NameRegistry,
* enabling the registration, management, and lookup of names
* with associated expiry dates tied to specific tokens.
* 此接口允许与 NameRegistry 智能合约进行交互,
* 从而可以注册、管理和查找与特定 token 相关的具有关联过期日期的名称。
*/interfaceIERC7644/* is IERC721 */{/**
* @dev Emitted when the name of a token is changed.
* @param tokenId The token ID whose name is changed.
* @param oldName The previous name of the token.
* @param newName The new name assigned to the token.
* @param expiryDate The expiry date of the new name registration.
* 当 token 的名称更改时发出。
* @param tokenId 名称已更改的 token ID。
* @param oldName 该 token 之前的名称。
* @param newName 分配给该 token 的新名称。
* @param expiryDate 新名称注册的到期日期。
*/eventNameChanged(uint256indexedtokenId,bytes32oldName,bytes32newName,uint256expiryDate);/**
* @dev Returns the name of the specified token, if the name has not expired.
* @param tokenId The token ID to query for its name.
* @return The name of the token, or an empty bytes32 if no name is set or it has expired.
* 返回指定 token 的名称(如果该名称尚未过期)。
* @param tokenId 要查询其名称的 token ID。
* @return 该 token 的名称;如果未设置名称或已过期,则返回一个空的 bytes32。
*/functionnameOf(uint256tokenId)externalviewreturns(bytes32);/**
* @dev Returns the token ID associated with a given name, if the name registration has not expired.
* @param _name The name to query for its associated token ID.
* @return The token ID associated with the name, or zero if no token is found or the name has expired.
* 返回与给定名称关联的 token ID(如果该名称注册尚未过期)。
* @param _name 要查询其关联 token ID 的名称。
* @return 与该名称关联的 token ID;如果未找到 token 或名称已过期,则返回零。
*/functiontokenIdOf(bytes32_name)externalviewreturns(uint256);/**
* @dev Allows a token owner to set or update the name of their token, subject to a duration for the name's validity.
* @param tokenId The token ID whose name is to be set or updated.
* @param _name The new name to assign to the token.
* @param duration The duration in seconds for which the name is valid, starting from the time of calling this function.
* Note: The name must be unique and not currently in use by an active (non-expired) registration.
* 允许 token 所有者设置或更新其 token 的名称,但须受名称有效期的限制。
* @param tokenId 要设置或更新其名称的 token ID。
* @param _name 要分配给该 token 的新名称。
* @param duration 名称有效的持续时间(以秒为单位),从调用此函数的时间开始计算。
* 注意:该名称必须是唯一的,并且当前不能被处于有效(未过期)注册状态的用户使用。
*/functionsetName(uint256tokenId,bytes32_name,uint256duration)external;/**
* @dev Returns the tokenId and expiryDate for a given name, if the name registration has not expired.
* @param _name The name to query for its associated token ID and expiry date.
* @return tokenId The token ID associated with the name.
* @return expiryDate The expiry date of the name registration.
* 返回给定名称的 tokenId 和 expiryDate(如果该名称注册尚未过期)。
* @param _name 要查询其关联 token ID 和到期日期的名称。
* @return tokenId 与该名称关联的 token ID。
* @return expiryDate 名称注册的到期日期。
*/functionnameInfo(bytes32_name)externalviewreturns(uint256tokenId,uint256expiryDate);}
pragmasolidity^0.8.0;import"@openzeppelin/contracts/token/ERC721/ERC721.sol";contractERC7644isERC721{eventNameChanged(uint256indexedtokenId,bytes32oldName,bytes32newName,uint256expiryDate);structNameRegistration{uint256tokenId;uint256expiryDate;}mapping(uint256=>bytes32)private_tokenNames;mapping(bytes32=>NameRegistration)private_nameRegistrations;mapping(uint256=>uint256)private_lastSetNameTime;uint256publicconstantMAX_DURATION=10*365days;uint256publicconstantMIN_SET_NAME_INTERVAL=1days;constructor()ERC721("Asd Token","ASDT"){}functionnameOf(uint256tokenId)publicviewreturns(bytes32){if(_tokenNames[tokenId]!=bytes32(0)&&_nameRegistrations[_tokenNames[tokenId]].expiryDate>block.timestamp){return_tokenNames[tokenId];}else{returnbytes32(0);}}functiontokenIdOf(bytes32_name)publicviewreturns(uint256){require(_nameRegistrations[_name].expiryDate>block.timestamp,"NameRegistry: Name expired");if(_nameRegistrations[_name].tokenId>0){return_nameRegistrations[_name].tokenId;}else{returnuint256(0);}}functionsetName(uint256tokenId,bytes32_name,uint256duration)public{require(ownerOf(tokenId)==msg.sender,"NameRegistry: Caller is not the token owner");require(duration<=MAX_DURATION,"NameRegistry: Duration exceeds maximum limit");require(block.timestamp-_lastSetNameTime[tokenId]>=MIN_SET_NAME_INTERVAL,"NameRegistry: Minimum interval not met");require(tokenIdOf(_name)==uint256(0)||tokenIdOf(_name)==tokenId,"NameRegistry: Name already in use and not expired");bytes32oldName=_tokenNames[tokenId];uint256expiryDate=block.timestamp+duration;_setTokenName(tokenId,_name,expiryDate);emitNameChanged(tokenId,oldName,_name,expiryDate);_lastSetNameTime[tokenId]=block.timestamp;}functionnameInfo(bytes32_name)publicviewreturns(uint256,uint256){require(_nameRegistrations[_name].tokenId>0&&_nameRegistrations[_name].expiryDate>block.timestamp,"NameRegistry: Name expired or does not exist");NameRegistrationmemoryregistration=_nameRegistrations[_name];return(registration.tokenId,registration.expiryDate);}function_setTokenName(uint256tokenId,bytes32_name,uint256expiryDate)internal{_tokenNames[tokenId]=_name;_nameRegistrations[_name]=NameRegistration(tokenId,expiryDate);}}