智能合約初體驗


參考地址:Ethereum Homestead

 

什么是智能合約

    智能合約是代碼和數據的集合,寄存與Blockchain的具體的地址。智能合約更想是在Blockchain中的一個自動化的代理(或者說是機器人or NPC),智能合約有自己的賬戶,在時間或事件的驅動下能自動執行一些功能,如可以在相互之間傳遞信息,修改區塊鏈的狀態(賬戶信息等),以及圖靈完備計算(可以用圖靈機做到的所有事情,通俗來說就是一般編程語言可以做的所有事情)。以太坊的智能合約是以太坊特定的字節碼,被叫做EVM字節碼。

智能合約高級語言

    用戶不可能直接編寫EVM字節碼,所以以太坊提供了幾種編寫智能合約的高級語言。

    Solidity:類JavaScript,這是以太坊推薦的旗艦語言,也是最流行的智能合約語言。具體用法參加Solidity文檔

    Serpent:類Python

    LLL:類Lisp

    可以根據不同的習慣選擇不同的高級語言。這里選用最流行的Solidity

相關概念

    以下的概念是智能合約可能用到的,這里不做詳細介紹,想了解的可以參考 智能合約菜鳥教程

    公鑰加密系統:

    點對點網絡:

    區塊鏈:區塊鏈可以看做是智能合約的基礎設施

    以太坊虛擬機:解釋執行智能合約字節碼的東西,功能類似於Java虛擬機

    節點:

    礦工:區塊鏈中參與處理區塊的節點叫做礦工。當前以太坊活躍的礦工:https://ethstats.net/

    工作量證明:礦工們總是在競爭解決一些數學問題。第一個解出答案的(算出下一個區塊)將獲得以太幣作為獎勵。然后所有節點都更新自己的區塊鏈。所有想要算出下一個區塊的礦工都有與其他節點保持同步,並且維護同一個區塊鏈的動力,因此整個網絡總是能達成共識。

    以太幣:ETH,以太坊中的虛擬貨幣,可以購買和使用,也可以與真實貨幣交易。以太幣的走勢圖

    Gas:相當於手續費。在以太坊執行程序以保存數據都要消耗一定量的以太幣。這個機制可以控制區塊鏈中計算的數量,保證效率。

智能合約與DApp

    以太坊社區把基於智能合約的應用稱為去中心化的應用程序(Decentralized App)。DApp的目標是(或者應該是)讓你的智能合約有一個友好的界面,外加一些額外的東西,例如IPFS(可以存儲和讀取數據的去中心化網絡,不是出自以太坊團隊但有類似的精神)。DApp可以跑在一台能與以太坊節點交互的中心化服務器上,也可以跑在任意一個以太坊平等節點上。(花一分鍾思考一下:與一般的網站不同,DApp不能跑在普通的服務器上。他們需要提交交易到區塊鏈並且從區塊鏈而不是中心化數據庫讀取重要數據。相對於典型的用戶登錄系統,用戶有可能被表示成一個錢包地址而其它用戶數據保存在本地。許多事情都會與目前的web應用有不同架構。)

    DApp流程:

  1. 用Solidity(或其他語言)編寫智能合約(后綴為.sol)
  2. 用solc編譯器將.sol合約編譯成EVM字節碼
  3. 編譯好的字節碼回送給dapp前端
  4. 前端將編譯好的智能合約部署到區塊鏈中
  5. 區塊鏈返回智能合約地址+ABI(合約接口的二進制表示。合約接口用JSON表示,包括變量,事件和可以調用的方法)
  6. 前端通過Address+ABI+nonce,調用智能合約。智能合約開始處理。

 

智能合約編譯器

    Solidity智能合約可以通過多種方式進行編譯

    在這里選擇solc和web3.eth.compile.solidity方式

geth安裝

    參考:go Ethereum client。安裝不比較簡單,這里詳細說了

solc安裝

1. 作為cpp-ethereum的一部分安裝  

    如果通過編譯的方式安裝了cpp-ethereum(參考:http://www.cnblogs.com/fengzhiwu/p/5547911.html),那么solc編譯器就會作為cpp-ethereum的一個子項目也被編譯安裝,在webthree-umbrella/build/solidity/solc目錄下找到solc編譯器的可執行文件。

image

    然后,在/bin或/usr/bin目錄下創建軟鏈接就行了

ln -s /home/vagrant/Code/workspace/webthree-umbrella/build/solidity/solc/solc /bin/solc

2. 單獨安裝solc

參考:http://solidity.readthedocs.io/en/latest/installing-solidity.html

  • 通過npm安裝:這種比較簡單,運行npm install solc就行了,不過我沒有在console中找到solc
  • 通過apt-get安裝:

sudo add-apt-repository ppa:ethereum/ethereum

sudo apt-get update

sudo apt-get install solc

which solc

    把solc添加入geth中直接使用(在geth中輸入)

admin.setSolc("path/to/solc")
  • 從源碼編譯安裝

    這種方法和安裝cpp-etheruemle類似,不過最后的編譯步驟改為:

cd webthree-umbrella
./webthree-helpers/scripts/ethupdate.sh --no-push --simple-pull --project solidity # update Solidity repo
./webthree-helpers/scripts/ethbuild.sh --no-git --project solidity --cores 4 -DEVMJIT=0 -DETHASHCL=0 # build Solidity only

測試

    打開一個geth console,輸入:web3.eth.getCompilers(),就會打印

image

 

智能合約體驗

編譯一個簡單的合約

    直接在console中編譯一個簡單的合約代碼

> source = "contract test { function multiply(uint a) returns(uint d) { return a * 7; } }"
> clientContract = eth.compile.solidity(source).test

編譯返回的結果的JSON格式如下

image   
 
    其中,
    code:編譯后的EVM字節碼
    info:編譯器返回的metadata
        abiDefination:Application Binary Interface定義。具體接口規則參見這里
    compilerVersion:編譯此代碼的solidity編譯器版本
    developerDoc:針對開發者的Natural Specification Format,類似於Doxygen。具體規則參見這里
    language:合約語言
    languageVersion:合約語言版本
    source:源代碼
    userDoc:針對用戶的Ethereum的Natural Specification Format,類似於Doxygen。
    
    編譯器返回的JSON結構反映了合約部署的兩種不同的路徑。info信息真實的存在於區中心化的雲中,作為metadata信息來公開驗證Blockchain中合約代碼的實現。而code信息通過創建交易的方式部署到區塊鏈中。
 

創建和部署合約

    在進行此步驟前,確保你有一個解鎖的賬戶並且賬戶中有余額。(可以創建自己獨立的測試網絡,即自己的區塊鏈,初始化的時候就可以初始化一些有余額的賬戶)。參考:Test Networks
image
 
    現在就可以在區塊鏈中創建一個合約了。創建合約的方式是發送一個交易,交易的目的地址是空地址,數據是前面JSON結構中的code字段。
    創建合約的流程如下
var primaryAddress = eth.accounts[0]
var abi = [{ constant: false, inputs: [{ name: 'a', type: 'uint256' } ]}]
var MyContract = eth.contract(abi)
var contract = MyContract.new(arg1, arg2, ..., {from: primaryAddress, data: evmByteCodeFromPreviousSection}) //arg1,arg2,...是構造參數,這里沒有,需要去掉。紅色部分用前面生成的code代替
    i. 獲得賬戶
image
    ii. 定義一個abi (abi是個js的數組,否則不成功)
image
    iii. 創建智能合約
image
    iv. 發送交易部署合約
image
 
    如果交易被pending,如圖說明你的miner沒有在挖礦,
image
 
    啟動一個礦工
miner.setEtherbase(eth.primaryAddress)    //設定開采賬戶
miner.start(8)
eth.getBlock("pending", true).transactions
    這時候發現交易已經在區塊中
image
    不過會發現,交易還是pending,這是因為該交易區塊沒有人協助進行運算驗證,這時候只需要再啟動一個礦工就行了
miner.start(8)
參考:Private Testnet
發現區塊1部署了交易
image
image
 

與合約進行交互

    可以通過eth.contract()定義一個合約對象,這個對象包含變數合約接口的abi
Multiply7 = eth.contract(clientContract.info.abiDefinition);
var myMultiply7 = Multiply7.at(contract.address);
image
image
    到這兒,就可以調用智能合約的函數了。
myMultiply7.multiply.call(3)
myMultiply7.multiply.sendTransaction(3, {from: contract.address})
image

 

結束

    到此,對智能合約的初次體驗就結束了。另外智能合約以及DApp還可以干很多NB的事情。以后會進一步討論。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM