Raziščite Solidity, vodilni programski jezik za razvoj pametnih pogodb na verigi blokov Ethereum. Ta celovit vodnik pokriva vse, od osnovnih konceptov do naprednih tehnik.
Solidity: Celovit vodnik po programiranju pametnih pogodb
Solidity je visokonivojski programski jezik, usmerjen v pogodbe, ki se uporablja za implementacijo pametnih pogodb na različnih platformah verige blokov, predvsem na Ethereumu. Nanj močno vplivajo C++, Python in JavaScript ter je zasnovan za ciljanje na Ethereum Virtual Machine (EVM). Ta vodnik ponuja podroben pregled jezika Solidity, primeren za začetnike in izkušene programerje, ki se želijo poglobiti v svet razvoja verige blokov.
Kaj so pametne pogodbe?
Preden se poglobimo v Solidity, je ključno razumeti, kaj so pametne pogodbe. Pametna pogodba je samoizvršljiva pogodba s pogoji dogovora, neposredno zapisanimi v kodo. Shranjena je v verigi blokov in se samodejno izvrši, ko so izpolnjeni vnaprej določeni pogoji. Pametne pogodbe omogočajo avtomatizacijo, preglednost in varnost v različnih aplikacijah, vključno z:
- Decentralizirane finance (DeFi): platforme za posojanje, izposojanje in trgovanje.
- Upravljanje dobavne verige: sledenje blagu in zagotavljanje preglednosti.
- Volilni sistemi: varno in preverljivo elektronsko glasovanje.
- Nepremičnine: avtomatizacija transakcij z nepremičninami.
- Zdravstvena nega: varno upravljanje podatkov o pacientih.
Zakaj Solidity?
Solidity je prevladujoči jezik za pisanje pametnih pogodb na Ethereumu in drugih z EVM združljivih verigah blokov zaradi več dejavnikov:
- Združljivost z EVM: Solidity je posebej zasnovan za prevajanje v bajtni kodo, ki jo je mogoče zagnati na Ethereum Virtual Machine.
- Podpora skupnosti: Velika in aktivna skupnost zagotavlja obsežno dokumentacijo, knjižnice in orodja.
- Varnostne funkcije: Solidity vključuje funkcije za ublažitev pogostih ranljivosti pametnih pogodb.
- Visokonivojska abstrakcija: Ponuja visokonivojske konstrukte, ki naredijo razvoj pogodb učinkovitejši in obvladljiv.
Nastavitev razvojnega okolja
Za začetek razvoja s Solidityem boste morali nastaviti ustrezno razvojno okolje. Tukaj je nekaj priljubljenih možnosti:
Remix IDE
Remix je spletni IDE, ki temelji na brskalniku in je popoln za učenje in eksperimentiranje s Solidityjem. Ne zahteva lokalne namestitve in ponuja funkcije, kot so:
- Urejevalnik kode s poudarjanjem sintakse in samodejnim dokončanjem.
- Prevajalnik za pretvorbo kode Solidity v bajtno kodo.
- Razvijalec za uvajanje pogodb v testna omrežja ali glavno omrežje.
- Razhroščevalnik za prehod skozi kodo in prepoznavanje napak.
Dostopajte do Remix IDE na https://remix.ethereum.org/
Truffle Suite
Truffle je celovit razvojni okvir, ki poenostavlja postopek ustvarjanja, testiranja in uvajanja pametnih pogodb. Zagotavlja orodja, kot so:
- Truffle: Orodje ukazne vrstice za ustvarjanje projektov, prevajanje, uvajanje in testiranje.
- Ganache: Osebna veriga blokov za lokalni razvoj.
- Drizzle: Zbirka knjižnic za sprednji del, ki olajšajo integracijo vaših pametnih pogodb z uporabniškimi vmesniki.
Za namestitev Truffla:
npm install -g truffle
Hardhat
Hardhat je še eno priljubljeno razvojno okolje za Ethereum, znano po svoji prilagodljivosti in razširljivosti. Omogoča vam prevajanje, uvajanje, testiranje in razhroščevanje kode Solidity. Ključne značilnosti vključujejo:
- Vgrajeno lokalno omrežje Ethereum za testiranje.
- Ekosistem vtičnikov za razširitev funkcionalnosti.
- Razhroščevanje s console.log.
Za namestitev Hardhata:
npm install --save-dev hardhat
Osnove Solidity: Sintaksa in tipi podatkov
Raziščimo osnovno sintakso in tipe podatkov v Solidityju.
Struktura pogodbe Solidity
Pogodba Solidity je podobna razredu v objektno usmerjenem programiranju. Sestavljena je iz spremenljivk stanja, funkcij in dogodkov. Tukaj je preprost primer:
pragma solidity ^0.8.0;
contract SimpleStorage {
uint256 storedData;
function set(uint256 x) public {
storedData = x;
}
function get() public view returns (uint256) {
return storedData;
}
}
Pojasnilo:
pragma solidity ^0.8.0;
: Določa različico prevajalnika Solidity. Ključno je uporabiti združljivo različico, da se izognete nepričakovanemu vedenju.contract SimpleStorage { ... }
: Določa pogodbo z imenomSimpleStorage
.uint256 storedData;
: Deklarira spremenljivko stanja z imenomstoredData
tipauint256
(neznamenovani celo število z 256 biti).function set(uint256 x) public { ... }
: Določa funkcijo z imenomset
, ki kot vhod vzame neznamenovano celo število in posodobi spremenljivkostoredData
. Ključna besedapublic
pomeni, da lahko funkcijo pokliče kdorkoli.function get() public view returns (uint256) { ... }
: Določa funkcijo z imenomget
, ki vrne vrednoststoredData
. Ključna besedaview
označuje, da funkcija ne spreminja stanja pogodbe.
Tipi podatkov
Solidity podpira različne tipe podatkov:
- Cela števila:
uint
(neznamenovano celo število) inint
(znamenovano celo število) z različnimi velikostmi (npr.uint8
,uint256
). - Booleove vrednosti:
bool
(true
alifalse
). - Naslovi:
address
(predstavlja Ethereum naslov). - Znakovni nizi:
bytes
(polja znakov fiksne velikosti) instring
(niz spremenljive velikosti). - Polja: Fiksne velikosti (npr.
uint[5]
) in spremenljive velikosti (npr.uint[]
). - Preslikave: Pari ključ-vrednost (npr.
mapping(address => uint)
).
Primer:
pragma solidity ^0.8.0;
contract DataTypes {
uint256 public age = 30;
bool public isAdult = true;
address public owner = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
bytes32 public name = "JohnDoe";
uint[] public numbers = [1, 2, 3, 4, 5];
mapping(address => uint) public balances;
constructor() {
balances[msg.sender] = 100;
}
}
Spremenljivke stanja proti lokalnim spremenljivkam
Spremenljivke stanja so deklarirane zunaj funkcij in shranjene v verigi blokov. Obstajajo v klicih funkcij in izvrševanju pogodb. V zgornjem primeru je storedData
spremenljivka stanja.
Lokalne spremenljivke so deklarirane znotraj funkcij in obstajajo samo znotraj obsega te funkcije. Niso shranjene v verigi blokov in se zavržejo, ko se funkcija zaključi.
Funkcije v Solidityju
Funkcije so gradniki pametnih pogodb. Določajo logiko in operacije, ki jih lahko pogodba izvede. Funkcije lahko:
- Spremenijo stanje pogodbe.
- Preberejo podatke iz stanja pogodbe.
- Komunicirajo z drugimi pogodbami.
- Pošljejo ali prejmejo Ether.
Vidnost funkcije
Funkcije Solidity imajo štiri modifikatorje vidnosti:
- javna: Lahko se kliče interno in eksterno.
- zasebna: Lahko se kliče interno samo znotraj pogodbe.
- interna: Lahko se kliče interno znotraj pogodbe in izvedenih pogodb.
- eksterna: Lahko se kliče samo eksterno.
Modifikatorji funkcij
Modifikatorji funkcij se uporabljajo za spreminjanje vedenja funkcije. Pogosto se uporabljajo za uveljavljanje varnostnih omejitev ali izvajanje preverjanj pred izvedbo logike funkcije.
Primer:
pragma solidity ^0.8.0;
contract Ownership {
address public owner;
constructor() {
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner, "Only owner can call this function");
_;
}
function transferOwnership(address newOwner) public onlyOwner {
owner = newOwner;
}
}
V tem primeru modifikator onlyOwner
preveri, ali je klicatelj lastnik pogodbe. Če ne, razveljavi transakcijo. Nadomestni znak _
predstavlja preostanek kode funkcije.
Spremenljivost stanja funkcije
Funkcije Solidity imajo lahko tudi modifikatorje spremenljivosti stanja:
- view: Označuje, da funkcija ne spreminja stanja pogodbe. Lahko bere spremenljivke stanja, vendar jih ne more zapisovati.
- pure: Označuje, da funkcija ne bere ali spreminja stanja pogodbe. Je popolnoma samoobsegajoča in deterministična.
- plačljiva: Označuje, da lahko funkcija prejme Ether.
Primer:
pragma solidity ^0.8.0;
contract Example {
uint256 public value;
function getValue() public view returns (uint256) {
return value;
}
function add(uint256 x) public pure returns (uint256) {
return x + 5;
}
function deposit() public payable {
value += msg.value;
}
}
Nadzorne strukture
Solidity podpira standardne nadzorne strukture, kot so zanke if
, else
, for
, while
in do-while
.
Primer:
pragma solidity ^0.8.0;
contract ControlStructures {
function checkValue(uint256 x) public pure returns (string memory) {
if (x > 10) {
return "Vrednost je večja od 10";
} else if (x < 10) {
return "Vrednost je manjša od 10";
} else {
return "Vrednost je enaka 10";
}
}
function sumArray(uint[] memory arr) public pure returns (uint256) {
uint256 sum = 0;
for (uint256 i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
}
Dogodki in beleženje
Dogodki omogočajo pametnim pogodbam komunikacijo z zunanjim svetom. Ko se dogodek sproži, se shrani v dnevnikih transakcij verige blokov. Te dnevnike lahko spremljajo zunanje aplikacije za sledenje dejavnosti pogodbe.
Primer:
pragma solidity ^0.8.0;
contract EventExample {
event ValueChanged(address indexed caller, uint256 newValue);
uint256 public value;
function setValue(uint256 newValue) public {
value = newValue;
emit ValueChanged(msg.sender, newValue);
}
}
V tem primeru se dogodek ValueChanged
sproži vsakič, ko se pokliče funkcija setValue
. Ključna beseda indexed
pri parametru caller
omogoča zunanjim aplikacijam filtriranje dogodkov na podlagi naslova klicatelja.
Dedišče
Solidity podpira dedovanje, kar vam omogoča ustvarjanje novih pogodb na podlagi obstoječih. To spodbuja ponovno uporabo kode in modularnost.
Primer:
pragma solidity ^0.8.0; contract BaseContract { uint256 public value; function setValue(uint256 newValue) public { value = newValue; } }
contract DerivedContract is BaseContract { function incrementValue() public { value++; } }
V tem primeru
DerivedContract
deduje odBaseContract
. Dedi vrednost spremenljivke stanjavalue
in funkcijosetValue
. Določa tudi lastno funkcijo,incrementValue
.Knjižnice
Knjižnice so podobne pogodbam, vendar ne morejo shranjevati podatkov. Uporabljajo se za uvajanje koda za ponovno uporabo, ki jo lahko pokliče več pogodb. Knjižnice se uvedejo samo enkrat, kar zmanjša stroške plina.
Primer:
pragma solidity ^0.8.0; library Math { function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } }
contract Example { using Math for uint256; uint256 public result; function calculateSum(uint256 x, uint256 y) public { result = x.add(y); } }
V tem primeru knjižnica
Math
določa funkcijoadd
. Izjavausing Math for uint256;
vam omogoča, da pokličete funkcijoadd
na spremenljivkahuint256
z uporabo notacije s piko.Pogoste ranljivosti pametnih pogodb
Pametne pogodbe so dovzetne za različne ranljivosti, ki lahko povzročijo izgubo sredstev ali nepričakovano vedenje. Ključno je, da se teh ranljivosti zavedate in sprejmete ukrepe za njihovo ublažitev.
Ponovni vstop (Reentrancy)
Ponovni vstop se pojavi, ko pogodba pokliče zunanjo pogodbo, zunanja pogodba pa pokliče nazaj v prvotno pogodbo, preden se izvedba prvotne pogodbe zaključi. To lahko privede do nepričakovanih sprememb stanja.
Ublažitev: Uporabite vzorec Preverjanja-Učinkov-Interakcij in razmislite o uporabi funkcij
transfer
alisend
za omejitev plina, ki je na voljo za zunanji klic.Prekoračitev in podpadek
Do prekoračitve pride, ko aritmetična operacija preseže največjo vrednost tipa podatkov. Do podpada pride, ko aritmetična operacija povzroči vrednost, ki je manjša od najmanjše vrednosti tipa podatkov.
Ublažitev: Uporabite knjižnice SafeMath (čeprav so s Solidityjem 0.8.0 in novejšimi različicami preverjanja prekoračitve in podpada privzeto vgrajena), da preprečite te težave.
Odvisnost od časovnega žiga
Zanašanje na časovni žig bloka (
block.timestamp
) lahko vašo pogodbo naredi ranljivo za manipulacijo s strani rudarjev, saj imajo ti določen nadzor nad časovnim žigom.Ublažitev: Izogibajte se uporabi
block.timestamp
za kritično logiko. Razmislite o uporabi prerokov ali drugih zanesljivejših virov časa.Zavrnitev storitve (DoS)
Napad DoS ima za cilj onemogočiti pogodbo zakonitim uporabnikom. To je mogoče doseči tako, da porabite ves razpoložljivi plin ali izkoristite ranljivosti, ki povzročijo razveljavitev pogodbe.
Ublažitev: Uvedite omejitve plina, izogibajte se zankam z neomejenimi ponovitvami in skrbno preverjajte uporabniške vnose.
Front running
Front running se pojavi, ko nekdo opazi čakajočo transakcijo in odda svojo transakcijo z višjo ceno plina, da jo izvede pred prvotno transakcijo.
Ublažitev: Uporabite sheme commit-reveal ali druge tehnike, da skrijete podrobnosti transakcije, dokler se ne izvedejo.
Najboljše prakse za pisanje varnih pametnih pogodb
- Naj bo preprosto: Napišite jedrnato in lahko razumljivo kodo.
- Upoštevajte vzorec Preverjanja-Učinkov-Interakcij: Zagotovite, da se preverjanja izvedejo pred kakršnimi koli spremembami stanja in da se interakcije z drugimi pogodbami izvedejo na koncu.
- Uporabite varnostna orodja: Uporabite orodja za statično analizo, kot sta Slither in Mythril, za prepoznavanje morebitnih ranljivosti.
- Napišite enote teste: Temeljito preizkusite svoje pametne pogodbe, da zagotovite, da se obnašajo po pričakovanjih.
- Preverite revizijo: Poskrbite, da vaše pametne pogodbe revidirajo ugledna varnostna podjetja, preden jih uvedete v glavno omrežje.
- Bodite na tekočem: Bodite na tekočem z najnovejšimi varnostnimi ranljivostmi in najboljšimi praksami v skupnosti Solidity.
Napredni koncepti Solidity
Ko imate trdno razumevanje osnov, lahko raziščete bolj napredne koncepte:
Sestavljanje
Solidity vam omogoča pisanje v vrstici kode za sestavljanje, kar vam daje večji nadzor nad EVM. Vendar pa povečuje tudi tveganje uvajanja napak in ranljivosti.
Posredniki
Posredniki vam omogočajo nadgradnjo vaših pametnih pogodb brez migracije podatkov. To vključuje uvedbo posredniške pogodbe, ki posreduje klice pogodbi za izvajanje. Ko želite nadgraditi pogodbo, preprosto uvedete novo pogodbo za izvajanje in posodobite posrednika, da pokaže na novo izvedbo.
Meta-transakcije
Meta-transakcije omogočajo uporabnikom interakcijo z vašo pametno pogodbo, ne da bi neposredno plačevali pristojbine za plin. Namesto tega relayer plača pristojbine za plin v njihovem imenu. To lahko izboljša uporabniško izkušnjo, zlasti za uporabnike, ki so novi v verigi blokov.
EIP-721 in EIP-1155 (NFT)
Solidity se običajno uporablja za ustvarjanje nezamenljivih žetonov (NFT) z uporabo standardov, kot sta EIP-721 in EIP-1155. Razumevanje teh standardov je ključno za gradnjo aplikacij, ki temeljijo na NFT.
Solidity in prihodnost verige blokov
Solidity igra ključno vlogo v hitro razvijajočem se okolju tehnologije verige blokov. Ker se sprejemanje verige blokov še naprej povečuje, bodo razvijalci Solidityja zelo iskani za gradnjo inovativnih in varnih decentraliziranih aplikacij. Jezik se nenehno posodablja in izboljšuje, zato je za uspeh na tem področju bistveno, da ste na tekočem z najnovejšim razvojem.
Zaključek
Solidity je zmogljiv in vsestranski jezik za gradnjo pametnih pogodb na verigi blokov Ethereum. Ta vodnik je zagotovil celovit pregled jezika Solidity, od osnovnih konceptov do naprednih tehnik. Z obvladovanjem Solidityja in upoštevanjem najboljših praks za varen razvoj lahko prispevate k razburljivemu svetu decentraliziranih aplikacij in pomagate oblikovati prihodnost tehnologije verige blokov. Ne pozabite vedno dati prednost varnosti, temeljito preizkusiti svojo kodo in biti obveščeni o najnovejšem razvoju v ekosistemu Solidity. Potencial pametnih pogodb je ogromen in s Solidityjem lahko svoje inovativne ideje uresničite.