# Solidity-ohjelmoinnin käyttö

Solidityä käytetään monimutkaisten **älykkäiden sopimusten** luomiseen, **jotka on suunniteltu toimimaan Ethereum-lohkoketjussa**. Tämä kieli tarjoaa ainutlaatuisia strategioita, jotka erottavat sen muista ohjelmointikielistä.

## Mikä on Solidity?

Solidity on korkean tason ohjelmointikieli, jolla luodaan älykkäitä sopimuksia Ethereum-lohkoketjussa. Älykkäät sopimukset ovat **itsestään suoritettavia sopimuksia, jotka automatisoivat osapuolten välisen omaisuuden vaihdon**. Niiden erityispiirre on, että älykkään sopimuksen noudattamisen varmistamiseksi ei tarvita välittäjiä.

Solidity-lähdekoodi käännetään bytecode-koodiksi ja **otetaan käyttöön** Ethereum-lohkoketjussa älykkäänä sopimuksena. Kun tämä on tehty, älykäs sopimus voidaan suorittaa millä tahansa verkon solmulla, ja tila tallennetaan lohkoketjuun. Esitämme esimerkin yksinkertaisesta sopimuksesta, joka mallintaa NFT-automaattia:

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

## Mihin sovelluksiin Solidity sopii?

Solidity on suunniteltu erityisesti **hajautettujen sovellusten** tai DApp-sovellusten **luomiseen, jotka** toimivat Ethereum Virtual Machine (EVM) -alustalla. Älykkäät sopimukset soveltuvat muun muassa digitaalisten varojen hallintaan, hajautettujen pörssien luomiseen ja äänestysjärjestelmien toteuttamiseen.

### Hajautettu rahoitus (DeFi)

Solidityä käytetään **hajautettujen pörssien, luotto- ja lainausalustojen, ennustemarkkinoiden ja kryptovaluuttojen** kaltaisten DeFi-sovellusten kehittämiseen. DeFi on noussut yhdeksi suosituimmista blockchain-teknologian käyttötapauksista. Tässä prosessissa Soliditystä on tullut välttämätön työkalu DeFi-sovellusten rakentamiseen Ethereum-verkostossa.

### Ei-vaihdettavat tunnukset

Ei-vaihdettava tunnus (NFT) on nauttinut suuresta suosiosta 2020-luvulta lähtien. NFT:t ovat ainutlaatuisia digitaalisia omaisuuseriä, jotka on tallennettu lohkoketjuun. Ne voivat olla **digitaalisia taideteoksia, urheilumuistoja tai pelialan esineitä**. Solidityä käytetään luomaan älykkäitä sopimuksia, jotka mahdollistavat NFT:t.

### Toimitusketjun hallinta

Solidityä voidaan käyttää älykkäiden sopimusten luomiseen **toimitusketjujen seurantaa ja hallintaa** varten. Sopimuksia käytetään erilaisten toimitusketjuprosessien automatisointiin. Näitä ovat esimerkiksi tavaroiden liikkeiden seuranta, tuotteiden aitouden varmistaminen ja maksujen käsittely osapuolten välillä.

### Täsmäytysjärjestelmät

Solidityä voidaan käyttää luomaan älykkäitä sopimuksia, jotka **toteuttavat turvallisia ja läpinäkyviä äänestysjärjestelmiä lohkoketjussa**. Sopimuksia voidaan käyttää varmistamaan, että äänet lasketaan oikein ja että äänestysprosessi on oikeudenmukainen ja läpinäkyvä.

## Mitkä ovat Solidityn edut ja haitat?

Solidity on tehokas kieli älykkäiden sopimusten rakentamiseen Ethereum-lohkoketjussa, mutta sillä on omat etunsa ja haittansa, jotka kehittäjien tulisi ottaa huomioon älykkäitä sopimuksia kehittäessään. Turvallisten älykkäiden sopimusten laatiminen vaatii kuitenkin tiettyä **osaamista ja varovaisuutta**.

Esimerkkinä alla on **älykäs sopimus, joka toimii mustana aukona**. Sopimukseen lähetetty Ether kuluu pysyvästi, eikä Etheriä ole mahdollista saada takaisin tai maksaa ulos:

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

### Solidityn edut

- **Joustavuus**: Solidity on monipuolinen kieli. Sitä voidaan käyttää erilaisten älykkäiden sopimusten kehittämiseen monenlaisiin käyttötarkoituksiin.
- **Turvallisuus**: Solidity on luotu turvallisuutta silmällä pitäen, ja se sisältää ominaisuuksia, kuten pääsynvalvonta, poikkeusten käsittely ja vikamekanismit, jotka auttavat kehittäjiä luomaan turvallisia sopimuksia.
- **Ethereum-yhteensopivuus**: Tällä hetkellä Solidity on suosituin kieli älykkäiden sopimusten luomiseen Ethereum-lohkoketjussa.
- **Erillinen yhteisö**: Suuri joukko lohkoketjujen kehittäjiä työskentelee Solidityn parissa, mikä tarjoaa runsaasti resursseja oppimiseen ja ongelmanratkaisuun.

### Solidityn haitat

- **Oppimiskäyrä**: Kehittäjille, joille blockchain ja älykkäiden sopimusten kehittäminen on uutta, Solidityn oppimiskäyrä on suhteellisen jyrkkä.
- **Muuttumattomuus**: Kun älykäs sopimus on otettu käyttöön lohkoketjussa, sitä ei voi enää muokata. Kehittäjien on siis oltava erittäin huolellisia kirjoittaessaan ja testatessaan.
- **Muodollisen varmennuksen puute**: Soliditysta puuttuvat sisäänrakennetut työkalut muodolliseen koodin tarkistukseen. Tämä edellyttää, että kehittäjät käyttävät ulkoisia työkaluja sopimustensa tarkkuuden takaamiseksi.
- **Rajoitetut työkalut**: Solidityn työkaluekosysteemi on vielä alkuvaiheessa, mikä voi aiheuttaa ongelmia integroiduissa kehitysympäristöissä (IDE), testauskehyksissä ja muissa kehitystyökaluissa.

## Mikä on Solidityn perusrakenteet?

Solidity on **objektisuuntautunut ohjelmointikieli,** joka **on suunniteltu älykkäitä sopimuksia varten**. Se on saanut vaikutteita JavaScriptista, Pythonista ja C++:sta. Kielen syntaksi on samanlainen kuin JavaScriptissa, mutta siinä on joitakin mielenkiintoisia erityispiirteitä.

### Muuttujat Solidity-kielessä

Ensi silmäyksellä Solidityn muuttujien käsittely saattaa vaikuttaa samanlaiselta kuin muissa ohjelmointikielissä. Kuitenkin merkittävä ero syntyy siitä, että Ethereum Virtual Machine (EVM) toimii suoritusympäristönä. Kaikki **EVM:llä suoritetut toiminnot, mukaan lukien tietojen tallennus, aiheuttavat tietyn määrän “kaasukustannuksia”**. Näin ollen ohjelmoinnin aikana on punnittava toiminnon tehokkuutta ja päätettävä, miten se voidaan toteuttaa mahdollisimman tehokkaasti.

Tavallisten muuttujien lisäksi Solidityssä on **vakioita, jotka on määriteltävä** kääntämisen aikana. Vakioille tarvitaan vähemmän kaasua tallennustilaa varten:

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

Sama pätee `immutable` muuttujiin, sillä ne vaativat vähemmän muistia ja **niitä ei voi muuttaa määrittelyn jälkeen**. Toisin kuin `constant` muuttujat, muuttumattomien muuttujien määrittely voidaan tehdä suorituksen aikana.

### Ohjauslauseet Solidity-kielessä

Imperatiivisen ohjelmointikielenä Solidity tukee tuttuja ohjauslauseita, kuten **haaroja ja silmukoita**. Esitämme koodin, jolla valitaan suurempi kahdesta luvusta, `a` ja `b`:

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

**Solidityn`for`** vastaa JavaScriptista tai C++:sta tuttua syntaksia:

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

**23-silmukka toimii myös tavalliseen tapaan**. Yhdistämme lopetusehdon numeeriseen laskuriin:

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

### Yksinkertaiset tyypit Solidity-kielessä

Solidity on **staattisesti tyypitetty kieli**, joka tukee ohjelmointikielissä yleisesti käytettyjä tyyppejä. Yksittäisiä arvoja edustavia yksinkertaisia tyyppejä ovat boolenit, numerot ja merkkijonot.

Solidityn boolenit kuvaavat arvoja `true` ja `false`. Ne voidaan linkittää käyttämällä **tunnettuja boolenien operaattoreita** ja käyttää `if` lauseissa:

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

Solidity tukee **laajaa valikoimaa numeerisia tyyppejä**. Kokonaisluvut voidaan jakaa merkittyihin (`int`) ja merkitsemättömiin (`uint`) lukuihin, joista jälkimmäiset voivat olla vain positiivisia. Lisäksi luvun alue voidaan määrittää 8 bitin välein, välillä `int265`:

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

Merkkijonoja käytetään Solidity-kielessä pääasiassa tilaviestien luomiseen. Kieli tukee **yksittäisiä ja kaksoislaattoja** sekä Unicode-merkkejä:

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

### Solidityn toiminnot

**Funktiot ovat** Solidityn**peruselementti**, kuten useimmissa ohjelmointikielissä. Funktion määritelmä on samanlainen kuin JavaScriptissä, jossa argumenttityypit on määriteltävä eksplisiittisesti. Lisäksi käytetään returns-avainsanaa `return` arvon tyypin ilmoittamiseen.

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

**Funktion kutsuminen** tapahtuu tavalliseen tapaan:

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

Mielenkiintoista on **, että nimettyjen argumenttien tavoin myös Solidityn palautusarvot voidaan nimetä.** Tässä tilanteessa riittää, että vastaavat muuttujat määritellään funktion rungossa, eikä eksplisiittistä palautusta `return` kautta tarvita:

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

Samoin kuin `constant` tai `immutable` muuttujassa, Solidity **-funktiot voidaan merkitä tilaa muuttamattomiksi**. Tätä tarkoitusta varten käytetään avainsanoja `view` ja `pure`. `view` -funktio ei muuta tilaa, kun taas `pure` -funktio takaa lisäksi, ettei se lue tilamuuttujia.

### Älykkäät sopimukset Solidity-kielellä

Vakiotyyppien lisäksi Solidity tuntee muutamia **älykkäisiin sopimuksiin erikoistuneita tyyppejä**. Perustyyppi on `address` ja se kartoittaa Ethereum-osoitteet. Osoitteet, jotka ovat `payable`, voivat vastaanottaa siirtoja Etherissä. Tätä tarkoitusta varten `payable` tarjoavat `balance()` ja `transfer()`.

```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` pohjalta kehitetty `contract` on keskeinen kielirakenne. **Sopimukset vastaavat suurin piirtein olio-ohjelmointikielten luokkia**. Sopimukset yhdistävät tilatiedot ja toiminnot ja suojaavat ne ulkomaailmalta. Sopimukset tukevat moniperintöä, kuten Python- tai C++-kielissä.

Sopimukset **alkavat yleensä `pragma` rivillä, jossa** määritellään sallittu Solidity-versio, jota seuraa varsinainen määritelmä:

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

Älykkäät sopimukset voivat määritellä **tilatiedot ja toiminnot**. Kuten C++- ja Java-kielistä tiedetään, kussakin tapauksessa voidaan määritellä yksi kolmesta käyttöoikeustasosta:

- `public`: Muuttujaa voidaan käyttää **lukemalla ja kirjoittamalla sopimuksen sisällä**. Lisäksi `view` funktio luodaan automaattisesti ulkoisen lukemisen getteriksi.
- `internal`: Muuttuja on **suojattu** ulkoiselta pääsyltä. Luku- ja kirjoitusoikeudet ovat mahdollisia sopimuksen sisällä sekä periytyvissä sopimuksissa.
- `private`: kuten `internal`, mutta **periytyvistä sopimuksista ei** ole **pääsyä**

Toimintoja voidaan edelleen luonnehtia seuraavasti: `external`. `external` **toimii osana sopimusrajapintaa** ja sitä käytetään ulkoiseen pääsyyn. `receive` etherin vastaanottamiseen on tunnettu esimerkki:

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

### Modifioijat Solidity-kielessä

Solidity-kielessä on mielenkiintoinen kielirakenne, modifioijat, jotka muistuttavat Pythonin koristeita. Pythonin tavoin Solidityn modifioijia käytetään **muuttamaan funktion kutsumista**. Niitä käytetään usein varmistamaan, että tietty ehto täyttyy ennen funktion suorittamista:

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

### Transaktioiden hallinta Solidity-ohjelmistolla

Solidityssa on sisäänrakennettu transaktioiden hallinta. Sitä voidaan käyttää varmistamaan, että **ether-siirto joko toteutetaan kokonaan** tai ei toteuteta lainkaan. Kieli ymmärtää avainsanan `revert`, joka laukaisee transaktion “peruuttamisen”. Avainsanalla `error` voit määritellä omat virhekoodisi:

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

Toinen **usein esiintyvä malli** on `require()` funktion käyttö. Tätä voidaan käyttää analogisesti `revert` kanssa:

```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/fi-fi/digitalguide/verkkosivustot/verkkosivujen-kehittaeminen/solidity-ohjelmointi/](https://www.ionos.com/fi-fi/digitalguide/verkkosivustot/verkkosivujen-kehittaeminen/solidity-ohjelmointi/) for AI/LLM consumption.