Truffle 智能合约开发

智能合约

开发工具

  • 下载Atom

    • CTRL+,打开配置管理
    • 安装插件 linter-solium autocomplete-solidity linter-solidity
  • 在线工具Remix

image

Truffle 智能合约开发

安装

$ npm install -g ethereumjs-testrpc truffle

启动

$ testrpc
EthereumJS TestRPC v6.0.3 (ganache-core: 2.0.2)

Available Accounts
==================
(0) 0x4927ee940390ea04396cdf45f8738efe34bc8cda
(1) 0x620f6185921c5098484fff59de44660408949da0
(2) 0x0948dc8f299e11947763ac5261fbec839bbe71fd
(3) 0xfbc433617f8eaba563adf82741d0b1083c787e31
(4) 0x33c095e2e0fdcf75d7657132f557ca68426e6e11
(5) 0x3596f5f81ac005c2ab6f4c0656bd2a0f4580af6a
(6) 0x98fb51da126450a6df0238addc4c3afc90c6e72d
(7) 0xe3c6e8378165725dc40539eb062b177daf48f843
(8) 0xfa28789a1f301d0b8d13e38d150ca84c05e834f9
(9) 0x43c86685df60442e0c4763c41fc1c2aa42e31437

Private Keys
==================
(0) 13e84c6f2264596a555ecf50c075cad011f70ded50dd751e9fea8586e8c36316
(1) be172cbc48294823ab38d263b6d846599a3c70269595e3ff9595f1463a3292fd
(2) a8b1010b89669e654bfe3d00373410290f6eec85bf81ef915c870fd2be35aa43
(3) 5aebf98da3414310ec1cc16327f5d073e0117e0b2018e64640d5c7c25996a6f0
(4) 5e6482bc2c1811fc113fc45979f2300807d1708a0e4f2a003bf6e0c20439b987
(5) 040311fcee969480e217b77d4d49ea0afe2e2c6a32a457e05dad34c54d090cc0
(6) b7cffb5c534a3021fc4155b81e5b45139a5b4885c04e96213c4ad797a202af6c
(7) 92db051b72d1901cdf386daa35f54ad9ae762f471133d4d0682d903b0af9d60d
(8) 0d54ef7d404b6b876237638bb422028be2113a171e3d4630965b34fab5e8acfc
(9) 7252563b853e3b3bf6c5d9cf819d8fb035b90a7769f86e2629d7dbd5ea0f8775

HD Wallet
==================
Mnemonic:      home survey unfair twenty tumble shaft verb income cigar harvest warm flash
Base HD Path:  m/44'/60'/0'/0/{account_index}

Listening on localhost:8545

初始化工程

wangxinguo@EF-WANGXINGUO MINGW64 /d/DApp/truffle
$ mkdir HelloWorld

wangxinguo@EF-WANGXINGUO MINGW64 /d/DApp/truffle
$ cd HelloWorld/

wangxinguo@EF-WANGXINGUO MINGW64 /d/DApp/truffle/HelloWorld
$ truffle init
Downloading...
Unpacking...
Setting up...
Unbox successful. Sweet!

Commands:

  Compile:        truffle compile
  Migrate:        truffle migrate
  Test contracts: truffle test

wangxinguo@EF-WANGXINGUO MINGW64 /d/DApp/truffle/HelloWorld
$ ll
total 2
drwxr-xr-x 1 wangxinguo 1049089   0 七月  5 16:11 build/
drwxr-xr-x 1 wangxinguo 1049089   0 七月  5 16:06 contracts/
drwxr-xr-x 1 wangxinguo 1049089   0 七月  5 16:36 migrations/
drwxr-xr-x 1 wangxinguo 1049089   0 七月  5 16:01 test/
-rw-r--r-- 1 wangxinguo 1049089 584 七月  5 16:21 truffle.js
-rw-r--r-- 1 wangxinguo 1049089 545 七月  5 16:01 truffle-config.js

image

编写合约

HelloWorld.sol

pragma solidity ^0.4.4;

contract HelloWorld {

  function sayHello() returns (string) {
    return "Hello world";
  }
}

编译

生成build文件

$ truffle compile

部署合约

修改migrations\2_deploy_contracts.js

var HelloWorld = artifacts.require("HelloWorld");

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

部署

wangxinguo@EF-WANGXINGUO MINGW64 /d/DApp/truffle/HelloWorld
$ truffle migrate
Error: No network specified. Cannot determine current network.

wangxinguo@EF-WANGXINGUO MINGW64 /d/DApp/truffle/HelloWorld
$ truffle migrate
Using network 'development'.

Running migration: 1_initial_migration.js
  Deploying Migrations...
  ... 0xad0e3a65ff378250602d006be234a5f77ef649cdf62d71bacde32f71b15b7531
  Migrations: 0xf848fb353a350a2e2c4580c64b3b476938d3a985
Saving successful migration to network...
  ... 0x49f3fab0213571cd7cab493b25f749693ef4d072be305f7f897b0a698e85e6cf
Saving artifacts...
Running migration: 2_deploy_contracts.js
  Deploying HelloWorld...
  ... 0x45cafe53dd0012cf62f976d37790623090cfb2fc29a186ea76641a3e5e745250
  HelloWorld: 0x1c2cfd8c56972d7c551d6bd495a03824c2589194
Saving successful migration to network...
  ... 0xf0914d6cae838858c02bf1c6368ca083d5500fbfcb7b5f1cb10f9eb891945b36
Saving artifacts...

部署失败,需要修改文件truffle.js

module.exports = {
    networks: {
        development: {
            host: "localhost",
            port: 8545,
            network_id: "*" // 匹配任何network id
         }
    }
};

获取合约对象

$ truffle console
truffle(development)> let contract
undefined
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],
        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: 'HelloWorld',
        abi: [Array],
        bytecode: '0x608060405234801561001057600080fd5b5061013f806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063ef5fb05b14610046575b600080fd5b34801561005257600080fd5b5061005b6100d6565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561009b578082015181840152602081019050610080565b50505050905090810190601f1680156100c85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60606040805190810160405280600b81526020017f48656c6c6f20776f726c640000000000000000000000000000000000000000008152509050905600a165627a7a72305820d540aaa7d3d21783829ff5aef0e77b259d6341917f26fec070513a1f3a5a6e140029',
        deployedBytecode: '0x608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063ef5fb05b14610046575b600080fd5b34801561005257600080fd5b5061005b6100d6565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561009b578082015181840152602081019050610080565b50505050905090810190601f1680156100c85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60606040805190810160405280600b81526020017f48656c6c6f20776f726c640000000000000000000000000000000000000000008152509050905600a165627a7a72305820d540aaa7d3d21783829ff5aef0e77b259d6341917f26fec070513a1f3a5a6e140029',
        sourceMap: '27:100:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;27:100:0;;;;;;;',
        deployedSourceMap: '27:100:0:-;;;;;;;;;;;;;;;;;;;;;;;;54:70;;8:9:-1;5:2;;;30:1;27;20:12;5:2;54:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;54:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83:6;98:20;;;;;;;;;;;;;;;;;;;;54:70;:::o',
        source: 'pragma solidity ^0.4.4;\r\n\r\ncontract HelloWorld {\r\n\r\n  function sayHello() returns (string) {\r\n    return "Hello world";\r\n  }\r\n}\r\n',
        sourcePath: 'D:\\DApp\\truffle\\HelloWorld\\contracts\\HelloWorld.sol',
        ast: [Object],
        legacyAST: [Object],
        compiler: [Object],
        networks: [Object],
        schemaVersion: '2.0.1',
        updatedAt: '2018-07-05T08:39:07.157Z' },
     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: '0x4927ee940390ea04396cdf45f8738efe34bc8cda',
        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: '1530777346103' },
  abi:
   [ { constant: false,
       inputs: [],
       name: 'sayHello',
       outputs: [Array],
       payable: false,
       stateMutability: 'nonpayable',
       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: '0x1c2cfd8c56972d7c551d6bd495a03824c2589194',
     abi: [ [Object] ],
     sayHello:
      { [Function: bound ]
        request: [Function: bound ],
        call: [Function: bound ],
        sendTransaction: [Function: bound ],
        estimateGas: [Function: bound ],
        getData: [Function: bound ],
        '': [Circular] },
     allEvents: [Function: bound ] },
  sayHello:
   { [Function]
     call: [Function],
     sendTransaction: [Function],
     request: [Function: bound ],
     estimateGas: [Function] },
  sendTransaction: [Function],
  send: [Function],
  allEvents: [Function: bound ],
  address: '0x1c2cfd8c56972d7c551d6bd495a03824c2589194',
  transactionHash: null }

调用合约

call只是本地调用,只读

truffle(development)> contract.sayHello.call()
'Hello world'

需要花费gas

truffle(development)> contract.sayHello()
{ tx: '0xbcdd3d18e262b4c5703b15ba6695280e87c29150995ae9dcbe36b257065e0f22',
  receipt:
   { transactionHash: '0xbcdd3d18e262b4c5703b15ba6695280e87c29150995ae9dcbe36b257065e0f22',
     transactionIndex: 0,
     blockHash: '0xaa7fbd9c93dfa295e295e01e6d1cd8359a7a004ad13d65459848fea2c1f785fa',
     blockNumber: 7,
     gasUsed: 21877,
     cumulativeGasUsed: 21877,
     contractAddress: null,
     logs: [],
     status: 1 },
  logs: [] }

修改合约

增加方法 echo

// constant 方法只读,默认执行call方法,不需要花费gas
  function echo(string name) constant returns (string) {
    return name;
  }

重新编译、部署、运行

$ truffle compile

$ truffle migrate --reset

truffle(development)> contract.echo("区块链")
'区块链'

直接启动

$ truffle develop

// 编译
truffle(develop)> complile

// 部署
truffle(develop)> migrate
Using network 'develop'.

// 运行
truffle(development)> let contract
undefined
truffle(development)> HelloWorld.deployed().then(instance => contract = instance)

// 调用
truffle(development)> contract.sayHello.call()
'Hello world'

猜你喜欢

转载自blog.csdn.net/weixin_37195606/article/details/81234655