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);
}

 
如有不对,烦请指出,感谢~