铸造/销毁权限:
在流通门票、优惠券、会员卡和网站访问权限等物品作为 token 的应用程序中,有必要为系统管理员提供铸造或销毁这些 token 的权限。这些权限可以在此方案中实现为 control tokens。
转移权限:
在这些应用程序中的某些情况下,可能希望限制将 token 转移到特定机构的能力。在这些情况下,机构证书作为 control token 颁发。然后,此 control token 的所有权提供了调节 token 转移的方法。
地址验证:
许多应用程序需要地址验证,以防止在铸造或转移目标 token 时收件人地址出现错误。向用户颁发 control token 作为地址验证的证明,收件人在执行铸造或转移交易时需要此 control token,从而防止错误发送。在某些情况下,此用于地址验证的 control token 可能会在身份验证过程后由政府机构或特定公司颁发。
// SPDX-License-Identifier: Apache-2.0
pragmasolidity^0.8.9;import"@openzeppelin/contracts/token/ERC721/ERC721.sol";import"@openzeppelin/contracts/token/ERC1155/ERC1155.sol";abstractcontractERC7303{structERC721Token{addresscontractId;}structERC1155Token{addresscontractId;uint256typeId;}mapping(bytes32=>ERC721Token[])private_ERC721_Contracts;mapping(bytes32=>ERC1155Token[])private_ERC1155_Contracts;modifieronlyHasToken(bytes32role,addressaccount){require(_checkHasToken(role,account),"ERC7303: not has a required token");_;}/**
* @notice Grant a role to user who owns a control token specified by the ERC-721 contractId.
* 允许进行多次调用,在这种情况下,用户必须拥有至少一个指定的 token。
* @param role byte32 您想要授予的角色。
* @param contractId address 用户需要拥有的 token 的 contractId 的地址。
*/function_grantRoleByERC721(bytes32role,addresscontractId)internal{require(IERC165(contractId).supportsInterface(type(IERC721).interfaceId),"ERC7303: provided contract does not support ERC721 interface");_ERC721_Contracts[role].push(ERC721Token(contractId));}/**
* @notice Grant a role to user who owns a control token specified by the ERC-1155 contractId.
* 允许进行多次调用,在这种情况下,用户必须拥有至少一个指定的 token。
* @param role byte32 您想要授予的角色。
* @param contractId address 用户需要拥有的 token 的 contractId 的地址。
* @param typeId uint256 用户需要拥有的 token 类型 ID。
*/function_grantRoleByERC1155(bytes32role,addresscontractId,uint256typeId)internal{require(IERC165(contractId).supportsInterface(type(IERC1155).interfaceId),"ERC7303: provided contract does not support ERC1155 interface");_ERC1155_Contracts[role].push(ERC1155Token(contractId,typeId));}function_checkHasToken(bytes32role,addressaccount)internalviewreturns(bool){ERC721Token[]memoryERC721Tokens=_ERC721_Contracts[role];for(uinti=0;i<ERC721Tokens.length;i++){if(IERC721(ERC721Tokens[i].contractId).balanceOf(account)>0)returntrue;}ERC1155Token[]memoryERC1155Tokens=_ERC1155_Contracts[role];for(uinti=0;i<ERC1155Tokens.length;i++){if(IERC1155(ERC1155Tokens[i].contractId).balanceOf(account,ERC1155Tokens[i].typeId)>0)returntrue;}returnfalse;}}