• Sonuç bulunamadı

Solidity Dili için Statik Analiz Aracı

N/A
N/A
Protected

Academic year: 2021

Share "Solidity Dili için Statik Analiz Aracı"

Copied!
12
0
0

Yükleniyor.... (view fulltext now)

Tam metin

(1)

Solidity Dili için Statik Analiz Aracı

Ahmet Gül ve Alper Şen

Boğaziçi Üniversitesi, Bilgisayar Mühendisliği Bölümü {ahmet.gul1,alper.sen}@boun.edu.tr

Özet. Günümüzde blokzinciri teknolojisi çözümleri yaygınlaşmaktadır. Bu çözümleri uygulamak için, Ethereum Sanal Makinesi üzerinde çalışan bir programlama dili olan Solidity kullanılarak geliştirilen akıllı sözleş-melerin, yaygınlaştırılmadan önce potansiyel hatalarının tespit edilmesi önem kazanmıştır. Statik analiz kaynak kod üzerinden, geliştirme sıra-sında hataların tespit edilmesinde kullanılan bir yöntemdir. Biz bu çalış-mada, akıllı sözleşmelerde yapılan temel kod yanlışlarını inceledik. Bun-ları kendi içlerinde gruplandırdık ve geliştiricilerin kodBun-larının kalitesini arttırabilmek için akıllı sözleşmelerdeki bu yaygın hataları tespit eden bir statik analiz aracı geliştirdik.

Anahtar Kelimeler: Ethereum, BlokZinciri, Solidity, Statik Analiz

Static Analysis Tool for Solidity Language

Ahmet Gül ve Alper Şen

Bogazici University, Department of Computer Engineering {ahmet.gul1,alper.sen}@boun.edu.tr

Abstract. Nowadays, blockchain technology solutions are becoming wi-despread. To apply these solutions, it becomes important to identify po-tential errors in smart contracts which are developed by using Solidity, a programming language running on the Ethereum Virtual Machine, be-fore these contracts are deployed. Static analysis is a method to detect errors on source code during the development. In this study, we exami-ned the common errors on smart contracts. We grouped them and we developed a static analysis tool to detect these common errors on smart contracts for developers to increase their code quality.

Keywords: Ethereum, BlockChain, Solidity, Static Analysis

(2)

1

Giriş

Blokzinciri, varlık işlemlerinin dijital olarak imzalanmış, sıralı, kriptografik ola-rak bağlanmış bloklarını içeren, fikir birliği modeliyle yönetilen merkezi olmayan bir veritabanıdır [1]. Başka bir deyişle, blokzinciri herkesin tam yetkili olup kim-senin tek yetkili olmadığı, otorite bulunmayan bir yapıdır. Herhangi bir kişi ya da kuruma güven duymama blokzincirinin özünü oluşturmaktadır.

Merkezsiz bir yapının sonucu olarak, blokzinciri platformları genellikle kimse-nin kontrol edemediği kripto para birimlerini oluşturmak için kullanılmaktadır. Örneğin; 2019 yılının haziran ayında en popüler kripto para birimlerinden olan Bitcoin 160.731.625.130 dolarlık bir market hacmine ulaştı [2].

Akıllı sözleşme, bir anlaşmanın şartlarını müzakare etmek için kurallarını saklayan, bu şartların otomatik olarak yerine getirildiğini doğrulayan ve daha sonra bu anlaşmayı gerçekleyen bir yazılım parçasıdır [3]. Blokzinciri teknolojisi güvenlik, dayanıklılık, sürerlik ve güvenilirlik özellikleri kapsamında değerlendi-rildiğinde, akıllı sözleşmelerin saklanması ve çalışması için en ideal ortamdır.

Ethereum, akıllı sözleşmelerin oluşturulması için özel olarak inşa edilmiş açık kaynaklı bir blokzinciri platformudur [4]. Akıllı sözleşmeler, Ethereum Sanal Ma-kinesi üzerinde çalışan değiştirilemez uygulamalar olarak tanımlanabilir [5]. De-ğiştirilemezlik tarafların sözleşmelerin şartlarını ve kodlarını hatalı dahi olsa ka-bul ettiklerini, bunların herhangi bir tarafça değiştirilemeyeceği anlamına gelir. Dijital varlıkları depolamaları ile meşhur blokzinciri platformları, üzerlerinde bulundurdukları akıllı sözleşmelerin açıkları ve hataları sebebiyle siber korsan-ları teşvik etmekte ve onlar tarafından sıklıkla hedef olarak seçilmektedirler. Bu sebepten dolayı, üzerinde herhangi bir hata barındırmayacak şekilde akıllı söz-leşmeler geliştirmek önem arz etmektedir. Örneğin, Haziran 2016’da popüler bir akıllı sözleşme olan DAO’dan 150 milyon dolar çalındı [6]. Blokzinciri üzerinde akıllı sözleşme geliştirecek kişilerin hata tespiti yapabilecek araçlara ihtiyaç duy-duğu açıktır.

Solidity, Ethereum Sanal Makinesi üzerinde akıllı sözleşmeler geliştirmek için oluşturulmuş bir programlama dilidir. Akıllı sözleşmeler Ethereum Sanal Maki-nesi üzerinde çalıştırılır ve bloklara dağıtılır. Akıllı sözleşmelerdeki açıklar, is-tenmeyen durumların önüne geçebilmek için statik ve dinamik analiz yöntemleri kullanılarak tespit edilebilir.

Statik analiz, bilgisayar programların çalıştırmadan kaynak kodlarını kulla-narak analiz etme işlemidir [7]. Öte yandan, dinamik program analizi ise prog-ramları gerçek ya da sanal bir işlemcide çalıştırmak suretiyle gerçekleştirilen bir yazılım analiz yöntemidir [8].

Bu çalışmada Solidity dili ile yazılmış akıllı sözleşmelerdeki potansiyel açık-ları tespit edebilmek için statik analiz yöntemini kullanan bir araç geliştirdik. Statik analiz yöntemini tercih etmedeki sebebimiz kodun tamamını kapsamayı garanti ettiği için bize olası tüm açık ve hataları gösterecek olmasıdır. Böylelikle aracımız ile yazılımcıların yazmış oldukları kodlardaki hataları, akıllı sözleşmeyi blokzincirine yaygınlaştırmadan önce tespit edebilmelerini hedefledik. Çalışma-mızın ikinci bölümünde çalışmaÇalışma-mızın daha iyi anlaşılabilmesi için Ethereum ve akıllı sözleşmeler ile Solidity hakkında genel bilgileri, daha sonra üçüncü

(3)

bölü-münde daha önce Ethereum ve Solidity’deki ataklar ve hataların tespiti hakkında yapılmış benzer çalışmaları, dördüncü bölümünde geliştirmiş olduğumuz aracın nasıl çalıştığını ve tespit edebildiği hataların neler olduğu hakkında bilgi verece-ğiz. Daha sonra beşinci bölümde ise örnek bir akıllı sözleşmedeki bazı hataları göstermek için vaka incelemesi yapacağız. Altıncı ve yedinci bölümlerde ise yap-mış olduğumuz deneyler ve gelecek çalışmalar hakkında bilgiler vereceğiz.

2

Temel Bilgiler

Blokzinciri verinin tek bir noktada saklanmadığı ve her paydaşta verinin ta-mamının bulunduğu bir yapıdır. İsteyen herkes paydaş olarak fikir birliği modeli doğrultusunda blokzincirine katılabilir. Blokzinciri bloklardan oluşur ve veri akışı tek yönlüdür. Blok içerisinde hash bilgisini, veriyi, işlemi ve zaman bilgisini bu-lunduran parçadır. Her bir blok eğer fikir birliği modeline göre uygunsa zincire eklenir ve bir daha değiştirilemez.

Ethereum bir bütün olarak ele alınacak olursa işlem tabanlı durum makinesi olarak görülebilir [9]. Bu platform üzerinde yapılan her bir operasyon için belirli bir gaz ücreti tanımlanmıştır. Bir başka deyişle, gaz ücreti operasyonun maliye-tini belirtmektedir [10]. Gaz ücreti, Ethereum blokzincirinin hayatta kalmasın-daki en önemli ögelerden biridir. Akıllı sözleşmeler madencilerin bilgisayarlarında çalışır ve burada yapılan her bir işlem için madenci o işlemin değeri kadar gaz kazanmış olur. Gaz ücreti, Ether cinsinden gerçek paraya çevrilebilmektedir.

Ethereum üzerinde iki farklı tür hesap bulunmaktadır [11]. Bunlardan birin-cisi, insanlar tarafından oluşturulabilen ve içinde Ether cinsinden paranın sak-landığı harici hesaplar, diğeri ise; akıllı sözleşmeler tanımlanırken oluşturulan sözleşme hesaplarıdır. Mevcutta Ethereum blokzincirinde 1.7 milyon tane akıllı sözleşme yani diğer bir deyişle 1.7 milyon hesap bulunmaktadır ve bunlardan beş yüz bini aktif durumdadır [12]. Her bir hesabın kendine özel bir genel-anahtarı bulunmaktadır. Hesap adresleri genel-anahtarlar olarak değerlendirebilir. İstem-ciler akıllı sözleşmelerle bu adresler aracılığıyla haberleşebilir.

Ethereum Sanal Makinesi için geliştirilmiş birden fazla dil bulunmaktadır. Solidity nesneye dayalı bir programlama dili olup akıllı sözleşme geliştirebilmek için oluşturulmuş en popüler dildir. Solidity geliştirilirken C++, JAVA ve Phy-ton dillerinden esinlenilmiştir [13]. Bu özelliğinden dolayı pek çok yazılımcı için öğrenmesi kolay bir dildir.

Akıllı sözleşmeler bloklar üzerinde çalışmaktadır. Solidity de blok bilgilerine erişebilecek değişkenleri üzerinde tutmaktadır. Örneğin; blok hash numarası, söz-leşme adres bilgisi, sözsöz-leşmeyi çağıran adres bilgisi, sözsöz-leşmeye gönderilen Ether miktarı, sözleşme hesabında bulunan Ether miktarı.

Akıllı sözleşmeler genel olarak birden çok fonksiyondan oluşmaktadır. Fonk-siyonlar akıllı sözleşmelerin dışarıya açılan kapılarıdır. İstemciler ve akıllı söz-leşmeler, ulaşmak istediği akıllı sözleşmeye üzerinde tanımlanan fonksiyonları çağırarak ulaşabilmektedirler. Solidity dili de akıllı sözleşmeler için fonksiyon geliştirmeyi desteklemektedir. Akıllı sözleşmelerdeki her bir fonksiyon çağırımı, bir işlem olarak değerlendirilmektedir.

(4)

3

İlgili Çalışmalar

Ethereum akıllı sözleşmelerindeki hata denetimi, aktif bir araştırma alanıdır. Wan ve diğerleri [14] block zinciri sistemlerindeki hata karakteristikleri hakkında bir çalışma yürüttüler. Bu çalışmalarında hataların blokzinciri sistemlerinin gü-venilirliğine zarar verdiğini ve hataların birbirlerine benzer özelliklere sahip ol-duğunu ortaya koydular. Atzei ve diğerleri [15] Ethereum akıllı sözleşmelerine yönelik saldırıları içeren bir çalışma yürüttüler. Bu çalışma, akıllı sözleşmelere zarar verilebilen yaygın yanlışları, hataları ve bunların sebep olabileceği sonuçları göstermektedir.

Araştırmaların çoğunluğu, Ethereum Sanal Makinesi byte kodlarını analiz eden araçlar geliştirmeyi amaçlamıştır. Örneğin, Luu ve diğerleri [16], Ethereum Sanal Makinesi byte kodundaki açıkları kontrol etmek için sembolik yürütmeye dayanan OYENTE aracını geliştirdi. Bu araç önce kontrol akış çizgesini sonra da bir takım sembolik izler oluşturur. Bu işlemlerden sonra ise bir kısıt çözümleyici izleri analiz etmektedir. Mythril [17] de Ethereum Sanal Makinesi byte kodlarını analiz eden, sembolik yürütmeye dayanan bir araçtır. OYENTE’den farklı ola-rak, Mythril analiz yaparken konkolik testi [18] kullanır. Fontein ve diğerleri [19], Mythril’in OYENTE’den daha fazla hata tespit edebileceğini gösterdi. Bu araç-lar, sözleşmelerin karmaşıklığının yüksek olması nedeniyle sözleşmelerdeki tüm yolları keşfetmeyi garanti edemeyip sadece bazı yolları keşfetmektedir.

Sembolik uygulama araçlarının dışında, akıllı sözleşmelerin güvenilirliğini arttırmak için geliştirilmiş statik analiz araçları da bulunmaktadır. Örneğin, Tsankov ve diğerleri [20] akıllı sözleşmelerin olası tüm davranışlarını keşfetmek için statik analiz aracı olan Securify’ı geliştirdi. Araç, güvenli olan ve güvenli ol-mayan davranışları sınıflandırma mantığına dayanmaktadır. Araç, sözleşmenin EVM bayt kodunu statik tek-atama formuna dönüştürür, ardından sözleşmelerle ilgili anlamsal gerçekleri ortaya çıkarır. Bu gerçeklere istinaden güvenlik kalıpla-rını kontrol ederek sözleşmelerin davranışlakalıpla-rının güvenli veya güvensiz olduğuna karar verir. Tikhomirov ve diğerleri [21] kaynak kodu ara bir gösterim formu olarak XML ayrıştırma ağacına çeviren ve bu ara gösterim formu üzerinde sor-gulamalar yaparak güvenlik açıklarını tespit eden başka bir statik analiz aracı olan SmartCheck’i geliştirdiler.

Güvenlik sorununa yol açmayan, ancak sözleşmelerdeki gaz tüketim maliye-tini artıran modeller bulma konusunda da çalışmalar yapılmıştır. Chen ve diğer-leri [22,23], akıllı sözleşmediğer-leri ve Ethereum Sanal Makinesi derleyicisini optimize etmek için gaz maliyetli modeller bulmayı önerdi.

4

Yöntem

Bu bölümde aracımızın nasıl çalıştığını ve ne tür hatalar bulmayı hedeflediğimizi açıklamaktayız.

Geliştirmiş olduğumuz araç bir statik analiz aracıdır ve Solidity kaynak kodu üzerinden çalışmaktadır. Şekil 1’de aracımızın akış çizelgesi görülmektedir. Soli-dity dili ile yazılmış olan akıllı sözleşme kaynak kodunu girdi değeri olarak alır.

(5)

Daha sonra bu kaynak kodu, Solidity dili için geliştirilmiş Antlr Parser [24] ara-cılığı ile JSON ağacına yerleştirir. Araç bu yerleştirme işleminden sonra JSON ağacını XML ağacına dönüştürür ve tanımlamış olduğumuz 53 farklı kuralı [25] XPath [26] sorguları ile ağaç üzerinde tarar. Araç eğer bu kurallardan herhangi birini bulursa, kullanıcıya bunu gösterir.

, Şekil 1. Program akış çizelgesi

Çalışmamız kapsamında 53 farklı kural tanımladık. Daha sonra bu kuralları kendi içlerinde dört farklı gruba ayırdık. Gruplama işlemi yaparken temel çıkış noktamız, tanımlanan bulgunun akıllı sözleşmeye ne oranda zarar verebilece-ğiydi. Kurallardan on bir tanesini 1. öncelikli yani akıllı sözleşmenin doğrudan saldırıya uğrayıp para kaybetmesine sebep olabilecek veya akıllı sözleşmede oluş-turulan kuralların çalışmamasına sebebiyet verecek açıklar olarak sınıflandırdık. Daha sonra kalan kurallardan sekiz tanesini ise 2. öncelikli yani akıllı sözleşmenin doğrudan saldırı yemesine sebep olmayacak fakat akıllı sözleşmenin efektif ça-lışmamasına sebebiyet verecek kod parçacıkların tespitini içeren kurallar olarak sınıflandırdık. Kalan kurallardan yirmi altı tanesini ise 3. öncelikli olarak grup-landırdık. 3. öncelikli kurallar genel olarak kötü kokan kodları tespit etmektedir. Bu kodlar akıllı sözleşmeye doğrudan bir zarar yaratan veya efektik çalışmayan kodlar değildir. Bu gruptaki hatalar genel olarak yazılımcının eski versiyon fonk-siyonlar ile iş yaptığını, güncel methodları kullanmadığı, kodun okunabilirliğini düşerecek ifadelerin kullanıldığını belirtir. En son kalan sekiz kuralı ise 4. ön-celikli olarak değerlendirdik. 4. önön-celikli kurallar Solidity dili için oluşturulmuş iyi yazılım örüntülerini içermektedir. Bu örüntülerin kullanılmaması yazılımcıya eksi bir değer katmamakla beraber; buradaki amacımız bu örüntüler tespit edi-lirse yazılımcıya doğru yolda olduğunu veya daha önceden onaylanmış ve bilinen bir çözüm kullandığını göstermektir.

Tablo 1’de, tanımlamış olduğumuz kuralların isimleri ve hangi öncelik katego-risine dahil edildiklerinin bilgisi bulunmaktadır.

5

Vaka İncelemesi

Çalışmamızın bu bölümünde aracımızın ne tarz hatalar tespit edebildiğini gös-termek için Recover [27] isimli akıllı sözleşmeyi örnek olarak inceledik. Bu akıllı

(6)

Tablo 1. Kural isimleri ve öncelik seviyeleri

Kural İsmi Kural Tanımı Öncelik Seviyesi Kural 1 Hatalı sıralanmış durum değiştirme sırası 1 Kural 2 Hatalı şekilde sayı bölme işlemi 1 Kural 3 Sayı taşma problemi 1 Kural 4 Payable fonksiyona karşılık payable

fallback fonksiyonun bulunmaması 1 Kural 5 Zaman bilgisi kullanımı 1 Kural 6 Kilitli para durumu 1 Kural 7 Keccak ve Sha3 içerisinde

tahmin edilebilir değer kullanımı 1 Kural 8 Hatalı fallback fonksiyon kullanımı 1 Kural 9 Kısıtlı yazım kuralı 1 Kural 10 Kısıtlı transfer kuralı 1 Kural 11 İş sıralama bağımlılığı 1 Kural 12 Boş döngü kullanımı 2 Kural 13 Koda gömülmüş adres değeri 2 Kural 14 Constant anahtar kelimeli fonksiyon kullanımı 2 Kural 15 Atomik olmayan iş tanımlanması 2 Kural 16 Dizi büyüklüğüne erişim 2 Kural 17 Storage ilişkili döngü 2 Kural 18 Sabit aralıklı döngü 2

Kural 19 Döngü tekrarı 2

Kural 20 Değişken veya fonksiyon

görünürlüğünün private yapılması 3 Kural 21 Harici library kullanımı 3 Kural 22 Hatalı view fonksiyon tanımı 3 Kural 23 Sabit derleyici seçmeme problemi 3 Kural 24 Döngüde bayrak kullanımı 3 Kural 25 Send ifadesinin kullanımı 3 Kural 26 Transfer,send veya call ifadelerinin

döngü içerisinde kullanımı 2 Kural 27 tx.origin kullanımı 3

Kural 28 throw kullanımı 3

Kural 29 suicide kullanımı 3

Kural 30 Hatalı string kontrolü 3

Kural 31 Boş if kullanımı 3

Kural 32 Hatalı şekilde dizi temizleme işlemi 3 Kural 33 sha3 ile hashleme problemi 3 Kural 34 Transfer ve TransferFrom

fonksiyonlarının dönüş değeri 3 Kural 35 Değişken veya fonksiyon

görünürlüğünün tanımlanmaması 3 Kural 36 approval fonksiyonu kullanımı 3 Kural 37 Belirsiz değişken türü kullanımı 3 Kural 38 Fonksiyon içerisinde revert kullanımı 3 Kural 39 Hatalı pure fonksiyon tanımı 3 Kural 40 Gereksiz return kullanımı 3 Kural 41 Gereksiz view fonksiyon kullanımı 3 Kural 42 assembly kullanımı 3 Kural 43 Çoklu kalıtım uyarısı 3 Kural 44 Gölge değer kullanımı 3 Kural 45 Gereksiz miras tespiti 3 Kural 46 Karşılıklı dışlama nesnesi (Mutex) paterni 4 Kural 47 İşlem sayacı paterni 4 Kural 48 Kontrol etkisi etkileşim paterni 4 Kural 49 Devre kesici patern 4 Kural 50 Bakiye limit kontrol paterni 4

Kural 51 Ölümcül patern 4

Kural 52 Hız kontrol paterni 4

(7)

sözleşme 774 satırdan oluşmaktadır. Fakat yalnızca bazı hataları inceleyeceğimiz için belirli kod parçacıklarını göstereceğiz.

Şekil 2’deki kod parçacağı Revocer akıllı sözleşmesinden alınmıştır. Bu kod parçacığında döngü içerisinde dizinin boyutuna .length ile erişim olduğu için fazladan gaz tüketimi olacaktır. Bunun sebebi döngünün her bir iterasyonunda .length kullanımından dolayı storage değişkenine yani bir sözleşme değişkenine erişim yapmasıdır. Daha sonra döngü içinde ise lokal değişkenler ile işlem yapılır. Bunun anlamı sözleşme değişkeni döngünün her iterasyonunda lokale kopyalana-cak ve bu işlem için her seferinde fazladan gaz harcanmış olakopyalana-caktır. Bu yüzden aracımız tarafından 2. öncelikli olan Kural 16 dizi büyüklüğüne erişim tespit edilmiştir.

c o n t r a c t R e c o v e r is I A r b i t r a b l e { s t r u c t C l a i m {

b y t e s 3 2 i t e m I D ; // R e l a t i o n one - to - one w i t h the i t e m . a d d r e s s f i n d e r ; // A d d r e s s of the i t e m f i n d e r . u i n t f i n d e r F e e ; // T o t a l f e e s p a i d by the f i n d e r . S t a t u s s t a t u s ; /* S t a t u s of the c l a i m r e l a t i v e to a d i s p u t e .*/ ... } C l a i m [] p u b l i c c l a i m s ; // C o l l e c t i o n of the c l a i m s . . . . . f u n c t i o n g e t C l a i m I D s B y A d d r e s s ( a d d r e s s _ f i n d e r ) p u b l i c v ie w r e t u r n s ( u i n t [] c l a i m I D s ) { u i n t c o u n t = 0; for ( u i n t i = 0; i < c l a i m s . l e n g t h ; i ++) { if ( c l a i m s [ i ]. f i n d e r == _ f i n d e r ) c o u n t ++; } ... } ... }

Şekil 2. Recover Akıllı Sözleşmesi’nden kod parçacığı

Burada fazladan gaz tüketimini engellemek için sözleşme değişkenindeki de-ğer lokal bir değişkene atanmalı ve döngü bu lokal değişken üzerinden çalışma-lıdır. Böylelikle sözleşme değişkeni lokale yalnızca bir kere alınacak ve fazladan gaz tüketiminin önüne geçilecektir. Şekil 3’te kod parçacığının düzeltilmiş hali bulunmaktadır. f u n c t i o n g e t C l a i m I D s B y A d d r e s s ( a d d r e s s _ f i n d e r ) p u b l i c v ie w r e t u r n s ( u i n t [] c l a i m I D s ) { u i n t c o u n t = 0; u i n t l o c a l V a r i a b l e = c l a i m s . l e n g t h ; for ( u i n t i = 0; i < l o c a l V a r i a b l e ; i ++) { if ( c l a i m s [ i ]. f i n d e r == _ f i n d e r ) c o u n t ++;

(8)

} ... }

Şekil 3. Recover Akıllı Sözleşmesi’nde düzeltilmiş kod parçacığı Bu sözleşmede aracımız tarafından tespit edilen bir diğer durum ise 3. önce-likli olan Kural 40 gereksiz return kullanımı durumudur. Kod parçacığı üzerinden de görülebileceği üzere getClaimIDsByAddress fonksiyonunun üzerine returns ifadesi uint tipinde bir dizi döndürebilecek şekilde bir tanım yapılmıştır. Fakat Şekil 2’deki kod incelendiğinde herhangi bir değer döndürmediği görülmektedir. Yazılımcı burada ya returns ifadesini kaldırmalı ya da claims değişkenini return ile döndürmelidir. Yazılımcı eğer bu kullanımdan vazgeçmezse, akıllı sözleşme-deki bu fonksiyonu çağıracak bir sözleşme ya da istemci, kendi tarafında değer karşılayacak şekilde bir kod yazacak ve akıllı sözleşmeden değer dönmeyeceği için hataya düşmüş olacaktır.

Yine aynı akıllı sözleşmede bulunan Şekil 4’te bulunan farklı bir kod par-çacağında ise 1. öncelikli olan Kural 2 hatalı şekilde sayı bölme işlemi durumu tespit edilmiştir. Burada bölme işlemi yapılırken SafeMath kütüphanesi kulla-nılmadığı için sayı taşma problemi yaşanabilir. Bununla beraber toplama işlemi sırasında da SafeMath kütüphanesi kullanılmadığı için sayı taşma problemi ha-tası yaşanma olasılığı fazladır. Her türlü matematiksel işlem yapılırken SafeMath kütüphanesini önermemizin sebebi Solidity’de tanımlanabilecek en büyük sayı ve en küçük sayı limitleri olan 2256 ve −2256’nın kolaylıkla aşılabilmesinden dolayı akıllı sözleşmelerin hata alabilmesidir. SafeMath kütüphanesi ise bu tarz hataları kendi içinde yakalar ve programın güvenilirliğini tehlikeye atmaz.

if ( _ r u l i n g == u i n t ( R u l i n g O p t i o n s . O w n e r W i n s ) ) { i t e m . o w n e r . s e n d ( i t e m . o w n e r F e e + i t e m . a m o u n t L o c k e d ) ; } e l s e if ( _ r u l i n g == u i n t ( R u l i n g O p t i o n s . F i n d e r W i n s ) ) { i t e m C l a i m . f i n d e r . s e n d ( i t e m C l a i m . f i n d e r F e e + i t e m . a m o u n t L o c k e d ) ; } e l s e { u i n t s p l i t _ a m o u n t = ( i t em . o w n e r F e e + i t e m . a m o u n t L o c k e d ) / 2; i t e m . o w n e r . s e n d ( s p l i t _ a m o u n t ) ; i t e m C l a i m . f i n d e r . s e n d ( s p l i t _ a m o u n t ) ; }

Şekil 4. Taşma problemine sebebiyet verebilecek kod parçacığı Örnek bir SafeMath [28] kütüphanesi kodu Şekil 5’te bulunmaktadır. l i b r a r y S a f e M a t h {

f u n c t i o n mul ( u i n t 2 5 6 a , u i n t 2 5 6 b ) i n t e r n a l p u r e r e t u r n s ( u i n t 2 5 6 ) {

(9)

r e t u r n 0; } u i n t 2 5 6 c = a * b ; r e q u i r e ( c / a == b ) ; r e t u r n c ; } f u n c t i o n div ( u i n t 2 5 6 a , u i n t 2 5 6 b ) i n t e r n a l p u r e r e t u r n s ( u i n t 2 5 6 ) { r e q u i r e ( b > 0) ; u i n t 2 5 6 c = a / b ; r e t u r n c ; } f u n c t i o n sub ( u i n t 2 5 6 a , u i n t 2 5 6 b ) i n t e r n a l p u r e r e t u r n s ( u i n t 2 5 6 ) { r e q u i r e ( b <= a ) ; u i n t 2 5 6 c = a - b ; r e t u r n c ; } f u n c t i o n add ( u i n t 2 5 6 a , u i n t 2 5 6 b ) i n t e r n a l p u r e r e t u r n s ( u i n t 2 5 6 ) { u i n t 2 5 6 c = a + b ; r e q u i r e ( c >= a ) ; r e t u r n c ; } }

Şekil 5. Örnek bir SafeMath Kütüphanesi kodu

Şekil 2’deki kod parçacığında 3. öncelikli olan Kural 25 send fonksiyonun kullanımı sıkıntısı da tespit edilmiştir. Burada send yerine daha güvenli olan transfer fonksiyonu kullanılmalıdır. Bunu önermemizin sebebi transfer fonksi-yonu eğer işlem hata alırsa throw ile hatayı fırlatmakta ve güvenli bir şekilde işlemi bitirmektedir. send fonksiyonu ise hata alırsa false dönmektedir. Bu du-rum send kullanıldığı zaman hatanın yazılımcı tarafından işlenmesi gereksinimi doğurur. Bununla beraber, yazılımcı hata işlemeyi sağlayacak bir geliştirme yap-mazsa akıllı sözleşme hata alacaktır.

Şekil 6’da kod parçacığının düzeltilmiş hali bulunmaktadır. if ( _ r u l i n g == u i n t ( R u l i n g O p t i o n s . O w n e r W i n s ) ) {

u i n t 2 5 6 t o t a l A m o u n t = i t e m . o w n e r F e e . add ( i t e m . a m o u n t L o c k e d ) ;

i t e m . o w n e r . s e n d ( t o t a l A m o u n t ) ;

(10)

{ u i n t 2 5 6 t o t a l A m o u n t 2 = i t e m C l a i m . f i n d e r F e e . add ( i t e m . a m o u n t L o c k e d ) ; i t e m C l a i m . f i n d e r . s e n d ( t o t a l A m o u n t 2 ) ; } e l s e { u i n t s p l i t _ a m o u n t = ( i t em . o w n e r F e e . add ( i t e m . a m o u n t L o c k e d ) ) . div (2) ; i t e m . o w n e r . s e n d ( s p l i t _ a m o u n t ) ; i t e m C l a i m . f i n d e r . s e n d ( s p l i t _ a m o u n t ) ; }

Şekil 6. SafeMath Kütüphanesi kullanılarak düzeltilmiş bir kod parçacığı Geliştirmiş olduğumuz araç kodların içeriği üzerinde herhangi bir değişik-lik yapmamaktadır. Araç yalnızca bulguları sunmakta olup, kodları değiştirme işlemi yazılımcıdan beklenmektedir.

6

Deneyler

Etherscan [29] Ethereum blokzinciri üzerindeki blokların, işlem hareketlerinin, akıllı sözleşmelerin ve hesapların bilgisini görüntüleyebileceğiniz bir platformdur. Bu platform üzerinde Solidity kaynak kodu açık olarak paylaşılmış, Ethereum blokzinciri üzerinde çalışan, hesabında en çok Ether’e sahip 5 akıllı sözleşmeyi kendi aracımız ile inceledik. İnceleme sonucun tespit edilen hataların önceliği ve tespit edilen bulgu sayısı sözleşmelerin isimleri ile beraber Tablo 2’dedir.

Tablo 2. Akıllı sözleşme isimleri ve öncelik bazlı bulgu sayıları Akıllı Sözleşme Adresi Öncelik 1 Öncelik 2 Öncelik 3 Öncelik 4

WETH9 0 0 1 0

DigixDAO: MultiSigWallet 0 5 22 0

Golem: MultiSigWallet 0 7 32 0

MultiSigWalletWithDailyLimit 3 15 15 0

Wallet 10 22 25 0

Tablo 2’de görülebileceği üzere dünya üzerinde en yüksek mevduata sahip akıllı sözleşmelerde dahi efektif olmayan, kötü örnek oluşturulabilecek kodlar bulunmaktadır. Tabloda belirtilen akıllı sözleşmeler içerisinde en yüksek meb-lağa sahip olan WETH9 [30] sözleşmelesi hariç hepsinde efektif olmayan şekilde gaz tüketimine sebep olabilecek kodlar tespit edilmiştir. DigixDAO MultiSigWal-let [31] ve Golem MultisigWalMultiSigWal-let [32] akıllı sözleşmeleri 1.öncelikte açık bulun-durmamalarına rağmen yazılımcıları hataya sürükleyebilecek kötü kokan kodlar ve fazla gaz tüketimine sebep olabilecek kodlar barındırmaktadırlar. MultiSig-WalletWithDailyLimit [33] ve Wallet [34] akıllı sözleşmeleri ise 1. öncelikli açıklar bulundurmaktadır. Tespit edilen 1. öncelikli açıklar; tahmin edilebilir değerler-den olan zaman bilgisine bağımlı kod yazımını anlatan Kural 5 zaman bilgisi

(11)

kullanımı ve akıllı sözleşmenin yalnızca Ether alıp, dışarıdaki herhangi bir he-saba aktaramayacağını ve bu sebepten sözleşmede bulunan Etherlerin içeride kilitli kalacağını anlatan Kural 6 kilitli para durumudur. İncelenen bu beş akıllı sözleşmede 4.öncelik olarak tanımladığımız herhangi bir iyi yazılım deseni tespit edilememiştir. Sözleşmeler bazı bulguları birden fazla kere barındırmaktadır.

7

Sonuçlar ve Gelecek Çalışmalar

Ethereum blokzinciri üzerinde geliştirilen akıllı sözleşmelerin sayısı her geçen gün artmaktadır. Bununla beraber akıllı sözleşmeler gündelik hayatımıza girdikçe So-lidity dilini öğrenmesi gereken kişi sayısı da artacak ve bu dil ile ilgili araçlara ihtiyaçlar artacaktır. Geliştirmiş olduğumuz statik analiz aracı ile yazılımcılara kodlarında olabilecek potansiyel açıkları göstermeyi hedefledik. Daha ileriki ça-lışmalarda kullanıcı sayısının artması ve buna istinaden dilde olacak gelişmeler kapsamında yeni kuralların eklenmesi, statik analiz yöntemi ile bulunamayacak açıkların dinamik analiz yöntemleri ile yakalanması konusunda çalışmalar yürü-tülmesi hedeflenmiştir.

Kaynakça

1. Sultan, K., Ruhi, U., Lakhani, R.: Conceptualizing Blockchains: Characteristics Applications. In 11th IADIS International Conference on Information Systems (2018)

2. "CoinMarketCap” , https://coinmarketcap.com/, accessed: 2019-06-19

3. Migliorini, S.: Enhancing Blockchain Smart-Contracts with Proof-of-Location. In 10th International Conference on Geographic Information Science (2018)

4. Buterin, V.: Ethereum: a next generation smart contract and decentralized appli-cation platform. https://github.com/ethereum/wiki/wiki/White-Paper (2013) 5. Antonopoulos, A.M., Wood, G.: Masterin Ethereum. O’Reilly Media, 2018 6. “DAO Contract”, https://bit.ly/2x8LNYB, accessed: 2018-10-04

7. J. Zheng, L. Williams, N. Nagappan, W. Snipes, J. P. Hudepohl, and M. A. Vouk, On the value of static analysis for fault detection in software. IEEE Trans. on Software Engineering, vol. 32, no. 4, pp. 240–253, 2006.

8. Ball, T.: The concept of dynamic analysis. In: Wang, J., Lemoine, M. (eds.) ESEC 1999 and ESEC-FSE 1999. LNCS, vol. 1687, p. 216. Springer, Heidelberg (1999) 9. Wood, G. Ethereum: A secure decentralised generalised transaction ledger, 2014. 10. Dannen, C. Introducing Ethereum and Solidity, 2017.

11. "Accounts", https://solidity.readthedocs.io/en/v0.5.7/introduction-to-smart-contracts.html#blockchain-basics, accessed: 2019-06-06

12. "Ecosystem Highlights", https://medium.com/@vikati/ranking-ethereum-smart-contracts-a27e6f622ac6, accessed: 2019-06-06

13. "Solidity", https://solidity.readthedocs.io/en/v0.5.7, accessed: 2019-06-06 14. Wan Z., Lo D., Xia X., Cai L. (2017) Bug Characteristics in Blockchain Systems:

A Large-Scale Empirical Study. In IEEE/ACM 14th International Conference on Mining Software Repositories (MSR)

15. Atzei, N., Bartoletti, M. And Cimoli, T.: A Survey of Attacks on Ethereum Smart Contracts SoK. In 6th International Conference on Principles of Security and Trust (2017)

(12)

16. Luu, L., Chu, D.H., Olickel, H., Saxena, P., Hobor, A.: Making smart contracts smarter. In: ACM SIGSAC Conference on Computer and Communications Security (2016)

17. Mueller, B. “Mythril - Reversing and bug hunting framework for the Ethereum blockchain.” [Online]. Available: https://github.com/bmueller/mythril/

18. K. Sen. Concolic testing. In Automated Software Engineering, pages 571–572, 2007. 19. Fontein, R.: “Comparison of static analysis tooling for smart contracts on the

EVM”. (2018) Available from: https://telluur.com/utwente/Module

20. Tsankov, P., Dan, A., Cohen, D.D., Gervais, A., Buenzli, F., Vechev, M.: Securify: Practical Security Analysis of Smart Contracts. In ACM SIGSAC Conference on Computer and Communications Security (2018)

21. Tikhomirov, S., Voskresenskaya, E., Ivanitskiy I., Takheviv R., Marchenko E., Ale-xandrov, Y.: SmartCheck: Static Analysis of Ethereum Smart Contracts. In: IEE-E/ACM 1st International Workshop on Emerging Trends in Software Engineering for Blockchain (WETSEB) (2018)

22. Chen T., Li X., Zhang X.: “Under-Optimized Smart Contracts Devour Your Mo-ney” In: IEEE 24th International Conference on Software Analysis, Evolution and Reengineering (SANER) (2017)

23. Chen T., Li Z., Zhao H., Chen J., Lio X., Li X., Zhang X.: Towards Saving Money in Using Ethereum Smart Contracts. In: ACM/IEEE 40th International Conference on Software Engineering: New Ideas and Emerging Results (2018)

24. "Solidity Antlr Parser" , https://github.com/federicobond/solidity-parser-antlr, accessed: 2018-07-01

25. "Kural Açıklamaları", https://github.com/ahmetgul93/Solidity-Static-Analyzer-Rule-Base, accessed: 2019-06-20

26. "XPath" , https://www.w3.org/TR/1999/REC-xpath-19991116/, accessed: 2019-06-06

27. "Recover", https://bit.ly/2x8qqqb, accessed: 2019-06-08

28. "SafeMath" , https://ethereumdev.io/safemath-protect-overflows/ , accessed: 2019-06-08

29. "Etherscan", https://etherscan.io/accounts, accessed: 2019-06-08 30. "WETH9 Contract", https://bit.ly/2KBPAqb, accessed: 2019-06-08

31. "DigixDAO: MultiSigWallet Contract", https://bit.ly/2RwDRK6, accessed: 2019-06-08

32. "Golem: MultiSigWallet Contract", https://bit.ly/2ht0kpz, accessed: 2019-06-08 33. "MultiSigWalletWithDailyLimit Contract", https://bit.ly/2xe7Tsw, accessed:

2019-06-08

Şekil

Tablo 1. Kural isimleri ve öncelik seviyeleri
Şekil 2. Recover Akıllı Sözleşmesi’nden kod parçacığı
Şekil 3. Recover Akıllı Sözleşmesi’nde düzeltilmiş kod parçacığı Bu sözleşmede aracımız tarafından tespit edilen bir diğer durum ise 3
Şekil 5. Örnek bir SafeMath Kütüphanesi kodu
+2

Referanslar

Benzer Belgeler

Sahip olunun bu algoritmik düşünce tarzı ile problemler için geliştirilen çözümleri, gerektiğinde temel programlama yapılarını kullanarak akış diyagramları

Kızgınlık ve öfke gibi olumsuz duyguları karşı tarafa aktarmak isterken sen dili kullanımı ile karşı tarafı suçlayıcı bir tavır takınılırken ben dili

Avusturya Ticaret Ofisi olarak sizi 03-04.11.2020 tarihlerinde etkinlik ortağımız DEIK ile birlikte sanal olarak organize ettiğimiz Virtual Smart City Showcase Austria &amp;

Karakter değişkenler için değişken isminden sonra ( $ ) belirteci konur ve karakter tırnak (“ “ ) içinde yazılır.. Kendinden sonra gelen bilginin ilk karakteri x’inci

Araştırma sonuçları incelendiğinde Alice programının programlama dili öğreniminde sağladığı yararlar ile ilgili öğrenciler en çok; kod mantığını

Bu çalışmada, çapa makinesi bıçağı üzerine uygulanan 5 farklı yük altında meydana gelen gerilme ve deformasyonlar AnsysWorkbench programı kullanılarak

6.2. Giriş:    Göstericiler (pointers) bellekte bulunan bir yerin adresini saklayan bir değişkendir (adres türünde  bir  değişkendir).  Gösterici  de  int, 

Sonuç olarak denilebi- lir ki Python, öğrenilmesi ve kullanılması kolay, neredeyse her iş için bir kütüphanesi olan güçlü bir programlama