Web3 – Abrufen des Variablenwerts aus dem bereitgestellten Vertrag ohne ABI

Ich versuche, mit Web3 1.0.0-beta.34 eine Brieftasche zu erstellen, die in der Lage ist, von den Benutzern hinzugefügte ERC20-Token zu verwalten. Nachdem ich der Brieftasche einen bestimmten Token mit seiner Adresse hinzugefügt hatte, konnte ich die Menge an Münzen in einer bestimmten Brieftasche abrufen.
Da ich möchte, dass die Benutzer einen beliebigen ERC20-Token hinzufügen, kenne ich die ABI des Token-Vertrags nicht. Web3 erfordert, dass die ABI einen Vertrag instanziiert, und ich habe dieses Problem gelöst, indem ich die ABI der einzelnen balanceOfFunktion erhalten und dann den Vertrag instanziiert habe, indem ich Folgendes verwendet habe:

var contract = new web3.eth.Contract(balanceOfABI, contractAddress);

Jetzt muss ich die Dezimalstellen des Tokens bekommen, also brauche ich im Grunde einen Getter für die decimalsVariable, aber das ist nicht möglich, da dies keine Funktion ist und ich den obigen Trick nicht verwenden kann.
Gibt es eine Möglichkeit, die ABI für eine gemeinsame Getter-Methode zu erstellen? Der JavaScript-Code sollte am Ende etwa so aussehen:

var contract = new web3.eth.Contract(getterABI, contractAddress);
contract.methods.decimals().call(function (error, result) {
    if(!error) 
        console.log(result);
});

Ich hoffe, ich habe meinen Punkt getroffen, vielen Dank.

Die ABI-Codierung unterscheidet nicht zwischen a variableund a function, sie sind alle Funktionen. So können Sie erhalten decimals, als ob eine Funktion wäre.
Außerdem haben alle ERC20-Token eine Standardschnittstelle (eine Reihe von Methoden), Sie müssen die ABI nicht für jeden Vertrag abrufen, sondern verwenden Sie einfach die Standard-ABI.
@Nulik Danke, ich konnte den ABI für die Variable erhalten, wie Sie sagten. Wie auch immer, ich habe auf Etherscan festgestellt, dass mehrere Token nicht denselben Code haben (zB Tronix und OmiseGO), vielleicht habe ich etwas nicht verstanden
Nun, sie werden niemals gleich sein, aber sie werden dem Standard (ERC20) entsprechen. Nur frühe Ethereum-Token sind nicht vollständig Standard.

Antworten (2)

Die ABI (Application Binary Interface) eines Vertrags definiert die Aktionen, die von diesem Vertrag durchgeführt werden können. Obwohl die Logik/der Code des Vertrags zwischen den ERC20-Token variieren kann, ist der ERC20-Standard selbst nur die Liste der Funktionsnamen. Wenn Sie also nur die grundlegenden Maßnahmen ergreifen, die ERC20 definiert, könnten Sie sie auf jeden ERC20-Vertrag anwenden, obwohl alle speziellen/zusätzlichen Funktionen, die dieser Vertrag verwendet, Ihre Brieftasche nicht kennen würden.

[
  {
    "constant": true,
    "inputs": [],
    "name": "name",
    "outputs": [
      {
        "name": "",
        "type": "string"
      }
    ],
    "payable": false,
    "type": "function"
  },
  {
    "constant": false,
    "inputs": [
      {
        "name": "_spender",
        "type": "address"
      },
      {
        "name": "_value",
        "type": "uint256"
      }
    ],
    "name": "approve",
    "outputs": [],
    "payable": false,
    "type": "function"
  },
  {
    "constant": true,
    "inputs": [],
    "name": "totalSupply",
    "outputs": [
      {
        "name": "",
        "type": "uint256"
      }
    ],
    "payable": false,
    "type": "function"
  },
  {
    "constant": false,
    "inputs": [
      {
        "name": "_from",
        "type": "address"
      },
      {
        "name": "_to",
        "type": "address"
      },
      {
        "name": "_value",
        "type": "uint256"
      }
    ],
    "name": "transferFrom",
    "outputs": [],
    "payable": false,
    "type": "function"
  },
  {
    "constant": true,
    "inputs": [],
    "name": "decimals",
    "outputs": [
      {
        "name": "",
        "type": "uint256"
      }
    ],
    "payable": false,
    "type": "function"
  },
  {
    "constant": true,
    "inputs": [
      {
        "name": "_who",
        "type": "address"
      }
    ],
    "name": "balanceOf",
    "outputs": [
      {
        "name": "balance",
        "type": "uint256"
      }
    ],
    "payable": false,
    "type": "function"
  },
  {
    "constant": true,
    "inputs": [],
    "name": "symbol",
    "outputs": [
      {
        "name": "",
        "type": "string"
      }
    ],
    "payable": false,
    "type": "function"
  },
  {
    "constant": false,
    "inputs": [
      {
        "name": "_to",
        "type": "address"
      },
      {
        "name": "_value",
        "type": "uint256"
      }
    ],
    "name": "transfer",
    "outputs": [],
    "payable": false,
    "type": "function"
  },
  {
    "constant": true,
    "inputs": [
      {
        "name": "_owner",
        "type": "address"
      },
      {
        "name": "_spender",
        "type": "address"
      }
    ],
    "name": "allowance",
    "outputs": [
      {
        "name": "remaining",
        "type": "uint256"
      }
    ],
    "payable": false,
    "type": "function"
  },
  {
    "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"
  }
]

Sie sollten ein gefälschtes abi erstellen, das einige gemeinsame Funktionen von erc21 enthält


[
    {
    "constant": false,
    "inputs": [
    {
    "name": "to",
    "type": "address"
    },
    {
    "name": "tokenId",
    "type": "uint256"
    }
    ],
    "name": "approve",
    "outputs": [],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "constant": false,
    "inputs": [
    {
    "name": "tokenId",
    "type": "uint256"
    }
    ],
    "name": "depositToGateway",
    "outputs": [],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "constant": false,
    "inputs": [
    {
    "name": "user",
    "type": "address"
    }
    ],
    "name": "register",
    "outputs": [],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "constant": false,
    "inputs": [],
    "name": "renounceOwnership",
    "outputs": [],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "constant": false,
    "inputs": [
    {
    "name": "from",
    "type": "address"
    },
    {
    "name": "to",
    "type": "address"
    },
    {
    "name": "tokenId",
    "type": "uint256"
    }
    ],
    "name": "safeTransferFrom",
    "outputs": [],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "constant": false,
    "inputs": [
    {
    "name": "from",
    "type": "address"
    },
    {
    "name": "to",
    "type": "address"
    },
    {
    "name": "tokenId",
    "type": "uint256"
    },
    {
    "name": "_data",
    "type": "bytes"
    }
    ],
    "name": "safeTransferFrom",
    "outputs": [],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "constant": false,
    "inputs": [
    {
    "name": "to",
    "type": "address"
    },
    {
    "name": "approved",
    "type": "bool"
    }
    ],
    "name": "setApprovalForAll",
    "outputs": [],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "constant": false,
    "inputs": [
    {
    "name": "from",
    "type": "address"
    },
    {
    "name": "to",
    "type": "address"
    },
    {
    "name": "tokenId",
    "type": "uint256"
    }
    ],
    "name": "transferFrom",
    "outputs": [],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "constant": false,
    "inputs": [
    {
    "name": "newOwner",
    "type": "address"
    }
    ],
    "name": "transferOwnership",
    "outputs": [],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "inputs": [],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "constructor"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": true,
    "name": "previousOwner",
    "type": "address"
    },
    {
    "indexed": true,
    "name": "newOwner",
    "type": "address"
    }
    ],
    "name": "OwnershipTransferred",
    "type": "event"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": true,
    "name": "from",
    "type": "address"
    },
    {
    "indexed": true,
    "name": "to",
    "type": "address"
    },
    {
    "indexed": true,
    "name": "tokenId",
    "type": "uint256"
    }
    ],
    "name": "Transfer",
    "type": "event"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": true,
    "name": "owner",
    "type": "address"
    },
    {
    "indexed": true,
    "name": "approved",
    "type": "address"
    },
    {
    "indexed": true,
    "name": "tokenId",
    "type": "uint256"
    }
    ],
    "name": "Approval",
    "type": "event"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": true,
    "name": "owner",
    "type": "address"
    },
    {
    "indexed": true,
    "name": "operator",
    "type": "address"
    },
    {
    "indexed": false,
    "name": "approved",
    "type": "bool"
    }
    ],
    "name": "ApprovalForAll",
    "type": "event"
    },
    {
    "constant": true,
    "inputs": [
    {
    "name": "owner",
    "type": "address"
    }
    ],
    "name": "balanceOf",
    "outputs": [
    {
    "name": "",
    "type": "uint256"
    }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
    },
    {
    "constant": true,
    "inputs": [],
    "name": "gateway",
    "outputs": [
    {
    "name": "",
    "type": "address"
    }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
    },
    {
    "constant": true,
    "inputs": [
    {
    "name": "tokenId",
    "type": "uint256"
    }
    ],
    "name": "getApproved",
    "outputs": [
    {
    "name": "",
    "type": "address"
    }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
    },
    {
    "constant": true,
    "inputs": [
    {
    "name": "owner",
    "type": "address"
    },
    {
    "name": "operator",
    "type": "address"
    }
    ],
    "name": "isApprovedForAll",
    "outputs": [
    {
    "name": "",
    "type": "bool"
    }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
    },
    {
    "constant": true,
    "inputs": [],
    "name": "isOwner",
    "outputs": [
    {
    "name": "",
    "type": "bool"
    }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
    },
    {
    "constant": true,
    "inputs": [],
    "name": "name",
    "outputs": [
    {
    "name": "",
    "type": "string"
    }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
    },
    {
    "constant": true,
    "inputs": [],
    "name": "owner",
    "outputs": [
    {
    "name": "",
    "type": "address"
    }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
    },
    {
    "constant": true,
    "inputs": [
    {
    "name": "tokenId",
    "type": "uint256"
    }
    ],
    "name": "ownerOf",
    "outputs": [
    {
    "name": "",
    "type": "address"
    }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
    },
    {
    "constant": true,
    "inputs": [
    {
    "name": "interfaceId",
    "type": "bytes4"
    }
    ],
    "name": "supportsInterface",
    "outputs": [
    {
    "name": "",
    "type": "bool"
    }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
    },
    {
    "constant": true,
    "inputs": [],
    "name": "symbol",
    "outputs": [
    {
    "name": "",
    "type": "string"
    }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
    },
    {
    "constant": true,
    "inputs": [
    {
    "name": "index",
    "type": "uint256"
    }
    ],
    "name": "tokenByIndex",
    "outputs": [
    {
    "name": "",
    "type": "uint256"
    }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
    },
    {
    "constant": true,
    "inputs": [
    {
    "name": "owner",
    "type": "address"
    },
    {
    "name": "index",
    "type": "uint256"
    }
    ],
    "name": "tokenOfOwnerByIndex",
    "outputs": [
    {
    "name": "",
    "type": "uint256"
    }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
    },
    {
    "constant": true,
    "inputs": [
    {
    "name": "tokenId",
    "type": "uint256"
    }
    ],
    "name": "tokenURI",
    "outputs": [
    {
    "name": "",
    "type": "string"
    }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
    },
    {
    "constant": true,
    "inputs": [],
    "name": "totalSupply",
    "outputs": [
    {
    "name": "",
    "type": "uint256"
    }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
    },
    {
        "constant": true,
        "inputs": [{
            "name": "",
            "type": "uint256"
        }],
        "name": "kittyIndexToApproved",
        "outputs": [{
            "name": "",
            "type": "address"
        }],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
        },
        {
            "constant": true,
            "inputs": [{
                "name": "_tokenId",
                "type": "uint256"
            }],
            "name": "approvedFor",
            "outputs": [{
                "name": "",
                "type": "address"
            }],
            "payable": false,
            "stateMutability": "view",
            "type": "function"
        }
    ]

Wie beantwortet dies die Frage?