Solidity Cheat Sheet
Aufbau eines Contracts
Jede Datei beginnt mit einer Lizenz und einem pragma; ein Contract ist die Einheit des Deployments.
| Syntax | Bedeutung |
|---|---|
// SPDX-License-Identifier: MIT | Lizenzkommentar, den der Compiler in Zeile 1 erwartet |
pragma solidity ^0.8.0; | Compiler-Version, für die die Datei geschrieben ist |
contract Counter { ... } | Einen Contract deklarieren (State + Funktionen) |
constructor(uint start) { count = start; } | Läuft genau einmal, beim Deployment |
import "./Token.sol"; | Eine andere Datei importieren |
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | Ein Bibliothekspaket importieren |
interface IToken { function balanceOf(address a) external view returns (uint); } | Ein Interface deklarieren (ohne Funktionskörper) |
library Math { function min(uint a, uint b) internal pure returns (uint) { ... } } | Eine Bibliothek wiederverwendbarer Funktionen |
Wertetypen
Ganzzahlen haben feste Größen und keine Nachkommastellen; 0.8 revertet bei Überlauf.
| Typ | Was er enthält |
|---|---|
uint256 / uint | Vorzeichenlose Ganzzahl, 0 bis 2^256 - 1 (uint ist uint256) |
uint8, uint16, ... uint128 | Kleinere vorzeichenlose Ganzzahlen, in 8-Bit-Schritten |
int256 / int | Vorzeichenbehaftete Ganzzahl (negativ erlaubt) |
bool | true oder false |
address | 20-Byte-Adresse eines Kontos oder Contracts |
address payable | Adresse, die Ether per transfer/send empfangen kann |
bytes32, bytes1... | Byte-Arrays fester Größe |
enum Status { Open, Closed } | Benannte Menge von Konstanten, gespeichert als uint8 |
1 ether, 1 gwei, 1 wei | Ether-Einheiten: 1 ether = 10^18 wei |
1 days, 2 hours, 30 minutes | Zeiteinheiten, in Sekunden |
Referenztypen & Datenort
Arrays, Strings, Bytes, Structs und Mappings liegen in storage, memory oder calldata.
| Syntax | Bedeutung |
|---|---|
string memory name | Dynamischer UTF-8-String (eine temporäre Kopie) |
bytes memory data | Dynamisches Byte-Array |
uint[] public scores; | Dynamisches Array im Storage |
uint[3] fixed; | Array fester Größe mit 3 Elementen |
uint[] memory tmp = new uint[](5); | Ein Array im Memory anlegen |
scores.push(42); | An ein Storage-Array anhängen |
scores.pop(); | Das letzte Element entfernen |
scores.length | Anzahl der Elemente |
storage | Dauerhaft, on-chain, teuer zu schreiben |
memory | Temporär, lebt für einen Aufruf |
calldata | Schreibgeschützte Eingabe externer Funktionen, am günstigsten |
Mappings & Structs
Ein Mapping ist eine Hashtabelle ohne Länge und ohne Iteration; ein Struct fasst Felder zusammen.
| Syntax | Bedeutung |
|---|---|
mapping(address => uint) public balances; | Key-Value-Speicher, jeder Schlüssel existiert (Standard 0) |
balances[msg.sender] += 1; | Lesen/Schreiben per Schlüssel |
mapping(address => mapping(address => uint)) allowance; | Verschachteltes Mapping |
struct User { string name; uint age; bool active; } | Ein Struct definieren |
User memory u = User("Ada", 36, true); | Ein Struct im Memory erzeugen |
User memory u = User({name: "Ada", age: 36, active: true}); | Erzeugung mit benannten Feldern |
users[msg.sender] = u; | Ein Struct in einem Mapping speichern |
users[msg.sender].age = 37; | Ein Feld im Storage aktualisieren |
delete users[msg.sender]; | Auf Standardwerte zurücksetzen |
Funktionen & Sichtbarkeit
Jede Funktion gibt an, wer sie aufrufen darf und ob sie State liest oder schreibt.
| Syntax | Bedeutung |
|---|---|
function add(uint a, uint b) public pure returns (uint) { return a + b; } | Eine Funktion mit Parametern und Rückgabewert |
public | Von überall aufrufbar (innen und außen) |
external | Nur von außerhalb des Contracts aufrufbar |
internal | Dieser Contract und Contracts, die von ihm erben |
private | Nur dieser Contract |
view | Liest State, schreibt ihn nie |
pure | Liest überhaupt keinen State |
payable | Kann mit dem Aufruf Ether empfangen |
returns (uint sum, bool ok) | Mehrere benannte Rückgabewerte |
(uint s, bool ok) = f(); | Mehrere Rückgabewerte destrukturieren |
uint public count; | Öffentliche State-Variable bekommt automatisch einen Getter count() |
Modifier, Konstanten & Vererbung
Prüfungen mit Modifiern wiederverwenden; Werte mit constant und immutable festlegen.
| Syntax | Bedeutung |
|---|---|
modifier onlyOwner() { require(msg.sender == owner, "Not owner"); _; } | Einen Modifier definieren (_ = Funktionskörper ausführen) |
function withdraw() public onlyOwner { ... } | Einen Modifier anwenden |
uint public constant MAX = 100; | Konstante zur Compile-Zeit |
address public immutable owner; | Einmal im Konstruktor gesetzt, danach fest |
contract Token is ERC20, Ownable { ... } | Von anderen Contracts erben |
function f() public virtual { ... } | Überschreiben erlauben |
function f() public override { ... } | Eine Elternfunktion überschreiben |
super.f(); | Die Implementierung des Elterncontracts aufrufen |
abstract contract Base { function f() public virtual; } | Contract mit nicht implementierten Funktionen |
Kontrollfluss
Die üblichen Anweisungen der C-Familie; kein switch, und Schleifen kosten pro Iteration Gas.
| Syntax | Bedeutung |
|---|---|
if (x > 5) { ... } else if (x > 2) { ... } else { ... } | Bedingte Verzweigungen |
for (uint i = 0; i < n; i++) { ... } | Zählschleife |
while (x < 10) { x++; } | Schleife, solange eine Bedingung gilt |
do { ... } while (cond); | Läuft mindestens einmal |
break; / continue; | Schleife verlassen / zur nächsten Iteration springen |
x > 0 ? a : b | Ternärer Ausdruck |
a / b | Ganzzahldivision (verwirft den Rest) |
a % b | Rest |
a ** 2 | Potenzierung |
unchecked { x++; } | Überlaufprüfungen überspringen (spart Gas, mit Vorsicht verwenden) |
Fehler: require, revert, assert
Eine fehlgeschlagene Prüfung macht die gesamte Transaktion rückgängig und erstattet ungenutztes Gas.
| Syntax | Bedeutung |
|---|---|
require(amount > 0, "Amount must be positive"); | Eingabe oder State validieren; mit Meldung reverten |
revert("Not allowed"); | Bedingungslos abbrechen |
error Insufficient(uint available, uint requested); | Einen eigenen Fehler deklarieren (günstiger als Strings) |
revert Insufficient(balance, amount); | Mit einem eigenen Fehler reverten |
assert(total == a + b); | Eine Invariante prüfen, die nie verletzt werden darf |
try token.transfer(to, amt) returns (bool ok) { ... } catch { ... } | Einen fehlschlagenden externen Aufruf behandeln |
Events
Events schreiben Logs, die Off-Chain-Anwendungen abonnieren können; aus Contracts sind sie nicht lesbar.
| Syntax | Bedeutung |
|---|---|
event Transfer(address indexed from, address indexed to, uint value); | Ein Event deklarieren |
emit Transfer(msg.sender, to, amount); | Es auslösen |
indexed | Filterbarer Parameter (bis zu 3 pro Event) |
event Log(string message); | Jeder ABI-Typ kann geloggt werden |
Ether, Adressen & globale Variablen
Der Transaktionskontext kommt aus msg, block und tx.
| Syntax | Bedeutung |
|---|---|
msg.sender | Adresse, die diese Funktion aufgerufen hat |
msg.value | Mit dem Aufruf gesendete Wei (braucht payable) |
block.timestamp | Zeit des aktuellen Blocks (Sekunden seit Epoche) |
block.number | Aktuelle Blockhöhe |
tx.origin | Das externe Konto (EOA), das die Tx gestartet hat (nicht zur Authentifizierung nutzen) |
address(this).balance | Ether-Guthaben dieses Contracts |
payable(to).transfer(1 ether); | Ether senden, revertet bei Fehler |
(bool ok, ) = to.call{value: amt}(""); | Low-Level-Senden, gibt Erfolgsflag zurück |
receive() external payable {} | Läuft bei einer einfachen Ether-Überweisung |
fallback() external payable {} | Läuft, wenn keine Funktion passt |
keccak256(abi.encodePacked(a, b)) | Werte hashen |
abi.encode(x), abi.decode(data, (uint)) | ABI-Daten kodieren / dekodieren |
Jedes Stück Solidity-Syntax, das du brauchst, auf einer Seite. Dieses Solidity Cheat Sheet ist eine Schnellreferenz für die Smart-Contract-Sprache von Ethereum und jeder EVM-Chain - einen Contract deklarieren, Typen wählen, Daten in Mappings und Structs speichern, Funktionen mit der richtigen Sichtbarkeit und Mutabilität schreiben und sie mit require, Modifiern und Events absichern.
Die Syntax hier ist Solidity 0.8, das arithmetische Überläufe standardmäßig prüft und mit Remix, Hardhat und Foundry funktioniert. Kopiere, was du brauchst, oder probiere es live im Solidity-Playground aus - schreibe einen Contract, kompiliere ihn und führe ihn auf einer EVM in deinem Browser aus.