1. 程式人生 > >一步一步學區塊鏈(5)智慧合約

一步一步學區塊鏈(5)智慧合約

以太坊區塊鏈技術2.0版本對於行業應用的開發最主要特性就是實現了智慧合約,本質上講智慧合約是由事件驅動的、
具有狀態的、執行在一個複製的、分享的賬本之上的、且能夠保管賬本上資產的程式。
它是一個可以被信任,總是按照事先的規則執行的操作。但與此同時,智慧合約部署完之後無法修改也會帶來其他問題,這是另一個議題。下面直接上乾貨。
本篇內容是基於go客戶端通過命令列完成智慧合約的編寫、釋出、呼叫。
可參考的專案地址:http://www.ethdocs.org/en/latest/contracts-and-transactions/contracts.html

1、安裝solidity智慧合約開發語言 
brew tap ethereum/ethereum
brew install solidity
which solc
2、開啟命令列,進入之前建立的私鏈,並設定日誌輸出檔案
jwter-WIFI:csdnBlog jwter$ geth --datadir "privateChain" console 2>> log_output
Welcome to the Geth JavaScript console!

instance: Geth/v1.4.18-stable-c72f5459/darwin/go1.7.3
coinbase: 0x56a957bbde2b2dcb6321c9aceb11c21d6dfe68f9
at block: 164 (Sat, 03 Dec 2016 16:29:24 CST)
 datadir: privateChain
 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


> 

3、設定編譯環境

> web3.eth.getCompilers()
["Solidity"]
> admin.setSolc("/usr/local/bin/solc")
"solc, the solidity compiler commandline interface\nVersion: 0.4.2+commit.af6afb04.Darwin.appleclang
\n\npath: /usr/local/bin/solc"
4、編寫智慧合約並編譯
> contractSource  = "contract test { function multiply(uint a) returns(uint d) { return a * 7; } }"
"contract test { function multiply(uint a) returns(uint d) { return a * 7; } }"
> contract = eth.compile.solidity(contractSource).test
{
  code: "0x606060405260308060106000396000f3606060405260e060020a6000350463c6888fa18114601c575b6002565b3
46002576007600435026060908152602090f3",
  info: {
    abiDefinition: [{
        constant: false,
        inputs: [...],
        name: "multiply",
        outputs: [...],
        payable: false,
        type: "function"
    }],
    compilerOptions: "--bin --abi --userdoc --devdoc --add-std --optimize -o /var/folders/c6/
1vhz7hcd7w9g883rwrn4vzvr0000gn/T/solc271136546",
    compilerVersion: "0.4.2",
    developerDoc: {
      methods: {}
    },
    language: "Solidity",
    languageVersion: "0.4.2",
    source: "contract test { function multiply(uint a) returns(uint d) { return a * 7; } }",
    userDoc: {
      methods: {}
    }
  }
}
5、定義智慧合約abi並編譯
> abi = [{constant:false , inputs:{name:'a',type:'uint256'}}]
[{
    constant: false,
    inputs: {
      name: "a",
      type: "uint256"
    }
}]
> myabi = eth.contract(abi)
6、部署前準備:解鎖賬戶、監控日誌檔案
> accountAddress = eth.accounts[0]
"0x56a957bbde2b2dcb6321c9aceb11c21d6dfe68f9"
> personal.unlockAccount(accountAddress)
Unlock account 0x56a957bbde2b2dcb6321c9aceb11c21d6dfe68f9
Passphrase: 
true
>
監控日誌檔案需新開視窗,執行以下命令。用於檢視部署完的智慧合約是否被同步到區塊鏈網路中
jwter-WIFI:csdnBlog jwter$ tail -f log_output
7、部署智慧合約
> myContract = myabi.new({from:accountAddress,data:contract.code})
{
  abi: [{
      constant: false,
      inputs: {
        name: "a",
        type: "uint256"
      }
  }],
  address: undefined,
  transactionHash: "0xf330f4affd3989d72a979410e3a53f3a4d2d4d832faaa6c1bb32f72998acbd4b"
}
8、檢視部署狀態,並同步到區塊鏈中智慧合約必須開始挖礦模式才是被同步到區塊鏈中
可根據監控日誌視窗可以看到交易是否執行,來決定何時執行miner.stop()
> txpool.status
{
  pending: 1,
  queued: 0
}
> miner.start()
true
> miner.stop()
true
> txpool.status
{
  pending: 0,
  queued: 0
}
9、呼叫智慧合約
> contractABI = eth.contract(contract.info.abiDefinition)
> 
> testContract = contractABI.at(myContract.address)
{
  abi: [{
      constant: false,
      inputs: [{...}],
      name: "multiply",
      outputs: [{...}],
      payable: false,
      type: "function"
  }],
  address: "0xcb0895d4b3b35b2a45a31fab853614c14e7759a4",
  transactionHash: null,
  allEvents: function(),
  multiply: function()
}
> testContract.multiply.call(3)
21

注意:記得儲存智慧合約部署完的地址,以及abi引數,因為部署完之後無法修改,
忘記地址則無法再次呼叫,同時部署智慧合約會消耗gas,完成後可觀察使用者的餘額是否變化。