Bu makale kripto para birimi veya merkezi olmayan finans hakkında değil. Bunun yerine, özel ihtiyaçlarınıza ve hedeflerinize bağlı olarak, genel EVM blok zincirlerini ve bunların bir sonraki projenizde nasıl kullanılabileceğini keşfedeceğiz. Üzerinde çalıştığım 0xweb kütüphanesini kullanarak artılarını, eksilerini ve pratik örnekleri inceleyeceğim.
Zaten çalışıyor. Veri modelinizi bir sözleşme olarak tanımlayın ve dağıtın.
Verileriniz yüklendikten sonra, blockchain çalıştığı sürece erişilebilir kalır. Diğer barındırma aboneliğinizden çok daha uzun olacağını varsayabilirim.
Blockchain'de okuma ve yazma süreçlerinin ayrılması, özellikle yedeklilik için birden fazla RPC sağlayıcısından yararlanıldığında, okuma işlemlerinde %100 kesintisiz çalışma süresini garanti eder.
Blok zincirleri, geleneksel barındırma çözümlerinden doğal olarak daha yüksek düzeyde güvenlik sağlar. Veri istismarları yalnızca veri modelinizin mantığında güvenlik açıkları varsa mümkündür.
Şifrelenmediği sürece verileriniz herkes tarafından açık, erişilebilir ve doğrulanabilir kalır; bu da şeffaflığı artırır.
Alan adları bu tür arka uç için gereksizdir. Bunun yerine, merkezi olmayan düğüm sağlayıcılarının bir listesi kullanılabilir ve bu da istemci kütüphanelerinin son kullanıcılar için en verimli seçeneği seçmesine olanak tanır.
Yukarıdaki özellikler sayesinde, blockchain tabanlı arka uçlar, proje bakımı ve geliştirmesi dursa bile veri güvenliğini ve 7/24 kullanılabilirliği sağlayarak kullanıcı güvenini doğal olarak oluşturur.
Blockchain'de saklanan diğer veri modellerini entegre edebilir veya diğer projeler veri modelinizi geliştirebilir.
Kullanıcılar, eylemleri izlemek veya otomatikleştirmek için çok sayıda üçüncü taraf projesinden yararlanabilir ve bu sayede veri modelinizin olanakları önemli ölçüde genişler.
Verilere geçmişteki herhangi bir noktadan ulaşılabilir.
Geçmiş özel olayları yükleyin veya gerçek zamanlı gelen olayları dinlemek için WebSockets'ı kullanın; böylece dinamik uygulama yanıtları etkinleştirin.
“Cüzdan” konsepti, kullanıcıların mesajları imzalayarak kendilerini doğrulamalarını sağlayarak, kesintisiz ve merkezi olmayan bir kullanıcı tanımlaması sağlıyor.
Kullanıcılar, tanımladığınız izinlere göre depolama alanınızdaki verileri değiştirebilir veya genişletebilir. Önemlisi, bu değişikliklerin maliyetleri kullanıcıların kendileri tarafından karşılanır. Düşük maliyetli bir blok zinciri seçerek, bu ücretler önemsiz kalabilir ve genellikle işlem başına yalnızca birkaç sente ulaşabilir.
Gerçek bir ödedikçe kullan modelini takip etse de, yalnızca depoladığınız SLOT'lar için ödeme yaparsınız. Her SLOT'un 32 baytı vardır, yeni veri yazmak 20000 GAS veya veriyi güncellemek 5000 GAS'a mal olur. Örnek olarak Polygon'u ele alalım, 30 gwei GAS fiyatı ve 0,60 $ POL fiyatı.
20000GAS × 30gwei = 0,008 POL × 0,60$ = 0,00032$
Bu çok fazla, bu yüzden "Floppy Disk" emojisi depolama miktarlarını en iyi şekilde temsil ediyor, bu da kendi başınıza ödeme yapıyorsanız daha küçük veri kümeleri için en uygun olduğu anlamına geliyor. Ancak, benzersiz bir avantaj, kullanıcıların kendi depolama ve eylemlerinin maliyetlerini karşılayabilmeleri, diğer teknolojilerde bulunmayan bir özellik. Bu yaklaşım, uygulamanızın kitlesel benimsenmesini engellese de, blockchain topluluğunda yaygın olarak kabul görmektedir.
Blockchain veri modelleri, verilerle etkileşime girmek için işlevleri destekler, ancak hesaplama yeteneklerinin kısıtlamaları vardır. Bu sınırlamalar, okuma eylemleri için kullandığınız RPC düğümlerine ve yazma eylemlerine (işlemlere) uygulanan katı GAS sınırlarına bağlıdır. Temel işlemler, döngüler ve daha derin çağrı yığınları genellikle yönetilebilirken, blockchain yoğun hesaplama iş yükleri için uygun değildir.
Bununla birlikte, genellikle söz konusu olan nispeten küçük veri boyutları göz önüne alındığında, mevcut sınırlar çoğu kullanım durumu için genellikle yeterlidir.
Blockchain geliştirmeye yeni başladıysanız, karmaşık ve başlaması zor olduğunu duymuş olabilirsiniz. Ancak bu doğru değildir. Blockchain geliştirme, bilindik kavramları, semantiği ve sözdizimini kullanır ve bu da göründüğünden daha kolay öğrenilmesini sağlar.
https://github.com/0xweb-org/examples-backend
Bu makale için bir uygulama sürüm yöneticisi sözleşmesi oluşturalım. Yeni sürümleri kontrol etmek ve yeni bir sürüm yayınlandığında indirme bağlantısını almak için bir arka uç gerektiren bir masaüstü uygulamanız olduğunu düşünün. Aşağıda, temel kavramların çoğunu gösteren son sözleşme bulunmaktadır:
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; struct Package { uint version; uint timestamp; string url; bytes32 sha256; } contract AppVersionManager is Ownable { // Events that are emitted on data updates event NewApplicationInfo(); event NewPackage(uint version, uint timestamp); // Custom error, when title for the application is empty error TitleIsEmpty(); // Some application information string public title; // @TODO: add further application related properties if required // Latest package Package public package; // Track all versions and their packages mapping (uint => Package) public packages; // List of all previous versions uint[] public versions; constructor () Ownable(msg.sender) { } function updateInfo(string calldata newTitle) external onlyOwner { if (bytes(newTitle).length == 0) { revert TitleIsEmpty(); } title = newTitle; emit NewApplicationInfo(); } function updatePackage(Package calldata newPackage) external onlyOwner { require(newPackage.version > package.version, "Newer package already published"); packages[package.version] = package; package = newPackage; versions.push(package.version); emit NewPackage(package.version, block.timestamp); } function findPackageAtTimestamp (uint timestamp) external view returns (Package memory) { if (package.timestamp <= timestamp) { return package; } // the countdown loop to find the latest package for the timestamp int i = int(versions.length); while (--i > -1) { Package memory pkg = packages[versions[uint(i)]]; if (pkg.timestamp <= timestamp) { return pkg; } } revert("No package found"); } function getPackage (uint version) external view returns (Package memory) { if (version == package.version) { return package; } return packages[version]; } }
Her geliştirici bu kodu asgari çabayla okuyabilir ve anlayabilir. TypeScript'e aşinaysanız, buradaki kavramların çoğu zaten mantıklı gelecektir. Daha da açık hale getirmek için, eşdeğer bir TypeScript örneği oluşturdum: AppVersionManager.ts 🔗 .
Basitçe ifade etmek gerekirse, Solidity'deki bir sözleşme durum bilgisi olan bir sınıf örneği olarak düşünülebilir. Özellikler, yöntemler, türler ve miras kavramları nesne yönelimli programlamada zaten iyi bilinmektedir. Burada açıklanacak ana kavram onlyOwner
değiştiricisidir (TypeScript'teki bir dekoratöre benzer).
Her blockchain hesabı esasen özel ve genel anahtarların bir çiftidir. Adres olarak bilinen hesabın kimliği genel anahtardan türetilir. Bir işlem yürütüldüğünde, gönderenin adresi msg.sender
olarak geçirilir. Bunu kullanarak, adresinizi oluşturucuda (sözleşme dağıtımı sırasında) saklayabiliriz. Daha sonra, onlyOwner
değiştiricisi, yalnızca sizin, sözleşme sahibi olarak, updateInfo
ve updatePackage
işlevlerini yürütebilmenizi sağlar. Başka biri bu eylemleri denerse, işlem geri alınır. onlyOwner
değiştiricisi, yaygın olarak kullanılan OpenZeppelin kütüphanesinin bir parçası olan Ownable
sözleşmesi tarafından sağlanır. Bu kütüphane, blockchain gelişimini kolaylaştırmak için birçok başka yararlı sözleşme içerir.
Tartışılacak bir diğer önemli konu ise depolama ve uygulamayı iki ayrı sözleşmeye bölen Proxy kavramıdır. Solidity'deki sözleşme uygulamaları değiştirilemezdir, yani dağıtımdan sonra yeni işlevler veya özellikler ekleyemezsiniz. Bunu aşmak için bir "Proxy" sözleşmesi dağıtabilirsiniz. Proxy depolamayı yönetir ve yalnızca bir fallback
işlevi içerir, bu da Proxy'nin depolama bağlamını korurken uygulama sözleşmesine çağrıları devreder.
Bu kavram karmaşık gelebilir, ancak JavaScript'te this
çalıştığına benzer. İşte açıklamaya yardımcı olacak kısa bir benzetme:
const foo = new Proxy({ bar: 'Lorem' }, { get (obj, prop) { return fooImplementation[prop].bind(obj) }, }); const fooImplementation = { logValue () { console.log('Bar value:', this.bar) } } foo.logValue();
Proxy sözleşmesi, uygulama sözleşmesine bir referans tutar. Yeni işlevler eklemek istiyorsanız, yeni bir uygulama sözleşmesi dağıtır ve proxy'yi bu yeni sözleşmeye referans verecek şekilde güncellersiniz, böylece işlev çağrıları güncellenen örneğe iletilir. Bu basit bir işlemdir, ancak dikkate alınması gereken bir uç durum vardır: oluşturucular.
Bir uygulama sözleşmesi dağıtılırken, kurucusu uygulama sözleşmesinin kendi depolaması içinde çalışır. Bu title = "Hello World"
gibi ayarlayıcıların proxy'nin depolamasını değiştirmeyeceği anlamına gelir. Bunu ele almak için başlatıcı işlev kavramını kullanırız:
initialize
fonksiyonu ile dağıtın.initialize
yönteminin proxy sözleşmesi bağlamında çağrılmasına olanak tanır.
Sonuç olarak, örneğin, title
özelliğinin güncellenmesi, onu proxy'nin depolama alanında doğru şekilde güncelleyecektir.
İşte AppVersionManager'ımızın yükseltilmiş bir uygulama sürümü: AppVersionManagerUpgradeable.sol .
Proxy sözleşmesinin kendisi oldukça evrenseldir ve uygulamadan bağımsızdır. Proxy'ler için birkaç iyi bilinen standart OpenZeppelin kütüphanesinde mevcuttur.
Bu kavramların bilgisine ve yukarıdaki örneklere sahip olduğunuzda, iş senaryolarınız için akıllı sözleşmeler geliştirmeye hazırsınız.
Öncelikle, sözleşmemizi dağıtmak istediğimiz blok zincirini seçmemiz gerekiyor. Bu örnek için Polygon'u seçtim. Düşük işlem maliyetleri sunuyor, uzun süredir var ve sürekli olarak iyi performans gösteriyor. 0,9 milyar dolarlık Toplam Kilitli Değer (TVL) ile birlikte istikrarlı ve verimli altyapısı onu güvenilir bir seçenek haline getiriyor. Sözleşmelerinizi halka açık blok zincirlerine dağıtmak, finansal kuruluşlarla birlikte var olmak anlamına geliyor. TVL metriği, bu kuruluşların blok zincirinin güvenilirliğine olan güvenini yansıtıyor.
Ayrıca, koşullar değişirse sözleşmeyi gelecekte her zaman başka bir blok zincirine yeniden dağıtabilirsiniz.
Demo projesi aynı zamanda CI test deposu olarak da hizmet veriyor, dolayısıyla tüm komutlar burada bulunabilir: https://github.com/0xweb-org/examples-backend/blob/master/deploy-cli.sh
# Install 0xweb library from NPM into the prject folder npm i 0xweb # Install required dependencies to compile/deploy *.sol files npx 0xweb init --hardhat --openzeppelin # Create or import the account. Private key will be encrypted with pin AND machine key. npx 0xweb accounts new --name foo --pin test --login # Save the private key securly and ensure the account has some POL tokens # Deploy. The foo account is selected as default. npx 0xweb deploy ./contracts/AppVersionManager.sol --chain polygon --pin test # Set title npx 0xweb c write AppVersionManager updateInfo --newTitle MySuperApp --pin test # Set latest package information npx 0xweb c write AppVersionManager updatePackage --arg0 'load(./data/package.json)' --pin test
Sadece birkaç komutla sözleşmeyi dağıttınız ve verileri güncellediniz. Arka uç için hepsi bu kadar—artık sizin tarafınızdan herhangi bir ek işlem gerektirmeden "sonsuza kadar" çalışır durumda. Bu dağıtımın maliyeti, 70 gwei'lik bir GAS fiyatı ve 0,51$'lık bir POL fiyatı ile şöyle olacaktır:
| GAZ | Polonya | $ |
---|---|---|---|
Dağıtmak | 850352 | 0,059 | 0,03 |
Başlığı Kaydet | 47517 | 0,0033 | 0,001 |
Paket Verilerini Kaydet | 169549 | 0,0118 | 0,006 |
Toplam | | | 0,037 |
Hiçbir bakım gerektirmeyen, merkezi olmayan , güvenli ve uzun ömürlü bir hizmet kurmak için sadece 4 sent harcıyorsunuz.
Sözleşme verilerinizi sorgulamak için RPC düğüm sağlayıcılarına ihtiyacınız olacak. https://chainlist.org adresinde düzinelerce ücretsiz sağlayıcı mevcuttur. Birden fazla sağlayıcı seçebilirsiniz ve iyi bir Web3 kütüphanesi, son kullanıcılarınız için en verimli olanı seçmek üzere çalışma zamanında bir round-robin stratejisi kullanabilir. 0xweb ile, oluşturulan TypeScript veya JavaScript sınıfları yalnızca en iyi uç noktaları seçmekle kalmaz, aynı zamanda tüm blok zinciri iletişimini soyutlar. İstemciler, veri almak için üst düzey yöntemler içerir ve bu da süreci sorunsuz ve verimli hale getirir.
# The deploy command also generates the class, but manual install is also possible npx 0xweb i 0x<address> --name AppVersionManager --chain polygon
import { AppVersionManager } from './0xc/polygon/AppVersionManager/AppVersionManager' const manager = new AppVersionManager(); console.log(`Title`, await manager.title()); console.log(`Package`, await manager.package());
Diğer programlama dilleri için, blockchain'e sorgu göndermeyi basitleştirmek için çok sayıda kütüphane mevcuttur. Dağıtımdan sonra, sözleşme adresiniz ve ABI'niz (arayüz) olacaktır.
Alternatif olarak, 0xweb kullanarak sözleşme verilerini sorgulamak için bir ara yazılım sunucusu başlatabilirsiniz.
npx 0xweb server start --port 3000 curl http://localhost:3000/api/c/read/AppVersionManager/package?chain=polygon
Bir avantajı, uygulamanıza herhangi bir kütüphane eklemenize gerek olmamasıdır - ham HTTP istekleri. Ancak, bu yaklaşım yönetmeniz gereken ek bir sunucuya dayanır. Genellikle, 0xweb tarafından oluşturulan sınıfları veya mevcut diğer blok zinciri kütüphanelerini kullanarak doğrudan blok zincirine sorgu göndermek daha iyidir.
Bu makalede, blok zincirlerinin hem basit hem de güçlü olabileceği, geleneksel barındırma çözümlerine kıyasla benzersiz avantajlar sunabileceği gösterildi.
Bir sonraki yazımda Greenfield ve Arweave gibi merkezi olmayan BLOB depolama ağlarını inceleyerek özelliklerini ve faydalarını vurgulamayı planlıyorum.
0xweb kütüphanesine eklenmesi için herhangi bir öneriniz veya fikriniz varsa, bunları yorumlarda paylaşmaktan çekinmeyin veya doğrudan [email protected] adresine ulaşın.