Naar hoofdinhoud gaan
Change page

Smart contract talen

Een geweldig aspect van Ethereum is dat smart contracts kunnen worden geprogrammeerd met relatief ontwikkelaarsvriendelijke talen. Als u ervaring hebt met Python of een andere taal met krullende haakjes(opens in a new tab), dan kunt een taal vinden met een vertrouwde syntaxis.

De twee meest actieve en onderhouden talen zijn:

  • Solidity
  • Vyper

Remix IDE voorziet in een uitgebreide ontwikkelomgeving voor het maken en testen van contracten in zowel Solidity als Vyper. Probeer Remix IDE in uw browser(opens in a new tab) om te beginnen met programmeren.

Meer ervaren ontwikkelaars kunnen misschien ook Yul gebruiken. Dit is een tussentaal voor de Ethereum Virtual Machine, of Yul+, een uitbreiding op Yul.

Bent u nieuwsgierig en wilt u graag helpen bij het testen van nieuwe talen die nog volop in ontwikkeling zijn? Dan kunt u experimenteren met Fe, een opkomende taal voor smart contracts die momenteel nog in de kinderschoenen staat.

Vereisten

Voorkennis van programmeertalen, vooral van JavaScript of Python, kan u helpen om de verschillen tussen smart contract-talen te begrijpen. We raden u ook aan om smart contracts als concept te doorgronden voordat u te diep graaft in de taalvergelijkingen. Intro tot smart contracts.

Solidity

  • Objectgeoriënteerde taal op hoog niveau voor het implementeren van smart contracts.
  • Taal met krullende haakjes die het meest beïnvloed is door C++.
  • Statisch getypt (het type van een variabele is bekend tijdens het compileren).
  • Ondersteunt:
    • Overerving (u kunt andere contracten uitbreiden).
    • Bibliotheken (u kunt herbruikbare code maken die u vanuit verschillende contracten kunt aanroepen, zoals statische functies in een statische klasse in andere objectgeoriënteerde programmeertalen).
    • Complexe door gebruikers gedefinieerde types.

Voorbeeldcontract

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}
Toon alle
Kopiëren

Dit voorbeeld zou u een idee moeten geven van hoe de contractsyntax van Solidity eruit ziet. Voor een meer gedetailleerde beschrijving van de functies en variabelen, zie de documentatie(opens in a new tab).

Vyper

  • Pythonische programmeertaal
  • Strong typing
  • Kleine en begrijpelijke compilercode
  • Efficiënte bytecodegeneratie
  • Heeft bewust minder mogelijkheden dan Solidity met als doel contracten veiliger en makkelijker te controleren te maken. Vyper ondersteunt geen:
    • Modifiers
    • Overerving
    • Inline assembly
    • Functie-overbelasting
    • Operator-overbelasting
    • Recursieve aanroepen
    • Oneindig lange lussen
    • Binaire vaste punten

Voor meer informatie, lees de Vyper-rationale(opens in a new tab).

Voorbeeld

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@external
33@payable
34def bid():
35 # Check if bidding period is over.
36 assert block.timestamp < self.auctionEnd
37 # Check if bid is high enough
38 assert msg.value > self.highestBid
39 # Track the refund for the previous high bidder
40 self.pendingReturns[self.highestBidder] += self.highestBid
41 # Track new high bid
42 self.highestBidder = msg.sender
43 self.highestBid = msg.value
44
45# Withdraw a previously refunded bid. The withdraw pattern is
46# used here to avoid a security issue. If refunds were directly
47# sent as part of bid(), a malicious bidding contract could block
48# those refunds and thus block new higher bids from coming in.
49@external
50def withdraw():
51 pending_amount: uint256 = self.pendingReturns[msg.sender]
52 self.pendingReturns[msg.sender] = 0
53 send(msg.sender, pending_amount)
54
55# End the auction and send the highest bid
56# to the beneficiary.
57@external
58def endAuction():
59 # It is a good guideline to structure functions that interact
60 # with other contracts (i.e. they call functions or send ether)
61 # into three phases:
62 # 1. checking conditions
63 # 2. performing actions (potentially changing conditions)
64 # 3. interacting with other contracts
65 # If these phases are mixed up, the other contract could call
66 # back into the current contract and modify the state or cause
67 # effects (ether payout) to be performed multiple times.
68 # If functions called internally include interaction with external
69 # contracts, they also have to be considered interaction with
70 # external contracts.
71
72 # 1. Conditions
73 # Check if auction endtime has been reached
74 assert block.timestamp >= self.auctionEnd
75 # Check if this function has already been called
76 assert not self.ended
77
78 # 2. Effects
79 self.ended = True
80
81 # 3. Interaction
82 send(self.beneficiary, self.highestBid)
Toon alle
Kopiëren

Dit voorbeeld zou u een idee moeten geven van de syntaxis van Vyper-contracten. Voor een meer gedetailleerde beschrijving van de functies en variabelen, zie de documentatie(opens in a new tab).

Yul en Yul+

Bent u nieuw met Ethereum en hebt u nog niet eerder geprogrammeerd met smart contract-talen? Dan raden we u aan om aan de slag te gaan met Solidity of Vyper. Verdiep u pas in Yul of Yul+ als u bekend bent met de best practices voor de beveiliging van smart contracts en de specifieke kenmerken van het werken met de EVM.

Yul

Yul+

  • Een zeer efficiënte uitbreiding op laag niveau voor Yul.
  • In eerste instantie ontworpen voor een optimistisch rollup-contract.
  • Yul+ kan worden gezien als een experimentele upgrade van Yul, waarbij nieuwe functies worden toegevoegd.

Voorbeeldcontract

Het volgende eenvoudige voorbeeld implementeert een machtsfunctie. Dit kan worden gecompileerd met solc --strict-assembly --bin input.yul. Het voorbeeld moet worden opgeslagen in het input.yul-bestand.

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}
Toon alle

Heeft u al ervaring met smart contracts? Dan kunt u hier(opens in a new tab) een volledige ERC20-implementatie in Yul vinden.

Fe

  • Statisch getypte taal voor de Ethereum Virtual Machine (EVM).
  • Geïnspireerd door Python en Rust.
  • Streeft ernaar om gemakkelijk te leren te zijn, zelfs voor ontwikkelaars die nieuw zijn in het Ethereum-ecosysteem.
  • De ontwikkeling van Fe staat nog in de kinderschoenen, maar de taal had al zijn alpha release in januari 2021.

Voorbeeldcontract

Het volgende is een eenvoudig contract dat is geïmplementeerd in 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
Toon alle

Hoe te kiezen

Net als bij elke andere programmeertaal gaat het vooral om het kiezen van de juiste toepassing voor de juiste taak en om persoonlijke voorkeuren.

Hier zijn een paar dingen om rekening mee te houden als u nog geen van de talen hebt geprobeerd:

Wat is er zo geweldig aan Solidity?

  • Bent u een beginner? Dan zijn er veel tutorials en leermiddelen beschikbaar. Lees hier meer over in het gedeelte Leren door te programmeren.
  • Goede tools voor ontwikkelaars beschikbaar.
  • Solidity heeft een grote gemeenschap van ontwikkelaars, wat betekent dat u waarschijnlijk vrij snel antwoorden op uw vragen zult vinden.

Wat is er zo geweldig aan Vyper?

  • Geweldige manier voor Python ontwikkelaars die willen beginnen met het schrijven van smart contracts.
  • Vyper heeft een kleiner aantal functies waardoor het zeer geschikt is om snel prototypes van ideeën te maken.
  • Vyper wil eenvoudig te controleren en maximaal menselijk leesbaar zijn.

Wat is er zo geweldig aan Yul en Yul+?

  • Simplistische en functionele taal op laag niveau.
  • Hiermee komt u veel dichter bij de onbewerkte EVM, wat kan helpen om het gasverbruik van uw contracten te optimaliseren.

Taalvergelijkingen

Bekijk deze Auditless-cheatsheet(opens in a new tab) voor vergelijkingen van basissyntax, de contractlevenscyclus, interfaces, operatoren, gegevensstructuren, functies, besturingsstroom en meer

Lees verder

Was dit artikel nuttig?