Przejdź do głównej zawartości

Pomóż nam zaktualizować tę stronę

🌏

Dostępna jest nowsza wersja tej strony, ale tylko w języku angielskim. Pomóż nam przetłumaczyć najnowszą wersję.

Przetłumacz stronę
Zobacz wersję po angielsku

Brak błędów!🐛

Ta strona nie jest tłumaczona. Na razie celowo zostawiliśmy tę stronę w języku angielskim.

Języki inteligentnych kontraktów

Ostatnia edycja: , Invalid DateTime
Edytuj stronę

Ś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 z Pythonem lub JavaScript, możesz znaleźć język o znanej składni.

Dwa najbardziej aktywne i obsługiwane języki to:

  • Solidity
  • Vyper

Bardziej doświadczeni programiści mogą również użyć Yul, pośredniego języka dla wirtualnej maszyny Ethereum, lub Yul+, rozszerzenia Yul.

Warunki 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

  • Wpłynęły na niego języki C++, Python i JavaScript.
  • Typowanie statyczne (typ zmiennej jest znany w czasie kompilacji).
  • Obsługuje:
    • Dziedziczenie (możesz rozszerzać inne kontrakty).
    • Biblioteki (można 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.
  • Dokumentacja
  • Portal poświęcony językowi Solidity
  • Solidity w przykładach
  • GitHub
  • Czat dotyczący Solidity na Glitterze
  • Ściągawka
  • Blog poświęcony Solidity

Przykładowy kontrakt

1// SPDX-License-Identifier: GPL-3.0
2pragma solidity >= 0.7.0;
3
4contract Coin {
5 // The keyword "public" makes variables
6 // accessible from other contracts
7 address public minter;
8 mapping (address => uint) public balances;
9
10 // Events allow clients to react to specific
11 // contract changes you declare
12 event Sent(address from, address to, uint amount);
13
14 // Constructor code is only run when the contract
15 // is created
16 constructor() {
17 minter = msg.sender;
18 }
19
20 // Sends an amount of newly created coins to an address
21 // Can only be called by the contract creator
22 function mint(address receiver, uint amount) public {
23 require(msg.sender == minter);
24 require(amount < 1e60);
25 balances[receiver] += amount;
26 }
27
28 // Sends an amount of existing coins
29 // from any caller to an address
30 function send(address receiver, uint amount) public {
31 require(amount <= balances[msg.sender], "Insufficient balance.");
32 balances[msg.sender] -= amount;
33 balances[receiver] += amount;
34 emit Sent(msg.sender, receiver, amount);
35 }
36}
37
Pokaż wszystko
📋 Kopiuj

Ten przykład powinien dać wyobrażenie o składni kontraktu Solidity. Bardziej szczegółowy opis funkcji i zmiennych znajdziesz w dokumentacji.

Vyper

  • Pythonowy język programowania
  • Silne typowanie
  • Niewielki i zrozumiały kod kompilatora
  • 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
    • Binarnej arytmetyki stałoprzecinkowej

Aby uzyskać więcej informacji, przeczytaj artykuł o podstawach Vypera.

Przykład

1# Open Auction
2
3# Auction params
4# Beneficiary receives money from the highest bidder
5beneficiary: public(address)
6auctionStart: public(uint256)
7auctionEnd: public(uint256)
8
9# Current state of auction
10highestBidder: public(address)
11highestBid: public(uint256)
12
13# Set to true at the end, disallows any change
14ended: public(bool)
15
16# Keep track of refunded bids so we can follow the withdraw pattern
17pendingReturns: public(HashMap[address, uint256])
18
19# Create a simple auction with `_bidding_time`
20# seconds bidding time on behalf of the
21# beneficiary address `_beneficiary`.
22@external
23def __init__(_beneficiary: address, _bidding_time: uint256):
24 self.beneficiary = _beneficiary
25 self.auctionStart = block.timestamp
26 self.auctionEnd = self.auctionStart + _bidding_time
27
28# Bid on the auction with the value sent
29# together with this transaction.
30# The value will only be refunded if the
31# auction is not won.
32
33@external
34@payable
35def bid():
36 # Check if bidding period is over.
37 assert block.timestamp < self.auctionEnd
38 # Check if bid is high enough
39 assert msg.value > self.highestBid
40 # Track the refund for the previous high bidder
41 self.pendingReturns[self.highestBidder] += self.highestBid
42 # Track new high bid
43 self.highestBidder = msg.sender
44 self.highestBid = msg.value
45
46# Withdraw a previously refunded bid. The withdraw pattern is
47# used here to avoid a security issue. If refunds were directly
48# sent as part of bid(), a malicious bidding contract could block
49# those refunds and thus block new higher bids from coming in.
50@external
51def withdraw():
52 pending_amount: uint256 = self.pendingReturns[msg.sender]
53 self.pendingReturns[msg.sender] = 0
54 send(msg.sender, pending_amount)
55
56# End the auction and send the highest bid
57# to the beneficiary.
58@external
59def endAuction():
60 # It is a good guideline to structure functions that interact
61 # with other contracts (i.e. they call functions or send Ether)
62 # into three phases:
63 # 1. checking conditions
64 # 2. performing actions (potentially changing conditions)
65 # 3. interacting with other contracts
66 # If these phases are mixed up, the other contract could call
67 # back into the current contract and modify the state or cause
68 # effects (ether payout) to be performed multiple times.
69 # If functions called internally include interaction with external
70 # contracts, they also have to be considered interaction with
71 # external contracts.
72
73 # 1. Conditions
74 # Check if auction endtime has been reached
75 assert block.timestamp >= self.auctionEnd
76 # Check if this function has already been called
77 assert not self.ended
78
79 # 2.
80 Effects
81 self.ended = True
82
83 # 3. Interaction
84 send(self.beneficiary, self.highestBid)
85
Pokaż wszystko
📋 Kopiuj

Ten przykład powinien dać wyobrażenie o składni kontraktu Vyper. Aby uzyskać bardziej szczegółowy opis funkcji i zmiennych, zobacz dokumentację.

Yul i Yul+

Jeśli dopiero zapoznajesz się z Ethereum i nie kodowałeś jeszcze w językach kontraktów inteligentnych, zalecamy rozpoczęcie pracy od Solidity lub Vyper. Zajrzyj do 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, Ethereum flavored WebAssembly, zaprojektowany tak, aby był użytecznym wspólnym mianownikiem 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 na potrzeby kontraktu typu optymistyczna wartość zbiorcza.
  • 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ć, używając 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}
17
Pokaż wszystko

Jeśli masz już duże doświadczenie w inteligentnych kontraktach, pełną implementację ERC20 w Yul znajdziesz tutaj.

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. Więcej informacji zawiera artykuł Ucz się 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 kontroli itd., sprawdź tę ściągawkę firmy Auditless

Dalsza lektura

Czy ten artykuł był pomocny?