在vue中使用web3.js开发以太坊dapp

前端如何使用以太坊智能合约方法

这里讲的是前端与MetaMask之间的交互

文中涉及到的官方文档
web3.js 1.0中文手册
MetaMask官方文档

1.cdn引入web3js

<!--引入web3-->
<script src="https://cdn.jsdelivr.net/gh/ethereum/web3.js/dist/web3.min.js"></script>

2.web3.js文件
链接:https://pan.baidu.com/s/1_mPT-ZcQ9GU_U1CVhBKpLA
提取码:cbey

3.使用npm安装web3js依赖

//在vue中安装web3
npm install web3 --save
//在main.js引入
import Web3 from 'web3'
Vue.prototype.Web3 = Web3

一、唤起MetaMask钱包进行登录

创建web3.js文件

//web3.js
// 智能合约地址
const contractAddress = '.....'
// 智能合约ABI
const contractABI=[]
var contract=null;
/**
 * 初始化
 * @param {Object} callback 返回账户地址
 */
function Init(callback){
	//判断用户是否安装MetaMask钱包插件
	if (typeof window.ethereum === "undefined") {
		//没安装MetaMask钱包进行弹框提示
		alert("Looks like you need a Dapp browser to get started.");
		alert("Consider installing MetaMask!");
	} else {
		//如果用户安装了MetaMask,你可以要求他们授权应用登录并获取其账号
		ethereum.enable()
		.catch(function (reason) {
			//如果用户拒绝了登录请求
			if (reason === "User rejected provider access") {
				// 用户拒绝登录后执行语句;
			} else {
				// 本不该执行到这里,但是真到这里了,说明发生了意外
				alert("There was an issue signing you in.");
			}
			}).then(function (accounts) {
				//如果用户同意了登录请求,你就可以拿到用户的账号
				var currentProvider = web3.currentProvider;
				var Web3 = web3js.getWeb3();
				web3 = new Web3();
				web3.setProvider(currentProvider);
				contract = new web3.eth.Contract(contractABI, contractAddress);
				// console.log('地址列表', accounts)
				//这里返回用户钱包地址
				callback(accounts[0]);
			});
	}
}
//导出相应的方法
export default {
	Init,
}

然后在需要用到的页面引入

import NCWeb3 from "@/web3";
NCWeb3.Init(addr=>{
	//得到相应的钱包地址
	console.log(addr)
})

二、调用智能合约里面的方法(分为两种,需要油费和不需要的)

不需要油费的比较简单,通过contract.methods.智能合约方法(所需的参数).call()直接调用

// 投资授权
function Approve(addr,value, callback) {
	contract.methods
		//智能合约方法(所需的参数)
		.approve(addr,value)
		.call()
		.then((res) => {
			console.log('投资授权成功', res)
			callback(res);
		})
		.catch((err) => {
			alert('投资授权失败,稍后再试:', err)
		});
}
//导出相应的方法
export default {
	Init,
	Approve,
}

需要油费比较麻烦一点,先调用web3.eth.estimateGas()方法估算交易的gas用量。再用web3.eth.getGasPrice()方法获取当前gas价格,最后使用ethereum.sendAsync方法发送以太币、调用智能合约:

// 投资
function join(account, addr,val, callback) {
	//要支付的ETH,十六进制
	let value = "0x0";
	//智能合约的参数也需要进行转换
	//web3.utils.padLeft左侧补0补齐到指定长度的字符串
	//参数数字转换
	val = web3.utils.toHex(val).substring(2);
	val = web3.utils.padLeft(val, 64);
	//参数地址转换
	addr=web3.utils.padLeft(addr, 64).substring(2)
	//智能合约方法,获取方式看下面
	let fun="0x095ea7b3"
	let data = fun + addr + val;
	sendTransfer(account, data, value, callback, errorCallBack);
}
/**
 * 发送交易
 * @param {Object} account 用户地址
 * @param {Object} data 数据
 * @param {Object} value 转账金额
 * @param {Object} callback 返回hash
 * @param {Object} errorCallBack 返回的错误
 */
function sendTransfer(account, data, value, callback, errorCallBack) {
	// estimateGas获取交易的 gas 用量
	const params = {
		from: account,
		to: contractAddress,
		data: data,
		value: value,
 	 };
	web3.eth.estimateGas(params, function (error1, gaslimit) {
		if (error1) {
			errorCallBack(error1);
		} else {
			// gasprice获取当前gas价格
			web3.eth.getGasPrice(function (error2, gasPrice) {
				if (error2) {
					errorCallBack(error2);
				} else {
					gaslimit -= -10000;
					let params = [
						{
							gasPrice: gasPrice,
							gasLimit: gaslimit,
							from: account,
							to: contractAddress,
							data: data,
							value: value,
						},
					];
					//ethereum.sendAsync方法发送以太币、调用智能合约:
					ethereum.sendAsync(
						{
							method: "eth_sendTransaction",
							params: params,
							from: account,
						},
						function (error, hash) {
							if (error) {
								// alert(error.message);
								errorCallBack(error.message);
							} else {
								callback(hash);
							}
						}
		           );
		           //监听MetaMask的事件
		           ethereum.on('accountsChanged', function (accounts) {
		             console.log(accounts[0])
		           })
				}
			});
		}
	});
}
//导出相应的方法
export default {
	Init,
	Approve,
	join,
}

获取智能合约方法十六进制方式
在vue中使用web3.js开发以太坊dapp_第1张图片
然后在需要用到的页面引入使用,但需要注意的一点是要等初始化完之后才能调用合约方法

import NCWeb3 from "@/web3";
NCWeb3.Init(addr=>{
	//得到相应的钱包地址
	console.log(addr)
	NCWeb3.Approve(addr,value, res=>{
		console.log('Approve方法返回的数据',res)
	})
	NCWeb3.join(account, addr,val, res=>{
		//由于join方法存在交易,所以这里会返回交易哈希值
		console.log('join方法返回的数据',res)
	})
})

需要邮费的方法存在交易,需要链上打包确认,可以通过web3.eth.getTransactionReceipt(‘交易哈希值’)方法进行监听该方法的执行情况。如果交易处于pending状态,则返回null,反之返回一个对象,status属性为true则成功,反之失败。

最后如果看完对你有用,请点击收藏关注,谢谢支持,有问题可以评论留言

你可能感兴趣的:(区块链,vue,区块链,web3)