go打造以太坊合約測試框架


傳送門: 柏鏈項目學院html



1 以太坊智能合約編譯

以太坊智能合約編寫使用solidity語言,通常狀況下咱們會在remix環境下進行編譯測試,在線環境相對比較穩定。若是不想用在線環境,那咱們就須要本身動手來編譯代碼,而且進行測試。咱們都須要準備哪些工具呢?git

  • 編譯器,solidity語言須要安裝solc編譯器
  • 以太坊節點,部署合約時須要用到

1.1 編譯器安裝和準備

安裝solc以及solcjsgithub

sudo npm install -g solc solc-cli --save-dev

solc能夠將sol代碼編譯爲go語言,solcjs能夠將sol代碼編譯爲abi。web

solc 使用方式以下:npm

ykdeMac-mini:abi yekai$ solc  -h
Usage:
  solc [OPTIONS] [ARGS]

Options: 
      --out-dir [PATH]   Output directory for the compiled contracts (Default is ./contracts)
      --optimise         If present activate the solc optimiser
  -k, --no-color         Omit color from output
      --debug            Show debug information
  -h, --help             Display help and usage details

不過本人通過實驗,這種solc的版本問題仍然會給編譯帶來很大困擾,由於我仍是推薦安裝以太坊官方的solidity庫,編譯就會到solc可執行程序。ubuntu

下載源碼api

git clone https://github.com/ethereum/solidity

編譯源碼,注意此處編譯的時候須要cmake,若是系統中不存在,能夠提早安裝一下。
若是須要安裝cmake,能夠參考:app

  • for ubuntu
sudo apt-get install cmake
  • for mac-os
brew install cmake

cmake存在後能夠編譯源碼了cors

cd solidity
mkdir build
cd build
cmake .. && make

編譯好solc以後須要將它放到$PATH環境變量所對應的某個路徑下,本人是直接拷貝到了/usr/local/bin下,固然你若是想創建一個軟鏈接也能夠,直接鏈接的路徑是準確的就行!框架

cp solc /usr/local/bin/

固然咱們本篇文章重點討論的是go語言的問題,因此go語言的安裝環境也須要搞定!

1.2 以太坊節點安裝和部署

這個網上也有不少文章,咱們暫且不展開討論。也能夠到這裏來查看區塊鏈技術百科

啓動geth,開發時使用開發者模式,相對比較容易一些,開發者模式會提供一個默認帳戶,這個帳戶有不少錢,並且使用此帳戶也無需解鎖,可是不要想太多,這個是私鏈的以太幣!
geth --rpc --rpcport "8545" --rpccorsdomain "*" --datadir ./data/ --nodiscover --networkid 18 --rpcapi "db,eth,net,web3,personal" --gasprice 0 --dev --dev.period 1 console 2> 1.log
啓動的目錄很關鍵,後面要用到,其目錄下會有data目錄,私鑰就存放在其中的一個子目錄下。

2 自動化生成測試代碼

下載自動化測試代碼框架,這個是基於go語言編寫的,目前尚在不斷完善中!

cd $GOPATH/src

git clone https://github.com/yekai1003/gosol

進入到目錄,能夠進行測試

cd gosol

在sol目錄下有一個示例智能合約,一個銀行存取款業務。

pragma solidity^0.5.0;

contract pdbank {
    address public  owner;
    mapping(address=>uint256) public balances;
    uint256 public totalAmount;
    string public bankName;
    //構造函數
    constructor(string memory _bankName) public  {
        owner = msg.sender;
        bankName = _bankName;
    }
    //充值
    function deposit() public payable {
        totalAmount += msg.value;
        balances[msg.sender] += msg.value;
    }
    //提現
    function withdraw(uint256 _amount) public payable {
        if(balances[msg.sender] > _amount) {
            balances[msg.sender]  -=  _amount;  
            msg.sender.transfer(_amount);
            totalAmount -= _amount;
        }
    }
}

2.1 編譯合約代碼

本框架能夠自動測試合約代碼是否有效,集編譯、部署、功能測試於一體。

編譯本工程

go build -i
mkdir build

templates/templates.toml這個文件是最初的配置文件

[common]
connstr = "http://localhost:8545"  #以太坊地址
keydir = "/Users/yekai/eth/data/keystore"  #私鑰所在目錄
contractaddr = "0xe98a031548fc8e8580e1d2d67637045a82b5250c" #合約地址,部署後拿到
buildpath = "build" #合約地址,部署後拿到
Codepath  =  "callsol.go"  #生成目標代碼路徑
TestCodepath  =  "testFunc.go" #生成調用時的目標代碼路徑
TestConfigpath  =  "config.toml" #生成調用時的目標代碼路徑


[Deploy]
contractname =  "Pdbank"  #部署合約函數,合約編譯成go語言後,能夠獲得
fromaddr  =  "0x70c53a4c94ccce9ce56effbfcb89b221f986cd41" #部署用的帳戶地址,須要消耗gas
pass  = "123"  #帳戶地址對應的密碼
AbiFile =  "contracts/pdbank.abi"  #編譯後ABI文件所在路徑

其中鏈接地址默認私鏈能夠沒必要改動,keydir是表明私鑰存在路徑,這個須要修改成本身本機中的位置,還記得geth的啓動目錄吧,在那裏能夠找到。
AbiFile這個文件是在編譯合約後獲得的,因此編譯以後能夠修改此處!

2.2 生成目標測試代碼

編譯合約代碼

localhost:gosol yekai$ ./gosol comp
templates init ok
[pdbank.sol] <nil>
pdbank.sol
/usr/local/bin/abigen
run complie go ok!! <nil>
run BuildAbi ok!! <nil>

此後能夠在contracts看到2個文件

localhost:gosol yekai$ ls contracts/
pdbank.abi  pdbank.go

若是合約名字不同,能夠修改一下以前的配置文件地方,對abi文件進行替換。

上面只是完成了第一步,編譯代碼,接着須要生成自動化的測試代碼。

localhost:gosol yekai$ ./gosol build
templates init ok
deploy config begin......
deploy config ok......
ImplRunCode() begin
ImplRunCode() end

能夠在build目錄獲得目標的代碼,進入到build目錄,能夠進行合約代碼測試工做了。

cd build 
go build -i

能夠查看一下命令幫助

localhost:build yekai$ ./build 
call build config.init
call build config.init ok
1 - help   :./build  1
2 - deploy  :./build  2
3 - test totalAmount:./build  3
4 - test bankName:./build  4
5 - test balances:./build  5
6 - test withdraw:./build  6
7 - test owner:./build  7
8 - test deposit:./build  8

以前的合約一共有這麼多個函數,因此自動化生成這些測試命令,須要先確認一下配置文件config.toml,這裏面的fromaddr和pass是部署合約使用,必須是正確的。

[common]
connstr = "http://localhost:8545"         #以太坊鏈接地址
keydir = "/Users/yekai/eth/data/keystore"           #以太坊私鑰目錄
ContractAddr = "0xe98a031548fc8e8580e1d2d67637045a82b5250c"  #合約地址,部署後獲得
Buildpath  =  "build"   #編譯目標目錄,默認爲build
Codepath  =  "callsol.go"     #編譯後的代碼文件名
TestCodepath  =  "testFunc.go"  #自動生成的測試用代碼文件名 
TestConfigpath  =  "config.toml" #自動生成的配置文件名

[Deploy]
func =  "DeployPdbank"  #部署函數入口
fromaddr  =  "0x70c53a4c94ccce9ce56effbfcb89b221f986cd41"   #部署用帳戶
pass  = "123"            #部署帳戶密碼
TestAddr = "0x70c53a4c94ccce9ce56effbfcb89b221f986cd41"     #測試用帳戶
TestPass = "123"     #測試用帳戶密碼

部署合約試試,能夠獲得合約地址和收據hash

localhost:build yekai$ ./build 2
call build config.init
call build config.init ok
0 0x70a4124d3fa01c05c608ae001f135eae06d500295a6907cde74563a2eeba5e0a 36
0xf375DB17BD4CFF8ff9E16D6665DbF75dED3CB567

合約地址拿到,別忘了去修改配置文件的信息,TestAddr與TestPass也能夠一塊兒設置下,不然後面測試的帳戶是空的

查看一下銀行的名稱:能夠看到yekai

localhost:build yekai$ ./build 4
call build config.init
call build config.init ok
yekai <nil>

充值試試,這個代碼callsol.go須要改一下 ,由於默認充值金額爲0.

func CallDeposit(addr, pass string) (*types.Transaction, error) {

    instance, err := contracts.NewPdbank(common.HexToAddress(Config.Common.ContractAddr), testclient)
    if err != nil {
        fmt.Println("failed to get contract instance", err)
        return nil, err
    }
    auth, err := MakeAuth(addr, pass)
    if err != nil {
        fmt.Println("failed to makeAuth", err)
        return nil, err
    }
    auth.Value = big.NewInt(100010)
    ts,err := instance.Deposit(auth)
    if err != nil {
        fmt.Println("failed to call ", err)
        return nil, err
    }
    fmt.Println(ts.ChainId(), ts.Hash().Hex(), ts.Nonce())
    return ts , err
}

再從新編譯一下,調用充值Deposit

go build -i

localhost:build yekai$ ./build 8
call build config.init
call build config.init ok
0 0x3083d6000959762c4c8911e4aaca8de9f8700140dd115ca96b1233d7bccd399d 38
localhost:build yekai$ ./build 5
call build config.init
call build config.init ok
100010 <nil>

能夠看到充值和餘額查看都ok!
本文先到此結束,後續將爲您介紹這個框架是如何開發的!



相關文章
相關標籤/搜索