Cara Membangun API Node.js Untuk Ethereum Blockchain
Diterbitkan: 2022-03-10Teknologi Blockchain telah meningkat dalam sepuluh tahun terakhir, dan telah menghidupkan sejumlah besar produk dan platform seperti Chainalysis (teknologi keuangan), Burstiq (teknologi kesehatan), Filament (IoT), Opus (streaming musik) dan Mata (keamanan siber).
Dari contoh-contoh ini, kita dapat melihat bahwa blockchain melintasi banyak produk dan kasus penggunaan — menjadikannya sangat penting dan berguna. Di fintech (teknologi keuangan), ini digunakan sebagai buku besar terdesentralisasi untuk keamanan dan transparansi di tempat-tempat seperti Chain, Chainalysis, dan juga berguna dalam teknologi kesehatan untuk keamanan data kesehatan sensitif di Burstiq dan Robomed — tidak ketinggalan teknologi media seperti Opus dan Audius yang juga menggunakan blockchain untuk transparansi royalti dan dengan demikian mendapatkan royalti penuh.
Ocular menggunakan keamanan yang dilengkapi dengan blockchain untuk manajemen identitas untuk sistem biometrik, sementara Filament menggunakan buku besar blockchain untuk komunikasi terenkripsi secara real-time. Ini menunjukkan betapa pentingnya blockchain bagi kita dengan membuat hidup kita lebih baik. Tapi apa sebenarnya blockchain itu?
Blockchain adalah database yang dibagikan di seluruh jaringan komputer. Setelah rekor ditambahkan ke rantai, cukup sulit untuk mengubahnya. Untuk memastikan bahwa semua salinan database adalah sama, jaringan melakukan pemeriksaan konstan.
Jadi mengapa kita membutuhkan blockchain? Blockchain adalah cara yang aman untuk merekam aktivitas dan menjaga data tetap segar sambil mempertahankan catatan riwayatnya dibandingkan dengan catatan atau basis data tradisional di mana peretasan, kesalahan, dan waktu henti sangat mungkin terjadi. Data tidak dapat dirusak oleh siapa pun atau terhapus secara tidak sengaja, dan Anda mendapat manfaat dari jejak data historis dan catatan terkini yang tidak dapat dihapus atau menjadi tidak dapat diakses karena waktu henti server.
Karena seluruh blockchain diduplikasi di banyak komputer, setiap pengguna dapat melihat seluruh blockchain. Transaksi atau catatan diproses bukan oleh satu administrator pusat, tetapi oleh jaringan pengguna yang bekerja untuk memverifikasi data dan mencapai konsensus.
Aplikasi yang menggunakan blockchain disebut dApps (Decentralised Applications). Melihat sekeliling hari ini, sebagian besar kita akan menemukan aplikasi terdesentralisasi di fintech, tetapi blockchain melampaui keuangan terdesentralisasi. Kami memiliki platform kesehatan, platform streaming/berbagi musik, platform e-niaga, platform keamanan siber, dan IoT yang bergerak menuju aplikasi terdesentralisasi (dApps) seperti yang disebutkan di atas.
Jadi, kapan masuk akal untuk mempertimbangkan menggunakan blockchain untuk aplikasi kita, daripada database atau catatan standar?
Aplikasi Umum Blockchain
- Mengelola Dan Mengamankan Hubungan Digital
Kapan pun Anda ingin menyimpan catatan aset jangka panjang yang transparan (misalnya, untuk mencatat hak milik atau apartemen), blockchain bisa menjadi solusi ideal. 'Kontrak pintar' Ethereum, khususnya, sangat bagus untuk memfasilitasi hubungan digital. Dengan kontrak cerdas, pembayaran otomatis dapat dilepaskan ketika pihak-pihak dalam suatu transaksi setuju bahwa persyaratan mereka telah terpenuhi. - Menghilangkan Perantara/Gatekeeper
Misalnya, sebagian besar penyedia saat ini harus berinteraksi dengan tamu melalui platform agregator terpusat, seperti Airbnb atau Uber (yang, pada gilirannya, memotong setiap transaksi). Blockchain bisa mengubah semua itu.
Misalnya, TUI sangat yakin akan kekuatan blockchain sehingga menjadi pionir cara untuk menghubungkan pelaku bisnis perhotelan dan pelanggan secara langsung. Dengan begitu, mereka dapat bertransaksi melalui blockchain dengan cara yang mudah, aman, dan konsisten, daripada melalui platform pemesanan pusat. - Rekam Transaksi Aman Antar Mitra Untuk Memastikan Kepercayaan
Basis data tradisional mungkin bagus untuk merekam transaksi sederhana antara dua pihak, tetapi ketika keadaan menjadi lebih rumit, blockchain dapat membantu mengurangi kemacetan dan menyederhanakan hubungan. Terlebih lagi, keamanan tambahan dari sistem terdesentralisasi membuat blockchain ideal untuk transaksi secara umum.
Contohnya adalah University Of Melbourne yang mulai menyimpan catatannya di blockchain. Kasus penggunaan yang paling menjanjikan untuk blockchain dalam pendidikan tinggi adalah mengubah "penyimpanan catatan" gelar, sertifikat, dan diploma. Ini menghemat banyak biaya dari server khusus untuk penyimpanan atau catatan. - Menyimpan Catatan Tindakan Sebelumnya Untuk Aplikasi Di Mana Data Berada Dalam Fluks Konstan
Blockchain adalah cara yang lebih baik dan lebih aman untuk merekam aktivitas dan menjaga data tetap segar sambil mempertahankan catatan riwayatnya. Data tidak dapat dirusak oleh siapa pun atau terhapus secara tidak sengaja, dan Anda mendapat manfaat dari jejak data historis, ditambah catatan terkini secara instan. Contoh use case yang baik adalah blockchain dalam e-commerce, baik blockchain maupun e-commerce melibatkan transaksi.
Blockchain membuat transaksi ini lebih aman dan lebih cepat sementara aktivitas e-commerce bergantung padanya. Teknologi Blockchain memungkinkan pengguna untuk berbagi dan menyimpan aset digital dengan aman baik secara otomatis maupun manual. Teknologi ini memiliki kapasitas untuk menangani aktivitas pengguna seperti pemrosesan pembayaran, pencarian produk, pembelian produk, dan layanan pelanggan. Ini juga mengurangi biaya yang dikeluarkan untuk manajemen inventaris dan pemrosesan pembayaran. - Desentralisasi Memungkinkan Untuk Digunakan Di Mana Saja
Tidak seperti sebelumnya di mana kami harus membatasi diri pada wilayah tertentu karena berbagai alasan seperti kebijakan pertukaran mata uang, keterbatasan gateway pembayaran membuat akses ke sumber daya keuangan banyak negara tidak di wilayah atau benua Anda menjadi sulit. Dengan kebangkitan dan kekuatan desentralisasi blockchain atau sistem peer-to-peer, ini menjadi lebih mudah untuk bekerja dengan negara lain.
Misalnya, toko e-niaga di Eropa dapat memiliki konsumen di Afrika dan tidak memerlukan perantara untuk memproses permintaan pembayaran mereka. Selain itu, teknologi ini membuka pintu bagi pengecer online untuk memanfaatkan pasar konsumen di negara-negara yang jauh dengan bitcoin, yaitu cryptocurrency. - Blockhain Adalah Teknologi-Netral
Blockchain bekerja dengan semua dan semua tumpukan teknologi yang digunakan oleh pengembang. Anda tidak perlu mempelajari Node sebagai pengembang Python untuk menggunakan blockchain atau mempelajari Golang. Ini membuat blockchain sangat mudah digunakan.
Kami benar-benar dapat menggunakannya secara langsung dengan aplikasi front-end kami di Vue/React dengan blockchain yang bertindak sebagai satu-satunya basis data kami untuk tugas-tugas sederhana yang tidak rumit dan kasus penggunaan seperti mengunggah data atau mendapatkan hash untuk menampilkan catatan untuk pengguna kami, atau membangun permainan frontend seperti kasino permainan dan permainan taruhan (di mana dibutuhkan kepercayaan yang tinggi). Juga, dengan kekuatan web3, kita dapat menyimpan data dalam rantai secara langsung.
Sekarang, kita telah melihat cukup banyak keuntungan menggunakan blockchain, tetapi kapan kita tidak perlu repot menggunakan blockchain sama sekali?
Kekurangan Blockchain
- Pengurangan Kecepatan Untuk Transaksi Digital
Blockchain membutuhkan daya komputasi yang sangat besar, yang cenderung mengurangi kecepatan transaksi digital, meskipun ada solusi yang disarankan untuk menggunakan database terpusat saat membutuhkan transaksi berkecepatan tinggi dalam milidetik. - Kekekalan Data
Kekekalan data selalu menjadi salah satu kelemahan terbesar dari blockchain. Jelas bahwa banyak sistem mendapat manfaat darinya termasuk rantai pasokan, sistem keuangan, dan sebagainya. Namun, ia menderita fakta bahwa begitu data ditulis, itu tidak dapat dihapus. Setiap orang di bumi memiliki hak atas privasi. Namun, jika orang yang sama menggunakan platform digital yang berjalan pada teknologi blockchain, maka dia tidak akan dapat menghapus jejaknya dari sistem ketika dia tidak menginginkannya di sana. Dengan kata sederhana, tidak mungkin dia bisa menghilangkan jejaknya — meninggalkan hak privasi berkeping-keping. - Membutuhkan Keahlian Pengetahuan
Menerapkan dan mengelola proyek blockchain itu sulit. Dibutuhkan pengetahuan yang mendalam untuk melalui seluruh proses. Inilah sebabnya mengapa sulit untuk menemukan spesialis atau ahli blockchain karena membutuhkan banyak waktu dan upaya untuk melatih seorang ahli blockchain. Oleh karena itu artikel ini adalah tempat yang baik untuk memulai dan panduan yang baik jika Anda sudah memulai. - Interoperabilitas
Beberapa jaringan blockchain yang bekerja keras untuk memecahkan masalah buku besar yang didistribusikan secara unik membuatnya sulit untuk menghubungkannya atau mengintegrasikannya satu sama lain. Hal ini membuat komunikasi antara rantai yang berbeda menjadi sulit. - Integrasi Aplikasi Lama
Banyak bisnis dan aplikasi masih menggunakan sistem dan arsitektur lama; mengadopsi teknologi blockchain membutuhkan perombakan total dari sistem ini yang harus saya katakan tidak layak untuk banyak dari mereka.
Blockchain masih berkembang dan jatuh tempo sepanjang waktu jadi jangan heran jika kontra yang disebutkan hari ini berubah menjadi pro di kemudian hari. Bitcoin yang merupakan cryptocurrency adalah salah satu contoh populer dari blockchain, blockchain populer yang sedang naik daun selain cryptocurrency bitcoin adalah blockchain Ethereum. Bitcoin berfokus pada cryptocurrency sementara Ethereum lebih fokus pada kontrak pintar yang telah menjadi kekuatan pendorong utama untuk platform teknologi baru.
Bacaan yang direkomendasikan : Bitcoin vs. Ethereum: Apa Bedanya?
Mari Mulai Membangun API Kita
Dengan pemahaman yang kuat tentang blockchain, sekarang mari kita lihat bagaimana membangun blockchain Ethereum dan mengintegrasikannya ke dalam API standar di Node.js. Tujuan utamanya adalah untuk mendapatkan pemahaman yang baik tentang bagaimana platform dApps dan Blockchain sedang dibangun.
Sebagian besar dApps memiliki arsitektur dan struktur yang serupa. Pada dasarnya, kami memiliki pengguna yang berinteraksi dengan frontend dApp — baik web atau seluler — yang kemudian berinteraksi dengan API backend. Backend, kemudian, berdasarkan permintaan berinteraksi dengan kontrak pintar atau blockchain melalui node publik; ini menjalankan aplikasi Node.js atau backend menggunakan blockchain dengan langsung menjalankan perangkat lunak Node.js. Masih ada banyak hal di antara proses-proses ini, mulai dari memilih untuk membangun aplikasi yang sepenuhnya terdesentralisasi atau aplikasi semi-desentralisasi hingga memilih apa yang harus didesentralisasi dan bagaimana cara menyimpan kunci pribadi dengan aman.
Bacaan yang direkomendasikan : Arsitektur Aplikasi Terdesentralisasi: Back End, Keamanan dan Pola Desain
Hal Yang Harus Kita Ketahui Dulu
Untuk tutorial ini, kita akan mencoba membangun backend aplikasi toko musik terdesentralisasi yang menggunakan kekuatan blockchain Ethereum untuk menyimpan musik dan membagikannya untuk diunduh atau streaming.
Struktur dasar dari aplikasi yang kami coba buat memiliki tiga bagian:
- Otentikasi , yang dilakukan melalui email; tentu saja kita perlu menambahkan kata sandi terenkripsi ke aplikasi.
- Penyimpanan data , dengan data musik pertama disimpan di ipfs dan alamat penyimpanan disimpan di blockchain untuk pengambilan.
- Retrieval , dengan setiap pengguna yang diautentikasi dapat mengakses data yang tersimpan di platform kami dan menggunakannya.
Kami akan membangun ini dengan Node.js, tetapi Anda juga dapat membangun dengan Python atau bahasa pemrograman lainnya. Kita juga akan melihat cara menyimpan data media di IPFS, mendapatkan alamat dan menulis fungsi untuk menyimpan alamat ini — dan mengambil alamat ini dari blockchain dengan bahasa pemrograman Solidity.
Berikut adalah beberapa alat yang harus kita miliki untuk membangun atau bekerja dengan Ethereum dan Node.js.
- Node.js
Persyaratan pertama adalah aplikasi Node. Kami mencoba membangun aplikasi Node.js, jadi kami membutuhkan kompiler. Pastikan Anda telah menginstal Node.js — dan silakan unduh biner dukungan jangka panjang ( LTS ) terbaru. - Suite Truffle
Truffle adalah lingkungan pengembangan dan pengujian kontrak, serta saluran aset untuk blockchain Ethereum. Ini menyediakan lingkungan untuk kompilasi, pipelining, dan menjalankan skrip. Setelah Anda berbicara tentang mengembangkan blockchain, Truffle adalah tempat pemberhentian yang populer untuk dikunjungi. Lihat tentang Truffle Suite di Truffle Suite: Alat Manis untuk Kontrak Cerdas. - Ganache CLI
Alat lain yang bekerja dengan baik dengan Truffle adalah Ganache-CLI. Itu dibangun dan dikelola oleh tim Truffle Suite. Setelah membangun dan mengompilasi, Anda memerlukan emulator untuk mengembangkan dan menjalankan aplikasi blockchain, dan kemudian menerapkan kontrak pintar untuk digunakan. Ganache memudahkan Anda untuk menerapkan kontrak di emulator tanpa menggunakan uang sebenarnya untuk biaya transaksi, akun yang dapat didaur ulang, dan banyak lagi. Baca lebih lanjut tentang Ganache CLI di Ganache CLI dan Ganache. - remix
Remix seperti alternatif untuk Ganache, tetapi juga dilengkapi dengan GUI untuk membantu menavigasi penerapan dan pengujian kontrak pintar Ethereum. Anda dapat mempelajarinya lebih lanjut di Remix — Ethereum IDE & komunitas. Yang harus Anda lakukan adalah mengunjungi https://remix.ethereum.org dan menggunakan GUI untuk menulis dan menyebarkan kontrak pintar. - Web3
Web3 adalah kumpulan perpustakaan yang memungkinkan Anda untuk berinteraksi dengan node Ethereum. Ini bisa berupa node lokal atau jarak jauh dari kontrak melalui HTTP, IPC atau Web Sockets. Pengantar Web3.js · Kursus Singkat Pengembang Blockchain Ethereum adalah tempat yang baik untuk belajar sedikit tentang Web3. - IPFS
Protokol inti yang digunakan dalam membangun dApps. InterPlanetary File System (IPFS) adalah protokol dan jaringan peer-to-peer untuk menyimpan dan berbagi data dalam sistem file terdistribusi. IPFS Powers the Distributed Web menjelaskan lebih lanjut tentang IPFS dan bagaimana biasanya digunakan.
Membuat API Backend Dari Awal
Jadi pertama kita harus membuat backend untuk digunakan, dan kita menggunakan Node.js. Saat kita ingin membuat API Node.js baru, hal pertama yang akan kita lakukan adalah menginisialisasi paket npm. Seperti yang mungkin Anda ketahui, npm adalah singkatan dari Node Package Manager , dan sudah dikemas dengan biner Node.js. Jadi kami membuat folder baru dan menyebutnya "blockchain-music" . Kami membuka terminal di direktori folder itu, dan kemudian jalankan perintah berikut:
$ npm init -y && touch server.js routes.js
Ini memulai proyek dengan file package.json dan menjawab ya untuk semua permintaan. Kemudian kita juga membuat file server.js dan file route.js untuk menulis fungsi routes
di API.
Setelah semua ini, Anda harus menginstal paket-paket yang kami butuhkan untuk membuat build kami mudah dan lugas. Proses ini merupakan proses yang berkelanjutan, yaitu Anda dapat menginstal paket kapan saja selama pengembangan proyek Anda.
Mari kita instal yang paling penting yang kita butuhkan saat ini:
- Express.js
- @truffle/kontrak
- Truffle.js
- web3.js
- dotenv
-
short-id
- MongoDB
- nodemon
Anda juga harus menginstal Truffle.js secara global , sehingga Anda dapat menggunakannya di mana saja di lingkungan lokal Anda. Jika Anda ingin menginstal semuanya sekaligus, jalankan kode berikut di Terminal Anda:
$ npm install nodemon truffle-contract dotenv mongodb shortid express web3 --save && npm install truffle -g
Bendera --save
adalah untuk menyimpan nama paket dalam file package.json . Bendera -g
adalah untuk menyimpan paket khusus ini secara global, sehingga kita dapat menggunakannya dalam proyek apa pun yang akan kita kerjakan.
Kami kemudian membuat file .env di mana kami dapat menyimpan URI rahasia database MongoDB kami untuk digunakan. Kami melakukannya dengan menjalankan touch.env di Terminal. Jika Anda belum memiliki akun database dengan MongoDB, mulailah dengan halaman MongoDB terlebih dahulu.
Paket dotenv mengekspor variabel yang disimpan ke lingkungan proses Node.js. Harap pastikan bahwa Anda tidak mendorong file .env saat mendorong ke repositori publik untuk menghindari kebocoran kata sandi dan data pribadi Anda.
Selanjutnya, kita harus menambahkan skrip untuk fase pembangunan dan pengembangan proyek kita di file package.json kita. Saat ini package.json kami terlihat seperti ini:
{ "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" } }
Kami kemudian akan menambahkan skrip awal ke file package.json untuk menggunakan server nodemon sehingga setiap kali kami melakukan perubahan, skrip akan me-restart server itu sendiri, dan skrip build yang menggunakan server node secara langsung, akan terlihat seperti ini:
{ "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" } }
Selanjutnya kita harus menginisialisasi Truffle untuk digunakan dalam smart contract kita dengan menggunakan paket Truffle yang kita install secara global tadi. Di folder yang sama dari proyek kami, kami menjalankan perintah berikut di bawah ini di terminal kami:
$ truffle init
Kemudian kita bisa mulai menulis kode kita di file server.js kita. Sekali lagi, kami mencoba membangun aplikasi toko musik terdesentralisasi sederhana, di mana pelanggan dapat mengunggah musik untuk diakses dan didengarkan oleh setiap pengguna lain.
Server.js kami harus bersih untuk memudahkan penyambungan dan pemisahan komponen, sehingga rute dan fungsi lainnya akan diletakkan di file lain seperti route.js . Contoh server.js kami dapat berupa:
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'); }) })
Pada dasarnya, di atas kita mengimpor perpustakaan yang kita butuhkan dengan require
, lalu menambahkan middleware yang memungkinkan penggunaan JSON di API kita menggunakan app.use
, lalu hubungkan ke database MongoDB kita dan dapatkan akses database, lalu kita tentukan cluster database mana kami mencoba mengakses (untuk tutorial ini adalah "Cluster0" ). Setelah ini, kami memanggil fungsi dan mengimpornya dari file rute . Terakhir, kami mendengarkan setiap koneksi yang dicoba pada port 8082
.
File server.js ini hanyalah barebone untuk memulai aplikasi. Perhatikan bahwa kita mengimpor route.js . File ini akan menyimpan titik akhir rute untuk API kami. Kami juga mengimpor paket yang perlu kami gunakan di file server.js dan menginisialisasinya.
Kami akan membuat lima titik akhir untuk konsumsi pengguna:
- Titik akhir pendaftaran untuk mendaftarkan pengguna hanya melalui email. Idealnya, kami akan melakukannya dengan email dan kata sandi, tetapi karena kami hanya ingin mengidentifikasi setiap pengguna, kami tidak akan menjelajah ke keamanan kata sandi dan hashing demi singkatnya tutorial ini.
POST /register Requirements: email
- Titik akhir login untuk pengguna melalui email.
POST /login Requirements: email
- Upload endpoint untuk pengguna — API yang mendapatkan data file musik. Frontend akan mengonversi file MP3/WAV ke buffer audio dan mengirim buffer itu ke API.
POST /upload Requirements: name, title of music, music file buffer or URL stored
- Access endpoint yang akan memberikan data buffer musik ke setiap pengguna terdaftar yang memintanya, dan mencatat siapa yang mengaksesnya.
GET /access/{email}/{id} Requirements: email, id
- Kami juga ingin memberikan akses ke seluruh perpustakaan musik dan mengembalikan hasilnya ke pengguna terdaftar.
GET /access/{email} Requirements: email
Kemudian kami menulis fungsi rute kami di file route.js kami. Kami menggunakan fitur penyimpanan dan pengambilan database, dan kemudian memastikan kami mengekspor fungsi rute di akhir file untuk memungkinkan untuk diimpor ke file atau folder lain.
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
Di dalam fungsi route
ini, kami memiliki banyak fungsi lain yang dipanggil dalam parameter app
dan db
. Ini adalah fungsi titik akhir API yang memungkinkan pengguna menentukan titik akhir di URL. Pada akhirnya kami memilih salah satu dari fungsi ini untuk dijalankan dan memberikan hasil sebagai respons terhadap permintaan yang masuk.
Kami memiliki empat fungsi titik akhir utama:
-
get
: untuk membaca operasi record -
post
: untuk membuat operasi record -
put
: untuk memperbarui operasi record -
delete
: untuk menghapus operasi record
Dalam fungsi routes
ini, kami menggunakan operasi get
dan post
. Kami menggunakan post
untuk pendaftaran, login, dan operasi unggah, dan get
untuk mengakses operasi data. Untuk sedikit penjelasan lebih lanjut tentang itu, Anda dapat melihat artikel Jamie Corkhill tentang "Cara Memulai Dengan Node: Pengantar API, HTTP, dan ES6+ JavaScript".
Pada kode di atas, kita juga dapat melihat beberapa operasi database seperti pada rute register . Kami menyimpan email pengguna baru dengan db.createa
dan memeriksa email di fungsi login dengan db.findOne
. Nah, sebelum kita bisa melakukan semuanya, kita perlu menamai sebuah koleksi atau tabel dengan metode db.collection
. Itulah yang akan kita bahas selanjutnya.
Catatan : Untuk mempelajari lebih lanjut tentang operasi database di MongoDB, periksa dokumentasi Metode Shell mongo.
Membangun Kontrak Cerdas Blockchain Sederhana Dengan Soliditas
Sekarang kita akan menulis kontrak Blockchain dalam Solidity (itulah bahasa yang digunakan untuk menulis kontrak pintar) untuk menyimpan data kita dan mengambilnya kembali saat kita membutuhkannya. Data yang ingin kita simpan adalah data file musik, artinya kita harus mengupload musik ke IPFS, kemudian menyimpan alamat buffer di blockchain.
Pertama, kita buat file baru di folder kontrak dan beri nama Inbox.sol . Untuk menulis kontrak pintar, sangat berguna untuk memiliki pemahaman yang baik tentang Soliditas, tetapi tidak sulit karena mirip dengan JavaScript.
Catatan : Jika Anda tertarik untuk mempelajari lebih lanjut tentang Soliditas, saya telah menambahkan beberapa sumber daya di bagian bawah artikel untuk membantu Anda memulai.
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; } }
Dalam kontrak kami, kami memiliki dua fungsi utama: fungsi sendIPFS
dan getHash
. Sebelum kita berbicara tentang fungsi, kita dapat melihat bahwa kita harus mendefinisikan kontrak terlebih dahulu yang disebut Inbox
. Di dalam kelas ini, kami memiliki struktur yang digunakan dalam objek ipfsInbox
(peristiwa pertama, lalu pengubah).
Setelah mendefinisikan struktur dan kejadian, kita harus menginisialisasi kontrak dengan memanggil fungsi constructor
. Kemudian kami mendefinisikan tiga fungsi. (Fungsi checkInbox
digunakan dalam pengujian untuk hasil pengujian.)
sendIPFS
adalah tempat pengguna memasukkan pengenal dan alamat hash setelah itu disimpan di blockchain. Fungsi getHash
mengambil alamat hash ketika diberi pengenal. Sekali lagi, logika di balik ini adalah bahwa kami pada akhirnya ingin menyimpan musik di IPFS. Untuk menguji cara kerjanya, Anda dapat menggunakan Remix IDE, menyalin, menempel, dan menguji kontrak Anda, serta men-debug kesalahan apa pun dan menjalankannya lagi (semoga itu tidak diperlukan!).
Setelah menguji bahwa kode kita berfungsi dengan benar di remix, mari kita lanjutkan untuk mengompilasinya secara lokal dengan Truffle suite. Tapi pertama-tama, kita perlu membuat beberapa perubahan pada file kita dan mengatur emulator kita menggunakan ganache-cli
:
Pertama, mari kita instal ganache-cli
. Di direktori yang sama, jalankan perintah berikut di terminal Anda:
$ npm install ganache-cli -g
Kemudian mari kita buka Terminal lain dan jalankan perintah lain di folder yang sama:
$ ganache-cli
Ini memulai emulator agar kontrak blockchain kami terhubung dan berfungsi. Minimalkan Terminal dan lanjutkan dengan Terminal lain yang telah Anda gunakan.
Sekarang buka file truffle.js jika Anda menggunakan Linux/Mac OS atau truffle-config.js di Windows, dan ubah file ini agar terlihat seperti ini:
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 } } };
Pada dasarnya yang kami lakukan adalah menambahkan jalur folder build tempat kontrak pintar dikonversi ke file JSON. Kemudian kami juga menentukan jaringan yang harus digunakan Truffle untuk migrasi.
Kemudian, juga di folder migrasi , buat file baru bernama 2_migrate_inbox.js dan tambahkan kode berikut di dalam file:
var IPFSInbox = artifacts.require("./Inbox.sol"); module.exports = function(deployer) { deployer.deploy(IPFSInbox); };
Kami melakukannya untuk mendapatkan file kontrak dan menyebarkannya secara otomatis ke JSON, menggunakan fungsi deployer
selama migrasi Truffle.
Setelah perubahan di atas kita jalankan:
$ truffle compile
Kita akan melihat beberapa pesan di akhir yang menunjukkan kompilasi yang berhasil, seperti:
> Compiled successfully using: - solc: 0.5.16+commit.9c3226ce.Emscripten.clang
Selanjutnya, kami memigrasikan kontrak kami dengan menjalankan:
$ truffle migrate
Setelah kami berhasil memigrasikan kontrak kami, kami harus memiliki sesuatu seperti ini di akhir:
Summary ======= > Total deployments: 1 > Final cost: 0.00973432 ETH
Dan kita hampir selesai! Kami telah membangun API kami dengan Node.js, dan juga menyiapkan dan membangun kontrak pintar kami.
Kita juga harus menulis tes untuk kontrak kita untuk menguji perilaku kontrak kita dan memastikan itu adalah perilaku yang diinginkan. Tes biasanya ditulis dan ditempatkan di folder test
. Contoh pengujian yang ditulis dalam file bernama InboxTest.js yang dibuat di folder pengujian adalah:
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") }) })
Jadi kami menjalankan pengujian kami dengan menjalankan yang berikut:
$ truffle test
Ini menguji kontrak kami dengan file di folder pengujian dan menunjukkan jumlah tes yang lulus dan gagal. Untuk tutorial ini, kita harus mendapatkan:
$ 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)
Mengintegrasikan Kontrak Cerdas ke API Backend Menggunakan Web3
Sering kali ketika Anda melihat tutorial, Anda melihat aplikasi terdesentralisasi yang dibangun untuk mengintegrasikan frontend langsung ke blockchain. Namun ada kalanya integrasi ke backend juga diperlukan, misalnya saat menggunakan API dan layanan backend pihak ketiga, atau saat menggunakan blockchain untuk membangun CMS.
Penggunaan Web3 sangat penting untuk tujuan ini, karena membantu kami mengakses node Ethereum jarak jauh atau lokal dan menggunakannya dalam aplikasi kami. Sebelum kita melanjutkan, kita akan membahas node Ethereum lokal dan remote. Node lokal adalah node yang digunakan pada sistem kami dengan emulator seperti ganache-cli
tetapi node jarak jauh adalah node yang digunakan pada faucet/platform online seperti ropsten atau rinkeby . Untuk menyelam lebih dalam, Anda dapat mengikuti tutorial tentang cara menyebarkan di ropsten panduan 5 menit untuk menyebarkan kontrak pintar dengan Truffle dan Ropsten atau Anda bisa menggunakan penyedia dompet truffle dan menyebarkan melalui Cara Lebih Mudah untuk Menyebarkan Kontrak Cerdas Anda.
Kami menggunakan ganache-cli
dalam tutorial ini, tetapi jika kami menggunakan ropsten, kami harus menyalin atau menyimpan alamat kontrak kami di suatu tempat seperti di file .env kami, kemudian lanjutkan untuk memperbarui file server.js , impor web3, impor kontrak yang dimigrasikan dan menyiapkan instans Web3.
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)); }) })
Di file server.js , kami memeriksa apakah instance web3 sudah diinisialisasi. Jika tidak, kami menginisialisasinya pada port jaringan yang telah kami tentukan sebelumnya ( 8545
). Kemudian kami membuat kontrak berdasarkan file JSON yang dimigrasikan dan paket truffle-contract
, dan menyetel penyedia kontrak ke penyedia instans Web3 yang harus sudah diinisialisasi sekarang.
Kami kemudian mendapatkan akun dengan web3.eth.getAccounts
. Untuk tahap pengembangan, kami memanggil fungsi yang disebarkan di kelas kontrak kami yang meminta ganache-cli
— yang masih berjalan — untuk memberi kami alamat kontrak untuk digunakan. Tetapi jika kita sudah menerapkan kontrak kita ke node jarak jauh, kita memanggil fungsi yang memasukkan alamat sebagai argumen. Fungsi sampel dikomentari di bawah variabel lms
yang ditentukan dalam kode kita di atas. Kemudian kita memanggil fungsi routes
dengan memasukkan instance aplikasi, instance database, instance kontrak ( lms
), dan data akun sebagai argumen. Terakhir, kami mendengarkan permintaan pada port 8082
.
Juga, sekarang, kita seharusnya sudah menginstal paket MongoDB, karena kita menggunakannya di API sebagai database kita. Setelah kami memilikinya, kami pindah ke halaman rute di mana kami menggunakan metode yang ditentukan dalam kontrak untuk menyelesaikan tugas-tugas seperti menyimpan dan mengambil data musik.
Pada akhirnya, route.js kita akan terlihat seperti ini:
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.
Apa selanjutnya?
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