快速学习-以太坊编写合约的部署脚本

编写合约的部署脚本

上节课我们已经通过编译从 solidity 源码得到了字节码,接下来我们会试图完成一个自动化脚本,将合约部署到区块链网络中。

部署的必要条件

与以太坊节点的通信连接

我们需要启动一个以太坊节点,连接到想要的网络,然后开放 HTTP-RPC的 API(默认 8545 端口)给外部调用;或者也可以用第三方提供的可用节点入口,以太坊社区有人专门为开发者提供了节点服务。目前我们直接用 ganache,不需要考虑这些问题,但如果配置其它网络,这个配置就是必要的。

余额大于 0 的账户

因为以太坊上的任何交易都需要账户发起,账户中必须有足够的余额来支付手续费(Transaction Fee),如果余额为 0 部署会失败。当然,我们目前用的是 ganache,里面默认有 10 个账户,每个账户 100ETH,不存在这个问题,但如果要部署到其它网络(私链、测试网络、主网)就必须考虑这个问题。

安装依赖

搞清楚部署的必要条件之后,我们需要安装必要的依赖包。首先是 web3.js,web3.js 的 1.0.0 版本尚未发布,但是相比 0.2x.x 版本变化非常大,1.x 中大量使用了 Promise,可以结合 async/await 使用,而 0.x 版本只支持回调,因为使用 async/await 能让代码可读性更好,我们这次选择使用 1.0.0 版本。

npm install web3

编写部署脚本

做好准备工作之后,我们开始编写合约部署脚本,在 scripts 目录下新建脚本文件 deploy.js:

const path = require('path');
const Web3 = require('web3');
const web3 = new Web3(new Web3.providers
	.HttpProvider('http://localhost:8545'));
// 1. 拿到 abi 和 bytecode 
const contractPath = path.resolve(__dirname,
	'../compiled/Car.json');
const {
	interface,
	bytecode
} = require(contractPath);
(async() => {
	// 2. 获取钱包里面的账户
	const accounts = await web3.eth.getAccounts();
	console.log('部署合约的账户:', accounts[0]);
	// 3. 创建合约实例并且部署
	var result = await new
	web3.eth.Contract(JSON.parse(interface))
		.deploy({
			data: bytecode,
			arguments: ['AUDI']
		})
		.send({
			from: accounts[0],
			gas: '1000000'
		});
	console.log('合约部署成功:', result);
})();

我们来熟悉一下 v1.0.0 版本中的部署操作。由于 1.0.0 版本中调用返回全部是 promise,所以我们这里用到了 ES7 中的 async/await 来处理所有异步调用。

第二步获取钱包账户,存为本地变量,然后选取 accounts[0] 作为部署合约的账户;我们应该确保这个账户中以太余额充足。

第三步中,我们用 promise 的链式调用完成了创建抽象合约对象、创建部署交易对象(deploy)和发送部署交易三个步骤,其中只有 send 一步是真正的异步请求调用。分开写就是这样:

const contract = new web3.eth.Contract(JSON.parse(interface)); 
const transaction = contract.deploy({ data: bytecode, arguments: 
['AUDI'] }); 
const result = await transaction.send({ from: accounts[0], gas: 
1000000 });

运行脚本

在根目录下运行写好的部署脚本:node scripts/deploy.js
查看结果,可以看到合约已经成功部署。我们发现返回结果有些复杂,所以可以对代码稍作改进,截取 address 返回,并计算一下部署花了多少时间:

const path = require('path');
const Web3 = require('web3');
const web3 = new Web3(new Web3.providers
	.HttpProvider('http://localhost:8545'));
// 1. 拿到 bytecode
const contractPath = path.resolve(__dirname,
	'../compiled/Car.json');
const {
	interface,
	bytecode
} = require(contractPath);
(async() => {
	// 2. 获取钱包里面的账户
	const accounts = await web3.eth.getAccounts();
	console.log('部署合约账户:', accounts[0]);
	// 3. 创建合约实例并且部署
	console.time('合约部署耗时');
	var result = await new
	web3.eth.Contract(JSON.parse(interface))
		.deploy({
			data: bytecode,
			arguments: ['AUDI']
		})
		.send({
			from: accounts[0],
			gas: '1000000'
		});
	console.timeEnd('合约部署耗时');
	console.log('合约部署成功:', result.options.address);
})();
发布了2157 篇原创文章 · 获赞 2418 · 访问量 24万+

猜你喜欢

转载自blog.csdn.net/weixin_42528266/article/details/105534460