Erc-20
Ethersjs - 獲取 ERC20 合約小數
我有以下內容:
import { ethers } from "ethers"; import { ws } from "../providers/node"; import abi from "../abi"; export default async (address: string) => { const tokenContract = new ethers.Contract(address, abi, ws); return { name: await tokenContract.name(), symbol: await tokenContract.symbol(), supply: await tokenContract.totalSupply(), decimals: await tokenContract.decimals(), }; };
abi 是在這裡找到的標準 erc20 abi:https ://ethereumdev.io/abi-for-erc20-contract-on-ethereum/
{ constant: true, inputs: [], name: "decimals", outputs: [ { name: "", type: "uint8", }, ], payable: false, stateMutability: "view", type: "function", },
除了
decimals()
函式的最後一個呼叫之外,所有這些呼叫都很好。我不斷收到以下錯誤:
cannot estimate gas; transaction may fail or may require manual gas limit
我嘗試像這樣設置呼叫的氣體限制:
await tokenContract.decimals({ gasLimit: "750000", });
但這再次導致相同的錯誤。
有沒有人能夠建議為什麼這可能會失敗?
我查詢的合約地址是有效的 ERC20 合約。
一般來說
name
,symbol
和decimal
是根據EIP-20的可選方法,因此您應該準備好處理這些方法錯誤或返回無效數據。還有一些合約以不同的方式實現這一點(例如,通過返回
bytes32
或觸發它們的回退方法),所以如果你想防彈,你應該對這些呼叫添加一些檢查。這種代幣合約的一個例子是“TheDAO”代幣:https ://etherscan.io/address/0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413#code
您嘗試查詢的合約(0x1800b081333A08bc5faAbb19a51dfCa15C1dfF21)是使用 ABIEncoderV2 編譯的,因此 etherjs 在使用用於呼叫 ABIV2 編譯合約的 ABIV1 時可能存在一些問題。
小數的定義與 V2 略有不同,但也與其他欄位不同,因此這並不能解釋為什麼您只在小數上出現錯誤,而只是嘗試直接從原始碼生成的 ABIV2:
[ { "inputs": [ { "internalType": "address", "name": "_wallet1", "type": "address" } ], "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, { "indexed": true, "internalType": "address", "name": "spender", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } ], "name": "Approval", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "previousOwner", "type": "address" }, { "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" } ], "name": "OwnershipTransferred", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } ], "name": "Transfer", "type": "event" }, { "inputs": [], "name": "_limitedbuys", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "owner", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" } ], "name": "allowance", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "approve", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" } ], "name": "balanceOf", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "decimals", "outputs": [ { "internalType": "uint8", "name": "", "type": "uint8" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "subtractedValue", "type": "uint256" } ], "name": "decreaseAllowance", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "dexPair", "outputs": [ { "internalType": "address", "name": "", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "dexRouter", "outputs": [ { "internalType": "contract IDexRouter", "name": "", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "addedValue", "type": "uint256" } ], "name": "increaseAllowance", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "bool", "name": "value", "type": "bool" } ], "name": "limitedbuys", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "name", "outputs": [ { "internalType": "string", "name": "", "type": "string" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "owner", "outputs": [ { "internalType": "address", "name": "", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "symbol", "outputs": [ { "internalType": "string", "name": "", "type": "string" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "totalSupply", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "transfer", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "transferFrom", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "newOwner", "type": "address" } ], "name": "transferOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "wallet1", "outputs": [ { "internalType": "address", "name": "", "type": "address" } ], "stateMutability": "view", "type": "function" } ]