Ethers.js:在 Maker (MKR) 合約上呼叫 symbol() 時出錯,但對於其他 ERC-20 代幣合約沒有問題
我在使用 ethers 來建構我正在建構的地址跟踪應用程序時遇到了問題。每當我使用我在我的程式碼中編寫的通用 ERC20 ABI 進行呼叫時(我只需要從令牌中檢索符號和小數),對於我測試過的幾乎每個令牌都可以正常工作。但是,對於 Maker 合約https://etherscan.io/address/0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2#code
呼叫 symbol() 將返回以下錯誤:
call revert exception (method="symbol()", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL_EXCEPTION, version=abi/5.3.0)
我已經重新創建了我在這個 ethers 程式碼盒 https://codesandbox.io/s/08bue?file=/src/App.js中遇到的問題
將此程式碼複製並粘貼到沙箱中(對不起,我不想創建帳戶來製作自己的沙箱)
import "./styles.css"; import { ethers } from "ethers"; // A Web3Provider wraps a standard Web3 provider, which is // what Metamask injects as window.ethereum into each page const provider = new ethers.providers.Web3Provider(window.ethereum); //mkr address (doesnt work) const mkrAddress = "0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2" //weth address (works) const wethAddress = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" //abi I am using in my code const ERC20_ABI = [ // Read-Only Functions "function decimals() view returns (uint8)", "function symbol() view returns (string)", ]; //mkr abi from etherscan const MKR_ABI = [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"stop","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"name_","type":"bytes32"}],"name":"setName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"src","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"stopped","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint256"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"push","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"move","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"start","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"src","type":"address"},{"name":"guy","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"wad","type":"uint256"}],"name":"pull","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"symbol_","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}] const contract = new ethers.Contract( mkrAddress, ERC20_ABI, provider ); const getSymbol = async () =>{ let sym = await contract.symbol() console.log(sym) } getSymbol() export default function App() { return ( <div className="App"> <h1>Hello CodeSandbox</h1> <h2>Check console</h2> </div> ); }
查看控制台和顯示屏,您可以看到錯誤。在聲明合約對象時,如果您將製造商合約換成我還包括在內的濕合約,您可以看到它現在執行良好。Maker 是迄今為止我遇到這個問題的唯一代幣。我包含了 etherscan 的 mkr ABI 並使用它似乎可以解決問題,但這對我的應用程序來說並不實用,因為我需要一個通用 ABI 來檢測每個可能的令牌。當我檢測到 mkr 合約地址時,我可以在 mkr ABI 中進行硬編碼,但這似乎不是一個很好的解決方案,特別是如果這可能發生在我不知道的其他代幣上。這個問題是否是由於 mkr 合約的編寫方式使其與大多數 erc20 代幣不同,就其符號而言?呼叫 decimals() 就可以了。我'
Maker 代幣未實現以下建議的可選參數符號和名稱
EIP-20
:正如您在此處看到的,Maker 使用 bytes32 作為符號和名稱。
,在 EIP-20 的情況下,它們都是字元串。
我建議您在嘗試獲取 ERC20 令牌的名稱和符號時只檢查 bytes32 和字元串。這應該涵蓋大多數情況。