Smart-Contract-Sprachen
Ein großartiger Aspekt von Ethereum ist, dass Smart Contracts mit relativ entwicklerfreundlichen Sprachen programmiert werden können. Wenn Sie Erfahrung mit Python oder einer anderen Programmiersprache mit geschweiften Klammern (opens in a new tab) haben, werden Sie eine Sprache mit vertrauter Syntax finden.
Die beiden aktivsten und am besten gepflegten Sprachen sind:
- Solidity
- Vyper
Die Remix IDE bietet eine umfassende Entwicklungsumgebung zum Erstellen und Testen von Verträgen in Solidity und Vyper. Probieren Sie die browserbasierte Remix IDE aus (opens in a new tab), um mit dem Programmieren zu beginnen.
Erfahrenere Entwickler möchten vielleicht auch Yul verwenden, eine Zwischensprache für die Ethereum Virtual Machine, oder Yul+, eine Erweiterung von Yul.
Wenn Sie neugierig sind und gerne beim Testen neuer Sprachen helfen möchten, die sich noch in der intensiven Entwicklung befinden, können Sie mit Fe experimentieren, einer aufstrebenden Smart-Contract-Sprache, die noch in den Kinderschuhen steckt.
Voraussetzungen
Vorkenntnisse in Programmiersprachen, insbesondere in JavaScript oder Python, können Ihnen helfen, die Unterschiede zwischen Smart-Contract-Sprachen zu verstehen. Wir empfehlen Ihnen außerdem, Smart Contracts als Konzept zu verstehen, bevor Sie zu tief in die Sprachvergleiche eintauchen. Einführung in Smart Contracts.
Solidity
- Objektorientierte Hochsprache zur Implementierung von Smart Contracts.
- Sprache mit geschweiften Klammern, die am stärksten von C++ beeinflusst wurde.
- Statisch typisiert (der Typ einer Variablen ist zur Kompilierzeit bekannt).
- Unterstützt:
- Vererbung (Sie können andere Verträge erweitern).
- Bibliotheken (Sie können wiederverwendbaren Code erstellen, den Sie aus verschiedenen Verträgen aufrufen können – wie statische Funktionen in einer statischen Klasse in anderen objektorientierten Programmiersprachen).
- Komplexe benutzerdefinierte Typen.
Wichtige Links
- Dokumentation (opens in a new tab)
- Solidity-Sprachportal (opens in a new tab)
- Solidity by Example (opens in a new tab)
- GitHub (opens in a new tab)
- Solidity Gitter-Chatroom (opens in a new tab) verbunden mit dem Solidity Matrix-Chatroom (opens in a new tab)
- Spickzettel (Cheat Sheet) (opens in a new tab)
- Solidity-Blog (opens in a new tab)
- Solidity auf Twitter (opens in a new tab)
Beispielvertrag
// SPDX-License-Identifier: GPL-3.0
pragma solidity >= 0.7.0;
contract Coin {
// Das Schlüsselwort "public" macht Variablen
// von anderen Verträgen aus zugänglich
address public minter;
mapping (address => uint) public balances;
// Ereignisse erlauben es Clients, auf spezifische
// von Ihnen deklarierte Vertragsänderungen zu reagieren
event Sent(address from, address to, uint amount);
// Konstruktor-Code wird nur ausgeführt, wenn der Vertrag
// erstellt wird
constructor() {
minter = msg.sender;
}
// Sendet eine Menge neu erstellter Coins an eine Adresse
// Kann nur vom Vertragsersteller aufgerufen werden
function mint(address receiver, uint amount) public {
require(msg.sender == minter);
require(amount < 1e60);
balances[receiver] += amount;
}
// Sendet eine Menge existierender Coins
// von einem beliebigen Aufrufer an eine Adresse
function send(address receiver, uint amount) public {
require(amount <= balances[msg.sender], "Insufficient balance.");
balances[msg.sender] -= amount;
balances[receiver] += amount;
emit Sent(msg.sender, receiver, amount);
}
}
Dieses Beispiel sollte Ihnen ein Gefühl dafür geben, wie die Syntax eines Solidity-Vertrags aussieht. Für eine detailliertere Beschreibung der Funktionen und Variablen siehe die Dokumentation (opens in a new tab).
Vyper
- Pythonische Programmiersprache
- Strenge Typisierung
- Kleiner und verständlicher Compiler-Code
- Effiziente Bytecode-Generierung
- Hat absichtlich weniger Funktionen als Solidity, mit dem Ziel, Verträge sicherer und einfacher zu überprüfen (auditieren) zu machen. Vyper unterstützt Folgendes nicht:
- Modifikatoren
- Vererbung
- Inline-Assembly
- Funktionsüberladung
- Operatorüberladung
- Rekursive Aufrufe
- Endlosschleifen
- Binäre Festkommazahlen
Weitere Informationen finden Sie in der Vyper-Begründung (Rationale) (opens in a new tab).
Wichtige Links
- Dokumentation (opens in a new tab)
- Vyper by Example (opens in a new tab)
- Mehr Vyper by Example (opens in a new tab)
- GitHub (opens in a new tab)
- Vyper-Community Discord-Chat (opens in a new tab)
- Spickzettel (Cheat Sheet) (opens in a new tab)
- Frameworks und Tools zur Smart-Contract-Entwicklung für Vyper
- VyperPunk - Lernen Sie, Vyper Smart Contracts zu sichern und zu hacken (opens in a new tab)
- Vyper Hub für die Entwicklung (opens in a new tab)
- Vyper Greatest Hits Smart-Contract-Beispiele (opens in a new tab)
- Kuratierte Awesome Vyper-Ressourcen (opens in a new tab)
Beispiel
# Offene Auktion
# Auktionsparameter
# Der Begünstigte erhält Geld vom Höchstbietenden
beneficiary: public(address)
auctionStart: public(uint256)
auctionEnd: public(uint256)
# Aktueller Status der Auktion
highestBidder: public(address)
highestBid: public(uint256)
# Wird am Ende auf true gesetzt, verbietet jegliche Änderung
ended: public(bool)
# Verfolgt zurückerstattete Gebote, damit wir dem Auszahlungsmuster folgen können
pendingReturns: public(HashMap[address, uint256])
# Erstellt eine einfache Auktion mit `_bidding_time`
# Sekunden Bietzeit im Namen der
# Begünstigten-Adresse `_beneficiary`.
@external
def __init__(_beneficiary: address, _bidding_time: uint256):
self.beneficiary = _beneficiary
self.auctionStart = block.timestamp
self.auctionEnd = self.auctionStart + _bidding_time
# Bieten Sie auf die Auktion mit dem Wert, der
# zusammen mit dieser Transaktion gesendet wird.
# Der Wert wird nur zurückerstattet, wenn die
# Auktion nicht gewonnen wird.
@external
@payable
def bid():
# Prüfen, ob die Bietfrist abgelaufen ist.
assert block.timestamp < self.auctionEnd
# Prüfen, ob das Gebot hoch genug ist
assert msg.value > self.highestBid
# Die Rückerstattung für den vorherigen Höchstbietenden verfolgen
self.pendingReturns[self.highestBidder] += self.highestBid
# Neues Höchstgebot verfolgen
self.highestBidder = msg.sender
self.highestBid = msg.value
# Ein zuvor zurückerstattetes Gebot abheben. Das Auszahlungsmuster wird
# hier verwendet, um ein Sicherheitsproblem zu vermeiden. Wenn Rückerstattungen direkt
# als Teil von bid() gesendet würden, könnte ein bösartiger bietender Vertrag
# diese Rückerstattungen blockieren und somit das Eingehen neuer, höherer Gebote verhindern.
@external
def withdraw():
pending_amount: uint256 = self.pendingReturns[msg.sender]
self.pendingReturns[msg.sender] = 0
send(msg.sender, pending_amount)
# Die Auktion beenden und das Höchstgebot
# an den Begünstigten senden.
@external
def endAuction():
# Es ist eine gute Richtlinie, Funktionen, die mit
# anderen Verträgen interagieren (d.h. sie rufen Funktionen auf oder senden Ether),
# in drei Phasen zu strukturieren:
# 1. Bedingungen prüfen
# 2. Aktionen ausführen (möglicherweise Bedingungen ändern)
# 3. Interaktion mit anderen Verträgen
# Wenn diese Phasen vermischt werden, könnte der andere Vertrag
# in den aktuellen Vertrag zurückrufen und den Zustand ändern oder bewirken,
# dass Effekte (Ether-Auszahlung) mehrfach ausgeführt werden.
# Wenn intern aufgerufene Funktionen Interaktionen mit externen
# Verträgen beinhalten, müssen sie auch als Interaktion mit
# externen Verträgen betrachtet werden.
# 1. Bedingungen
# Prüfen, ob die Endzeit der Auktion erreicht wurde
assert block.timestamp >= self.auctionEnd
# Prüfen, ob diese Funktion bereits aufgerufen wurde
assert not self.ended
# 2. Effekte
self.ended = True
# 3. Interaktion
send(self.beneficiary, self.highestBid)
Dieses Beispiel sollte Ihnen ein Gefühl dafür geben, wie die Syntax eines Vyper-Vertrags aussieht. Für eine detailliertere Beschreibung der Funktionen und Variablen siehe die Dokumentation (opens in a new tab).
Yul und Yul+
Wenn Sie neu bei Ethereum sind und noch nicht mit Smart-Contract-Sprachen programmiert haben, empfehlen wir Ihnen, mit Solidity oder Vyper zu beginnen. Beschäftigen Sie sich erst mit Yul oder Yul+, wenn Sie mit den Best Practices für die Sicherheit von Smart Contracts und den Besonderheiten der Arbeit mit der EVM vertraut sind.
Yul
- Zwischensprache für Ethereum.
- Unterstützt die EVM und Ewasm (opens in a new tab), ein Ethereum-spezifisches WebAssembly, und ist als nutzbarer gemeinsamer Nenner beider Plattformen konzipiert.
- Gutes Ziel für High-Level-Optimierungsstufen, von denen sowohl EVM- als auch Ewasm-Plattformen gleichermaßen profitieren können.
Yul+
- Eine hochgradig effiziente Low-Level-Erweiterung für Yul.
- Ursprünglich für einen Optimistic Rollup-Vertrag entwickelt.
- Yul+ kann als experimenteller Upgrade-Vorschlag für Yul betrachtet werden, der neue Funktionen hinzufügt.
Wichtige Links
- Yul-Dokumentation (opens in a new tab)
- Yul+-Dokumentation (opens in a new tab)
- Yul+-Einführungsbeitrag (opens in a new tab)
Beispielvertrag
Das folgende einfache Beispiel implementiert eine Potenzfunktion. Es kann mit solc --strict-assembly --bin input.yul kompiliert werden. Das Beispiel sollte in der Datei input.yul gespeichert werden.
{
function power(base, exponent) -> result
{
switch exponent
case 0 { result := 1 }
case 1 { result := base }
default
{
result := power(mul(base, base), div(exponent, 2))
if mod(exponent, 2) { result := mul(base, result) }
}
}
let res := power(calldataload(0), calldataload(32))
mstore(0, res)
return(0, 32)
}
Wenn Sie bereits viel Erfahrung mit Smart Contracts haben, finden Sie hier (opens in a new tab) eine vollständige ERC-20-Implementierung in Yul.
Fe
- Statisch typisierte Sprache für die Ethereum Virtual Machine (EVM).
- Inspiriert von Python und Rust.
- Soll leicht zu erlernen sein – auch für Entwickler, die neu im Ethereum-Ökosystem sind.
- Die Entwicklung von Fe befindet sich noch in einem frühen Stadium, die Sprache hatte ihre Alpha-Veröffentlichung im Januar 2021.
Wichtige Links
- GitHub (opens in a new tab)
- Fe-Ankündigung (opens in a new tab)
- Fe-Roadmap 2021 (opens in a new tab)
- Fe Discord-Chat (opens in a new tab)
- Fe auf Twitter (opens in a new tab)
Beispielvertrag
Das Folgende ist ein einfacher Vertrag, der in Fe implementiert wurde.
type BookMsg = bytes[100]
contract GuestBook:
pub guest_book: map<address, BookMsg>
event Signed:
book_msg: BookMsg
pub def sign(book_msg: BookMsg):
self.guest_book[msg.sender] = book_msg
emit Signed(book_msg=book_msg)
pub def get_msg(addr: address) -> BookMsg:
return self.guest_book[addr].to_mem()
Wie man sich entscheidet
Wie bei jeder anderen Programmiersprache geht es hauptsächlich darum, das richtige Werkzeug für die jeweilige Aufgabe zu wählen, sowie um persönliche Vorlieben.
Hier sind ein paar Dinge, die Sie beachten sollten, wenn Sie noch keine der Sprachen ausprobiert haben:
Was ist großartig an Solidity?
- Wenn Sie Anfänger sind, gibt es viele Tutorials und Lernwerkzeuge. Mehr dazu finden Sie im Abschnitt Lernen durch Programmieren.
- Gute Entwickler-Tools verfügbar.
- Solidity hat eine große Entwickler-Community, was bedeutet, dass Sie höchstwahrscheinlich recht schnell Antworten auf Ihre Fragen finden werden.
Was ist großartig an Vyper?
- Großartiger Einstieg für Python-Entwickler, die Smart Contracts schreiben möchten.
- Vyper hat eine geringere Anzahl von Funktionen, was es ideal für das schnelle Prototyping von Ideen macht.
- Vyper zielt darauf ab, leicht überprüfbar (auditierbar) und maximal menschenlesbar zu sein.
Was ist großartig an Yul und Yul+?
- Einfache und funktionale Low-Level-Sprache.
- Ermöglicht es, viel näher an die reine EVM heranzukommen, was helfen kann, den Gasverbrauch Ihrer Verträge zu optimieren.
Sprachvergleiche
Für Vergleiche der grundlegenden Syntax, des Vertragslebenszyklus, von Schnittstellen, Operatoren, Datenstrukturen, Funktionen, Kontrollfluss und mehr, sehen Sie sich diesen Spickzettel von Auditless (opens in a new tab) an.