Akıllı sözleşmeleri yükseltme
Ethereum üzerindeki akıllı sözleşmeler, Ethereum Sanal Makinesi'nde (EVM) çalışan kendi kendini yürüten programlardır. Bu programlar tasarımları gereği değişmezdir, bu da sözleşme dağıtıldıktan sonra iş mantığında herhangi bir güncelleme yapılmasını engeller.
Değişmezlik, akıllı sözleşmelerin güven gereksinimsizliği, merkeziyetsizliği ve güvenliği için gerekli olsa da, bazı durumlarda bir dezavantaj olabilir. Örneğin, değişmez kod, geliştiricilerin savunmasız sözleşmeleri düzeltmesini imkansız hale getirebilir.
Ancak, akıllı sözleşmeleri iyileştirmeye yönelik artan araştırmalar, çeşitli yükseltme modellerinin tanıtılmasına yol açmıştır. Bu yükseltme modelleri, geliştiricilerin iş mantığını farklı sözleşmelere yerleştirerek akıllı sözleşmeleri (değişmezliği korurken) yükseltmelerini sağlar.
Ön koşullar
Akıllı sözleşmeler, akıllı sözleşme anatomisi ve Ethereum Sanal Makinesi (EVM) hakkında iyi bir anlayışa sahip olmalısınız. Bu kılavuz ayrıca okuyucuların akıllı sözleşme programlamayı kavradığını varsaymaktadır.
Akıllı sözleşme yükseltmesi nedir?
Bir akıllı sözleşme yükseltmesi, sözleşmenin durumunu korurken bir akıllı sözleşmenin iş mantığını değiştirmeyi içerir. Özellikle akıllı sözleşmeler bağlamında yükseltilebilirliğin ve değişebilirliğin aynı şey olmadığını açıklığa kavuşturmak önemlidir.
Ethereum ağındaki bir adrese dağıtılmış bir programı hâlâ değiştiremezsiniz. Ancak kullanıcılar bir akıllı sözleşme ile etkileşime girdiğinde yürütülen kodu değiştirebilirsiniz.
Bu, aşağıdaki yöntemlerle yapılabilir:
-
Bir akıllı sözleşmenin birden fazla sürümünü oluşturmak ve durumu (yani verileri) eski sözleşmeden sözleşmenin yeni bir örneğine taşımak.
-
İş mantığını ve durumu depolamak için ayrı sözleşmeler oluşturmak.
-
Fonksiyon çağrılarını değişmez bir vekil kontrattan değiştirilebilir bir mantık sözleşmesine devretmek için vekil (proxy) modelleri kullanmak.
-
Belirli fonksiyonları yürütmek için esnek uydu sözleşmelerle arayüz oluşturan ve bunlara dayanan değişmez bir ana sözleşme oluşturmak.
-
Fonksiyon çağrılarını bir vekil kontrattan mantık sözleşmelerine devretmek için elmas (diamond) modelini kullanmak.
Yükseltme mekanizması #1: Sözleşme taşıma
Sözleşme taşıma, aynı yazılımın benzersiz durumlarını oluşturma ve yönetme fikri olan sürüm oluşturmaya dayanır. Sözleşme taşıma, mevcut bir akıllı sözleşmenin yeni bir örneğini dağıtmayı ve depolamayı ve bakiyeleri yeni sözleşmeye aktarmayı içerir.
Yeni dağıtılan sözleşme boş bir depolamaya sahip olacak, bu da eski sözleşmeden verileri kurtarmanıza ve yeni uygulamaya yazmanıza olanak tanıyacaktır. Daha sonra, yeni adresi yansıtması için eski sözleşmeyle etkileşime giren tüm sözleşmeleri güncellemeniz gerekecektir.
Sözleşme taşımadaki son adım, kullanıcıları yeni sözleşmeyi kullanmaya geçmeye ikna etmektir. Yeni sözleşme sürümü, değişmezliği koruyan kullanıcı bakiyelerini ve adreslerini muhafaza edecektir. Eğer bu Token tabanlı bir sözleşmeyse, eski sözleşmeyi atıp yeni sözleşmeyi kullanmaları için borsalarla da iletişime geçmeniz gerekecektir.
Sözleşme taşıma, kullanıcı etkileşimlerini bozmadan akıllı sözleşmeleri yükseltmek için nispeten basit ve güvenli bir önlemdir. Ancak, kullanıcı depolamasını ve bakiyelerini yeni sözleşmeye manuel olarak taşımak zaman alıcıdır ve yüksek Gaz maliyetlerine neden olabilir.
Sözleşme taşıma hakkında daha fazlası. (opens in a new tab)
Yükseltme mekanizması #2: Veri ayrımı
Akıllı sözleşmeleri yükseltmenin bir başka yöntemi de iş mantığını ve veri depolamayı ayrı sözleşmelere ayırmaktır. Bu, veriler depolama sözleşmesinde saklanırken kullanıcıların mantık sözleşmesiyle etkileşime girdiği anlamına gelir.
Mantık sözleşmesi, kullanıcılar uygulamayla etkileşime girdiğinde yürütülen kodu içerir. Ayrıca depolama sözleşmesinin adresini tutar ve veri almak ve ayarlamak için onunla etkileşime girer.
Bu arada, depolama sözleşmesi, kullanıcı bakiyeleri ve adresleri gibi akıllı sözleşmeyle ilişkili durumu tutar. Depolama sözleşmesinin mantık sözleşmesine ait olduğunu ve dağıtım sırasında ikincisinin adresiyle yapılandırıldığını unutmayın. Bu, yetkisiz sözleşmelerin depolama sözleşmesini çağırmasını veya verilerini güncellemesini engeller.
Varsayılan olarak, depolama sözleşmesi değişmezdir; ancak işaret ettiği mantık sözleşmesini yeni bir uygulamayla değiştirebilirsiniz. Bu, depolamayı ve bakiyeleri sağlam tutarken EVM'de çalışan kodu değiştirecektir.
Bu yükseltme yöntemini kullanmak, depolama sözleşmesindeki mantık sözleşmesinin adresini güncellemeyi gerektirir. Daha önce açıklanan nedenlerden dolayı yeni mantık sözleşmesini de depolama sözleşmesinin adresiyle yapılandırmalısınız.
Veri ayrımı modelinin uygulanması, sözleşme taşımaya kıyasla tartışmasız daha kolaydır. Ancak, akıllı sözleşmeleri kötü niyetli yükseltmelerden korumak için birden fazla sözleşmeyi yönetmeniz ve karmaşık yetkilendirme şemaları uygulamanız gerekecektir.
Yükseltme mekanizması #3: Vekil (Proxy) modelleri
Vekil modeli de iş mantığını ve verileri ayrı sözleşmelerde tutmak için veri ayrımını kullanır. Ancak, bir vekil modelinde, depolama sözleşmesi (vekil olarak adlandırılır) kod yürütme sırasında mantık sözleşmesini çağırır. Bu, mantık sözleşmesinin depolama sözleşmesini çağırdığı veri ayrımı yönteminin tersidir.
Bir vekil modelinde şu olaylar gerçekleşir:
-
Kullanıcılar, verileri depolayan ancak iş mantığını barındırmayan vekil kontrat ile etkileşime girer.
-
Vekil kontrat, mantık sözleşmesinin adresini depolar ve
delegatecallfonksiyonunu kullanarak tüm fonksiyon çağrılarını (iş mantığını barındıran) mantık sözleşmesine devreder. -
Çağrı mantık sözleşmesine iletildikten sonra, mantık sözleşmesinden dönen veriler alınır ve kullanıcıya döndürülür.
Vekil modellerini kullanmak, delegatecall fonksiyonunun anlaşılmasını gerektirir. Temel olarak, delegatecall, bir sözleşmenin başka bir sözleşmeyi çağırmasına izin veren bir işlem kodudur, asıl kod yürütmesi ise çağıran sözleşmenin bağlamında gerçekleşir. Vekil modellerinde delegatecall kullanmanın bir sonucu, vekil kontratın kendi depolamasına okuma ve yazma yapması ve mantık sözleşmesinde depolanan mantığı sanki dahili bir fonksiyon çağırıyormuş gibi yürütmesidir.
Solidity belgelerinden (opens in a new tab):
Hedef adresteki kodun çağıran sözleşmenin bağlamında (yani adresinde) yürütülmesi ve
msg.senderilemsg.valuedeğerlerinin değişmemesi dışında bir mesaj çağrısıyla aynı olan delegatecall adında özel bir mesaj çağrısı varyantı vardır. Bu, bir sözleşmenin çalışma zamanında farklı bir adresten dinamik olarak kod yükleyebileceği anlamına gelir. Depolama, mevcut adres ve bakiye hâlâ çağıran sözleşmeye atıfta bulunur, yalnızca kod çağrılan adresten alınır.
Vekil kontrat, içine yerleşik bir fallback fonksiyonu olduğu için bir kullanıcı bir fonksiyonu her çağırdığında delegatecall'u başlatmayı bilir. Solidity programlamada, bir fonksiyon çağrısı bir sözleşmede belirtilen fonksiyonlarla eşleşmediğinde geri dönüş fonksiyonu (opens in a new tab) yürütülür.
Vekil modelinin çalışmasını sağlamak, vekil kontratın desteklemediği fonksiyon çağrılarını nasıl ele alması gerektiğini belirten özel bir geri dönüş fonksiyonu yazmayı gerektirir. Bu durumda vekilin geri dönüş fonksiyonu, bir delegatecall başlatmak ve kullanıcının isteğini mevcut mantık sözleşmesi uygulamasına yeniden yönlendirmek üzere programlanmıştır.
Vekil kontrat varsayılan olarak değişmezdir, ancak güncellenmiş iş mantığına sahip yeni mantık sözleşmeleri oluşturulabilir. Yükseltmeyi gerçekleştirmek, vekil kontratta referans verilen mantık sözleşmesinin adresini değiştirmekten ibarettir.
Vekil kontratı yeni bir mantık sözleşmesine işaret ederek, kullanıcılar vekil kontrat fonksiyonunu çağırdığında yürütülen kod değişir. Bu, kullanıcılardan yeni bir sözleşmeyle etkileşime girmelerini istemeden bir sözleşmenin mantığını yükseltmemize olanak tanır.
Vekil modelleri, sözleşme taşımayla ilişkili zorlukları ortadan kaldırdıkları için akıllı sözleşmeleri yükseltmek için popüler bir yöntemdir. Ancak, vekil modellerinin kullanımı daha karmaşıktır ve yanlış kullanıldığında fonksiyon seçici çakışmaları (opens in a new tab) gibi kritik kusurlara yol açabilir.
Vekil modelleri hakkında daha fazlası (opens in a new tab).
Yükseltme mekanizması #4: Strateji modeli
Bu teknik, belirli özellikleri uygulamak için diğer programlarla arayüz oluşturan yazılım programları oluşturmayı teşvik eden strateji modelinden (opens in a new tab) etkilenmiştir. Strateji modelini Ethereum geliştirmeye uygulamak, diğer sözleşmelerden fonksiyonlar çağıran bir akıllı sözleşme oluşturmak anlamına gelir.
Bu durumdaki ana sözleşme, temel iş mantığını içerir, ancak belirli fonksiyonları yürütmek için diğer akıllı sözleşmelerle ("uydu sözleşmeler") arayüz oluşturur. Bu ana sözleşme ayrıca her uydu sözleşmesi için adresi depolar ve uydu sözleşmesinin farklı uygulamaları arasında geçiş yapabilir.
Yeni bir uydu sözleşmesi oluşturabilir ve ana sözleşmeyi yeni adresle yapılandırabilirsiniz. Bu, bir akıllı sözleşme için stratejileri değiştirmenize (yani yeni mantık uygulamanıza) olanak tanır.
Daha önce tartışılan vekil modeline benzese de, strateji modeli farklıdır çünkü kullanıcıların etkileşime girdiği ana sözleşme iş mantığını barındırır. Bu modeli kullanmak, temel altyapıyı etkilemeden bir akıllı sözleşmede sınırlı değişiklikler yapma fırsatı sunar.
Temel dezavantaj, bu modelin çoğunlukla küçük yükseltmeleri sunmak için yararlı olmasıdır. Ayrıca, ana sözleşme tehlikeye girerse (örneğin bir hack yoluyla), bu yükseltme yöntemini kullanamazsınız.
Yükseltme mekanizması #5: Elmas modeli
Elmas modeli, vekil modeli üzerinde bir iyileştirme olarak düşünülebilir. Elmas modelleri vekil modellerinden farklıdır çünkü elmas vekil kontratı fonksiyon çağrılarını birden fazla mantık sözleşmesine devredebilir.
Elmas modelindeki mantık sözleşmeleri yüzeyler (facets) olarak bilinir. Elmas modelinin çalışmasını sağlamak için, vekil kontratta fonksiyon seçicilerini (opens in a new tab) farklı yüzey adresleriyle eşleyen bir eşleme oluşturmanız gerekir.
Bir kullanıcı bir fonksiyon çağrısı yaptığında, vekil kontrat o fonksiyonu yürütmekten sorumlu yüzeyi bulmak için eşlemeyi kontrol eder. Ardından (geri dönüş fonksiyonunu kullanarak) delegatecall'u başlatır ve çağrıyı uygun mantık sözleşmesine yönlendirir.
Elmas yükseltme modelinin geleneksel vekil yükseltme modellerine göre bazı avantajları vardır:
-
Tüm kodu değiştirmeden sözleşmenin küçük bir bölümünü yükseltmenize olanak tanır. Yükseltmeler için vekil modelini kullanmak, küçük yükseltmeler için bile tamamen yeni bir mantık sözleşmesi oluşturmayı gerektirir.
-
Tüm akıllı sözleşmeler (vekil modellerinde kullanılan mantık sözleşmeleri dahil) 24KB boyut sınırına sahiptir, bu da özellikle daha fazla fonksiyon gerektiren karmaşık sözleşmeler için bir sınırlama olabilir. Elmas modeli, fonksiyonları birden fazla mantık sözleşmesine bölerek bu sorunu çözmeyi kolaylaştırır.
-
Vekil modelleri, erişim kontrollerine her şeyi kapsayan bir yaklaşım benimser. Yükseltme fonksiyonlarına erişimi olan bir varlık tüm sözleşmeyi değiştirebilir. Ancak elmas modeli, varlıkları bir akıllı sözleşme içindeki belirli fonksiyonları yükseltmekle kısıtlayabileceğiniz modüler bir izin yaklaşımı sağlar.
Elmas modeli hakkında daha fazlası (opens in a new tab).
Akıllı sözleşmeleri yükseltmenin artıları ve eksileri
| Artıları | Eksileri |
|---|---|
| Bir akıllı sözleşme yükseltmesi, dağıtım sonrası aşamada keşfedilen güvenlik açıklarını düzeltmeyi kolaylaştırabilir. | Akıllı sözleşmeleri yükseltmek, merkeziyetsizlik ve güvenlik açısından sonuçları olan kod değişmezliği fikrini geçersiz kılar. |
| Geliştiriciler, merkeziyetsiz uygulamalara yeni özellikler eklemek için mantık yükseltmelerini kullanabilirler. | Kullanıcılar, akıllı sözleşmeleri keyfi olarak değiştirmeyecekleri konusunda geliştiricilere güvenmelidir. |
| Hatalar hızlı bir şekilde düzeltilebildiği için akıllı sözleşme yükseltmeleri son kullanıcılar için güvenliği artırabilir. | Akıllı sözleşmelere yükseltme işlevselliği programlamak, başka bir karmaşıklık katmanı ekler ve kritik kusur olasılığını artırır. |
| Sözleşme yükseltmeleri, geliştiricilere farklı özelliklerle denemeler yapmaları ve dapp'leri zaman içinde iyileştirmeleri için daha fazla alan sağlar. | Akıllı sözleşmeleri yükseltme fırsatı, geliştiricileri geliştirme aşamasında gerekli özeni göstermeden projeleri daha hızlı başlatmaya teşvik edebilir. |
| Akıllı sözleşmelerdeki güvensiz erişim kontrolü veya merkezileşme, kötü niyetli aktörlerin yetkisiz yükseltmeler gerçekleştirmesini kolaylaştırabilir. |
Akıllı sözleşmeleri yükseltirken dikkat edilmesi gerekenler
-
Özellikle vekil modelleri, strateji modelleri veya veri ayrımı kullanıyorsanız, yetkisiz akıllı sözleşme yükseltmelerini önlemek için güvenli erişim kontrolü/yetkilendirme mekanizmaları kullanın. Buna bir örnek, yükseltme fonksiyonuna erişimi yalnızca sözleşmenin sahibinin çağırabileceği şekilde kısıtlamaktır.
-
Akıllı sözleşmeleri yükseltmek karmaşık bir faaliyettir ve güvenlik açıklarının ortaya çıkmasını önlemek için yüksek düzeyde özen gerektirir.
-
Yükseltmeleri uygulama sürecini merkeziyetsizleştirerek güven varsayımlarını azaltın. Olası stratejiler arasında yükseltmeleri kontrol etmek için bir çoklu imzalı cüzdan sözleşmesi kullanmak veya bir DAO üyelerinin yükseltmeyi onaylamak için oy kullanmasını gerektirmek yer alır.
-
Sözleşmeleri yükseltmenin içerdiği maliyetlerin farkında olun. Örneğin, sözleşme taşıma sırasında durumu (örneğin kullanıcı bakiyeleri) eski bir sözleşmeden yeni bir sözleşmeye kopyalamak birden fazla işlem gerektirebilir, bu da daha fazla Gaz ücreti anlamına gelir.
-
Kullanıcıları korumak için zaman kilitleri (timelocks) uygulamayı düşünün. Bir zaman kilidi, bir sistemdeki değişikliklere uygulanan bir gecikmeyi ifade eder. Zaman kilitleri, yükseltmeleri kontrol etmek için çoklu imzalı bir yönetişim sistemiyle birleştirilebilir: önerilen bir eylem gerekli onay eşiğine ulaşırsa, önceden tanımlanmış gecikme süresi geçene kadar yürütülmez.
Zaman kilitleri, önerilen bir değişikliğe (örneğin mantık yükseltmesi veya yeni ücret şemaları) katılmıyorlarsa kullanıcılara sistemden çıkış yapmaları için biraz zaman tanır. Zaman kilitleri olmadan, kullanıcıların önceden haber vermeden bir akıllı sözleşmede keyfi değişiklikler uygulamayacakları konusunda geliştiricilere güvenmeleri gerekir. Buradaki dezavantaj, zaman kilitlerinin güvenlik açıklarını hızlı bir şekilde yamama yeteneğini kısıtlamasıdır.
Kaynaklar
OpenZeppelin Upgrades Eklentileri - Yükseltilebilir akıllı sözleşmeleri dağıtmak ve güvence altına almak için bir araç paketi.
Eğitimler
- Patrick Collins'ten Akıllı Sözleşmelerinizi Yükseltme | YouTube Eğitimi (opens in a new tab)
- Austin Griffith'ten Ethereum Akıllı Sözleşme Taşıma Eğitimi (opens in a new tab)
- Pranesh A.S'den Akıllı sözleşmeleri yükseltmek için UUPS vekil modelini kullanma (opens in a new tab)
- fangjun.eth'ten Web3 Eğitimi: OpenZeppelin kullanarak yükseltilebilir akıllı sözleşme (vekil) yazma (opens in a new tab)
İleri okuma
- Santiago Palladino'dan Akıllı Sözleşme Yükseltmelerinin Durumu (opens in a new tab)
- Bir Solidity akıllı sözleşmesini yükseltmenin birden fazla yolu (opens in a new tab) - Crypto Market Pool blogu
- Öğrenin: Akıllı Sözleşmeleri Yükseltme (opens in a new tab) - OpenZeppelin Belgeleri
- Naveen Sahu'dan Solidity Sözleşmelerinin Yükseltilebilirliği İçin Vekil Modelleri: Şeffaf ve UUPS Vekilleri (opens in a new tab)
- Nick Mudge'dan Elmas Yükseltmeleri Nasıl Çalışır (opens in a new tab)