Solidity的Truffle框架實戰

FLy_鵬程萬里發表於2018-07-14

前置工作:

1. 建立工程目錄

在你想放工程的任何位置,建立一個資料夾truffleTest,來做為你的工程根目錄。

$ mkdir -p /Users/admin/develop/blockchain_workspace/truffleTest

2. 初始化框架

進入到工程根目錄下(現在應該是個空目錄),並執行下述命令。

$ cd /Users/admin/develop/blockchain_workspace/truffleTest
$ truffle init

正確執行後,我們將得到下面這樣的目錄結構:


目錄結構簡單說明如下:

  • app/ - 你的應用檔案執行的預設目錄。這裡麵包括推薦的javascript檔案和css樣式檔案目錄,但你可以完全決定如何使用這些目錄。
  • contract/ - Truffle預設的合約檔案存放地址。
  • migrations/ - 存放釋出指令碼檔案
  • test/ - 用來測試應用和合約的測試檔案
  • truffle.js - Truffle的配置檔案

相關詳細說明,詳見:初始化Truffle

3.放入自己的合約

刪除./contract目錄下的自帶demo合約,切記不要刪除./contract/Migrations.sol合約,它是Truffle用來幫助部署的。

$ cd /Users/admin/develop/blockchain_workspace/truffleTest/contracts

$ rm ConvertLib.sol MetaCoin.sol

./contract目錄下建立一個自己的合約檔案Greeter.sol

pragma solidity ^0.4.0;

contract Greeter         
{
    address creator;     
    string greeting;     

    function Greeter(string _greeting) public   
    {
        creator = msg.sender;
        greeting = _greeting;
    }

    function greet() constant returns (string)          
    {
        return greeting;
    }
    
    function setGreeting(string _newgreeting) 
    {
        greeting = _newgreeting;
    }
    
     /**********
     Standard kill() function to recover funds 
     **********/
    
    function kill()
    { 
        if (msg.sender == creator)
            suicide(creator);  // kills this contract and sends remaining funds back to creator
    }

}

程式碼來自fiveDogIt的一段入門程式碼05_greeter.sol

4. 修改釋出指令碼

./migrations/2_deploy_contracts.js下的內容由:

module.exports = function(deployer) {
  deployer.deploy(ConvertLib);
  deployer.autolink();
  deployer.deploy(MetaCoin);
};

修改為:

module.exports = function(deployer) {
  deployer.deploy(Greeter);
};

目的是去掉原有自帶的Demo部署流程,修改為要部署的合約。修改完後,記得儲存,不然釋出時會報錯,找不到相關合約。詳細釋出流程參考:部署(migrate)

5. 編譯

進入到工程根目錄./truffleTest目錄下,進行編譯:

$ truffle compile
Compiling Greeter.sol...

Writing artifacts to ./build/contracts

6. 啟動你的客戶端

啟動之前安裝好的EthereumJS RPC客戶端。

$ testrpc

EthereumJS TestRPC v3.0.3

Available Accounts
==================

Private Keys
==================

HD Wallet
==================
Mnemonic:      degree debate income mask fiber issue album diet unfair police race car
Base HD Path:  m/44'/60'/0'/0/{account_index}

Listening on localhost:8545

7. 部署合約(migrate)

部署合約到網路上:

$ truffle migrate
Running migration: 2_deploy_contracts.js
  Deploying Greeter...
  Greeter: 0xe66038995cf64b14da96d26cbe1c96d30dec0e95
Saving successful migration to network...
Saving artifacts...

備註

  • 如果報錯出現了一些你之前編譯部署過,但你已經不需要的合約,可以用truffle migrate --reset來重置部署,但可能根據情況,你需要更新移植版本號,來管理不同的版本,詳見部署(migrate)

  • 若誤刪Truffle自帶用來部署的合約./contracts/Migrations.sol,會出現下述報錯,需要補回到./contract目錄,重初始化一次得到。

$ truffle migrate
Running migration: 1_initial_migration.js
/Users/admin/develop/blockchain_workspace/truffleTest/migrations/1_initial_migration.js:2
  deployer.deploy(Migrations);
                  ^

ReferenceError: Migrations is not defined
    at module.exports (/Users/admin/develop/blockchain_workspace/truffleTest/migrations/1_initial_migration.js:2:19)
    at /usr/local/lib/node_modules/truffle/lib/migrate.js:109:7
    at /usr/local/lib/node_modules/truffle/lib/require.js:82:7
    at tryToString (fs.js:425:3)
    at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:412:12)

8. 看一下效果

我們使用truffle console功能在控制檯與合約互動,來看下效果。

$ truffle console
truffle(default)> Greeter.deployed().setGreeting("Hello world!");
'0xf6a00b4466c9ab38d7eb60dc9f8d15f5f1e500e24ea91bd9e28f6233bad08aed'
truffle(default)> Greeter.deployed().greet.call();
'Hello world!'
truffle(default)>
  • 在console中為簡單需要,與使用直接使用程式碼方式在返回結果處理上有一點點差異,參見控制檯
  • 要直接使用程式碼與合約互動,參見合約互動
  • 控制檯內,可以通過宣告變數來減少輸入的內容,比如var g = Greeter.deployed();g.greet();。更多詳見控制檯

常見報錯

  • 以太坊客戶端連線配置不正確,或未正常啟動時。
$ truffle console
/usr/local/lib/node_modules/truffle/lib/repl.js:25
    if (err) return done(err);
                    ^

ReferenceError: done is not defined
    at /usr/local/lib/node_modules/truffle/lib/repl.js:25:21
    at /usr/local/lib/node_modules/truffle/lib/repl.js:57:21
    at /usr/local/lib/node_modules/truffle/lib/contracts.js:46:25
    at /usr/local/lib/node_modules/truffle/node_modules/web3/lib/web3/property.js:119:13
    at /usr/local/lib/node_modules/truffle/node_modules/web3/lib/web3/requestmanager.js:82:20
    at exports.XMLHttpRequest.request.onreadystatechange (/usr/local/lib/node_modules/truffle/node_modules/web3/lib/web3/httppro
vider.js:114:13)
    at exports.XMLHttpRequest.dispatchEvent (/usr/local/lib/node_modules/truffle/node_modules/xmlhttprequest/lib/XMLHttpRequest.
js:591:25)
    at setState (/usr/local/lib/node_modules/truffle/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:610:14)
    at exports.XMLHttpRequest.handleError (/usr/local/lib/node_modules/truffle/node_modules/xmlhttprequest/lib/XMLHttpRequest.js
:532:5)
    at ClientRequest.errorHandler (/usr/local/lib/node_modules/truffle/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:459:14)
    at emitOne (events.js:96:13)
    at ClientRequest.emit (events.js:188:7)
    at Socket.socketErrorListener (_http_client.js:309:9)
    at emitOne (events.js:96:13)
    at Socket.emit (events.js:188:7)
    at emitErrorNT (net.js:1281:8)
  • 若合約未進行部署就進行呼叫,可能出現下述報錯:
truffle(default)> Greeter.deployed().setGreeting("Hello world!");
Error: Cannot find deployed address: Greeter not deployed or address not set.
    at Function.Contract.deployed (/Users/admin/develop/blockchain_workspace/truffleTest/build/contracts/Greeter.sol.js:311:1
3)
    at evalmachine.<anonymous>:1:-53

    at ContextifyScript.Script.runInContext (vm.js:37:29)
    at Object.exports.runInContext (vm.js:69:17)
    at TruffleInterpreter.interpret (/usr/local/lib/node_modules/truffle/lib/repl.js:99:17)
    at bound (domain.js:280:14)
    at REPLServer.runBound [as eval] (domain.js:293:12)
    at REPLServer.onLine (repl.js:513:10)
    at emitOne (events.js:96:13)
    at REPLServer.emit (events.js:188:7)
  • 部署時填合約名稱有誤,本應該寫為deployer.deploy(IntegerLiteral);,卻寫成了deployer.deploy("IntegerLiteral");
  Deploying undefined...
Error encountered, bailing. Network state unknown. Review successful transactions manually.
TypeError: Cannot read property 'apply' of undefined
    at /usr/local/lib/node_modules/truffle/lib/deployer.js:62:28
    at process._tickDomainCallback (internal/process/next_tick.js:129:7)

相關文章