1. 程式人生 > >5分鐘教你發行ERC20代幣和代幣生態

5分鐘教你發行ERC20代幣和代幣生態

上一篇文章用不專業、入門的語言分享了一下筆者理解的代幣價值。本文將講述一下代幣生態的運作、如何發行代幣以及如何用一門常用的程式語言(Java)操作它。

雖然類似的文章一搜一大堆,但是根據筆者的實踐,幾乎很少有一篇文章可以真的把整個流程講解的透徹,並且無障礙的實踐落地,所以本文把實踐後的內容從新整理,希望對感興趣的小夥伴有所幫助。

代幣生態

首先介紹一下代幣生態的運作,先來介紹一個常見基於代幣的商業模式,例如一個某APP的宣傳語是“XX即挖礦,隨時提現到錢包,發財就是這麼容易”。這裡提到幾個點,挖礦、提現、發財。這個宣傳語很有誤導性,挖礦挖出來是啥,真的礦?提現到哪裡,支付寶?怎麼就發財了。

上一篇文章提到過,代幣可以被幾乎零成本的創造出來,然後儲存在合約建立者的以太坊錢包中,這裡挖礦挖出來的其實是專案方發行的代幣。而提現也不是提現到微信支付寶,而是提現到以太坊錢包,而套現就需要把代幣轉移到交易所中去交易,至於能不能發財,就要看手裡的代幣和專案前景了。為了更明瞭,用如下圖表示整個過程。

這個代幣生態下主要分為APP內和APP外,APP的使用者,通過XX即挖礦獲得代幣,此時的代幣還並不是真正以太坊網路上的代幣,它只存在於APP的伺服器中,和傳統的積分並無兩樣。

然後使用者可以通過“提現”操作,將代幣提現到它的以太坊錢包中,而提現的實現就是通過代幣智慧合約。為什麼不是,使用者 XX 即挖礦的同時,就將代幣發到使用者的以太坊錢包呢?或許有的專案是這麼做的吧,但是以太坊網路轉賬需要消耗GAS(以太坊),每筆代幣轉賬需要消耗 0.001 - 0.002 以太坊(現價大概是5元左右),使用者的每個“挖礦行為”都可能讓她獲得代幣,頻繁的轉賬成本很高,另外也不方便專案方鎖倉之類的控制行為。

所以大多數的模式,都要走一個提現申請過程。提現會提到一個支援ERC20代幣的錢包,例如imtoken。在錢包裡的代幣依然是一串數字,只有專案方將代幣運作上交易所,才有可能交易套現。而代幣的價格往往也和上市的交易所直接掛鉤,如果運作上市知名交易所,如幣安、火幣等幣價可能堅挺,如果是不知名的交易所,可能就命途多舛了。

有了可以交易該代幣的交易所,使用者將代幣提現到交易所中,通過賣出代幣獲得USDT、ETH、BTC等硬通貨數字貨幣,最後在法幣交易板塊(OTC)賣掉,收到法幣完成套現。

是不是覺得這個模式就是空手套,零成本弄出一堆數字,然後使用者進來瘋狂的挖礦,至於最後能不能讓使用者賺到錢就看資本運作和二級市場表現了。記得周鴻禕伯伯說過一句話,XX比販毒還賺錢,這種錢我們也要賺。所以下面的內容,就在技術上詳細講解下如何發行代幣和如何用一個常用的程式語言操作它。

代幣發行

前期準備:外網連線、以太坊錢包(MetaMask)、ERC20代幣智慧合約。

  1. 在 Chrome 外掛商店搜尋並安裝 MetaMask

2. 執行後,用它來給我們初始化一個以太坊錢包。

為了測試,我們可以點選左上角切換到測試網路

發行數字貨幣需要消耗以太坊,在測試網路中可以免費獲得測試所需的以太坊:

Ethernet Faucet,然後點 Send me 1 test ether! 即可。一會就有會一個以太坊轉到你的賬戶,如果是在真是網路上,需要你去交易所買以太坊,然後提現到自己的MetaMask錢包,當然也可以用 MetaMask 匯入有 以太坊 的錢包。

然後就可以釋出智慧合約了。這裡我準備一份智慧合約:

這個合約看起來比較複雜,但是基本都是基於各種開源社群的合約內容改造的,如果你理解面嚮物件語言的話,合約的內容非常好理解,類似於Java的介面、繼承等概念,最後要釋出的智慧合約DncToken,它繼承並實現了若干個介面,除了ERC20標準介面外,同時具有總量限制,可以焚燒等特點,智慧合約程式碼的繼承樹如下:

有了智慧合約,然後把它釋出到以太坊網路中。我們使用 Remix - Solidity IDE 網站來發布智慧合約。MetaMask會把當前賬戶相關的資訊填寫到網站上,我們只需要把智慧合約的程式碼貼上進去,簡單的改一下配置就可以了:

把網站當前使用的 solidity 編譯器版本號改成和檔案頭一致,把Enable Optimization 去掉。然後切換到 Compile 頁面,點選Start Compile。

最後在Run頁面,點選 Deploy

然後會彈出 MetaMask 確認頁面,輸入一個 Gas 數量即可,點選Submit。

然後可以看到合約開始部署~

部署完畢後,點選那個合約,會幫你開啟一個網站,檢視合約詳情:

點選合約地址,會跳轉到合約校驗釋出頁面,點選Verify And Publish

填寫好下面資訊,同時貼上程式碼:

拉到最下面,然後確認即可。釋出成功後,會看到如下頁面:

然後在賬戶中,就可以看到如下內容了:

因為這份智慧合約初始狀態,只約定代幣總量,要通過 mint (鑄幣) 函式呼叫,才會給某個賬戶鑄幣,並且鑄幣總量不能超過約定到代幣總量,當然也可以通過轉賬功能,在鑄幣後給別的地址轉賬,那麼如何用一個常用到程式語言操作代幣智慧合約呢,用Java為例做進一步說明。

Java操作代幣

很多文章的操作方法,會安裝一堆東西,例如以太坊本地執行環境之類,其實根本不需要,只要安裝 solidity(智慧合約程式語言)編譯工具 solcjs 和 以太坊Java 介面工具 web3j 即可,和以太坊網路打交道的事情,可以通過網路完成。

首先安裝基本工具:(Mac系統)

sudo npm install -g solc
brew tap web3j/web3j
brew install web3j

為Java專案新增依賴

<dependency>	
    <groupId>org.web3j</groupId>	
    <artifactId>core</artifactId>	
    <version>3.5.0</version>
</dependency>

然後把智慧合約檔案放入Java專案的根目錄,執行

#!/usr/bin/env bash
solcjs dnc.sol --bin --abi -o ./
web3j solidity generate --solidityTypes dnc_sol_DncToken.bin dnc_sol_DncToken.abi -o src/main/java -p org.bilan.module.asset.dnc

然後在Java專案的 org.bilan.module.asset.dnc 包中,就出現了智慧合約的Java版啦~

然後用如下程式碼載入智慧合約

package org.bilan.module.asset;
import org.bilan.module.asset.config.ContractConfig;
import org.bilan.module.asset.dnc.Dnc_sol_DncToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.WalletUtils;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.gas.DefaultGasProvider;
import java.math.BigInteger;
/** 
* Created by Vic on 2018/8/5. 
*/
@Componentpublic class ContractLoader {

    @Autowired    
    private ContractConfig config;

    private static Logger logger = LoggerFactory.getLogger(WithdrawJob.class);

    public Dnc_sol_DncToken loadContract(){
        try{            
            //以太坊基礎設施網路申請訪問 https://ropsten.infura.io            
            Web3j web3j = Web3j.build(new HttpService(config.getNet()));           
            Credentials credentials = WalletUtils.loadCredentials( 
                   config.getPassword(), //錢包密碼                    
                   config.getKeyStore()); //錢包的 keystore 檔案
            Dnc_sol_DncToken contract = Dnc_sol_DncToken.load(config.getAddress(), //合約地址     
                            web3j, credentials, DefaultGasProvider.GAS_PRICE, DefaultGasProvider.GAS_LIMIT);
            return contract;        
        }        
        catch (Exception e){
            logger.error("load contract error", e);                   
            return null;        
        }
    }}

做幾點解釋,config.getNet() 配置,是在以太坊基礎設施網路中申請的訪問(https://infura.io),簡單的註冊後就可以使用它提供的 Access Key 訪問到以太坊主網和測試網。錢包密碼是建立錢包的時候建立的,MetaMask 不支援匯出 keystore 檔案,所以最開始使用 MetaMask 建立錢包看來不明智,我們需要在官網上可以申請錢包,然後用 MetaMask 匯入。

Dnc_sol_DncToken.load 函式需要的 address 就是智慧合約的部署地址了,前面的內容中有提到。

合約載入好了以後,就可以呼叫合約中的函數了,例如呼叫鑄幣函式(mint):

Integer decimal = contractConfig.getDecimals(); 
BigDecimal decimalPart = BigDecimal.TEN.pow(decimal); 
BigDecimal amount = mintApplyVo.getAmount().multiply(decimalPart); 
Address toAddress = new Address(mintApplyVo.getAddress()); 
TransactionReceipt receipt = dnc.mint(toAddress, new Uint256(amount.toBigInteger())).send();

值得注意的是,如果你要鑄 100 個幣,給智慧合約的引數是 100 * pow( 10, decimal ), 這個decimal是智慧合約內的一個引數,描述這個一個幣的小數位數。

呼叫成功後,會返回 TransactionHash,用 TransactionHash 可以在 https://etherscan.io/ 上 找到交易的詳細資料,這筆交易已經被打包到區塊中了,它不能被篡改哦~

再來看一下轉賬的呼叫:

BigDecimal decimalPart = BigDecimal.TEN.pow(decimal);
BigDecimal amount = vo.getAmount().multiply(decimalPart);
Address toAddress = new Address(userWalletVo.getEthAddress());
TransactionReceipt receipt = dnc.transfer(toAddress, new Uint256(amount.toBigInteger())).send();

和 呼叫 mint 並沒有什麼兩樣,只不過這次使用 transfer 函式而已。通過鑄幣後,就可以在自己的錢包中看到這個代幣啦,還可以轉賬給別人~

是不是覺得很簡單~ 感興趣的話可以自己試試哦,不過千萬別搞什麼ICO,如果你看了這個然後去發幣搞ICO被判非法集資,我可是不會負責的~