协议说明

简单摘要

用于管理多种代币类型的合约的标准接口。单个部署的合同可以包括可替换代币、不可替换代币或其他配置(如半可替换代币)的任何组合。

意义

像VRC-20和VRC-721这样的代币标准要求为每个代币类型或集合部署一个单独的合约。这在Vision链上部署了大量冗余的字节码,并通过将每个代币合约分离到自己的许可地址的性质来限制某些功能。随着区块链游戏和Enjin Coin等平台的兴起,游戏开发者可能会创造成千上万的代币类型,需要一种新的代币标准来支持它们。并且,VRC-1155并不是专门针对游戏的,许多其他应用可以从这种灵活性中受益。

通过这种设计可以实现新的功能,如一次转移多种代币类型,节省交易成本。多个代币的交易(托管/原子交换)可以建立在这个标准之上,它消除了单独 "批准 "个别代币合约的需要。也很容易在一个合同中描述和混合多个可替代或不可替代的代币类型。

摘要

实现VRC-1155标准的智能合约必须实现VRC1155接口中的所有功能。

实现VRC-1155标准的智能合约必须实现VRC-165 supportsInterface函数,如果通过interfaceID参数传递0xd9b67a26,则必须返回常量值true。

必须实现

接口

实现VRC-1155标准的智能合约必须实现VRC1155接口中的所有功能。

实现VRC-1155标准的智能合约必须实现VRC-165 supportsInterface函数,如果通过interfaceID参数传递0xd9b67a26,则必须返回常量值true。

pragma solidity ^0.5.9;

interface VRC1155 /* is VRC165 */ {

    event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value);
    event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values);
    event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
    event URI(string _value, uint256 indexed _id);

    function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external;

    function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data) external;

    function balanceOf(address _owner, uint256 _id) external view returns (uint256);

    function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory);

    function setApprovalForAll(address _operator, bool _approved) external;

    function isApprovedForAll(address _owner, address _operator) external view returns (bool);
}

VRC-1155 Token Receiver

智能合约必须实现VRC1155TokenReceiver接口中的所有功能以接受转账。更多细节请参见 "安全转移规则"。

智能合约必须实现VRC-165 supportsInterface函数,并标志着支持VRC1155TokenReceiver接口以接受转账。请参阅 "VRC1155TokenReceiver VRC-165规则 "以了解更多细节。

pragma solidity ^0.5.9;

interface VRC1155TokenReceiver {
 
    function onVRC1155Received(address _operator, address _from, uint256 _id, uint256 _value, bytes calldata _data) external returns(bytes4);
    function onVRC1155BatchReceived(address _operator, address _from, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data) external returns(bytes4);       
}

token转移前请确认合约必须实现一下接口,否则不能接收1155资产

function supportsInterface(bytes4 interfaceID) external view returns (bool) {
    return  interfaceID == 0x01ffc9a7 ||    // VRC-165 support (i.e. `bytes4(keccak256('supportsInterface(bytes4)'))`).
            interfaceID == 0xd37fbeb15;      // VRC-1155 `VRC1155TokenReceiver` support (i.e. `bytes4(keccak256("onVRC1155Received(address,address,uint256,uint256,bytes)")) ^ bytes4(keccak256("onVRC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`).
}

安全转移规则

safeTransferFrom规则。

  • 呼叫者必须被批准管理从_from账户中转出的代币(见 "批准 "部分)。
  • 如果_to是零地址,则必须恢复。
  • 如果代币持有人id的余额低于发送给收件人的值,必须恢复。
  • 如果出现任何其他错误,必须回复。
  • 必须发出TransferSingle事件以反映余额的变化(见 "TransferSingle和TransferBatch事件规则 "部分)。
    在满足上述条件后,这个函数必须检查_to是否是一个智能合约(例如代码大小>0)。如果是,它必须在_to上调用onVRC1155Received并采取适当的行动(见 "onVRC1155Received规则 "部分)。
    *由发送方提供的用于传输的_data参数必须通过其_data参数将其内容不加改动地传递给onVRC1155Received钩子函数。

Metadata 元数据

URI值允许客户进行ID替换。如果字符串{id}存在于任何URI中,客户必须用十六进制的实际令牌ID来替换它。这允许大量的代币使用相同的链上字符串,只需定义一次URI,就可以让大量的代币使用。

  • 替换的十六进制ID的字符串格式必须是lowVRCase字母数字。[0-9a-f],没有0x前缀。
  • 替换后的十六进制ID的字符串格式必须是前导零,必要时填充到64个十六进制字符长度。
    URI 示例: https://token-cdn-domain/{id}.json 如何客户端可以识别 314592/0x4CCE0,应当将URI 展示为 https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json

Metadata Extensions 元数据扩展

pragma solidity ^0.5.9;
interface VRC1155Metadata_URI {
    function uri(uint256 _id) external view returns (string memory);
}

VRC-1155元数据URI JSON模式

该JSON模式松散地基于 "VRC721元数据JSON模式",但包括可选的格式化,允许客户端替换ID。如果字符串{id}存在于任何JSON值中,它必须被所有遵循此标准的客户端软件替换为实际的令牌ID。

{
    "title": "Token Metadata",
    "type": "object",
    "properties": {
        "name": {
            "type": "string",
            "description": "Identifies the asset to which this token represents",
        },
        "decimals": {
            "type": "integer",
            "description": "The number of decimal places that the token amount should display - e.g. 18, means to divide the token amount by 1000000000000000000 to get its user representation.",
        },
        "description": {
            "type": "string",
            "description": "Describes the asset to which this token represents",
        },
        "image": {
            "type": "string",
            "description": "A URI pointing to a resource with mime type image/* representing the asset to which this token represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive.",
        },
        "properties": {
            "type": "object",
            "description": "Arbitrary properties. Values may be strings, numbers, object or arrays.",
        },
    }
}