區塊鏈入門(5)Truffle 項目實戰,Solidity IDE, 智能合約部署

在上一張咱們學習了Truffle項目的建立,部署等相關內容,今天咱們就來實戰一下.

今天咱們要作3件事: 
        1) 學習搭建一個Solidity IDE(Remix).
        2) 使用這個Solidity Ide編寫一份智能合約.
        3) 在咱們前面第1,2,3章中部署的私有網絡節點集羣中部署這個合約,並可以在不一樣的節點中調用這個合約.

Remix,是一個Solidity開發語言的Ide, 它是一款運行在瀏覽器端的solidity ide,也是官方推薦使用的ide.

另外還有其它的solidiy ide,好比:Ethereum Studio, IntelliJ IDEA Plugin, Vistual studio extension...等這些ide的詳細狀況請參考官方文檔:
https://solidity.readthedocs.io/en/latest/index.html

咱們主要講解Remix.

官方推薦的Solidity基於瀏覽器端的Ide(Remix)

運行Remix有兩種方式,一種是直接用瀏覽器打開網址: https://remix.ethereum.org/
直接打開官方部署的編輯器,進行開發.

另一種方式就是在本地部署Remix服務, 順序運行下面的命令:
> git clone https://github.com/ethereum/remix
> cd remix
> npm install
> npm start
Remix服務就部署好了,而後在瀏覽器中打開:http://127.0.0.1:8080
就能夠直接使用本地部署Remix進行開發了.

本地搭建Rmix 編輯器的好處,是能夠隨意修改編輯器中,源代碼的字體.
vim ./node_modules/brace/index.js

找到下面的內容:
var editorCss = ".ace_editor {\
    position: relative;\
    overflow: hidden;\
    font: 10px/normal 'Ubuntu Mono', 'Monaco', 'Menlo', 'Consolas', 'source-code-pro', monospace;\
    direction: ltr;\
}\
.ace_scroller {\
    position: absolute;\
    overflow: hidden;\
    top: 0;\
    bottom: 0;\
    background-color: inherit;\
    -ms-user-select: none;\
    -moz-user-select: none;\
    -webkit-user-select: none;\
    user-select: none;\
    cursor: text;\
}\
在font這這一行,把字體修改爲本身喜歡的大小和樣式.

而後從新執行命令:
npm install
npm start

從新打開網頁,便可看到效果:javascript

在Remix上編寫第一份智能合約

打開瀏覽器,訪問http://127.0.0.1:8080, 新建文件'SimpleStorage.sol'
pragma solidity ^0.4.0;
contract SimpleStorage {
    uint storeddata;
    function set(uint x) {
        storeddata = x; 
    }
    function get() constant returns(uint retVal)  {
        return storeddata;
    } 
    function multiply(uint a) returns(uint d) {
        return a * 7;
    }
}

 
這個SimpleStorage功能很簡單,把一個數乘以7並保存起來,提供獲取和設置它的接口.

你們最好手動輸入以上內容體驗一下Remix的效果.也能夠故意輸錯,看看Remix是如何提醒錯誤的.

Remix調試模式

第一種是默認模式:javascript vm
第二種,是經過本地私有網絡的rpc端口,連接到本地私有網絡進行調試
還記得咱們第2章中建立的以太坊私有網絡節點集羣嗎?  進入以前的私有網絡目錄,並使用咱們講過的方法啓動節點:
cd ~/Documents/private-chain/
geth --datadir ./data/00 --networkid 314590 --ipcdisable --port 61910 --rpcport 8200 console
回到Remix瀏覽器Ide中,選中右側邊欄的'Contact'選項卡.在'Execution environment'選項中,選擇:'web3 provider', ide會彈出提示,讓你輸入以前咱們啓動的私有網絡的rpc地址和端口, 輸入: 
http://localhost:8200

肯定, 能夠看到ide彈出提示:
Invalid JSON RPC response: "" 
咱們按照官方提供的方法,增長几個選項,啓動命令修改以後以下:
geth --datadir ./data/00 --networkid 314590 --ipcdisable --port 61910 --rpc --rpcapi 'web3,eth,debug' --rpccorsdomain '*' --rpcport 8200 console
####咱們增長了如下幾個命令選項:####
--rpc --rpcapi 'web3,eth,debug' --rpccorsdomain '*'
 
而後Remix從新連接私有網絡的RPC地址, Idea沒有了錯誤提示. 回到剛纔啓動的網絡節點,在命令行輸入命令查看帳號:
> eth.accounts ["0x5fba50fce50baf0b8a7314200ba46336958ac97e"]
觀察Remix中, 有側邊欄'Contract' tab頁中的'Transaction origin',這裏顯示的就是這個帳號地址.  
點擊下方的'create'按鈕.錯誤又來了:

    callback contain no result Error: authentication needed: password or unlock

提示帳號被鎖定,須要'Transaction origin'中指定的帳號的密碼,或者解鎖帳戶.
回到geth命令行,執行下面的命令解鎖帳戶:
> personal.unlockAccount("0x5fba50fce50baf0b8a7314200ba46336958ac97e", 'password of account')
true
再次點擊'Create', 出現提示:
    

而且在geth命令行中,看到了一個提示: 
    > INFO [06-19|00:21:11] Submitted contract creation              fullhash=0x5aaf0021c94f52e37eda6c17cfbea2995c1ad1935816e7cac84c73448bd6ab2d contract=0xa7fdc326fa65a15665e3637ff33a120ff3758cdb
    > 

就像以前咱們在第三章中,從一個帳戶發送以太幣到另外一個帳戶,須要調用miner.start(),挖礦來確認咱們的交易同樣.
這裏咱們調用一下:
    > miner.start(3); admin.sleepBlocks(1); miner.stop();
    INFO [06-19|00:22:31] Updated mining threads                   threads=3
    INFO [06-19|00:27:08] Successfully sealed new block            number=38 hash=b7fdac…eb3c3f
    INFO [06-19|00:27:08] 🔨 mined potential block                  number=38 hash=b7fdac…eb3c3f
    INFO [06-19|00:27:08] Commit new mining work                   number=39 txs=0 uncles=0 elapsed=1.836ms
    INFO [06-19|00:27:08] Successfully sealed new block            number=39 hash=210027…1218e0
    INFO [06-19|00:27:08] 🔨 mined potential block                  number=39 hash=210027…1218e0
    INFO [06-19|00:27:08] Commit new mining work                   number=40 txs=0 uncles=0 elapsed=183.453µs
    true
    > 
    這裏這一串語句表示啓動3個線程來挖礦,挖到第一個區塊就中止.

####查看未確認的交易數量####
    >txpool.status

回到Remix中,咱們能夠看到,合約已經建立成功了.  

其中,有get, multiply, 和set 3個按鈕分別對應了SimpleStorage合約中的3個函數,用於測試函數的功能.
下面在set按鈕後面的的輸入框中,輸入參數'106',點擊'set'按鈕.

合約就被調用了.可是任然須要挖礦來確認.繼續運行這個命令:
    miner.start(3); admin.sleepBlocks(1); miner.stop();

等到挖礦完成,咱們能夠在瀏覽器的Remix中看到合約的set()函數的運行結果.  
點擊'get'按鈕,獲取SimpleStorage合約中'storeddata'的值,能夠看到咱們獲取到的結果是'106',說明咱們的合約沒有問題.
另外'multiply',你們能夠自行測試.

在私有鏈中部署智能合約

首先建立truffle項目,依次輸入如下命令:
    mkdir SimpleStorage
    cd SimpleStorage
    truffle init
以上命令建立並初始化truffle項目,在第4章中有說明, 這裏不在重複.

把Remix中的SimpleStorage.sol保存到SimpleStorage/contracts目錄中.

增長SimpleStorage的部署
在migrations中增長部署SimpleStorage的功能.在第四章中曾經詳細介紹Migration以及合約的部署.這裏直接提供代碼.  打開migration/2_deploy_contracts.js, 修改成:
var ConvertLib = artifacts.require("./ConvertLib.sol");
var MetaCoin = artifacts.require("./MetaCoin.sol");
var SimpleStorage = artifacts.require("./SimpleStorage.sol")

module.exports = function(deployer) {
  deployer.deploy(ConvertLib);
  deployer.link(ConvertLib, MetaCoin);
  deployer.deploy(MetaCoin);
  deployer.deploy(SimpleStorage);
};
編譯
    cd SimpleStorage
    truflle compile

編譯以後,咱們開始把合約SipleStorage部署到咱們的私有鏈中.
用咱們第二章中的方法啓動節點:
    > geth --datadir ./data/00 --networkid 314590 --ipcdisable --port 61910 --rpcport 8200 console
節點啓動成功後,咱們執行部署合約的命令. cd SimpleStorage truffle migrate 我靠,什麼鬼意思...他媽的執行失敗,顯示下面的信息.
Error: Invalid JSON RPC response: "" at Object.InvalidResponse (/usr/local/node-v6.10.2-linux-x64/lib/node_modules/truffle/node_modules/web3/lib/web3/errors.js:35:16) [image023] 查看大量資料後,發如今部署合約到私有鏈時,須要要注意如下幾點: 1) geth啓動節點的時候,必須帶有--rpcapi選項,而且選項的值必須包含有:"web3", "net", "eth"這3個設置,另外爲了保證rpc爲啓用,還應該帶有"--rpc"等一系列相關的參數. 2) 注意SimpleStorage項目目錄中:SimpleStorage/truffle.js(項目的配置文件),關於"rpcport"的配置必需要與啓動節點時,設置的端口號一致.
        module.exports = {
          networks: {
            development: {
              host: "localhost",
              port: 8545,
              network_id: "*" // Match any network id
            }
          }
        };
        咱們須要把prot: 8545,修改成geth啓動節點時設置的:8200

    3) 啓動節點後,節點中默認的帳戶是被鎖定的,沒法執行部署合約的操做,須要調用下面的命令解鎖帳戶:
        > personal.unlockAccount(eth.accounts[0],"password", 1000*60*20)
    
        第一個參數是帳戶地址.
        第二個參數:帳戶密碼.
        第三個參數:帳戶解鎖持續的時間, 以毫秒爲單位,這裏這樣只是爲了更方便的設置以分鐘爲單位(20分鐘)
    咱們把帳戶解鎖持續時間稍微設置久一點,以避免在部署的過程當中,帳戶忽然被鎖定,致使意外的出現.

有了以上3個須要注意的地方,咱們從新執行部署:

調整啓動命令後,用下面的命令啓動:
    > geth --datadir ./data/00 --networkid 314590 --ipcdisable --port 61910 --rpc --rpcapi 'web3,eth,net' --rpccorsdomain '*' --rpcport 8200 console
    INFO [06-24|19:15:09] Starting peer-to-peer node               instance=Geth/v1.6.1-stable-021c3c28/linux-amd64/go1.8.1
#####....這裏是不少書輸出的日誌信息....#####
    Welcome to the Geth JavaScript console!

    instance: Geth/v1.6.1-stable-021c3c28/linux-amd64/go1.8.1
    coinbase: 0x5fba50fce50baf0b8a7314200ba46336958ac97e
    at block: 41 (Sat, 24 Jun 2017 00:34:18 CST)
     datadir: /home/zl/Documents/private-chain/data/00
     modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
#####....啓動完成,咱們執行解鎖帳戶unlock.....#####
    > personal.unlockAccount(eth.accounts[0], "ko2005", 20*(60*1000))
    true

私有網絡節點的操做完成後,回到剛纔SimpleStorage所在的命令行, 執行部署命令:
    > truffle migrate    
    Using network 'development'.
    Running migration: 1_initial_migration.js
      Deploying Migrations...

能夠看到,執行的輸出結果與上一次不太同樣了,好像離成功更近了.咱們繼續等一下子.
[過了一分鐘,仍是沒反應,先來放一首歌....]
[....等啊等....
[草它大爺的,等了快10分鐘仍是沒有反應....]
[.....好像不按咱們的套路來啊.....]
[........]

忽然想起來一件事,咱們在以前的私有網絡中,用戶之間轉帳都是要經過挖礦來確認的...
這尼瑪..
回到剛纔啓動的私有網絡命令行,執行挖礦:
    > miner.start(3); admin.sleepBlocks(1); miner.stop();
    INFO [06-24|19:16:43] Updated mining threads                   threads=3
    INFO [06-24|19:16:43] Starting mining operation 
    INFO [06-24|19:16:43] Commit new mining work                   number=42 txs=1 uncles=0 elapsed=3.079ms

這行命令的意思: 啓動挖礦程序,在挖到一個區塊以後,中止挖礦.

[挖礦又是一個耗時間的操做...]

一下子, 部署合約的命令行輸出內容:
      Migrations: 0xbc14f4725810403de4b31cdaf00a84e2ea7252dc
    Saving successful migration to network...

同時,查看私有網絡的命令行,輸出內容: 
    > miner.start(3); admin.sleepBlocks(1); miner.stop();
    INFO [06-24|19:16:43] Updated mining threads                   threads=3
    INFO [06-24|19:16:43] Starting mining operation 
    INFO [06-24|19:16:43] Commit new mining work                   number=42 txs=1 uncles=0 elapsed=3.079ms
    INFO [06-24|19:32:05] Successfully sealed new block            number=42 hash=de460c…aefbfb
    INFO [06-24|19:32:05] 🔨 mined potential block                  number=42 hash=de460c…aefbfb
    INFO [06-24|19:32:05] Commit new mining work                   number=43 txs=0 uncles=0 elapsed=2.730ms
    true
    > INFO [06-24|19:32:06] Submitted transaction                    fullhash=0xdf799ee7e5981011125dca4e5edcdbbf344dfbc81f466be7e69ba266572e2724 recipient=0xbc14f4725810403de4b31cdaf00a84e2ea7252dc

看這命令行輸出"Submitted transaction",意思又的讓咱們挖礦確認吧, ,老套路,咱們懂, 再挖,命令行我就不打出來了.跟以前同樣的.
又等一下子..

SimpleStorage命令行輸出: 
    Saving artifacts...

區塊鏈網絡命令行輸出: 
    > INFO [06-24|19:49:31] Submitted contract creation              fullhash=0xb399d73bb5ed563e4acf6ad0b8ffc5e28ef114a1643df90b6218e568473c0b66 contract=0x6853da42bccdee332f180be1dd1e118e825ac57e

這尼瑪套路咱們算是明白了,但這尼瑪套路也太長了吧. 用周星馳的話來講就是:
我走過最長的路,就是這尼瑪以太坊的套路....

反正我就這樣一直走下去,最後總算是部署成功了,這就是個人執行結果:

合約部署成功後,咱們嘗試執行如下合約..今天就到這裏吧...
這一章咱們瞭解瞭如下幾點:
    1) 基於瀏覽器端的solidity ide "Remix",以及如何搭建本地版本的"Remix"
    2) Remix 的大概使用方法
    3) 使用Remix部署智能合約到Debug網絡中
    4) 如何建立一個簡單的truffle 項目, 進行項目建立,編寫部署代碼, 編譯..到執行部署的詳細流程.
    5) 在部署智能合約到以太坊私有鏈時,須要注意的許多地方.
    6) 咱們成功部署了一個智能合約在以太坊私有鏈中....

下一次咱們講一下如何在私有鏈中調用已經部署好的智能合約....
工做忙的時候,更新會稍慢,你們敬請期待..  
相關文章
相關標籤/搜索