如何在自己設計的頁面中調用metamask-1


啟發:

https://github.com/MetaMask/metamask-extension/issues/714

https://github.com/MetaMask/metamask-extension/issues/3383

()

下面是cryptokitties這個游戲使用metamask的方法:

如果你沒有添加metamask並且打開它,你是進不去這個游戲的,你點擊開始游戲,它會一直卡在這里

 

然后當你打開了metamask之后,這時候無論你連接的是什么網絡,這時候應該是探測到了window.web3.currentProvider !== 'undefined'了,然后你就可以進行下一步注冊了

 

上面那樣子就注冊好了,這個時候你就能夠進行登錄了

 

然后點擊登錄后你就能夠看見下面的頁面彈出:

就是你想要進入這個頁面你需要進行簽名

當我的錢包logout了以后,頁面也會一起logout:

 

 然后點擊開始又會出現下面的頁面,這時候用戶也沒有登錄到上面的賬戶:

當然你也可以在網頁上進行一些不需要登錄也能執行的操作,但是當要進行一些操作時,你就可以看見,顯示的是你還沒有登錄,就是錢包下線的同時,網頁賬戶也會跟着下線

 

然后當你在metamask上登錄后,網站狀態就會變成:

 

然后在過程中,點擊我的主頁的時候,有顯示一個錯誤,就是我進入到了錯誤的網絡:

在我的主頁上能看見下面的信息:

可以看見復制地址處的address的確是metamask處現在的賬號

然后這就是網頁與metamask之間的關系,但是怎么實現呢,要接着學習了
 

 

()

Developing for MetaMask

https://github.com/MetaMask/faq/blob/master/detecting_metamask.md

Detecting MetaMask

Metamask/Mist currently inject their interface into page as global web3 object.

window.addEventListener('load', function() { // Checking if Web3 has been injected by the browser (Mist/MetaMask) if (typeof web3 !== 'undefined') { // Use the browser's ethereum provider var provider = web3.currentProvider } else { console.log('No web3? You should consider trying MetaMask!') } })

The provider object is a low-level object with just one supported method: provider.sendAsync(options, callback).

The options object has several useful fields: method (the method name), from (the sender address), params (an array of parameters to send to that method).

These methods all correspond directly to the options in the RPC provider spec.

這個網頁就是教你怎么使用metamask來進行開發的,從這個文檔我好像明白了什么,就是其實metamask是提供整個web3接口的,就是我們直接在網頁上進行對metamask的web3進行調用即可,它給的web3接口的詳細信息在https://github.com/ethereum/wiki/wiki/JSON-RPC上有寫

To see if the injected provider is from MetaMask, you can check web3.currentProvider.isMetaMask.

 

Installing Web3.js

Because default web3 API is not very user friendly, most developers will import a convenience library like Web3.js or EthJS using the bundler of their choice.

就是說一般默認的那個web3可能使用得並不是很方便,所以其實我們是能夠自己下載Web3.js的庫來進行調用的;或者使用  EthJS ,就是一個輕量級的eth的使用方法:

Installing EthJS

npm install --save ethjs

Using a Convenience Library

Once you've detected an Ethereum browser, and imported a convenience library, you can initialize that library using the detected web3.currentProvider object. For web3 with browserify, this might look like this:

var Web3 = require('web3') var localWeb3 = new Web3(web3.currentProvider)

Initializing an EthJS instance looks similar:

const Eth = require('ethjs'); const eth = new Eth(web3.currentProvider);

當然我還是選擇第一個,但是如果想學習第二個,可以看https://github.com/ethjs/ethjs,有空看看

 

 

()

想要使用第一種方法web3.js library的話,就看下面的網址的內容

但是吧,如果你的瀏覽器本身就已經安裝了metamask,那你就可以直接在網頁上使用web3了,而不用還要跟下面這樣鏈接

當然,如果你只是想在網頁上調用web3,與metamask無關,那么就繼續往下看,不然就跳過這一部分

Ethereum JavaScript API

https://github.com/ethereum/web3.js

這就是JavaScript API 的接口

網址上的調用方法就是加上這一句話:

<script src="https://cdn.jsdelivr.net/gh/ethereum/web3.js/dist/web3.min.js"></script>

 

As a Browser module

CDN

<script src="https://cdn.jsdelivr.net/gh/ethereum/web3.js/dist/web3.min.js"></script>
到這個網址上看https://cdn.jsdelivr.net/gh/ethereum/web3.js/dist/,長成下面這樣:

上面的是0.20版本的,當然也有1.0版本的,https://www.jsdelivr.com/package/gh/ethereum/web3.js?version=1.0.0-beta.22&path=dist

 

<script src="https://cdn.jsdelivr.net/gh/ethereum/web3.js@1.0.0-beta.36/dist/web3.min.js"></script>

所以就是調用這些js包后,就可以更之前一樣調用web3啦

但是調用了1.0版本的包,得出來的結果還是0.20版本
<script src="https://cdn.jsdelivr.net/gh/ethereum/web3.js@1.0.0-beta.36/dist/web3.min.js"></script> <script type="text/javascript"> console.log(web3.version);

然后瀏覽器返回結果是

MetaMask: web3 will be deprecated in the near future in favor of the ethereumProvider https://github.com/MetaMask/faq/blob/master/detecting_metamask.md#web3-deprecation inpage.js:1:2023 {…} ​ api: "0.20.3"

但是后面一想,這個是單純地使用web3的方法,我這里是要和metamask連在一起,所以就不能用web3.min.js了,或許有什么方法可以改變metamask的web3的版本,但是我們現在先把0.20 的版本學會吧

 

注意:

有個web3需要注意的地方:

一開始聲明的方法有所改變 ,就是從

web3 = require('web3');

變成了

var Web3 = require('web3');

var web3 = new Web3();

 

 

 ()

接着看:https://github.com/MetaMask/faq/blob/master/DEVELOPERS.md

MetaMask Compatibility Guide

接的是0.20版本的web3.js:https://github.com/ethereum/wiki/wiki/JavaScript-API

然后使用metamask的情況就是,在html的JavaScript中:

<script type="text/javascript"> console.log(web3.version); window.addEventListener('load', function() { // Checking if Web3 has been injected by the browser (Mist/MetaMask) if (typeof web3 !== 'undefined') { console.log(web3); // Use the browser's ethereum provider var provider = web3.currentProvider console.log(provider); } else { console.log('No web3? You should consider trying MetaMask!') } }

 

結果是返回:

MetaMask: web3 will be deprecated in the near future in favor of the ethereumProvider https://github.com/MetaMask/faq/blob/master/detecting_metamask.md#web3-deprecation inpage.js:1:2023 {…} ​ api: "0.20.3" ​ ... ​ <prototype>: Object { … } createAndBuyToken:381:5 Proxy ​ <target>: {…} ​​ _extend: function e() ​​ _requestManager: Object { provider: {…}, polls: {}, timeout: null } ​​ bzz: Object { _requestManager: {…}, blockNetworkRead: e() , syncEnabled: e() , … } ​​ currentProvider: Object { mux: {…}, publicConfigStore: {…}, rpcEngine: {…} } ​​ ...

那如果我的metamask不是登錄狀態,那又應該是怎樣呢:

如果不是登錄狀況,檢測的方法是查看其的web3.eth.coinbase,詳細內容看本博客的如何在自己設計的頁面中調用metamask-2

 

 All Async - Think of MetaMask as a light client

The user does not have the full blockchain on their machine, so data lookups can be a little slow. For this reason, we are unable to support most synchronous methods. The exceptions to this are,就是在metamask的web3中的調用基本上都是異步的,下面的幾個除外:

  • eth_accounts (web3.eth.accounts)
  • eth_coinbase (web3.eth.coinbase)
  • eth_uninstallFilter (web3.eth.uninstallFilter)
  • web3.eth.reset (uninstalls all filters).
  • net_version (web3.version.network).

Usually, to make a method call asynchronous, add a callback as the last argument to a synchronous method. See the Ethereum wiki on "using callbacks"

Using synchronous calls is both a technical limitation and a user experience issue. They block the user's interface. So using them is a bad practice, anyway. Think of this API restriction as a gift to your users.

 

舉個異步例子:

 Network check

When a user interacts with a dapp via MetaMask, they may be on the mainnet or testnet. As a best practice, your dapp should inspect the current network via the net_version json rpc call. Then, the dapp can use the correct deployed contract addresses for the network, or show which network is expected in a message.

For example:

查看你的metamask連接的網絡是什么,即其的networkId是多少,即chainId是多少來得到信息:

web3.version.getNetwork((err, netId) => {
  switch (netId) {
    case "1":
      console.log('This is mainnet')
      break
    case "2":
      console.log('This is the deprecated Morden test network.')
      break
    case "3":
      console.log('This is the ropsten test network.')
      break
    case "4":
      console.log('This is the Rinkeby test network.')
      break
    case "42":
      console.log('This is the Kovan test network.')
      break
    default:
      console.log('This is an unknown network.')
  }
})

:shipit: Account management and transaction signing is managed externally to the dapp

Many Dapps have a built-in identity management solution as a fallback. When an Ethereum Browser environment has been detected, the user interface should reflect that the accounts are being managed externally.

var accounts = web3.eth.accounts;
console.log(accounts); // ["0x407d73d8a49eeb85d32cf465507dd71d507100c1"] 

在這里得到的賬戶的信息都是錢包里的賬戶

Also see the Ethereum wiki on "accounts"

🙋 Account List Reflects User Preference

When a user selects an account in MetaMask, that account silently becomes the web3.eth.accounts[0] in your JS context, the only member of the web3.eth.accounts array.

當你在metamask選擇了使用其中一個賬戶后,他就被指定為web3.eth.accounts[0]或web3.eth.defaultAccount

For your convenience, consider the web3.eth.defaultAccount variable a dapp-provided variable. However, it should not be used as a data source of user intention.

👂 Listening for Selected Account Changes 監聽賬戶的變化

Since these variables reflect user intention, but do not (currently) have events representing their values changing, we somewhat reluctantly recommend using an interval to check for account changes.

For example, if your application only cares about the web3.eth.accounts[0] value, you might add some code like this somewhere in your application:

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

 

上面的那個是JavaScript版本的web3js調用的API,當然還有其他版本的,如java的、PHP的

之前寫JavaScript的寫習慣了,還是用這個

Other implementations

 

然后后面進行了一次簡單的調用

      window.addEventListener('load', function() {

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

            var provider = web3.currentProvider;
            console.log(web3.eth.accounts[0]);

          } else {
            console.log('No web3? You should consider trying MetaMask!')
          }

        })

結果是:

{…}
​
BuyToken: function ()
​
CreateAndBuyToken: function ()
​
RevocateSell: function ()
​
SellToken: function ()
​
Send: function ()
​
_eth: Object { _requestManager: {…}, getBalance: e()
, getStorageAt: e()
, … }
​
abi: Array(24) [ {…}, {…}, {…}, … ] ​ address: "0x4eb2bb88ac610f989d07..." ​ ... withdrawl: function () ​ <prototype>: Object { … } createAndBuyToken:433:13 0x3455f15cc11f2e77c055...

但是可以看見,返回的賬戶的值是你的錢包metamask里面的第一個賬號的值,說明你成功連接上了metamask

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM