Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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?
@Georgi87

This comment has been minimized.

Copy link

@Georgi87 Georgi87 commented Nov 16, 2015

To not inject and overwrite web3 in Mist is the right way, because there could be incompatibility issues. The mist provider should have a property VERSION with the minimum version of web3 required by the dApp to be compatible with mist.
The way I think the workflow should be for dApps, which have a remote node (blockapps) as fallback:

  1. dApp checks if mist.web3Provider is available.
  2. dApp checks if the web3 version loaded in the dApp is compatible with the one required by mist.
    2.1. If so, connect to mist.
    2.2. If not, connect to the remote node
@frozeman

This comment has been minimized.

Copy link
Owner Author

@frozeman frozeman commented Nov 16, 2015

So you agree with Proposal 1?
EDIT: will talk with @bas-vk about the RPC version

@step21

This comment has been minimized.

Copy link

@step21 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

This comment has been minimized.

Copy link
Owner Author

@frozeman frozeman commented Nov 16, 2015

Yes 1,2,3 is possible

@alexvandesande

This comment has been minimized.

Copy link

@alexvandesande alexvandesande commented Nov 16, 2015

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

@jarradh

This comment has been minimized.

Copy link

@jarradh jarradh commented Nov 16, 2015

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

This comment has been minimized.

Copy link
Owner Author

@frozeman frozeman commented Nov 17, 2015

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

This comment has been minimized.

Copy link

@kumavis 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

This comment has been minimized.

Copy link
Owner Author

@frozeman frozeman commented Nov 17, 2015

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

This comment has been minimized.

Copy link

@lexansoft lexansoft commented Dec 1, 2015

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

This comment has been minimized.

Copy link

@ethernomad ethernomad commented Dec 7, 2015

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

This comment has been minimized.

Copy link

@ethernomad ethernomad commented Dec 7, 2015

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

This comment has been minimized.

Copy link

@barkthins barkthins commented Apr 4, 2016

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

This comment has been minimized.

Copy link

@balamuraliv balamuraliv commented Jul 21, 2016

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

This comment has been minimized.

Copy link

@ethernomad ethernomad commented Nov 16, 2016

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