web3 编译以太坊智能合约流程

简介

本文适合已经对以太坊有所了解,并自己动手做过一些测试的读者。
本文使用的代码来源于 http://blog.csdn.net/daichunkai123/article/details/78112640 ,但我在根据文章实践的过程中发现这篇文章中有一些坑,我将在本文中予以修正。

环境安装(也是本人测试使用环境)

  1. 安装并启动testrpc
npm install -g ethereumjs-testrpc@6.0.3  //安装

testrpc //启动

如果没有问题的话应该能看到如下启动结果

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

Available Accounts
==================
(0) 0xfdf80a012e7f10d37fec96a2a433873fa280e87f
(1) 0x5151266599202047bcefd9781e8a8a8106215a04
(2) 0xf1f1b589cc5c30c2c1201b068c03234350c965ee
(3) 0xeeddf154340918413342847b211ed7cdfd93b4ab
(4) 0xf424bd1614f8f0f1c373c9786ce8843f9ea876b1
(5) 0x495ed606355c6641db65b79d2141b2e5335b9152
(6) 0xb852b04ee986134dfb4d45c04e706191c9fad98a
(7) 0xa0f9447b3b3c185dcbb9233d87324ccb93fa63a5
(8) 0xed17431844db4397bf306cd7ae52bbf4205049c7
(9) 0x4319490601a39ab02115b857e97b4d387fbc8ebc

Private Keys
==================
(0) f6332a202237d5cd3ab933d6e14495bcf3cb3c27b60db49a1cddfe5233845322
(1) edd9e00b182bcd38e757695e1515846738974688013d5f4f8891b7735f75538e
(2) 33119eb84f9c4412e89d4808240eb9f984a96ddfe0d6c83da5b970071da59fbd
(3) 818cbe48dc54f2709eb5be6f0251ffad5816e83f6835ece6bb9b4cc7399e62b8
(4) 6ddc5d434aa1753b5646b1d515f5e34b35f8774b7e56ddae26d0f60c79f33ecf
(5) 75c9a353b2bcf788d0059f13ce2955c13eddb3cd519ce96ddbe720dd02e7b119
(6) beb73e4ec6153a777d112a60aee1267885d4dbdce72490075801059b5907225e
(7) 93acdb0c7563d689ea905317db2efcf7f76436b88945196fc1b999c378726818
(8) 13ed28f25756aaaa526fddcfb41c265edcc3ffd73ccfdd4162014679e7f7d818
(9) 6d78f5cfd9f5333d6fa316a0a890d1850aef5efb83768e00d6f29b7ba061882d

HD Wallet
==================
Mnemonic:      salad embrace pass fatal anger sadness apart plunge kidney liar abstract hockey
Base HD Path:  m/44'/60'/0'/0/{account_index}

Listening on localhost:8545

2、安装web3test

mkdir web3test
cd web3test
npm install web3@0.20.0 --save
npm install solc@0.4.21 --save

注:可使用npm view web3 versions 查看所有可用的web3.js版本。使用npm view web3 version查看当前安装的版本。注意web3.js版本非常重要,据我测试以下内容在[email protected]上是会报错的。

准备合约源文件

//FILE:HelloWorldContract.sol
pragma solidity ^0.4.0;
contract HelloWorldContract {
  function sayHi() constant returns (string){
    return 'Hello World';
  }
}

测试编译脚本

//FILE:compile.js
const fs = require ('fs');
const solc = require ('solc');
const input = fs.readFileSync('HelloWorldContract.sol');
const output = solc.compile(input.toString(), 1);
for (var contractName in output.contracts){
 console.log(contractName + ': ' + output.contracts[contractName].bytecode)
}

我本地运行该脚本看到如下结果(输出结果可能会不同但以不报错为准):

$node compile.js
:HelloWorldContract: 6060604052341561000f57600080fd5b61014e8061001e6000396000f3006060604052600436106100405763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630c49c36c8114610045575b600080fd5b341561005057600080fd5b6100586100cf565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561009457808201518382015260200161007c565b50505050905090810190601f1680156100c15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6100d7610110565b60408051908101604052600b81527f48656c6c6f20576f726c640000000000000000000000000000000000000000006020820152905090565b602060405190810160405260008152905600a165627a7a7230582053f213cf29e3a3510df6454588fab2d1eade12af4f8424d8a26974f5a23db8770029

部署合约

//FILE:compileDeploy.js
console.log('Setting up ...');
const fs = require('fs');
const solc = require('solc');
const Web3 = require('web3');
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
console.log('Reading Contract...');
const input = fs.readFileSync('HelloWorldContract.sol');
console.log('Compiling Contract...');
const output = solc.compile(input.toString(),1);
const bytecode = output.contracts[':HelloWorldContract'].bytecode;
const abi = output.contracts[':HelloWorldContract'].interface;

//Contract Object

const helloWorldContract = web3.eth.contract(JSON.parse(abi));

var account = web3.eth.accounts[0];

console.log("Deploying the contract");

const helloWorldContractInstance = helloWorldContract.new({
    data: '0x' + bytecode,
    from: account,
    gas: 1000000
}, (err, res) => {
    if (err) {
        console.log(err);
        return;
    }
    console.log(res.transactionHash);
    // If we have an address property, the contract was deployed
    if (res.address) {
        console.log('Contract address: ' + res.address);
    }
});

运行脚本

$node compileDeploy.js
Setting up ...
Reading Contract...
Compiling Contract...
Deploying the contract
0x0ee6ba6651e6e44497325441ac073e190e0ff405837204d1da465f049710adf0
0x0ee6ba6651e6e44497325441ac073e190e0ff405837204d1da465f049710adf0
Contract address: 0x6406fbd7ebe94dccf40b52fb8e71555a91f282bf

合约交互

导出ABI文件

// FILE: exportABI.js
console.log('Setting up...');
const fs = require ('fs');
const solc = require ('solc');
const Web3 = require ('web3');
console.log('Reading Contract...');
const input = fs.readFileSync('HelloWorldContract.sol');
console.log('Compiling Contract...');
const output = solc.compile(input.toString(), 1);
const bytecode = output.contracts[':HelloWorldContract'].bytecode;
console.log('Generating ABI...');
const abi = output.contracts[':HelloWorldContract'].interface;
fs.writeFile("./HelloWorldABI.JSON", abi, function(err) {
    if(err) {
        return console.log(err);
    }
console.log("ABI Saved");
});
$node exportABI.json
Setting up...
Reading Contract...
Compiling Contract...
Generating ABI...
ABI Saved
$cat HelloWorldABI.json
[{"constant":true,"inputs":[],"name":"sayHi","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"

调用合约方法

//FILE: callContract.js
console.log('Setting up...');
const solc = require ('solc');
const Web3 = require ('web3');
const fs = require ('fs');
console.log('Reading abi');
const HelloWorldABI = fs.readFileSync("./HelloWorldABI.JSON");
console.log('Connecting');
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
console.log('Creating contract instance');
const helloWorldContract = web3.eth.contract(JSON.parse(HelloWorldABI));
var helloWorldContractInstance = helloWorldContract.at("0x6406fbd7ebe94dccf40b52fb8e71555a91f282bf");  //此处0x6406fbd7ebe94dccf40b52fb8e71555a91f282bf 为部署合约的输出Contract address: 0x6406fbd7ebe94dccf40b52fb8e71555a91f282bf
console.log ('calling the contract locally');
console.log(helloWorldContractInstance.sayHi.call());

运行

$node callContract.js

Setting up...
Reading abi
Connecting
Creating contract instance
calling the contract locally
Hello World

可以看到输出结果“Hello World”

其他环境

node v 6.9.5

你可能感兴趣的:(以太坊,区块链)