Ethereum Blockchain İçin Bir Node.js API Nasıl Oluşturulur
Yayınlanan: 2022-03-10Blockchain teknolojisi son on yılda yükselişte ve Chainalysis (finans teknolojisi), Burstiq (sağlık teknolojisi), Filament (IoT), Opus (müzik akışı) gibi çok sayıda ürün ve platformu hayata geçirdi. ve Oküler (siber güvenlik).
Bu örneklerden, blockchain'in birçok ürünü ve kullanım durumlarını kestiğini görebiliriz - bu da onu çok gerekli ve kullanışlı hale getirir. Fintech'te (finans teknolojisi), Chain, Chainalysis gibi yerlerde güvenlik ve şeffaflık için merkezi olmayan defterler olarak kullanılır ve ayrıca Burstiq ve Robomed'deki hassas sağlık verilerinin güvenliği için sağlık teknolojisinde faydalıdır - Opus gibi medya teknolojilerini unutmamak gerekir ve telif şeffaflığı için blok zinciri kullanan ve böylece tam telif hakkı alan Audius.
Ocular, biyometrik sistemler için kimlik yönetimi için blok zinciri ile birlikte gelen güvenliği kullanırken, Filament gerçek zamanlı şifreli iletişim için blok zinciri defterlerini kullanır. Bu, hayatımızı daha iyi hale getirerek blockchain'in bizim için ne kadar önemli olduğunu gösteriyor. Ama tam olarak bir blok zinciri nedir?
Blok zinciri, bir bilgisayar ağı arasında paylaşılan bir veritabanıdır . Zincire bir kayıt eklendikten sonra değiştirilmesi oldukça zordur. Veritabanının tüm kopyalarının aynı olduğundan emin olmak için ağ sürekli kontroller yapar.
Peki neden blok zincirine ihtiyacımız var? Blok zinciri, saldırıların, hataların ve kesintilerin çok olası olduğu geleneksel kayıtlara veya veritabanlarına kıyasla geçmişinin kaydını tutarken faaliyetleri kaydetmenin ve verileri taze tutmanın güvenli bir yoludur . Veriler hiç kimse tarafından bozulamaz veya yanlışlıkla silinemez ve hem geçmişteki bir veri izinden hem de bir sunucunun kapalı kalması nedeniyle silinemeyen veya erişilemeyen anlık güncel bir kayıttan yararlanırsınız.
Blok zincirinin tamamı birçok bilgisayarda kopyalandığından, herhangi bir kullanıcı blok zincirinin tamamını görüntüleyebilir. İşlemler veya kayıtlar tek bir merkezi yönetici tarafından değil, verileri doğrulamak ve fikir birliğine varmak için çalışan bir kullanıcı ağı tarafından işlenir.
Blockchain kullanan uygulamalara dApps (Merkezi Olmayan Uygulamalar) denir. Bugün etrafa baktığımızda, çoğunlukla fintech'te merkezi olmayan uygulamalar bulacağız, ancak blok zinciri, merkezi olmayan finansın ötesine geçiyor. Sağlık platformlarımız, müzik akışı/paylaşım platformlarımız, e-ticaret platformlarımız, siber güvenlik platformlarımız ve yukarıda belirtildiği gibi merkezi olmayan uygulamalara (dApp'ler) doğru ilerleyen IOT'larımız var.
Peki, uygulamalarımız için standart bir veritabanı veya kayıt yerine blok zinciri kullanmayı düşünmek ne zaman mantıklı olur?
Blockchain'in Ortak Uygulamaları
- Dijital İlişkileri Yönetme ve Güvence Altına Alma
Uzun vadeli, şeffaf bir varlık kaydı tutmak istediğinizde (örneğin, mülk veya apartman haklarını kaydetmek için), blockchain ideal çözüm olabilir. Özellikle Ethereum 'akıllı sözleşmeleri' dijital ilişkileri kolaylaştırmak için harikadır. Akıllı bir sözleşme ile, bir işlemdeki taraflar koşullarının karşılandığını kabul ettiğinde otomatik ödemeler serbest bırakılabilir. - Aracıları/Kapı Bekçilerini Ortadan Kaldırmak
Örneğin, çoğu sağlayıcı şu anda misafirlerle Airbnb veya Uber gibi merkezi bir toplayıcı platform aracılığıyla etkileşim kurmak zorundadır (bu da her işlemden bir pay alır). Blockchain tüm bunları değiştirebilir.
Örneğin, TUI, blok zincirinin gücüne o kadar ikna olmuş ki, otelcileri ve müşterileri doğrudan birbirine bağlamanın yollarına öncülük ediyor. Bu şekilde, merkezi bir rezervasyon platformu yerine blok zinciri aracılığıyla kolay, güvenli ve tutarlı bir şekilde işlem yapabilirler. - Güveni Sağlamak İçin Ortaklar Arasındaki Güvenli İşlemleri Kaydedin
Geleneksel bir veritabanı, iki taraf arasındaki basit işlemleri kaydetmek için iyi olabilir, ancak işler daha karmaşık hale geldiğinde blok zinciri, darboğazları azaltmaya ve ilişkileri basitleştirmeye yardımcı olabilir. Dahası, merkezi olmayan bir sistemin ek güvenliği, blok zinciri genel olarak işlemler için ideal hale getirir.
Bir örnek, kayıtlarını blok zincirinde depolamaya başlayan Melbourne Üniversitesi'dir. Yüksek öğrenimde blok zinciri için en umut verici kullanım örneği, derecelerin, sertifikaların ve diplomaların “kayıt tutma” biçimini dönüştürmektir. Bu, depolama veya kayıtlar için ayrılmış sunuculardan çok fazla maliyet tasarrufu sağlar. - Verilerin Sabit Akışta Olduğu Uygulamalar İçin Geçmiş Eylemlerin Kayıtlarını Tutma
Blockchain, etkinliği kaydetmenin ve geçmişinin kaydını tutarken verileri taze tutmanın daha iyi ve daha güvenli bir yoludur. Veriler hiç kimse tarafından bozulamaz veya yanlışlıkla silinemez ve hem geçmiş bir veri izinden hem de anında güncel bir kayıttan yararlanırsınız. İyi bir kullanım örneği, e-ticarette blok zinciridir, hem blok zinciri hem de e-ticaret işlemleri içerir.
Blockchain bu işlemleri daha güvenli ve hızlı hale getirirken, e-ticaret faaliyetleri onlara güvenir. Blockchain teknolojisi, kullanıcıların dijital varlıkları hem otomatik hem de manuel olarak paylaşmasını ve güvenli bir şekilde saklamasını sağlar. Bu teknoloji, ödeme işleme, ürün arama, ürün satın alma ve müşteri hizmetleri gibi kullanıcı etkinliklerini yönetme kapasitesine sahiptir. Ayrıca envanter yönetimi ve ödeme işlemleri için harcanan masrafları da azaltır. - Ademi Merkeziyetçilik Her Yerde Kullanılabilmesini Sağlar
Daha önce döviz politikaları gibi çeşitli nedenlerle kendimizi belirli bir bölgeyle sınırlamak zorunda kaldığımız yerlerin aksine, ödeme ağ geçitlerinin kısıtlamaları bölgenizde veya kıtanızda olmayan birçok ülkenin finansal kaynaklarına erişimi zorlaştırıyor. Blok zincirinin ademi merkeziyetçiliğinin veya eşler arası sisteminin yükselişi ve gücü ile bu, diğer ülkelerle çalışmak daha kolay hale geliyor.
Örneğin, Avrupa'daki bir e-ticaret mağazası, Afrika'da tüketicilere sahip olabilir ve ödeme taleplerini işlemek için bir aracıya ihtiyaç duymaz. Ayrıca bu teknolojiler, çevrimiçi perakendecilerin uzak ülkelerdeki tüketici pazarlarını bitcoin, yani bir kripto para birimi ile kullanmaları için kapılar açmaktadır. - Blockhain Teknolojiden Tarafsız
Blockchain, bir geliştirici tarafından kullanılan tüm teknoloji yığınlarıyla çalışır. Blockchain kullanmak veya Golang öğrenmek için bir Python geliştiricisi olarak Node öğrenmeniz gerekmez. Bu, blok zincirinin kullanımını çok kolaylaştırır.
Aslında onu doğrudan Vue/React'teki ön uç uygulamalarımızla kullanabiliriz ve basit karmaşık olmayan görevler için tek veritabanımız olarak hareket eden blok zinciri ile kullanıcılarımız için kayıtları görüntülemek için veri yüklemek veya karma elde etmek veya kumarhane gibi ön uç oyunlar oluşturmak gibi durumları kullanabiliriz. oyunlar ve bahis oyunları (yüksek miktarda güvenin gerekli olduğu). Ayrıca web3'ün gücü ile doğrudan zincirde veri depolayabiliyoruz.
Şimdi, blok zinciri kullanmanın pek çok avantajını gördük, ancak ne zaman bir blok zinciri kullanmakla hiç uğraşmamalıyız?
Blockchain'in Dezavantajları
- Dijital İşlem için Azaltılmış Hız
Blok zincirleri, dijital işlemlerin hızını düşürme eğiliminde olan büyük miktarda bilgi işlem gücü gerektirir, ancak geçici çözümler olsa da, milisaniye cinsinden yüksek hızlı işlemlere ihtiyaç duyulduğunda merkezi veritabanlarının kullanılması tavsiye edilir. - Veri Değişmezliği
Veri değişmezliği her zaman blok zincirinin en büyük dezavantajlarından biri olmuştur. Tedarik zinciri, finansal sistemler vb. dahil olmak üzere birden fazla sistemin bundan faydalandığı açıktır. Bununla birlikte, veriler bir kez yazıldıktan sonra kaldırılamaması gerçeğinden muzdariptir. Yeryüzündeki her insanın mahremiyet hakkı vardır. Ancak aynı kişi blockchain teknolojisi ile çalışan bir dijital platform kullanıyorsa, orada olmasını istemediği zaman onun izini sistemden kaldıramayacaktır. Basit bir deyişle, izini kaldırmasının - mahremiyet haklarını parçalara ayırmasının - hiçbir yolu yok. - Uzmanlık Bilgisi Gerektirir
Bir blockchain projesini uygulamak ve yönetmek zordur. Tüm süreçten geçmek için kapsamlı bilgi gerektirir. Bu nedenle blok zinciri uzmanlarına veya uzmanlarına rastlamak zordur çünkü bir blok zinciri uzmanı yetiştirmek çok zaman ve çaba gerektirir. Bu nedenle, bu makale başlamak için iyi bir yer ve zaten başladıysanız iyi bir rehberdir. - birlikte çalışabilirlik
Dağıtılmış defter problemini benzersiz bir şekilde çözmek için çok çalışan çoklu blok zinciri ağları, onları ilişkilendirmeyi veya birbirleriyle entegre etmeyi zorlaştırır. Bu, farklı zincirler arasındaki iletişimi zorlaştırır. - Eski Uygulamalar Entegrasyonu
Birçok işletme ve uygulama hala eski sistemleri ve mimariyi kullanıyor; Blockchain teknolojisini benimsemek, birçoğu için mümkün olmadığını söylemeliyim ki, bu sistemlerin tamamen elden geçirilmesini gerektiriyor.
Blockchain hala her zaman gelişiyor ve olgunlaşıyor, bu nedenle bugün bahsedilen bu dezavantajlar daha sonra bir profesyonele dönüşürse şaşırmayın. Bir kripto para birimi olan Bitcoin, popüler bir blok zinciri örneğidir, bitcoin kripto para biriminin yanı sıra yükselişte olan popüler bir blok zinciri, Ethereum blok zinciridir. Bitcoin kripto para birimlerine odaklanırken, Ethereum daha çok yeni teknoloji platformları için ana itici güç olan akıllı sözleşmelere odaklanır.
Önerilen okuma : Bitcoin vs. Ethereum: Fark Nedir?
API'mizi Oluşturmaya Başlayalım
Sağlam bir blok zinciri anlayışıyla, şimdi bir Ethereum blok zincirinin nasıl oluşturulacağına ve Node.js'de standart bir API'ye nasıl entegre edileceğine bakalım. Nihai hedef, dApp'lerin ve Blockchain platformlarının nasıl oluşturulduğuna dair iyi bir anlayış elde etmektir.
Çoğu dApp benzer mimariye ve yapıya sahiptir. Temel olarak, web veya mobil dApp ön ucuyla etkileşime giren ve daha sonra arka uç API'leriyle etkileşime giren bir kullanıcımız var. Ardından, arka uç, istek üzerine akıllı sözleşme(ler) veya genel düğümler aracılığıyla blok zinciri ile etkileşime girer; bunlar ya Node.js uygulamalarını çalıştırır ya da arka uç, doğrudan Node.js yazılımını çalıştırarak blok zinciri kullanır. Bu süreçler arasında, tamamen merkezi olmayan bir uygulama veya yarı merkezi olmayan bir uygulama oluşturmayı seçmekten, neyin merkezileştirilmeyeceğini ve özel anahtarların nasıl güvenli bir şekilde saklanacağını seçmeye kadar pek çok şey var.
Önerilen okuma : Merkezi Olmayan Uygulamalar Mimarisi: Arka Uç, Güvenlik ve Tasarım Modelleri
Önce Bilmemiz Gerekenler
Bu öğretici için, müziği depolamak ve indirme veya akış için paylaşmak için Ethereum blok zincirinin gücünü kullanan merkezi olmayan bir müzik mağazası uygulamasının arka ucunu oluşturmaya çalışacağız.
Oluşturmaya çalıştığımız uygulamanın temel yapısı üç bölümden oluşmaktadır:
- E-posta ile yapılan kimlik doğrulama ; tabi ki uygulamaya şifreli bir şifre eklememiz gerekiyor.
- Müzik verileriyle birlikte verilerin depolanması ilk önce ipfs'de depolanır ve depolama adresi geri alınmak üzere blok zincirinde saklanır.
- Kimliği doğrulanmış herhangi bir kullanıcının platformumuzda depolanan verilere erişebilmesi ve kullanabilmesi ile alma.
Bunu Node.js ile oluşturacağız, ancak Python veya başka bir programlama dili ile de oluşturabilirsiniz. Ayrıca medya verilerini IPFS'de nasıl depolayacağımızı, adresi nasıl alacağımızı ve bu adresi depolamak için işlevleri nasıl yazacağımızı ve bu adresi Solidity programlama diliyle bir blok zincirinden nasıl alacağımızı göreceğiz.
Ethereum ve Node.js oluşturmak veya bunlarla çalışmak için elimizde bulundurmamız gereken bazı araçlar.
- Node.js
İlk gereksinim bir Düğüm uygulamasıdır. Bir Node.js uygulaması oluşturmaya çalışıyoruz, bu yüzden bir derleyiciye ihtiyacımız var. Lütfen Node.js'nin kurulu olduğundan emin olun ve lütfen en son uzun vadeli destek ikili dosyasını ( LTS ) indirin. - yer mantarı süiti
Truffle, bir sözleşme geliştirme ve test ortamının yanı sıra Ethereum blok zinciri için bir varlık hattıdır. Komut dosyalarının derlenmesi, sıralanması ve çalıştırılması için bir ortam sağlar. Blockchain geliştirmekten bahsettiğinizde, Truffle gitmek için popüler bir duraktır. Truffle Suite'teki Truffle Suite'e göz atın: Akıllı Sözleşmeler için Tatlı Araçlar. - ganaj CLI
Truffle ile birlikte iyi çalışan bir başka araç da Ganache-CLI'dir. Truffle Suite ekibi tarafından inşa edilmiş ve bakımı yapılmıştır. Oluşturup derledikten sonra, blok zinciri uygulamaları geliştirmek ve çalıştırmak için bir öykünücüye ihtiyacınız var ve ardından kullanılacak akıllı sözleşmeleri dağıtın. Ganache, işlem maliyeti, geri dönüştürülebilir hesaplar ve çok daha fazlası için gerçek parayı kullanmadan bir emülatörde bir sözleşme dağıtmanızı kolaylaştırır. Ganache CLI ve Ganache'de Ganache CLI hakkında daha fazla bilgi edinin. - remix
Remix, Ganache'ye bir alternatif gibidir, ancak aynı zamanda Ethereum akıllı sözleşmelerinin dağıtımında ve test edilmesinde gezinmeye yardımcı olacak bir GUI ile birlikte gelir. Bununla ilgili daha fazla bilgiyi Remix — Ethereum IDE ve topluluğu üzerinde bulabilirsiniz. Tek yapmanız gereken https://remix.ethereum.org adresini ziyaret etmek ve akıllı sözleşmeleri yazmak ve dağıtmak için GUI'yi kullanmak. - Web3
Web3, bir Ethereum düğümü ile etkileşime girmenizi sağlayan bir kitaplık koleksiyonudur. Bunlar, HTTP, IPC veya Web Sockets aracılığıyla sözleşmenin yerel veya uzak düğümleri olabilir. Web3.js'ye Giriş · Ethereum Blockchain Developer Crash Course, Web3 hakkında biraz bilgi edinmek için iyi bir yerdir. - IPFS
dApp'lerin oluşturulmasında kullanılan bir çekirdek protokol. Gezegenler Arası Dosya Sistemi (IPFS), verileri dağıtılmış bir dosya sisteminde depolamak ve paylaşmak için bir protokol ve eşler arası ağdır. IPFS, Dağıtılmış Web'e Güç Sağlar, IPFS ve genellikle nasıl kullanıldığı hakkında daha fazla bilgi verir.
Sıfırdan Bir Arka Uç API'si Oluşturma
Bu yüzden önce kullanılacak bir arka uç oluşturmalıyız ve Node.js kullanıyoruz. Yeni bir Node.js API oluşturmak istediğimizde yapacağımız ilk şey bir npm paketi başlatmak. Muhtemelen bildiğiniz gibi, npm, Node Package Manager anlamına gelir ve Node.js ikili dosyasıyla önceden paketlenmiş olarak gelir. Bu yüzden yeni bir klasör oluşturuyoruz ve buna “blockchain-music” diyoruz. Bu klasör dizinindeki terminali açıyoruz ve ardından aşağıdaki komutu çalıştırıyoruz:
$ npm init -y && touch server.js routes.js
Bu, projeyi bir package.json dosyasıyla başlatır ve tüm istemlere evet yanıtı verir. Ardından, API'de routes
fonksiyonlarını yazmak için bir server.js dosyası ve bir route.js dosyası da oluşturuyoruz.
Tüm bunlardan sonra, yapımızı kolay ve anlaşılır hale getirmek için ihtiyaç duyduğumuz paketleri kurmanız gerekecek. Bu süreç süreklidir, yani projenizin geliştirilmesi sırasında istediğiniz zaman bir paket kurabilirsiniz.
Şimdi ihtiyacımız olan en önemlilerini yükleyelim:
- Express.js
- @trüf/sözleşme
- Truffle.js
- web3.js
- dotenv
-
short-id
- MongoDB
- düğüm
Ayrıca yerel ortamınızda her yerde kullanabilmeniz için Truffle.js'yi global olarak yüklemeniz gerekir. Hepsini bir kerede kurmak istiyorsanız, Terminalinizde aşağıdaki kodu çalıştırın:
$ npm install nodemon truffle-contract dotenv mongodb shortid express web3 --save && npm install truffle -g
--save
bayrağı paketin adını package.json dosyasına kaydetmek içindir. -g
bayrağı, üzerinde çalışacağımız herhangi bir projede kullanabilmemiz için bu özel paketi global olarak depolamak içindir.
Ardından, kullanım için MongoDB veritabanı gizli URI'mizi saklayabileceğimiz bir .env dosyası oluşturuyoruz. Bunu Terminalde touch.env çalıştırarak yapıyoruz. Henüz MongoDB ile bir veritabanı hesabınız yoksa, önce MongoDB sayfasından başlayın.
dotenv paketi, depolanan değişkenimizi Node.js işlem ortamına aktarır. Parolalarınızın ve özel verilerinizin sızdırılmasını önlemek için lütfen genel depolara gönderirken .env dosyasını zorlamadığınızdan emin olun.
Ardından, package.json dosyamıza projemizin inşa ve geliştirme aşamaları için scriptler eklememiz gerekiyor. Şu anda package.json'umuz şuna benziyor:
{ "name": "test", "version": "1.0.0", "description": "", "main": "server.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "express": "^4.17.1", "socket.io": "^2.3.0", "truffle-contract": "^4.0.31", "web3": "^1.3.0" } }
Ardından, nodemon sunucusunu kullanmak için package.json dosyasına bir başlatma komut dosyası ekleyeceğiz, böylece değişiklik yaptığımızda sunucunun kendisini yeniden başlatacak ve düğüm sunucusunu doğrudan kullanan bir derleme komut dosyası şöyle görünebilir:
{ "name": "test", "version": "1.0.0", "description": "", "main": "server.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "nodemon server.js", "build": "node server.js" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "express": "^4.17.1", "socket.io": "^2.3.0", "truffle-contract": "^4.0.31", "web3": "^1.3.0" } }
Ardından, daha önce global olarak kurduğumuz Truffle paketini kullanarak akıllı sözleşmemizde kullanmak için Truffle'ı başlatmamız gerekiyor. Projelerimizin aynı klasöründe aşağıdaki komutu terminalimizde çalıştırıyoruz:
$ truffle init
Ardından server.js dosyamıza kodumuzu yazmaya başlayabiliriz. Yine, müşterilerin diğer her kullanıcının erişmesi ve dinlemesi için müzik yükleyebileceği basit bir merkezi olmayan müzik mağazası uygulaması oluşturmaya çalışıyoruz.
Server.js'miz , bileşenlerin kolay birleştirilmesi ve ayrıştırılması için temiz olmalıdır, bu nedenle rotalar ve diğer işlevler, route.js gibi diğer dosyalara konacaktır. Örnek server.js'miz şunlar olabilir:
require('dotenv').config(); const express= require('express') const app =express() const routes = require('./routes') const Web3 = require('web3'); const mongodb = require('mongodb').MongoClient const contract = require('truffle-contract'); app.use(express.json()) mongodb.connect(process.env.DB,{ useUnifiedTopology: true },(err,client)=>{ const db =client.db('Cluster0') //home routes(app,db) app.listen(process.env.PORT || 8082, () => { console.log('listening on port 8082'); }) })
Temel olarak, ihtiyaç duyduğumuz kitaplıkları require
ile içe aktarıyoruz, ardından app.use kullanarak app.use
JSON kullanımına izin veren bir ara katman yazılımı ekliyoruz, ardından MongoDB veritabanımıza bağlanıp veritabanı erişimini alıyoruz ve ardından hangi veritabanı kümesini belirliyoruz. erişmeye çalışıyoruz (bu eğitim için “Cluster0” dır ). Bundan sonra işlevi çağırır ve onu route dosyasından içe aktarırız. Son olarak, 8082
numaralı bağlantı noktasındaki herhangi bir bağlantı girişimini dinliyoruz.
Bu server.js dosyası, uygulamayı başlatmak için yalnızca bir barebone. route.js dosyasını içe aktardığımıza dikkat edin. Bu dosya, API'miz için rota uç noktalarını tutacaktır. Ayrıca kullanmamız gereken paketleri server.js dosyasına aktardık ve bunları ilklendirdik.
Kullanıcı tüketimi için beş uç nokta oluşturacağız:
- Kullanıcıları yalnızca e-posta yoluyla kaydetmek için kayıt uç noktası. İdeal olarak, bunu bir e-posta ve parola ile yapardık, ancak yalnızca her bir kullanıcıyı tanımlamak istediğimizden, bu öğreticinin kısalığı uğruna parola güvenliği ve karma işlemine girmeyeceğiz.
POST /register Requirements: email
- Kullanıcılar için e-posta ile oturum açma bitiş noktası.
POST /login Requirements: email
- Kullanıcılar için uç nokta yükleyin — müzik dosyasının verilerini alan API. Ön uç, MP3/WAV dosyalarını bir ses arabelleğine dönüştürecek ve bu arabelleği API'ye gönderecektir.
POST /upload Requirements: name, title of music, music file buffer or URL stored
- Müzik arabelleği verilerini, isteyen herhangi bir kayıtlı kullanıcıya sağlayacak ve ona kimlerin eriştiğini kaydedecek erişim uç noktasına.
GET /access/{email}/{id} Requirements: email, id
- Ayrıca tüm müzik kitaplığına erişim sağlamak ve sonuçları kayıtlı bir kullanıcıya iade etmek istiyoruz.
GET /access/{email} Requirements: email
Daha sonra route.js dosyamıza route fonksiyonlarımızı yazıyoruz. Veritabanı depolama ve alma özelliklerini kullanırız ve ardından başka bir dosya veya klasöre aktarılmasını mümkün kılmak için dosyanın sonunda rota işlevini dışa aktardığımızdan emin oluruz.
const shortid = require('short-id') function routes(app, db){ app.post('/register', (req,res)=>{ let email = req.body.email let idd = shortid.generate() if(email){ db.findOne({email}, (err, doc)=>{ if(doc){ res.status(400).json({"status":"Failed", "reason":"Already registered"}) }else{ db.insertOne({email}) res.json({"status":"success","id":idd}) } }) }else{ res.status(400).json({"status":"Failed", "reason":"wrong input"}) } }) app.post('/login', (req,res)=>{ let email = req.body.email if(email){ db.findOne({email}, (err, doc)=>{ if(doc){ res.json({"status":"success","id":doc.id}) }else{ res.status(400).json({"status":"Failed", "reason":"Not recognised"}) } }) }else{ res.status(400).json({"status":"Failed", "reason":"wrong input"}) } }) app.post('/upload', (req,res)=>{ let buffer = req.body.buffer let name = req.body.name let title = req.body.title if(buffer && title){ }else{ res.status(400).json({"status":"Failed", "reason":"wrong input"}) } }) app.get('/access/:email/:id', (req,res)=>{ if(req.params.id && req.params.email){ }else{ res.status(400).json({"status":"Failed", "reason":"wrong input"}) } }) } module.exports = routes
Bu route
fonksiyonunun içinde, hem app
hem de db
parametreleri içinde çağrılan birçok başka fonksiyonumuz var. Bunlar, kullanıcıların URL'de bir uç nokta belirtmesini sağlayan API uç noktası işlevleridir. Sonuç olarak, bu işlevlerden birinin yürütülmesini seçiyoruz ve gelen isteklere yanıt olarak sonuçlar sağlıyoruz.
Dört ana uç nokta fonksiyonumuz var:
-
get
: kayıt işlemlerini okumak için -
post
: kayıt işlemleri oluşturmak için -
put
: kayıt işlemlerini güncellemek için -
delete
: kayıt işlemlerini silmek için
Bu routes
fonksiyonunda get
ve post
işlemlerini kullandık. Kayıt, giriş ve yükleme işlemleri için post
kullanıyoruz ve veri işlemlerine erişmek için get
. Bununla ilgili biraz daha fazla açıklama için Jamie Corkhill'in "Düğümle Nasıl Başlanır: API'lere Giriş, HTTP ve ES6+ JavaScript" başlıklı makalesine göz atabilirsiniz.
Yukarıdaki kodda, register route'daki gibi bazı veritabanı işlemlerini de görebiliriz. Yeni bir kullanıcının e-postasını db.createa
db.findOne
oturum açma işlevinde e-postayı kontrol ettik. Şimdi hepsini yapmadan önce bir koleksiyon veya tabloyu db.collection
metodu ile isimlendirmemiz gerekiyor. Bundan sonra ele alacağımız şey tam olarak bu.
Not : MongoDB'deki veritabanı işlemleri hakkında daha fazla bilgi edinmek için mongo Shell Methods belgelerine bakın.
Sağlamlıkla Basit Bir Blockchain Akıllı Sözleşmesi Oluşturma
Şimdi, verilerimizi basitçe depolamak ve ihtiyacımız olduğunda almak için Solidity'de (akıllı sözleşmelerin yazıldığı dil budur) bir Blockchain sözleşmesi yazacağız. Saklamak istediğimiz veriler müzik dosyası verileridir, yani müziği IPFS'ye yüklememiz ve ardından arabelleğin adresini bir blok zincirinde saklamamız gerekir.
İlk olarak, sözleşme klasöründe yeni bir dosya oluşturup adını Inbox.sol olarak adlandırıyoruz. Akıllı bir sözleşme yazmak için Solidity hakkında iyi bir anlayışa sahip olmak faydalıdır, ancak JavaScript'e benzer olduğu için zor değildir.
Not : Solidity hakkında daha fazla bilgi edinmek istiyorsanız, başlamanız için makalenin altına birkaç kaynak ekledim.
pragma solidity ^0.5.0; contract Inbox{ //Structure mapping (string=>string) public ipfsInbox; //Events event ipfsSent(string _ipfsHash, string _address); event inboxResponse(string response); //Modifiers modifier notFull (string memory _string) { bytes memory stringTest = bytes(_string); require(stringTest.length==0); _; } // An empty constructor that creates an instance of the conteact constructor() public{} //takes in receiver's address and IPFS hash. Places the IPFSadress in the receiver's inbox function sendIPFS(string memory _address, string memory _ipfsHash) notFull(ipfsInbox[_address]) public{ ipfsInbox[_address] = _ipfsHash; emit ipfsSent(_ipfsHash, _address); } //retrieves hash function getHash(string memory _address) public view returns(string memory) { string memory ipfs_hash=ipfsInbox[_address]; //emit inboxResponse(ipfs_hash); return ipfs_hash; } }
Sözleşmemizde iki ana işlevimiz var: sendIPFS
ve getHash
işlevleri. Fonksiyonlardan bahsetmeden önce Inbox
adında bir sözleşme tanımlamamız gerektiğini görebiliriz. Bu sınıfın içinde ipfsInbox
nesnesinde kullanılan yapılar var (önce olaylar, sonra değiştiriciler).
Yapıları ve olayları tanımladıktan sonra, constructor
işlevini çağırarak sözleşmeyi başlatmamız gerekiyor. Daha sonra üç fonksiyon tanımladık. (Test sonuçları için testte checkInbox
işlevi kullanıldı.)
sendIPFS
, kullanıcının tanımlayıcıyı ve hash adresini girdikten sonra blok zincirinde depolandığı yerdir. getHash
işlevi, tanımlayıcı verildiğinde karma adresini alır. Yine, bunun arkasındaki mantık, nihayetinde müziği IPFS'de saklamak istediğimizdir. Nasıl çalıştığını test etmek için bir Remix IDE'ye atlayabilir, sözleşmenizi kopyalayabilir, yapıştırabilir ve test edebilir, ayrıca hataları ayıklayabilir ve yeniden çalıştırabilirsiniz (umarım buna gerek kalmaz!).
Kodumuzun remixte doğru çalıştığını test ettikten sonra, onu Truffle paketi ile yerel olarak derlemeye geçelim. Ama önce, dosyalarımızda bazı değişiklikler yapmamız ve ganache-cli
kullanarak öykünücüümüzü kurmamız gerekiyor:
İlk ganache-cli
. Aynı dizinde, terminalinizde aşağıdaki komutu çalıştırın:
$ npm install ganache-cli -g
Ardından başka bir Terminal açalım ve aynı klasörde başka bir komut çalıştıralım:
$ ganache-cli
Bu, blok zinciri sözleşmemizin bağlanması ve çalışması için öykünücüyü başlatır. Terminali simge durumuna küçültün ve kullandığınız diğer Terminal ile devam edin.
Şimdi, Windows'ta bir Linux/Mac OS veya truffle-config.js kullanıyorsanız truffle.js dosyasına gidin ve bu dosyayı şöyle görünecek şekilde değiştirin:
const path = require("path"); module.exports = { // to customize your Truffle configuration! contracts_build_directory: path.join(__dirname, "/build"), networks: { development: { host: "127.0.0.1", port: 8545, network_id: "*" //Match any network id } } };
Temel olarak yaptığımız şey, akıllı sözleşmenin JSON dosyalarına dönüştürüldüğü derleme klasörünün yolunu eklemek. Ardından Truffle'ın taşıma için kullanması gereken ağı da belirledik.
Ardından, yine geçişler klasöründe 2_migrate_inbox.js adlı yeni bir dosya oluşturun ve dosyaların içine aşağıdaki kodu ekleyin:
var IPFSInbox = artifacts.require("./Inbox.sol"); module.exports = function(deployer) { deployer.deploy(IPFSInbox); };
Bunu, Truffle geçişi sırasında dağıtım işlevini kullanarak sözleşme dosyasını almak ve otomatik olarak bir deployer
dağıtmak için yaptık.
Yukarıdaki değişikliklerden sonra çalıştırıyoruz:
$ truffle compile
Sonunda başarılı derlemeyi gösteren bazı mesajlar görmeliyiz, örneğin:
> Compiled successfully using: - solc: 0.5.16+commit.9c3226ce.Emscripten.clang
Ardından, aşağıdakileri çalıştırarak sözleşmemizi taşırız:
$ truffle migrate
Sözleşmelerimizi başarıyla taşıdıktan sonra, sonunda şöyle bir şeye sahip olmalıyız:
Summary ======= > Total deployments: 1 > Final cost: 0.00973432 ETH
Ve neredeyse bitirdik! API'mizi Node.js ile oluşturduk ve ayrıca akıllı sözleşmemizi kurup oluşturduk.
Ayrıca, sözleşmemizin davranışını test etmek ve istenen davranış olduğundan emin olmak için sözleşmemiz için testler yazmalıyız. Testler genellikle yazılır ve test
klasörüne yerleştirilir. Test klasöründe oluşturulan InboxTest.js adlı bir dosyaya yazılmış örnek bir test:
const IPFSInbox = artifacts.require("./Inbox.sol") contract("IPFSInbox", accounts =>{ it("emit event when you send a ipfs address", async()=>{ //ait for the contract const ipfsInbox = await IPFSInbox.deployed() //set a variable to false and get event listener eventEmitted = false //var event = () await ipfsInbox.ipfsSent((err,res)=>{ eventEmitted=true }) //call the contract function which sends the ipfs address await ipfsInbox.sendIPFS(accounts[1], "sampleAddress", {from: accounts[0]}) assert.equal(eventEmitted, true, "sending an IPFS request does not emit an event") }) })
Bu yüzden aşağıdakileri çalıştırarak testimizi çalıştırıyoruz:
$ truffle test
Test klasöründeki dosyalarla sözleşmemizi test eder ve başarılı ve başarısız testlerin sayısını gösterir. Bu eğitim için şunları almalıyız:
$ truffle test Using network 'development'. Compiling your contracts... =========================== > Compiling .\contracts\Inbox.sol > Artifacts written to C:\Users\Ademola\AppData\Local\Temp\test--2508-n0vZ513BXz4N > Compiled successfully using: — solc: 0.5.16+commit.9c3226ce.Emscripten.clang Contract: IPFSInbox √ emit event when you send an ipfs address (373ms) 1 passing (612ms)
Akıllı Sözleşmeyi Web3 Kullanarak Arka Uç API'sine Entegre Etme
Çoğu zaman öğreticileri gördüğünüzde, ön ucu doğrudan blok zincirine entegre etmek için oluşturulmuş merkezi olmayan uygulamalar görürsünüz. Ancak, örneğin üçüncü taraf arka uç API'lerini ve hizmetlerini kullanırken veya bir CMS oluşturmak için blok zinciri kullanırken, arka uca entegrasyonun da gerekli olduğu zamanlar vardır.
Uzak veya yerel Ethereum düğümlerine erişmemize ve bunları uygulamalarımızda kullanmamıza yardımcı olduğu için Web3'ün kullanımı bu amaç için çok önemlidir. Devam etmeden önce, yerel ve uzak Ethereum düğümlerini tartışacağız. Yerel düğümler, sistemimizde ganache-cli
gibi öykünücülerle dağıtılan düğümlerdir, ancak uzak düğüm, ropsten veya rinkeby gibi çevrimiçi musluklara/platformlara dağıtılandır. Daha derine dalmak için, Truffle ve Ropsten ile akıllı sözleşmeleri dağıtmak için ropsten'de nasıl dağıtılacağına ilişkin 5 dakikalık kılavuzu takip edebilir veya trüf cüzdan sağlayıcısını kullanabilir ve Akıllı Sözleşmelerinizi Dağıtmanın Daha Kolay Yolu aracılığıyla dağıtabilirsiniz.
Bu öğreticide ganache-cli
kullanıyoruz, ancak ropsten üzerinde konuşlandırıyor olsaydık, sözleşme adresimizi .env dosyamızdaki gibi bir yere kopyalamalı veya saklamalıydık, ardından server.js dosyasını güncellemeye, web3'ü içe aktarmaya, içe aktarmaya geçmeliydik. taşınan sözleşme ve bir Web3 örneği ayarlayın.
require('dotenv').config(); const express= require('express') const app =express() const routes = require('./routes') const Web3 = require('web3'); const mongodb = require('mongodb').MongoClient const contract = require('truffle-contract'); const artifacts = require('./build/Inbox.json'); app.use(express.json()) if (typeof web3 !== 'undefined') { var web3 = new Web3(web3.currentProvider) } else { var web3 = new Web3(new Web3.providers.HttpProvider('https://localhost:8545')) } const LMS = contract(artifacts) LMS.setProvider(web3.currentProvider) mongodb.connect(process.env.DB,{ useUnifiedTopology: true }, async(err,client)=>{ const db =client.db('Cluster0') const accounts = await web3.eth.getAccounts(); const lms = await LMS.deployed(); //const lms = LMS.at(contract_address) for remote nodes deployed on ropsten or rinkeby routes(app,db, lms, accounts) app.listen(process.env.PORT || 8082, () => { console.log('listening on port '+ (process.env.PORT || 8082)); }) })
server.js dosyasında, web3 örneğinin zaten başlatılıp başlatılmadığını kontrol ediyoruz. Değilse, daha önce tanımladığımız ağ bağlantı noktasında ( 8545
) başlatıyoruz. Ardından, taşınan JSON dosyasına ve truffle-contract
paketine dayalı bir sözleşme oluşturuyoruz ve sözleşme sağlayıcıyı, şimdiye kadar başlatılmış olması gereken Web3 bulut sunucusu sağlayıcısına ayarlıyoruz.
Daha sonra web3.eth.getAccounts
ile hesapları alıyoruz. Geliştirme aşaması için, hala çalışmakta olan ganache-cli
bize kullanmamız için bir sözleşme adresi vermesini isteyen sözleşme sınıfımızdaki konuşlandırılmış işlevi çağırıyoruz. Ancak sözleşmemizi uzak bir düğüme zaten dağıtmışsak, adresi argüman olarak girerek bir işlev çağırırız. Örnek fonksiyon, yukarıdaki kodumuzda tanımlanan lms
değişkeninin altında yorumlanmıştır. Ardından, uygulama örneğini, veritabanı örneğini, sözleşme örneğini ( lms
) ve hesap verilerini bağımsız değişkenler olarak girerek routes
işlevini çağırırız. Son olarak, 8082
numaralı bağlantı noktasındaki istekleri dinliyoruz.
Ayrıca, şimdiye kadar MongoDB paketini kurmuş olmamız gerekirdi, çünkü API'mizde veritabanımız olarak kullanıyoruz. Bunu elde ettikten sonra, müzik verilerini kaydetme ve alma gibi görevleri gerçekleştirmek için sözleşmede tanımlanan yöntemleri kullandığımız rotalar sayfasına geçiyoruz.
Sonunda, route.js dosyamız şöyle görünmelidir:
const shortid = require('short-id') const IPFS =require('ipfs-api'); const ipfs = IPFS({ host: 'ipfs.infura.io', port: 5001,protocol: 'https' }); function routes(app, dbe, lms, accounts){ let db= dbe.collection('music-users') let music = dbe.collection('music-store') app.post('/register', (req,res)=>{ let email = req.body.email let idd = shortid.generate() if(email){ db.findOne({email}, (err, doc)=>{ if(doc){ res.status(400).json({"status":"Failed", "reason":"Already registered"}) }else{ db.insertOne({email}) res.json({"status":"success","id":idd}) } }) }else{ res.status(400).json({"status":"Failed", "reason":"wrong input"}) } }) app.post('/login', (req,res)=>{ let email = req.body.email if(email){ db.findOne({email}, (err, doc)=>{ if(doc){ res.json({"status":"success","id":doc.id}) }else{ res.status(400).json({"status":"Failed", "reason":"Not recognised"}) } }) }else{ res.status(400).json({"status":"Failed", "reason":"wrong input"}) } }) app.post('/upload', async (req,res)=>{ let buffer = req.body.buffer let name = req.body.name let title = req.body.title let id = shortid.generate() + shortid.generate() if(buffer && title){ let ipfsHash = await ipfs.add(buffer) let hash = ipfsHash[0].hash lms.sendIPFS(id, hash, {from: accounts[0]}) .then((_hash, _address)=>{ music.insertOne({id,hash, title,name}) res.json({"status":"success", id}) }) .catch(err=>{ res.status(500).json({"status":"Failed", "reason":"Upload error occured"}) }) }else{ res.status(400).json({"status":"Failed", "reason":"wrong input"}) } }) app.get('/access/:email', (req,res)=>{ if(req.params.email){ db.findOne({email: req.body.email}, (err,doc)=>{ if(doc){ let data = music.find().toArray() res.json({"status":"success", data}) } }) }else{ res.status(400).json({"status":"Failed", "reason":"wrong input"}) } }) app.get('/access/:email/:id', (req,res)=>{ let id = req.params.id if(req.params.id && req.params.email){ db.findOne({email:req.body.email},(err,doc)=>{ if(doc){ lms.getHash(id, {from: accounts[0]}) .then(async(hash)=>{ let data = await ipfs.files.get(hash) res.json({"status":"success", data: data.content}) }) }else{ res.status(400).json({"status":"Failed", "reason":"wrong input"}) } }) }else{ res.status(400).json({"status":"Failed", "reason":"wrong input"}) } }) } module.exports = routes
At the beginning of the routes file, we imported the short-id
package and ipfs-http-client
and then initialized IPFS with the HTTP client using the backend URL ipfs.infura.io
and port 5001
. This allowed us to use the IPFS methods to upload and retrieve data from IPFS (check out more here).
In the upload route, we save the audio buffer to IPFS which is better compared to just storing it on the blockchain for anyone registered or unregistered to use. Then we saved the address of the buffer in the blockchain by generating an ID and using it as an identifier in the sendIFPS
function. Finally, then we save all the other data associated with the music file to our database. We should not forget to update our argument in the routes function since we changed it in the server.js file.
In the access route using id
, we then retrieve our data by getting the id
from the request, using the id
to access the IPFS hash address, and then access the audio buffer using the address. But this requires authentication of a user by email which is done before anything else.
Phew, we're done ! Right now we have an API that can receive requests from users, access a database, and communicate to a node that has the software running on them. We shouldn't forget that we have to export our function with module.exports
though!
As we have noticed, our app is a decentralized app . However, it's not fully decentralized as we only stored our address data on the blockchain and every other piece of data was stored securely in a centralized database which is the basis for semi-dApps . So the consumption of data can be done directly via request or using a frontend application in JavaScript to send fetch requests.
Our music store backend app can now safely store music data and provide access to anyone who needs to access it, provided it is a registered user. Using blockchain for music sharing makes it cheaper to store music data while focusing on connecting artists directly with users, and perhaps it could help them generate revenue that way. This wouldn't require a middleman that uses royalty; instead, all of the revenue would go to the artist as users request their music to either download or stream. A good example of a music streaming application that uses blockchain just like this is Opus OPUS: Decentralized music sharing platform. However, there are also a few others like Musicoin, Audius, and Resonate.
Sıradaki ne?
The final thing after coding is to start our server by running npm run start
or npm run build
and test our backend endpoints on either the browser or with Postman. After running and testing our API we could add more features to our backend and blockchain smart contract. If you'd like to get more guidance on that, please check the further reading section for more articles.
It's worth mentioning that it is critical to write unit and integration tests for our API to ensure correct and desirable behaviors. Once we have all of that done, we can deploy our application on the cloud for public use. This can be done on its own with or without adding a frontend (microservices) on Heroku, GCP, or AWS for public use. Happy coding!
Note : You can always check my repo for reference. Also, please note that the .env file containing the MongoDB database URI is included for security reasons.
Further Reading And Related Resources
- “How to Build Ethereum Dapp with React.js: Complete Step-By-Step Guide,” Gregory McCubbin
- “Ethereum + IPFS + React DApp Tutorial Pt. 1,” Alexander Ma
- “Ethereum Development with Go,” Miguel Mota
- “Create your first Ethereum dAPP with Web3 and Vue.JS (Part 1),” Nico Vergauwen
- “Deploy a Smart Contract on Ethereum with Python, Truffle and web3py,” Gabriel Saldanha
- “Why Use Blockchain Technology?,” Bernard Marr
- “How To Build Your Own Blockchain Using Node.js,” DevTeam.Space
- “How To Build A Blockchain App With Ethereum, Web3.js & Solidity Smart Contracts,” Gregory McCubbin
- “How To Build A Simple Cryptocurrency Blockchain In Node.js,” Alfrick Opidi
- “How Blockchain Technology Is Going To Revolutionize Ecommerce,” Sergii Shanin
- “4 Ways Blockchain Will Transform Higher Education — Smarter With Gartner,” Susan Moore
- “How To Learn Solidity: The Ultimate Ethereum Coding Tutorial,” Ryan Molecke
- “Developing Ethereum Smart Contracts For Beginners,” Coursetro
- “Learn about Ethereum,” Ethereum official site