TRC1是合约token的一种约定标准,兼容以太坊ERC20标准,开发者基于TRC1约定标准开发token合约,实现约定里的一类标准方法和状态,包括transfer,approve这些重要功能。
基于TRC1开发的合约token,能够被其他合约应用交互使用实现代币分发和交易。
可选,returns name of the token 如: "MyToekn"
function name() view returns (string name)
可选,returns the symbol of the token 如:"MT"
function symbol() view returns (string symbol)
可选,returns the number of decimals the token uses
function decimals() view returns (uint8 decimals)
token 总数
function totalSupply() view returns (uint256 totalSupply)
获取_owner账户token余额
function balanceOf(address _owner) view returns (uint256 balance)
调用者向_to地址账户转入_value数量的token,要求必须触发Transfer Event。如果调用者账户余额不足,需抛出异常。
function transfer(address _to, uint256 _value) returns (bool success)
transferFrom需配合下面的apprve方法使用,通过approve方法授权调用者使用_from账户的一定数量的余额,调用者可以使用transferFrom方法,从_from账户转出_value数量的token到_to账户。用途如授权合约账户使用_from账户的token来抵扣transfer手续费等操作。 调用需触发Transfer Event,如果_from账户授权使用的token数量不足,需要抛出异常。
function transferFrom(address _from, address _to, uint256 _value) returns (bool success)
授权 _spender账户可以使用调用者 _value部分的token。重复调用将覆盖之前设置的_value。
function approve(address _spender, uint256 _value) returns (bool success)
查询_spender账户允许使用的_owner账户的token数量。
function allowance(address _owner, address _spender) view returns (uint256 remaining)
当发生transfer token时需触发此事件,即使交易数量为0也要同样触发。 如果合约铸造发行更多的token时,需触发此事件,并设置_from账户地址为0x0。
event Transfer(address indexed _from, address indexed _to, uint256 _value)
调用approve方法成功时需触发此事件。
event Approval(address indexed _owner, address indexed _spender, uint256 _value)
以下提供一些已实现的ERC20标准的合约,可以通过继承这些以实现的标准合约发行token。
本文档描述一个不可替换的资产标准接口。
在智能合约中实现标准的不可替换资产,提供资产追踪和转移的基本功能。 我们考虑了个人拥有和转移资产,以及委托给第三方操作的情况。不可替代的唯一性资产可以是对数字内容或收藏品的所有权等,比如:加密猫,原创音乐专辑等。资产应该是可辨识区分的,如每个加密猫都是唯一的,每张原创音乐专辑都是唯一的,必须单独追踪每一个资产的所有权。
我们可以将资产或者资产凭证保存在某个可信的位置生成URI,然后用此URI在合约中注册生成唯一的资产Token,基于此Token,我们可以实现:
事件 | 说明 |
---|---|
Transfer | 资产所有权转移事件 |
Approval | 资产的批准地址修改事件 |
ApprovalForAll | 操作员被启⽤或禁⽤事件 |
函数 | 说明 |
---|---|
name | 合约名称 |
symbol | 合约的缩写名字 |
tokenURI | 查给定资产的URI |
balanceOf | 查询产权人的资产数量 |
ownerOf | 查找资产的所有者 |
safeTransferFrom | 安全的资产所有权转移 |
transferFrom | 资产所有权转移 |
approve | 设置或修改资产的批准地址 |
setApprovalForAll | 允许或禁止第三方操作员管理msg.sender的所有资产 |
getApproved | 获取某个资产的批准地址 |
isApprovedForAll | 查询地址是否为另一个地址的授权操作员 |
interface TRC2 {
// 当资产所有权改变时触发
// 当资产被创建(`from` == 0)和被销毁(`to` == 0)时触发
// 在创建合约时创建和分配的资产不触发
// 资产转移后,资产的批准地址应该重置为空
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
// 当资产的批准地址修改时触发
// 0地址表示没有批准地址
// 当Transfer事件触发时,资产的批准地址也应充值为空
event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
// 当操作员被启用或禁用时触发
// 操作员能管理产权人的所有资产
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
// 查询产权人的资产数量
// 资产分配给0地址是无效的,通过这个函数查询0地址会抛出异常
// @param _owner 要查询余额的地址
// @return `_owner`拥有的资产数量,可能是0
function balanceOf(address _owner) external view returns (uint256);
// 查找资产的所有者
// 将资产分配给0地址是无效的,查询它们会抛出异常
// @param _tokenId 资产标识
// @return 资产的所有者
function ownerOf(uint256 _tokenId) external view returns (address);
// 将资产的所有权从一个地址转移到另一个地址
// 除非`msg.sender`是资产的所有者,或已授权的操作员,或资产的批准地址,否则抛异常
// 如果`_from`不是资产的拥有者,抛异常
// 如果 `_to`是0地址,抛异常
// 如果`_tokenId`不是一个有效的资产,抛异常
// 当转移完成后,函数检查`_to`是否是一个智能合约(code size > 0)
// 如果是,调用`_to`的`onERC721Received`,抛异常如果返回值不是
// `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`
// @param _from 资产当前的所有者
// @param _to 新的所有者
// @param _tokenId 要转移的资产
// @param data 没有指定格式的附加数据,调用`_to`的函数时发送
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
// 将资产的所有权从一个地址转移到另一个地址
// 除了data参数为空,其它和上一个函数一样
// @param _from 资产当前的所有者
// @param _to 新的所有者
// @param _tokenId 要转移的资产
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
// 资产所有权转移
// 调用者需确认 `_to` 能够接收资产,否则它们可能会永久丢失
// 除非`msg.sender`是资产的所有者,或已授权的操作员,或资产的批准地址,否则抛异常
// 如果`_from`不是资产的拥有者,抛异常
// 如果 `_to`是0地址,抛异常
// 如果`_tokenId`不是一个有效的资产,抛异常
// @param _from 资产当前的所有者
// @param _to 新的所有者
// @param _tokenId 要转移的资产
function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
// 设置或修改资产的批准地址
// 零地址表示没有批准地址
// 除非`msg.sender`是资产的所有者,或所有者已授权的操作员,否则抛异常
// @param _approved 资产新的批准地址
// @param _tokenId 资产标识
function approve(address _approved, uint256 _tokenId) external payable;
// 允许或禁止第三方操作员进行管理`msg.sender`的所有资产
// 发送ApprovalForAll事件,合约必须允许给每个所有者设置多个操作员
// @param _operator 添加到授权操作员集合的地址
// @param _approved 允许时填true,禁用时填false
function setApprovalForAll(address _operator, bool _approved) external;
// 获取某个资产的批准地址
// `_tokenId`无效时抛出异常
// @param _tokenId 资产标识
// @return 资产的批准地址,没有设置时返回0地址
function getApproved(uint256 _tokenId) external view returns (address);
// 查询地址是否为另一个地址的授权操作员
// @param _owner 资产所有者地址
// @param _operator 操作员地址
// @return `_operator`是`_owner`的操作员时返回true,否则返回false
function isApprovedForAll(address _owner, address _operator) external view returns (bool);
// 合约名称
function name() external view returns (string _name);
/// 合约的名字缩写
function symbol() external view returns (string _symbol);
// 查给定资产的URI
// `_tokenId`无效时抛异常
function tokenURI(uint256 _tokenId) external view returns (string);
}
每个资产都由合约中的唯一的uint256类型的ID标识,此标识在合约的生命周期内不能修改,键值对(contract address, uint256 tokenId)在区块链中全局唯一而且能完全标识出特定资产。实现时合约可以简单的将ID从0开始累加,但不应假设ID值有任何特定的模式,必须将ID视为一个黑盒。还要注意资产可能会因为被销毁而变的无效。
提供了安全的转移函数safeTransferFrom
和不安全的函数transferFrom
。转移可以通过以下对象发起:
此外,授权的操作员也可以设置资产的批准地址,这为钱包、经纪人和拍卖应用提供了一套强大的工具,可以快速的使用大量的资产。
本文档描述一个可授权的不可替换的资产标准接口。
在智能合约中实现标准的不可替换资产,提供资产追踪和转移的基本功能。 我们考虑了个人拥有和转移资产,以及委托给第三方操作的情况。不可替代的唯一性资产可以是对数字内容或收藏品的所有权等,比如:加密猫,原创音乐专辑等。资产应该是可辨识区分的,如每个加密猫都是唯一的,每张原创音乐专辑都是唯一的,必须单独追踪每一个资产的所有权。
我们可以将资产或者资产凭证保存在某个可信的位置生成URI,然后用此URI在合约中注册生成唯一的资产Token,基于此Token,我们可以实现:
事件 | 说明 |
---|---|
Transfer | 资产所有权转移事件 |
Approval | 资产的批准地址修改事件 |
ApprovalForAll | 操作员被启⽤或禁⽤事件 |
Accessible | 访问权限修改事件 |
函数 | 说明 |
---|---|
name | 合约名称 |
symbol | 合约的缩写名字 |
tokenURI | 查给定资产的URI |
balanceOf | 查询产权人的资产数量 |
ownerOf | 查找资产的所有者 |
safeTransferFrom | 安全的资产所有权转移 |
transferFrom | 资产所有权转移 |
approve | 设置或修改资产的批准地址 |
setApprovalForAll | 允许或禁止第三方操作员管理msg.sender的所有资产 |
getApproved | 获取某个资产的批准地址 |
isApprovedForAll | 查询地址是否为另一个地址的授权操作员 |
setAccessible | 设置/修改/取消访问权限 |
accessible | 查询访问权限 |
interface TRC2_1 {
// 当资产所有权改变时触发
// 当资产被创建(`from` == 0)和被销毁(`to` == 0)时触发
// 在创建合约时创建和分配的资产不触发
// 资产转移后,资产的批准地址应该重置为空
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
// 当资产的批准地址修改时触发
// 0地址表示没有批准地址
// 当Transfer事件触发时,资产的批准地址也应充值为空
event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
// 当操作员被启用或禁用时触发
// 操作员能管理产权人的所有资产
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
// 设置/修改/取消访问权限时触发
event Accessible(uint256 _tokenId, address _to, uint256 _data);
// 查询产权人的资产数量
// 资产分配给0地址是无效的,通过这个函数查询0地址会抛出异常
// @param _owner 要查询余额的地址
// @return `_owner`拥有的资产数量,可能是0
function balanceOf(address _owner) external view returns (uint256);
// 查找资产的所有者
// 将资产分配给0地址是无效的,查询它们会抛出异常
// @param _tokenId 资产标识
// @return 资产的所有者
function ownerOf(uint256 _tokenId) external view returns (address);
// 将资产的所有权从一个地址转移到另一个地址
// 除非`msg.sender`是资产的所有者,或已授权的操作员,或资产的批准地址,否则抛异常
// 如果`_from`不是资产的拥有者,抛异常
// 如果 `_to`是0地址,抛异常
// 如果`_tokenId`不是一个有效的资产,抛异常
// 当转移完成后,函数检查`_to`是否是一个智能合约(code size > 0)
// 如果是,调用`_to`的`onERC721Received`,抛异常如果返回值不是
// `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`
// @param _from 资产当前的所有者
// @param _to 新的所有者
// @param _tokenId 要转移的资产
// @param data 没有指定格式的附加数据,调用`_to`的函数时发送
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
// 将资产的所有权从一个地址转移到另一个地址
// 除了data参数为空,其它和上一个函数一样
// @param _from 资产当前的所有者
// @param _to 新的所有者
// @param _tokenId 要转移的资产
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
// 资产所有权转移
// 调用者需确认 `_to` 能够接收资产,否则它们可能会永久丢失
// 除非`msg.sender`是资产的所有者,或已授权的操作员,或资产的批准地址,否则抛异常
// 如果`_from`不是资产的拥有者,抛异常
// 如果 `_to`是0地址,抛异常
// 如果`_tokenId`不是一个有效的资产,抛异常
// @param _from 资产当前的所有者
// @param _to 新的所有者
// @param _tokenId 要转移的资产
function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
// 设置或修改资产的批准地址
// 零地址表示没有批准地址
// 除非`msg.sender`是资产的所有者,或所有者已授权的操作员,否则抛异常
// @param _approved 资产新的批准地址
// @param _tokenId 资产标识
function approve(address _approved, uint256 _tokenId) external payable;
// 允许或禁止第三方操作员进行管理`msg.sender`的所有资产
// 发送ApprovalForAll事件,合约必须允许给每个所有者设置多个操作员
// @param _operator 添加到授权操作员集合的地址
// @param _approved 允许时填true,禁用时填false
function setApprovalForAll(address _operator, bool _approved) external;
// 获取某个资产的批准地址
// `_tokenId`无效时抛出异常
// @param _tokenId 资产标识
// @return 资产的批准地址,没有设置时返回0地址
function getApproved(uint256 _tokenId) external view returns (address);
// 查询地址是否为另一个地址的授权操作员
// @param _owner 资产所有者地址
// @param _operator 操作员地址
// @return `_operator`是`_owner`的操作员时返回true,否则返回false
function isApprovedForAll(address _owner, address _operator) external view returns (bool);
// 设置/修改/取消访问权限
// 除非`msg.sender`是资产的所有者,或已授权的操作员,或资产的批准地址,否则抛异常
// @param _tokenId 要操作的资产
// @param _to 用户地址
// @param _data 自定义数据
function setAccessible(uint256 _tokenId, address _to, uint256 _data) external;
// 查询访问权限
// @param _tokenId 要查询的资产
// @param _to 用户地址
// @return 返回自定义的`_data`值,无记录时返回0
function accessible(uint256 _tokenId, address _to) external view returns (uint256);
// 合约名称
function name() external view returns (string _name);
/// 合约的名字缩写
function symbol() external view returns (string _symbol);
// 查给定资产的URI
// `_tokenId`无效时抛异常
function tokenURI(uint256 _tokenId) external view returns (string);
}
每个资产都由合约中的唯一的uint256类型的ID标识,此标识在合约的生命周期内不能修改,键值对(contract address, uint256 tokenId)在区块链中全局唯一而且能完全标识出特定资产。实现时合约可以简单的将ID从0开始累加,但不应假设ID值有任何特定的模式,必须将ID视为一个黑盒。还要注意资产可能会因为被销毁而变的无效。
提供了安全的转移函数safeTransferFrom
和不安全的函数transferFrom
。转移可以通过以下对象发起:
此外,授权的操作员也可以设置资产的批准地址,这为钱包、经纪人和拍卖应用提供了一套强大的工具,可以快速的使用大量的资产。
可通过函数setAccessible
授权其他用户访问某资产,最后一个参数data用来存储额外的自定义数据,比如可以存储授权过期的时间戳。data参数设置为0时,执行取消授权操作。
被授权的用户,应允许对资产执行只读访问,不能修改、转移资产,或再次授权给第三方。