Ruka kwenda kwenye maudhui makuu

Kupunguza ukubwa wa mikataba ili kupambana na kikomo cha ukubwa wa mkataba

Solidity
mikataba erevu
ghala
Wastani
Markus Waas
26 Juni 2020
6 soma ndani ya dakika

Kwa nini kuna kikomo?

Mnamo Novemba 22, 2016 (opens in a new tab) uma mgumu wa Spurious Dragon ulianzisha EIP-170 (opens in a new tab) ambao uliongeza kikomo cha ukubwa wa mkataba-erevu cha kb 24.576. Kwa wewe kama msanidi programu wa Solidity hii inamaanisha unapoongeza utendaji zaidi na zaidi kwenye mkataba wako, wakati fulani utafikia kikomo na wakati wa kupeleka utaona hitilafu:

Onyo: Ukubwa wa msimbo wa Mkataba umezidi baiti 24576 (kikomo kilichoanzishwa katika Spurious Dragon). Mkataba huu huenda usiweze kupelekwa kwenye Mtandao Mkuu. Fikiria kuwezesha kiboreshaji (na thamani ndogo ya "runs"!), kuzima jumbe za urejeshaji, au kutumia maktaba.

Kikomo hiki kilianzishwa ili kuzuia mashambulizi ya kunyimwa huduma (DOS). Wito wowote kwa mkataba una gharama nafuu kiasi kwa upande wa gesi. Hata hivyo, athari za wito wa mkataba kwa nodi za Ethereum huongezeka isivyo sawia kulingana na ukubwa wa msimbo wa mkataba unaoitwa (kusoma msimbo kutoka kwenye diski, kuchakata msimbo awali, kuongeza data kwenye uthibitisho wa Merkle). Wakati wowote unapokuwa na hali kama hiyo ambapo mshambuliaji anahitaji rasilimali chache kusababisha kazi nyingi kwa wengine, unapata uwezekano wa mashambulizi ya DOS.

Hapo awali hili halikuwa tatizo kubwa kwa sababu kikomo kimoja cha asili cha ukubwa wa mkataba ni kikomo cha gesi cha bloku. Ni wazi, mkataba lazima upelekwe ndani ya muamala unaoshikilia msimbo baiti wote wa mkataba. Ikiwa utajumuisha muamala huo mmoja tu kwenye bloku, unaweza kutumia gesi yote hiyo, lakini si isiyo na kikomo. Tangu Sasisho la London, kikomo cha gesi cha bloku kimeweza kubadilika kati ya vitengo milioni 15 na milioni 30 kulingana na mahitaji ya mtandao.

Katika yafuatayo tutaangalia baadhi ya mbinu zilizopangwa kulingana na athari zake zinazowezekana. Fikiria kuhusu hilo kwa mtazamo wa kupunguza uzito. Mkakati bora kwa mtu kufikia uzito anaolenga (katika hali yetu 24kb) ni kuzingatia mbinu zenye athari kubwa kwanza. Katika visa vingi kurekebisha lishe yako tu kutakufikisha hapo, lakini wakati mwingine unahitaji zaidi kidogo. Kisha unaweza kuongeza mazoezi (athari ya kati) au hata virutubisho (athari ndogo).

Athari kubwa

Tenganisha mikataba yako

Hii inapaswa kuwa mbinu yako ya kwanza kila wakati. Unawezaje kutenganisha mkataba katika mikataba midogo mingi? Kwa ujumla inakulazimisha kubuni usanifu mzuri kwa mikataba yako. Mikataba midogo inapendekezwa kila wakati kutoka kwa mtazamo wa usomaji wa msimbo. Kwa ajili ya kugawanya mikataba, jiulize:

  • Ni vitendaji vipi vinavyohusiana? Kila seti ya vitendaji inaweza kuwa bora katika mkataba wake.
  • Ni vitendaji vipi ambavyo havihitaji kusoma hali ya mkataba au sehemu ndogo tu ya hali hiyo?
  • Unaweza kutenganisha ghala na utendaji?

Maktaba

Njia moja rahisi ya kuhamisha msimbo wa utendaji mbali na ghala ni kutumia maktaba (opens in a new tab). Usitangaze vitendaji vya maktaba kama vya ndani kwani vitaongezwa moja kwa moja kwenye mkataba (opens in a new tab) wakati wa ukusanyaji. Lakini ukitumia vitendaji vya umma, basi vitakuwa katika mkataba tofauti wa maktaba. Fikiria kutumia kwa (opens in a new tab) ili kufanya matumizi ya maktaba yawe rahisi zaidi.

Proksi

Mkakati wa hali ya juu zaidi ungekuwa mfumo wa proksi. Maktaba hutumia DELEGATECALL kwa nyuma, ambayo hutekeleza kitendaji cha mkataba mwingine kwa kutumia hali ya mkataba unaoita. Angalia chapisho hili la blogu (opens in a new tab) ili kujifunza zaidi kuhusu mifumo ya proksi. Hukupa utendaji zaidi, k.m., huwezesha uwezo wa kusasishwa, lakini pia huongeza utata mwingi. Singeongeza hizo ili tu kupunguza ukubwa wa mkataba isipokuwa ndiyo chaguo lako pekee kwa sababu yoyote ile.

Athari ya kati

Ondoa vitendaji

Hili linapaswa kuwa dhahiri. Vitendaji huongeza ukubwa wa mkataba kwa kiasi kikubwa.

  • Nje: Mara nyingi tunaongeza vitendaji vingi vya kuona kwa sababu za kurahisisha. Hiyo ni sawa kabisa mpaka ufikie kikomo cha ukubwa. Kisha unaweza kutaka kufikiria kweli kuondoa vyote isipokuwa vile vya muhimu kabisa.
  • Ndani: Unaweza pia kuondoa vitendaji vya ndani/binafsi na kuingiza msimbo moja kwa moja mradi tu kitendaji kinaitwa mara moja tu.

Epuka vigezo vya ziada

1function get(uint id) returns (address,address) {
2 MyStruct memory myStruct = myStructs[id];
3 return (myStruct.addr1, myStruct.addr2);
4}
1function get(uint id) returns (address,address) {
2 return (myStructs[id].addr1, myStructs[id].addr2);
3}

Mabadiliko rahisi kama haya hufanya tofauti ya 0.28kb. Kuna uwezekano unaweza kupata hali nyingi sawa katika mikataba yako na hizo zinaweza kujumlisha na kuwa kiasi kikubwa.

Fupisha ujumbe wa hitilafu

Jumbe ndefu za urejeshaji na hasa jumbe nyingi tofauti za urejeshaji zinaweza kufanya mkataba uwe mkubwa. Badala yake tumia misimbo mifupi ya hitilafu na uisimbue katika mkataba wako. Ujumbe mrefu unaweza kuwa mfupi zaidi:

1require(msg.sender == owner, "Ni mmiliki wa mkataba huu pekee anayeweza kuita kitendaji hiki");
1require(msg.sender == owner, "OW1");

Tumia hitilafu maalum badala ya jumbe za hitilafu

Hitilafu maalum zilianzishwa katika Solidity 0.8.4 (opens in a new tab). Ni njia nzuri ya kupunguza ukubwa wa mikataba yako, kwa sababu zimesimbwa kwa ABI kama viteuzi (kama vile vitendaji vilivyo).

1error Unauthorized();
2
3if (msg.sender != owner) {
4 revert Unauthorized();
5}

Fikiria thamani ya chini ya 'run' kwenye kiboreshaji

Unaweza pia kubadilisha mipangilio ya kiboreshaji. Thamani chaguo-msingi ya 200 inamaanisha kwamba inajaribu kuboresha msimbo baiti kana kwamba kitendaji kinaitwa mara 200. Ukiibadilisha kuwa 1, kimsingi unakiambia kiboreshaji kiboreshe kwa ajili ya hali ya kuendesha kila kitendaji mara moja tu. Kitendaji kilichoboreshwa kwa ajili ya kuendeshwa mara moja tu kinamaanisha kimeboreshwa kwa ajili ya upelekaji wenyewe. Fahamu kwamba hii huongeza gharama za gesi za kuendesha vitendaji, kwa hivyo unaweza usitake kufanya hivyo.

Athari ndogo

Epuka kupitisha miundo kwa vitendaji

Ikiwa unatumia ABIEncoderV2 (opens in a new tab), inaweza kusaidia kutopitisha miundo kwa kitendaji. Badala ya kupitisha kigezo kama muundo, pitisha vigezo vinavyohitajika moja kwa moja. Katika mfano huu tumeokoa 0.1kb nyingine.

1function get(uint id) returns (address,address) {
2 return _get(myStruct);
3}
4
5function _get(MyStruct memory myStruct) private view returns(address,address) {
6 return (myStruct.addr1, myStruct.addr2);
7}
1function get(uint id) returns(address,address) {
2 return _get(myStructs[id].addr1, myStructs[id].addr2);
3}
4
5function _get(address addr1, address addr2) private view returns(address,address) {
6 return (addr1, addr2);
7}

Tangaza mwonekano sahihi kwa vitendaji na vigezo

  • Vitendaji au vigezo vinavyoitwa kutoka nje tu? Vitangaze kama external badala ya public.
  • Vitendaji au vigezo vinavyoitwa kutoka ndani ya mkataba tu? Vitangaze kama private au internal badala ya public.

Ondoa virekebishaji

Virekebishaji, hasa vinapotumiwa sana, vinaweza kuwa na athari kubwa kwenye ukubwa wa mkataba. Fikiria kuviondoa na badala yake utumie vitendaji.

1modifier checkStuff() {}
2
3function doSomething() checkStuff {}
1function checkStuff() private {}
2
3function doSomething() { checkStuff(); }

Dokezo hizo zinapaswa kukusaidia kupunguza kwa kiasi kikubwa ukubwa wa mkataba. Kwa mara nyingine tena, siwezi kusisitiza vya kutosha, daima zingatia kugawanya mikataba ikiwezekana kwa athari kubwa zaidi.

Ukurasa ulihaririwa mwisho: 3 Machi 2026

Umesaidika na mafunzo haya?