ERC20藏品合約標準解析及程式碼實現
我們可以用以太坊智慧合約來模擬稀有的收藏品,每一個通證都遵循以太坊ERC-721標準,
它是DieterShirley在2017年末提出的以太坊改進建議書。ERC721可以使智慧合約像類似於
ERC20代幣一樣進行交易,
區別在於,ERC721通證是獨一無二的,每一個都有唯一的ID,具有不可取代性。
ERC721約定了一些介面函式,使它在一定程度上符合ERC20代幣標準。這麼做是為了讓現有的
錢包更容易顯示代幣的基本資訊。這些函式可以讓符合ERC721標準的智慧合約像比特幣或者
以太幣這樣普通的數字加密幣一樣,通過智慧合約程式設計的方式定義一些功能讓使用者實現向他人
傳送代幣或檢查賬戶餘額等操作。
這是一個簡明的ERC721智慧合約宣告:
contract ERC721 {
//與ERC20相容的介面
function name() constant returns (string name);
function symbol() constant returns (string symbol);
function totalSupply() constant returns (uint256 totalSupply);
function balanceOf(address _owner) constant returns (uint balance);
//所有權相關的介面
function ownerOf(uint256 _tokenId) constant returns (address owner);
function approve(address _to, uint256 _tokenId);
function takeOwnership(uint256 _tokenId);
function transfer(address _to, uint256 _tokenId);
function tokenOfOwnerByIndex(address _owner, uint256 _index) constant returns (uint tokenId);
//通證元資料介面
function tokenMetadata(uint256 _tokenId) constant returns (string infoUrl);
//事件
event Transfer(address indexed _from, address indexed _to, uint256 _tokenId);
event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId);
}
name - 名稱
該函式應當返回通證的名稱。 例如:
contract MyNFT {
function name() constant returns(string name){
return "My Non-FungibleToken";
}
}
Symbol - 符號
該函式應當返回通證的符號,它有助於提高與ERC20的相容性。例如:
contract MyNFT {
function symbol() constant returns(string symbol){
return "MNFT";
}
}
totalSupply - 總髮行量
該函式應當返回區塊鏈上供應的通證總數量,該數量不一定是固定不變的。
例如:
contract MyNFT {
//想發行多少取決於你 ;)
uint256 private totalSupply = 1000000000;
function totalSupply() constant returns (uint256supply){
return totalSupply;
}
}
balanceOf - 餘額
該函式用於查詢某一地址裡的通證餘額。例如:
contract MyNFT {
mapping(address => uint) privatebalances;
function balanceOf(address _owner) constant returns(uint balance){
return balances[_owner];
}
}
下面這些函式定義了合約如何處理通證的所有權及如何轉移所有權。其中最重要的兩個函式
是獲取(takeOwnership)和轉賬(transfer),用來實現使用者之間的通證流轉,就像銀行的提款
和匯款功能。
ownerOf - 持幣人
該函式返回通證持有人的地址。因為每一個ERC721通證都是不可替代的,因此可以在區塊鏈上
唯一的地址找到,我們可以用通證的ID來確定其持有人。
contract MyNFT {
mapping(uint256 => address) privatetokenOwners;
mapping(uint256 => bool) private tokenExists;
function ownerOf(uint256 _tokenId) constant returns (address owner) {
require(tokenExists[_tokenId]);
return tokenOwners[_tokenId];
}
}
approve - 授權
該函式用來授權給另一主體代表持有人進行通證轉移操作。例如,假設Alice有一個ERC721通證,她可以
呼叫approve
函式來授權給她的朋友Bob,然後Bob就可以代表Alice行使通證持有人的權利。
contract MyNFT {
mapping(address => mapping (address=> uint256)) allowed;
function approve(address _to, uint256 _tokenId){
require(msg.sender ==ownerOf(_tokenId));
require(msg.sender != _to);
allowed[msg.sender][_to] = _tokenId;
Approval(msg.sender, _to, _tokenId);
}
}
takeOwnership - 獲取
該函式類似於取款功能,一個外部主體通過呼叫takeOwnership
函式來從另一個使用者的賬戶
中提取ERC721通證。
因此,在一個使用者被(其他人)授權擁有一定數量的通證的情況下,可以通過該功能將這部分
通證從另一個使用者的賬戶中提取出來。
contract MyNFT {
function takeOwnership(uint256_tokenId){
require(tokenExists[_tokenId]);
address oldOwner = ownerOf(_tokenId);
address newOwner = msg.sender;
require(newOwner != oldOwner);
require(allowed[oldOwner][newOwner] == _tokenId);
balances[oldOwner] -= 1;
tokenOwners[_tokenId] = newOwner;
balances[oldOwner] += 1;
Transfer(oldOwner, newOwner,_tokenId);
}
}
transfer - 轉賬
另一種轉移通證的方法時使用transfer
函式。轉賬(transfer)功能可以讓使用者將通證發給另一個使用者,
類似於操作比特幣這樣的加密數字貨幣。然而,只有在匯出賬戶之前授權過匯入賬戶持有其通證的
情況下,才可以進行轉賬。
contract MyNFT {
mapping(address => mapping(uint256 => uint256)) private ownerTokens;
function removeFromTokenList(address owner, uint256 _tokenId) private {
for(uint256 i = 0;ownerTokens[owner][i] != _tokenId;i++){
ownerTokens[owner][i] = 0;
}
}
function transfer(address _to, uint256 _tokenId){
address currentOwner = msg.sender;
address newOwner = _to;
require(tokenExists[_tokenId]);
require(currentOwner == ownerOf(_tokenId));
require(currentOwner != newOwner);
require(newOwner != address(0));
removeFromTokenList(_tokenId);
balances[oldOwner] -= 1;
tokenOwners[_tokenId] = newOwner;
balances[newOwner] += 1;
Transfer(oldOwner, newOwner, _tokenId);
}
}
tokenOfOwnerByIndex - 通證檢索
這個函式是可選的,但推薦你實現它。
每一個ERC721通證的持有者可以同時持有不止一個通證,因為每個通證都有唯一的ID,但是,要跟蹤某個使用者持有的
通證可能就會比較困難。為此,合約需要記錄每個使用者持有的每個通證。通過這種方式,使用者可以
通過索引清單檢索其擁有的通證。通證檢索(tokenOfOwnerByIndex)函式可以通過這種方式追溯某一特定的通證。
contract MyNFT {
mapping(address => mapping(uint256 => uint256)) private ownerTokens;
function tokenOfOwnerByIndex(address _owner, uint256 _index) constant returns (uint tokenId){
return ownerTokens[_owner][_index];
}
}
tokenMetaData - 通證元資料
就像我們之前所說的,使物品具有不可替代性的是它們獨一無二的特質。美元和網球卡不可替代,
因為它們的特徵不同。但是,在區塊鏈上將這些區分每個通證的特徵儲存下來成本很高,也不推薦這麼做。
為了解決這個問題,我們可以儲存每個通證的引用(references),例如IPFS雜湊或HTTP(S)連結,這些
引用,被稱作元資料。元資料是可選的。
tokenMetaData函式應當返回通證的元資料,或者通證資料的連結。
contract MyNFT {
mapping(uint256 => string) tokenLinks;
function tokenMetadata(uint256 _tokenId) constant returns (string infoUrl) {
return tokenLinks[_tokenId];
}
}
當呼叫合約方法的時候,事件將會被觸發,並且一旦被觸發就會向監聽系統傳播。外部應用可以監聽區塊鏈
中的事件,一旦接收到區塊鏈中的事件被觸發,監聽系統就可以通過事件中包含的資訊執行邏輯程式。
ERC721標準定義了下面兩個事件。
Transfer - 轉賬
當一個通證的所有權從一個使用者轉移到另一個時,將觸發該事件,事件的資訊包括匯出賬戶、匯入賬戶和通證ID。
contract MyNFT {
event Transfer(address indexed _from,address indexed _to, uint256 _tokenId);
}
Approval - 批准
當一個使用者允許另一個使用者持有其通證的時候(例如啟用“授權”功能的時候),該事件就會被觸發,事件的資訊中
包含這些通證現在的持有賬戶、被授權賬戶以及通證ID。
contract MyNFT {
event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId);
}
完整的原始碼在這裡。
相關推薦
ERC20藏品合約標準解析及程式碼實現
我們可以用以太坊智慧合約來模擬稀有的收藏品,每一個通證都遵循以太坊ERC-721標準, 它是DieterShirley在2017年末提出的以太坊改進建議書。ERC721可以使智慧合約像類似於 ERC20代幣一樣進行交易, 區別在於,ERC721通證是獨一無
ERC20代幣合約標準解析及程式碼實現
目前幾乎所有用於艾希歐籌集資金的代幣,都是基於同樣的技術:以太坊ERC-20標準。 因此這些代幣實際上就是實現了ERC20標準的智慧合約。在下文中,我們將全面剖析ERC20 標準規範,並給出一個ERC20代幣合約的完整實現程式碼。此外,在下文中我們將不加區分
K近鄰演算法(KNN)原理解析及python實現程式碼
KNN演算法是一個有監督的演算法,也就是樣本是有標籤的。KNN可以用於分類,也可以用於迴歸。這裡主要講knn在分類上的原理。KNN的原理很簡單: 放入一個待分類的樣本,使用者指定k的大小,然後計算所有訓練樣本與該樣
蜂鳴器實現音樂播放及應用解析、程式碼實現
兩者區別 首先,需要說明的是,這裡的“源”不是指電源。而是指震盪源。 無源蜂鳴器的特點是: 1、 無源內部不帶震盪源,所以如果用直流訊號無法令其鳴叫。必須用2K~5K的方波(建議使用PWM)去驅動它 &nbs
大牛的23種設計模式及程式碼實現全解析
一、設計模式的分類 總體來說設計模式分為三大類: 建立型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。 結構型模式,共七種:介面卡模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。 行為型模式,共十一種:策略模式、模板
nginx學習三 nginx配置項解析詳解及程式碼實現
nginx配置項解析詳解及程式碼實現 0回顧 在上一節,用nginx簡單實現了一個hello world程式:當我們在瀏覽器中輸入lochost/hello ,瀏覽器就返回:hello world。為什麼會這樣呢,簡單一點說就是當我們請求訪問hello這個服務,ngi
Spring 容器IOC解析及簡單實現
interface utf-8 cat container 就是 pat 註入 () class 最近一段時間,“容器”兩個字一直縈繞在我的耳邊,甚至是吃飯、睡覺的時候都在我腦子裏蹦來蹦去的。隨著這些天一次次的交流、討論,對於容器的理解也逐漸加深。理論上的東西終歸要落實到實
FM算法解析及Python實現
line 類型檢查 lse pytho spl ont 核心 ict 作者 1. 什麽是FM? FM即Factor Machine,因子分解機。 2. 為什麽需要FM? 1、特征組合是許多機器學習建模過程中遇到的問題,如果對特征直接建模,很有可能會忽略掉特征與特征之間的關聯
菜鳥學SSH——Spring容器IOC解析及簡單實現
最近一段時間,“容器”兩個字一直縈繞在我的耳邊,甚至是吃飯、睡覺的時候都在我腦子裡蹦來蹦去的。隨著這些天一次次的交流、討論,對於容器的理解也逐漸加深。理論上的東西終歸要落實到實踐,今天就藉助Spring容器實現原理,簡單說說吧。 簡單的說,Spring就是通過工廠+反射將我們的bean放到它
深入理解spring的事務管理機制及程式碼實現
Spring的事務管理機制 Spring事務管理高層抽象主要包括3個介面,Spring的事務主要是由他們共同完成的: PlatformTransactionManager:事務管理器—主要用於平臺相關事務的管理 TransactionDefinition: 事務定義資訊(隔
FFM演算法解析及Python實現
1. 什麼是FFM? 通過引入field的概念,FFM把相同性質的特徵歸於同一個field,相當於把FM中已經細分的feature再次進行拆分從而進行特徵組合的二分類模型。 2. 為什麼需要FFM? 在傳統的線性模型中,每個特徵都是獨立的,如果需要考慮特徵與特徵之間的相互作用,可能需要人工對特徵進行交叉
OpenCV(一)——高斯卷積核原理及程式碼實現
貼出getGaussianKernel原始碼 在smooth.cpp中 提示:Gaussian核基於 正態分佈函式設計 μ是均值,σ^2是方差 正態函式(即一維Gaussian卷積核)如下 二維卷積核通過對一維積分得到,並且μ = 0 根據如下原始碼可知
微信公眾號掃碼登陸原理及程式碼實現
1.使用者開啟公眾號點選掃碼功能(注意我們用 scancode_waitmsg這種型別即可) 2.使用者掃描了二維碼會給微信傳送資訊,然後微信把資訊以XML格式傳送給我們的伺服器 3.接收資料,並把資料保存於資料庫或者快取,程式碼如下: $wechatObj = new
Java常用的九種排序方法及程式碼實現
package com.algorithm.Demo; import java.util.ArrayList; import java.util.Arrays; import j
【深度學習】ResNet解讀及程式碼實現
簡介 ResNet是何凱明大神在2015年提出的一種網路結構,獲得了ILSVRC-2015分類任務的第一名,同時在ImageNet detection,ImageNet localization,COCO detection和COCO segmentation等任務中均獲得了第一名,在當
softmax函式注意事項及程式碼實現
import numpy as np def softmax(x): """ softmax function """ # assert(len(x.shape) > 1, "dimension must be larger than 1") # print
蒙特.卡羅方法求解圓周率近似值原理及程式碼實現
原理 對於某些不能精確求解的問題,蒙特.卡羅方法是一種非常巧妙的尋找近似解的方法。 以求解圓周率的問題為例,假設有一個單位圓及其外切正方形,我們往正方形內扔飛鏢,當扔的次數足夠多以後,“落在圓內的次數/落在正方形內的次數”這個比值會無限接近“圓的面積/
大資料教程(8.2)wordcount程式原理及程式碼實現/執行
上一篇部落格分享了mapreduce的程式設計思想,本節博主將帶小夥伴們瞭解wordcount程式的原理和程式碼實現/執行細節。通過本節可以對mapreduce程式有一個大概的認識,其實hadoop中的map、reduce程
機器學習-*-K均值聚類及程式碼實現
KMeans聚類 在聚類演算法中,最出名的應該就是k均值聚類(KMeans)了,幾乎所有的資料探勘/機器學習書籍都會介紹它,有些初學者還會將其與KNN等混淆。k均值是一種聚類演算法,屬於無監督學習的一種,而KNN是有監督學習/分類學習的一種。 聚類:顧名思義,就是講某些相似的事物聚在
機器學習-*-DBSCAN聚類及程式碼實現
DBSCAN DBSCAN(Density-Based Spatial Clustering of Applications with Noise,具有噪聲的基於密度的聚類方法) 原理 首先描述以下幾個概念,假設我們有資料集