Use web3.js to compile, publish and call smart contracts

brief:

web3.js  is a collection of libraries that allow you to interact with local or remote ethernet nodes using HTTP or IPC connections.

solc.js is a compiler for solidity. The official recommended compilation method.

Ganache CLI, part of the Truffle suite of Ethereum development tools, is the command-line version of Ganache , a personal blockchain developed for Ethereum.

Ganache CLI uses ethereumjs to simulate full client-side behavior and make developing Ethereum applications faster, easier, and more secure. It also includes all the popular RPC functions and features (like events) and can run deterministically to make development easy.

Note: testrpc has been deprecated and has been renamed Ganache CLI

This article environment:

node

macOs 10.13.4

web3.js 1.0.0-beta.34

furrow 0.4.22

Environment installation:

web3.js

npm install web3

ganache-cli

npm and ganache-cli

furrow

npm install groove

solidity code:

demo.sol

pragma solidity ^ 0.4.0;

Calc contract {
  uint count;
  function add(uint a, uint b) returns(uint){
    count++;
    return a + b;
  }
  function getCount() returns (uint){
    return count;
  }
}

Next, compile and publish through web3.js:

 (1) Start Ganache

ganache-cli

This will list 10 pre-created accounts and 10 private keys

Create a local private chain address: localhost:8545

(2) Import the required modules:

web3.js

let Web3 = require('web3');
let furrow = require ("furrow");
let fs   = require('fs');

(3) Instance the web3 object, and use solc to compile solidity to obtain the objects required for publishing

if(typeof web3 != 'undefined'){
	web3=new Web3(web3.currentProvider);
}else{
	web3 = new Web3('http://localhost:8545');
}
let source=fs.readFileSync("./demo.sol","utf8");
let cacl=solc.compile(source,1);
let abi= JSON.parse(cacl.contracts[':Calc'].interface);
let bytecode=cacl.contracts[':Calc'].bytecode;
Note: When solc is compiled, a colon will be added before the solidity class method.

(3) When publishing, an account is required. If the account is not activated, unlockAccount() is required to activate it.

web3.eth.getAccounts().then(data=>{
	web3.eth.personal.unlockAccount(data[0])
})
Note: web3.eth.getAccounts() is an abnormal method, and data cannot be read by direct reading.

(4) Deploy, the contract address will be returned if the deployment is successful.

var rsContract=new web3.eth.Contract(abi).deploy({
	data:'0x'+bytecode, //begins with 0x
	arguments:[], //pass the parameters of the constructor
}).send({
	from:data[0],
	gas:1500000,
	gasPrice:'3000000000000'
},function(error,transactionHash){
	console.log("send callback");
	console.log("error:"+error);
	console.log("send transactionHash:"+transactionHash);
})
.on('error', function(error){ console.error(error) })
.then(function(newContractInstance){
	var newContractAddress=newContractInstance.options.address
	console.log("New contract address:"+newContractAddress);
});

Notice:

    1. The data in deploy must start with 0x.

    2. from is the account address, not the contract address

    3. When publishing, you need to pass in gas and gasPrice. If the gas is too small or too large, an error will be reported.

    The default value of gas is 90000

    The default value of gasPrice is 20000000000 

(5) Calling the test

var MyContract = new web3.eth.Contract(abi,newContractAddress);
    MyContract.methods.add(1,3).call().then(console.log);

By passing in the abi and contract address, the contract method can be called through the call method of web3.js.

Summarize:

The attention of the text is the place where you step on the pit, I hope it can help everyone. The following is the complete example code:

let Web3 = require('web3');
let furrow = require ("furrow");
let fs   = require('fs');
if(typeof web3 != 'undefined'){
	web3=new Web3(web3.currentProvider);
}else{
	web3 = new Web3('http://localhost:8545');
}
let source=fs.readFileSync("./demo.sol","utf8");
let cacl=solc.compile(source,1);
let abi= JSON.parse(cacl.contracts[':Calc'].interface);
let bytecode=cacl.contracts[':Calc'].bytecode; //contract binary code
web3.eth.getAccounts().then(data=>{
	web3.eth.personal.unlockAccount(data[0]).then(openAccountState=>{
		if(openAccountState){
			console.log("Account opening status:"+openAccountState);
			var rsContract=new web3.eth.Contract(abi).deploy({
				data:'0x'+bytecode,
				arguments:[], //pass the parameters of the constructor
			}).send({
				from:data[0],
				gas:1500000,
				gasPrice:'3000000000000'
			},function(error,transactionHash){
				console.log("send callback");
				console.log("error:"+error);
				console.log("send transactionHash:"+transactionHash);
			})
			.on('error', function(error){ console.error(error) })
			// .on('transactionHash', function(transactionHash){ console.log("hash:",transactionHash)})
			// .on('receipt', function(receipt){
			//    console.log(receipt.contractAddress) // contains the new contract address
			// })
			//.on('confirmation', function(confirmationNumber, receipt){console.log("receipt,",receipt)})
			.then(function(newContractInstance){
				var newContractAddress=newContractInstance.options.address
				console.log("New contract address:"+newContractAddress);

				web3.eth.getBlockNumber().then(blockNum=>{
					console.log("Current block number: "+blockNum);
					web3.eth.getBlock(blockNum).then(data=>{
						console.log("Current block information: ");
						console.log(data);
					})
				});
				var MyContract = new web3.eth.Contract(abi,newContractAddress);
					MyContract.methods.add(1,3).call().then(console.log);




			});
			
		}
	});
});

Quote:

http://web3js.readthedocs.io/en/1.0/web3.html#version

https://www.npmjs.com/package/ganache-cli

https://www.npmjs.com/package/solc

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324736918&siteId=291194637