此demo练习过程:使用Truffle编译合约,并部署到Ganache中,通过MetaMask与Ganache连接起来,通过web3提供的api与MetaMask进行交互来完成:查看本地帐户、发送交易、调用智能合约的功能。
合约内容:
pragma solidity >=0.4.22 <0.9.0;
contract helloworld{
function say() public pure returns(string memory){
return "hello world";
}
}
js测试代码:
<template>
<div>
<button @click="connectMetamask">连接钱包</button>
<button @click="getBalance2">查询钱包ETH余额</button>
<button @click="sendTransaction">ETH转账</button>
<button @click="send">合约 send</button>
<button @click="call">合约 call</button>
</div>
</template>
<script>
import Web3 from 'web3'
var jsonInterface =require('./helloworld.json')
//合约地址
var contractAddress="0xAA3cB7ba536671157C4E4Dd81AF3dcA1C413AAAe";
export default {
name: "test",
data(){
return {
}
},
created() {
//遇到钱包多账户切换的时候,需要使用监听事件
ethereum.on("accountsChanged", function(accounts) {
console.log('钱包切换',accounts)
window.location.reload();
});
//当所连接网络ID变化时触发
ethereum.on("chainChanged",(networkIDstring)=>{
console.log('链切换',networkIDstring)
window.location.reload();
});
console.log("jsonInterface",typeof jsonInterface)
},
mounted() {
this.init();
},
methods: {
async init(){
console.log("init")
this.connectMetamask();
},
connectMetamask() {
if (typeof window.ethereum !== 'undefined'|| (typeof window.web3 !== 'undefined')) {
// 检测到Web3浏览器用户。 现在可以使用提供程序了。
const provider = window['ethereum'] || window.web3.currentProvider;
// 实例化web3
let web3 = new Web3(provider);
window.web3 = web3;//挂载在window上,方便直接获取
//ethereum.enable() 方法请求用户授权应用访问MetaMask中的用户账号信息。
window.ethereum.enable().then((res) => {
console.log("当前钱包地址:" + res)
})
}else {
alert("请安装MetaMask钱包")
}
},
async getBalance1() {
let accounts = await web3.eth.getAccounts();
console.log("返回节点所控制的账户列表", accounts);
web3.eth.getBalance(accounts[0],(err, balance) => {
if (!err) {
console.log("ETH余额==", web3.utils.fromWei(balance));
}
})
},
async getBalance2() {
// 实例化web3
let web3= new Web3(ethereum);
let myAccount = await this.getAccount();
//给定地址的当前账户余额,以 wei 为单位
let balance = await web3.eth.getBalance(myAccount);
/*
区块链开发以太坊ETH单位转换关系
1kwei = 10^3wei(10的 3次幂)
1mwei = 10^6wei(10的 6次幂)
1gwei = 10^9wei(10的 9次幂)
1szabo = 10^12wei(10的 12次幂)
1finney = 10^15wei(10的 15次幂)
1ether = 10^18wei(10的 18次幂)
1kether = 10^21wei(10的 21次幂)
1mether = 10^24wei(10的 24次幂)
1gether = 10^27wei(10的 27次幂)
*/
console.log("ETH余额==", parseInt(balance) / Math.pow(10, 18)); //pow() 函数用来求 x 的 y 次幂(次方)
//web3.utils.fromWei 将任意数量的 wei 转换为 ether.
console.log("ETH余额==", web3.utils.fromWei(balance));
},
sendTransaction() {
web3.eth.getAccounts().then((res, err) => {
let fromAddress = res[0];
//转账数量
let amount = 1 * Math.pow(10, 18);
//收款地址
let toAddress = "0x18a29Ae28e3BE4eaEC93388D92DC7a4DAD3f7893";
let transactionObject = {
// gas: 21000, //(可选) 交易可用的 gas 量
// gasPrice: 5000000000, //(可选) 交易可用的 gas 价格,以 wei 为单位, 默认值通过 web3.eth.gasPrice 获得。
from: fromAddress,//发送账户地址。
to: toAddress, //(可选) 交易消息的目标地址,对于合约创建交易来说其值为空。
value: amount // (可选) 交易转账金额,以 wei 为单位,也是合约创建交易的初始转账。
}
console.log("transactionObject:", transactionObject);
//向以太坊网络提交一个交易。
web3.eth.sendTransaction(transactionObject, (err, result) => {
console.log("转账Hash=", result)
})
});
},
async send(){
const contract = new web3.eth.Contract(jsonInterface.abi, contractAddress);
let myAccount = await this.getAccount();
//methods.myMethod.send 向合约发送交易来执行其方法。注意这会改变合约状态。
// say 为合约中的方法
contract.methods.say().send({
from: myAccount
},(error, transactionHash) => {
console.log('返回',transactionHash);
})
},
async getAccount(){
let accounts = await web3.eth.getAccounts();
console.log("返回节点所控制的账户列表", accounts);
// 取第一个账户
let myAccount = accounts[0];
return myAccount;
},
async call(){
let myAccount = await this.getAccount();
const contract = new web3.eth.Contract(jsonInterface.abi, contractAddress);
//methods.myMethod.call 将在不发送交易的情况下调用该“常量”方法并在 EVM 中执行其智能合约方法。注意此种调用方式无法改变智能合约状态。
contract.methods.say().call({from: myAccount}, function(error, result){
console.log('返回',result);
});
}
}
}
</script>
测试
|