Πώς να χρησιμοποιήσετε τον προγραμματισμό Solidity
Το Solidity χρησιμοποιείται για τη δημιουργία σύνθετων έξυπνων συμβολαίων (Smart Contracts) που έχουν σχεδιαστεί για να λειτουργούν στο blockchain Ethereum. Αυτή η γλώσσα παρουσιάζει μοναδικές στρατηγικές που την διακρίνουν από άλλες γλώσσες προγραμματισμού.
Τι είναι η Solidity;
Το Solidity είναι μια γλώσσα προγραμματισμού υψηλού επιπέδου για τη δημιουργία έξυπνων συμβολαίων στο blockchain Ethereum. Τα έξυπνα συμβόλαια είναι συμβόλαια που εκτελούνται αυτόματα και αυτοματοποιούν την ανταλλαγή περιουσιακών στοιχείων μεταξύ των μερών. Το ιδιαίτερο χαρακτηριστικό τους είναι ότι δεν χρειάζονται μεσάζοντες για να διασφαλιστεί η συμμόρφωση με το έξυπνο συμβόλαιο.
Ο πηγαίος κώδικας Solidity μεταγλωττίζεται σε bytecode και αναπτύσσεται στο blockchain Ethereum ως έξυπνο συμβόλαιο. Μόλις ολοκληρωθεί, το έξυπνο συμβόλαιο μπορεί να εκτελεστεί από οποιονδήποτε κόμβο στο δίκτυο και η κατάσταση αποθηκεύεται στο blockchain. Παρουσιάζουμε ένα παράδειγμα ενός απλού συμβολαίου που μοντελοποιεί έναν αυτόματο πωλητή NFT:
pragma Solidity 0.8.7;
contract NFTVendingMachine {
// Declare state variables
address public owner;
mapping (address => uint) public nftBalance;
// Run on deployment
constructor() {
owner = msg.sender;
nftBalance[address(this)] = 100;
}
// Allow the owner to restock the NFT balance
function restock(uint amount) public {
require(msg.sender == owner, "Only the owner can restock.");
nftBalance[address(this)] += amount;
}
// Allow anyone to purchase NFTs
function purchase(uint amount) public payable {
require(msg.value >= amount * 1 ether, "You must pay at least 1 ETH per NFT");
require(nftBalance[address(this)] >= amount, "Not enough NFTs in stock to complete this purchase");
nftBalance[address(this)] -= amount;
nftBalance[msg.sender] += amount;
}
}solidityΓια ποιες εφαρμογές είναι κατάλληλο το Solidity;
Το Solidity έχει σχεδιαστεί ειδικά για τη δημιουργία κατανεμημένων εφαρμογών ή DApps που εκτελούνται στην Ethereum Virtual Machine (EVM). Τα έξυπνα συμβόλαια είναι κατάλληλα για τη διαχείριση ψηφιακών περιουσιακών στοιχείων, τη δημιουργία αποκεντρωμένων ανταλλαγών και την εφαρμογή συστημάτων ψηφοφορίας, μεταξύ άλλων.
Αποκεντρωμένες χρηματοοικονομικές υπηρεσίες (DeFi)
Το Solidity χρησιμοποιείται για την ανάπτυξη εφαρμογών DeFi, όπως αποκεντρωμένα χρηματιστήρια, πλατφόρμες πίστωσης και δανεισμού, αγορές προβλέψεων και κρυπτονομίσματα. Το DeFi έχει γίνει μία από τις πιο δημοφιλείς περιπτώσεις χρήσης της τεχνολογίας blockchain. Στην πορεία, το Solidity έχει καταστεί ένα απαραίτητο εργαλείο για τη δημιουργία εφαρμογών DeFi στο δίκτυο Ethereum.
Μη ανταλλάξιμα tokens
Τα μη ανταλλάξιμα tokens (NFT) έχουν απολαύσει μεγάλη δημοτικότητα από τη δεκαετία του 2020. Τα NFT είναι μοναδικά ψηφιακά περιουσιακά στοιχεία που αποθηκεύονται στο blockchain. Μπορεί να είναι ψηφιακά έργα τέχνης, αναμνηστικά αθλητικών γεγονότων ή αντικείμενα από τη βιομηχανία των ηλεκτρονικών παιχνιδιών. Το Solidity χρησιμοποιείται για τη δημιουργία των έξυπνων συμβολαίων που τροφοδοτούν τα NFT.
Διαχείριση της αλυσίδας εφοδιασμού
Το Solidity μπορεί να χρησιμοποιηθεί για τη δημιουργία έξυπνων συμβολαίων για την παρακολούθηση και τη διαχείριση των αλυσίδων εφοδιασμού. Τα συμβόλαια χρησιμοποιούνται για την αυτοματοποίηση διαφόρων διαδικασιών της αλυσίδας εφοδιασμού. Αυτές περιλαμβάνουν την παρακολούθηση της κίνησης των εμπορευμάτων, την επαλήθευση της αυθεντικότητας των προϊόντων και την επεξεργασία των πληρωμών μεταξύ των μερών.
Συστήματα συμφιλίωσης
Το Solidity μπορεί να χρησιμοποιηθεί για τη δημιουργία έξυπνων συμβολαίων που εφαρμόζουν ασφαλή και διαφανή συστήματα ψηφοφορίας στο blockchain. Τα συμβόλαια μπορούν να χρησιμοποιηθούν για να διασφαλιστεί ότι οι ψήφοι καταμετρώνται σωστά και ότι η διαδικασία ψηφοφορίας είναι δίκαιη και διαφανής.
Ποια είναι τα πλεονεκτήματα και τα μειονεκτήματα του Solidity;
Αν και η Solidity είναι μια ισχυρή γλώσσα για τη δημιουργία έξυπνων συμβολαίων στο blockchain Ethereum, έχει τα δικά της πλεονεκτήματα και μειονεκτήματα που οι προγραμματιστές πρέπει να λαμβάνουν υπόψη κατά την ανάπτυξη έξυπνων συμβολαίων. Ωστόσο, η δημιουργία ασφαλών έξυπνων συμβολαίων απαιτεί ένα συγκεκριμένο επίπεδο επάρκειας και προσοχής.
Για παράδειγμα, παρακάτω παρουσιάζεται ένα έξυπνο συμβόλαιο που λειτουργεί ως μαύρη τρύπα. Οποιοδήποτε Ether αποστέλλεται στο συμβόλαιο καταναλώνεται μόνιμα, χωρίς δυνατότητα ανάκτησης του Ether ή πραγματοποίησης πληρωμής:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >= 0.9.0;
// This contract swallows all Ether sent to it
contract Blackhole {
event Received(address, uint);
receive() external payable {
emit Received(msg.sender, msg.value);
}
}solidityΠλεονεκτήματα της Solidity
- Ευελιξία: Η Solidity είναι μια ευέλικτη γλώσσα. Μπορεί να χρησιμοποιηθεί για την ανάπτυξη διαφορετικών έξυπνων συμβολαίων με ποικίλες περιπτώσεις χρήσης.
- Ασφάλεια: Η Solidity δημιουργήθηκε με έμφαση στην ασφάλεια, ενσωματώνοντας χαρακτηριστικά όπως έλεγχοι πρόσβασης, διαχείριση εξαιρέσεων και μηχανισμοί αποτυχίας για να βοηθήσει τους προγραμματιστές στη δημιουργία ασφαλών συμβολαίων.
- Συμβατότητα με Ethereum: Επί του παρόντος, η Solidity είναι η προτιμώμενη γλώσσα για τη δημιουργία έξυπνων συμβολαίων στο blockchain Ethereum.
- Διακριτή κοινότητα: Μια μεγάλη κοινότητα προγραμματιστών blockchain εργάζεται με τη Solidity, με αποτέλεσμα να υπάρχει πληθώρα πόρων για μάθηση και επίλυση προβλημάτων.
Μειονεκτήματα της Solidity
- Καμπύλη μάθησης: Για τους προγραμματιστές που είναι νέοι στον τομέα της ανάπτυξης blockchain και έξυπνων συμβολαίων, το Solidity έχει μια σχετικά απότομη καμπύλη μάθησης.
- Αμεταβλητότητα: Μόλις ένα έξυπνο συμβόλαιο αναπτυχθεί στο blockchain, δεν μπορεί να τροποποιηθεί περαιτέρω. Συνεπώς, οι προγραμματιστές πρέπει να είναι εξαιρετικά προσεκτικοί κατά τη σύνταξη και τη δοκιμή.
- Έλλειψη επίσημης επαλήθευσης: Το Solidity δεν διαθέτει ενσωματωμένα εργαλεία για επίσημη αναθεώρηση κώδικα. Αυτό απαιτεί από τους προγραμματιστές να χρησιμοποιούν εξωτερικά εργαλεία για να εγγυηθούν την ακρίβεια των συμβολαίων τους.
- Περιορισμένα εργαλεία: Το οικοσύστημα εργαλείων του Solidity βρίσκεται ακόμα σε αρχικό στάδιο, κάτι που μπορεί να οδηγήσει σε προβλήματα με τα Ολοκληρωμένα Περιβάλλοντα Ανάπτυξης (IDE), τα πλαίσια δοκιμών και άλλα εργαλεία ανάπτυξης.
Ποια είναι η βασική σύνταξη της Solidity;
Η Solidity είναι μια αντικειμενοστραφής γλώσσα προγραμματισμού σχεδιασμένη για έξυπνα συμβόλαια. Εμπνέεται από τις γλώσσες JavaScript, Python και C++. Η σύνταξη της γλώσσας είναι παρόμοια με αυτή της JavaScript, αν και με κάποιες ενδιαφέρουσες ιδιαιτερότητες.
Μεταβλητές στη Solidity
Με την πρώτη ματιά, ο χειρισμός των μεταβλητών στο Solidity μπορεί να φαίνεται παρόμοιος με αυτόν άλλων γλωσσών προγραμματισμού. Ωστόσο, μια κρίσιμη διαφορά προκύπτει από το γεγονός ότι η Ethereum Virtual Machine (EVM) λειτουργεί ως περιβάλλον εκτέλεσης. Όλες οι λειτουργίες στην EVM, συμπεριλαμβανομένης της αποθήκευσης δεδομένων, συνεπάγονται ένα ορισμένο κόστος «αερίου». Κατά συνέπεια, κατά τον προγραμματισμό, πρέπει να σταθμίζεται η αποδοτικότητα μιας λειτουργίας και να προσδιορίζεται ο τρόπος με τον οποίο μπορεί να υλοποιηθεί με τον πιο αποδοτικό δυνατό τρόπο.
Εκτός από τις κανονικές μεταβλητές, η Solidity διαθέτει σταθερές, οι οποίες πρέπει να οριστούν κατά τη διάρκεια της μεταγλώττισης. Οι σταθερές απαιτούν λιγότερο αέριο για αποθήκευση:
// Regular variable can be declared without defining
int a;
// Constant needs to be defined at declaration
int constant b = 51;solidityΤο ίδιο ισχύει και για immutable μεταβλητές, καθώς απαιτούν λιγότερο αέριο και δεν μπορούν να αλλάξουν μετά την εκχώρηση. Σε αντίθεση με constant μεταβλητές, η εκχώρηση των αμετάβλητων μεταβλητών μπορεί να γίνει κατά την εκτέλεση.
Δηλώσεις ελέγχου στη Solidity
Ως γλώσσα προγραμματισμού, η Solidity υποστηρίζει γνωστές δηλώσεις ελέγχου, όπως διακλαδώσεις και βρόχους. Παρουσιάζουμε τον κώδικα για την επιλογή του μεγαλύτερου από δύο αριθμούς, a και b:
int largerNumber = 0;
// If-else statement
if (a > b) {
largerNumber = a;
} else {
largerNumber = b;
}solidityΟ βρόχοςfor στη Solidity αντιστοιχεί στη σύνταξη που είναι γνωστή από τις γλώσσες JavaScript ή C++:
// Loop 10 times
for (int i = 0; i < 10; i++) {
// …
}solidityΟ βρόχος while λειτουργεί επίσης ως συνήθως. Συνδυάζουμε μια συνθήκη τερματισμού με μια αριθμητική μεταβλητή μετρητή:
bool continueLoop = true;
int counter = 0;
// Loop at most 10 times
while (continueLoop && counter < 10) {
// …
counter++;
}solidityΑπλοί τύποι στη Solidity
Η Solidity είναι μια στατικά τυποποιημένη γλώσσα και υποστηρίζει τους τύπους που συναντώνται συνήθως στις γλώσσες προγραμματισμού. Οι απλοί τύποι που αντιπροσωπεύουν μεμονωμένες τιμές περιλαμβάνουν Booleans, αριθμούς και συμβολοσειρές.
Οι Booleans στο Solidity αντιστοιχούν στις τιμές true και false. Μπορούν να συνδεθούν χρησιμοποιώντας τους γνωστούς Boolean τελεστές και να χρησιμοποιηθούν σε if δηλώσεις:
bool paymentReceived = true;
bool itemsStocked = true;
bool continueTransaction = paymentReceived && itemsStocked;
if (continueTransaction) {
// ...
}solidityΤο Solidity υποστηρίζει ένα ευρύ φάσμα αριθμητικών τύπων. Οι ακέραιοι αριθμοί μπορούν να διακριθούν σε αριθμούς με πρόσημο (int) και χωρίς πρόσημο (uint), όπου οι τελευταίοι μπορούν να είναι μόνο θετικοί. Επιπλέον, το εύρος ενός αριθμού μπορεί να καθοριστεί σε βήματα των 8 bit, από int8 έως int16 και έως int265:
uint8 smallNumber = 120;
int8 negativeNumber = -125;
int8 result = smallNumber + negativeNumber;
assert(result == -5)solidityΟι συμβολοσειρές χρησιμοποιούνται στο Solidity κυρίως για τη δημιουργία μηνυμάτων κατάστασης. Η γλώσσα υποστηρίζει απλά και διπλά εισαγωγικά, καθώς και χαρακτήρες Unicode:
string message = 'Hello World';
string success = unicode"Transfer sent";SolidityΛειτουργίες στο Solidity
Οι συναρτήσεις είναι μια θεμελιώδης πτυχή της Solidity, όπως και στις περισσότερες γλώσσες προγραμματισμού. Ο ορισμός μιας συνάρτησης είναι παρόμοιος με αυτόν της JavaScript, όπου οι τύποι των ορίσματος πρέπει να καθορίζονται ρητά. Επιπλέον, χρησιμοποιείται η λέξη-κλειδί returns για να υποδείξει τους return τύπους τιμών.
// Define a function
function addNumbers(int a, int b) returns (int) {
return a + b;
}solidityΗ κλήση μιας συνάρτησης γίνεται ως συνήθως:
// Call the function
int result = addNumbers(2, 3);solidityΕίναι ενδιαφέρον ότι, όπως και τα ονομασμένα ορίσματα, οι τιμές επιστροφής στο Solidity μπορούν επίσης να ονομαστούν. Σε αυτή την περίπτωση, αρκεί η εκχώρηση των αντίστοιχων μεταβλητών στο σώμα της συνάρτησης και δεν είναι απαραίτητη η ρητή επιστροφή μέσω return:
function divideNumbers(int dividend, int divisor) returns (int quotient) {
quotient = dividend / divisor;
// No `return` necessary
}solidityΠαρόμοια με τις μεταβλητές constant ή immutable, στις συναρτήσεις Solidity μπορούν να επισημανθούν ως μη τροποποιούσες την κατάσταση. Οι λέξεις-κλειδιά view και pure χρησιμοποιούνται για το σκοπό αυτό. Μια συνάρτηση view δεν αλλάζει την κατάσταση, ενώ μια συνάρτηση pure εγγυάται επιπλέον ότι δεν θα διαβάσει τις μεταβλητές κατάστασης.
Έξυπνα συμβόλαια σε Solidity
Εκτός από τους τυπικούς τύπους, το Solidity γνωρίζει μια σειρά από ειδικούς τύπους έξυπνων συμβολαίων. Ο βασικός τύπος είναι address και αντιστοιχεί σε διευθύνσεις Ethereum. Οι διευθύνσεις που είναι payable μπορούν να λάβουν μεταφορές σε Ether. Για το σκοπό αυτό, οι διευθύνσεις payable παρέχουν τις μεθόδους balance() και transfer().
// Get address of this contract
address mine = address(this);
// Get payable external address
address payable other = payable(0x123);
// Transfer if balances fulfill conditions
if (other.balance < 10 && mine.balance >= 100) {
other.transfer(10);
}solidityΜε βάση τον τύπο address, ο τύπος contract υπάρχει ως κεντρική γλωσσική δομή. Οι συμβάσεις αντιστοιχούν περίπου στις κλάσεις στις αντικειμενοστραφείς γλώσσες προγραμματισμού. Έτσι, οι συμβάσεις ομαδοποιούν δεδομένα κατάστασης και λειτουργίες και τα προστατεύουν από τον έξω κόσμο. Οι συμβάσεις υποστηρίζουν πολλαπλή κληρονομικότητα, όπως είναι γνωστό από τις γλώσσες Python ή C++.
Οι συμβάσεις συνήθως ξεκινούν με μια γραμμή pragma που καθορίζει την επιτρεπόμενη έκδοση Solidity, ακολουθούμενη από τον πραγματικό ορισμό:
// Make sure Solidity version matches
pragma Solidity >=0.7.1 <0.9.0;
// Contract definition
contract Purchase {
// Public state variables
address seller;
address buyer;
// View-function
function getSeller() external view returns (address) {
return seller;
}
}solidityΤα έξυπνα συμβόλαια μπορούν να ορίζουν δεδομένα και λειτουργίες κατάστασης. Όπως είναι γνωστό από τις γλώσσες C++ και Java, σε κάθε περίπτωση μπορεί να οριστεί ένα από τα τρία επίπεδα πρόσβασης:
public: Η μεταβλητή είναι προσβάσιμη μέσω ανάγνωσης και εγγραφής από το εσωτερικό της σύμβασης. Επιπλέον, μια συνάρτησηviewδημιουργείται αυτόματα ως getter για εξωτερική πρόσβαση ανάγνωσης.internal: Η μεταβλητή προστατεύεται από εξωτερική πρόσβαση. Η πρόσβαση για ανάγνωση και εγγραφή είναι δυνατή από το εσωτερικό της σύμβασης, καθώς και από τις συμβάσεις που την κληρονομούν.private: όπωςinternal, αλλά δεν υπάρχει πρόσβαση από συμβόλαια που κληρονομούν.
Οι συναρτήσεις μπορούν περαιτέρω να χαρακτηριστούν ως external. Μια συνάρτηση external λειτουργεί ως μέρος της διεπαφής συμβολαίου και χρησιμοποιείται για εξωτερική πρόσβαση. Η συνάρτηση receive για τη λήψη αιθέρα είναι ένα γνωστό παράδειγμα:
// Define without `function` keyword
receive() external payable {
// Handle Ether
}solidityΤροποποιητές στη Solidity
Η Solidity διαθέτει μια ενδιαφέρουσα γλωσσική δομή με τη μορφή τροποποιητών, οι οποίοι μοιάζουν με τους διακοσμητές της Python. Όπως και στην Python, οι τροποποιητές στη Solidity χρησιμοποιούνται για να αλλάξουν την κλήση μιας συνάρτησης. Χρησιμοποιούνται συχνά για να διασφαλίσουν ότι μια συγκεκριμένη συνθήκη πληρούται πριν από την εκτέλεση μιας συνάρτησης:
contract Sale {
uint price;
address payable owner;
modifier onlyOwner {
// Will throw error if called by anyone other than the owner
require(
msg.sender == owner,
"Only owner can call this function."
);
// The wrapped function's body is inserted here
_;
}
// `onlyOwner` wraps `changePrice`
function changePrice(uint newPrice) public onlyOwner {
// We'll only get here if the owner called this function
price = newPrice;
}
}solidityΔιαχείριση συναλλαγών με Solidity
Το Solidity διαθέτει ενσωματωμένη διαχείριση συναλλαγών. Αυτό μπορεί να χρησιμοποιηθεί για να διασφαλιστεί ότι μια μεταφορά ether είτε θα ολοκληρωθεί πλήρως είτε δεν θα ολοκληρωθεί καθόλου. Η γλώσσα κατανοεί τη λέξη-κλειδί revert, η οποία ενεργοποιεί την «αναίρεση» μιας συναλλαγής. Με τη λέξη-κλειδί error μπορείτε να ορίσετε τους δικούς σας κωδικούς σφάλματος:
// Custom error definition
error InsufficientPayment(uint256 paid, uint256 required);
// Contract representing a sale
contract Sale {
uint price;
// Purchase if enough ether transferred
function purchase() public payable {
if (msg.value < price) {
revert InsufficientPayment(msg.value, price);
}
// Complete purchase
}
}solidityΈνα άλλο συχνά συναντώμενο μοτίβο είναι η χρήση της συνάρτησης require(). Αυτή μπορεί να χρησιμοποιηθεί αναλογικά με revert:
// Using `require()` function
if (!condition) revert("Error message");
// Equivalent to
require(condition, "Error message");solidity