简体   繁体   中英

Unable to set provider in web3 object

I am following an online course on DApp creation and I am currently trying to set up the application that will be used in the tutorials.

The Dapp is set up using Truffle and Metamask on Chrome. All the Dapp files were provided by the course (actually an Ubuntu linux instance was provided for use in a Virtual machine) but soon it became evident that due to changes in more recent versions of Metamask (the course dates from 2017 I think) the web front-end controls related to account addresses (a drop down list displaying them and a button calling a function that sends an account address to the contract) were broken. Being new to the whole ecosystem I followed a suggestion from a fellow student that modified the initWeb3 function from this

  initWeb3: function() {
        // Is there is an injected web3 instance?
    if (typeof web3 !== 'undefined') {
      App.web3Provider = web3.currentProvider;
    } else {
      // If no injected web3 instance is detected, fallback to the TestRPC
      App.web3Provider = new Web3.providers.HttpProvider('http://127.0.0.1:9545');
    }
    web3 = new Web3(App.web3Provider);
    App.populateAddress();
    return App.initContract();
  }

to this

  initWeb3: function() {

            // Is there is an injected web3 instance?

            if (typeof web3 !== 'undefined') {
            ethereum.enable().then(() => {
            App.web3Provider = web3.givenProvider;
            });

            } else {

            // If no injected web3 instance is detected, fallback to the TestRPC
            App.web3Provider = new Web3.providers.HttpProvider(App.url);
            }

            web3 = new Web3(App.web3Provider);
            App.populateAddress();
            return App.initContract();

            }

I understand that the key difference is the ethereum.enable() call. This did make the relevant controls appear in the (Chrome) webpage and now Metamask also displays a popup requiring approval of its communication with the account by the user. The problem is that when the webpage loads, Chrome records the following error:

Uncaught Error: Invalid provider passed to setProvider(); provider is null
    at Function.setProvider (truffle-contract.js:308)
    at Object.success (app.js:61)
    at i (jquery.min.js:2)
    at Object.fireWith [as resolveWith] (jquery.min.js:2)
    at y (jquery.min.js:4)
    at XMLHttpRequest.c (jquery.min.js:4)

I assume that this is related to the changes in the app.js file but I could not find a solution. I have tried replacing App.web3Provider = new Web3.providers.HttpProvider(App.url) from the "new" version with App.web3Provider = new Web3.providers.HttpProvider('http://127.0.0.1:9545'); that existed in the original version but this did not make any difference. Same with givenProvider and currentProvider .

Me and other fellow students have contracted the staff behind the course for assistance but none was provided (I have taken up the issue with them as well). I have googled the error and spent significant time reading back the results but so far no solution has been provided - some results suggest this is actually a Web3 bug but I could not be certain. If anyone can assist with the issue it will be appreciated.

Thanks

I have resolved the issue - I have used code from the Ethereum Javascript API page to initiate my web3 instance inside the if..else block and then set App.web3Provider provider to the provider of the instance

 initWeb3: function() { // Is there is an injected web3 instance? if (typeof web3 !== 'undefined') { ethereum.enable().then(() => { web3 = new Web3(web3.currentProvider); }); } else { // If no injected web3 instance is detected, fallback to the TestRPC web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); } App.web3Provider=web3.currentProvider; App.populateAddress(); return App.initContract(); },

I ran into this issue following the tutorial on Truffle's site here: https://trufflesuite.com/tutorial/index.html . I resolved it slightly differently, but similar order.

 initWeb3: async function() { // Modern dapp browsers... if (window.ethereum){ web3 = new Web3(web3.currentProvider); try { //Request account access await window.ethereum.request({ method: "eth_requestAccounts" }); } catch (error) { // User denied account access... console.error("User denied account access"); } App.web3Provider = web3.currentProvider; console.log("modern dapp browser"); } // Legacy dapp browsers... else if (window.web3) { App.web3Provider = window.web3.currentProvider; console.log("legacy dapp browser"); } // if no injected web3 instance is detected, fall back to Ganache else { App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545'); } web3 = new Web3(App.web3Provider); return App.initContract(); },

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM