Stabilitātes paraugprakse viedo līgumu drošībai

emuārs 1NewsDevelopersEnterpriseBlockchain ExplainedEvents and ConferencesPressBiļeteni

Contents

Abonējiet mūsu biļetenu.

Epasta adrese

Mēs cienām jūsu privātumu

HomeBlogBlockchain izstrāde

Stabilitātes paraugprakse viedo līgumu drošībai

Sākot ar uzraudzību līdz laika zīmoga apsvērumiem, šeit ir daži padomi, lai nodrošinātu, ka jūsu Ethereum viedie līgumi tiek stiprināti. Iesniedzis ConsenSys 2020. gada 21. augusts Ievietots 2020. gada 21. augustā

labas prakses varonis

Ar ConsenSys rūpību, mūsu bloku ķēdes drošības ekspertu komandu.

Ja esat pieņēmis viedo līgumu drošības domāšanu pie sirds un saņemat risinājumu EVM īpatnībām, ir pienācis laiks apsvērt dažus drošības modeļus, kas raksturīgi Solidity programmēšanas valodai. Šajā apkopojumā mēs koncentrēsimies uz drošas attīstības ieteikumiem, kas var būt noderīgi arī viedo līgumu izstrādei citās valodās.. 

Labi, iesim iekšā.

Pareizi izmantojiet assert (), pieprasiet (), revert ()

Ērtības funkcijas apgalvot un pieprasīt var izmantot, lai pārbaudītu apstākļus un izmestu izņēmumu, ja nosacījums nav izpildīts.

The apgalvot Funkcija jāizmanto tikai iekšējo kļūdu pārbaudei un invariantu pārbaudei.

The pieprasīt Funkcija jāizmanto, lai nodrošinātu derīgus nosacījumus, piemēram, ievadi vai līguma stāvokļa mainīgos, vai lai apstiprinātu atgriešanās vērtības no zvaniem uz ārējiem līgumiem. 

Šīs paradigmas ievērošana ļauj oficiāliem analīzes rīkiem pārbaudīt, vai nederīgo opkodu nekad nevar sasniegt: tas nozīmē, ka kodā netiek pārkāpti invarianti un ka kods ir oficiāli pārbaudīts.

pragmas cietība ^ 0,5,0; līgums Dalītājs {funkcija sendHalf (adrese maksājama adrese) valsts apmaksājamā peļņa (uint atlikums) {pieprasīt (msg.value% 2 == 0, "Nepieciešama pat vērtība."); // Require () var būt izvēles ziņojuma virkne uint balanceBeforeTransfer = adrese (šī) .balance; [bool panākumi,] = addr.call.value (msg.value / 2) (""); pieprasīt (panākumus); // Tā kā mēs atgriezāmies, ja pārskaitījums neizdevās, nevajadzētu būt // nekādam, lai mums joprojām būtu puse naudas. apgalvot (adrese (šī). bilance == balanceBeforeTransfer – msg.value / 2); // izmantots iekšējai kļūdu pārbaudei atgriešanās adrese (šī) .balance; }} Koda valoda: JavaScript (javascript)

Skat SWC-110 & SWC-123

Modifikatorus izmantojiet tikai pārbaudēm

Kods modifikatorā parasti tiek izpildīts pirms funkcijas pamatteksta, tāpēc jebkuras stāvokļa izmaiņas vai ārējie zvani pārkāpj Pārbaudes-Ietekme-Mijiedarbība modeli. Turklāt šos apgalvojumus izstrādātājs var arī nepamanīt, jo modifikatora kods var būt tālu no funkciju deklarācijas. Piemēram, ārējs zvans modifikatorā var izraisīt atkārtotas iekļūšanas uzbrukumu:

līguma reģistrs {adreses īpašnieks; funkcija isVoter (adrese _addr) ārējā atgriešanās (bool) {// Code}} līgums Vēlēšanas {Reģistra reģistrs; modifikators isEligible (adrese _addr) {pieprasīt (register.isVoter (_addr)); _; } funkcija balss () isEligible (msg.sender) public {// Code}} Koda valoda: JavaScript (javascript)

Šajā gadījumā reģistra līgums var veikt atkārtotu uzbrukumu, izsaucot vietni isVoter () Election.vote ().

Piezīme: Izmantot modifikatori lai aizstātu vairāku funkciju, piemēram, isOwner (), nosacījumu pārbaudes dublikātus, citādi izmantojiet funkciju vai atgriezieties funkcijas iekšpusē. Tas padara jūsu viedā līguma kodu vieglāk lasāmu un vieglāk revidējamu.

Sargieties noapaļot ar veselu skaitļu dalījumu

Visi skaitļu dalījumi noapaļo uz leju līdz tuvākajam skaitlim. Ja jums nepieciešama lielāka precizitāte, apsveriet iespēju izmantot reizinātāju vai saglabājiet gan skaitītāju, gan saucēju.

(Nākotnē Solidity būs fiksēts punkts (kas to atvieglos.)

// slikts laiks x = 5/2; // Rezultāts ir 2, visi vesels skaitlis dalās uz leju līdz tuvākajam skaitlim Koda valoda: JavaScript (javascript)

Reizinātāja izmantošana novērš noapaļošanu uz leju, šis reizinātājs jāņem vērā, strādājot ar x nākotnē:

// labs uint reizinātājs = 10; uint x = (5 * reizinātājs) / 2; Koda valoda: JavaScript (javascript)

Skaitītāja un saucēja glabāšana nozīmē, ka varat aprēķināt skaitītāja / saucēja ārpus ķēdes rezultātu:

// labs uint skaitītājs = 5; uint saucējs = 2; Koda valoda: JavaScript (javascript)

Jāapzinās kompromisi starp abstrakti līgumi un saskarnes

Gan saskarnes, gan abstrakti līgumi nodrošina pielāgojamu un atkārtoti lietojamu pieeju viedajiem līgumiem. Saskarnes, kas tika ieviestas ar Solidity 0.4.11, ir līdzīgas abstraktiem līgumiem, taču tām nevar būt nevienas funkcijas. Saskarnēm ir arī ierobežojumi, piemēram, nespēja piekļūt krātuvei vai mantošana no citām saskarnēm, kas abstraktos līgumus parasti padara praktiskākus. Lai gan saskarnes noteikti ir noderīgas, izstrādājot līgumus pirms ieviešanas. Turklāt ir svarīgi paturēt prātā, ka, ja līgums tiek mantots no abstrakta līguma, tam ir jāievieš visas neīstenotās funkcijas, prioritāri vai arī tas būs arī abstrakts.

Rezerves funkcijas

Saglabājiet rezerves funkcijas vienkāršas

Rezerves funkcijas tiek izsaukti, kad līgumam tiek nosūtīts ziņojums bez argumentiem (vai ja neviena funkcija neatbilst), un piekļuve 2300 gāzēm ir pieejama tikai tad, kad tiek izsaukti no .send () vai .transfer (). Ja vēlaties saņemt ēterus no .send () vai .transfer (), atkāpšanās funkcijā visvairāk varat reģistrēt notikumu. Izmantojiet pareizu funkciju, ja ir nepieciešams aprēķināt vairāk gāzes.

// slikta funkcija () maksājamā {atlikumi [msg.sender] + = msg.value; } // labas funkcijas depozīts () maksājamais ārējais {atlikumi [msg.sender] + = msg.value; } funkcija () maksājama {pieprasīt (msg.data.length == 0); emitēt LogDepositReceived (ziņ. sūtītājs); } Koda valoda: JavaScript (javascript)

Pārbaudiet datu garumu rezerves funkcijās

Kopš rezerves funkcijas tiek pieprasīta ne tikai vienkārša ētera pārsūtīšana (bez datiem), bet arī tad, ja neatbilst neviena cita funkcija, jums jāpārbauda, ​​vai dati ir tukši, ja rezerves funkciju paredzēts izmantot tikai saņemto ēteru reģistrēšanai. Pretējā gadījumā zvanītāji nemanīs, ja jūsu līgums tiek izmantots nepareizi un tiek izsauktas funkcijas, kas nepastāv.

// slikta funkcija () maksājama {emit LogDepositReceived (msg.sender); } // laba funkcija () maksājama {pieprasīt (msg.data.length == 0); emitēt LogDepositReceived (ziņ. sūtītājs); } Koda valoda: JavaScript (javascript)

Skaidri iezīmējiet maksājamās funkcijas un mainīgos

Sākot no Solidity 0.4.0, katrai funkcijai, kas saņem ēteri, ir jāizmanto maksājamais modifikators, pretējā gadījumā, ja darījumam ir msg.value > 0 atgriezīsies (izņemot piespiedu kārtā).

Piezīme: Kaut kas, iespējams, nav acīmredzams: maksājamais modifikators attiecas tikai uz zvaniem no ārējiem līgumiem. Ja es tajā pašā līgumā izsaucu nemaksājamo funkciju apmaksājamajā funkcijā, nemaksājamā funkcija neizdosies, kaut arī joprojām.

Skaidri atzīmējiet redzamību funkcijās un stāvokļa mainīgajos

Skaidri iezīmējiet funkciju un stāvokļa mainīgo redzamību. Funkcijas var norādīt kā ārējas, publiskas, iekšējas vai privātas. Lūdzu, izprotiet atšķirības starp tām, piemēram, publiskā vietā var pietikt ar ārēju. Stāvokļa mainīgajiem ārējs nav iespējams. Redzamības nepārprotama iezīmēšana atvieglos nepareizu pieņēmumu uztveršanu par to, kurš var izsaukt funkciju vai piekļūt mainīgajam.

  • Ārējās funkcijas ir daļa no līguma saskarnes. Ārēju funkciju f nevar izsaukt iekšēji (t.i., f () nedarbojas, bet tas.f () darbojas). Ārējās funkcijas dažreiz ir efektīvākas, ja tās saņem lielu datu masīvu.
  • Publiskās funkcijas ir daļa no līguma saskarnes, un tās var izsaukt vai nu iekšēji, vai arī izmantojot ziņojumus. Valsts stāvokļa mainīgajiem lielumiem tiek ģenerēta automātiska labošanas funkcija (skat. Zemāk).
  • Iekšējām funkcijām un stāvokļa mainīgajiem var piekļūt tikai iekšēji, to neizmantojot.
  • Privātās funkcijas un stāvokļa mainīgie ir redzami tikai līgumam, kurā tie ir definēti, nevis atvasinātajos līgumos. Piezīme: Viss, kas atrodas līgumā, ir redzams visiem novērotājiem ārpus blokķēdes, pat privātiem mainīgajiem.

// slikts uint x; // noklusējums ir iekšējs stāvokļa mainīgajiem, taču tam ir jāpadara skaidra funkcija buy () {// noklusējums ir public // public code} // good uint private y; function buy () external {// tikai ārēji izsaucams vai izmantojot this.buy ()} funkciju utilītu () public {// izsaucams ārēji, kā arī iekšēji: šī koda maiņa prasa domāt par abiem gadījumiem. } function internalAction () internal {// internal code} Koda valoda: PHP (php)

Skat SWC-100 un SWC-108

Bloķēt pragmas uz konkrētu kompilatora versiju

Līgumi jāizvieto ar to pašu kompilatora versiju un karodziņiem, ar kuriem tie ir pārbaudīti visvairāk. Pragmas bloķēšana palīdz nodrošināt, ka līgumi nejauši netiek izvietoti, izmantojot, piemēram, jaunāko kompilatoru, kuram var būt lielāks neatklātu kļūdu risks. Līgumus var izvietot arī citi, un pragma norāda oriģinālo autoru paredzēto kompilatora versiju.

// slikta pragmas stingrība ^ 0,4.4; // laba pragmas drošība 0.4.4; Koda valoda: JavaScript (javascript)

Piezīme: peldoša pragmas versija (ti. ^ 0.4.25) kompilēs ar 0.4.26-nightly.2018.9.25, taču nakts versijas nekad nevajadzētu izmantot ražošanas koda sastādīšanai..

Brīdinājums: Pragmas paziņojumiem var ļaut peldēt, ja līgums ir paredzēts citu izstrādātāju patēriņam, kā tas ir gadījumā ar līgumiem bibliotēkā vai EthPM paketē. Pretējā gadījumā izstrādātājam būtu manuāli jāatjaunina pragma, lai kompilētu lokāli.

Skat SWC-103

Izmantojiet notikumus, lai uzraudzītu līguma darbību

Var būt noderīgi, ja ir veids, kā uzraudzīt līguma darbību pēc tā ieviešanas. Viens no veidiem, kā to paveikt, ir apskatīt visus līguma darījumus, tomēr tas var būt nepietiekams, jo ziņojumu zvani starp līgumiem netiek ierakstīti blokķēdē. Turklāt tas parāda tikai ievades parametrus, nevis faktiskās izmaiņas, kas tiek veiktas stāvoklī. Arī notikumus var izmantot, lai aktivizētu funkcijas lietotāja saskarnē.

līgums Labdarība {kartēšana (adrese => uint) atlikumi; funkcija donate () maksājamā publiskā {atlikumi [msg.sender] + = msg.value; }} līgums Spēle {funkcija buyCoins () maksājamais publiskais {// 5% tiek novirzīts labdarības labdarībai.donate.value (msg.value / 20) (); }} Koda valoda: JavaScript (javascript)

Šeit spēles līgums veiks iekšēju zvanu uz Charity.donate (). Šis darījums netiks rādīts labdarības ārējo darījumu sarakstā, bet būs redzams tikai iekšējos darījumos.

Pasākums ir ērts veids, kā reģistrēt kaut ko, kas noticis līgumā. Emitētie notikumi paliek blokķēdē kopā ar citiem līguma datiem, un tie ir pieejami turpmākai revīzijai. Šeit ir uzlabojums iepriekš minētajā piemērā, izmantojot pasākumus, lai sniegtu Labdarības ziedojumu vēsturi.

līgums Labdarība {// definē notikuma notikumu LogDonate (uint _amount); kartēšana (adrese => uint) atlikumi; funkcija donate () maksājamā publiskā {atlikumi [msg.sender] + = msg.value; // emit event emit LogDonate (msg.value); }} līgums Spēle {funkcija buyCoins () maksājamais publiskais {// 5% tiek novirzīts labdarības labdarībai.donate.value (msg.value / 20) (); }} Koda valoda: JavaScript (javascript)

Šeit visi darījumi, kas tiek noslēgti ar Labdarības līgumu, tieši vai nē, tiks parādīti šī līguma notikumu sarakstā kopā ar saziedotās naudas summu.

Piezīme. Dodiet priekšroku jaunākiem Solidity konstrukcijām. Dodiet priekšroku tādām konstrukcijām / aizstājvārdiem kā pašiznīcināšanās (nevis pašnāvība) un keccak256 (virs sha3). Šādus modeļus, piemēram, pieprasīt (msg.sender.send (1 ēteris)), var arī vienkāršot, izmantojot pārsūtīšanu (), tāpat kā msg.sender.transfer (1 ēteris). Pārbaudiet Solidity Change žurnāls līdzīgākām izmaiņām.

Ņemiet vērā, ka ‘iebūvētie’ var būt ēnoti

Pašlaik ir iespējams ēna iebūvētie globālie elementi Solidity. Tas ļauj līgumiem ignorēt iebūvēto funkciju, piemēram, msg un revert (), funkcionalitāti. Lai gan tas ir paredzēts, tas var maldināt līguma lietotājus par līguma patieso uzvedību.

līgums PretendingToRevert {funkcija revert () iekšējā konstante {}} līguma piemērsContract ir PretendingToRevert {funkcija somethingBad () public {revert (); }}

Līguma lietotājiem (un auditoriem) būtu jāzina pilns viedo līgumu pirmkods visām lietojumprogrammām, kuras viņi plāno izmantot.

Izvairieties no tx.origin lietošanas

Nekad neizmantojiet tx.origin autorizācijai, citam līgumam var būt metode, kas izsauks jūsu līgumu (kur, piemēram, lietotājam ir daži līdzekļi), un jūsu līgums atļaus šo darījumu, jo jūsu adrese ir tx.origin.

līgums MyContract {adreses īpašnieks; funkcija MyContract () public {īpašnieks = msg.sender; } funkcija sendTo (adreses uztvērējs, uint summa) public {pieprasīt (tx.origin == īpašnieks); [Bool panākumi,] = uztvērējs. zvana vērtība (summa) {""); pieprasīt (panākumus); }} līgums AttackingContract {MyContract myContract; adreses uzbrucējs; funkcija AttackingContract (adrese myContractAddress) public {myContract = MyContract (myContractAddress); uzbrucējs = ziņojuma sūtītājs; } function () public {myContract.sendTo (uzbrucējs, msg.sender.balance); }} Koda valoda: JavaScript (javascript)

Lai autorizētos, jums jāizmanto msg.sender (ja jūsu līgums tiek izsaukts citā līgumā, msg.sender būs līguma adrese, nevis tā lietotāja adrese, kurš zvanīja uz līgumu).

Vairāk par to varat izlasīt šeit: Cietības dokumenti

Brīdinājums: Papildus autorizācijas problēmai pastāv iespēja, ka tx.origin nākotnē tiks noņemta no Ethereum protokola, tāpēc kods, kas izmanto tx.origin, nebūs saderīgs ar nākamajiem izlaidumiem Vitāliks: “NEGAIMĒT, ka tx.origin arī turpmāk būs lietojams vai nozīmīgs.”

Ir arī vērts pieminēt, ka, izmantojot tx.origin, jūs ierobežojat savstarpēju izmantojamību starp līgumiem, jo ​​līgumu, kas izmanto tx.origin, nevar izmantot cits līgums, jo līgums nevar būt tx.origin.

Skat SWC-115

Laika zīmoga atkarība

Lietojot laika zīmogu, lai izpildītu kritisko funkciju līgumā, ir trīs galvenie apsvērumi, īpaši, ja darbības ir saistītas ar naudas pārskaitījumu.

Laika zīmoga manipulācijas

Jāapzinās, ka bloka laika zīmogu var manipulēt kalnračnieks. Apsveriet to līgumu:

uint256 konstanta privātā sāls = block.timestamp; funkcija nejauša (uint Max) nemainīga privātā atdeve (uint256 rezultāts) {// iegūst vislabāko sēklas nejaušību uint256 x = sāls * 100 / Maks; uint256 y = sāls * bloks. skaits / (sāls% 5); uint256 sēkla = bloķēt.numurs / 3 + (sāls% 300) + Last_Payout + y; uint256 h = uint256 (block.blockhash (sēkla)); atgriešanās uint256 ((h / x))% Max + 1; // nejaušs skaitlis starp 1 un Maks.} Koda valoda: PHP (php)

Kad līgumā tiek izmantots laika zīmogs nejauša skaitļa iegūšanai, kalnrači faktiski var ievietot laika zīmogu 15 sekunžu laikā pēc bloka apstiprināšanas, ļaujot kalnračam iepriekš aprēķināt iespēju, kas ir labvēlīgāka viņu izredzēm loterijā. Laika zīmogi nav nejauši, un tos nevajadzētu izmantot šajā kontekstā.

15 sekunžu likums

The Dzeltenā grāmata (Ethereum atsauces specifikācijā) nav norādīts ierobežojums, cik daudz bloku var novirzīties laikā, bet tajā ir norādīts ka katram laika zīmogam jābūt lielākam par tā vecāka laika zīmogu. Tautas Ethereum protokola ieviešana Gets un Paritāte abi noraida blokus ar laika zīmogu ilgāk par 15 sekundēm nākotnē. Tādēļ labs īkšķis, novērtējot laika zīmoga lietošanu, ir šāds: ja jūsu laika atkarīgā notikuma mērogs var mainīties par 15 sekundēm un saglabāt integritāti, ir droši izmantot block.timestamp.

Neizmantojiet block.number kā laika zīmogu

Ir iespējams novērtēt laika deltu, izmantojot rekvizītu block.number un vidējais bloķēšanas laiks, tomēr tas nav nākotnes pierādījums, jo var mainīties bloķēšanas laiki (piemēram, dakšu reorganizācija un grūtības bumba). Pārdošanā, kas ilgst dienas, 15 sekunžu noteikums ļauj sasniegt ticamāku laika aprēķinu.

Skat SWC-116

Vairāku mantojuma piesardzība

Izmantojot Solidity vairākkārtēju mantojumu, ir svarīgi saprast, kā sastādītājs sastāda mantojuma grafiku.

līgums Galīgais {uint public a; funkcija Gala (uint f) public {a = f; }} līgums B ir Galīgā {int valsts nodeva; funkcija B (uint f) Galīgā (f) public {} funkcija setFee () public {maksa = 3; }} līgums C ir Galīgais {int public fee; funkcija C (uint f) Galīgā (f) public {} funkcija setFee () public {maksa = 5; }} līgums A ir B, C {funkcija A () public B (3) C (5) {setFee (); }} Kodu valoda: PHP (php)

Izvietojot līgumu, sastādītājs mantojumu no labās uz kreiso linearizēs (pēc atslēgvārda vecāki ir uzskaitīti no līdzīgākajiem līdz atvasinātajiem). Lūk, A līguma linearizācija:

Fināls <- B <- C <- A

Linearizācijas rezultātā nodevas vērtība būs 5, jo C ir visvairāk atvasinātais līgums. Tas var šķist acīmredzams, taču iedomājieties scenārijus, kur C var ēnot būtiskas funkcijas, pārkārtot būla klauzulas un likt izstrādātājam rakstīt izmantojamus līgumus. Statiskā analīze pašlaik nerada problēmas ar aizēnotām funkcijām, tāpēc tā ir jāpārbauda manuāli.

Lai palīdzētu sniegt ieguldījumu, Solidity’s Github ir: projektu ar visiem ar mantojumu saistītiem jautājumiem.

Skat SWC-125

Tipa drošībai adreses vietā izmantojiet saskarnes tipu

Kad funkcija kā argumentu uzskata līguma adresi, labāk ir nodot saskarni vai līguma veidu, nevis neapstrādātu adresi. Ja funkcija tiek izsaukta citur pirmkodā, kompilators tā nodrošinās papildu tipa drošības garantijas.

Šeit mēs redzam divas alternatīvas:

līgums Validator {funkcija validēt (uint) ārējās atgriešanās (bool); } contract TypeSafeAuction {// laba funkcija validateBet (Validator _validator, uint _value) iekšējā atgriešanās (bool) {bool valid = _validator.validate (_value); atgriešanās derīga; }} contract TypeUnsafeAuction {// slikta funkcija validateBet (adrese _addr, uint _value) iekšējā atgriešanās (bool) {Validator validator = Validator (_addr); bool valid = validator.validate (_value); atgriešanās derīga; }} Koda valoda: JavaScript (javascript)

Iepriekš minētā TypeSafeAuction līguma izmantošanas priekšrocības var redzēt no šī piemēra. Ja validateBet () tiek izsaukts ar adreses argumentu vai cita veida līgumu, nevis Validator, kompilators izmetīs šo kļūdu:

līguma NonValidator {} līguma izsole ir TypeSafeAuction {NonValidator nonValidator; function bet (uint _value) {bool valid = validateBet (nonValidator, _value); // TypeError: nederīgs argumenta tips funkcijas izsaukumā. // Nepieciešama netieša netieša pārveidošana no līguma NonValidator // par pieprasītu līguma Validator }} Koda valoda: JavaScript (javascript)

Lai pārbaudītu, vai ārēji piederošie konti, neizmantojiet ekstodizāciju

Lai pārbaudītu, vai zvans tika veikts no ārēji piederoša konta (EOA) vai līguma konta, bieži izmanto šādu modifikatoru (vai līdzīgu pārbaudi):

// slikts modifikators isNotContract (adrese _a) {uint size; montāža {size: = extcodesize (_a)} pieprasīt (izmērs == 0); _; } Koda valoda: JavaScript (javascript)

Ideja ir tieša: ja adresē ir kods, tas nav EOA, bet gan līguma konts. Tomēr, līgumam būvniecības laikā nav pieejams avota kods. Tas nozīmē, ka, kamēr konstruktors darbojas, tas var veikt zvanus uz citiem līgumiem, bet tā adreses ekskodēšana atgriež nulli. Zemāk ir minimāls piemērs, kas parāda, kā šo pārbaudi var apiet:

tikai līgumsFOREOA {uint public flag; // slikts modifikators isNotContract (adrese _a) {uint len; montāža {len: = extcodesize (_a)} pieprasīt (len == 0); _; } function setFlag (uint i) public isNotContract (msg.sender) {karogs = i; }} līgums FakeEOA {konstruktors (adrese _a) public {OnlyForEOA c = OnlyForEOA (_a); c.setFlag (1); }} Koda valoda: JavaScript (javascript)

Tā kā līguma adreses var iepriekš aprēķināt, šī pārbaude var arī neizdoties, ja tā pārbauda adresi, kas n blokā ir tukša, bet kurai ir izvietots līgums kādā blokā, kas ir lielāks par n.

Brīdinājums: Šis jautājums ir niansēts. Ja jūsu mērķis ir novērst to, ka citi līgumi var piezvanīt uz jūsu līgumu, iespējams, pietiek ar extcodesize pārbaudi. Alternatīva pieeja ir pārbaudīt (tx.origin == msg.sender) vērtību, lai arī tas ir trūkumi.

Var būt arī citas situācijas, kurās ekstodēšanas pārbaude kalpo jūsu mērķim. To visu aprakstīšana šeit ir ārpus darbības jomas. Izprotiet EVM pamatā esošo uzvedību un izmantojiet savu lēmumu.

Vai jūsu Blockchain kods ir drošs?

Rezervējiet vienas dienas pārbaudi uz vietas pie mūsu drošības ekspertiem. Book Yours Today DiligenceSecuritySmart ContractsSolidityNewsletterRakstieties uz mūsu biļetenu, lai iegūtu jaunākās Ethereum ziņas, uzņēmuma risinājumus, izstrādātāju resursus un daudz ko citu. E-pasta adreseEkskluzīvs satursKā izveidot veiksmīgu Blockchain produktuTīmekļa seminārs

Kā izveidot veiksmīgu Blockchain produktu

Kā izveidot un palaist Ethereum mezgluTīmekļa seminārs

Kā izveidot un palaist Ethereum mezglu

Kā izveidot savu Ethereum APITīmekļa seminārs

Kā izveidot savu Ethereum API

Kā izveidot sociālo marķieriTīmekļa seminārs

Kā izveidot sociālo marķieri

Drošības rīku izmantošana viedo līgumu izstrādēTīmekļa seminārs

Drošības rīku izmantošana viedo līgumu izstrādē

Finanšu digitālo aktīvu un DeFi nākotneTīmekļa seminārs

Finanšu nākotne: digitālie aktīvi un DeFi

Mike Owergreen Administrator
Sorry! The Author has not filled his profile.
follow me