Ana içeriğe geç
Change page

Akıllı sözleşme güvenliği

Son düzenleme: @selcuk45(opens in a new tab), 25 Eylül 2023

Akıllı sözleşmeler son derece esnektir ve blokzincirlere dağıtılan kod temelinde değiştirilemez mantık çalıştırırken büyük miktarlarda değer ve veriyi de kontrol etme özelliğine de sahiptir. Bu, canlı bir güven gerektirmeyen ve merkeziyetsiz uygulamalar ekosistemi yaratmıştır ve bu uygulamalar geleneksel sistemlere oranla birçok avantaja sahiptir. Aynı zamanda, akıllı sözleşmelerdeki güvenlik açıklarından yararlanarak kar peşinde koşan saldırganlar için fırsatlar sunarlar.

Ethereum gibi halka açık blokzincirler, akıllı sözleşmelerin güvenliğini sağlama sorununu daha da karmaşık hale getirir. Dağıtılmış sözleşme kodu genellikle güvenlik açıklarını kapatmak için değiştirilemez, ayrıca akıllı sözleşmelerden çalınan varlıkların takibi aşırı derecede zordur ve çoğunlukla değiştirilemezlik kaynaklı olarak geri alınamaz.

Rakamlar değişkenlik gösterse de, akıllı sözleşmelerdeki güvenlik açıklarından kaynaklı kaybedilen veya çalınan toplam değerin miktarının 1 milyar doları rahatlıkla aştığı tahmin edilmektedir. Bu, DAO hacki(opens in a new tab) (3.6 milyon ETH çalınmıştır; değeri, günümüz fiyatlarıyla 1 milyar doların üzerindedir), Parity çoklu imza cüzdanı hacki(opens in a new tab) (Hackerlara 30 milyon dolar kaybedilmiştir), Parity donmuş cüzdan sorunu(opens in a new tab) (300 milyon dolardan fazla ETH sonsuza kadar kilitlenmiştir) gibi yüksek profilli olayları içerir.

Sayılan sorunlar geliştiricilerin güvenli, güçlü ve sağlam akıllı sözleşmeler oluşturmaya çaba harcamasını zorunlu kılmaktadır. Akıllı sözleşme güvenliği ciddi bir iştir ve her geliştiricinin öğrenmesi gerekir. Bu kılavuz, Ethereum geliştiricilerinin güvenlik konusunda dikkat etmesi gereken hususları ele alacak ve akıllı sözleşme güvenliğini geliştirmeye yönelik kaynakları inceleyecektir.

Ön koşullar

Güvenlik konusuna girmeden önce akıllı sözleşme geliştirmenin temelleri ile aşina olduğunuzdan emin olun.

Güvenli Ethereum akıllı sözleşmeleri oluşturma yönergeleri

1. Uygun erişim kontrolleri tasarlayın

Akıllı sözleşmelerde, public veya external olarak işaretlenmiş olan fonksiyonlar herhangi bir harici olarak sahiplenilmiş hesap (EOA'lar) veya sözleşme hesabı tarafından çağırılabilir. Başkalarının sözleşmeniz ile etkileşime girmesini istiyorsanız fonksiyonlar için herkese açık görülebilirliği belirtmeniz gereklidir. Ancak private olarak işaretlenmiş olan fonksiyonlar harici hesaplardan değil, sadece akıllı sözleşmenin içinden çağırılabilir. Her ağ katılımcısına sözleşme fonksiyonlarına erişim hakkı vermek, özellikle de hassas işlemleri herkesin yapabileceği anlamına geliyorsa (örneğin yeni jetonlar basmak) sorunlar yaratabilir.

Akıllı sözleşme fonksiyonlarının izinsiz kullanımını engellemek için güvenli erişim kontrolleri uygulamak şarttır. Erişim kontrol mekanizmaları, bir akıllı sözleşmedeki belirli fonksiyonları kullanma olanağını sözleşmeyi yönetmekten sorumlu olan hesaplar gibi onaylı varlıklar ile sınırlar. Sahiplenilebilir desen ve rol tabanlı kontrol, akıllı sözleşmelerde erişim kontrolü uygulamaya yönelik iki kullanışlı desendir:

Sahiplenilebilir desen

Sahiplenilebilir desende, sözleşme yaratım sürecinde bir adres sözleşmenin "sahibi" olarak ayarlanır. Korunan fonksiyonlara bir OnlyOwner niteleyicisi atanır; bu niteleyici, sözleşmenin fonksiyonu yürütmeden önce çağıran adresin kimliğini doğrulamasını sağlar. Korunan fonksiyonlara sözleşme sahibinin dışındaki diğer adreslerden yapılan çağrılar hep geri döndürülerek istenmeyen erişim engellenir.

Rol tabanlı erişim kontrolü

Bir akıllı sözleşmede tek bir adresi Owner olarak kaydetmek, merkezileşme riskini beraberinde getirir ve tek bir başarısızlık noktasını temsil eder. Sahibin hesap anahtarları açığa çıkarsa, saldırganlar sahip olunan sözleşmeye saldırabilir. İşte bu nedenle, birden fazla yönetim hesabı olan rol tabanlı bir erişim kontrol deseninin kullanılması daha iyi bir seçenek olabilir.

Rol tabanlı erişim kontrolünde, hassas fonksiyonlara erişim bir grup güvenilir katılımcıya dağıtılır. Örnek olarak, bir hesap jeton basmaktan sorumlu olabilir, diğer hesap da yükseltmeleri gerçekleştirir veya sözleşmeyi duraklatır. Erişim kontrolünü bu yolla merkeziyetsizleştirmek, tek başarısızlık noktalarını ortadan kaldırır ve kullanıcılar için güven varsayımlarını azaltır.

Çoklu imzalı cüzdanlar kullanma

Güvenli erişim kontrolü uygulamaya yönelik diğer bir yaklaşım ise sözleşmeyi yönetmek için çoklu imzalı hesap kullanmaktır. Çoklu imzalı hesaplar, sıradan bir EOA'nın aksine birden fazla varlığa aittir ve işlemleri yürütmek için belirlenen minimum sayıda hesaptan (örneğin 5 hesaptan 3'ü) imza alınmasını şart koşar.

Erişim kontrolü için çoklu imza kullanmak, hedef sözleşme üzerinde yapılacak eylemlerin birden fazla tarafın iznini gerektirmesi nedeniyle ekstra bir güvenlik katmanı sağlar. Bu, özellikle sahiplenilebilir desenin kullanılması zorunluysa kullanışlıdır, çünkü bir saldırganın veya içeriden kötü niyetli birinin hassas sözleşme fonksiyonlarını kötü amaçlar için manipüle etmesini daha da zorlaştırır.

2. Sözleşme operasyonlarını korumak için require(), assert() ve revert() ifadelerini kullanın

Belirtildiği gibi, akıllı sözleşmenizdeki herkese açık fonksiyonları blokzincire dağıtıldıktan sonra herkes çağırabilir. Harici hesapların bir sözleşme ile nasıl etkileşime geçeceğini önceden bilemeyeceğiniz için dağıtmadan önce sorunlu işlemlere karşı dahili önlemleri uygulamaya koymak idealdir. Akıllı sözleşmelerde yürütmenin bazı gereklilikleri başarıyla karşılayamadığı durumlarda istisnaları tetiklemek ve durum değişikliklerini geri almak için doğru davranışları require(), assert(), ve revert() ifadelerini kullanarak uygulatabilirsiniz.

require(): require, fonksiyonların başlangıcında tanımlanır ve önceden belirlenmiş koşulların çağrılan fonksiyon yürütülmeden önce karşılanmasını sağlar. Bir require ifadesi, bir fonksiyona devam etmeden önce kullanıcı girdilerini doğrulamak, durum değişkenlerini kontrol etmek veya çağıran hesabın kimliğini doğrulamak için kullanılabilir.

assert(): assert(), dahili hataları tespit etmek ve kodunuzda "değişmez" ihlali olup olmadığını kontrol etmek için kullanılır. Bir değişmez, bir sözleşmenin durumu ile ilgili olarak tüm fonksiyon yürütmeleri için doğru olması gereken mantıksal bir çıkarımdır. Bir jeton sözleşmesinin maksimum toplam arzı veya bakiyesi, değişmeze örnek olarak verilebilir. assert() kullanmanız sözleşmenizin asla güvenlik açığı olan bir duruma gelmemesini ve gelirse de durum değişkenlerinde yapılan tüm değişikliklerin geri alınmasını sağlar.

revert(): revert(), gerekli koşul sağlanmadığında bir istisna tetikleyen bir eğer-değilse ifadesinde kullanılabilir. Aşağıdaki örnek sözleşmede, fonksiyonların yürütülmesini korumak için revert() kullanılmaktadır:

1pragma solidity ^0.8.4;
2
3contract VendingMachine {
4 address owner;
5 error Unauthorized();
6 function buy(uint amount) public payable {
7 if (amount > msg.value / 2 ether)
8 revert("Not enough Ether provided.");
9 // Perform the purchase.
10 }
11 function withdraw() public {
12 if (msg.sender != owner)
13 revert Unauthorized();
14
15 payable(msg.sender).transfer(address(this).balance);
16 }
17}
Tümünü göster

3. Akıllı sözleşmeleri test edin ve kod doğruluğunu onaylayın

Ethereum Sanal Makinası'nda çalışan kodun değiştirilemezliği, akıllı sözleşmelerin geliştirme aşamasında daha yüksek seviyede bir kalite kontrole ihtiyaç duyduğunu gösterir. Sözleşmeyi kapsamlı bir şekilde test etmek ve beklenmeyen bir sonuç olup olmadığını görmek için gözlemlemek, güvenliği büyük oranda artırır ve uzun vadede kullanıcılarınızı korur.

Sık kullanılan yöntem, sözleşmenin kullanıcılardan alması beklenen taklit verileri kullanarak küçük birim testleri yazmaktır. Birim testi yapmak, bazı fonksiyonların çalışıp çalışmadığını test etmek ve bir akıllı sözleşmenin beklendiği gibi çalıştığından emin olmak açısından kullanışlıdır.

İzole şekilde kullanıldığında birim testi yapmak maalesef akıllı sözleşme güvenliğini geliştirmekte minimal seviyede etkilidir. Bir birim testi, bir fonksiyonun taklit veriler için düzgün şekilde yürütüldüğünü kanıtlayabilse de, birim testleri sadece yazılan testler kadar etkilidir. Bu, akıllı sözleşmenizin güvenliğine zarar verebilecek eksik uç durumlarını ve güvenlik açıklarını tespit etmeyi zorlaştırır.

Birim testini statik ve dinamik analiz kullanarak özellik tabanlı test ile birleştirmek daha doğru bir yaklaşımdır. Statik analiz, ulaşılabilir program durumlarını ve yürütme yollarını analiz etmek için kontrol akış grafikleri(opens in a new tab) ve soyut söz dizimi ağaçları(opens in a new tab) gibi düşük seviye gösterimlere dayanır. Bu esnada, bulandırma gibi dinamik analiz teknikleri, güvenlik özelliklerini ihlal eden işlemleri tespit etmek için sözleşme kodunu rastgele girdi değerleri ile yürütür.

Resmi doğrulama, akıllı sözleşmelerdeki güvenlik özelliklerini doğrulamaya yönelik başka bir tekniktir. Sıradan testlerin aksine, resmi doğrulama bir akıllı sözleşmede hata bulunmadığını kesin bir şekilde kanıtlayabilir. Bu, istenen güvenlik özelliklerini belirleyen bir resmi spesifikasyon oluşturarak ve sözleşmelerin resmi bir modelinin bu spesifikasyona uyduğu kanıtlanarak gerçekleştirilir.

4. Kodunuz için bağımsız bir inceleme yapılmasını talep edin

Sözleşmenizi test ettikten sonra başkalarından herhangi bir güvenlik sorunu için kaynak koduna bakmalarını istemek doğru olur. Test etmek, bir akıllı sözleşmedeki her hatayı ortaya çıkarmayacaktır, ancak bağımsız bir inceleme yaptırmak güvenlik açıklarının tespit edilmesi ihtimalini artırır.

Denetimler

Akıllı sözleşme denetim hizmeti almak, bağımsız bir kod incelemesi gerçekleştirmenin bir yoludur. Denetimciler, akıllı sözleşmelerin güvenli olmasının, kalite eksikleri ve tasarım hataları içermemesinin sağlanmasında önemli bir rol oynar.

Bununla birlikte, denetimleri sihirli değnek gibi görmemelisiniz. Akıllı sözleşme denetimleri her hatayı yakalamaz ve çoğunlukla ek bir dizi inceleme sunmak üzere tasarlanmıştır, bu da geliştiriciler tarafından ilk geliştirme ve test esnasında gözden kaçırılabilecek sorunları tespit etmeye yardımcı olur. Ayrıca akıllı sözleşme denetiminin faydasını maksimuma çıkarmak için kodu düzgün biçimde belgelemek ve satır içi yorumlar eklemek gibi denetimcilerle çalışmaya yönelik en iyi uygulamaları(opens in a new tab) takip etmelisiniz.

Hata ödülleri

Bir hata ödülü programı oluşturmak, harici kod incelemelerinin uygulamaya koymaya yönelik başka bir yaklaşımdır. Hata ödülü, bir uygulamada güvenlik açığı bulan kişilere (genelde beyaz şapkalı hackerlar) verilen para cinsinden bir ödüldür.

Düzgün şekilde kullanıldığında, hata ödülleri hacker topluluğunun üyelerine kodunuzda kritik hatalar bulunup bulunmadığını incelemeleri için bir teşvik sunar. Bunun gerçek hayattaki örneklerinden biri, Ethereum üzerinde çalışan bir Katman 2 protokolü olan Optimism(opens in a new tab) üzerinde bir saldırganın sınırsız miktarda Ether yaratabilmesine olanak tanıyan "sınırsız para hatası"dır. Neyse ki bir beyaz şapkalı hacker hatayı bulmuş(opens in a new tab) ve takıma bildirmiş, bu süreçte de büyük bir ödeme almıştır(opens in a new tab).

Bir hata ödülü programının ödemesini ilgili fonların miktarı ile orantılı bir şekilde ayarlamak kullanışlı bir stratejidir. “Hata ödülünü ölçeklendirme(opens in a new tab)” olarak tanımlanan bu yaklaşım, kişilerin güvenlik açıklarını istismar etmek yerine sorumlu şekilde bildirmesi için parasal teşvikler sağlar.

5. Akıllı sözleşme geliştirme sırasında en iyi uygulamaları takip edin

Denetimlerin ve hata ödüllerinin varlığı, yüksek kalitede kod yazma sorumluluğunuz açısından bir mazeret değildir. Akıllı sözleşme güvenliğinin iyi seviyede olması için ilk olarak düzgün tasarım ve geliştirme süreçleri oluşturmanız gerekir:

  • Tüm kodu git gibi bir sürüm denetimi sisteminde depolayın

  • Tüm kod değişikliklerini çekme istekleri aracılığı ile yapın

  • Çekme isteklerinin en az bir bağımsız denetçisi olduğundan emin olun; bir projede tek başınıza çalışıyorsanız, başka geliştiriciler bulmayı ve kod incelemesi alışverişinde bulunmayı düşünün

  • Akıllı sözleşmeleri test etmek, derlemek ve dağıtmak için bir geliştirme ortamı kullanın

  • Kodunuzu Mythril ve Slither gibi temel kod analiz araçlarından geçirin. İdeal olarak, bunu her çekme isteği birleştirmesinden önce yapmalı ve çıktılardaki farkları karşılaştırmalısınız

  • Kodunuzun hatasız bir şekilde derlendiğinden ve Solidity derleyicisinin herhangi bir uyarı vermediğinden emin olun

  • Kodunuzu düzgün biçimde belgelendirin (NatSpec(opens in a new tab) kullanın) ve sözleşme yapısı hakkındaki detayları anlaşılabilir bir dille açıklayın. Bu, başkalarının sizin kodunuzu denetlemesini ve incelemesini kolaylaştıracaktır.

6. Güçlü olağanüstü durum kurtarma planları uygulayın

Güvenli erişim kontrolleri tasarlamak, fonksiyon değiştiricileri uygulamak ve diğer öneriler, akıllı sözleşme güvenliğini artırabilir ancak kötü niyetli saldırıların gerçekleşme ihtimalini sıfıra indirgeyemez. Güvenli akıllı sözleşmeler oluşturmak, "başarısızlığa hazırlanmayı" ve saldırılara karşı etkili bir şekilde cevap vermek için bir geri dönüş planına sahip olmayı gerektirir. Düzgün bir olağanüstü durum kurtarma planı, aşağıdaki bileşenlerin bazılarını ya da hepsini kapsar:

Sözleşme yükseltmeleri

Ethereum akıllı sözleşmeleri varsayılan olarak değiştirilemez olsa da, yükseltme desenleri kullanılarak bir dereceye kadar değiştirilebilirliğe ulaşmak mümkündür. Kritik bir hatanın eski sözleşmenizi kullanılamaz hale getirdiği ve yeni bir mantık dağıtmanın en makul seçenek olduğu durumlarda sözleşmeleri yükseltmek gereklidir.

Sözleşme yükseltme mekanizmaları farklı şekilde çalışsa da, "vekil deseni" akıllı sözleşmeleri yükseltmeye yönelik daha popüler yaklaşımlardan biridir. Vekil desenleri, bir uygulamanın durum ve mantığını iki sözleşme arasında ayırır. İlk sözleşme ('vekil sözleşmesi' adı verilir) durum değişkenlerini depolar (örneğin kullanıcı bakiyeleri), ikinci sözleşme ise ('mantık sözleşmesi' adı verilir) sözleşme fonksiyonlarını yürütmek için gereken kodu tutar.

Hesaplar, tüm fonksiyon çağrılarını delegatecall()(opens in a new tab) düşük seviye çağrısı kullanarak mantık sözleşmesine ileten vekil sözleşmesi ile etkileşime geçer. Sıradan bir mesaj çağrısının aksine delegatecall(), mantık sözleşmesinin adresinde çalışan kodun çağıran sözleşme bağlamında yürütülmesini sağlar. Bu, mantık sözleşmesinin her zaman vekilin depolamasına yazacağı (kendi depolaması yerine) ve msg.sender ile msg.value değerlerinin orijinal halinin korunacağı anlamına gelir.

Mantık sözleşmesine çağrılar devretmek için adresinin vekil sözleşmesinin depolamasında depolanması gerekir. Dolayısıyla sözleşmenin mantığını yükseltme, sadece başka bir mantık sözleşmesi dağıtmaktan ve yeni adresi vekil sözleşmesinde depolamaktan ibarettir. Vekil sözleşmesine sonraki çağrılar otomatik olarak yeni mantık sözleşmesine yönlendirildiği için kodu gerçekten değiştirmeden sözleşmeyi "yükseltmiş" olursunuz.

Sözleşme yükseltme hakkında daha fazla ayrıntı.

Acil durdurmalar

Belirtildiği gibi, bir akıllı sözleşmedeki tüm hataları geniş çaplı denetim ve test yoluyla bulmak mümkün olmayabilir. Dağıtım sonrası kodunuzda bir güvenlik açığı ortaya çıkarsa, sözleşme adresinde çalışan kodu değiştiremeyeceğiniz için bu açığı kapatmak imkansızdır. Ayrıca yükseltme mekanizmalarını (örneğin vekil desenleri) uygulamak zaman alabilir (genelde farklı taraflardan onay alınması gerekir), bu da saldırganlara daha fazla zarar vermek için daha fazla zaman tanır.

Nükleer seçenek ise bir sözleşmede güvenlik açığı bulunan fonksiyonlara gelecek çağrıları engelleyen bir "acil durdurma" fonksiyonunu uygulamaya koymaktır. Acil durdurmalar genelde şu bileşenlerden oluşur:

  1. Akıllı sözleşmenin durdurulmuş bir durumda olup olmadığını gösteren global bir Boole değişkeni. Bu değişken, sözleşme oluşturulurken false olarak ayarlanmıştır ancak sözleşme durdurulduğunda true şekline döner.

  2. Yürütülürken Boole değişkenine başvuran fonksiyonlar. Bu fonksiyonlar, akıllı sözleşme durdurulmamışsa erişilebilir durumdadır ve acil durdurma özelliği tetiklendiğinde erişilemez hale gelir.

  3. Acil durdurma fonksiyonuna erişimi olan, Boole değişkenini true yapan bir varlık. Bu fonksiyona yapılan çağrılar, kötü niyetli eylemleri önlemek için güvenilir bir adres ile (örneğin sözleşme sahibi) sınırlandırılabilir.

Sözleşmenin acil durdurmayı etkinleştirmesinin ardından belirli fonksiyonlar çağrılabilir niteliğini kaybeder. Bu, seçili fonksiyonların global değişkene başvuran bir niteleyici ile paketlenmesi yoluyla gerçekleştirilir. Bu desenin sözleşmelerdeki bir uygulamasını açıklayan bir örneği(opens in a new tab) aşağıda bulabilirsiniz:

1// This code has not been professionally audited and makes no promises about safety or correctness. Use at your own risk.
2
3contract EmergencyStop {
4
5 bool isStopped = false;
6
7 modifier stoppedInEmergency {
8 require(!isStopped);
9 _;
10 }
11
12 modifier onlyWhenStopped {
13 require(isStopped);
14 _;
15 }
16
17 modifier onlyAuthorized {
18 // Check for authorization of msg.sender here
19 _;
20 }
21
22 function stopContract() public onlyAuthorized {
23 isStopped = true;
24 }
25
26 function resumeContract() public onlyAuthorized {
27 isStopped = false;
28 }
29
30 function deposit() public payable stoppedInEmergency {
31 // Deposit logic happening here
32 }
33
34 function emergencyWithdraw() public onlyWhenStopped {
35 // Emergency withdraw happening here
36 }
37}
Tümünü göster
Kopyala

Bu örnek, acil durdurmaların temel özelliklerini göstermektedir:

  • isStopped, başlangıçta false olan ve sözleşme acil durum moduna geçtiğinde değişerek true olan bir Boole değeridir.

  • onlyWhenStopped ve stoppedInEmergency fonksiyon niteleyicileri, isStopped değişkenini kontrol eder. stoppedInEmergency, sözleşmenin güvenlik açığı olduğunda (örneğin deposit()) erişilemez olması gereken fonksiyonları kontrol etmek için kullanılır. Basitçe ifade etmek gerekirse, bu fonksiyonlara yapılan çağrılar geri döndürülür.

onlyWhenStopped, sadece bir acil durum esnasında çağrılabilir olması gereken fonksiyonlar (örneğin emergencyWithdraw()) için kullanılır. Bu tarz fonksiyonlar durumun çözüme kavuşturulmasına yardımcı olabilir ve bundan dolayı "yasaklı fonksiyonlar" listesinden çıkarılmıştır.

Acil durdurma fonksiyonunu kullanmak, akıllı sözleşmenizdeki ciddi güvenlik açıkları ile baş etmek adına etkili bir tedbirdir. Ancak, kullanıcıların kendi faydalarına etkinleştirmemeleri konusunda geliştiricilere güvenmesi ihtiyacını artırır. Bu amaçla, acil durdurma kontrolünün merkeziyetsizleştirilmesi için ya zincir üstü bir oy mekanizmasına tabi tutularak ya zaman kilidi uygulanarak ya da çoklu imza cüzdanından onay alınarak çözümler geliştirmek mümkündür.

Olay izleme

Olaylar(opens in a new tab), akıllı sözleşme fonksiyonlarına yapılan çağrıları takip etmenize ve durum değişkenlerindeki değişiklikleri izlemenize olanak tanır. Akıllı sözleşmenizi, bir tarafın güvenlik açısından kritik bir eylem (örneğin, fon çekme) gerçekleştirdiğinde bir olay yayımlayacak şekilde programlamak idealdir.

Olayları günlüğe kaydetmek ve bunları zincir dışında izlemek, sözleşme işlemleri hakkında bilgi sağlar ve kötü niyetli eylemlerin daha hızlı tespitine yardımcı olur. Bu, ekibinizin hızlı bir şekilde hacklere yanıt verebilmesi ve kullanıcılar üzerindeki etkiyi azaltmak için fonksiyonları duraklatma veya yükseltme yapma gibi önlemler alabilmesi anlamına gelir.

Ayrıca, sözleşmelerinizle biri etkileşimde bulunduğunda otomatik olarak uyarıları ileten hazır bir izleme aracını da tercih edebilirsiniz. Bu araçlar işlem hacmi, fonksiyon çağrılarının sıklığı veya sürecin parçası olan spesifik fonksiyonlar gibi farklı tetikleyicilere göre özel uyarılar oluşturmanıza olanak sağlar. Örneğin, tek bir işlemde çekilen miktarın belirli bir eşiği aşması durumunda devreye girecek bir uyarı programlayabilirsiniz.

7. Güvenli yönetişim sistemleri tasarlayın

Ana akıllı sözleşmelerin kontrolünü topluluk üyelerine devretmek suretiyle uygulamanızı merkeziyetsizleştirmeyi düşünebilirsiniz. Bu durumda akıllı sözleşme sistemi, topluluk üyelerinin yönetimsel eylemleri zincir üstünde yönetişim sistemi aracılığıyla onaylayabilmesine olanak tanıyan bir yönetişim modülü içerecektir. Örneğin, bir vekil sözleşmenin yeni bir uygulamaya yükseltilmesi teklifi, jeton sahipleri tarafından oylanabilir.

Merkezi olmayan yönetişim, özellikle geliştiricilerin ve son kullanıcıların çıkarlarını uyumlu hale getirdiği için faydalı olabilir. Yine de, akıllı sözleşme yönetişim mekanizmaları yanlış uygulandığında yeni riskleri beraberinde getirebilir. Saldırganın bir flash loan (hızlı kredi) alarak büyük miktarda oy hakkı (elindeki jeton sayısıyla ölçülen) elde etmesi ve kötü niyetli bir teklifi kabul ettirmesi makul bir senaryo olabilir.

Zincir üstünde yönetişimle ilgili sorunları önlemenin bir yolu, bir zaman kilidi(opens in a new tab) kullanmaktır. Zaman kilidi, bir akıllı sözleşmenin belirli bir süre geçene kadar belirli eylemleri gerçekleştirmesini engeller. Diğer stratejiler arasında her bir jetona ne kadar süreyle kilitlendiğine dayalı olarak bir "oylama ağırlığı" atama veya bir adresin oy gücünü mevcut blok yerine geçmişteki bir dönemde (örneğin, geçmişteki 2-3 blok) ölçme gibi yöntemler yer alır. Her iki yöntem de oy gücünü zincir üstündeki oyları hızla etkileyecek şekilde toplama olasılığını azaltır.

Güvenli yönetişim sistemleri tasarlama(opens in a new tab) ve DAO'lardaki farklı oylama mekanizmaları(opens in a new tab) hakkında daha fazla bilgi.

8. Kodun karmaşıklık düzeyini minimuma indirgeyin

Geleneksel yazılım geliştiricileri, yazılım tasarımına gereksiz karmaşıklık eklememeyi tavsiye eden "KISS" ("keep it simple, stupid - basit tut, aptal") prensibini iyi bilir. Bu, uzun süredir kabul gören "karmaşık sistemler karmaşık şekillerde başarısız olur" düşüncesine uygundur ve bu sistemler maliyetli hatalara daha yatkındır.

Akıllı sözleşmeleri yazarken işleri basit tutmak, akıllı sözleşmelerin potansiyel olarak büyük miktarlarda değeri kontrol ettiği göz önüne alındığında özellikle önemlidir. Akıllı sözleşme yazarken basitliği sağlamaya yönelik bir ipucu, mümkün olduğunda OpenZeppelin Sözleşmeleri(opens in a new tab) gibi mevcut kütüphaneleri yeniden kullanmaktır. Bu kütüphaneler, geliştiriciler tarafından kapsamlı bir şekilde denetlenmiş ve test edilmiş olduğundan bunların kullanılması, yeni işlevselliğin sıfırdan yazılarak hataların eklenmesi olasılığını azaltır.

Başka yaygın bir tavsiye de küçük fonksiyonlar yazmak ve iş mantığını birden fazla sözleşmeye bölerek sözleşmeleri modüler tutmaktır. Basit kod yazmak, akıllı sözleşmedeki saldırı yüzeyini azaltırken genel sistem doğruluğu hakkında düşünmeyi ve olası tasarım hatalarını erken tespit etmeyi de kolaylaştırır.

9. Yaygın akıllı sözleşme güvenlik açıklarına karşı savunma geliştirin

Yeniden giriş

Ethereum Sanal Makinesi, eş zamanlılığa izin vermez; yani bir mesaj çağrısına dahil olan iki sözleşme aynı anda çalışamaz. Harici bir çağrı sözleşmenin yürütülmesini ve hafızasını çağrı dönene kadar duraklatır; bunun ardından yürütme normal şekilde devam eder. Bu süreç resmi olarak kontrol akışını(opens in a new tab) başka bir sözleşmeye aktarmak olarak tanımlanabilir.

Çoğunlukla zararsız olsa da, kontrol akışını güvenilmeyen sözleşmelere aktarmak yeniden giriş gibi problemlere yok açabilir. Yeniden giriş saldırısı, kötü niyetli bir sözleşmenin güvenlik açığı bulunan bir sözleşmeye asıl fonksiyonun çağrısı tamamlanmadan geri çağrı yapması durumunda gerçekleşir. Bu tür bir saldırı en iyi şekilde örnek vererek açıklanabilir.

Herhangi bir kişinin Ether yatırmasına ve çekmesine izin veren basit bir akıllı sözleşme ('Victim') düşünün:

1// This contract is vulnerable. Do not use in production
2
3contract Victim {
4 mapping (address => uint256) public balances;
5
6 function deposit() external payable {
7 balances[msg.sender] += msg.value;
8 }
9
10 function withdraw() external {
11 uint256 amount = balances[msg.sender];
12 (bool success, ) = msg.sender.call.value(amount)("");
13 require(success);
14 balances[msg.sender] = 0;
15 }
16}
Tümünü göster
Kopyala

Bu sözleşme, kullanıcıların sözleşmeye önceden yatırılmış olan ETH'yi çekmesini sağlayan withdraw() fonksiyonunu açığa çıkartır. Sözleşme, bir çekimi işlerken şu işlemleri gerçekleştirir:

  1. Kullanıcının ETH bakiyesini kontrol eder
  2. Fonları çağıran adrese yollar
  3. Bakiyeyi 0'a ayarlayarak kullanıcının ek çekimler yapmasını önler

Victim sözleşmesindeki withdraw() fonksiyonu, "kontroller-etkileşimler-etkiler" desenini takip eder. Yürütme için gerekli koşulların sağlanıp sağlanmadığını (yani kullanıcının pozitif bir ETH bakiyesi olup olmadığını) kontrol eder ve işlemin etkilerini uygulamadan önce (yani kullanıcının bakiyesini düşürmek) çağıranın adresine ETH göndererek etkileşimi gerçekleştirir.

Eğer withdraw() bir dışarıdan sahip olunan hesap (EOA) tarafından çağrılırsa, fonksiyon beklenildiği gibi çalışır: msg.sender.call.value() çağırana ETH gönderir. Ancak msg.sender, withdraw() çağrısı yapan bir akıllı sözleşme hesabı ise, msg.sender.call.value() kullanarak fon gönderildiğinde aynı zamanda o adreste depolanan kod da çalışacaktır.

Sözleşme adresinde dağıtılan kodun şu olduğunu hayal edin:

1 contract Attacker {
2 function beginAttack() external payable {
3 Victim(victim_address).deposit.value(1 ether)();
4 Victim(victim_address).withdraw();
5 }
6
7 function() external payable {
8 if (gasleft() > 40000) {
9 Victim(victim_address).withdraw();
10 }
11 }
12}
Tümünü göster
Kopyala

Bu sözleşme üç şey yapmak üzere tasarlanmıştır:

  1. Başka bir hesaptan yatırma işlemini kabul etmek (muhtemelen saldırganın EOA'sı)
  2. Victim sözleşmesine 1 ETH yatırmak
  3. Akıllı sözleşmede depolanan 1 ETH'yi çekmek

Burada, gelen msg.sender.call.value tarafından bırakılan gaz miktarı 40.000'den fazla ise Attacker'ın Victim'deki withdraw() fonksiyonunu tekrar çağıran başka bir fonksiyonu olması hariç yanlış hiçbir şey yoktur. Bu, Attacker'a Victim'e yeniden girebilme ve ilk withdraw çağrısı tamamlanmadan önce daha fazla fon çekebilme olanağı sağlar. Bu döngü şöyle görünür:

1- Attacker's EOA calls `Attacker.beginAttack()` with 1 ETH
2- `Attacker.beginAttack()` deposits 1 ETH into `Victim`
3- `Attacker` calls `withdraw() in `Victim`
4- `Victim` checks `Attacker`’s balance (1 ETH)
5- `Victim` sends 1 ETH to `Attacker` (which triggers the default function)
6- `Attacker` calls `Victim.withdraw()` again (note that `Victim` hasn’t reduced `Attacker`’s balance from the first withdrawal)
7- `Victim` checks `Attacker`’s balance (which is still 1 ETH because it hasn’t applied the effects of the first call)
8- `Victim` sends 1 ETH to `Attacker` (which triggers the default function and allows `Attacker` to reenter the `withdraw` function)
9- The process repeats until `Attacker` runs out of gas, at which point `msg.sender.call.value` returns without triggering additional withdrawals
10- `Victim` finally applies the results of the first transaction (and subsequent ones) to its state, so `Attacker`’s balance is set to 0
Tümünü göster
Kopyala

Özetle, çağıranın bakiyesi fonksiyonun yürütülmesi tamamlanana kadar 0'a ayarlanmadığı için sonraki çağrılar başarılı olacak ve çağıranın bakiyesini birden fazla kez çekmesine olanak tanıyacaktır. Bu tür saldırılar, 2016 DAO hack(opens in a new tab) olayında olduğu gibi akıllı sözleşmenin fonlarını boşaltmak için kullanılabilir. Yeniden giriş saldırıları, yeniden giriş suistimallerinin herkese açık listesi(opens in a new tab) içinde gösterildiği gibi bugün hala akıllı sözleşmeler için ciddi bir sorundur.

Yeniden giriş saldırılarını engelleme

Yeniden girişle başa çıkmak için izlenebilecek bir yaklaşım, kontroller-etkiler-etkileşimler modelini(opens in a new tab) takip etmektir. Bu model, yürütmenin, yürütme işlemine devam etmeden önce gerekli kontrolleri gerçekleştiren kodla başladığı, ardından sözleşme durumunu manipüle eden kodla devam ettiği ve son olarak diğer sözleşmeler veya EOA'larla etkileşimde bulunan kodun geldiği bir şekilde düzenlenmesini sağlar.

Kontroller-etkiler-etkileşim modeli, aşağıda gösterilen Victim sözleşmesinin revize edilmiş bir sürümünde kullanılır:

1contract NoLongerAVictim {
2 function withdraw() external {
3 uint256 amount = balances[msg.sender];
4 balances[msg.sender] = 0;
5 (bool success, ) = msg.sender.call.value(amount)("");
6 require(success);
7 }
8}
Kopyala

Bu sözleşme, kullanıcının bakiyesi üzerinde bir kontrol gerçekleştirir, withdraw() fonksiyonunun etkilerini uygular (kullanıcının bakiyesini 0'a ayarlayarak) ve son olarak etkileşimi gerçekleştirir (kullanıcının adresine ETH gönderir). Bu, sözleşmenin depolamasını harici çağrıdan önce güncellemesini sağlayarak ilk saldırıya yol açan yeniden giriş koşulunu ortadan kaldırır. Attacker sözleşmesini NoLongerAVictim'e çağırmak hala mümkün olsa da balances[msg.sender] 0 olarak ayarlandığı için ek çekimler hata verir.

Diğer bir seçenek ise bir fonksiyon çağrısı tamamlanana kadar sözleşmenin durumunun bir kısmını kilitleyen karşılıklı hariç tutma kilidi (genellikle "mutex" olarak tanımlanır) kullanmaktır. Bu, fonksiyon yürütülmeden önce true olarak ayarlanan ve çağrı tamamlandıktan sonra false şekline dönen bir Boole değişkeni kullanılarak uygulanır. Aşağıdaki örnekte görüldüğü gibi mutex kullanmak, bir fonksiyonu orijinal çağrı halen işleniyorken tekrarlı çağrılara karşı koruyarak yeniden girişi etkin biçimde durdurur.

1pragma solidity ^0.7.0;
2
3contract MutexPattern {
4 bool locked = false;
5 mapping(address => uint256) public balances;
6
7 modifier noReentrancy() {
8 require(!locked, "Blocked from reentrancy.");
9 locked = true;
10 _;
11 locked = false;
12 }
13 // This function is protected by a mutex, so reentrant calls from within `msg.sender.call` cannot call `withdraw` again.
14 // The `return` statement evaluates to `true` but still evaluates the `locked = false` statement in the modifier
15 function withdraw(uint _amount) public payable noReentrancy returns(bool) {
16 require(balances[msg.sender] >= _amount, "No balance to withdraw.");
17
18 balances[msg.sender] -= _amount;
19 bool (success, ) = msg.sender.call{value: _amount}("");
20 require(success);
21
22 return true;
23 }
24}
Tümünü göster
Kopyala

Ayrıca fonları hesaplara gönderen bir "itme ödemeleri" sistemi yerine, kullanıcıların akıllı sözleşmelerden fonlarını çekmesini gerektiren bir çekme ödemeleri(opens in a new tab) sistemini de kullanabilirsiniz. Bu, bilinmeyen adreslerde yanlışlıkla kod tetikleme ihtimalini ortadan kaldırır (ve aynı zamanda belirli hizmet reddi saldırılarını önleyebilir).

Tamsayı yetersizlikleri ve taşmaları

Tamsayı taşması, bir aritmetik işlemin sonucunun kabul edilebilir değer aralığının dışına düşerek tamsayıyı temsil edilebilir en düşük değere yuvarlamasına neden olduğu zaman gerçekleşir. Örneğin bir uint8 yalnızca 2^8-1=255'e kadar değerleri saklayabilir. 255'ten büyük değerleri sonuç veren aritmetik işlemler taşma yapar ve tıpkı bir otomobildeki kilometre sayacı azami kilometreye (999999) ulaşınca sıfırlandığı gibi uint'yi 0 olarak ayarlar.

Tamsayı yetersizlikleri de benzer sebeplerden dolayı gerçekleşir: bir aritmetik işlemin sonuçlarının kabul edilebilir aralığın altına düşmesi. Bir uint8 içinde 0'ı azaltmaya çalıştığınızı düşünelim; sonuç, basit olarak temsil edilebilir maksimum değere (255) yuvarlanacaktır.

Hem tamsayı taşmaları hem de tamsayı yetersizlikleri, bir sözleşmenin durum değişkenlerinde beklenmedik değişimlere yol açabilir ve planlanmamış yürütmeye sebep olabilir. Bir saldırganın geçersiz bir işlem gerçekleştirmek için akıllı sözleşmedeki aritmetik taşmayı nasıl istismar edebileceğinin bir örneğini aşağıda görebilirsiniz:

1pragma solidity ^0.7.6;
2
3// This contract is designed to act as a time vault.
4// User can deposit into this contract but cannot withdraw for at least a week.
5// User can also extend the wait time beyond the 1 week waiting period.
6
7/*1. Deploy TimeLock
82. Deploy Attack with address of TimeLock
93. Call Attack.attack sending 1 ether. You will immediately be able to
10 withdraw your ether.
11
12What happened?
13Attack caused the TimeLock.lockTime to overflow and was able to withdraw
14before the 1 week waiting period.
15*/
16
17contract TimeLock {
18 mapping(address => uint) public balances;
19 mapping(address => uint) public lockTime;
20
21 function deposit() external payable {
22 balances[msg.sender] += msg.value;
23 lockTime[msg.sender] = block.timestamp + 1 weeks;
24 }
25
26 function increaseLockTime(uint _secondsToIncrease) public {
27 lockTime[msg.sender] += _secondsToIncrease;
28 }
29
30 function withdraw() public {
31 require(balances[msg.sender] > 0, "Insufficient funds");
32 require(block.timestamp > lockTime[msg.sender], "Lock time not expired");
33
34 uint amount = balances[msg.sender];
35 balances[msg.sender] = 0;
36
37 (bool sent, ) = msg.sender.call{value: amount}("");
38 require(sent, "Failed to send Ether");
39 }
40}
41
42contract Attack {
43 TimeLock timeLock;
44
45 constructor(TimeLock _timeLock) {
46 timeLock = TimeLock(_timeLock);
47 }
48
49 fallback() external payable {}
50
51 function attack() public payable {
52 timeLock.deposit{value: msg.value}();
53 /*
54 if t = current lock time then we need to find x such that
55 x + t = 2**256 = 0
56 so x = -t
57 2**256 = type(uint).max + 1
58 so x = type(uint).max + 1 - t
59 */
60 timeLock.increaseLockTime(
61 type(uint).max + 1 - timeLock.lockTime(address(this))
62 );
63 timeLock.withdraw();
64 }
65}
Tümünü göster
Tamsayı yetersizliklerini ve taşmalarını engelleme

Solidity derleyicisi, 0.8.0 versiyonu itibariyle tamsayı yetersizliklerini ve taşmalarını sonuç veren kodları reddetmektedir. Ancak daha düşük bir derleme versiyonu ile derlenen sözleşmeler ya aritmetik işlemleri içeren fonksiyonlarda kontroller gerçekleştirmeli ya da yetersizlik/taşma kontrolü yapan kütüphaneleri (örneğin, SafeMath(opens in a new tab)) kullanmalıdır.

Kâhin manipülasyonu

Kâhinler, zincir dışından bilgi edinir ve bu bilgiyi akıllı sözleşmelerin kullanımı için zincir üstünde gönderir. Kâhinler sayesinde sermaye piyasaları gibi zincir dışında sistemlerle birlikte çalışan akıllı sözleşmeler tasarlayabilir ve bu sayede uygulama alanlarını önmeli ölçüde genişletebilirsiniz.

Ancak eğer kâhin yozlaşmışsa ve zincir üstünde yanlış bilgiler gönderiyorsa akıllı sözleşmeler, hatalara sebep olabilecek yanlış girdileri temel alarak yürütülür. Bu, bir blokzincir kâhininden gelen bilginin doğru, güncel olduğundan ve zamanında alındığından emin olma görevini ilgilendiren ''kâhin sorunu''nun temelidir.

Buna bağlı bir güvenlik endişesi de bir varlığın spot fiyatını almak için merkeziyetsiz borsa gibi zincir üstünde kâhin kullanımıdır. Merkeziyetsiz finans (DeFi) sektörünün borç verme platformları, bunu genellikle bir kullanıcın ne kadar ödünç alabileceğine karar vermek için kullanıcının teminatının değerini belirlemek amacıyla yapar.

DEX (merkeziyetsiz borsa) fiyatları, büyük ölçüde piyasalarda pariteleri eski haline getiren arbitrajcılar sayesinde genellikle doğrudur. Ancak bu fiyatlar, özellikle zincir üstündeki kâhinin varlık fiyatlarını geçmişe dönük ticaret düzenine dayanarak hesapladığı durumlarda (ki genelde durum böyledir) manipülasyona açıktır.

Örneğin bir saldırgan, borç verme sözleşmenizle etkileşime geçmeden hemen önce hızlı kredi alıp varlığın spot fiyatını suni olarak yükseltebilir. Varlık fiyatı için DEX sorgulama, normalin üstünde bir değer döndürerek (saldırganın varlık talebini çarpıtan büyük ''satın alım emri'' sebebiyle) alması gerekenden daha fazlasını ödünç alabilmesine imkan tanır. Bu gibi ''hızlı kredi saldırıları'' DeFi (merkeziyetsiz finans) uygulamaları arasında fiyat kâhinlerinin güvenilirliğini baltalamak için kullanıldı ve protokollerde milyonlarca dolarlık fon kaybına neden oldu.

Kâhin manipülasyonunu engelleme

Kâhin manipülasyonundan kaçınmanın asgari şartı, tek nokta hatalarından kaçınmak için çok sayıda kaynaktan bilgi sorgulayan bir merkeziyetsiz kâhin ağı kullanmaktır. Çoğu durumda merkeziyetsiz kâhinler, kâhin düğümlerini doğru bilgi aktarımı yapmaya teşvik etmek amacıyla onları merkezi kâhinlerden daha güvenli yapan yerleşik kripto-ekonomik teşviklere sahiptir.

Varlık fiyatları için bir zincir üstünde kâhin sorgulaması yapmayı planlıyorsanız zamana göre ağırlıklandırılmış ortalama fiyat (TWAP) mekanizmasını uygulayan bir tanesini kullanmayı göz önünde bulundurun. Bir TWAP kâhini(opens in a new tab), bir varlığın fiyatını iki farklı zaman noktasında sorgular (bunu değiştirebilirsiniz) ve elde edilen ortalamaya dayanarak spot fiyatı hesaplar. Daha uzun zaman dilimleri seçmek, yeni işlenmiş büyük emirler varlık fiyatını etkilemeyeceğinden protokolünüzü fiyat manipülasyonuna karşı korur.

Geliştiriciler için akıllı sözleşme güvenlik kaynakları

Akıllı sözleşmeleri analiz etmeye ve kod doğruluğunu teyit etmeye yönelik araçlar

  • Test araçları ve kütüphaneleri - Akıllı sözleşmeler üzerinde birim testleri, statik analiz ve dinamik analiz gerçekleştirmeye yönelik sektörel standart niteliğinde araçlar ve kütüphaneler koleksiyonu.

  • Resmi doğrulama araçları - Akıllı sözleşmelerde işlevsel doğruluğu teyit etmeye ve değişmezleri kontrol etmeye yönelik araçlar.

  • Akıllı sözleşme denetim hizmetleri - Ethereum geliştirme projeleri için akıllı sözleşme denetim hizmetleri sağlayan organizasyonların listesi.

  • Hata ödülü platformları - Hata ödüllerini koordine etme ve akıllı sözleşmelerdeki kritik güvenlik açıklarının sorumluluk bilinci içinde bildirilmesini ödüllendirme platformları.

  • Çatallanma Kontrolcüsü(opens in a new tab) - Çatallanmış bir sözleşme ile ilgili mevcut tüm bilgileri kontrol etmeye yönelik ücretsiz bir çevrimiçi araç.

  • ABI Şifreleyicisi(opens in a new tab) - Solidity sözleşme fonksiyonlarınızı ve yapıcı bağımsız değişkenlerinizi şifrelemeye yarayan ücretsiz bir çevrimiçi hizmet.

Akıllı sözleşmeleri izlemeye yarayan araçlar

Akıllı sözleşmelerin güvenli yönetimine yönelik araçlar

  • OpenZeppelin Defender Admin(opens in a new tab) - Erişim kontrolleri, yükseltmeler ve duraklatma dahil olmak üzere akıllı sözleşme yönetimine yönelik bir arayüz.

  • Safe(opens in a new tab) - Ethereum üzerinde çalışan ve bir işlemi gerçekleştirmeden önce minimum sayıda kişinin onayının alınmasını gerektiren bir akıllı sözleşme cüzdanı (N'nin M'si).

  • OpenZeppelin Sözleşmeleri(opens in a new tab) - Sözleşme sahipliği, yükseltmeler, erişim kontrolleri, yönetişim, duraklatabilirlik ve benzeri yönetimsel özellikleri uygulamaya yönelik sözleşme kütüphaneleri.

Akıllı sözleşme denetim hizmetleri

  • ConsenSys Diligence(opens in a new tab) - Blokzincir ekosistemindeki projelerin protokollerinin kullanıma hazır olmasını ve kullanıcıları korumak amacıyla oluşturulmasını sağlayan akıllı sözleşme denetim hizmeti.

  • CertiK(opens in a new tab) - Son teknoloji ürünü resmi Doğrulama teknolojisinin akıllı sözleşmelerde ve blokzincir ağlarında kullanımına öncülük eden blokzincir güvenlik şirketi.

  • Trail of Bits(opens in a new tab) - Riskleri azaltmak ve kodu güçlendirmek için güvenlik araştırmalarını saldırgan zihniyetiyle birleştiren siber güvenlik şirketi.

  • PeckShield(opens in a new tab) - Blokzincir ekosisteminin tamamının güvenliği, gizliliği ve kullanılabilirliği için ürünler ve hizmetler sunan blokzincir güvenlik şirketi.

  • QuantStamp(opens in a new tab) - Güvenlik ve risk değerlendirme hizmetleri aracılığıyla blokzincir teknolojisinin genel olarak benimsenmesini kolaylaştıran denetim hizmeti.

  • OpenZeppelin(opens in a new tab) - Dağıtılmış sistemler için güvenlik denetimleri sunan akıllı sözleşme güvenlik şirketi.

  • Runtime Verification(opens in a new tab) - Akıllı sözleşmelerin resmi modellenmesi ve doğrulanması üzerine uzmanlaşmış güvenlik şirketi.

  • Hacken(opens in a new tab) - Blokzincir güvenliğine 360 derece yaklaşımını getiren Web3 siber güvenlik denetimcisi.

  • Nethermind(opens in a new tab) - Ethereum ve Starknet üzerinde akıllı sözleşmelerin bütünlüğünü ve kullanıcıların güvenliğini güvence altına alan Solidity ve Cairo denetim hizmetleri.

  • HashEx(opens in a new tab) - HashEx, kripto paraların güvenliğini güvence altına almak için blokzincir ve akıllı sözleşme denetimlerine odaklanırken akıllı sözleşme geliştirme, penetrasyon testi ve blokzincir danışmanlığı gibi hizmetler de sunar.

  • Code4rena(opens in a new tab) - Akıllı sözleşme güvenlik uzmanlarına güvenlik açıklarını bulmaya ve web3'ü daha güvenli hale getirmeye yönelik teşvikler sunan rekabetçi denetim platformu.

Hata ödülü platformları

  • Immunefi(opens in a new tab) - Akıllı sözleşmeler ve DeFi projeleri için güvenlik araştırmacılarının kodu inceledikleri, güvenlik açıklarını bildirdikleri, ödeme aldıkları ve kriptoyu daha güvenli hale getirdikleri hata ödülü platformu.

  • HackerOne(opens in a new tab) - İşletmeler ile penetrasyon testi uzmanları ve siber güvenlik araştırmacılarını bir araya getiren güvenlik açığı koordinasyonu ve hata ödülü platformu.

  • HackenProof(opens in a new tab) - Kripto projeleri (DeFi, Akıllı Sözleşmeler, Cüzdanlar, CEX ve dahası) için güvenlik profesyonellerinin derecelendirme hizmetleri verdikleri ve araştırmacıların alakalı, doğrulanmış hata raporları için ödeme aldıkları uzman hata ödülü platformu.

Akıllı sözleşmelerle ilgili bilinen güvenlik açıklarına ve hatalarına ilişkin yayınlar

Akıllı sözleşme güvenliğini öğrenmeye yönelik güçlükler

Akıllı sözleşmeleri güvenli kılmaya yönelik en iyi uygulamalar

Akıllı sözleşme güvenliği üzerine öğreticiler

Bu makale yararlı oldu mu?