使用元掩码时检测 web3 默认帐户的更好模式

Posted

技术标签:

【中文标题】使用元掩码时检测 web3 默认帐户的更好模式【英文标题】:Better pattern to detect web3 default account when using metamask 【发布时间】:2017-11-10 04:42:01 【问题描述】:

上下文:我想使用 blockies 在页面上呈现身份图标,我从 web3 获取 defaultAccount,为此,用户必须使用钱包中选择的地址登录到 metamask。

问题:web 应用似乎在页面的加载事件上没有检测到 web3 对象,建议在此处检测它。

代码:下面的灵感来自于:

https://github.com/MetaMask/metamask-plugin/issues/1158

https://github.com/MetaMask/faq/blob/master/DEVELOPERS.md#partly_sunny-web3---ethereum-browser-environment-check

我一直有 间歇性 行为,有时 web3 存在,有时不存在,我能想到的唯一解决方案是有一个计时器,但这在我看来有点过于简单,我更喜欢更优雅的东西。

问题:是否有更好的解决方案来在页面加载时从 web3 中检测 defaultAccount?

 function startApp()  
        GenerateIdenticon();  
  


window.addEventListener('load', function ()  

// Checking if Web3 has been injected by the browser (Mist/MetaMask)
if (typeof web3 !== 'undefined') 

    // Use Mist/MetaMask's provider
    window.web3 = new Web3(web3.currentProvider); 
    if (web3.currentProvider.isMetaMask === true) 
        if (typeof web3.eth.defaultAccount === 'undefined') 
            document.body.innerhtml = '<body><h1>Oops! Your browser does not support Ethereum Ðapps.</h1></body>';   
        
        else 
            startApp();
        
    
    else 
         alert('No web3? Please use google chrome and metamask plugin to enter this Dapp!', null, null);
        // fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
       window.web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

【问题讨论】:

【参考方案1】:
function _Connect(callback)
    if(typeof web3 !== 'undefined') 
          web3 = new Web3(window.web3.currentProvider);
          web3.version.getNetwork((err, netId) => 
              switch (netId) 
                case "1":
                    callback('Switch Network', null);   
                  break
                case "2":
                  console.log('This is the deprecated Morden test network.');
                  callback('Switch Network', null);
                  break
                case "3":
                    console.log('Connected to the ropsten test network.');
                    web3.eth.defaultAccount = web3.eth.accounts[0];
                    if(!web3.eth.defaultAccount)
                        console.log('Log into metamask');
                        _Connect(callback);
                    else 
                                                    // Success
                        console.log(`Web3 ETH Account: $web3.eth.defaultAccount`);
                        callback(false, web3.eth.defaultAccount);
                       
                  break
                default:
                  console.log('This is an unknown network.');
                  callback('Switch Network', null);
              
            );
         else 
          console.log(`Failed: Web3 instance required, try using MetaMask.`);
          callback('Install Metamask', null);
           

【讨论】:

登录元掩码不会导致页面刷新,所以我使用递归来继续检查他们是否已经登录。所有其他最终调用回调的操作都是状态,如果用户采取行动将导致刷新页面并再次启动_Connect函数。【参考方案2】:

Chrome 插入 MetaMask Web3 库时存在延迟,因此需要超时(1 秒超时应该足够了)。

超时后,检查web3全局对象是否存在,然后读取默认账号。

如果不存在,则插入您自己的 web3 对象。

【讨论】:

以上是关于使用元掩码时检测 web3 默认帐户的更好模式的主要内容,如果未能解决你的问题,请参考以下文章

获取 web3 元掩码中的注册资产

元掩码 web3 未定义

Web3 元掩码连接无法读取未定义的属性(读取“以太坊”)

元掩码未连接到 localhost 8545

Web3 发送没有元掩码的合约方法

如何检查所选帐户是不是有我的自定义令牌?