Języki inteligentnego kontraktu
Ostatnia aktualizacja strony: 25 lutego 2026
Świetnym aspektem Ethereum jest to, że inteligentne kontrakty można programować przy użyciu stosunkowo przyjaznych dla programistów języków. Jeśli masz doświadczenie w Pythonie lub jakimkolwiek języku z nawiasami klamrowymi (opens in a new tab), możesz znaleźć język o znajomej składni.
Dwa najbardziej aktywne i obsługiwane języki to:
- Solidity
- Vyper
Remix IDE zapewnia kompleksowe środowisko programistyczne do tworzenia i testowania kontraktów zarówno w Solidity, jak i Vyper. Wypróbuj Remix IDE w przeglądarce (opens in a new tab), aby zacząć kodować.
Bardziej doświadczeni programiści mogą również chcieć użyć Yul, języka pośredniego dla Wirtualnej Maszyny Ethereum, lub Yul+, rozszerzenia Yul.
Jeśli jesteś ciekawy i chcesz pomóc w testowaniu nowych języków, które wciąż są w fazie intensywnego rozwoju, możesz poeksperymentować z Fe, nowym językiem inteligentnych kontraktów, który obecnie jest jeszcze w początkowej fazie rozwoju.
Wymagania wstępne
Wcześniejsza znajomość języków programowania, zwłaszcza JavaScript lub Python, może pomóc w zrozumieniu różnic w językach inteligentnych kontraktów. Zalecamy również zrozumienie inteligentnych kontraktów jako koncepcji przed zbytnim zagłębieniem się w porównania języków. Wprowadzenie do inteligentnych kontraktów.
Solidity
- Obiektowy język wysokiego poziomu do implementacji inteligentnych kontraktów.
- Język z nawiasami klamrowymi, na który największy wpływ miał C++.
- Typowanie statyczne (typ zmiennej jest znany w czasie kompilacji).
- Obsługuje:
- Dziedziczenie (możesz rozszerzać inne kontrakty).
- Biblioteki (możesz utworzyć kod wielokrotnego użytku, który można wywoływać z różnych kontraktów — jak funkcje statyczne w klasie statycznej w innych językach programowania obiektowego).
- Złożone typy zdefiniowane przez użytkownika.
Ważne linki
- Dokumentacja (opens in a new tab)
- Portal języka Solidity (opens in a new tab)
- Solidity na przykładach (opens in a new tab)
- GitHub (opens in a new tab)
- Czat Gitter Solidity (opens in a new tab) zmostowany z czatem Matrix Solidity (opens in a new tab)
- Ściągawka (opens in a new tab)
- Blog Solidity (opens in a new tab)
- Twitter Solidity (opens in a new tab)
Przykładowy kontrakt
// SPDX-License-Identifier: GPL-3.0
pragma solidity >= 0.7.0;
contract Coin {
// Słowo kluczowe "public" udostępnia zmienne
// z innych kontraktów
address public minter;
mapping (address => uint) public balances;
// Zdarzenia pozwalają klientom reagować na określone
// zmiany w kontrakcie, które zadeklarujesz
event Sent(address from, address to, uint amount);
// Kod konstruktora jest uruchamiany tylko wtedy, gdy kontrakt
// jest tworzony
constructor() {
minter = msg.sender;
}
// Wysyła pewną ilość nowo utworzonych monet na dany adres
// Może być wywołane tylko przez twórcę kontraktu
function mint(address receiver, uint amount) public {
require(msg.sender == minter);
require(amount < 1e60);
balances[receiver] += amount;
}
// Wysyła pewną ilość istniejących monet
// od dowolnego wywołującego na dany adres
function send(address receiver, uint amount) public {
require(amount <= balances[msg.sender], "Niewystarczające saldo.");
balances[msg.sender] -= amount;
balances[receiver] += amount;
emit Sent(msg.sender, receiver, amount);
}
}
Ten przykład powinien dać wyobrażenie o składni kontraktu Solidity. Aby uzyskać bardziej szczegółowy opis funkcji i zmiennych, zobacz dokumentację (opens in a new tab).
Vyper
- Pythonowy język programowania
- Silne typowanie
- Niewielki i zrozumiały kod kompilatora
- Efektywne generowanie kodu bajtowego
- Celowo ma mniej funkcji niż Solidity, aby zwiększyć bezpieczeństwo kontraktów i ułatwić ich audyt. Nieobsługiwane przez Vyper:
- Modyfikatory
- Dziedziczenie
- Wbudowany asembler
- Przeciążenie funkcji
- Przeciążenie operatora
- Wywołania rekurencyjne
- Pętle o nieskończonej długości
- Binarne punkty stałe
Aby uzyskać więcej informacji, przeczytaj uzasadnienie Vyper (opens in a new tab).
Ważne linki
- Dokumentacja (opens in a new tab)
- Vyper na przykładach (opens in a new tab)
- Więcej przykładów Vyper (opens in a new tab)
- GitHub (opens in a new tab)
- Czat Discord społeczności Vyper (opens in a new tab)
- Ściągawka (opens in a new tab)
- Frameworki i narzędzia do tworzenia inteligentnych kontraktów dla Vyper
- VyperPunk - naucz się zabezpieczać i hakować inteligentne kontrakty Vyper (opens in a new tab)
- Centrum programistyczne Vyper (opens in a new tab)
- Przykłady inteligentnych kontraktów Vyper – największe hity (opens in a new tab)
- Awesome Vyper – wyselekcjonowane zasoby (opens in a new tab)
Przykład
# Otwarta aukcja
# Parametry aukcji
# Beneficjent otrzymuje pieniądze od licytującego, który złożył najwyższą ofertę
beneficiary: public(address)
auctionStart: public(uint256)
auctionEnd: public(uint256)
# Obecny stan aukcji
highestBidder: public(address)
highestBid: public(uint256)
# Ustawiane na true na końcu, uniemożliwia wszelkie zmiany
ended: public(bool)
# Śledzenie zwróconych ofert, abyśmy mogli postępować zgodnie ze wzorcem wypłaty
pendingReturns: public(HashMap[address, uint256])
# Utwórz prostą aukcję z czasem licytacji `_bidding_time`
# sekund w imieniu
# adresu beneficjenta `_beneficiary`.
@external
def __init__(_beneficiary: address, _bidding_time: uint256):
self.beneficiary = _beneficiary
self.auctionStart = block.timestamp
self.auctionEnd = self.auctionStart + _bidding_time
# Licytuj w aukcji z wartością wysłaną
# razem z tą transakcją.
# Wartość zostanie zwrócona tylko wtedy, gdy
# aukcja nie zostanie wygrana.
@external
@payable
def bid():
# Sprawdź, czy okres licytacji się skończył.
assert block.timestamp < self.auctionEnd
# Sprawdź, czy oferta jest wystarczająco wysoka
assert msg.value > self.highestBid
# Śledź zwrot dla poprzedniego licytującego z najwyższą ofertą
self.pendingReturns[self.highestBidder] += self.highestBid
# Śledź nową wysoką ofertę
self.highestBidder = msg.sender
self.highestBid = msg.value
# Wypłać wcześniej zwróconą ofertę. Wzorzec wypłaty jest
# używany tutaj w celu uniknięcia problemu z bezpieczeństwem. Gdyby zwroty były bezpośrednio
# wysyłane w ramach bid(), złośliwy kontrakt licytacyjny mógłby zablokować
# te zwroty, a tym samym zablokować napływ nowych, wyższych ofert.
@external
def withdraw():
pending_amount: uint256 = self.pendingReturns[msg.sender]
self.pendingReturns[msg.sender] = 0
send(msg.sender, pending_amount)
# Zakończ aukcję i wyślij najwyższą ofertę
# do beneficjenta.
@external
def endAuction():
# Dobrą wytyczną jest strukturyzowanie funkcji, które wchodzą w interakcję
# z innymi kontraktami (tj. wywołują funkcje lub wysyłają ether)
# w trzech fazach:
# 1. sprawdzanie warunków
# 2. wykonywanie działań (potencjalnie zmieniających warunki)
# 3. interakcja z innymi kontraktami
# Jeśli te fazy są pomieszane, inny kontrakt może wywołać
# z powrotem bieżący kontrakt i zmodyfikować stan lub spowodować
# wielokrotne wykonanie efektów (wypłata etheru).
# Jeśli funkcje wywoływane wewnętrznie obejmują interakcję z zewnętrznymi
# kontraktami, muszą być również traktowane jako interakcja z
# kontraktami zewnętrznymi.
# 1. Warunki
# Sprawdź, czy osiągnięto czas zakończenia aukcji
assert block.timestamp >= self.auctionEnd
# Sprawdź, czy ta funkcja została już wywołana
assert not self.ended
# 2. Efekty
self.ended = True
# 3. Interakcja
send(self.beneficiary, self.highestBid)
Ten przykład powinien dać wyobrażenie o składni kontraktu Vyper. Aby uzyskać bardziej szczegółowy opis funkcji i zmiennych, zobacz dokumentację (opens in a new tab).
Yul i Yul+
Jeśli dopiero zapoznajesz się z Ethereum i nie kodowałeś jeszcze w językach inteligentnych kontraktów, zalecamy rozpoczęcie od Solidity lub Vyper. Przyjrzyj się Yul lub Yul+ dopiero po zapoznaniu się z najlepszymi praktykami w zakresie bezpieczeństwa inteligentnych kontraktów i specyfiką pracy z EVM.
Yul
- Język pośredni dla Ethereum.
- Obsługuje EVM i Ewasm (opens in a new tab), czyli WebAssembly w stylu Ethereum, i jest zaprojektowany jako użyteczny wspólny mianownik dla obu platform.
- Dobry cel dla etapów optymalizacji wysokiego poziomu, które mogą przynieść korzyści zarówno platformom EVM, jak i Ewasm.
Yul+
- Niskopoziomowe, bardzo wydajne rozszerzenie do Yul.
- Początkowo zaprojektowany dla kontraktu rollup optymistyczny.
- Yul+ można postrzegać jako eksperymentalną propozycję ulepszenia Yul, dodającą do niego nowe funkcje.
Ważne linki
- Dokumentacja Yul (opens in a new tab)
- Dokumentacja Yul+ (opens in a new tab)
- Wpis wprowadzający do Yul+ (opens in a new tab)
Przykładowy kontrakt
Poniższy prosty przykład implementuje funkcję potęgową. Można go skompilować za pomocą solc --strict-assembly --bin input.yul. Przykład należy zapisać
w pliku input.yul.
{
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)
}
Jeśli masz już duże doświadczenie z inteligentnymi kontraktami, pełną implementację ERC20 w Yul można znaleźć tutaj (opens in a new tab).
Fe
- Statycznie typowany język dla maszyny wirtualnej Ethereum (EVM).
- Zainspirowany Pythonem i Rustem.
- Ma być łatwy do nauczenia — nawet dla deweloperów, którzy są nowicjuszami w ekosystemie Ethereum.
- Rozwój Fe jest wciąż na wczesnym etapie, język miał swoją wersję alfa w styczniu 2021 roku.
Ważne linki
- GitHub (opens in a new tab)
- Ogłoszenie Fe (opens in a new tab)
- Plan rozwoju Fe 2021 (opens in a new tab)
- Czat Discord Fe (opens in a new tab)
- Twitter Fe (opens in a new tab)
Przykładowy kontrakt
Poniżej znajduje się prosty kontrakt zaimplementowany w Fe.
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()
Jak wybrać
Podobnie jak w przypadku każdego innego języka programowania, najczęściej chodzi o wybór odpowiedniego narzędzia do danej pracy, jak również o osobiste preferencje.
Oto kilka rzeczy do rozważenia, jeśli nie próbowałeś jeszcze żadnego z języków:
Co jest wspaniałego w Solidity?
- Jeśli dopiero zaczynasz, jest tam wiele samouczków i narzędzi do nauki. Zobacz więcej na ten temat w sekcji Nauka przez kodowanie.
- Dostępne dobre narzędzia programistyczne.
- Solidity ma dużą społeczność programistów, co oznacza, że najprawdopodobniej szybko znajdziesz odpowiedzi na swoje pytania.
Co jest wspaniałego w Vyper?
- Świetny sposób na rozpoczęcie pracy dla programistów Pythona, którzy chcą pisać inteligentne kontrakty.
- Vyper ma mniejszą liczbę funkcji, dzięki czemu świetnie nadaje się do szybkiego prototypowania pomysłów.
- Vyper ma być łatwy do skontrolowania i w największym stopniu czytelny dla człowieka.
Co jest wspaniałego w Yul i Yul+?
- Uproszczony i funkcjonalny język niskiego poziomu.
- Pozwala zbliżyć się do pierwotnej EVM, co może pomóc zoptymalizować zużycie gazu w Twoich kontraktach.
Porównania języków
Aby porównać podstawową składnię, cykl życia kontraktu, interfejsy, operatory, struktury danych, funkcje, przepływ sterowania i nie tylko, sprawdź tę ściągawkę od Auditless (opens in a new tab)