1. 程式人生 > >ERC20藏品合約標準解析及程式碼實現

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,具有噪聲的基於密度的聚類方法) 原理 首先描述以下幾個概念,假設我們有資料集