Metamask

未處理的拒絕(TypeError):this.web3.eth 未定義

  • November 20, 2021

我的 getWeb3.js 文件:

import Web3 from 'web3'

export default async () => {
   var web3Provider = null;
   if (typeof window.ethereum !== "undefined") {
       web3 = new Web3(window.ethereum)
       try {
           // Request account access if needed
           await window.ethereum.enable()
           // Acccounts now exposed
       } catch (error) {
           // User denied account access...
           console.log("MetaMask cannot be enabled!")
       }
   }
   // Legacy dapp browsers...
   else if (window.web3) {
       web3Provider = new Web3(window.web3.currentProvider);
   }
   // Non-dapp browsers...we use ganache
   else {
       console.log('Non-Ethereum browser detected. You should consider trying MetaMask!');
       web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
       console.log("ganache")
   }
   return web3
}

我是這樣稱呼getWeb3的,它總是抱怨這個var accounts = await this.web3.eth.getAccounts(),說this.web3.eth is undefined

export default class PaypalContract {
 constructor() {
   console.log(instance)
   if (!instance) {
     

instance = this this.web3 = getWeb3() console.log(“web3 init:",this.web3) this.contract = contract(PaypalContractMeta) this.contract.setProvider(this.web3) this.usdtcontract = contract(usdtContractMeta) this.usdtcontract.setProvider(this.web3) }

return instance


 }

 async payToContract(coin_address,recipient,price,order_id) {
   //const { eth: { accounts: [ account ] } } = this.web3

var accounts = await this.web3.eth.getAccounts() var account = accounts[0] console.log(‘account:’,account) console.log(“coin address:",coin_address) const coincontractInstance = await this.usdtcontract.at(coin_address) const contractInstance = await this.contract.deployed() var priceUnit = this.web3.utils.toBN(price).mul(this.web3.utils.toBN(this.web3.utils.toWei(“1”))) await coincontractInstance.approve(contractInstance.address,priceUnit,{from: account}) await contractInstance.deposit(coin_address,recipient,priceUnit,order_id,{ from: account }) await contractInstance.setExpiryDate(order_id,0,{ from: account })


 }

這解決了。

我不應該在 getWeb3 中使用非同步模式和等待,刪除它們可以解決問題。

  1. 您正在使用糟糕的命名約定。Web3 中的提供程序是您用來建構Web3 實例的,例如window.web3.currentProviderwindow.ethereum
  2. window.ethereum不是 Web3 實例,它是 Web3 提供程序。所以你必須這樣做:web3Provider = new Web3(window.ethereum);
  3. 當您有契約時,您需要告訴它使用您選擇的 Web3 實例this.contract.setProvider(this.web3);
  4. 你應該測試一下if (typeof window.ethereum !== "undefined") {
  5. 也不要ethereum.enable()立即執行,而是在您的使用者執行了“登錄”或“發送 tx”等保證它的操作後執行。僅僅載入您的頁面並不能保證它。
  6. 10**18您可以使用 ,而不是使用web3.utils.toWei(1)
  7. 不要使用 Javascript 數字,而是使用 BN 大數字,以便保留所有數字:var priceUnit = web3.utils.toBN(price).mul(web3.utils.toBN(web3.utils.toWei("1")));.
  8. 當您await執行類似 的合約操作時await coincontractInstance.approve(,請查看返回的對象,特別是receipt.status確保它在盲目跟進下一個 tx 之前已通過。

乾杯

引用自:https://ethereum.stackexchange.com/questions/89374