ERC-20 Token-Standard
Seite zuletzt aktualisiert: 26. Februar 2026
Einführung
Was ist ein Token?
Token können praktisch alles in Ethereum darstellen:
- Reputationspunkte auf einer Online-Platform
- Fähigkeiten eines Charakters in einem Spiel
- Vermögenswerte wie Anteile an einer Firma
- Eine Fiat-Währung wie der US-Dollar
- Eine Goldunze
- und mehr...
Diese mächtigen Eigenschaften von Ethereum sollten in einem stabilen Standard bereitgestellt werden, oder? Und genau das ist der Punkt, an dem ERC-20 ins Spiel kommt! Dieser Standard ermöglicht es Entwicklern, Token zu erstellen, die mit anderen Produkten und Services interagieren können. Der ERC-20-Standard wird auch verwendet, um zusätzliche Funktionalität bereitzustellen.
Was ist ERC-20?
Der ERC-20 führt einen Standard für fungible Token ein, das heißt, sie haben eine Eigenschaft, die jeden Token genau gleich (in Art und Wert) wie einen anderen Token macht. Zum Beispiel verhält sich ein ERC-20-Token genau wie der ETH. Das bedeutet, dass ein Token immer dem Wert aller anderen Token entspricht.
Voraussetzungen
Hauptteil
Der im November 2015 von Fabian Vogelsteller eingereichte ERC-20-Antrag (Ethereum Request for Comments 20) ist ein Token-Standard, der eine API für Tokens innerhalb von Smart Contracts implementiert.
Beispielfunktionalitäten, die ERC-20 bietet:
- Token von einem Konto auf ein anderes übertragen
- den aktuellen Token-Saldo eines Kontos abfragen
- den im Netz verfügbaren Gesamtvorrat an Token ermitteln
- genehmigen, ob ein Token-Betrag von einem Konto durch ein Drittkonto ausgegeben werden kann
Wenn ein Smart Contract die folgenden Methoden und Ereignisse implementiert, kann er als ERC-20-Token-Vertrag bezeichnet werden und ist nach der Bereitstellung dafür verantwortlich, die erstellten Token auf Ethereum zu verfolgen.
Aus EIP-20 (opens in a new tab):
Methoden
1function name() public view returns (string)2function symbol() public view returns (string)3function decimals() public view returns (uint8)4function totalSupply() public view returns (uint256)5function balanceOf(address _owner) public view returns (uint256 balance)6function transfer(address _to, uint256 _value) public returns (bool success)7function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)8function approve(address _spender, uint256 _value) public returns (bool success)9function allowance(address _owner, address _spender) public view returns (uint256 remaining)Alles anzeigenEreignisse
1event Transfer(address indexed _from, address indexed _to, uint256 _value)2event Approval(address indexed _owner, address indexed _spender, uint256 _value)Beispiele
Sehen wir uns an, wie wichtig ein Standard ist, um uns die Überprüfung jedes ERC-20-Token-Vertrags auf Ethereum zu erleichtern. Wir benötigen lediglich das Contract Application Binary Interface (ABI), um eine Schnittstelle zu einem beliebigen ERC-20-Token zu erstellen. Wie Sie unten sehen können, werden wir ein vereinfachtes ABI verwenden, um es zu einem Beispiel mit geringer Reibung zu machen.
Web3.py-Beispiel
Stellen Sie zunächst sicher, dass Sie die Python-Bibliothek Web3.py (opens in a new tab) installiert haben:
1pip install web31from web3 import Web3234w3 = Web3(Web3.HTTPProvider("https://cloudflare-eth.com"))56dai_token_addr = "0x6B175474E89094C44Da98b954EedeAC495271d0F" # DAI7weth_token_addr = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" # Gedeckter Ether (WETH)89acc_address = "0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11" # Uniswap V2: DAI 21011# Dies ist eine vereinfachte Contract Application Binary Interface (ABI) eines ERC-20-Token-Vertrags.12# Es werden nur die Methoden verfügbar gemacht: balanceOf(address), decimals(), symbol() und totalSupply()13simplified_abi = [14 {15 'inputs': [{'internalType': 'address', 'name': 'account', 'type': 'address'}],16 'name': 'balanceOf',17 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],18 'stateMutability': 'view', 'type': 'function', 'constant': True19 },20 {21 'inputs': [],22 'name': 'decimals',23 'outputs': [{'internalType': 'uint8', 'name': '', 'type': 'uint8'}],24 'stateMutability': 'view', 'type': 'function', 'constant': True25 },26 {27 'inputs': [],28 'name': 'symbol',29 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}],30 'stateMutability': 'view', 'type': 'function', 'constant': True31 },32 {33 'inputs': [],34 'name': 'totalSupply',35 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],36 'stateMutability': 'view', 'type': 'function', 'constant': True37 }38]3940dai_contract = w3.eth.contract(address=w3.to_checksum_address(dai_token_addr), abi=simplified_abi)41symbol = dai_contract.functions.symbol().call()42decimals = dai_contract.functions.decimals().call()43totalSupply = dai_contract.functions.totalSupply().call() / 10**decimals44addr_balance = dai_contract.functions.balanceOf(acc_address).call() / 10**decimals4546# DAI47print("===== %s =====" % symbol)48print("Total Supply:", totalSupply)49print("Addr Balance:", addr_balance)5051weth_contract = w3.eth.contract(address=w3.to_checksum_address(weth_token_addr), abi=simplified_abi)52symbol = weth_contract.functions.symbol().call()53decimals = weth_contract.functions.decimals().call()54totalSupply = weth_contract.functions.totalSupply().call() / 10**decimals55addr_balance = weth_contract.functions.balanceOf(acc_address).call() / 10**decimals5657# WETH58print("===== %s =====" % symbol)59print("Total Supply:", totalSupply)60print("Addr Balance:", addr_balance)Alles anzeigenBekannte Probleme
Problem beim Empfang von ERC-20-Token
Bis zum 20.06.2024 gingen aufgrund dieses Problems ERC-20-Token im Wert von mindestens 83.656.418 US-Dollar verloren. Beachten Sie, dass eine reine ERC-20-Implementierung anfällig für dieses Problem ist, es sei denn, Sie implementieren zusätzlich zu dem Standard eine Reihe weiterer Einschränkungen, wie unten aufgeführt.
Wenn ERC-20-Token an einen Smart Contract gesendet werden, der nicht für den Umgang mit ERC-20-Token ausgelegt ist, können diese Token dauerhaft verloren gehen. Das passiert, weil der empfangende Vertrag nicht die Funktionalität hat, die eingehenden Token zu erkennen oder darauf zu reagieren, und es gibt keinen Mechanismus im ERC-20-Standard, um den empfangenden Vertrag über die eingehenden Token zu benachrichtigen. Die Hauptursachen dieses Problems sind:
- Token-Übertragungsmechanismus
- ERC-20-Token werden mit den Funktionen transfer oder transferFrom übertragen
- Wenn ein Benutzer Token an eine Vertragsadresse mit diesen Funktionen sendet, werden die Token unabhängig davon übertragen, ob der empfangende Vertrag dafür ausgelegt ist oder nicht
- Fehlende Benachrichtigung
- Der empfangende Vertrag erhält keine Benachrichtigung oder Rückmeldung, dass Token an ihn gesendet wurden
- Wenn der empfangende Vertrag keinen Mechanismus hat, um Token zu verarbeiten (z.B. eine Fallback-Funktion oder eine spezielle Funktion zur Verwaltung des Tokenempfangs), bleiben die Token effektiv in der Adresse des Vertrags hängen
- Keine eingebaute Verarbeitung
- Der ERC-20-Standard enthält keine obligatorische Funktion, die empfangende Verträge implementieren müssen, was dazu führt, dass viele Verträge nicht in der Lage sind, eingehende Token richtig zu verwalten
Mögliche Lösungen
Es ist zwar nicht möglich, dieses Problem mit ERC-20 vollständig zu verhindern, aber es gibt Methoden, mit denen die Wahrscheinlichkeit eines Sickerverlusts für den Endnutzer erheblich verringert werden kann:
- Das häufigste Problem tritt auf, wenn ein Benutzer Token an die Adresse des Token-Vertrags selbst sendet (z. B. USDT, die an die Adresse des USDT-Token-Vertrags eingezahlt werden). Es wird empfohlen, die transfer(..)-Funktion einzuschränken, um solche Übertragungsversuche rückgängig zu machen. Erwägen Sie, die Prüfung require(_to != address(this)); in die Implementierung der Funktion transfer(..) aufzunehmen.
- Die transfer(..)-Funktion ist im Allgemeinen nicht dafür ausgelegt, Token in Verträge einzuzahlen.
Genehmigung(..) & transferFrom(..)-Muster wird stattdessen verwendet, um ERC-20-Token in Verträge einzuzahlen. Es ist möglich, die Transferfunktion so einzuschränken, dass keine Token in Verträge mit dieser Funktion eingezahlt werden können. Dies kann jedoch die Kompatibilität mit Verträgen beeinträchtigen, die davon ausgehen, dass Token mit der Funktion trasnfer(..) in Verträge eingezahlt werden können (z. B. Uniswap-Liquiditätspools). - Gehen Sie immer davon aus, dass ERC-20-Token in Ihrem Vertrag landen können, auch wenn Ihr Vertrag eigentlich keine erhalten soll. Es gibt keine Möglichkeit, versehentliche Einzahlungen aufseiten des Empfängers zu verhindern oder abzulehnen. Es wird empfohlen, eine Funktion zu implementieren, mit der versehentlich hinterlegte ERC-20-Token extrahiert werden können.
- Erwägen Sie die Verwendung alternativer Token-Standards.
Aus diesem Problem sind einige alternative Standards hervorgegangen, wie zum Beispiel ERC-223 oder ERC-1363.
Weiterführende Lektüre
- EIP-20: ERC-20-Token-Standard (opens in a new tab)
- OpenZeppelin – Tokens (opens in a new tab)
- OpenZeppelin – ERC-20-Implementierung (opens in a new tab)
- Alchemy – Leitfaden für Solidity-ERC20-Token (opens in a new tab)