-
-
Save frozeman/fbc7465d0b0e6c1c4c23 to your computer and use it in GitHub Desktop.
/* | |
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? |
So you agree with Proposal 1?
EDIT: will talk with @bas-vk about the RPC version
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.
Yes 1,2,3 is possible
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
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.
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
#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());
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"));
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 ...
?
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?
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];
}
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.
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.
Relying on a global web3 seems to be incompatible with "use strict";
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:
2.1. If so, connect to mist.
2.2. If not, connect to the remote node