Solidity ka­su­ta­takse keerukate nu­ti­le­pin­gute loomiseks, mis on mõeldud töötama Ethereumi plo­kiahe­las. See keel pakub uni­kaal­seid stra­tee­giaid, mis eristavad seda teistest prog­ram­mee­ri­mis­keel­test.

Mis on Solidity?

Solidity on kõr­ge­ta­se­me­line prog­ram­mee­ri­mis­keel, mis on mõeldud nutikate lepingute loomiseks Ethereumi plo­kiahe­las. Nutikad lepingud on ise täitvad lepingud, mis au­to­ma­ti­see­rivad varade va­he­ta­mise osapoolte vahel. Nende eripäraks on see, et nutika lepingu täitmise ta­ga­miseks ei ole vaja va­hen­da­jaid.

Solidity lähtekood kom­pi­lee­ri­takse bait­koo­diks ja ra­ken­da­takse Ethereumi plo­kiahe­las nutika lepinguna. Kui see on tehtud, saab nutikat lepingut täita mis tahes võrgu sõlm ja selle seisund sal­ves­ta­takse plo­kiahe­lasse. Toome näite lihtsast lepingust, mis mo­del­lee­rib NFT-müü­gi­au­to­maati:

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

Milliste ra­ken­duste jaoks on Solidity sobiv?

Solidity on spet­siaal­selt loodud Ethereum Virtual Machine’il (EVM) töötavate hajutatud ra­ken­duste ehk DAppide loomiseks. Nutikad lepingud sobivad muu hulgas di­gi­taal­va­rade hal­da­miseks, det­sent­ra­li­see­ri­tud börside loomiseks ja hää­le­tus­süs­teemide ra­ken­da­miseks.

Det­sent­ra­li­see­ri­tud rahandus (DeFi)

Solidity’t ka­su­ta­takse selliste DeFi-ra­ken­duste aren­da­miseks nagu det­sent­ra­li­see­ri­tud börsid, krediidi- ja lae­nu­plat­vor­mid, ennustus turud ja krüp­to­va­luu­tad. DeFi on saanud üheks po­pu­laar­se­maks blockc­hain-teh­no­loo­gia ka­su­tus­vald­kon­naks. Selle protsessi käigus on Solidity muutunud asen­da­ma­tuks vahendiks DeFi-ra­ken­duste loomiseks Ethereumi võr­gus­ti­kus.

Asen­da­ma­tud tokenid

Asen­da­ma­tud tokenid (NFT) on alates 2020. aastatest olnud väga po­pu­laar­sed. NFT-d on uni­kaal­sed di­gi­taal­sed varad, mis on sal­ves­ta­tud plo­kiahe­las. Need võivad olla di­gi­taal­sed kuns­ti­teo­sed, spor­di­mä­les­tuse­se­med või män­gu­töös­tuse ar­te­fak­tid. NFT-de töö­ta­miseks vajalike nutikate lepingute loomiseks ka­su­ta­takse Solidityt.

Tar­neahela juhtimine

Solidity’t saab kasutada arukate lepingute loomiseks tar­neahe­late jäl­gi­miseks ja hal­da­miseks. Lepingud ka­su­ta­takse erinevate tar­neahela prot­ses­side au­to­ma­ti­see­ri­miseks. Nende hulka kuuluvad kaupade liikumise jälgimine, toodete au­tent­suse kont­rol­li­mine ja osa­pool­te­va­he­liste maksete tööt­le­mine.

Lep­pi­mis­süs­tee­mid

Solidity abil saab luua nutikaid lepinguid, mis ra­ken­da­vad turvalisi ja lä­bi­paist­vaid hää­le­tus­süs­teeme plo­kiahe­las. Lepingute abil saab tagada, et hääled loetakse õigesti ja et hää­le­tus­prot­sess on õiglane ja lä­bi­pais­tev.

Millised on Solidity eelised ja puudused?

Kuigi Solidity on võimas keel nutikate lepingute loomiseks Ethereumi plo­kiahe­las, on sellel oma spet­sii­fi­li­sed eelised ja puudused, mida arendajad peaksid nutikate lepingute väl­ja­töö­ta­misel arvesse võtma. Siiski nõuab tur­valiste nutikate lepingute koos­ta­mine teatud taseme oskusi ja et­te­vaat­lik­kust.

Näitena on allpool toodud nutikas leping, mis toimib musta auguna. Kõik lepingule saadetud Etherid ku­lu­ta­takse lõplikult ära, ilma või­ma­lu­seta Etherit tagasi saada või väl­ja­mak­seid teha:

// 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 eelised

  • Paind­lik­kus: Solidity on mit­me­külgne keel. Seda saab kasutada erinevate nutikate lepingute aren­da­miseks mit­me­su­guste ka­su­tus­juh­tude jaoks.
  • Tur­va­li­sus: Solidity loodi tur­va­li­sust silmas pidades, si­sal­da­des selliseid omadusi nagu juur­de­pää­su­kont­roll, erandite kä­sit­le­mine ja rikke meh­ha­nis­mid, et aidata aren­da­ja­tel luua turvalisi lepinguid.
  • Ethereumi ühilduvus: Praegu on Solidity eelis­ta­tud keel nutikate lepingute loomiseks Ethereumi plo­kiahe­las.
  • Erinev kogukond: So­li­dityga töötab suur plo­kiahela aren­da­jate kogukond, mis pakub rohkesti ressursse õp­pi­miseks ja prob­leemide la­hen­da­miseks.

Solidity puudused

  • Õppekõver: aren­da­ja­tele, kes on blockc­haini ja nutikate lepingute aren­da­mi­sega alles alguses, on Solidity suh­te­li­selt järsk õppekõver.
  • Muutmatus: Kui nutikas leping on plo­kiahe­las ka­su­tusele võetud, ei saa seda enam muuta. Seetõttu peavad arendajad kir­ju­ta­misel ja tes­ti­misel olema äärmiselt et­te­vaat­li­kud.
  • Ametliku kontrolli puudumine: Solidityl puuduvad sis­se­ehi­ta­tud töö­riis­tad amet­likuks koodi kont­rol­li­miseks. Seetõttu peavad arendajad kasutama väliseid tööriistu, et tagada oma lepingute täpsus.
  • Piiratud töö­riis­tad: Solidity töö­riis­tade öko­süs­teem on veel al­gus­jär­gus, mis võib põh­jus­tada probleeme in­teg­ree­ri­tud aren­dus­kesk­kon­dade (IDE), tes­ti­mis­raa­mis­tike ja muude aren­dus­va­hen­di­tega.

Mis on Solidity põhiline süntaks?

Solidity on ob­jek­to­rien­tee­ri­tud prog­ram­mee­ri­mis­keel, mis on loodud nutikate lepingute jaoks. See on ins­pi­ree­ri­tud Ja­vaSc­rip­tist, Pythonist ja C++-st. Keele süntaks on sarnane Ja­vaSc­rip­tiga, kuigi sisaldab mõningaid hu­vi­ta­vaid eri­pä­ra­susi.

Muutujad Soliditys

Es­ma­pil­gul võib Solidity muutujate kä­sit­le­mine tunduda sarnane teiste prog­ram­mee­ri­mis­keel­tega. Siiski on oluline erinevus selles, et Ethereum Virtual Machine (EVM) toimib täit­mis­kesk­kon­nana. Kõik EVM-is tehtavad toimingud, seal­hul­gas andmete sal­ves­ta­mine, tekitavad teatud koguse „gaasi” kulusid. Seetõttu tuleb prog­ram­mee­ri­mise käigus kaaluda toimingu efek­tiiv­sust ja otsustada, kuidas seda või­ma­li­kult efek­tiiv­selt rakendada.

Lisaks ta­valis­tele muu­tu­ja­tele on Solidity-s ka kons­tan­did, mis tuleb mää­rat­leda kom­pi­lee­ri­mise ajal. Kons­tan­did vajavad sal­ves­ta­miseks vähem gaasi:

// Regular variable can be declared without defining
int a;
// Constant needs to be defined at declaration
int constant b = 51;
solidity

Sama kehtib ka immutable muutuja kohta, kuna need vajavad vähem gaasi ja neid ei saa pärast määramist muuta. Erinevalt constant muutujast saab muu­tu­ma­tute muutujate määramine toimuda käitamise ajal.

Kont­rolla­val­dused Soliditys

Im­pe­ra­tiivse prog­ram­mee­ri­mis­kee­lena toetab Solidity tuttavaid kont­rollaval­disi, nagu harud ja tsüklid. Näitame koodi kahe arvu, a ja b, suurema va­li­miseks:

int largerNumber = 0;
// If-else statement
if (a > b) {
    largerNumber = a;
} else {
        largerNumber = b;
}
solidity

Solidityfor -tsükkel vastab Ja­vaSc­rip­tist või C++-st tuntud sün­tak­sile:

// Loop 10 times
for (int i = 0; i < 10; i++) {
    // …
}
solidity

23-tsükkel töötab samuti ta­va­pä­ra­selt. Kom­bi­nee­rime lõ­pe­ta­mis­tin­gi­muse numb­ri­lise loen­dur­muu­tu­jaga:

bool continueLoop = true;
int counter = 0;
// Loop at most 10 times
while (continueLoop && counter < 10) {
    // …
    counter++;
}
solidity

Lihtsad tüübid Soliditys

Solidity on staa­ti­li­selt tüübitav keel ja toetab prog­ram­mee­ri­mis­keel­tes levinud tüüpe. Ük­sik­väär­tusi esindavad lihtsad tüübid hõlmavad booli väärtusi, numbreid ja stringe.

Solidity booleanid kaar­dis­ta­vad väärtused true ja false. Neid saab ühendada tuntud boo­lea­nide ope­raa­to­rite abil ja kasutada if aval­dis­tes:

bool paymentReceived = true;
bool itemsStocked = true;
bool continueTransaction = paymentReceived && itemsStocked;
if (continueTransaction) {
    // ...
}
solidity

Solidity toetab laia valikut numb­rilisi tüüpe. Täisarvud võib jagada märgiga (int) ja märgita (uint) arvudeks, kusjuures viimased võivad olla ainult po­si­tiiv­sed. Lisaks võib arvu vahemiku määrata 8-bitiste sammude kaupa, alates int8, läbi int16 kuni int265:

uint8 smallNumber = 120;
int8 negativeNumber = -125;
int8 result = smallNumber + negativeNumber;
assert(result == -5)
solidity

Stringe ka­su­ta­takse Soliditys peamiselt staa­tus­sõ­nu­mite ge­ne­ree­ri­miseks. Keel toetab ühe­kord­seid ja ka­he­kord­seid jutumärke ning Unicode-märki:

string message = 'Hello World';
string success = unicode"Transfer sent";
Solidity

Funkt­sioo­nid Soliditys

Funkt­sioo­nid on Soliditypõhiline aspekt, nagu enamikus prog­ram­mee­ri­mis­keel­tes. Funkt­siooni määratlus on sarnane Ja­vaSc­rip­tiga, kus ar­gu­men­tide tüübid tuleb sel­ge­sõ­na­li­selt mää­rat­leda. Lisaks ka­su­ta­takse märksõna returns, et näidata return väär­tus­tüüpi.

// Define a function
function addNumbers(int a, int b) returns (int) {
    return a + b;
}
solidity

Funkt­siooni kutsumine toimub ta­va­pä­ra­sel viisil:

// Call the function
int result = addNumbers(2, 3);
solidity

Huvitaval kombel, ana­loog­selt nimetatud ar­gu­men­ti­dega, saab Soliditys ka ta­gas­ta­ta­vaid väärtusi nimetada. Sellisel juhul piisab vastavate muutujate mää­ra­mi­sest funkt­siooni kehas ja sel­ge­sõ­na­line ta­gas­ta­mine return kaudu ei ole vajalik:

function divideNumbers(int dividend, int divisor) returns (int quotient) {
    quotient = dividend / divisor;
    // No `return` necessary
}
solidity

Sarnaselt constant või immutable muutujaga, võib Solidity funkt­sioone märkida kui olekut muutmata. Selleks ka­su­ta­takse märksõnu view ja pure. view funkt­sioon ei muuda olekut, samas kui pure funkt­sioon tagab lisaks, et ei loe oleku muutujaid.

Arukad lepingud Soliditys

Lisaks stan­dard­tüü­pi­dele tunneb Solidity ka mõningaid nutikate lepingute jaoks spet­sia­li­see­ri­tud tüüpe. Põhitüüp on address ja see kaar­dis­tab Ethereumi aadresse. Aadressid, mis on payable, võivad vastu võtta üle­kan­deid Etheris. Selleks pakuvad payable aadressid balance() ja transfer() meetodeid.

// 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 põhjal on contract keskne kee­le­konst­rukt­sioon. Lepingud vastavad li­gi­kaud­selt ob­jek­to­rien­tee­ri­tud prog­ram­mee­ri­mis­keelte klas­si­dele. Seega koondavad lepingud ole­ku­and­med ja funkt­sioo­nid ning kaitsevad neid vä­lis­maa­ilma eest. Lepingud toetavad mit­me­kord­set pärimist, nagu on teada Pythonist või C++-st.

Lepingud algavad ta­va­li­selt pragma reaga, milles täp­sus­ta­takse lubatud Solidity versioon, millele järgneb tegelik määratlus:

// 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

Nutikad lepingud võivad mää­rat­leda seisundi andmed ja funkt­sioo­nid. Nagu C++ ja Java puhul teada, võib igal juhul mää­rat­leda ühe kolmest juur­de­pää­su­ta­se­mest:

  • public: Muutuja on kät­te­saa­dav lepingust lugemise ja kir­ju­ta­mise teel. Lisaks luuakse au­to­maat­selt view funkt­sioon, mis on välise lu­ge­mis­õi­guse saamiseks getter.
  • internal: Muutuja on vä­lis­juur­de­pääsu eest kaitstud. Lugemis- ja kir­ju­tus­juur­de­pääs on võimalik nii lepingu sees kui ka pä­ran­da­tud le­pin­gu­tes.
  • private: nagu internal, kuid pä­ran­da­tud le­pin­gu­test ei ole juur­de­pääsu

Funkt­sioone võib veelgi ise­loo­mus­tada järg­mi­selt: external. external funkt­sioon toimib lepingu liidese osana ja seda ka­su­ta­takse väliseks juur­de­pääs­uks. receive funkt­sioon eetri vas­tu­võt­miseks on tuntud näide:

// Define without `function` keyword
receive() external payable {
    // Handle Ether
}
solidity

Mo­di­fi­kaa­to­rid Soliditys

Solidity’l on huvitav kee­le­konst­rukt­sioon mo­di­fi­kaa­to­rite vormis, mis sar­na­ne­vad Pythoni de­ko­ra­to­ri­tega. Sarnaselt Pythoniga ka­su­ta­takse Solidity mo­di­fi­kaa­to­reid funkt­siooni kutsumise muut­miseks. Neid ka­su­ta­takse sageli selleks, et tagada konk­reetse tingimuse täitmine enne funkt­siooni täitmist:

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

Tehingute haldamine Solidity abil

Solidity-l on sis­se­ehi­ta­tud tehingute haldus. Seda saab kasutada tagamaks, et eetrite ülekanne kas täie­li­kult ar­vel­da­takse või üldse mitte. Keel mõistab märksõna revert, mis käivitab tehingu ta­ga­si­pöö­ra­mise. Märk­sõ­naga error saate mää­rat­leda oma veakoodid:

// 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

Teine sageli esinev muster on funkt­siooni require() ka­su­ta­mine. Seda saab kasutada ana­loog­selt funkt­sioo­niga revert:

// Using `require()` function
if (!condition) revert("Error message");
// Equivalent to
require(condition, "Error message");
solidity
Go to Main Menu