Przejdź do głównej zawartości
Change page

Języki inteligentnego kontraktu

Strona ostatnio zaktualizowana: 26 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.

Przykładowy kontrakt

1// SPDX-License-Identifier: GPL-3.0
2pragma solidity >= 0.7.0;
3
4contract Coin {
5 // Słowo kluczowe "public" udostępnia zmienne
6 // z innych kontraktów
7 address public minter;
8 mapping (address => uint) public balances;
9
10 // Zdarzenia pozwalają klientom reagować na określone
11 // zmiany w kontrakcie, które zadeklarujesz
12 event Sent(address from, address to, uint amount);
13
14 // Kod konstruktora jest uruchamiany tylko wtedy, gdy kontrakt
15 // jest tworzony
16 constructor() {
17 minter = msg.sender;
18 }
19
20 // Wysyła pewną ilość nowo utworzonych monet na dany adres
21 // Może być wywołane tylko przez twórcę kontraktu
22 function mint(address receiver, uint amount) public {
23 require(msg.sender == minter);
24 require(amount < 1e60);
25 balances[receiver] += amount;
26 }
27
28 // Wysyła pewną ilość istniejących monet
29 // od dowolnego wywołującego na dany adres
30 function send(address receiver, uint amount) public {
31 require(amount <= balances[msg.sender], "Niewystarczające saldo.");
32 balances[msg.sender] -= amount;
33 balances[receiver] += amount;
34 emit Sent(msg.sender, receiver, amount);
35 }
36}
Pokaż wszystko

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).

Przykład

1# Otwarta aukcja
2
3# Parametry aukcji
4
5# Beneficjent otrzymuje pieniądze od licytującego, który złożył najwyższą ofertę
6
7beneficiary: public(address)
8auctionStart: public(uint256)
9auctionEnd: public(uint256)
10
11# Obecny stan aukcji
12
13highestBidder: public(address)
14highestBid: public(uint256)
15
16# Ustawiane na true na końcu, uniemożliwia wszelkie zmiany
17
18ended: public(bool)
19
20# Śledzenie zwróconych ofert, abyśmy mogli postępować zgodnie ze wzorcem wypłaty
21
22pendingReturns: public(HashMap[address, uint256])
23
24# Utwórz prostą aukcję z czasem licytacji `_bidding_time`
25
26# sekund w imieniu
27
28# adresu beneficjenta `_beneficiary`.
29
30@external
31def __init__(_beneficiary: address, _bidding_time: uint256):
32 self.beneficiary = _beneficiary
33 self.auctionStart = block.timestamp
34 self.auctionEnd = self.auctionStart + _bidding_time
35
36# Licytuj w aukcji z wartością wysłaną
37
38# razem z tą transakcją.
39
40# Wartość zostanie zwrócona tylko wtedy, gdy
41
42# aukcja nie zostanie wygrana.
43
44@external
45@payable
46def bid():
47 # Sprawdź, czy okres licytacji się skończył.
48 assert block.timestamp < self.auctionEnd
49 # Sprawdź, czy oferta jest wystarczająco wysoka
50 assert msg.value > self.highestBid
51 # Śledź zwrot dla poprzedniego licytującego z najwyższą ofertą
52 self.pendingReturns[self.highestBidder] += self.highestBid
53 # Śledź nową wysoką ofertę
54 self.highestBidder = msg.sender
55 self.highestBid = msg.value
56
57# Wypłać wcześniej zwróconą ofertę. Wzorzec wypłaty jest
58
59# używany tutaj w celu uniknięcia problemu z bezpieczeństwem. Gdyby zwroty były bezpośrednio
60
61# wysyłane w ramach bid(), złośliwy kontrakt licytacyjny mógłby zablokować
62
63# te zwroty, a tym samym zablokować napływ nowych, wyższych ofert.
64
65@external
66def withdraw():
67 pending_amount: uint256 = self.pendingReturns[msg.sender]
68 self.pendingReturns[msg.sender] = 0
69 send(msg.sender, pending_amount)
70
71# Zakończ aukcję i wyślij najwyższą ofertę
72
73# do beneficjenta.
74
75@external
76def endAuction():
77 # Dobrą wytyczną jest strukturyzowanie funkcji, które wchodzą w interakcję
78 # z innymi kontraktami (tj. wywołują funkcje lub wysyłają ether)
79 # w trzech fazach:
80 # 1. sprawdzanie warunków
81 # 2. wykonywanie działań (potencjalnie zmieniających warunki)
82 # 3. interakcja z innymi kontraktami
83 # Jeśli te fazy są pomieszane, inny kontrakt może wywołać
84 # z powrotem bieżący kontrakt i zmodyfikować stan lub spowodować
85 # wielokrotne wykonanie efektów (wypłata etheru).
86 # Jeśli funkcje wywoływane wewnętrznie obejmują interakcję z zewnętrznymi
87 # kontraktami, muszą być również traktowane jako interakcja z
88 # kontraktami zewnętrznymi.
89
90 # 1. Warunki
91 # Sprawdź, czy osiągnięto czas zakończenia aukcji
92 assert block.timestamp >= self.auctionEnd
93 # Sprawdź, czy ta funkcja została już wywołana
94 assert not self.ended
95
96 # 2. Efekty
97 self.ended = True
98
99 # 3. Interakcja
100 send(self.beneficiary, self.highestBid)
Pokaż wszystko

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.

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.

1{
2 function power(base, exponent) -> result
3 {
4 switch exponent
5 case 0 { result := 1 }
6 case 1 { result := base }
7 default
8 {
9 result := power(mul(base, base), div(exponent, 2))
10 if mod(exponent, 2) { result := mul(base, result) }
11 }
12 }
13 let res := power(calldataload(0), calldataload(32))
14 mstore(0, res)
15 return(0, 32)
16}
Pokaż wszystko

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.

Przykładowy kontrakt

Poniżej znajduje się prosty kontrakt zaimplementowany w Fe.

1type BookMsg = bytes[100]
2
3contract GuestBook:
4 pub guest_book: map<address, BookMsg>
5
6 event Signed:
7 book_msg: BookMsg
8
9 pub def sign(book_msg: BookMsg):
10 self.guest_book[msg.sender] = book_msg
11
12 emit Signed(book_msg=book_msg)
13
14 pub def get_msg(addr: address) -> BookMsg:
15 return self.guest_book[addr].to_mem()
16
Pokaż wszystko

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)

Dalsza lektura

Czy ten artykuł był pomocny?