close

以下運行裝置為 MAC

testrpc是模擬區塊鏈的工具,一開始運行的預設值會給予10組私鑰

truffle是智能合約的開發框架,其指令包含了編譯智能合約,以及將智能合約部署到區塊鏈上,每變動一次智能合約,都必須重新編譯,並且重新部署。

智能合約所使用的語言是solidity,Ethereum上的智能合約需要使用solidity1語言來撰寫。雖然還有其他能用來撰寫智能合約的語言如Serpent(類Python)、lll(類Fortran),目前看到所有公開的智能合約都是使用solidity撰寫。solidity是一種類似Javascript的語言,而且圍繞著solidity的各種開發工具鏈,都是使用屬於Javascript生態系的npm來提供的。 因為和Javascript不同,solidity與Java或C#同屬於強型別(Strong Type,在定義變數時需要指定型別)語言、在定義函式(function)時同樣需指定回傳的型別(type)、同樣也需要先編譯才能執行。這些特性都是Javascript所不具備的。

可在sublime 安裝solidity插件,即可用sublime使用solidity:

1.

command + shift + p,在進入install package

螢幕快照 2018-02-25 上午1.11.41  

再輸入ethereum,即可安裝solidity插件

螢幕快照 2018-02-25 上午1.15.00  

回到sublime切換至solidity語言

view  -> syntax -> solidity

(一)準備工具

首先在MAC上必須裝好Node.js,再使用以下命令安裝所需的工具:

1.安裝testrpc

$ npm install -g ethereumjs-testrpc truffle

以終端機啟動testrpc

螢幕快照 2018-02-25 上午12.29.39  

再開啟新的終端機畫面

2.建立專案

在終端機輸入指令

$mkdir SmartContractDemo  //建立SmartContractDemo根資料夾

$cd SmartContractDemo      //進入SmartContractDemo

$mkdir HelloWorld              //建立HelloWorld子資料夾

$cd HelloWorld                  //進入HelloWorld

$truffle init                       //建立專案

接著會出現以下畫面

螢幕快照 2018-02-25 上午1.00.33  

建立成功後,可到資料夾查看,contracts資料夾至少有兩個.sol檔案

螢幕快照 2018-02-25 上午1.02.55  

建立智能合約

螢幕快照 2018-02-25 上午1.07.44  

範例合約內容如下

pragma solidity ^0.4.4;

contract HelloWorld {
function sayHello() returns (string) {
return ("Hello World");
}

可到sublime撰寫,並以sol檔案儲存在contracts資料夾,檔名為HelloWorld.sol

再回到終端機指令,編譯智能合約

chenjunongdeMBP:HelloWorld erinchen$ truffle compile

Compiling ./contracts/HelloWorld.sol...

 

Compilation warnings encountered:

 

/Users/erinchen/SmartContractDemo/HelloWorld/contracts/HelloWorld.sol:4:3: Warning: No visibility specified. Defaulting to "public".

  function sayHello() returns (string) {

  ^

Spanning multiple lines.

,/Users/erinchen/SmartContractDemo/HelloWorld/contracts/HelloWorld.sol:8:3: Warning: No visibility specified. Defaulting to "public".

  function echo(string name) constant returns (string) {

  ^

Spanning multiple lines.

,/Users/erinchen/SmartContractDemo/HelloWorld/contracts/HelloWorld.sol:4:3: Warning: Function state mutability can be restricted to pure

  function sayHello() returns (string) {

  ^

Spanning multiple lines.

,/Users/erinchen/SmartContractDemo/HelloWorld/contracts/HelloWorld.sol:8:3: Warning: Function state mutability can be restricted to pure

  function echo(string name) constant returns (string) {

  ^

Spanning multiple lines.

 

Writing artifacts to ./build/contracts

 

 

2.部署合約

 

再來就是部署合約,打開migrations資料夾,用sublime打開2_deploy_contracts.js

在migrations裡的檔案,檔案名稱第一個必須是數字

螢幕快照 2018-02-25 上午1.29.48  

 

2_deploy_contracts.js內容為

var HelloWorld = artifacts.require("HelloWorld");
module.exports = function(deployer) {
deployer.deploy(HelloWorld);
};

存檔後再回到終端機輸入migrate指令

HelloWorld erinchen$ truffle migrate

Using network 'development'.

 

Running migration: 1_initial_migration.js

  Deploying HelloWorld...

  ... 0x9576f04f4fb6c97ad4e7cbc70c795cb4fbfacb54e19005249726c3dc286defdf

  HelloWorld: 0x2964dfe69eb87f04bddf1f832bf01c0ffdd481b6

Saving artifacts...

Running migration: 2_deploy_contracts.js

  Replacing HelloWorld...

  ... 0x8499f8ad9116f4664d264b364e01c6a114f191645f2b2677c7039af0a58c1bc6

  HelloWorld: 0xaf921755151aa154918fb31dc4c3c13c1b324dd9

Saving artifacts...

chenjunongdeMBP:HelloWorld erinchen$

 

切換到testrpc畫面可看到已經更新過

螢幕快照 2018-02-25 上午1.37.23  

 

執行truffle console 可以用JavaScript來和剛部署的合約互動

 

chenjunongdeMBP:HelloWorld erinchen$ truffle console

truffle(development)> HelloWorld.deployed().then(instance => contract = instance)

TruffleContract {

  constructor: 

   { [Function: TruffleContract]

     _static_methods: 

      { setProvider: [Function: setProvider],

        new: [Function: new],

        at: [Function: at],

        deployed: [Function: deployed],

        defaults: [Function: defaults],

        hasNetwork: [Function: hasNetwork],

        isDeployed: [Function: isDeployed],

        detectNetwork: [Function: detectNetwork],

        setNetwork: [Function: setNetwork],

        resetAddress: [Function: resetAddress],

        link: [Function: link],

        clone: [Function: clone],

        addProp: [Function: addProp],

        toJSON: [Function: toJSON] },

     _properties: 

      { contract_name: [Object],

        contractName: [Object],

        abi: [Object],

        network: [Function: network],

        networks: [Function: networks],

        address: [Object],

        links: [Function: links],

        events: [Function: events],

        binary: [Function: binary],

        deployedBinary: [Function: deployedBinary],

        unlinked_binary: [Object],

        bytecode: [Object],

        deployedBytecode: [Object],

        sourceMap: [Object],

        deployedSourceMap: [Object],

        source: [Object],

        sourcePath: [Object],

        ast: [Object],

        compiler: [Object],

        schema_version: [Function: schema_version],

        schemaVersion: [Function: schemaVersion],

        updated_at: [Function: updated_at],

        updatedAt: [Function: updatedAt] },

     _property_values: {},

     _json: 

      { contractName: 'HelloWorld',

        abi: [Object],

        bytecode: '0x6060604052341561000f57600080fd5b6102488061001e6000396000f30060606040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063ef5fb05b14610051578063f15da729146100df575b600080fd5b341561005c57600080fd5b6100646101b5565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100a4578082015181840152602081019050610089565b50505050905090810190601f1680156100d15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156100ea57600080fd5b61013a600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506101f8565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561017a57808201518184015260208101905061015f565b50505050905090810190601f1680156101a75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101bd610208565b6040805190810160405280600b81526020017f48656c6c6f20576f726c64000000000000000000000000000000000000000000815250905090565b610200610208565b819050919050565b6020604051908101604052806000815250905600a165627a7a723058206a318e67943d89d0ac46520096dce59c31e037a5081ef146cdf4f5dd4e2654be0029',

        deployedBytecode: '0x60606040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063ef5fb05b14610051578063f15da729146100df575b600080fd5b341561005c57600080fd5b6100646101b5565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100a4578082015181840152602081019050610089565b50505050905090810190601f1680156100d15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156100ea57600080fd5b61013a600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506101f8565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561017a57808201518184015260208101905061015f565b50505050905090810190601f1680156101a75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101bd610208565b6040805190810160405280600b81526020017f48656c6c6f20576f726c64000000000000000000000000000000000000000000815250905090565b610200610208565b819050919050565b6020604051908101604052806000815250905600a165627a7a723058206a318e67943d89d0ac46520096dce59c31e037a5081ef146cdf4f5dd4e2654be0029',

        sourceMap: '25:173:0:-;;;;;;;;;;;;;;;;;',

        deployedSourceMap: '25:173:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:2;8:100;;;99:1;94:3;90;84:5;80:1;75:3;71;64:6;52:2;49:1;45:3;40:15;;8:100;;;12:14;3:109;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;123:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:2;8:100;;;99:1;94:3;90;84:5;80:1;75:3;71;64:6;52:2;49:1;45:3;40:15;;8:100;;;12:14;3:109;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:70:0;78:6;;:::i;:::-;92:22;;;;;;;;;;;;;;;;;;;;49:70;:::o;123:73::-;168:6;;:::i;:::-;189:4;182:11;;123:73;;;:::o;25:173::-;;;;;;;;;;;;;;;:::o',

        source: 'pragma solidity ^0.4.4;\n\ncontract HelloWorld {\n  function sayHello() returns (string) {\n    return ("Hello World");\n  }\n\n  function echo(string name) constant returns (string) {\n    return name;\n}\n}\n',

        sourcePath: '/Users/erinchen/SmartContractDemo/HelloWorld/contracts/HelloWorld.sol',

        ast: [Object],

        compiler: [Object],

        networks: [Object],

        schemaVersion: '1.0.1',

        updatedAt: '2018-02-24T17:35:49.888Z' },

     setProvider: [Function: bound setProvider],

     new: [Function: bound new],

     at: [Function: bound at],

     deployed: [Function: bound deployed],

     defaults: [Function: bound defaults],

     hasNetwork: [Function: bound hasNetwork],

     isDeployed: [Function: bound isDeployed],

     detectNetwork: [Function: bound detectNetwork],

     setNetwork: [Function: bound setNetwork],

     resetAddress: [Function: bound resetAddress],

     link: [Function: bound link],

     clone: [Function: bound clone],

     addProp: [Function: bound addProp],

     toJSON: [Function: bound toJSON],

     web3: 

      Web3 {

        _requestManager: [Object],

        currentProvider: [Object],

        eth: [Object],

        db: [Object],

        shh: [Object],

        net: [Object],

        personal: [Object],

        bzz: [Object],

        settings: [Object],

        version: [Object],

        providers: [Object],

        _extend: [Object] },

     class_defaults: 

      { from: '0x01cb838698e4bd068fa8678777684e99d4e22f7c',

        gas: 6721975,

        gasPrice: 100000000000 },

     currentProvider: 

      HttpProvider {

        host: 'http://localhost:8545',

        timeout: 0,

        user: undefined,

        password: undefined,

        headers: undefined,

        send: [Function],

        sendAsync: [Function],

        _alreadyWrapped: true },

     network_id: '1519492998810' },

  abi: 

   [ { constant: false,

       inputs: [],

       name: 'sayHello',

       outputs: [Object],

       payable: false,

       stateMutability: 'nonpayable',

       type: 'function' },

     { constant: true,

       inputs: [Object],

       name: 'echo',

       outputs: [Object],

       payable: false,

       stateMutability: 'view',

       type: 'function' } ],

  contract: 

   Contract {

     _eth: 

      Eth {

        _requestManager: [Object],

        getBalance: [Object],

        getStorageAt: [Object],

        getCode: [Object],

        getBlock: [Object],

        getUncle: [Object],

        getCompilers: [Object],

        getBlockTransactionCount: [Object],

        getBlockUncleCount: [Object],

        getTransaction: [Object],

        getTransactionFromBlock: [Object],

        getTransactionReceipt: [Object],

        getTransactionCount: [Object],

        call: [Object],

        estimateGas: [Object],

        sendRawTransaction: [Object],

        signTransaction: [Object],

        sendTransaction: [Object],

        sign: [Object],

        compile: [Object],

        submitWork: [Object],

        getWork: [Object],

        coinbase: [Getter],

        getCoinbase: [Object],

        mining: [Getter],

        getMining: [Object],

        hashrate: [Getter],

        getHashrate: [Object],

        syncing: [Getter],

        getSyncing: [Object],

        gasPrice: [Getter],

        getGasPrice: [Object],

        accounts: [Getter],

        getAccounts: [Object],

        blockNumber: [Getter],

        getBlockNumber: [Object],

        protocolVersion: [Getter],

        getProtocolVersion: [Object],

        iban: [Object],

        sendIBANTransaction: [Function: bound transfer] },

     transactionHash: null,

     address: '0xaf921755151aa154918fb31dc4c3c13c1b324dd9',

     abi: [ [Object], [Object] ],

     sayHello: 

      { [Function: bound ]

        request: [Function: bound ],

        call: [Function: bound ],

        sendTransaction: [Function: bound ],

        estimateGas: [Function: bound ],

        getData: [Function: bound ],

        '': [Circular] },

     echo: 

      { [Function: bound ]

        request: [Function: bound ],

        call: [Function: bound ],

        sendTransaction: [Function: bound ],

        estimateGas: [Function: bound ],

        getData: [Function: bound ],

        string: [Circular] },

     allEvents: [Function: bound ] },

  sayHello: 

   { [Function]

     call: [Function],

     sendTransaction: [Function],

     request: [Function: bound ],

     estimateGas: [Function] },

  echo: 

   { [Function]

     call: [Function],

     sendTransaction: [Function],

     request: [Function: bound ],

     estimateGas: [Function] },

  sendTransaction: [Function],

  send: [Function],

  allEvents: [Function: bound ],

  address: '0xaf921755151aa154918fb31dc4c3c13c1b324dd9',

  transactionHash: null }

 

在合約中加入新方法,例如在HelloWorld.sol加入echo

 

function echo(string name) constant returns (string) {
return name;
}

存檔完,重新compile和migrate

$truffle console
truffle(development)> let contract
undefined
truffle(development)> HelloWorld.deployed().then(instance => contract = instance)
TruffleContract {
constructor:以下略過

echo方法將輸入的內容回傳了,同時宣告了constant,不需要使用call()方法,truffle會自動使用call來呼叫。

arrow
arrow
    全站熱搜

    Kimchi11 發表在 痞客邦 留言(0) 人氣()