Smart contract talen
Laatst bewerkt: @tarcanhursit(opens in a new tab), 17 juni 2024
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.
Belangrijke links
- Documentatie(opens in a new tab)
- Solidity-taalportaal(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) overbrugd naar Solidity Matrix Chatroom(opens in a new tab)
- Cheat sheet(opens in a new tab)
- Solidity-blog(opens in a new tab)
- Solidity op X (Twitter)(opens in a new tab)
Voorbeeldcontract
1// SPDX-License-Identifier: GPL-3.02pragma solidity >= 0.7.0;34contract Coin {5 // The keyword "public" makes variables6 // accessible from other contracts7 address public minter;8 mapping (address => uint) public balances;910 // Events allow clients to react to specific11 // contract changes you declare12 event Sent(address from, address to, uint amount);1314 // Constructor code is only run when the contract15 // is created16 constructor() {17 minter = msg.sender;18 }1920 // Sends an amount of newly created coins to an address21 // Can only be called by the contract creator22 function mint(address receiver, uint amount) public {23 require(msg.sender == minter);24 require(amount < 1e60);25 balances[receiver] += amount;26 }2728 // Sends an amount of existing coins29 // from any caller to an address30 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 alleKopië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).
Belangrijke links
- Documentatie(opens in a new tab)
- Vyper door voorbeelden(opens in a new tab)
- Meer Vyper door voorbeelden(opens in a new tab)
- Github(opens in a new tab)
- Vyper-gemeenschap Discord-chat(opens in a new tab)
- Cheat sheet(opens in a new tab)
- Frameworks en tools voor de ontwikkeling van smart contracts voor Vyper
- VyperPunk - leer smart contracts van Vyper beveiligen en hacken(opens in a new tab)
- VyperExamples - Vyper-kwetsbaarheidsvoorbeelden(opens in a new tab)
- Vyper Hub voor ontwikkeling(opens in a new tab)
- Vyper greatest hits, voorbeelden smart contract(opens in a new tab)
- Geweldige door Vyper samengestelde bronnen(opens in a new tab)
Voorbeeld
1# Open Auction23# Auction params4# Beneficiary receives money from the highest bidder5beneficiary: public(address)6auctionStart: public(uint256)7auctionEnd: public(uint256)89# Current state of auction10highestBidder: public(address)11highestBid: public(uint256)1213# Set to true at the end, disallows any change14ended: public(bool)1516# Keep track of refunded bids so we can follow the withdraw pattern17pendingReturns: public(HashMap[address, uint256])1819# Create a simple auction with `_bidding_time`20# seconds bidding time on behalf of the21# beneficiary address `_beneficiary`.22@external23def __init__(_beneficiary: address, _bidding_time: uint256):24 self.beneficiary = _beneficiary25 self.auctionStart = block.timestamp26 self.auctionEnd = self.auctionStart + _bidding_time2728# Bid on the auction with the value sent29# together with this transaction.30# The value will only be refunded if the31# auction is not won.32@external33@payable34def bid():35 # Check if bidding period is over.36 assert block.timestamp < self.auctionEnd37 # Check if bid is high enough38 assert msg.value > self.highestBid39 # Track the refund for the previous high bidder40 self.pendingReturns[self.highestBidder] += self.highestBid41 # Track new high bid42 self.highestBidder = msg.sender43 self.highestBid = msg.value4445# Withdraw a previously refunded bid. The withdraw pattern is46# used here to avoid a security issue. If refunds were directly47# sent as part of bid(), a malicious bidding contract could block48# those refunds and thus block new higher bids from coming in.49@external50def withdraw():51 pending_amount: uint256 = self.pendingReturns[msg.sender]52 self.pendingReturns[msg.sender] = 053 send(msg.sender, pending_amount)5455# End the auction and send the highest bid56# to the beneficiary.57@external58def endAuction():59 # It is a good guideline to structure functions that interact60 # with other contracts (i.e. they call functions or send ether)61 # into three phases:62 # 1. checking conditions63 # 2. performing actions (potentially changing conditions)64 # 3. interacting with other contracts65 # If these phases are mixed up, the other contract could call66 # back into the current contract and modify the state or cause67 # effects (ether payout) to be performed multiple times.68 # If functions called internally include interaction with external69 # contracts, they also have to be considered interaction with70 # external contracts.7172 # 1. Conditions73 # Check if auction endtime has been reached74 assert block.timestamp >= self.auctionEnd75 # Check if this function has already been called76 assert not self.ended7778 # 2. Effects79 self.ended = True8081 # 3. Interaction82 send(self.beneficiary, self.highestBid)Toon alleKopië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
- Tussentaal voor Ethereum.
- Ondersteunt de EVM en Ewasm(opens in a new tab), een WebAssembly met Ethereum-elementen. Het is ontworpen om een bruikbare gemene deler te zijn van beide platformen.
- Goed uitgangspunt voor optimalisatiestappen op hoog niveau waar zowel EVM- als Ewasm-platforms van kunnen profiteren.
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.
Belangrijke links
- Yul-documentatie(opens in a new tab)
- Yul+-documentatie(opens in a new tab)
- Yul+-speeltuin(opens in a new tab)
- Yul+ -kennismakingspost(opens in a new tab)
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) -> result3 {4 switch exponent5 case 0 { result := 1 }6 case 1 { result := base }7 default8 {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.
Belangrijke links
- Github(opens in a new tab)
- Fe-aankondiging(opens in a new tab)
- Fe 2021-routekaart(opens in a new tab)
- Fe Discord Chat(opens in a new tab)
- Fe X (Twitter)(opens in a new tab)
Voorbeeldcontract
Het volgende is een eenvoudig contract dat is geïmplementeerd in Fe.
1type BookMsg = bytes[100]23contract GuestBook:4 pub guest_book: map<address, BookMsg>56 event Signed:7 book_msg: BookMsg89 pub def sign(book_msg: BookMsg):10 self.guest_book[msg.sender] = book_msg1112 emit Signed(book_msg=book_msg)1314 pub def get_msg(addr: address) -> BookMsg:15 return self.guest_book[addr].to_mem()16Toon 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