Skip to content

Instantly share code, notes, and snippets.

@frozeman
Last active July 22, 2021 01:00
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save frozeman/fbc7465d0b0e6c1c4c23 to your computer and use it in GitHub Desktop.
Save frozeman/fbc7465d0b0e6c1c4c23 to your computer and use it in GitHub Desktop.
Mist web3 loading proposal
/*
Basically "web3" comes from Mist,
but "Web3" CAN come from the dapp.
A Dapp has 3 ways to use web3.
2. and 3. would work when in Mist and outside.
*/
// 1. simply use, web3 comes already defined
web3
// 2. optional use web3 from mist, OR load if outside of mist
if(typeof web3 === 'undefined')
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
// 3. always use web3 provided by the dapp ("Web3" won't be supplied by Mist), but the provider from mist
if(typeof web3 !== 'undefined')
web3 = new Web3(web3.currentProvider);
else
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
// Add RPC version?
@step21
Copy link

step21 commented Nov 16, 2015

Yeah, looks reasonable. If I understand correctly, the proposal is that 1), 2) and 3) are all possible, right? Agree with above that a version property could be useful.

@frozeman
Copy link
Author

Yes 1,2,3 is possible

@alexvandesande
Copy link

It's also important to provide a framework in case web3 isn't being provided by a third party, like when an app that is supposed to be loaded in mist is accessed by a normal web browser without geth or any external provider.

In this scenario an explanation should be provided to the end user with a link on how to solve it. Ideally it would be some sort of modal (styles and exact content to be decided by Ðapp developer) but it could also be a simple javascript alert (users tend to press ok and ignore these):

"Your browser currently doesn't support Ethereum enabled apps. Try one of these actions:"

  • Download Mist, an ethereum compatible browser
  • Install a browser plugin
  • Use this app using Metamask, a in browser ethereum version"

Or something along these lines

@0xc1c4da
Copy link

When we spoke I originally was of the idea that the DApp should handle it, but if the web3 object is going to be consistent and not change that much, I very much like the idea of DApps expecting web3 to be considered a "native" object.

I like the 1 & 2 options, I don't think 3 is necessary, except maybe in these early days.

@frozeman
Copy link
Author

All there options are possible, as mist only provides the web3 object not the Web3 class.
I think we will have some API changes coming as we want to get web3 be the best tool. So 3. is definelty the best option for now

@kumavis
Copy link

kumavis commented Nov 17, 2015

#3 is my favorite, after a small change:

the provider shouldn't be on a browser-specific object, or you'll see all other browsers impersonating Mist just to provide the same behavior ( historical precedent with user-agent )

with this change it would look like:

if(typeof web3Provider !== 'undefined')
  web3 = new Web3(web3Provider);
else
  web3 = new Web3(new CustomWeb3Provider());

@frozeman
Copy link
Author

I agree with kumavis. But using web3.currentProvider. This will allow other browsers like meta mask to follow the same route and a dapp simple has to check if web3 is available and use its provider, when instantiating its one web3 version.

if(typeof web3 !== 'undefined')
  web3 = new Web3(web3.currentProvider);
else
  web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

@lexansoft
Copy link

I do not like the web3/Web3 pair. Not clear.

May be we can have clear Mist object? Something like:

if(typeof Mist !== 'undefined')
web3 = Mist.web3;
else ...

?

@ethernomad
Copy link

This is very important for JavaScript NPM libraries. Should they use web3 provided by Mist or use their own version, but get the provider from Mist.

How does a library know what web3.eth.defaultAccount should be?

@ethernomad
Copy link

Maybe something like this?:

if (typeof web3 !== 'undefined') {
  var defaultAccount = web3.eth.defaultAccount;
  var web3 = new Web3(web3.currentProvider);
  web3.eth.defaultAccount = defaultAccount;
}
else {
  var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
  web3.eth.defaultAccount = web3.eth.accounts[0];
}

@barkthins
Copy link

I've seen many issues over the years of assuming there's only one of anything in code. However, there are some issues with web3.js and multiple instances of web3 that I've found the hard way.

web3.js ostensibly supports multiple instances of web3: web3 = new Web3() can be done in every javascript file. I used to do that. I find I'm now creating one of them and passing them around my (nodejs) program for most types of work. Why's that? Because of the following issue:
contracts cache a a pointer to web3.eth (contract._eth). If you have multiple copies of web3 and you do anything that requires handles (such as events), things get very confused very quickly, because you end up stopListening on the wrong instance of web3.eth (for example). You have to be careful not to "cross" your instances of web3 and in particular web3.eth.

That being said, there's an issue with only having one provider. Trust. Do you really trust your local node to not get hacked? I don't, and neither do most modern bitcoin wallets. In my applications that involve any serious amounts of ether or other logic coming from javascript land I plan on having multiple providers in different locations and cross-checking for transaction completion and uncles among several providers. I will probably have this "multiple web3 instances needed" isolated to one part of my code - that of confirming completion of a transaction, before I move my javascript side state on to the next application state. A better idea is to move as much of that type of logic to a trust-minimized proxy on-chain, but still, there's some reason for your javascript code, right?

In the end, as far as javascript modularity goes, if you have one provider, you want exactly one copy of web3 lying around due to the above event handle issues. The same would apply if you had exactly one postgress database, one mysql database, etc. The exception being, I believe, for transaction confirmation.

So create your instances of web3 in ONE place, and provide an accessor function for them. One instance for initiating transactions, and one or more instances for confirmation transactions depending on your paranoia level. Distributed new Web3() in your code will lead to problems when you start mixing different bits of code together.

just my 2 cents.

@balamuraliv
Copy link

I am new to Blockchain and I' trying to do sample application using MIX IDE .How to display the transaction data in front end (index.html)
Can I use web3 object in MIX..Please guide me.

@ethernomad
Copy link

Relying on a global web3 seems to be incompatible with "use strict";

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment