Solidity

Ethers.js:在 Maker (MKR) 合約上呼叫 symbol() 時出錯,但對於其他 ERC-20 代幣合約沒有問題

  • June 22, 2022

我在使用 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 和字元串。這應該涵蓋大多數情況。

引用自:https://ethereum.stackexchange.com/questions/130586