Wie behandelt man sowohl String- als auch Bytes32-Methodenrückgaben?

Ich habe den folgenden Code, um ERC20-Token-Symbole aus Adressen zu extrahieren:

const AllTokenSymbols = await Promise.all(
    allTokens.map(tokenAddress => {
        const tokenContract = new web3.eth.Contract(detailedERC20ABI, tokenAddress);
        return tokenContract.methods.symbol().call();
    })
);

Aber es scheint, dass einer der Token bytes32den Symboltyp anstelle des stringTyps hat: https://etherscan.io/address/0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2#readContract

Uncaught (in promise) Error: ERROR: The returned value is not a convertible string:
    at o.formatOutputString [as _outputFormatter] (https://multitoken.github.io/MultiToken/js/web3.min.js:1:469203)
    at o.decode (https://multitoken.github.io/MultiToken/js/web3.min.js:1:476648)
    at https://multitoken.github.io/MultiToken/js/web3.min.js:1:472761
    at Array.forEach (<anonymous>)
    at m.decodeParameters (https://multitoken.github.io/MultiToken/js/web3.min.js:1:472728)
    at M.l._decodeMethodReturn (https://multitoken.github.io/MultiToken/js/web3.min.js:1:669532)
    at c.outputFormatter (https://multitoken.github.io/MultiToken/js/web3.min.js:1:674775)
    at c.formatOutput (https://multitoken.github.io/MultiToken/js/web3.min.js:1:330711)
    at o (https://multitoken.github.io/MultiToken/js/web3.min.js:1:334321)
    at https://multitoken.github.io/MultiToken/js/web3.min.js:1:415963
    at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/inpage.js:1:89025
    at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/inpage.js:1:8261
    at i (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/inpage.js:1:26492)
    at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/inpage.js:1:11091
    at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/inpage.js:1:8261
    at u (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/inpage.js:1:11367)
    at s (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/inpage.js:1:11289)
    at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/inpage.js:1:11091
    at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/inpage.js:1:88390
    at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/inpage.js:1:89974
    at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/inpage.js:1:20704
    at u (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/inpage.js:1:11381)
From previous event:
    at j.F [as _captureStackTrace] (https://multitoken.github.io/MultiToken/js/web3.min.js:1:351026)
    at j._resolveFromExecutor (https://multitoken.github.io/MultiToken/js/web3.min.js:1:378765)
    at new j (https://multitoken.github.io/MultiToken/js/web3.min.js:1:372241)
    at o (https://multitoken.github.io/MultiToken/js/web3.min.js:1:412425)
    at r (https://multitoken.github.io/MultiToken/js/web3.min.js:1:334238)
    at Object.l._executeMethod (https://multitoken.github.io/MultiToken/js/web3.min.js:1:674963)
    at Promise.all.allTokens.map.token (https://multitoken.github.io/MultiToken/js/multitoken.js:239:55)
    at Array.map (<anonymous>)
    at HTMLSelectElement.<anonymous> (https://multitoken.github.io/MultiToken/js/multitoken.js:237:23)

Gibt es eine einfache Möglichkeit, dies zu handhaben, ohne eine Reihe von Versprechungen auszurollen?

Antworten (1)

So gelöst:

const detailedERC20ABI = [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"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":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_decimals","type":"uint8"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"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"},{"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"}];
const detailedERC20bytes32ABI = [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"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":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"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":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_decimals","type":"uint8"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"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"},{"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"}];

const AllTokenSymbols = await Promise.all(
    allTokens.map(tokenAddress => {
        const tokenContract = new web3.eth.Contract(detailedERC20ABI, tokenAddress);
        return tokenContract.methods.symbol().call().catch(async function (err) {
            const tokenContractBytes32 = new web3js.eth.Contract(detailedERC20bytes32ABI, tokenAddress);
            return web3.utils.toUtf8(await tokenContractBytes32.methods.symbol().call());
        });
    })
);