此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測試代碼:
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); }); } }}
測試