# Kuidas kasutada Solidity programmeerimist

Solidity kasutatakse keerukate **nutilepingute** loomiseks, **mis on mõeldud töötama Ethereumi plokiahelas**. See keel pakub unikaalseid strateegiaid, mis eristavad seda teistest programmeerimiskeeltest.

## Mis on Solidity?

Solidity on kõrgetasemeline programmeerimiskeel, mis on mõeldud nutikate lepingute loomiseks Ethereumi plokiahelas. Nutikad lepingud on **ise täitvad lepingud, mis automatiseerivad varade vahetamise osapoolte vahel**. Nende eripäraks on see, et nutika lepingu täitmise tagamiseks ei ole vaja vahendajaid.

Solidity lähtekood kompileeritakse baitkoodiks ja **rakendatakse** Ethereumi plokiahelas nutika lepinguna. Kui see on tehtud, saab nutikat lepingut täita mis tahes võrgu sõlm ja selle seisund salvestatakse plokiahelasse. Toome näite lihtsast lepingust, mis modelleerib NFT-müügiautomaati:

```solidity
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;
    }
}
```

## Milliste rakenduste jaoks on Solidity sobiv?

Solidity on spetsiaalselt loodud Ethereum Virtual Machine’il (EVM) töötavate **hajutatud rakenduste** ehk DAppide **loomiseks**. Nutikad lepingud sobivad muu hulgas digitaalvarade haldamiseks, detsentraliseeritud börside loomiseks ja hääletussüsteemide rakendamiseks.

### Detsentraliseeritud rahandus (DeFi)

Solidity’t kasutatakse selliste DeFi-rakenduste arendamiseks nagu **detsentraliseeritud börsid, krediidi- ja laenuplatvormid, ennustus turud ja krüptovaluutad**. DeFi on saanud üheks populaarsemaks blockchain-tehnoloogia kasutusvaldkonnaks. Selle protsessi käigus on Solidity muutunud asendamatuks vahendiks DeFi-rakenduste loomiseks Ethereumi võrgustikus.

### Asendamatud tokenid

Asendamatud tokenid (NFT) on alates 2020. aastatest olnud väga populaarsed. NFT-d on unikaalsed digitaalsed varad, mis on salvestatud plokiahelas. Need võivad olla **digitaalsed kunstiteosed, spordimälestusesemed või mängutööstuse artefaktid**. NFT-de töötamiseks vajalike nutikate lepingute loomiseks kasutatakse Solidityt.

### Tarneahela juhtimine

Solidity’t saab kasutada arukate lepingute loomiseks **tarneahelate jälgimiseks ja haldamiseks**. Lepingud kasutatakse erinevate tarneahela protsesside automatiseerimiseks. Nende hulka kuuluvad kaupade liikumise jälgimine, toodete autentsuse kontrollimine ja osapooltevaheliste maksete töötlemine.

### Leppimissüsteemid

Solidity abil saab luua nutikaid lepinguid, mis **rakendavad turvalisi ja läbipaistvaid hääletussüsteeme plokiahelas**. Lepingute abil saab tagada, et hääled loetakse õigesti ja et hääletusprotsess on õiglane ja läbipaistev.

## Millised on Solidity eelised ja puudused?

Kuigi Solidity on võimas keel nutikate lepingute loomiseks Ethereumi plokiahelas, on sellel oma spetsiifilised eelised ja puudused, mida arendajad peaksid nutikate lepingute väljatöötamisel arvesse võtma. Siiski nõuab turvaliste nutikate lepingute koostamine teatud taseme **oskusi ja ettevaatlikkust**.

Näitena on allpool toodud **nutikas leping, mis toimib musta auguna**. Kõik lepingule saadetud Etherid kulutatakse lõplikult ära, ilma võimaluseta Etherit tagasi saada või väljamakseid teha:

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

- **Paindlikkus**: Solidity on mitmekülgne keel. Seda saab kasutada erinevate nutikate lepingute arendamiseks mitmesuguste kasutusjuhtude jaoks.
- **Turvalisus**: Solidity loodi turvalisust silmas pidades, sisaldades selliseid omadusi nagu juurdepääsukontroll, erandite käsitlemine ja rikke mehhanismid, et aidata arendajatel luua turvalisi lepinguid.
- **Ethereumi ühilduvus**: Praegu on Solidity eelistatud keel nutikate lepingute loomiseks Ethereumi plokiahelas.
- **Erinev kogukond**: Solidityga töötab suur plokiahela arendajate kogukond, mis pakub rohkesti ressursse õppimiseks ja probleemide lahendamiseks.

### Solidity puudused

- **Õppekõver**: arendajatele, kes on blockchaini ja nutikate lepingute arendamisega alles alguses, on Solidity suhteliselt järsk õppekõver.
- **Muutmatus**: Kui nutikas leping on plokiahelas kasutusele võetud, ei saa seda enam muuta. Seetõttu peavad arendajad kirjutamisel ja testimisel olema äärmiselt ettevaatlikud.
- **Ametliku kontrolli puudumine**: Solidityl puuduvad sisseehitatud tööriistad ametlikuks koodi kontrollimiseks. Seetõttu peavad arendajad kasutama väliseid tööriistu, et tagada oma lepingute täpsus.
- **Piiratud tööriistad**: Solidity tööriistade ökosüsteem on veel algusjärgus, mis võib põhjustada probleeme integreeritud arenduskeskkondade (IDE), testimisraamistike ja muude arendusvahenditega.

## Mis on Solidity põhiline süntaks?

Solidity on **objektorienteeritud programmeerimiskeel**, mis **on loodud nutikate lepingute jaoks**. See on inspireeritud JavaScriptist, Pythonist ja C++-st. Keele süntaks on sarnane JavaScriptiga, kuigi sisaldab mõningaid huvitavaid eripärasusi.

### Muutujad Soliditys

Esmapilgul võib Solidity muutujate käsitlemine tunduda sarnane teiste programmeerimiskeeltega. Siiski on oluline erinevus selles, et Ethereum Virtual Machine (EVM) toimib täitmiskeskkonnana. Kõik **EVM-is tehtavad toimingud, sealhulgas andmete salvestamine, tekitavad teatud koguse „gaasi” kulusid**. Seetõttu tuleb programmeerimise käigus kaaluda toimingu efektiivsust ja otsustada, kuidas seda võimalikult efektiivselt rakendada.

Lisaks tavalistele muutujatele on Solidity-s ka **konstandid, mis tuleb määratleda** kompileerimise ajal. Konstandid vajavad salvestamiseks vähem gaasi:

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

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 muutumatute muutujate määramine toimuda käitamise ajal.

### Kontrollavaldused Soliditys

Imperatiivse programmeerimiskeelena toetab Solidity tuttavaid kontrollavaldisi, nagu **harud ja tsüklid**. Näitame koodi kahe arvu, `a` ja `b`, suurema valimiseks:

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

**Solidity`for` -tsükkel** vastab JavaScriptist või C++-st tuntud süntaksile:

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

**23-tsükkel töötab samuti tavapäraselt**. Kombineerime lõpetamistingimuse numbrilise loendurmuutujaga:

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

### Lihtsad tüübid Soliditys

Solidity on **staatiliselt tüübitav keel** ja toetab programmeerimiskeeltes levinud tüüpe. Üksikväärtusi esindavad lihtsad tüübid hõlmavad booli väärtusi, numbreid ja stringe.

Solidity booleanid kaardistavad väärtused `true` ja `false`. Neid saab ühendada **tuntud booleanide operaatorite** abil ja kasutada `if` avaldistes:

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

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

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

Stringe kasutatakse Soliditys peamiselt staatussõnumite genereerimiseks. Keel toetab **ühekordseid ja kahekordseid jutumärke** ning Unicode-märki:

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

### Funktsioonid Soliditys

**Funktsioonid on** Solidity**põhiline aspekt**, nagu enamikus programmeerimiskeeltes. Funktsiooni määratlus on sarnane JavaScriptiga, kus argumentide tüübid tuleb selgesõnaliselt määratleda. Lisaks kasutatakse märksõna returns, et näidata `return` väärtustüüpi.

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

**Funktsiooni kutsumine** toimub tavapärasel viisil:

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

Huvitaval kombel, **analoogselt nimetatud argumentidega, saab Soliditys ka tagastatavaid väärtusi nimetada**. Sellisel juhul piisab vastavate muutujate määramisest funktsiooni kehas ja selgesõnaline tagastamine `return` kaudu ei ole vajalik:

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

Sarnaselt `constant` või `immutable` muutujaga, **võib** Solidity **funktsioone märkida kui olekut muutmata**. Selleks kasutatakse märksõnu `view` ja `pure`. `view` funktsioon ei muuda olekut, samas kui `pure` funktsioon tagab lisaks, et ei loe oleku muutujaid.

### Arukad lepingud Soliditys

Lisaks standardtüüpidele tunneb Solidity ka mõningaid **nutikate lepingute jaoks spetsialiseeritud tüüpe**. Põhitüüp on `address` ja see kaardistab Ethereumi aadresse. Aadressid, mis on `payable`, võivad vastu võtta ülekandeid Etheris. Selleks pakuvad `payable` aadressid `balance()` ja `transfer()` meetodeid.

```solidity
// 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);
}
```

`address` põhjal on `contract` keskne keelekonstruktsioon. **Lepingud vastavad ligikaudselt objektorienteeritud programmeerimiskeelte klassidele**. Seega koondavad lepingud olekuandmed ja funktsioonid ning kaitsevad neid välismaailma eest. Lepingud toetavad mitmekordset pärimist, nagu on teada Pythonist või C++-st.

Lepingud **algavad tavaliselt `pragma` reaga**, milles täpsustatakse lubatud Solidity versioon, millele järgneb tegelik määratlus:

```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;
    }
}
```

Nutikad lepingud võivad määratleda **seisundi andmed ja funktsioonid**. Nagu C++ ja Java puhul teada, võib igal juhul määratleda ühe kolmest juurdepääsutasemest:

- `public`: Muutuja on kättesaadav **lepingust lugemise ja kirjutamise teel**. Lisaks luuakse automaatselt `view` funktsioon, mis on välise lugemisõiguse saamiseks getter.
- `internal`: Muutuja on välisjuurdepääsu eest **kaitstud**. Lugemis- ja kirjutusjuurdepääs on võimalik nii lepingu sees kui ka pärandatud lepingutes.
- `private`: nagu `internal`, kuid **pärandatud lepingutest ei** ole **juurdepääsu**

Funktsioone võib veelgi iseloomustada järgmiselt: `external`. `external` funktsioon **toimib lepingu liidese osana** ja seda kasutatakse väliseks juurdepääsuks. `receive` funktsioon eetri vastuvõtmiseks on tuntud näide:

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

### Modifikaatorid Soliditys

Solidity’l on huvitav keelekonstruktsioon modifikaatorite vormis, mis sarnanevad Pythoni dekoratoritega. Sarnaselt Pythoniga kasutatakse Solidity modifikaatoreid **funktsiooni kutsumise muutmiseks**. Neid kasutatakse sageli selleks, et tagada konkreetse tingimuse täitmine enne funktsiooni täitmist:

```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;
    }
}
```

### Tehingute haldamine Solidity abil

Solidity-l on sisseehitatud tehingute haldus. Seda saab kasutada tagamaks, et **eetrite ülekanne kas täielikult arveldatakse** või üldse mitte. Keel mõistab märksõna `revert`, mis käivitab tehingu tagasipööramise. Märksõnaga `error` saate määratleda oma veakoodid:

```solidity
// 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
    }
}
```

Teine **sageli esinev muster** on funktsiooni `require()` kasutamine. Seda saab kasutada analoogselt funktsiooniga `revert`:

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


This is a markdown version of: [https://www.ionos.com/et-ee/digitalguide/veebisaidid/veebiarendus/solidity-programmeerimine/](https://www.ionos.com/et-ee/digitalguide/veebisaidid/veebiarendus/solidity-programmeerimine/) for AI/LLM consumption.