第二十八課 區(qū)塊鏈應(yīng)用DAPP如何探測(cè)MetaMask的賬號(hào)和登錄狀態(tài)?

1,摘要

目前PC版區(qū)塊鏈DAPP應(yīng)用中,大部分程序都是使用MetaMask作為去中心話錢包進(jìn)行交易操作。
那么,作為程序員,如何實(shí)現(xiàn)類似的功能呢?通過本文學(xué)習(xí),你可以了解:
1)加密貓的賬戶檢測(cè)流程
2) 檢測(cè)MetaMask是否已安裝
3)檢測(cè)MetaMask賬號(hào)已鎖定
4)探測(cè)MetaMask是否處于主網(wǎng)
5)探測(cè)監(jiān)聽賬號(hào)有變化

2, 加密貓的購買和賬戶檢測(cè)流程

1)是否安裝MetaMask插件
點(diǎn)擊https://www.cryptokitties.co/ 訪問加密貓網(wǎng)站時(shí),如果對(duì)應(yīng)的PC瀏覽器chrome/360瀏覽器沒有安裝MetaMask查件,會(huì)有如下提示:

2)注冊(cè)和以太坊地址簽名授權(quán)認(rèn)證
當(dāng)你安裝好metamask之后,這時(shí)候無論你連接的是什么網(wǎng)絡(luò),這時(shí)候應(yīng)該是探測(cè)到了window.web3.currentProvider !== 'undefined'了,然后你就可以進(jìn)行下一步注冊(cè)了。

注冊(cè)賬號(hào)

同意隱私條款

進(jìn)行以太坊地址簽名授權(quán)認(rèn)證:
簽名授權(quán)

完成簽名授權(quán)后,就類似于微信授權(quán)登錄,網(wǎng)站認(rèn)同你的操作是賬號(hào)擁有者本人的操作。

3)MetaMask退出狀態(tài)
當(dāng)MetaMask錢包logout了以后,頁面也會(huì)一起logout。

提示登錄MetaMask

當(dāng)用戶登錄后,該提示消失。
用戶登錄MetaMask

4),探測(cè)MetaMask是否處于主網(wǎng)
當(dāng)用戶切換到非主網(wǎng)時(shí),會(huì)有以下提示。更好為第一個(gè)主網(wǎng)后,這個(gè)提示會(huì)消失。

提示網(wǎng)絡(luò)不正確

3, MetaMask賬戶檢測(cè)流程的代碼實(shí)現(xiàn)

作為程序員,總是喜歡刨根問底,這個(gè)代碼是怎么實(shí)現(xiàn)的呢?
輝哥這兒來逐個(gè)解釋下。

1)MetaMask插件是否已安裝
檢測(cè)樣例代碼:

// Checking if Web3 has been injected by the browser (Mist/MetaMask)
    if (typeof web3 !== 'undefined') {
         App.web3Provider = web3.currentProvider
         web3 = new Web3(App.web3Provider);

         /* To see if the injected provider is from MetaMask */
         if(web3.currentProvider.isMetaMask) {
          console.log('The injected provider is from MetaMask!')
         }
     } else {
      console.log('No web3? You should consider trying MetaMask!')
      window.alert('No web3? You should consider trying MetaMask!');

         /*
         App.web3Provider = new Web3.providers.HttpProvider("http://localhost:9545")
         web3 = new Web3(App.web3Provider);*/
     }

上面代碼包含是否存在web3,如果web3已定義,則表示瀏覽器存在Mist/MetaMask錢包插件,否則不存在。
web3.currentProvider.isMetaMask用于判斷該web3是否是MetaMask插件。

2)檢測(cè)MetaMask賬號(hào)是否已退出
樣例代碼:

    /*這個(gè)是判斷你有沒有登錄,coinbase是你此時(shí)選擇的賬號(hào)*/
     if (!web3.eth.coinbase) {
      window.alert('Please LOGIN MetaMask first.');
      return;
    } else {
      console.log('MetaMask is Login.')
    }

如果不是登錄狀況,檢測(cè)的方法是查看其的web3.eth.coinbase是否有效。

3)探測(cè)MetaMask是否處于主網(wǎng)
樣例代碼:

/* 只有在the ropsten test network才允許操作 */
    web3.version.getNetwork((err, netId) => {
      switch (netId) {
        case "1":
          window.alert('切換到the ropsten test network網(wǎng)絡(luò)再操作!');
          console.log('This is mainnet');
          return;
        case "2":
          window.alert('切換到the ropsten test network網(wǎng)絡(luò)再操作!');
          console.log('This is the deprecated Morden test network.');
          return;
        case "3":
          console.log('This is the ropsten test network.');
          break;
        case "4":
          window.alert('切換到the ropsten test network網(wǎng)絡(luò)再操作!');
          console.log('This is the Rinkeby test network.');
          return;
        case "42":
          window.alert('切換到the ropsten test network網(wǎng)絡(luò)再操作!');
          console.log('This is the Kovan test network.');
          return;
        default:
          window.alert('切換到the ropsten test network網(wǎng)絡(luò)再操作!');
          console.log('This is an unknown network.');
          return;
      }
    });

此段代碼表示只有MetaMask錢包處于"the ropsten test network"網(wǎng)絡(luò)下(netId == 3)下才不返回,在其他網(wǎng)絡(luò)下都不返回。有些場(chǎng)景是只有處于主網(wǎng)下才能操作,修改不同case下的代碼即可。

4)探測(cè)監(jiān)聽賬號(hào)有變化

var account = web3.eth.accounts[0];
var accountInterval = setInterval(function() {
  if (web3.eth.accounts[0] !== account) {
    account = web3.eth.accounts[0];
    updateInterface();
  }
}, 100);

就是檢測(cè)當(dāng)前賬號(hào)account是否同web3.eth.accounts[0]的賬號(hào)。

5) MetaMask授權(quán)登錄
這個(gè)相對(duì)比較負(fù)責(zé),單獨(dú)有一篇文章講清楚。

4,代碼實(shí)現(xiàn)和測(cè)試

我們?cè)?a href="http://www.lxweimin.com/p/ecaa4dc22bef" target="_blank">第二十六課 如何從零開始搭建一個(gè)Truffle框架的DAPP應(yīng)用基礎(chǔ)上增加相關(guān)的檢測(cè)代碼完成相關(guān)功能。
1) 增加合約部署網(wǎng)絡(luò)配置
truffle.js 增加測(cè)試ropsten網(wǎng)絡(luò)和mainnet主網(wǎng)的配置。另外需要增加.env文件用于讀取助記詞。對(duì)配置不了解的,可參考文章第二十三課 如何部署TRUFFLE智能合約到以太坊主網(wǎng)(以寵物商店為例),便于智能合約能部署到ropsten網(wǎng)絡(luò)和mainnet主網(wǎng),而不僅僅是本地網(wǎng)絡(luò)。

const dotenv = require('dotenv');
const result = dotenv.config();
if (result.error) {
  throw result.error;
}
console.log(result.parsed);

var NonceTrackerSubprovider = require("web3-provider-engine/subproviders/nonce-tracker");
var HDWalletProvider = require("truffle-hdwallet-provider");

/*訪問https://infura.io/注冊(cè)后獲取的api-key*/
var infura_apikey = "8ce5ebd357144bef8dceae3de1915e29";

/*讀取.env文件配置的助記詞*/
var mnemonic_ropsten = process.env.mnemonic_ropsten;
var mnemonic_mainnet = process.env.mnemonic_mainnet;

module.exports = {
  // See <http://truffleframework.com/docs/advanced/configuration>
  // to customize your Truffle configuration!
  networks: {
    development: {
      host: "127.0.0.1",
      port: 7545,
      network_id: "*", // Match any network id
      gas: 4500000
    },
    local: {
      host: "127.0.0.1",
      port: 8545,
      network_id: "*", // Match any network id
      //gas: 4300000
    },
    ropsten: {
      provider: new HDWalletProvider(mnemonic_ropsten, "https://ropsten.infura.io/"+infura_apikey),
      network_id: 3,
      gas: 3012388,
      gasPrice: 30000000000
    },
    mainnet: {
      provider: function () {
        var wallet = new HDWalletProvider(mnemonic_mainnet, "https://mainnet.infura.io/Np7IGWoN2UOb0tgRWx55");
        var nonceTracker = new NonceTrackerSubprovider();
        wallet.engine._providers.unshift(nonceTracker);
        nonceTracker.setEngine(wallet.engine);
        return wallet;
      },
      gas: 6000000,
      network_id: 1,
      gasPrice: 10 * 1000000000
    }
  }
};

2) 增加合約部署網(wǎng)絡(luò)配置
我們把目錄名字改為detect-mask,把合約部署上去。
1] 安裝truffle-hdwallet-provider,dotenv配置
第二十三課 如何部署TRUFFLE智能合約到以太坊主網(wǎng)(以寵物商店為例)詳細(xì)介紹安裝truffle-hdwallet-provider,dotenv配置的方法。安裝之后可以運(yùn)行truffle.js的代碼。

~/work/detect-metamask$npm install truffle-hdwallet-provider

~/work/detect-metamask$npm install dotenv

2] 安裝truffle-hdwallet-provider,dotenv配置

3] 部署合約到ropsten網(wǎng)絡(luò)
部署前記得要把你的MetaMask的助記詞輸入到.env文件配置好。
MetaMask的第一個(gè)賬號(hào)有ropsten 測(cè)試網(wǎng)絡(luò)的1個(gè)以上的ETH。

~/work/detect-metamask$truffle migrate --network ropsten --reset --compile-all

輸出成功提示:

duncanwang@ubuntu:~/work/detect-metamask$ truffle migrate --network ropsten  --reset --compile-all
{ mnemonic_ropsten: 'mosquito electric slim hybrid craft change shrimp digital car wonder term oven',
  mnemonic_mainnet: '' }
Compiling ./contracts/InfoContract.sol...
Compiling ./contracts/Migrations.sol...
Writing artifacts to ./build/contracts

Using network 'ropsten'.

Running migration: 1_initial_migration.js
  Deploying Migrations...
  ... 0x00ae767a18708401a0ab9d09923f71be10e9c4bbcef1f500d0fb9764c3752a2d
  Migrations: 0x2dbd179c7ba53cc86822c452e66890735251512c
Saving successful migration to network...
  ... 0x8e09b242e3db42a10e67d45a6b65becc5a747aca9f6bf3db81311dcda7d84bfb
Saving artifacts...
Running migration: 2_info_contract.js
  Deploying InfoContract...
  ... 0x33e4245f1248eee14e075d36ad426f0593d284445691ba2dfcba8becbd2c025d
  InfoContract: 0xf83fc52facdcd73782d927fdd1e0ac94e9b36a52
Saving successful migration to network...
  ... 0x7c1f6621db07f5e5894ceb0c556690abea6c26ba838dc3673e0f6fb5503f4b79
Saving artifacts...

4] 安裝lite-server,并在新窗口啟動(dòng)lite-server

~/work/detect-metamask$ npm install lite-server --save-dev

~/work/detect-metamask$ npm run dev

3) 測(cè)試CHROME中不存在MetaMask插件
當(dāng)CHROME瀏覽器不存在MetaMask時(shí),會(huì)提示需要安裝MetaMask插件。

4) 測(cè)試CHROME中MetaMask處于logout狀態(tài)時(shí)
當(dāng)MetaMask處于LOGOUT狀態(tài)時(shí),

image.png

更新主頁會(huì)有登錄提示:

image.png

5) 當(dāng)MetaMask處于主網(wǎng)時(shí),會(huì)有網(wǎng)絡(luò)配置錯(cuò)誤提示

image.png

6) 當(dāng)MetaMask處于Ropsten測(cè)試網(wǎng)絡(luò),進(jìn)行更新操作
更新輸入“王登輝”“18”,點(diǎn)擊更新。

image.png

MetaMask交易確認(rèn)后,智能合約更新成功。


image.png

5,完整代碼下載

如果不想從頭建立工程,可直接從輝哥的知識(shí)星球拉取代碼。
歡迎加入輝哥知識(shí)星球,從中下載本案例代碼工程,也可加專門微信群交流技術(shù)問題。

掃碼加入
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容