如何使⽤web3.js部署智能合约
原⽂:
在编译之前,需要安装node以及npm,之后需要建⽴⼀个⽂件夹,使⽤以下指令
$ mkdir web3test && cd web3test
$ npm init
$npm install web3 --save
Enter Solidity.
In a nutshell, ( check for the correct docs version !) is the language in which you write contracts, it’s syntax is similar to
javascript (importantly it is statically typed and supports libraries and other cool features). So the plan is to write a contract,
then compile it and then release/interact with it through web3.js which we briefly covered in the last part
of this series. So
let’s start with a very very simple contract.
pragma solidity ^0.4.0;
contract HelloWorldContract {
function sayHi()constant returns(string){
return'Hello World';
}
}
While it might look simple, there is a lot going on here, so let’s comment this example:
// You will also need a solidity linter for ATOM ! like linter-solidity
// FILE : HelloWorldContract.sol
/
/ Notice the .sol (for solidity) extension.
pragma solidity ^0.4.0;
// will not compile with a compiler earlier than version 0.4.0
contract HelloWorldContract {
// notice the word contract
function sayHi()constant returns(string){
// As a typed language, this function specifies what it returns via the constant returns (string) bit.
return'Hello World';
}
}
This contract should respond with “Hellow World” when called (we’ll look into that later) via the sayHi() function. Compiling :
As mentioned, in order to make contracts work, we first need to compile them and then release or deploy them into the
network, the first thing we will need to compile is the solc ( solidity ) node package:
npm install solc
And now in atom we actually do the compiling:
以下所有的js⽂件都需要在⼀个终端运⾏命令⾏:eth -j -admin-via-http,否则会出现各种错误。
// FILE: compile.js
const fs = require ('fs');
const solc = require ('solc');
const input = fs.readFileSync('HelloWorldContract.sol');
const output = String(), 1);
for (var contractName acts){
console.log(contractName + ': ' + acts[contractName].bytecode)
}
// :helloWorldContract:
6060604052341561000f57600080fd5b5b6101488061001f6000396000f300606060405263ffffffff7c010000000000000000000000000000000000000000000
Success ! the weird looking block at the bottom is our compiled contract ( Ethereum-specific binary format or bytecode ), we now need to deploy it to the blockchain and then interact with it:
pre - Deploying :
In order to deploy our contract we first need to create a contract object in web3, in order to do that we need to format those numbers up there into an
// FILE: compileDeploy.js
const fs = require ('fs');
const solc = require ('solc');
const Web3 = require ('web3');
const web3 = new Web3(new Web3.providers.HttpProvider("localhost:8545"));
const input = fs.readFileSync('HelloWorldContract.sol');
const output = String(), 1);
const bytecode = acts[':helloWorldContract'].bytecode;
const abi = acts[':helloWorldContract'].interface;
const helloWorldContract = act(JSON.parse(abi));
console.log(helloWorldContract); //
An ABI in case you were wondering Neat
Deploying
//FILE: compileDeploy.js
console.log('');
const fs = require ('fs');
const solc = require ('solc');
const Web3 = require ('web3');
const web3 = new Web3(new Web3.providers.HttpProvider("localhost:8545"));
console.log('');
const input = fs.readFileSync('HelloWorldContract.sol');
console.log('');
const output = String(), 1);
const bytecode = acts[':helloWorldContract'].bytecode;
const abi = acts[':helloWorldContract'].interface;
/
/Contract Object
const helloWorldContract = act(JSON.parse(abi));
console.log('unlocking Coinbase account');
const password = "账户密码";
try {
web3.personal.unlockAccount(⾃⼰的账户名称, password,100);
} catch(e) {
console.log(e);
return;
}
console.log("Deploying the contract");
const helloWorldContractInstance = w({
data: '0x' + bytecode,
from: 账户名称,
gas: 1000000
}, (err, res) => {
if (err) {
console.log(err);
return;
}
console.ansactionHash);
// If we have an address property, the contract was deployed
if (res.address) {
console.log('Contract address: ' + res.address);
}
});
And the Readout:
What just happened ?
In Ethereum, a contract is created by sending a transaction (from an address you control - hence the unlock part), the
payload of this transaction ( which has to be formatted accordingly  — hence the contractInstance part) is the contract code
which now lives on the blockchain and has an address, let’s query our trusty block explorer () and see what it tells us: Beyond the obvious observation that it exists and was identified as a contract , there is a TxHash and a Contract Creator Address ( along with the Contract Address ) that is now part of the blockchains history; and if you click on the Contract
Code tab ?
You will get the exact compiled contract we started with, an instance of which now lives on the blockchain and is ready for us to interact with ! ( scroll up to the :helloworld code comment, it’s the same code plus the 0x bit ).
Setting up ...
Reading Contract ...
Compiling Contract ...
unlocking Coinbase account
Deploying the contract
0x876453431987c163b84153e99ec8f6f7a7bd232bb41dfe0537884907d7769664
0x876453431987c163b84153e99ec8f6f7a7bd232bb41dfe0537884907d7769664
Contract address: 0x2759054bbfbaed66319ecbce83824efce04ee63c
A note about  costs: Even though we are on  a testnet where  the  Ether is  free, it  should be noted that  this transaction  incurred in  some  costs and  there
Interacting with the contract…
So now that our smart contract has been created and deployed, our last task will be to interact with it, if you remember our
contract has one function:
function sayHi()constant returns(string){
return'Hello World';
}
Which if we are successful will somehow return the words “Hello World”, well that’s the plan anyways.
Inspecting our contract via web3:
Now that our contract lives in the blockchain, we can query the blockchain for our contracts code like so:
console.log('');
const solc = require ('solc');
const Web3 = require ('web3');
const web3 = new Web3(new Web3.providers.HttpProvider("localhost:8545"));
console.log('');
const deployedHelloWorldContractInstance = Code("0x2759054bbfbaed66319ecbce83824efce04ee63c");
console.log('Contract Code: ' + deployedHelloWorldContractInstance);
And our readout:
Contract Code: 0x606060405263ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630c49c36c811461003d575
Which surprise surprise is still the same code we added to our hello world contract.
Gotcha time: Now in order to call our method: sayHi() we need to instantiate a contract, the gotcha is that we need an ABI to
do so, and the original maker of the contract (that’s us) needs to make it available, so we need to rewrite our original
contract code (compileDeploy.js ) so we can write our ABI and then read it in json format, for clarity sake here’s a script
that takes care of the writing part ,you can merge it with the compileDeploy one:
//FILE: exportABI.js
console.log('');
const fs = require ('fs');
const solc = require ('solc');
const Web3 = require ('web3');
console.log('');
const input = fs.readFileSync('HelloWorldContract.sol');
console.log('');
const output = String(), 1);
const bytecode = acts[':HelloWorldContract'].bytecode;
console.log('');
const abi = acts[':HelloWorldContract'].interface;
fs.writeFile("./HelloWorldABI.JSON", abi, function(err) {
if(err) {
return console.log(err);
}
console.log("ABI Saved");
});
Resulting in the following HelloWorldABI.json:
[{"constant":true,"inputs":[],"name":"sayHi","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"}]
Back to calling our method:
let’s try instantiating a contract by joining these 2 parts ( the abi and the contract code):
FILE: callContract.js
console.log('');
const solc = require ('solc');
const Web3 = require ('web3');
console.log('Reading abi');
const HelloWorldABI = require("./HelloWorldABI.json");
console.log('Connecting');
const web3 = new Web3(new Web3.providers.HttpProvider("localhost:8545"));
const helloWorldContract = act(HelloWorldABI);
var helloWorldContractInstance = helloWorldContract.at("0x2759054bbfbaed66319ecbce83824efce04ee63c");
console.log(helloWorldContractInstance);
And our resulting instance contract code:
Contract {
_eth:
Eth {
_requestManager: RequestManager { provider: [Object], polls: {}, timeout: null },
getBalance: { [Function: send] request: [Function: bound ], call: 'eth_getBalance' },
getStorageAt: { [Function: send] request: [Function: bound ], call: 'eth_getStorageAt' },
getCode: { [Function: send] request: [Function: bound ], call: 'eth_getCode' },
getBlock: { [Function: send] request: [Function: bound ], call: [Function: blockCall] },
getUncle: { [Function: send] request: [Function: bound ], call: [Function: uncleCall] },
getCompilers: { [Function: send] request: [Function: bound ], call: 'eth_getCompilers' },
getBlockTransactionCount:
{ [Function: send]
request: [Function: bound ],
call: [Function: getBlockTransactionCountCall] },
getBlockUncleCount:
{ [Function: send]
request: [Function: bound ],
call: [Function: uncleCountCall] },
getTransaction:
{ [Function: send]
request: [Function: bound ],
call: 'eth_getTransactionByHash' },
getTransactionFromBlock:
{ [Function: send]
request: [Function: bound ],
call: [Function: transactionFromBlockCall] },
getTransactionReceipt:
{ [Function: send]
request: [Function: bound ],
call: 'eth_getTransactionReceipt' },
getTransactionCount: { [Function: send] request: [Function: bound ], call: 'eth_getTransactionCount' }, call: { [Function: send] request: [Function: bound ], call: 'eth_call' },solidity
estimateGas: { [Function: send] request: [Function: bound ], call: 'eth_estimateGas' },
sendRawTransaction: { [Function: send] request: [Function: bound ], call: 'eth_sendRawTransaction' },
signTransaction: { [Function: send] request: [Function: bound ], call: 'eth_signTransaction' },
sendTransaction: { [Function: send] request: [Function: bound ], call: 'eth_sendTransaction' },
sign: { [Function: send] request: [Function: bound ], call: 'eth_sign' },
compile: { solidity: [Object], lll: [Object], serpent: [Object] },
submitWork: { [Function: send] request: [Function: bound ], call: 'eth_submitWork' },
getWork: { [Function: send] request: [Function: bound ], call: 'eth_getWork' },
coinbase: [Getter],
getCoinbase: { [Function: get] request: [Function: bound ] },
mining: [Getter],
getMining: { [Function: get] request: [Function: bound ] },
hashrate: [Getter],
getHashrate: { [Function: get] request: [Function: bound ] },
syncing: [Getter],
getSyncing: { [Function: get] request: [Function: bound ] },
gasPrice: [Getter],

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。