Tutustu Solidityyn, johtavaan ohjelmointikieleen älysopimusten kehittämiseen Ethereum-lohkoketjussa. Tämä kattava opas kattaa kaiken peruskäsitteistä edistyneisiin tekniikoihin.
Solidity: Kattava opas älysopimusten ohjelmointiin
Solidity on korkean tason, sopimuspohjainen ohjelmointikieli, jota käytetään älysopimusten toteuttamiseen eri lohkoketjuympäristöissä, erityisesti Ethereumissa. Siihen ovat vaikuttaneet voimakkaasti C++, Python ja JavaScript, ja se on suunniteltu Ethereum Virtual Machinelle (EVM). Tämä opas tarjoaa yksityiskohtaisen yleiskatsauksen Solidityyn, joka sopii sekä aloittelijoille että kokeneille ohjelmoijille, jotka haluavat sukeltaa lohkoketjujen kehittämisen maailmaan.
Mitä ovat älysopimukset?
Ennen kuin sukellamme Solidityyn, on tärkeää ymmärtää, mitä älysopimukset ovat. Älysopimus on itsestään toteuttava sopimus, jonka ehdot on kirjoitettu suoraan koodiin. Se on tallennettu lohkoketjuun ja toteutuu automaattisesti, kun ennalta määrätyt ehdot täyttyvät. Älysopimukset mahdollistavat automaation, läpinäkyvyyden ja turvallisuuden erilaisissa sovelluksissa, kuten:
- Hajautettu rahoitus (DeFi): Laina-, otto- ja kaupankäyntialustat.
- Toimitusketjun hallinta: Tavaran seuranta ja läpinäkyvyyden varmistaminen.
- Äänestysjärjestelmät: Turvallinen ja todennettava sähköinen äänestys.
- Kiinteistöt: Kiinteistökauppojen automatisointi.
- Terveydenhuolto: Potilastietojen turvallinen hallinta.
Miksi Solidity?
Solidity on hallitseva kieli älysopimusten kirjoittamiseen Ethereumissa ja muissa EVM-yhteensopivissa lohkoketjuissa useiden tekijöiden vuoksi:
- EVM-yhteensopivuus: Solidity on suunniteltu erityisesti kääntymään tavukoodiksi, joka voidaan suorittaa Ethereum Virtual Machinella.
- Yhteisön tuki: Suuri ja aktiivinen yhteisö tarjoaa laajan dokumentaation, kirjastoja ja työkaluja.
- Turvallisuusominaisuudet: Solidity sisältää ominaisuuksia, jotka lieventävät yleisiä älysopimusten haavoittuvuuksia.
- Korkean tason abstraktio: Tarjoaa korkean tason rakenteita, jotka tekevät sopimusten kehittämisestä tehokkaampaa ja hallittavampaa.
Kehitysympäristön määrittäminen
Aloittaaksesi kehittämisen Soliditylla, sinun on määritettävä sopiva kehitysympäristö. Tässä on joitain suosittuja vaihtoehtoja:
Remix IDE
Remix on online-pohjainen IDE, joka on täydellinen Solidityn oppimiseen ja kokeilemiseen. Se ei vaadi paikallista asennusta ja tarjoaa ominaisuuksia, kuten:
- Koodieditori syntaksikorostuksella ja automaattisella täydennyksellä.
- Kääntäjä Solidity-koodin muuntamiseen tavukoodiksi.
- Julkaisija sopimusten käyttöönottoa varten testiverkkoihin tai pääverkkoon.
- Virheenkorjaaja koodin läpikäyntiin ja virheiden tunnistamiseen.
Pääset Remix IDE:hen osoitteessa https://remix.ethereum.org/
Truffle Suite
Truffle on kattava kehitysympäristö, joka yksinkertaistaa älysopimusten rakentamista, testaamista ja käyttöönottoa. Se tarjoaa työkaluja, kuten:
- Truffle: Komentorivityökalu projektin luomiseen, kääntämiseen, käyttöönottoon ja testaamiseen.
- Ganache: Henkilökohtainen lohkoketju paikallista kehitystä varten.
- Drizzle: Kokoelma käyttöliittymäkirjastoja, jotka helpottavat älysopimusten integroimista käyttöliittymiin.
Trufflen asentaminen:
npm install -g truffle
Hardhat
Hardhat on toinen suosittu Ethereum-kehitysympäristö, joka tunnetaan joustavuudestaan ja laajennettavuudestaan. Sen avulla voit kääntää, ottaa käyttöön, testata ja korjata Solidity-koodiasi. Tärkeimpiä ominaisuuksia ovat:
- Sisäänrakennettu paikallinen Ethereum-verkko testausta varten.
- Laajennusekosysteemi toiminnallisuuden laajentamiseen.
- Console.log-virheenkorjaus.
Hardhatin asentaminen:
npm install --save-dev hardhat
Solidityn perusteet: Syntaksi ja tietotyypit
Tutkitaan Solidityn perussyntaksia ja tietotyyppejä.
Solidity-sopimuksen rakenne
Solidity-sopimus on samanlainen kuin luokka olio-ohjelmoinnissa. Se koostuu tilamuuttujista, funktioista ja tapahtumista. Tässä on yksinkertainen esimerkki:
pragma solidity ^0.8.0;
contract SimpleStorage {
uint256 storedData;
function set(uint256 x) public {
storedData = x;
}
function get() public view returns (uint256) {
return storedData;
}
}
Selitys:
pragma solidity ^0.8.0;
: Määrittää Solidity-kääntäjän version. On erittäin tärkeää käyttää yhteensopivaa versiota odottamattoman käyttäytymisen välttämiseksi.contract SimpleStorage { ... }
: Määrittää sopimuksen nimeltäSimpleStorage
.uint256 storedData;
: Ilmoittaa tilamuuttujan nimeltästoredData
, jonka tyyppi onuint256
(etumerkitön kokonaisluku, jossa on 256 bittiä).function set(uint256 x) public { ... }
: Määrittää funktion nimeltäset
, joka ottaa etumerkittömän kokonaisluvun syötteenä ja päivittäästoredData
-muuttujan. Avainsanapublic
tarkoittaa, että kuka tahansa voi kutsua funktiota.function get() public view returns (uint256) { ... }
: Määrittää funktion nimeltäget
, joka palauttaastoredData
-arvon. Avainsanaview
osoittaa, että funktio ei muokkaa sopimuksen tilaa.
Tietotyypit
Solidity tukee useita tietotyyppejä:
- Kokonaisluvut:
uint
(etumerkitön kokonaisluku) jaint
(etumerkillinen kokonaisluku), joilla on vaihtelevat koot (esim.uint8
,uint256
). - Totuusarvot:
bool
(true
taifalse
). - Osoitteet:
address
(edustaa Ethereum-osoitetta). - Tavut:
bytes
(kiinteän kokoiset tavutaulukot) jastring
(dynaamisen kokoinen merkkijono). - Taulukot: Kiinteän kokoiset (esim.
uint[5]
) ja dynaamisen kokoiset (esim.uint[]
). - Kartoitukset: Avain-arvo -parit (esim.
mapping(address => uint)
).
Esimerkki:
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;
}
}
Tilamuuttujat vs. Paikalliset muuttujat
Tilamuuttujat ilmoitetaan funktioiden ulkopuolella ja tallennetaan lohkoketjuun. Ne säilyvät funktioiden kutsujen ja sopimusten suoritusten välillä. Yllä olevassa esimerkissä storedData
on tilamuuttuja.
Paikalliset muuttujat ilmoitetaan funktioiden sisällä ja ovat olemassa vain kyseisen funktion laajuudessa. Niitä ei tallenneta lohkoketjuun, ja ne hävitetään, kun funktio on suoritettu loppuun.
Funktiot Solidityssa
Funktiot ovat älysopimusten rakennuspalikoita. Ne määrittävät logiikan ja toiminnot, jotka sopimus voi suorittaa. Funktiot voivat:
- Muokata sopimuksen tilaa.
- Lukea tietoja sopimuksen tilasta.
- Olla vuorovaikutuksessa muiden sopimusten kanssa.
- Lähettää tai vastaanottaa Etheriä.
Funktion näkyvyys
Solidity-funktioilla on neljä näkyvyyden muokkaajaa:
- public: Voidaan kutsua sisäisesti ja ulkoisesti.
- private: Voidaan kutsua vain sisäisesti sopimuksen sisältä.
- internal: Voidaan kutsua sisäisesti sopimuksen sisältä ja johdetuista sopimuksista.
- external: Voidaan kutsua vain ulkoisesti.
Funktion muokkaajat
Funktion muokkaajia käytetään funktion toiminnan muuttamiseen. Niitä käytetään usein turvallisuusrajoitusten noudattamiseen tai tarkistusten suorittamiseen ennen funktion logiikan suorittamista.
Esimerkki:
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;
}
}
Tässä esimerkissä onlyOwner
-muokkaaja tarkistaa, onko soittaja sopimuksen omistaja. Jos ei, se palauttaa tapahtuman. Paikkamerkki _
edustaa funktion koodin loppua.
Funktion tilan muuttuvuus
Solidity-funktioilla voi myös olla tilan muuttuvuusmuokkaajia:
- view: Osoittaa, että funktio ei muokkaa sopimuksen tilaa. Se voi lukea tilamuuttujia, mutta ei voi kirjoittaa niihin.
- pure: Osoittaa, että funktio ei lue tai muokkaa sopimuksen tilaa. Se on täysin itsenäinen ja deterministinen.
- payable: Osoittaa, että funktio voi vastaanottaa Etheriä.
Esimerkki:
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;
}
}
Ohjausrakenteet
Solidity tukee tavallisia ohjausrakenteita, kuten if
, else
, for
, while
ja do-while
-silmukoita.
Esimerkki:
pragma solidity ^0.8.0;
contract ControlStructures {
function checkValue(uint256 x) public pure returns (string memory) {
if (x > 10) {
return "Value is greater than 10";
} else if (x < 10) {
return "Value is less than 10";
} else {
return "Value is equal to 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;
}
}
Tapahtumat ja lokit
Tapahtumat mahdollistavat älysopimusten kommunikoinnin ulkomaailman kanssa. Kun tapahtuma lähetetään, se tallennetaan lohkoketjun tapahtumalokeihin. Ulkoiset sovellukset voivat valvoa näitä lokeja sopimuksen toiminnan seuraamiseksi.
Esimerkki:
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);
}
}
Tässä esimerkissä ValueChanged
-tapahtuma lähetetään aina, kun setValue
-funktiota kutsutaan. Avainsana indexed
caller
-parametrissa mahdollistaa ulkoisten sovellusten suodattaa tapahtumia soittajan osoitteen perusteella.
Periytyminen
Solidity tukee periytymistä, jonka avulla voit luoda uusia sopimuksia olemassa olevien perusteella. Tämä edistää koodin uudelleenkäyttöä ja modulaarisuutta.
Esimerkki:
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++;
}
}
Tässä esimerkissä DerivedContract
perii BaseContract
-sopimuksen. Se perii value
-tilamuuttujan ja setValue
-funktion. Se määrittää myös oman funktion, incrementValue
.
Kirjastot
Kirjastot ovat samanlaisia kuin sopimukset, mutta ne eivät voi tallentaa tietoja. Niitä käytetään uudelleenkäytettävän koodin käyttöönottoon, jota useat sopimukset voivat kutsua. Kirjastot otetaan käyttöön vain kerran, mikä vähentää kaasun kustannuksia.
Esimerkki:
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);
}
}
Tässä esimerkissä Math
-kirjasto määrittää add
-funktion. Lause using Math for uint256;
antaa sinun kutsua add
-funktiota uint256
-muuttujissa käyttämällä pistenotaatiota.
Yleiset älysopimusten haavoittuvuudet
Älysopimukset ovat alttiita erilaisille haavoittuvuuksille, jotka voivat johtaa varojen menetykseen tai odottamattomaan käyttäytymiseen. On erittäin tärkeää olla tietoinen näistä haavoittuvuuksista ja ryhtyä toimiin niiden lieventämiseksi.
Uudelleenkutsu
Uudelleenkutsu tapahtuu, kun sopimus kutsuu ulkoista sopimusta ja ulkoinen sopimus kutsuu takaisin alkuperäiseen sopimukseen ennen kuin alkuperäisen sopimuksen suoritus on valmis. Tämä voi johtaa odottamattomiin tilanmuutoksiin.
Lievitys: Käytä Checks-Effects-Interactions -mallia ja harkitse transfer
- tai send
-funktioiden käyttöä ulkoisen puhelun käytettävissä olevan kaasun rajoittamiseksi.
Ylivuoto ja alivuoto
Ylivuoto tapahtuu, kun aritmeettinen operaatio ylittää tietotyypin enimmäisarvon. Alivuoto tapahtuu, kun aritmeettinen operaatio johtaa arvoon, joka on pienempi kuin tietotyypin vähimmäisarvo.
Lievitys: Käytä SafeMath-kirjastoja (vaikka Solidity 0.8.0 ja uudemmissa versioissa ylivuoto- ja alivuototarkistukset on sisäänrakennettu oletusarvoisesti) näiden ongelmien estämiseksi.
Aikaleiman riippuvuus
Lohkon aikaleiman (block.timestamp
) luottaminen voi tehdä sopimuksestasi alttiin louhijoiden manipuloinnille, koska heillä on jonkin verran hallintaa aikaleimaan.
Lievitys: Vältä block.timestamp
-arvon käyttöä kriittisessä logiikassa. Harkitse oraakkelien tai muiden luotettavampien aikojen lähteiden käyttöä.
Palvelunestohyökkäys (DoS)
DoS-hyökkäyksillä pyritään tekemään sopimuksesta käyttökelvoton laillisille käyttäjille. Tämä voidaan saavuttaa kuluttamalla kaikki käytettävissä oleva kaasu tai hyödyntämällä haavoittuvuuksia, jotka saavat sopimuksen palautumaan.
Lievitys: Ota käyttöön kaasurajat, vältä silmukoita, joissa on rajoittamattomat iteraatiot, ja validoi käyttäjän syötteet huolellisesti.
Front Running
Front running tapahtuu, kun joku tarkkailee odottavaa tapahtumaa ja lähettää oman tapahtumansa korkeammalla kaasun hinnalla, jotta se suoritettaisiin ennen alkuperäistä tapahtumaa.
Lievitys: Käytä sitoutumis-paljastusjärjestelmiä tai muita tekniikoita piilottaaksesi tapahtuman tiedot vasta sen jälkeen, kun ne on suoritettu.
Parhaat käytännöt turvallisten älysopimusten kirjoittamiseen
- Pidä se yksinkertaisena: Kirjoita ytimekästä ja helposti ymmärrettävää koodia.
- Noudata Checks-Effects-Interactions -mallia: Varmista, että tarkistukset suoritetaan ennen kuin tilan muutoksia tehdään, ja että vuorovaikutus muiden sopimusten kanssa tehdään viimeisenä.
- Käytä suojaustyökaluja: Käytä staattisia analyysityökaluja, kuten Slither ja Mythril, mahdollisten haavoittuvuuksien tunnistamiseen.
- Kirjoita yksikkötestejä: Testaa älysopimuksesi perusteellisesti varmistaaksesi, että ne toimivat odotetulla tavalla.
- Hanki auditoitu: Pyydä hyvämaineisia turvallisuusalan yrityksiä auditoimaan älysopimuksesi ennen niiden käyttöönottoa pääverkkoon.
- Pysy ajan tasalla: Pysy ajan tasalla Solidity-yhteisön uusimmista suojaushaavoittuvuuksista ja parhaista käytännöistä.
Edistyneet Solidity-käsitteet
Kun sinulla on vankka käsitys perusteista, voit tutkia edistyneempiä käsitteitä:
Assembly
Solidity antaa sinun kirjoittaa sisäistä assembly-koodia, mikä antaa sinulle enemmän hallintaa EVM:ään. Se lisää kuitenkin myös virheiden ja haavoittuvuuksien aiheuttamisen riskiä.
Proxyt
Proxyjen avulla voit päivittää älysopimuksiasi ilman tietojen siirtämistä. Tähän sisältyy proxy-sopimuksen käyttöönotto, joka välittää puhelut toteutussopimukseen. Kun haluat päivittää sopimuksen, otat yksinkertaisesti käyttöön uuden toteutussopimuksen ja päivität proxyn osoittamaan uuteen toteutukseen.
Meta-tapahtumat
Meta-tapahtumien avulla käyttäjät voivat olla vuorovaikutuksessa älysopimuksesi kanssa maksamatta kaasumaksuja suoraan. Sen sijaan välittäjä maksaa kaasumaksut heidän puolestaan. Tämä voi parantaa käyttökokemusta, erityisesti käyttäjille, jotka ovat uusia lohkoketjussa.
EIP-721 ja EIP-1155 (NFT:t)
Soliditya käytetään yleisesti Non-Fungible Tokenien (NFT) luomiseen käyttämällä standardeja, kuten EIP-721 ja EIP-1155. Näiden standardien ymmärtäminen on ratkaisevan tärkeää NFT-pohjaisten sovellusten rakentamisessa.
Solidity ja lohkoketjun tulevaisuus
Soliditylla on kriittinen rooli lohkoketjuteknologian nopeasti kehittyvässä maisemassa. Kun lohkoketjun käyttöönotto kasvaa edelleen, Solidity-kehittäjillä on suuri kysyntä innovatiivisten ja turvallisten hajautettujen sovellusten rakentamisessa. Kieltä päivitetään ja parannetaan jatkuvasti, joten pysyminen ajan tasalla viimeisimmistä kehityksestä on välttämätöntä menestyksen saavuttamiseksi tällä alalla.
Johtopäätös
Solidity on tehokas ja monipuolinen kieli älysopimusten rakentamiseen Ethereum-lohkoketjuun. Tämä opas on tarjonnut kattavan yleiskatsauksen Solidityyn peruskäsitteistä edistyneisiin tekniikoihin. Hallitsemalla Solidityn ja noudattamalla turvallisen kehityksen parhaita käytäntöjä voit osallistua hajautettujen sovellusten jännittävään maailmaan ja auttaa muokkaamaan lohkoketjuteknologian tulevaisuutta. Muista aina asettaa turvallisuus etusijalle, testata koodisi perusteellisesti ja pysyä ajan tasalla Solidity-ekosysteemin viimeisimmistä kehityksestä. Älysopimusten potentiaali on valtava, ja Solidityn avulla voit toteuttaa innovatiiviset ideasi.