《前言》html
(二)PLSQL報表系統node
(三)SSO單點登陸git
(四) 短信中心與消息中心github
(五)錢包系統web
(七)權限系統編程
(八)監控系統json
(九)會員中心api
《虛擬幣交易平臺(區塊鏈)》 ——上 【發行區塊鏈代幣】
關於對於區塊鏈 或者 比特幣尚未一個基礎概念的就自行百度吧,什麼「去中心化」,「挖礦」,「POW」,等等等等,亂七八糟的東西
就隨便找個三分鐘科普視頻看一下就好了。咱們這邊將就直接進入正題,如何發行一個區塊代幣。
說到代幣,始終繞不過比特幣,關於比特幣有幾個點仍是要說一下:
1,首先比特幣的代碼是開源的,因此不少山寨幣修改比特幣加密算法而後就發行本身的代幣,不少沒有創新意義的山寨幣是沒有價值的。
2,比特幣是基於區塊鏈技術的首個應用。 更準確的說在沒有「區塊鏈」這個名詞以前把「BitCoin」表明比特幣,而「bitCoin」表明實現比特幣的技術(大小寫不一樣)。
3,比特幣的技術「區塊鏈」 從最本質來講是一種思想,用什麼語言去實現它是均可以的,哪怕是Java,C#。但經常使用的仍是C/C++。
4,比特幣不表明區塊鏈,比特幣的區塊鏈技術有不少不足的地方,好比:不具備「圖靈完備」。 就是他不能像Android同樣,基於他開發應用。
5,第一條裏面說沒有競爭優點的山寨幣是沒有價值的。這種就是一般用來作ICO的「空氣幣」,而所謂的ICO今天基本能夠看作割韭菜的代名詞如今國家已經禁止了ICO。
而有競爭優點的纔有價值好比擴容了區塊的萊特幣(LTC)。好比以「智能合約」著稱的 以太坊(以太坊是區塊鏈技術,代幣是以太幣,另外還有硬分叉的以太經典)。
說了這麼多廢話,今天咱們這一篇只要討論的仍是如何發幣,直接來點乾貨?
總的來講2種方式:
A: 直接下載比特幣的源代碼,如何能看懂C/C++ 就沒難度,直接改掉名字就好了。
具體怎麼搞呢?很是簡單:https://github.com/bitcoin/bitcoin 直接上GITHub下載 而後改吧。
B:前面說了比特幣的區塊鏈是不具有圖靈完備的,因此有些將區塊鏈封裝成平臺的咱們只要基於這個平臺
開發本身的代幣應用就好了。好比: 超級帳本(hyperledger), 還有前面提到的以太坊(Ethereum)。
下面我會重點講一下以太坊。
===================================華麗的分割線==========================================
講到這裏咱們纔是真的切入正題了,利用以太坊發幣。關於以太坊是什麼?什麼是智能合約? 這些能百度到的概念性東西
我就不作百度的搬運工了,我直接講實操的部分。
首先咱們能夠下載須要咱們須要下載以太坊的錢包客戶端:
其實以太坊的錢包客戶端 主要的都是Geth這個工具, Geth是必定要下載的 Ethereum Wallet 和 Mist 都是基於geth作了一個圖形化界面。
注意,重點來了!以太坊是基於go語言發開的,自己咱們也能夠下載以太坊的源碼而後像改比特幣源碼同樣去改爲本身的區塊鏈,
Github的以太坊源碼連接: https://github.com/ethereum/go-ethereum
可是迴歸到本質是上來講仍是那句話:首先要能看的懂,其次改完以後要有競爭力。
咱們貼一下錢包客戶端的圖,整篇博客都是文字 就太不利於閱讀了,我這裏貼的 Ethereum Wallet,推薦使用Ethereum Wallet。
默認以太坊錢包客戶端會鏈接上真實以太坊「主鏈」也叫公有鏈,因此就在一直同步區塊,這就很費事了,以太坊有專門開發人員提供測試環境也就是測試鏈(Rinkeby)
這個咱們晚點再說。
若是利用以太坊發幣第一種方式是,直接下載以太坊源碼修改以太坊的話,那第二種辦法就是利用以太坊的區塊鏈技術發佈一個私有鏈!
怎麼作?咱們先嚐試着發佈一個本身的私有鏈。
步驟以下:
1,下載geth錢包客戶端:
2,下載圖形化錢包客戶端:
3,本身建立一個私有鏈須要一個創世文件genesis.json,這裏我直接提供了。(geth從1.7版本開始創世文件要加config參數)
{
"config"
: {
"chainId"
: 15,
"homesteadBlock"
: 0,
"eip155Block"
: 0,
"eip158Block"
: 0
},
"coinbase"
:
"0x0000000000000000000000000000000000000000"
,
"difficulty"
:
"0x40000"
,
"extraData"
:
""
,
"gasLimit"
:
"0xffffffff"
,
"nonce"
:
"0x0000000000000042"
,
"mixhash"
:
"0x0000000000000000000000000000000000000000000000000000000000000000"
,
"parentHash"
:
"0x0000000000000000000000000000000000000000000000000000000000000000"
,
"timestamp"
:
"0x00"
,
"alloc"
: { }
}
將這個文件,保存到txt,更名叫genesis.json,固然名字能夠本身決定。這就是一個普通的json文件。
裏面的字段是什麼意思呢? 我來解釋一下(其實也是百度查的):
參數名稱 | 參數描述 |
---|---|
mixhash | 與nonce配合用於挖礦,由上一個區塊的一部分生成的hash。注意他和nonce的設置須要知足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章節所描述的條件。 |
nonce | nonce就是一個64位隨機數,用於挖礦,注意他和mixhash的設置須要知足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章節所描述的條件。 |
difficulty | 設置當前區塊的難度,若是難度過大,cpu挖礦就很難,這裏設置較小難度 |
alloc | 用來預置帳號以及帳號的以太幣數量,由於私有鏈挖礦比較容易,因此咱們不須要預置有幣的帳號,須要的時候本身建立便可以。 |
coinbase | 礦工的帳號,隨便填 |
timestamp | 設置創世塊的時間戳 |
parentHash | 上一個區塊的hash值,由於是創世塊,因此這個值是0 |
extraData | 附加信息,隨便填,能夠填你的個性信息 |
gasLimit | 該值設置對GAS的消耗總量限制,用來限制區塊能包含的交易信息總和,由於咱們是私有鏈,因此填最大。 |
這裏暫時不要去懂太多,反正知道 咱們須要一個創世文件genesis.json便可。
4,將創世文件保存下來,我這裏放到C:\Program Files\Geth, 我這裏是由於Geth客戶端 安裝就在C盤,若是C盤空間不是很足就不建議安裝在C盤了
正式環境的主鏈如今有60G左右,很佔空間。
5,運行命令經過cmd命令運行。 直接打開geth就連接到主鏈了,默認是主鏈,因此咱們經過命令加載創世文件。
geth –datadir 「%cd%\chain」 init genesis.json
有可能會出現找不到文件的情況,因此咱們要定位一下geth的目錄。
創世區塊加載成功了!
6, 再經過命令來啓動私有鏈,並進入控制檯:
geth --identity "Nearetherum" --rpc --rpccorsdomain "*" --datadir 「%cd%\chain」 --port "30303" --rpcapi "db,eth,net,web3" --networkid 11100 console
私有鏈啓動成功了!
咱們來看看geth的一些基本參數:
參數描述
identity:區塊鏈的標示,隨便填寫,用於標示目前網絡的名字
init:指定創世塊文件的位置,並建立初始塊
datadir:設置當前區塊鏈網絡數據存放的位置
port:網絡監聽端口
rpc:啓動rpc通訊,能夠進行智能合約的部署和調試
rpcapi:設置容許鏈接的rpc的客戶端,通常爲db,eth,net,web3
networkid:設置當前區塊鏈的網絡ID,用於區分不一樣的網絡,是一個數字
console:啓動命令行模式,能夠在Geth中執行命令
nodiscover:禁止被網絡中其它節點發現,須要手動添加該節點到網絡
執行 personal命令,這個私有鏈裏沒有任何錢包
咱們建立一個錢包帳戶試試:
personal.newAccount("123456")
再執行personal:
帳戶建立成功了。
好了,到這裏咱們的私有鏈就建立的差很少了,接下來就是在咱們的私有鏈裏咱們要運用起來,就得有人挖礦,挖礦其實就是記帳。
輸入命令:miner.start() 或者miner.start(1) 。這裏miner.start(1) 就是一個線程挖礦的意思。 這裏中止挖礦是:miner.stop()
挖礦就開始了。
因爲咱們在挖礦也就是記帳,因此區塊會慢慢增長,佔用的空間也會越來也多。
注意:挖礦挖到的ether幣會默認保在第一個帳戶中即eth.acccounts[0]中,因此要先建立一個錢包!
7,geth 不要關讓他繼續挖礦,咱們打開圖形化界面看看,這時會發現右上角有一個PRIVATE-NET!
PRIVATE-NET,意思就是啓動連接的是私有鏈網絡。 若是咱們沒有啓動私有鏈默認是連接主鏈了。
後面咱們還會介紹以太坊的測試環境Rinkeby。
咱們直接點擊運行,錢包客戶端,這時候回發現錢包客戶端裏面有一個錢包地址,這就是咱們剛剛在Geth裏面建立的錢包。
看看 是否是咱們上面建立的錢包,這裏咱們裏面就有私有鏈的以太坊了。這15個以太幣就是咱們剛剛挖礦獲得了,咱們繼續開啓挖礦,就能夠繼續得到以太幣!
不過這是私有鏈的。固然咱們能夠在私有鏈上部署智能合約!
這裏就比咱們直接拿以太坊的源碼去改方便太多了。直接用以太坊發佈本身的私有鏈,發佈本身的代幣了!
不過缺點是私有鏈咱們須要別人來同步咱們的區塊鏈,而且還要有人來挖礦記帳以及確認交易,若是中止挖礦的話,就不會再產生以太幣,智能合約也沒用了
說白了就是沒人挖礦就沒有新的區塊來產生。
===========================================華麗的分割線===================================
咱們來回顧一下以上咱們講了三種發行代幣的方式:
1,上GitHub上下載比特幣的源碼而後進行修改。缺點:須要懂C/C++,而且能充分理解比特幣思想而後才能改動。
而且比特幣底層區塊不具有圖靈完備,從長遠來講也就只能發個幣。因此不推薦!
2,以太坊一樣是開源的,咱們能夠上Github下載以太坊的源碼而後修改,優勢是以太坊是能夠編程的,但一樣須要精通Go語言而且
要去改底層算法,因此不推薦!
3,利用以太坊技術發佈一個私有鏈/聯盟鏈。缺點是須要人挖礦記帳。(這裏說明一下比特幣,萊特幣都是須要人挖礦記帳的,以太幣也同樣。)
那麼問題來了,有沒有不須要挖礦的,好比那些作ICO的圈錢割韭菜的,他們就根本沒有礦工,是怎麼回事?
接下來纔是我整篇博客要寫的重點? 基於「智能合約」發行代幣!
寫了這麼多才寫到重點,上面寫的那些都基本是廢話了。仍是那句話,我這裏更多的就寫實操的東西,關於概念性的玩意,我就不作百度
的搬運工了。在此以前咱們先記住幾個網站:
以太坊官網:https://www.ethereum.org/
以太坊愛好者:http://ethfans.org/
以太坊區塊瀏覽器:https://etherscan.io/
以太坊測試環境Rinkeby狀態網:https://www.rinkeby.io/
=======================================華麗的分割線==============================
正文開始,首先咱們打開以太坊錢包客戶端,可能有的人會卡一下,不要緊由於錢包客戶端會在本地建立區塊,而且開始同步一部分區塊。
打開以後咱們看到第一個選擇:
稍微懂一點英文咱們都能看明白什麼意思,Main Network 就是主鏈,Test Network 就是測試鏈。Main Network也就是真實的以太坊環境,咱們能夠嘗試進主鏈看看。不過主鏈如今區塊應該有60多G,因此同步時間會比較久。
並且以太幣如今已經漲到了5千大洋一個,咱們基於以太坊部署智能合約 髮型代幣是須要「以太幣」的。 這對於咱們新手來講,反覆嘗試部署,不可能去交易所買那麼多以太幣來測試。(能夠嘗試挖礦得到以太坊,可是太難!)
因此,咱們用測試環境「Rinkeby」。自己以太坊有幾個測試鏈Rinkeby,只是其中之一!(好比還有:ropsten 可是不推薦使用了)
咱們建立一個在Rinkeby 測試鏈的以太坊錢包:
正常狀況下的話,這裏建立完錢包以後就一步一步進入到錢包客戶端主界面了,可是有可能會出現連接不上Rinkeby的故障
好比我這種:
這是什麼緣由呢?實際上是由於咱們本地沒有加載Rinkeby的創始區塊,而且客戶端也不知道去哪裏同步區塊。這個時候咱們就要用到咱們
前面提到的那些網站,咱們打開:https://www.rinkeby.io/ 訪問速度比較慢的就下載個FQ軟件。
這裏咱們看到首先咱們須要Rinkeby的創始區塊json,跟前面咱們發私有鏈流程是同樣的,把Rinkeby.json 保存在本地geth目錄下。
(因爲以前的文章是我昨天用筆記本寫的,今天我換了臺式機因此我geth的目錄變成了d盤下,不要緊咱們在cmd命令窗口裏,定位一下目錄就好了)
而後流程是同樣的,上面咱們看到https://www.rinkeby.io/#geth 裏面有四個節點選擇,關於這四個節點要細講起來,就要講的東西比較多,這裏咱們就選第一個吧:Archive node 。
geth --datadir=$HOME/.rinkeby init rinkeby.json
而後使用同步全節點:
geth --networkid=4 --datadir=$HOME/.rinkeby --cache=1024 --syncmode=full --ethstats='demon28@163.com' --bootnodes=enode://a24ac7c5484ef4ed0c5eb2d36620ba4e4aa13b8c84684e1b4aab0cebea2ae45cb4d375b77eab56516d34bfbd3c1a833fc51296ff084b770b94fb9028c4d25ccf@52.169.42.101:30303
注意:--ethstats: 改爲本身的郵箱,這個隨便填個郵箱就行,可是要改一下!上面那個demon28@163.com 是個人郵箱,要改爲本身的!
這個時候再打開錢包客戶端就能夠鏈接Rinkeby了! 咱們會發現rinkeby的區塊要比以太坊主鏈要小好多,這裏除了是測試環境之外還有一個緣由,由於Rinkeby是不容許挖礦的。
若是,Rinkeby的測試環境容許挖礦的話,那測試環境的區塊就會愈來愈大,有可能測試環境甚至可能比主鏈區塊都大,那麼問題來了!
前面咱們說過經過部署智能合約發行代幣,是須要以太幣的,幾遍是測試環境也是,那麼Rinkeby又不能挖礦,咱們怎麼得到Rinkeby測試鏈下的以太幣?
其實很簡單!直接問以太坊要唄,夠直接吧! https://www.rinkeby.io/#faucet
在此以前,咱們得先有一個接受Rinkeby以太幣的錢包地址,前面若是建立成功的,進入客戶端界面以後會有錢包地址顯示,若是沒有的就建立一下!
那麼咱們這裏就建立了一個rinkeby錢包:
也能夠像前面咱們操做私有鏈同樣在geth裏面操做,也是同樣的。圖形化界面只是封裝了一下而已!
接下來,咱們繼續來問官網要 rinkeby的測試以太幣
看到這個有點懵是不? 我也是,我也沒明白上面要我填上面,起初我也覺得只要填錢包地址就能夠了,後來發現不是這麼回事。
百度一下,纔讀懂這句英文: Social network URL containing your Ethereum address ! (可能英文比較好的人沒有我這個問題,我是屬於英文比較很差的)
意思就是說:"給他一個網絡訪問地址,打開裏面的內容是rinkeby錢包地址!" 雖然意思明白了,可是具體這麼搞呢?
上面有說,用 「推脫」 或者 「谷歌+」 或者 「Facebook」 。 (都要FQ,這個FQ的問題就靠本身解決咯!)
其實我上一次要幣的時候用的github的gists,gists就至關於一個網絡記事本,雖然也要FQ,可是github仍是比較熟悉的,不過如今github不讓用了,因此咱們今天咱們嘗試用一下google+。
關於谷歌帳號怎麼註冊,怎麼登錄這個我就不說了。登錄後,至關於咱們發朋友圈,發QQ說說同樣,發一條google+的消息就好了,以下圖:
而後把訪問地址複製!
再回到 https://www.rinkeby.io/#faucet而後直接要三個以太幣。
別要多了,自己這就是測試幣要多了沒用! 而且要的越多時間到帳的時間越久。上面也寫了,要3個的話到帳時間要8個小時!。
在這8個小時的等待時間裏,咱們可讓Rinkeby的區塊慢慢同步。 通常睡一覺次日就到了!
通過漫長的等待,終於rinkeby的區塊也同步完了,於此同時。咱們索要的Rinkeby的測試幣也到帳了。
有沒有比較快的方式,也有! 直接加幾個以太坊的羣,問羣裏的大神要1個就好! 咱們這裏寫的比較細,主要是把幾個源頭說清楚!
咱們長話短說,測試幣到帳以後,咱們就要部署智能合約了!
=====================================華麗的分割線==========================================
智能合約 是用solidity 這種腳本語言開發的,相似JavaScript 不是很複雜。 咱們點擊錢包客戶端的 右上角的 Contracts (合約)
再選擇部署智能合約!
這裏我直接提供一個官網的發行代幣智能合約: 官網文檔:https://ethereum.org/token
pragma solidity ^0.4.16; interface tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) public; } contract TokenERC20 { // Public variables of the token string public name; string public symbol; uint8 public decimals = 18; // 18 decimals is the strongly suggested default, avoid changing it uint256 public totalSupply; // This creates an array with all balances mapping (address => uint256) public balanceOf; mapping (address => mapping (address => uint256)) public allowance; // This generates a public event on the blockchain that will notify clients event Transfer(address indexed from, address indexed to, uint256 value); // This notifies clients about the amount burnt event Burn(address indexed from, uint256 value); /** * Constructor function * * Initializes contract with initial supply tokens to the creator of the contract */ function TokenERC20( uint256 initialSupply, string tokenName, string tokenSymbol ) public { totalSupply = initialSupply * 10 ** uint256(decimals); // Update total supply with the decimal amount balanceOf[msg.sender] = totalSupply; // Give the creator all initial tokens name = tokenName; // Set the name for display purposes symbol = tokenSymbol; // Set the symbol for display purposes } /** * Internal transfer, only can be called by this contract */ function _transfer(address _from, address _to, uint _value) internal { // Prevent transfer to 0x0 address. Use burn() instead require(_to != 0x0); // Check if the sender has enough require(balanceOf[_from] >= _value); // Check for overflows require(balanceOf[_to] + _value > balanceOf[_to]); // Save this for an assertion in the future uint previousBalances = balanceOf[_from] + balanceOf[_to]; // Subtract from the sender balanceOf[_from] -= _value; // Add the same to the recipient balanceOf[_to] += _value; Transfer(_from, _to, _value); // Asserts are used to use static analysis to find bugs in your code. They should never fail assert(balanceOf[_from] + balanceOf[_to] == previousBalances); } /** * Transfer tokens * * Send `_value` tokens to `_to` from your account * * @param _to The address of the recipient * @param _value the amount to send */ function transfer(address _to, uint256 _value) public { _transfer(msg.sender, _to, _value); } /** * Transfer tokens from other address * * Send `_value` tokens to `_to` on behalf of `_from` * * @param _from The address of the sender * @param _to The address of the recipient * @param _value the amount to send */ function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) { require(_value <= allowance[_from][msg.sender]); // Check allowance allowance[_from][msg.sender] -= _value; _transfer(_from, _to, _value); return true; } /** * Set allowance for other address * * Allows `_spender` to spend no more than `_value` tokens on your behalf * * @param _spender The address authorized to spend * @param _value the max amount they can spend */ function approve(address _spender, uint256 _value) public returns (bool success) { allowance[msg.sender][_spender] = _value; return true; } /** * Set allowance for other address and notify * * Allows `_spender` to spend no more than `_value` tokens on your behalf, and then ping the contract about it * * @param _spender The address authorized to spend * @param _value the max amount they can spend * @param _extraData some extra information to send to the approved contract */ function approveAndCall(address _spender, uint256 _value, bytes _extraData) public returns (bool success) { tokenRecipient spender = tokenRecipient(_spender); if (approve(_spender, _value)) { spender.receiveApproval(msg.sender, _value, this, _extraData); return true; } } /** * Destroy tokens * * Remove `_value` tokens from the system irreversibly * * @param _value the amount of money to burn */ function burn(uint256 _value) public returns (bool success) { require(balanceOf[msg.sender] >= _value); // Check if the sender has enough balanceOf[msg.sender] -= _value; // Subtract from the sender totalSupply -= _value; // Updates totalSupply Burn(msg.sender, _value); return true; } /** * Destroy tokens from other account * * Remove `_value` tokens from the system irreversibly on behalf of `_from`. * * @param _from the address of the sender * @param _value the amount of money to burn */ function burnFrom(address _from, uint256 _value) public returns (bool success) { require(balanceOf[_from] >= _value); // Check if the targeted balance is enough require(_value <= allowance[_from][msg.sender]); // Check allowance balanceOf[_from] -= _value; // Subtract from the targeted balance allowance[_from][msg.sender] -= _value; // Subtract from the sender's allowance totalSupply -= _value; // Update totalSupply Burn(_from, _value); return true; } }
====================================華麗的分割線=======================================
若是沒有rinkeby的測試以太幣,這裏是不能部署智能合約的,這裏也牽扯到一個「燃料」 的知識點。燃料在以太坊裏面叫「gas」。
其實就是以太幣,可是他的單位比以太幣小不少不少。假如以太幣是一元的話,gas大概就是0.000001分錢。固然這個隨着以太坊的價格浮動的。
咱們接着來部署發行代幣的智能合約:
再來輸入密碼確認:
回過頭來點開本身的錢包,就能夠看到部署的智能合約,也就是咱們發行的區塊鏈代幣,在等待區塊確認。 這裏咱們前面給的gas確認速度就會越快!
以太坊是目前區塊鏈中確認速度最快的,咱們看到咱們發行的Near幣 已經成功了。
咱們嘗試着新建幾個帳戶相互之間用咱們發行的NearCoin轉帳試試。
每次交易都要收手續費的,這個手續費就是挖礦人員得到的收益之一。
到帳了··!!
另外,若是須要轉帳給別人,須要別人先添加觀察你的智能合約,就能夠得到了。
================================================華麗的分割線==============================================
最後再回顧一下說的四種發行代幣的方式:
1,修改比特幣源碼。
2,修改以太坊源碼。
3,發佈私有鏈。
4,部署智能合約 (重點)。
行了,這篇博客寫了我兩天時間,中間有些概念我也不知道我理解的對不對。若是有理解錯誤的地方還望指正!
在下一篇的博客中,我將根據個人經驗來寫如何開發一個 「虛擬幣交易平臺」。
若是您以爲這篇文章對您有幫助,請捐助:
好了,就到這裏有興趣一塊兒探討Winner框架的能夠加咱們QQ羣:261083244。或者掃描左側二維碼加羣。