web3.js是以太坊提供的一个NodeJs库,封装了一些和以太坊交互的常用对象、函数。主要包括版本、账号、交易、合约等信息的获取和调用。本文主要介绍通过web3.js调用及执行智能合约
准备工作:
安装node,npm,这里就不介绍了
本文中使用的私有链是Ganache,它是可视化私有链,前身就是大名鼎鼎的testRPC。更重要的是只有在产生交易时它才会挖矿,很适合用来测试智能合约。
1、新建项目
由于web3.js 1.x 和 0.x版本api不同,尽管web3.js的1.0 release还没出来,这里仍然选用1.0 beta版本演示,方便后续学习
> mkdir demo && cd demo
> npm init
> npm install [email protected] --save
> npm install solc --save
2、创建合约
在项目下新建MetaCoin.sol,把以下内容复制到文件中。该合约内容是使用truffle初始化项目(truffle unbox metacoin
)后生成的。
pragma solidity ^0.4.24;
contract MetaCoin {
mapping(address => uint) balances;
event Transfer(address indexed _from, address indexed _to, uint256 _value);
constructor() public {
balances[tx.origin] = 10000;
}
function sendCoin(address receiver, uint amount) public returns (bool sufficient) {
if (balances[msg.sender] < amount) return false;
balances[msg.sender] -= amount;
balances[receiver] += amount;
emit Transfer(msg.sender, receiver, amount);
return true;
}
function getBalance(address addr) public view returns (uint) {
return balances[addr];
}
}
3、编译合约
web3.js 1.0版本移除了compile方法,所以web3.eth.compile.solidity(source)
已经不能用了。如果需要编译合约有两种方式
- 使用
solc
- 在网页上编译 https://remix.ethereum.org
本文使用solc直接在项目中编译合约,方便查看编译后的结果
const fs = require('fs');
const Web3 = require("web3");
const solc = require('solc');
const data = fs.readFileSync('./MetaCoin.sol');
// console.log(data.toString())
const web3 = new Web3();
// Ganache默认端口7545
web3.setProvider(new Web3.providers.HttpProvider("http://localhost:7545"));
// 1 是优化器参数
const output = solc.compile(data.toString(), 1);
// console.log(output)
const bytecode = output.contracts[':MetaCoin'].bytecode;
const abi = output.contracts[':MetaCoin'].interface;
4、部署合约
// 第一个参数:合约的abi对象
new web3.eth.Contract(JSON.parse(abi), {
// 必填,合约发起者
from: '0x75441ac9a1d2DaAA5638beae207546c8D14a7f6d',
// 合约bytecode,也可也在deploy中传入
data: bytecode,
// 即gas limit,该交易最大可使用的Gas
gas: 4712388,
gasPrice: '1000000'
}).deploy().send().then((instance) => {
// console.log(instance)
// 合约地址
// console.log(`Address: ${instance.options.address}`);
//执行合约,只是查询状态,不需要挖矿,所以调用call方法
instance.methods.getBalance('0x75441ac9a1d2DaAA5638beae207546c8D14a7f6d').call({
//非必填,该合约方法的调用者
from: '0x6cc022FAE89414146b2A2646ca5143e23dA5b7e7'
}, function (error, result) {
console.log('error:' + error)
console.log('result:' + result)
})
})
其中要注意的是:web3.js 1.0版本和0.x版本获取账号的方法不一样,如下web3.eth.accounts[0]
web3.js 0.x版本中的方法web3.eth.getAccounts().then(function (value) { console.log(value[0]) })
web3.js 1.0版本中的方法
5、调用已经部署过的合约,执行合约方法
// 相对于部署合约,多了第二个参数,即合约地址
const metaCoinContract = new web3.eth.Contract(JSON.parse(abi), '0x83A87C3DC9CD2146e29D8aCFb7470Bc86d8bFf28', {
// 非必填,合约的bytecode
data: bytecode,
// 非必填,合约的创建者
from: '0x906210387ADC119767900692fA5E59417C809642',
//Gas limit
gas: 4712388,
gasPrice: '1000000'
});
// 调用合约中的sendCoin方法
metaCoinContract.methods.sendCoin('0x84d939AD8034c3ce2A7D4D100b939d4523b9E46E', 100).send({
//非必填,该合约方法的调用者
from: '0x75441ac9a1d2DaAA5638beae207546c8D14a7f6d'
}).on('transactionHash', function (hash) {
console.log(hash)
}).on('receipt', function (receipt) {
console.log(receipt)
}).on('confirmation', function (confirmationNumber, receipt) {
console.log(confirmationNumber)
}).on('error', console.error)
// 调用合约中的getBalance方法
metaCoinContract.methods.getBalance('0x75441ac9a1d2DaAA5638beae207546c8D14a7f6d').call({
//非必填,该合约方法的调用者
from: '0x6cc022FAE89414146b2A2646ca5143e23dA5b7e7'
}, function (error, result) {
console.log('error:' + error)
console.log('result:' + result)
})
欢迎订阅「K叔区块链」 - 专注于区块链技术学习
博客地址: http://www.jouypub.com
简书主页: https://www.jianshu.com/u/756c9c8ae984
segmentfault主页: https://segmentfault.com/blog/jouypub
腾讯云主页: https://cloud.tencent.com/developer/column/72548