1、FT(Fungible Token)
FT即同质化代币,同质化的加密货币构成了目前市场上大部分的代币。
FT以这样的方式配置的数字资产——即每个代币(或代币的碎片)与下一个代币等同。
可替代性是法定货币中的一个特征。例如,一张20美元的钞票可以兑换成任何其他20美元的钞票,甚至可以兑换成零头。即使不是绝对的20美元钞票,它也可以是5美元钞票的倍数,甚至更少,总之总量等于20美元。
2、NFT(Non-Fungible Token)
NFT即非同质化代币,非同质化代币通常是指开发者在以太坊平台上根据 ERC-721 标准/协议所发行的代币。用来描述一种独特的数字资产,它的所有权是在区块链上可以进行溯源的。
NFT 是唯一的、不可拆分的 token,所有的艺术品,不管是图书文字、音乐或是影像…等各种形式,甚至是数字化的收藏品与线上游戏都可以通过 NFT 的特殊认证方式来验证其独特与稀有价值。
因此NFT 与传统经济体系中的收藏品相比具有不同的特征:
- 所有权:中心化机构(比如游戏运营方)可以随意掌控甚至夺走虚拟资产,而 NFT是玩家钱包中真正拥有的资产。
- 永久性:一旦 NFT 被铸造,就可以永远存在于区块链上。
- 稀缺性可证明:由于所有记录都可公开访问,因此可以随时确认 NFT 现存的数量。
- 出处可证明:可以确切知道谁曾持有过该 NFT,一直追溯到 NFT 的创作者。
- 可编程性:使用智能合约技术,NFT 可以在玩家之间甚至与其他游戏或应用之间进行交易。
- 去中心化:经济以完全信任的方式保持其完整性,一旦启动,即便离开游戏项目方仍然可以由社区自发推动运行。
3、FT和NFT的区别
同质化代币(Fungible Token, FT) | 非同质化代币(Non-Fungible Token) |
---|---|
可互换性 FT 可与同种 FT 进行互换。举例来说,美元可与其他美元进行互换,且不影响价值。 | 不可互换性 NFT 不可与同种 NFT 进行互换。如将 NFT 借出,返还为同一 NFT,而不是其他 NFT。举例来说,自己的出生证明不可与别人进行互换 |
统一性 所有同种 FT 规格相同,代币之间相同。 | 独特性 每个 NFT 独一无二,与同种 NFT 各不相同。 |
可分性 FT 可划分为更小单元,价值同等即可。举例来说,1 美元可换成 2 个 50 美分或 4 个 25 美分。 | 不可分性 NFT 不可分割。基本单元为一个代币,也只存在一个代币。 |
方便性 易于拆分和交换 | 防盗性 每个代币具有独特性,应用场景多种多样,如游戏、知识产权、实体资产、身份证明、金融文书、票务等 |
ERC-20 以太坊区块链著名协议,支持发布了 OMG、SNC、TRX 等代币。 | ERC-721 以太坊区块链新协议,支持发布独特的非同质化代币,最佳用例包括加密猫(CryptoKitties)等加密收藏项目。 |
4、ERC-20标准
官方说明文档地址:https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
ERC-20标准以太坊上的一个代币协议,所有基于以太坊开发的代币合约都遵守这个协议。
4.1 协议中包含的方法
//1.name
//返回string类型的ERC20代币的名字,例如:StatusNetwork
function name() constant returns (string name)
//2.symbol
//返回string类型的ERC20代币的符号,也就是代币的简称,例如:SNT
function name() constant returns (string name)
//3.decimals
//支持几位小数点后几位。如果设置为3。也就是支持0.001表示。
function symbol() constant returns (string symbol)
//4.totalSupply
//发行代币的总量,可以通过这个函数来获取。所有智能合约发行的代币总量是一定的,totalSupply必须设置初始值。如果不设置初始值,这个代币发行就说明有问题。
function totalSupply() constant returns (uint256 totalSupply)
//5.balanceOf
//输入地址,可以获取该地址代币的余额。
function balanceOf(address _owner) constant returns (uint256 balance)
//6.transfer
//调用transfer函数将自己的token转账给_to地址,_value为转账个数
function transfer(address _to, uint256 _value) returns (bool success)
//7.approve
//批准_spender账户从自己的账户转移_value个token。可以分多次转移。
function approve(address _spender, uint256 _value) returns (bool success)
//8.transferFrom
//与approve搭配使用,approve批准之后,调用transferFrom函数来转移token。
function transferFrom(address _from, address _to, uint256 _value) returns (bool success)
//9.allowance
//返回_spender仍然允许从_owner提取的金额。
function allowance(address _owner, address _spender) constant returns (uint256 remaining)
4.2 协议中包含的事件
//1.Transfer
//在发生代币转移时必须触发,包括生成新代币
event Transfer(address indexed _from, address indexed _to, uint256 _value)
//2.Approval
//成功调用approve(address _spender, uint256 _value)方法时触发
event Approval(address indexed _owner, address indexed _spender, uint256 _value)
4.3 例子
账户A有1000个ETH,想允许B账户随意调用100个ETH。
- A账户按照以下形式调用approve函数approve(B,100)
- 当B账户想用这100个ETH中的10个ETH给C账户时,则调用transferFrom(A, C, 10)
- 这时调用allowance(A, B),可以查看B账户还能够调用A账户多少个token。
5、ERC-721
官方说明文档:https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
ERC-721兼容了ERC-20的一些特性,与ERC-20的主要区别是定义了token的owner, 即每个token都详细记录它历史的拥有者,以及定义了token的Metadata, 即元数据。ERC-721还需要实现ERC165中的接口。
5.1 ERC165接口
interface ERC165 {
//ERC165标准要求合约提供其实现了哪些接口,如若对应接口实现则返回true
function supportsInterface(bytes4 interfaceID) external view returns (bool);
}
5.2 ERC-721接口
interface ERC721 /* is ERC165 */ {
//NFT 资产的转移,包括生成新代币
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
//特定 NFT 资产第三方操作的授权
event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
//特定地址下所有 NFT 资产第三方操作的授权
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
//与ERC20兼容的接口
//代币名字
function name() constant returns (string name);
//代币符号
function symbol() constant returns (string symbol);
//发行的总代币数
function totalSupply() constant returns (uint256 totalSupply);
//_owner拥有的代币数
function balanceOf(address _owner) constant returns (uint balance);
//返回Token拥有者的地址,由于每个ERC721令牌都是不可替代的,因此它们是唯一的,它通过唯一ID在区块链中引用,我们可以使用其ID来确定Token的所有者。
function ownerOf(uint256 _tokenId) external view returns (address);
// _from将_tokenId转移给_to,转移前会先检查是否具备转移该 NFT 的资格
//调用者自己确认_to地址能正常接收NFT,否则将永久丢失此NFT
function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
// _from将_tokenId转移给_to
//要求_tokenId属于_from
//要求_tokenId合法,即是当前合约正在监测的NFTs 中的任何一个
//要求_to的地址不为0,如果_to是智能合约(地址的size大于0),调用onERC721Received方法
//安全是指如果交易失败会进行回滚
//实际data为空字符串
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
//data是没有指定格式的附加数据
//其他与不带数据的safeTransferFrom方法相同
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
//我是小气鬼,只授权你花一个
//允许_approved对_tokenId的所有权进行操作
function approve(address _approved, uint256 _tokenId) external payable;
//TA 真的授权给我花 TA 其中的一个 NFT 了吗?
//返回_tokenId的授权地址
function getApproved(uint256 _tokenId) external view returns (address);
//我的就是你的,全让你花
//授予或撤销_operator所具有的所有NFTs的控制权,成功后触发ApprovalForAll事件
function setApprovalForAll(address _operator, bool _approved) external;
//TA 真的为我倾尽所有了吗?
//查询_owner所持有的全部NFTs对_operator的操作授权状态,true为全授权操作
function isApprovedForAll(address _owner, address _operator) external view returns (bool);
}
5.3 可选实现接口:ERC721Metadata
Metadata用于定义单个代币的唯一特征,为一个特定的代币ID提供描述性信息 。以加密猫为例,每只加密猫都有不同的颜色、形状、名称等。
interface ERC721Metadata /* is ERC721 */ {
//代币名字
function name() external pure returns (string _name);
//代币符号
function symbol() external pure returns (string _symbol);
//返回_tokenId所对应的外部资源文件的URI,外部资源文件(json)需要包含名字、描述、图片
function tokenURI(uint256 _tokenId) external view returns (string);
}
5.3.1 外部资源文件的模板
{
"title": "Asset Metadata",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Identifies the asset to which this NFT represents"
},
"description": {
"type": "string",
"description": "Describes the asset to which this NFT represents"
},
"image": {
"type": "string",
"description": "A URI pointing to a resource with mime type image/* representing the asset to which this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive."
}
}
}
5.3.2 Metadata的存储位置
- 链上:
- 元数据与代币一起永久存在,在任何应用的生命周期结束后仍会存在
- 元数据可以根据链上逻辑进行更改
- 链的存储空间有限
- 链下:通过tokenURI方法告诉应用程序在何处查找给定项的元数据
5.3.3 ERC-721规范的NFT一般具有以下属性
• tokenId:在合约内唯一的 NFT ID,在NFT的生命周期中不可改变(要实现全链唯一的必须用(contractAddr, tokenId)组成的元组)
• name:名称,类似于ERC-20的名称
• symbol:符号,类似于ERC-20的符号
• uri:指向外部信息的链接,一般是一个JSON,而在JSON中有进一步更加具体的信息
5.4 可选实现接口:ERC721Enumerable
interface ERC721Enumerable /* is ERC721 */ {
//合约当前管理的NTFs数量
function totalSupply() external view returns (uint256);
//查询索引为_index的资产对应的tokenId
function tokenByIndex(uint256 _index) external view returns (uint256);
//查询_owner拥有的NFT列表中对应索引的tokenId
function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);
}
如有不对,烦请指出,感谢~