【以太坊开发】Truffle框架实战(二)

一、创建项目根目录

mkdir -p /home/simon/project/ColorBayDemo
cd /home/simon/project/ColorBayDemo

二、项目初始化

truffle init

三、创建智能合约

在根目录下的contracts文件夹下新建一文件ColorBay.sol,代码如下:

pragma solidity ^0.4.17;

contract ColorBay {
    function calculate(uint a, uint b) public pure returns (uint) { #计算a与b的乘积
        return a * b;
    }
}

注意:public修饰符应该写在任何自定义修饰符前;pure修饰器表示不需要去获取我们的状态变量

四、编译合约

truffle develop
#省略显示账号列表信息
> compile
Compiling ./contracts/ColorBay.sol...
Compiling ./contracts/Migrations.sol...
Writing artifacts to ./build/contracts

五、合约单元测试

打开官方开发文档 http://truffleframework.com/docs/getting_started/solidity-tests,将EXAMPLE栏的代码复制到新建文件TestColorBay.sol中,并修改成如下:

pragma solidity ^0.4.17;

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/ColorBay.sol";

contract TestColorBay {
  function testCalculateIsRight() {
    ColorBay colorbay = ColorBay(DeployedAddresses.ColorBay());
    Assert.equal(colorbay.calculate(3, 4), 12, "3 * 4 should be 12"); #如果要测试返回失败时的效果,将12改成任意错误数字,如120
  }

}

执行测试命令:

> test
# 返回成功时的效果:
Using network 'develop'.

Compiling ./contracts/ColorBay.sol...
Compiling ./test/TestColorBay.sol...
Compiling truffle/Assert.sol...
Compiling truffle/DeployedAddresses.sol...
#省略中间警告信息
TestColorBay
    ✓ testCalculateIsRight (146ms)

  1 passing (1s)

如果要测试返回失败时的效果,将TestColorBay.sol中一行Assert.equal(colorbay.calculate(3, 4), 12, "3 * 4 should be 12");修改成Assert.equal(colorbay.calculate(3, 4), 120, "3 * 4 should be 12");,在控制台中再次执行test命令,返回信息如下:

# 返回失败时的效果:
Using network 'develop'.

Compiling ./contracts/ColorBay.sol...
Compiling ./test/TestColorBay.sol...
Compiling truffle/Assert.sol...
Compiling truffle/DeployedAddresses.sol...
#省略中间警告信息
TestColorBay
    1) testCalculateIsRight

    Events emitted during test:
    ---------------------------

    TestEvent(result: , message: 3 * 4 should be 12 (Tested: 12, Against: 120))

    ---------------------------


  0 passing (950ms)
  1 failing

  1) TestColorBay testCalculateIsRight:
     Error: 3 * 4 should be 12 (Tested: 12, Against: 120)
      at /usr/lib/node_modules/truffle/build/webpack:/~/truffle-core/lib/testing/soliditytest.js:61:1
      at Array.forEach (native)
      at processResult (/usr/lib/node_modules/truffle/build/webpack:/~/truffle-core/lib/testing/soliditytest.js:59:1)
      at process._tickDomainCallback (internal/process/next_tick.js:135:7)


1

六、新建发布脚本

在项目根目录下的文件夹migrations下,新建文件2_deploy_colorbay.js, 编写如下代码:

var ColorBay = artifacts.require("./ColorBay.sol");

module.exports = function(deployer) {
  deployer.deploy(ColorBay); #注意,如果合约的构造函数需要传递参数,从第二个位置开始增加参数
};

七、移植部署合约

> migrate #如果需要重新移植,加--reset选项
Using network 'develop'.

Running migration: 1_initial_migration.js
  Deploying Migrations...
  ... 0xcae8151fa504661038bcc80ee6f80e3ebc5aa55cb91f7b809d0ef084958ffa4f
  Migrations: 0x2a504b5e7ec284aca5b6f49716611237239f0b97
Saving successful migration to network...
  ... 0xad16ddf12b1be2f43938221b5fd7dfa05dae1c6da09776f16f25b2e4a7f4cedc
Saving artifacts...
Running migration: 2_deploy_colorbay.js
  Deploying ColorBay...
  ... 0x5302dfc1537dfe40b1df44a873810f27b4c9f5692c55d46a14127ef1b645f980
  ColorBay: 0x2eca6fcfef74e2c8d03fbaf0ff6712314c9bd58b #此处为合约地址
Saving successful migration to network...
  ... 0x05d263b8571d786abcca55bf0248d2b0185697ae076b19bf3403015a7ada9f6b
Saving artifacts...

八、测试合约部署是否成功

truffle(develop)> web3.eth.getCode('0x2eca6fcfef74e2c8d03fbaf0ff6712314c9bd58b');
'0x606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638dfa4363146044575b600080fd5b3415604e57600080fd5b606b60048080359060200190919080359060200190919050506081565b6040518082815260200191505060405180910390f35b60008183029050929150505600a165627a7a72305820d9c655b8112892366b8577e059f3210d2aaef10bb3e8038f15861c4de2628f4f0029'

将返回的合约字节码与项目根目录下build/contracts/ColorBay.json中的键bytecode的值对比,如果一致,说明合约部署成功!

九、调用合约

> var colorbay;
undefined
> colorbay = ColorBay.deployed().then(instance => colorbay = instance); #创建一个ColorBay合约实例colorbay
#返回信息如下:
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],
        transactionHash: [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],
        legacyAST: [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: 'ColorBay',
        abi: [Object],
        bytecode: '0x6060604052341561000f57600080fd5b60ba8061001d6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638dfa4363146044575b600080fd5b3415604e57600080fd5b606b60048080359060200190919080359060200190919050506081565b6040518082815260200191505060405180910390f35b60008183029050929150505600a165627a7a72305820d9c655b8112892366b8577e059f3210d2aaef10bb3e8038f15861c4de2628f4f0029',
        deployedBytecode: '0x606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638dfa4363146044575b600080fd5b3415604e57600080fd5b606b60048080359060200190919080359060200190919050506081565b6040518082815260200191505060405180910390f35b60008183029050929150505600a165627a7a72305820d9c655b8112892366b8577e059f3210d2aaef10bb3e8038f15861c4de2628f4f0029',
        sourceMap: '28:121:0:-;;;;;;;;;;;;;;;;;',
        deployedSourceMap: '28:121:0:-;;;;;;;;;;;;;;;;;;;;;;;;53:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;109:4;137:1;133;:5;126:12;;53:93;;;;:::o',
        source: 'pragma solidity ^0.4.17;\r\n\r\ncontract ColorBay {\r\n    function calculate(uint a, uint b) public pure returns (uint) {\r\n        return a * b;\r\n    }\r\n}\r\n',
        sourcePath: '/home/simon/project/ColorBayDemo/contracts/ColorBay.sol',
        ast: [Object],
        legacyAST: [Object],
        compiler: [Object],
        networks: [Object],
        schemaVersion: '2.0.0',
        updatedAt: '2018-04-16T15:09:48.351Z' },
     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: '0x627306090abab3a6e1400e9345bc60c78a8bef57',
        gas: 6721975,
        gasPrice: 100000000000 },
     currentProvider: 
      HttpProvider {
        host: 'http://127.0.0.1:9545/',
        timeout: 0,
        user: undefined,
        password: undefined,
        headers: undefined,
        send: [Function],
        sendAsync: [Function],
        _alreadyWrapped: true },
     network_id: '4447' },
  abi: 
   [ { constant: true,
       inputs: [Object],
       name: 'calculate',
       outputs: [Object],
       payable: false,
       stateMutability: 'pure',
       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: '0x2eca6fcfef74e2c8d03fbaf0ff6712314c9bd58b',
     abi: [ [Object] ],
     calculate: 
      { [Function: bound ]
        request: [Function: bound ],
        call: [Function: bound ],
        sendTransaction: [Function: bound ],
        estimateGas: [Function: bound ],
        getData: [Function: bound ],
        'uint256,uint256': [Circular] },
     allEvents: [Function: bound ] },
  calculate: 
   { [Function]
     call: [Function],
     sendTransaction: [Function],
     request: [Function: bound ],
     estimateGas: [Function] },
  sendTransaction: [Function],
  send: [Function],
  allEvents: [Function: bound ],
  address: '0x2eca6fcfef74e2c8d03fbaf0ff6712314c9bd58b',
  transactionHash: null }

> colorbay.calculate(3, 4); #调用合约方法
{ [String: '12'] s: 1, e: 1, c: [ 12 ] }

十、总结

与上一篇文章《【以太坊开发】Truffle框架实战(一)》相比,本篇是直接在truffle控制台中操作,省去了第五步配置测试网络一节。在开发过程中,需要熟练掌握以上流程并快速排查出错误。

你可能感兴趣的:(【以太坊开发】Truffle框架实战(二))