MetaMask 使我們能夠通路去中心化應用程式 (dApp),同時使用 MetaMask 錢包提供一種身份驗證形式。它提供一鍵式安全登入流程,允許我們在前端使用以太币通路區塊鍊資源。[1]MetaMask 抽象出微妙的過程,例如在與區塊鍊互動時簽署交易,并将您的 MetaMask 的公共位址提供給應用程式。
是以,作為開發者,在建構這些dApps時,難免會出現錯誤,而這些錯誤應該得到妥善處理,讓開發者和使用者都知道哪裡出了問題。由于 MetaMask 文檔沒有針對使用 MetaMask 時可能出現的多種錯誤的全面而清晰的指南,是以我在此處編制了一份最常見錯誤及其含義的清單。
4001
當嘗試連接配接到錢包時,如果使用者在此界面上的任意位置單擊“取消”并終止該過程,則會傳回4001錯誤。
這是錯誤的 JSON 結構:
'4001': {
standard: 'EIP-1193',
message: 'User rejected the request.',
},
4100
當 dApp 想要對未經授權的帳戶采取行動時,會發生此錯誤。
例如,要執行某些操作(如簽名消息),您需要先使用以下eth_requestAccounts方法從 MetaMask 獲得帳戶權限:
import { ethers } from "ethers";
const accounts = await ethereum.request({
method: "eth_requestAccounts",
});
const address = accounts[0];
const provider = new ethers.providers.Web3Provider(ethereum);
const signer = provider.getSigner();
const signature = await signer.signMessage(address);
console.log(signer);
同樣,要切換你的錢包鍊,你需要使用該wallet_switchEthereumChain方法,該方法依次通過 MetaMask 擴充程式請求權限:
// switching the chain for MetaMask wallet
await provider.request({
method: "wallet_switchEthereumChain",
params: [{ chainId: "0x89" }],
});
如果權限被拒絕,錢包将傳回此錯誤:
'4100': {
standard: 'EIP-1193',
message: 'The requested account and/or method has not been authorized by the user.',
},
4200
MetaMask 啟用兩種方法:受限和不受限。這些方法允許 dApp 執行連接配接到錢包、簽署交易以及添加或切換網絡等操作。
MetaMask 不支援的方法會傳回此錯誤:
'4200': {
standard: 'EIP-1193',
message: 'The requested method is not supported by this Ethereum provider.',
},
您可以在此處找到指向現有方法的連結[2]。
4900
當使用者的 MetaMask 錢包未連接配接任何鍊時傳回此錯誤:
ethereum.on('disconnect', (error) => console.log(error));
這與disconnect事件有關。當錢包斷開連接配接并且無法向鍊送出請求時會觸發此事件。除了斷開連接配接,這也可能由于網絡連接配接問題而發生。
一旦我們發出disconnect,提供者将不會接受任何新的請求,直到重建立立與鍊的連接配接,這需要重新加載頁面。您還可以使用ethereum.isConnected() 方法[3]來确定提供程式是否已斷開連接配接。
這是錯誤的 JSON 響應:
'4900': {
standard: 'EIP-1193',
message: 'The provider is disconnected from all chains.',
},
4901
此錯誤意味着使用者未連接配接到該交易的适當鍊。例如,如果交易要求使用者在 Polygon 鍊上,而他們在Harmony 或以太坊區塊[4]鍊上。
需要注意的一件事是,MetaMask 提供程式允許我們監聽chainChanged事件,如果目前連接配接的鍊發生變化,該事件将監聽并采取行動:
ethereum.on('chainChanged', (chainId) => {console.log(chainId)});
我們将 RPC 請求送出[5]給目前連接配接的鍊,這使得通過監聽變化來跟蹤目前鍊 ID 變得很重要。每條鍊都有其唯一的 chainID,您可以在Chainlist 上找到它。[6]
如果它無法向該特定鍊送出 RPC 請求,它會傳回錯誤:
'4901': {
standard: 'EIP-1193',
message: 'The provider is disconnected from the specified chain.',
}
32700
如果使用者向合約發送不完整的請求對象,則會傳回此錯誤。如果發送給合約的對象不包含它需要的所有資料,就會發生這種情況。
這是 JSON 響應:
'-32700': {
standard: 'JSON RPC 2.0',
message: 'Invalid JSON was received by the server. An error occurred on the server while parsing the JSON text.',
},
32600
此處,對象有效,但結構或屬性不正确。它有點類似于 32700,但在這種情況下,它的内部結構不正确。
這是 JSON 響應:
'-32600': {
standard: 'JSON RPC 2.0',
message: 'The JSON sent is not a valid Request object.',
},
32601
如果指定的方法根本不存在,則傳回此錯誤:
'-32601': {
standard: 'JSON RPC 2.0',
message: 'The method does not exist / is not available.',
},
您可以在此處找到指向現有方法的連結[7]。
32602
如果傳遞給RPC 方法[8]的參數不正确,我們會收到此錯誤。例如,在定義transactionParameters 時,from屬性引用accounts[0]。
通常,accounts[0]應該是使用者的錢包位址,但在這種情況下,我們将其配置設定給一個空數組:
let accounts = [];
const amountEth = 1
const paymentAddress = '0x71C7656EC7ab88b098defB751B7401B5f6d8976F'
const transactionParameters = { from: accounts[0], to: paymentAddress, value: web3.toWei(amountEth, 'ether') };
function Mint(){
ethereum.request({ method: 'eth_sendTransaction', params: [transactionParameters] });
}
該Mint函數将傳回此特定錯誤,因為參數顯然無效:
'-32602': {
standard: 'JSON RPC 2.0',
message: 'Invalid method parameter(s).',
},
32603
這是由幾件事引起的一攬子錯誤。這可能是因為您正在嘗試向您的錢包添加一條新鍊(手動或通過 dApp)但添加了錯誤的鍊資料。或者,你正試圖完成一筆交易,但你沒有足夠的代币來支付 gas 費。例如,如果您在以太坊主網上進行交易,則無論您是否使用其他代币進行交易,都必須以 ETH 支付汽油費。
最後,它可能與沒有最新版本的 MetaMask 一樣微不足道。
這是錯誤的 JSON 響應:
'-32603': {
standard: 'JSON RPC 2.0',
message: 'Internal JSON-RPC error.',
},
32000
可能觸發此錯誤的一種情況是,生産中使用的合約位址是您部署到測試網的合約。這是一個我們可以糾正的簡單錯誤。
類似于我們擁有開發環境和生産環境的 Web2,在建構 dApp 時,我們使用測試網部署我們的合約,是以我們可以在建構時測試它,而無需在主網上使用真正的 ETH。是以,部署在測試網和主網上的同一份合約将具有不同的位址。如果您為您所在的鍊使用了錯誤的位址,則會傳回此錯誤。
一般來說,在處理智能合約時,你需要像合約位址、ABI 檔案和你的簽名者這樣的參數:
const provider = new ethers.providers.Web3Provider(ethereum);
const signer = provider.getSigner();
const countContract = new ethers.Contract(contractAddress, contractABI, signer);
/*
* Call the getAllCount method from your Smart Contract
*/
const count = await countContract.getAllCount()
如果這些參數中的任何一個錯誤,您很可能會得到他的錯誤,也稱為“使用者輸入錯誤”:
'-32000': {
standard: 'EIP-1474',
message: 'Invalid input.',
},
32001
在這種情況下,我們請求的資源在區塊鍊上不存在。這可能是用戶端的錯字。
想象一下,您正在嘗試擷取有關 ETH 鍊上不存在的塊号的資訊:
import Web3 from 'web3';
const web3 = new Web3(web3Provider);
var block = await web3.eth.getBlock({invalid block number})
你會得到這個 JSON 響應:
'-32001': {
standard: 'EIP-1474',
message: 'Resource not found.',
},
32002
此錯誤表示請求的資源确實存在,但在請求時目前不可用。當我們嘗試通路目前正在使用的資源時,可能會發生這種情況。當您嘗試使用特定資源/方法時,它可能會在 MetaMask 擴充上發生,例如當 MetaMask 目前正在執行相同操作時切換鍊。
在建構你的 dApp 時,你應該學會在該方法成功啟動後禁用你的按鈕,這樣使用者就不會快速連續點選。
這是此錯誤的 JSON 響應:
'-32002': {
standard: 'EIP-1474',
message: 'Resource unavailable.',
},
32003
這個錯誤可能是很多事情的結果。可能是因為發件人位址不存在,資金不足,賬戶被鎖定,或者我們無法簽署交易。要解決此問題,請確定交易中的所有内容都是正确的。
如果不滿足完成交易所需的條件,則可以拒絕交易:
'-32003': {
standard: 'EIP-1474',
message: 'Transaction rejected.',
},
32004
完全不支援該方法。可能它不存在或者隻是一個印刷錯誤:
'-32004': {
standard: 'EIP-1474',
message: 'Method not supported.',
},
32005
此錯誤表示 RPC 提供程式已超出速率限制。如果 RPC 提供程式終結點對請求數有速率限制,則可能會出現此問題:
'-32005': {
standard: 'EIP-1474',
message: 'Request limit exceeded.',
},
此外,錯誤消息“intrinsic gas too low”是一個相當常見的錯誤。這僅僅是因為在啟動交易時配置設定的氣體限制小于所需的限制。
這種情況最常發生在交易複雜的情況下,這可能會使汽油費無法預測:
ethereum
.request({
method: 'eth_sendTransaction',
params: [
{
from: accounts[0],
to: '0xbCfDCCDbE7B3D681A1144D25a31e0D4BE869079a',
value: '0x293434x341af62c0000',
gasPrice: '0x09184e242',
gas: '0x2709',
gasLimit: '0x2723'
},
],
})
.then((txHash) => console.log(txHash))
.catch((error) => console.error);
結論
如果你已經走到最後,恭喜你!我們介紹了一堆可能的錯誤以及如何處理它們。現在,在建構你的下一個 dApp 時,你可以輕松地解釋這些錯誤并修複它們,而不必對最初導緻它們的原因感到困惑。這有助于改善您處理這些 Web3 技術的開發人員體驗。
您可以從官方資源[9]中檢視有關 MetaMask 錯誤的更多資訊。
引用連結
[1] 以太币通路區塊鍊資源。: https://docs.ethers.io/
[2] 您可以在此處找到指向現有方法的連結: https://docs.metamask.io/guide/rpc-api.html#ethereum-json-rpc-methods
[3] 方法: https://docs.metamask.io/guide/ethereum-provider.html#ethereum-isconnected
[4] Harmony 或以太坊區塊: https://blog.logrocket.com/ethereum-vs-harmony-which-blockchain-right-for-you/
[5] 将 RPC 請求送出: https://blog.logrocket.com/leverage-ethereum-blockchain-data-json-rpc/
[6] Chainlist 上找到它。: https://chainlist.org/
[7] 您可以在此處找到指向現有方法的連結: https://docs.metamask.io/guide/rpc-api.html#ethereum-json-rpc-methods
[8] 如果傳遞給RPC 方法: https://docs.metamask.io/guide/rpc-api.html#ethereum-json-rpc-methods
[9] 您可以從官方資源: https://eips.ethereum.org/EIPS/eip-1474