Ana içeriğe atla

Yeni Başlayanlar İçin Merhaba Dünya Akıllı Sözleşmesi - Fullstack

Solidity
Hardhat
Alchemy
akıllı sözleşmeler
dağıtım
blok gezgini
ön yüz
işlemler
çerçeve
Başlangıç
nstrike2
25 Ekim 2021
37 dakikalık okuma

Blokzincir geliştirmeye yeniyseniz ve nereden başlayacağınızı veya akıllı sözleşmeleri nasıl dağıtacağınızı ve onlarla nasıl etkileşime gireceğinizi bilmiyorsanız, bu rehber tam size göre. MetaMask (opens in a new tab), Solidity (opens in a new tab), Hardhat (opens in a new tab) ve Alchemy (opens in a new tab) kullanarak Goerli test ağında basit bir akıllı sözleşme oluşturmayı ve dağıtmayı adım adım inceleyeceğiz.

Bu eğitimi tamamlamak için bir Alchemy hesabına ihtiyacınız olacak. Ücretsiz bir hesap için kaydolun (opens in a new tab).

Herhangi bir noktada sorularınız olursa, Alchemy Discord (opens in a new tab) üzerinden bize ulaşmaktan çekinmeyin!

Bölüm 1 - Hardhat Kullanarak Akıllı Sözleşmenizi Oluşturun ve Dağıtın

Ethereum ağına bağlanın

Ethereum zincirine istek yapmanın birçok yolu vardır. Basitlik adına, kendi başımıza bir düğüm çalıştırmadan Ethereum zinciriyle iletişim kurmamızı sağlayan bir Blokzincir geliştirici platformu ve API'si olan Alchemy'de ücretsiz bir hesap kullanacağız. Alchemy ayrıca izleme ve analitik için geliştirici araçlarına sahiptir; akıllı sözleşme dağıtımımızın arka planında neler olup bittiğini anlamak için bu eğitimde bunlardan yararlanacağız.

Uygulamanızı ve API anahtarınızı oluşturun

Bir Alchemy hesabı oluşturduktan sonra, bir uygulama oluşturarak bir API anahtarı üretebilirsiniz. Bu, Goerli test ağına istek yapmanızı sağlayacaktır. Test ağlarına aşina değilseniz Alchemy'nin ağ seçme kılavuzunu okuyabilirsiniz (opens in a new tab).

Alchemy kontrol panelinde, gezinme çubuğundaki Apps (Uygulamalar) açılır menüsünü bulun ve Create App (Uygulama Oluştur) seçeneğine tıklayın.

Hello world create app

Uygulamanıza 'Hello World' adını verin ve kısa bir açıklama yazın. Ortamınız olarak Staging'i ve ağınız olarak Goerli'yi seçin.

create app view hello world

Not: Goerli'yi seçtiğinizden emin olun, aksi takdirde bu eğitim çalışmayacaktır.

Create app (Uygulama oluştur) düğmesine tıklayın. Uygulamanız aşağıdaki tabloda görünecektir.

Bir Ethereum hesabı oluşturun

İşlem göndermek ve almak için bir Ethereum hesabına ihtiyacınız var. Kullanıcıların Ethereum hesap adreslerini yönetmelerini sağlayan tarayıcı içi sanal bir cüzdan olan MetaMask'ı kullanacağız.

MetaMask'ı ücretsiz olarak indirebilir ve buradan (opens in a new tab) bir hesap oluşturabilirsiniz. Bir hesap oluştururken veya zaten bir hesabınız varsa, sağ üstteki "Goerli Test Network" (Goerli Test Ağı) seçeneğine geçtiğinizden emin olun (böylece gerçek parayla işlem yapmamış oluruz).

Adım 4: Bir Musluktan Ether Ekleyin

Akıllı sözleşmenizi test ağına dağıtmak için biraz sahte ETH'ye ihtiyacınız olacak. Goerli ağında ETH almak için bir Goerli musluğuna gidin ve Goerli hesap adresinizi girin. Goerli musluklarının son zamanlarda biraz güvenilmez olabileceğini unutmayın - denenebilecek seçeneklerin bir listesi için test ağları sayfasına bakın:

Not: ağ yoğunluğu nedeniyle bu biraz zaman alabilir. ``

Adım 5: Bakiyenizi Kontrol Edin

ETH'nin cüzdanınızda olduğunu iki kez kontrol etmek için, Alchemy'nin composer aracını (opens in a new tab) kullanarak bir eth_getBalance (opens in a new tab) isteği yapalım. Bu, cüzdanımızdaki ETH miktarını döndürecektir. Daha fazlasını öğrenmek için Alchemy'nin composer aracının nasıl kullanılacağına dair kısa eğitimine (opens in a new tab) göz atın.

MetaMask hesap adresinizi girin ve Send Request (İstek Gönder) düğmesine tıklayın. Aşağıdaki kod parçacığına benzeyen bir yanıt göreceksiniz.

{ "jsonrpc": "2.0", "id": 0, "result": "0x2B5E3AF16B1880000" }

Not: Bu sonuç ETH değil, wei cinsindendir. Wei, Ether'in en küçük birimi olarak kullanılır.

Oh be! Sahte paramızın hepsi orada.

Adım 6: Projemizi başlatalım

İlk olarak, projemiz için bir klasör oluşturmamız gerekecek. Komut satırınıza gidin ve aşağıdakileri girin.

mkdir hello-world
cd hello-world

Artık proje klasörümüzün içinde olduğumuza göre, projeyi başlatmak için npm init kullanacağız.

Henüz npm yüklü değilse, Node.js ve npm'i yüklemek için bu talimatları (opens in a new tab) izleyin.

Bu eğitimin amacı doğrultusunda, başlatma sorularını nasıl yanıtladığınız önemli değildir. Referans olması açısından biz şu şekilde yaptık:

package.json dosyasını onaylayın ve başlamaya hazırız!

Adım 7: Hardhat'i İndirin

Hardhat, Ethereum yazılımınızı derlemek, dağıtmak, test etmek ve hatalarını ayıklamak için bir geliştirme ortamıdır. Geliştiricilere, canlı zincire dağıtmadan önce yerel olarak akıllı sözleşmeler ve merkeziyetsiz uygulamalar (dapp) oluştururken yardımcı olur.

hello-world projemizin içinde şunu çalıştırın:

npm install --save-dev hardhat

Kurulum talimatları (opens in a new tab) hakkında daha fazla ayrıntı için bu sayfaya göz atın.

Adım 8: Hardhat projesi oluşturun

hello-world proje klasörümüzün içinde şunu çalıştırın:

npx hardhat

Daha sonra bir karşılama mesajı ve ne yapmak istediğinizi seçme seçeneği görmelisiniz. "create an empty hardhat.config.js" (boş bir hardhat.config.js oluştur) seçeneğini seçin:

Bu, projede bir hardhat.config.js dosyası oluşturacaktır. Bunu eğitimin ilerleyen kısımlarında projemizin kurulumunu belirtmek için kullanacağız.

Adım 9: Proje klasörleri ekleyin

Projeyi düzenli tutmak için iki yeni klasör oluşturalım. Komut satırında, hello-world projenizin kök dizinine gidin ve şunu yazın:

mkdir contracts
mkdir scripts
  • contracts/, hello world akıllı sözleşme kod dosyamızı tutacağımız yerdir
  • scripts/, sözleşmemizi dağıtmak ve onunla etkileşime girmek için komut dosyalarını tutacağımız yerdir

Adım 10: Sözleşmemizi yazalım

Kendi kendinize ne zaman kod yazacağız diye soruyor olabilirsiniz. Zamanı geldi!

Favori düzenleyicinizde hello-world projesini açın. Akıllı sözleşmeler en yaygın olarak, bizim de akıllı sözleşmemizi yazmak için kullanacağımız Solidity dilinde yazılır.‌

  1. contracts klasörüne gidin ve HelloWorld.sol adında yeni bir dosya oluşturun
  2. Aşağıda bu eğitim için kullanacağımız örnek bir Hello World akıllı sözleşmesi bulunmaktadır. Aşağıdaki içerikleri HelloWorld.sol dosyasına kopyalayın.

Not: Bu sözleşmenin ne yaptığını anlamak için yorumları okuduğunuzdan emin olun.

Bu, oluşturulduğunda bir mesajı saklayan temel bir akıllı sözleşmedir. update işlevi çağrılarak güncellenebilir.

Adım 11: MetaMask ve Alchemy'yi projenize bağlayın

Bir MetaMask cüzdanı, Alchemy hesabı oluşturduk ve akıllı sözleşmemizi yazdık, şimdi bu üçünü birbirine bağlama zamanı.

Cüzdanınızdan gönderilen her işlem, benzersiz özel anahtarınızı kullanan bir imza gerektirir. Programımıza bu izni sağlamak için özel anahtarımızı bir ortam (environment) dosyasında güvenle saklayabiliriz. Ayrıca Alchemy için bir API anahtarını da burada saklayacağız.

İşlem gönderme hakkında daha fazla bilgi edinmek için, Web3 kullanarak işlem gönderme hakkındaki bu eğitime (opens in a new tab) göz atın.

İlk olarak, proje dizininize dotenv paketini kurun:

npm install dotenv --save

Ardından, projenin kök dizininde bir .env dosyası oluşturun. MetaMask özel anahtarınızı ve HTTP Alchemy API URL'nizi buna ekleyin.

Ortam dosyanızın adı .env olmalıdır, aksi takdirde bir ortam dosyası olarak tanınmayacaktır.

process.env veya .env-custom veya başka bir isim vermeyin.

Animated walkthrough of getting an Alchemy API key

.env dosyanız şu şekilde görünmelidir:

API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key"
PRIVATE_KEY = "your-metamask-private-key"

Bunları kodumuza fiilen bağlamak için, 13. adımda hardhat.config.js dosyamızda bu değişkenlere referans vereceğiz.

Adım 12: Ethers.js'yi Kurun

Ethers.js, standart JSON-RPC yöntemlerini (opens in a new tab) daha kullanıcı dostu yöntemlerle sararak Ethereum ile etkileşime girmeyi ve istekte bulunmayı kolaylaştıran bir kütüphanedir.

Hardhat, ek araçlar ve genişletilmiş işlevsellik için eklentileri (opens in a new tab) entegre etmemize olanak tanır. Sözleşme dağıtımı için Ethers eklentisinden (opens in a new tab) yararlanacağız.

Proje dizininizde şunu yazın:

npm install --save-dev @nomiclabs/hardhat-ethers "ethers@^5.0.0"

Adım 13: hardhat.config.js dosyasını güncelleyin

Şimdiye kadar birkaç bağımlılık ve eklenti ekledik, şimdi projemizin hepsinden haberdar olması için hardhat.config.js dosyasını güncellememiz gerekiyor.

hardhat.config.js dosyanızı şu şekilde görünecek biçimde güncelleyin:

Adım 14: Sözleşmemizi derleyelim

Şimdiye kadar her şeyin çalıştığından emin olmak için sözleşmemizi derleyelim. compile görevi, yerleşik hardhat görevlerinden biridir.

Komut satırından şunu çalıştırın:

npx hardhat compile

SPDX license identifier not provided in source file hakkında bir uyarı alabilirsiniz, ancak bunun için endişelenmenize gerek yok — umarım diğer her şey iyi görünüyordur! Değilse, her zaman Alchemy Discord (opens in a new tab) kanalından mesaj atabilirsiniz.

Adım 15: Dağıtım komut dosyamızı yazalım

Artık sözleşmemiz yazıldığına ve yapılandırma dosyamız hazır olduğuna göre, sözleşme dağıtım komut dosyamızı yazmanın zamanı geldi.

scripts/ klasörüne gidin ve deploy.js adında yeni bir dosya oluşturarak içine aşağıdaki içerikleri ekleyin:

Hardhat, Sözleşmeler eğitiminde (opens in a new tab) bu kod satırlarının her birinin ne yaptığını açıklama konusunda harika bir iş çıkarıyor, biz de onların açıklamalarını buraya uyarladık.

const HelloWorld = await ethers.getContractFactory("HelloWorld")

ethers.js'deki bir ContractFactory, yeni akıllı sözleşmeleri dağıtmak için kullanılan bir soyutlamadır, bu nedenle buradaki HelloWorld, hello world sözleşmemizin örnekleri için bir fabrika (opens in a new tab)'dır. hardhat-ethers eklentisi ContractFactory ve Contract kullanıldığında, örnekler varsayılan olarak ilk imzalayana (sahibine) bağlanır.

const hello_world = await HelloWorld.deploy()

Bir ContractFactory üzerinde deploy() çağırmak dağıtımı başlatacak ve bir Contract nesnesine çözümlenen bir Promise döndürecektir. Bu, akıllı sözleşme işlevlerimizin her biri için bir yöntemi olan nesnedir.

Adım 16: Sözleşmemizi dağıtalım

Sonunda akıllı sözleşmemizi dağıtmaya hazırız! Komut satırına gidin ve şunu çalıştırın:

npx hardhat run scripts/deploy.js --network goerli

Daha sonra şuna benzer bir şey görmelisiniz:

Contract deployed to address: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570

Lütfen bu adresi kaydedin. Bunu eğitimin ilerleyen kısımlarında kullanacağız.

Goerli Etherscan (opens in a new tab)'e gider ve sözleşme adresimizi aratırsak, başarıyla dağıtıldığını görebilmeliyiz. İşlem şuna benzer görünecektir:

From adresi MetaMask hesap adresinizle eşleşmelidir ve To adresi Contract Creation (Sözleşme Oluşturma) diyecektir. İşleme tıklarsak, sözleşme adresimizi To alanında göreceğiz.

Tebrikler! Az önce bir Ethereum test ağına bir akıllı sözleşme dağıttınız.

Arka planda neler olup bittiğini anlamak için Alchemy kontrol panelimizdeki (opens in a new tab) Explorer (Gezgin) sekmesine gidelim. Birden fazla Alchemy uygulamanız varsa, uygulamaya göre filtrelediğinizden ve Hello World'ü seçtiğinizden emin olun.

Burada, .deploy() işlevini çağırdığımızda Hardhat/Ethers'ın bizim için arka planda yaptığı bir avuç JSON-RPC yöntemini göreceksiniz. Buradaki iki önemli yöntem, sözleşmemizi Goerli zincirine yazma isteği olan eth_sendRawTransaction (opens in a new tab) ve hash değeri verilen işlemimiz hakkında bilgi okuma isteği olan eth_getTransactionByHash (opens in a new tab)'dir. İşlem gönderme hakkında daha fazla bilgi edinmek için, Web3 kullanarak işlem gönderme hakkındaki eğitimimize göz atın.

Bölüm 2: Akıllı Sözleşmenizle Etkileşime Geçin

Artık Goerli ağına başarılı bir şekilde bir akıllı sözleşme dağıttığımıza göre, onunla nasıl etkileşime geçeceğimizi öğrenelim.

Bir interact.js dosyası oluşturun

Bu, etkileşim betiğimizi yazacağımız dosyadır. Bölüm 1'de daha önce yüklediğiniz Ethers.js kütüphanesini kullanacağız.

scripts/ klasörünün içinde interact.js adında yeni bir dosya oluşturun ve aşağıdaki kodu ekleyin:

// interact.js

const API_KEY = process.env.API_KEY
const PRIVATE_KEY = process.env.PRIVATE_KEY
const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS

.env dosyanızı güncelleyin

Yeni ortam değişkenleri kullanacağız, bu yüzden onları daha önce oluşturduğumuz .env dosyasında tanımlamamız gerekiyor.

Alchemy API_KEY değerimiz ve akıllı sözleşmenizin dağıtıldığı CONTRACT_ADDRESS için bir tanım eklememiz gerekecek.

.env dosyanız şuna benzer görünmelidir:

# .env

API_URL = "https://eth-goerli.alchemyapi.io/v2/<your-api-key>"
API_KEY = "<your-api-key>"
PRIVATE_KEY = "<your-metamask-private-key>"
CONTRACT_ADDRESS = "0x<your contract address>"

Sözleşme ABI'nizi alın

Sözleşme , akıllı sözleşmemizle etkileşime geçmek için kullanılan arayüzdür. Hardhat otomatik olarak bir ABI oluşturur ve bunu HelloWorld.json içine kaydeder. ABI'yi kullanmak için, interact.js dosyamıza aşağıdaki kod satırlarını ekleyerek içerikleri ayrıştırmamız gerekecek:

// interact.js
const contract = require("../artifacts/contracts/HelloWorld.sol/HelloWorld.json")

Eğer ABI'yi görmek isterseniz, konsolunuza yazdırabilirsiniz:

console.log(JSON.stringify(contract.abi))

ABI'nizin konsola yazdırıldığını görmek için terminalinize gidin ve şunu çalıştırın:

npx hardhat run scripts/interact.js

Sözleşmenizin bir örneğini oluşturun

Sözleşmemizle etkileşime geçmek için kodumuzda bir sözleşme örneği oluşturmamız gerekiyor. Bunu Ethers.js ile yapmak için üç kavramla çalışmamız gerekecek:

  1. Sağlayıcı (Sağlayıcı) - size Blokzincir'e okuma ve yazma erişimi veren bir düğüm sağlayıcısı
  2. İmzalayıcı (İmzalayıcı) - işlemleri imzalayabilen bir Ethereum hesabını temsil eder
  3. Sözleşme (Contract) - zinciriçi dağıtılmış belirli bir sözleşmeyi temsil eden bir Ethers.js nesnesi

Sözleşmemizin örneğini oluşturmak için önceki adımdaki sözleşme ABI'sini kullanacağız:

Sağlayıcılar, İmzalayıcılar ve Sözleşmeler hakkında daha fazla bilgiyi ethers.js belgelerinde (opens in a new tab) bulabilirsiniz.

Başlangıç mesajını okuyun

Sözleşmemizi initMessage = "Hello world!" ile dağıttığımızı hatırlıyor musunuz? Şimdi akıllı sözleşmemizde saklanan o mesajı okuyacağız ve konsola yazdıracağız.

JavaScript'te ağlarla etkileşime girerken asenkron fonksiyonlar kullanılır. Asenkron fonksiyonlar hakkında daha fazla bilgi edinmek için bu Medium makalesini okuyun (opens in a new tab).

Akıllı sözleşmemizdeki message fonksiyonunu çağırmak ve başlangıç mesajını okumak için aşağıdaki kodu kullanın:

Terminalde npx hardhat run scripts/interact.js kullanarak dosyayı çalıştırdıktan sonra şu yanıtı görmeliyiz:

The message is: Hello world!

Tebrikler! Ethereum Blokzincir'inden akıllı sözleşme verilerini başarıyla okudunuz, harika iş çıkardınız!

Mesajı güncelleyin

Sadece mesajı okumak yerine, update fonksiyonunu kullanarak akıllı sözleşmemizde kayıtlı olan mesajı da güncelleyebiliriz! Oldukça havalı, değil mi?

Mesajı güncellemek için, oluşturduğumuz Sözleşme nesnesi üzerinde doğrudan update fonksiyonunu çağırabiliriz:

  1. satırda, döndürülen işlem nesnesi üzerinde .wait() çağrısı yaptığımıza dikkat edin. Bu, betiğimizin fonksiyondan çıkmadan önce işlemin Blokzincir'de kazılmasını beklemesini sağlar. Eğer .wait() çağrısı dahil edilmezse, betik sözleşmedeki güncellenmiş message değerini göremeyebilir.

Yeni mesajı okuyun

Güncellenmiş message değerini okumak için önceki adımı tekrarlayabilmelisiniz. Bir dakikanızı ayırın ve bu yeni değeri yazdırmak için gerekli değişiklikleri yapıp yapamayacağınızı görün!

Eğer bir ipucuna ihtiyacınız varsa, bu noktada interact.js dosyanızın nasıl görünmesi gerektiği aşağıda verilmiştir:

Şimdi sadece betiği çalıştırın; eski mesajı, güncelleme durumunu ve yeni mesajı terminalinize yazdırılmış olarak görebilmelisiniz!

npx hardhat run scripts/interact.js --network goerli

The message is: Hello World!
Updating the message...
The new message is: This is the new message.

Bu betiği çalıştırırken, yeni mesaj yüklenmeden önce Updating the message... adımının yüklenmesinin biraz zaman aldığını fark edebilirsiniz. Bunun nedeni madencilik sürecidir; işlemlerin kazılırken nasıl takip edileceğini merak ediyorsanız, bir işlemin durumunu görmek için Alchemy bellek havuzunu (mempool) (opens in a new tab) ziyaret edin. Eğer işlem düşerse, Goerli Etherscan (opens in a new tab)'i kontrol etmek ve işlem özetinizi (hash) aramak da faydalı olacaktır.

Bölüm 3: Akıllı Sözleşmenizi Etherscan'de Yayınlayın

Akıllı sözleşmenizi hayata geçirmek için tüm zor işleri yaptınız; şimdi onu dünyayla paylaşma zamanı!

Akıllı sözleşmenizi Etherscan'de doğrulayarak, herkesin kaynak kodunuzu görüntülemesini ve akıllı sözleşmenizle etkileşime girmesini sağlayabilirsiniz. Hadi başlayalım!

1. Adım: Etherscan hesabınızda bir API Anahtarı oluşturun

Yayınlamaya çalıştığınız akıllı sözleşmenin size ait olduğunu doğrulamak için bir Etherscan API Anahtarı gereklidir.

Henüz bir Etherscan hesabınız yoksa, bir hesap için kaydolun (opens in a new tab).

Giriş yaptıktan sonra, gezinme çubuğunda kullanıcı adınızı bulun, üzerine gelin ve My profile düğmesini seçin.

Profil sayfanızda bir yan gezinme çubuğu görmelisiniz. Yan gezinme çubuğundan API Keys'i seçin. Ardından, yeni bir API anahtarı oluşturmak için "Add" düğmesine basın, uygulamanıza hello-world adını verin ve Create New API Key düğmesine basın.

Yeni API anahtarınız API anahtarı tablosunda görünmelidir. API anahtarını panonuza kopyalayın.

Ardından, Etherscan API anahtarını .env dosyamıza eklememiz gerekiyor.

Ekledikten sonra, .env dosyanız şu şekilde görünmelidir:

API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key"
PUBLIC_KEY = "your-public-account-address"
PRIVATE_KEY = "your-private-account-address"
CONTRACT_ADDRESS = "your-contract-address"
ETHERSCAN_API_KEY = "your-etherscan-key"

Hardhat ile dağıtılan akıllı sözleşmeler

hardhat-etherscan kurulumu

Sözleşmenizi Hardhat kullanarak Etherscan'de yayınlamak basittir. Başlamak için öncelikle hardhat-etherscan eklentisini kurmanız gerekecek. hardhat-etherscan, akıllı sözleşmenin kaynak kodunu ve ABI'sini Etherscan'de otomatik olarak doğrulayacaktır. Bunu eklemek için hello-world dizininde şunu çalıştırın:

npm install --save-dev @nomiclabs/hardhat-etherscan

Kurulduktan sonra, hardhat.config.js dosyanızın en üstüne aşağıdaki ifadeyi ekleyin ve Etherscan yapılandırma seçeneklerini ekleyin:

Akıllı sözleşmenizi Etherscan'de doğrulayın

Tüm dosyaların kaydedildiğinden ve tüm .env değişkenlerinin doğru şekilde yapılandırıldığından emin olun.

Sözleşme adresini ve dağıtıldığı ağı ileterek verify görevini çalıştırın:

npx hardhat verify --network goerli DEPLOYED_CONTRACT_ADDRESS 'Hello World!'

DEPLOYED_CONTRACT_ADDRESS değerinin Goerli test ağında dağıtılan akıllı sözleşmenizin adresi olduğundan emin olun. Ayrıca, son argüman ('Hello World!'), 1. bölümdeki dağıtım adımı sırasında kullanılan dize değeriyle aynı olmalıdır.

Her şey yolunda giderse, terminalinizde aşağıdaki mesajı göreceksiniz:

Successfully submitted source code for contract
contracts/HelloWorld.sol:HelloWorld at 0xdeployed-contract-address
for verification on Etherscan. Waiting for verification result...


Successfully verified contract HelloWorld on Etherscan.
https://goerli.etherscan.io/address/<contract-address>#contracts

Tebrikler! Akıllı sözleşme kodunuz Etherscan'de!

Akıllı sözleşmenizi Etherscan'de inceleyin!

Terminalinizde sağlanan bağlantıya gittiğinizde, Etherscan'de yayınlanan akıllı sözleşme kodunuzu ve ABI'nizi görebilmelisiniz!

Harika - başardın şampiyon! Artık herkes akıllı sözleşmenizi çağırabilir veya ona yazabilir! Bir sonraki adımda ne inşa edeceğinizi görmek için sabırsızlanıyoruz!

Bölüm 4 - Akıllı sözleşmenizi önyüz ile entegre etme

Bu eğitimin sonunda şunları nasıl yapacağınızı öğreneceksiniz:

  • Bir MetaMask cüzdanını merkeziyetsiz uygulamanıza (dapp) bağlamak
  • Alchemy Web3 (opens in a new tab) API'sini kullanarak akıllı sözleşmenizden veri okumak
  • MetaMask kullanarak Ethereum işlemlerini imzalamak

Bu dapp için önyüz çerçevemiz olarak React (opens in a new tab) kullanacağız; ancak, çoğunlukla projemize Web3 işlevselliği kazandırmaya odaklanacağımız için temel prensiplerini açıklamaya çok fazla zaman ayırmayacağımızı belirtmek önemlidir.

Ön koşul olarak, başlangıç seviyesinde React bilgisine sahip olmalısınız. Eğer değilseniz, resmi React'e Giriş eğitimini (opens in a new tab) tamamlamanızı öneririz.

Başlangıç dosyalarını klonlayın

İlk olarak, bu projenin başlangıç dosyalarını almak için hello-world-part-four GitHub deposuna (opens in a new tab) gidin ve bu depoyu yerel makinenize klonlayın.

Klonlanan depoyu yerel olarak açın. İki klasör içerdiğine dikkat edin: starter-files ve completed.

  • starter-files- bu dizinde çalışacağız, kullanıcı arayüzünü (UI) Ethereum cüzdanınıza ve Bölüm 3'te Etherscan'de yayınladığımız akıllı sözleşmeye bağlayacağız.
  • completed tamamlanmış eğitimin tamamını içerir ve yalnızca takıldığınızda referans olarak kullanılmalıdır.

Ardından, starter-files kopyanızı favori kod düzenleyicinizde açın ve src klasörüne gidin.

Yazacağımız tüm kodlar src klasörü altında yer alacaktır. Projemize Web3 işlevselliği kazandırmak için HelloWorld.js bileşenini ve util/interact.js JavaScript dosyalarını düzenleyeceğiz.

Başlangıç dosyalarını inceleyin

Kodlamaya başlamadan önce, başlangıç dosyalarında bize nelerin sağlandığını inceleyelim.

React projenizi çalıştırın

React projesini tarayıcımızda çalıştırarak başlayalım. React'in güzelliği, projemizi tarayıcımızda çalıştırdıktan sonra, kaydettiğimiz tüm değişikliklerin tarayıcımızda canlı olarak güncellenmesidir.

Projenin çalışmasını sağlamak için starter-files klasörünün kök dizinine gidin ve projenin bağımlılıklarını yüklemek için terminalinizde npm install komutunu çalıştırın:

cd starter-files
npm install

Bunların yüklenmesi bittikten sonra terminalinizde npm start komutunu çalıştırın:

npm start

Bunu yaptığınızda tarayıcınızda projemizin önyüzünü göreceğiniz http://localhost:3000/ (opens in a new tab) adresi açılmalıdır. Bir alan (akıllı sözleşmenizde saklanan mesajı güncellemek için bir yer), bir "Connect Wallet" (Cüzdanı Bağla) düğmesi ve bir "Update" (Güncelle) düğmesinden oluşmalıdır.

Herhangi bir düğmeye tıklamayı denerseniz, çalışmadıklarını fark edeceksiniz; bunun nedeni, işlevlerini henüz programlamamış olmamızdır.

HelloWorld.js bileşeni

Düzenleyicimizde src klasörüne geri dönelim ve HelloWorld.js dosyasını açalım. Üzerinde çalışacağımız birincil React bileşeni olduğu için bu dosyadaki her şeyi anlamamız son derece önemlidir.

Bu dosyanın en üstünde, React kütüphanesi, useEffect ve useState hook'ları, ./util/interact.js dosyasından bazı öğeler (bunları yakında daha ayrıntılı olarak açıklayacağız!) ve Alchemy logosu dahil olmak üzere projemizi çalıştırmak için gerekli olan birkaç içe aktarma (import) ifadesi olduğunu fark edeceksiniz.

Sırada, belirli olaylardan sonra güncelleyeceğimiz durum (state) değişkenlerimiz var.

// HelloWorld.js

//Durum değişkenleri
const [walletAddress, setWallet] = useState("")
const [status, setStatus] = useState("")
const [message, setMessage] = useState("No connection to the network.")
const [newMessage, setNewMessage] = useState("")

İşte değişkenlerin her birinin temsil ettiği şeyler:

  • walletAddress - kullanıcının cüzdan adresini saklayan bir dize (string)
  • status - kullanıcıya dapp ile nasıl etkileşime gireceği konusunda rehberlik eden yararlı bir mesajı saklayan bir dize
  • message - akıllı sözleşmedeki mevcut mesajı saklayan bir dize
  • newMessage - akıllı sözleşmeye yazılacak yeni mesajı saklayan bir dize

Durum değişkenlerinden sonra, henüz uygulanmamış beş işlev göreceksiniz: useEffect, addSmartContractListener, addWalletListener, connectWalletPressed ve onUpdatePressed. Aşağıda ne işe yaradıklarını açıklayacağız:

  • useEffect (opens in a new tab) - bu, bileşeniniz oluşturulduktan (render) sonra çağrılan bir React hook'udur. İçine boş bir dizi [] prop'u geçirildiği için (bkz. satır 4), yalnızca bileşenin ilk oluşturulmasında çağrılacaktır. Burada akıllı sözleşmemizde saklanan mevcut mesajı yükleyeceğiz, akıllı sözleşme ve cüzdan dinleyicilerimizi çağıracağız ve bir cüzdanın zaten bağlı olup olmadığını yansıtmak için kullanıcı arayüzümüzü güncelleyeceğiz.
  • addSmartContractListener - bu işlev, HelloWorld sözleşmemizin UpdatedMessages olayını izleyecek ve akıllı sözleşmemizde mesaj değiştirildiğinde kullanıcı arayüzümüzü güncelleyecek bir dinleyici kurar.
  • addWalletListener - bu işlev, kullanıcının cüzdanının bağlantısını kesmesi veya adres değiştirmesi gibi kullanıcının MetaMask cüzdan durumundaki değişiklikleri algılayan bir dinleyici kurar.
  • connectWalletPressed - bu işlev, kullanıcının MetaMask cüzdanını dapp'imize bağlamak için çağrılacaktır.
  • onUpdatePressed - bu işlev, kullanıcı akıllı sözleşmede saklanan mesajı güncellemek istediğinde çağrılacaktır.

Bu dosyanın sonuna doğru, bileşenimizin kullanıcı arayüzü (UI) bulunmaktadır.

Bu kodu dikkatlice incelerseniz, çeşitli durum değişkenlerimizi kullanıcı arayüzümüzde nerede kullandığımızı fark edeceksiniz:

  • 6-12 satırlarında, kullanıcının cüzdanı bağlıysa (yani walletAddress.length > 0), "walletButton" kimliğine sahip düğmede kullanıcı walletAddress değerinin kısaltılmış bir sürümünü görüntüleriz; aksi takdirde sadece "Connect Wallet" (Cüzdanı Bağla) yazar.
    1. satırda, message dizesinde yakalanan, akıllı sözleşmede saklanan mevcut mesajı görüntüleriz.
  • 23-26 satırlarında, metin alanındaki girdi değiştiğinde newMessage durum değişkenimizi güncellemek için kontrollü bir bileşen (opens in a new tab) kullanırız.

Durum değişkenlerimize ek olarak, sırasıyla publishButton ve walletButton kimliklerine sahip düğmelere tıklandığında connectWalletPressed ve onUpdatePressed işlevlerinin çağrıldığını da göreceksiniz.

Son olarak, bu HelloWorld.js bileşeninin nereye eklendiğine değinelim.

React'te diğer tüm bileşenler için bir kapsayıcı görevi gören ana bileşen olan App.js dosyasına giderseniz, HelloWorld.js bileşenimizin 7. satırda enjekte edildiğini göreceksiniz.

Son olarak, sizin için sağlanan bir dosyayı daha, interact.js dosyasını inceleyelim.

interact.js dosyası

M-V-C (opens in a new tab) paradigmasına uymak istediğimizden, dapp'imizin mantığını, verilerini ve kurallarını yönetmek için tüm işlevlerimizi içeren ayrı bir dosya isteyeceğiz ve ardından bu işlevleri önyüzümüze (HelloWorld.js bileşenimize) dışa aktarabileceğiz.

👆🏽interact.js dosyamızın tam olarak amacı budur!

src dizininizdeki util klasörüne gidin; tüm akıllı sözleşme etkileşimi ve cüzdan işlevlerimizi ve değişkenlerimizi içerecek interact.js adlı bir dosya eklediğimizi fark edeceksiniz.

Dosyanın en üstünde helloWorldContract nesnesini yorum satırı haline getirdiğimizi fark edeceksiniz. Bu eğitimin ilerleyen kısımlarında, bu nesneyi yorum satırı olmaktan çıkaracağız ve akıllı sözleşmemizi bu değişkende örneklendireceğiz, ardından bunu HelloWorld.js bileşenimize dışa aktaracağız.

helloWorldContract nesnemizden sonraki uygulanmamış dört işlev şunları yapar:

  • loadCurrentMessage - bu işlev, akıllı sözleşmede saklanan mevcut mesajı yükleme mantığını işler. Alchemy Web3 API'sini (opens in a new tab) kullanarak Hello World akıllı sözleşmesine bir okuma çağrısı yapacaktır.
  • connectWallet - bu işlev, kullanıcının MetaMask'ini dapp'imize bağlayacaktır.
  • getCurrentWalletConnected - bu işlev, sayfa yüklendiğinde dapp'imize zaten bağlı bir Ethereum hesabı olup olmadığını kontrol edecek ve kullanıcı arayüzümüzü buna göre güncelleyecektir.
  • updateMessage - bu işlev, akıllı sözleşmede saklanan mesajı güncelleyecektir. Hello World akıllı sözleşmesine bir yazma çağrısı yapacaktır, bu nedenle kullanıcının MetaMask cüzdanının mesajı güncellemek için bir Ethereum işlemini imzalaması gerekecektir.

Artık neyle çalıştığımızı anladığımıza göre, akıllı sözleşmemizden nasıl okuma yapacağımızı öğrenelim!

Adım 3: Akıllı sözleşmenizden okuma yapın

Akıllı sözleşmenizden okuma yapmak için şunları başarıyla kurmanız gerekir:

  • Ethereum zincirine bir API bağlantısı
  • Akıllı sözleşmenizin yüklenmiş bir örneği
  • Akıllı sözleşme işlevinize çağrı yapacak bir işlev
  • Akıllı sözleşmeden okuduğunuz veriler değiştiğinde güncellemeleri izleyecek bir dinleyici

Bu çok fazla adım gibi gelebilir, ancak endişelenmeyin! Her birini nasıl yapacağınızı adım adım göstereceğiz! :)

Ethereum zincirine bir API bağlantısı kurun

Bu eğitimin 2. Bölümünde akıllı sözleşmemizden okuma yapmak için Alchemy Web3 anahtarımızı (opens in a new tab) nasıl kullandığımızı hatırlıyor musunuz? Zincirden okuma yapmak için dapp'inizde de bir Alchemy Web3 anahtarına ihtiyacınız olacak.

Eğer henüz sahip değilseniz, ilk olarak starter-files klasörünüzün kök dizinine gidip terminalinizde aşağıdakini çalıştırarak Alchemy Web3 (opens in a new tab)'ü yükleyin:

npm install @alch/alchemy-web3

Alchemy Web3 (opens in a new tab), Web3.js (opens in a new tab) etrafında bir sarmalayıcıdır ve bir Web3 geliştiricisi olarak hayatınızı kolaylaştırmak için gelişmiş API yöntemleri ve diğer önemli avantajlar sağlar. Uygulamanızda hemen kullanmaya başlayabilmeniz için minimum yapılandırma gerektirecek şekilde tasarlanmıştır!

Ardından, API anahtarımızı aldıktan sonra saklayabileceğimiz güvenli bir yere sahip olmak için proje dizininize dotenv (opens in a new tab) paketini yükleyin.

npm install dotenv --save

Dapp'imiz için, HTTP API anahtarımız yerine Websockets API anahtarımızı kullanacağız, çünkü bu, akıllı sözleşmede saklanan mesajın ne zaman değiştiğini algılayan bir dinleyici kurmamıza olanak tanıyacaktır.

API anahtarınızı aldıktan sonra, kök dizininizde bir .env dosyası oluşturun ve Alchemy Websockets URL'nizi buna ekleyin. Sonrasında .env dosyanız şu şekilde görünmelidir:

REACT_APP_ALCHEMY_KEY = wss://eth-goerli.ws.alchemyapi.io/v2/<anahtar>

Artık dapp'imizde Alchemy Web3 uç noktamızı kurmaya hazırız! util klasörümüzün içinde yer alan interact.js dosyamıza geri dönelim ve dosyanın en üstüne aşağıdaki kodu ekleyelim:

// interact.js

require("dotenv").config()
const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY
const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
const web3 = createAlchemyWeb3(alchemyKey)

//export const helloWorldContract;

Yukarıda, ilk olarak .env dosyamızdan Alchemy anahtarını içe aktardık ve ardından Alchemy Web3 uç noktamızı kurmak için alchemyKey değerimizi createAlchemyWeb3 işlevine geçirdik.

Bu uç nokta hazır olduğuna göre, akıllı sözleşmemizi yükleme zamanı geldi!

Hello World akıllı sözleşmenizi yükleme

Hello World akıllı sözleşmenizi yüklemek için sözleşme adresine ve ABI'sine ihtiyacınız olacak; bu eğitimin 3. Bölümünü tamamladıysanız her ikisi de Etherscan'de bulunabilir.

Etherscan'den sözleşme ABI'nizi nasıl alırsınız

Bu eğitimin 3. Bölümünü atladıysanız, 0x6f3f635A9762B47954229Ea479b4541eAF402A6A (opens in a new tab) adresine sahip HelloWorld sözleşmesini kullanabilirsiniz. ABI'si burada (opens in a new tab) bulunabilir.

Bir sözleşme ABI'si, bir sözleşmenin hangi işlevi çağıracağını belirlemek ve işlevin verileri beklediğiniz biçimde döndürmesini sağlamak için gereklidir. Sözleşme ABI'mizi kopyaladıktan sonra, onu src dizininize contract-abi.json adlı bir JSON dosyası olarak kaydedelim.

contract-abi.json dosyanız src klasörünüzde saklanmalıdır.

Sözleşme adresimiz, ABI'miz ve Alchemy Web3 uç noktamızla donanmış olarak, akıllı sözleşmemizin bir örneğini yüklemek için sözleşme yöntemini (opens in a new tab) kullanabiliriz. Sözleşme ABI'nizi interact.js dosyasına içe aktarın ve sözleşme adresinizi ekleyin.

// interact.js

const contractABI = require("../contract-abi.json")
const contractAddress = "0x6f3f635A9762B47954229Ea479b4541eAF402A6A"

Artık nihayet helloWorldContract değişkenimizi yorum satırı olmaktan çıkarabilir ve AlchemyWeb3 uç noktamızı kullanarak akıllı sözleşmeyi yükleyebiliriz:

// interact.js
export const helloWorldContract = new web3.eth.Contract(
  contractABI,
  contractAddress
)

Özetlemek gerekirse, interact.js dosyanızın ilk 12 satırı artık şu şekilde görünmelidir:

Sözleşmemizi yüklediğimize göre, artık loadCurrentMessage işlevimizi uygulayabiliriz!

interact.js dosyanızda loadCurrentMessage işlevini uygulama

Bu işlev son derece basittir. Sözleşmemizden okuma yapmak için basit bir asenkron web3 çağrısı yapacağız. İşlevimiz akıllı sözleşmede saklanan mesajı döndürecektir:

interact.js dosyanızdaki loadCurrentMessage işlevini aşağıdaki gibi güncelleyin:

// interact.js

export const loadCurrentMessage = async () => {
  const message = await helloWorldContract.methods.message().call()
  return message
}

Bu akıllı sözleşmeyi kullanıcı arayüzümüzde görüntülemek istediğimizden, HelloWorld.js bileşenimizdeki useEffect işlevini aşağıdaki gibi güncelleyelim:

// HelloWorld.js

//sadece bir kez çağrılır
useEffect(async () => {
  const message = await loadCurrentMessage()
  setMessage(message)
}, [])

Unutmayın, loadCurrentMessage işlevimizin yalnızca bileşenin ilk oluşturulması sırasında bir kez çağrılmasını istiyoruz. Akıllı sözleşmedeki mesaj değiştikten sonra kullanıcı arayüzünü otomatik olarak güncellemek için yakında addSmartContractListener işlevini uygulayacağız.

Dinleyicimize dalmadan önce, şu ana kadar elimizde ne olduğuna bir bakalım! HelloWorld.js ve interact.js dosyalarınızı kaydedin ve ardından http://localhost:3000/ (opens in a new tab) adresine gidin.

Mevcut mesajın artık "Ağa bağlantı yok" demediğini fark edeceksiniz. Bunun yerine akıllı sözleşmede saklanan mesajı yansıtıyor. Harika!

Kullanıcı arayüzünüz artık akıllı sözleşmede saklanan mesajı yansıtmalıdır

Şimdi o dinleyiciden bahsetmişken...

addSmartContractListener işlevini uygulayın

Bu eğitim serisinin 1. Bölümünde (opens in a new tab) yazdığımız HelloWorld.sol dosyasını hatırlarsanız, akıllı sözleşmemizin update işlevi çağrıldıktan sonra yayımlanan UpdatedMessages adlı bir akıllı sözleşme olayı olduğunu anımsayacaksınız (bkz. satır 9 ve 27):

Akıllı sözleşme olayları, sözleşmenizin blokzincirde bir şeyin gerçekleştiğini (yani bir olay olduğunu), belirli olayları 'dinleyebilen' ve bunlar gerçekleştiğinde harekete geçebilen önyüz uygulamanıza iletmesinin bir yoludur.

addSmartContractListener işlevi, özellikle Hello World akıllı sözleşmemizin UpdatedMessages olayını dinleyecek ve yeni mesajı görüntülemek için kullanıcı arayüzümüzü güncelleyecektir.

addSmartContractListener işlevini aşağıdaki gibi değiştirin:

Dinleyici bir olayı algıladığında ne olduğunu inceleyelim:

  • Olay yayımlandığında bir hata oluşursa, bu status durum değişkenimiz aracılığıyla kullanıcı arayüzüne yansıtılacaktır.
  • Aksi takdirde, döndürülen data nesnesini kullanacağız. data.returnValues, dizideki ilk öğenin önceki mesajı ve ikinci öğenin güncellenmiş mesajı sakladığı sıfır indeksli bir dizidir. Sonuç olarak, başarılı bir olayda message dizemizi güncellenmiş mesaja ayarlayacağız, newMessage dizesini temizleyeceğiz ve akıllı sözleşmemizde yeni bir mesajın yayınlandığını yansıtmak için status durum değişkenimizi güncelleyeceğiz.

Son olarak, HelloWorld.js bileşeninin ilk oluşturulmasında başlatılması için dinleyicimizi useEffect işlevimizde çağıralım. Sonuç olarak, useEffect işleviniz şu şekilde görünmelidir:

// HelloWorld.js

useEffect(async () => {
  const message = await loadCurrentMessage()
  setMessage(message)
  addSmartContractListener()
}, [])

Artık akıllı sözleşmemizden okuma yapabildiğimize göre, ona nasıl yazacağımızı da öğrenmek harika olurdu! Ancak, dapp'imize yazmak için öncelikle ona bağlı bir Ethereum cüzdanımız olmalıdır.

Bu yüzden, bir sonraki adımda Ethereum cüzdanımızı (MetaMask) kurmayı ve ardından onu dapp'imize bağlamayı ele alacağız!

Adım 4: Ethereum cüzdanınızı kurun

Ethereum zincirine herhangi bir şey yazmak için kullanıcıların sanal cüzdanlarının özel anahtarlarını kullanarak işlemleri imzalaması gerekir. Bu eğitim için, son kullanıcı için bu işlem imzalama sürecini son derece kolaylaştırdığından, Ethereum hesap adresinizi yönetmek için kullanılan tarayıcıdaki sanal bir cüzdan olan MetaMask (opens in a new tab)'ı kullanacağız.

Ethereum'daki işlemlerin nasıl çalıştığı hakkında daha fazla bilgi edinmek istiyorsanız, Ethereum Vakfı'nın bu sayfasına göz atın.

MetaMask'ı İndirin

Buradan (opens in a new tab) ücretsiz olarak MetaMask'ı indirebilir ve bir hesap oluşturabilirsiniz. Bir hesap oluştururken veya zaten bir hesabınız varsa, sağ üstteki "Goerli Test Network" (Goerli Test Ağı) seçeneğine geçtiğinizden emin olun (böylece gerçek parayla işlem yapmamış oluruz).

Bir Musluktan (Faucet) Ether Ekleyin

Ethereum blokzincirinde bir işlemi imzalamak için biraz sahte ETH'ye ihtiyacımız olacak. ETH almak için FaucETH (opens in a new tab)'e gidebilir ve Goerli hesap adresinizi girebilir, "Request funds" (Fon talep et) seçeneğine tıklayabilir, ardından açılır menüden "Ethereum Testnet Goerli"yi seçebilir ve son olarak tekrar "Request funds" düğmesine tıklayabilirsiniz. Kısa bir süre sonra MetaMask hesabınızda ETH görmelisiniz!

Bakiyenizi Kontrol Edin

Bakiyemizin orada olduğunu iki kez kontrol etmek için, Alchemy'nin oluşturucu aracını (opens in a new tab) kullanarak bir eth_getBalance (opens in a new tab) isteği yapalım. Bu, cüzdanımızdaki ETH miktarını döndürecektir. MetaMask hesap adresinizi girip "Send Request" (İstek Gönder) düğmesine tıkladıktan sonra şöyle bir yanıt görmelisiniz:

{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"}

NOT: Bu sonuç ETH değil, wei cinsindendir. Wei, Ether'in en küçük birimi olarak kullanılır. Wei'den ETH'ye dönüşüm şöyledir: 1 ETH = 10¹⁸ wei. Yani 0xde0b6b3a7640000 değerini ondalık sayıya çevirirsek 1*10¹⁸ elde ederiz, bu da 1 ETH'ye eşittir.

Oh be! Sahte paramızın hepsi orada! 🤑

Adım 5: MetaMask'ı Kullanıcı Arayüzünüze Bağlayın

MetaMask cüzdanımız kurulduğuna göre, dapp'imizi ona bağlayalım!

connectWallet işlevi

interact.js dosyamızda, daha sonra HelloWorld.js bileşenimizde çağırabileceğimiz connectWallet işlevini uygulayalım.

connectWallet işlevini aşağıdaki gibi değiştirelim:

Peki bu devasa kod bloğu tam olarak ne yapıyor?

Öncelikle, tarayıcınızda window.ethereum nesnesinin etkin olup olmadığını kontrol eder.

window.ethereum, MetaMask ve diğer cüzdan sağlayıcıları tarafından enjekte edilen ve web sitelerinin kullanıcıların Ethereum hesaplarını talep etmesine olanak tanıyan küresel bir API'dir. Onaylanırsa, kullanıcının bağlı olduğu blokzincirlerden veri okuyabilir ve kullanıcının mesajları ve işlemleri imzalamasını önerebilir. Daha fazla bilgi için MetaMask belgelerine (opens in a new tab) göz atın!

Eğer window.ethereum mevcut değilse, bu MetaMask'ın yüklü olmadığı anlamına gelir. Bu, döndürülen address değerinin boş bir dize olduğu ve status JSX nesnesinin kullanıcının MetaMask'ı yüklemesi gerektiğini ilettiği bir JSON nesnesinin döndürülmesiyle sonuçlanır.

Şimdi, eğer window.ethereum mevcut ise, işte o zaman işler ilginçleşir.

Bir try/catch döngüsü kullanarak, window.ethereum.request({ method: "eth_requestAccounts" }); (opens in a new tab) çağrısı yaparak MetaMask'a bağlanmayı deneyeceğiz. Bu işlevi çağırmak tarayıcıda MetaMask'ı açacak ve kullanıcıdan cüzdanını dapp'inize bağlaması istenecektir.

  • Kullanıcı bağlanmayı seçerse, method: "eth_requestAccounts", kullanıcının dapp'e bağlanan tüm hesap adreslerini içeren bir dizi döndürecektir. Sonuç olarak, connectWallet işlevimiz, bu dizideki ilk address değerini (bkz. satır 9) ve kullanıcıdan akıllı sözleşmeye bir mesaj yazmasını isteyen bir status mesajını içeren bir JSON nesnesi döndürecektir.
  • Kullanıcı bağlantıyı reddederse, JSON nesnesi döndürülen address için boş bir dize ve kullanıcının bağlantıyı reddettiğini yansıtan bir status mesajı içerecektir.

Bu connectWallet işlevini yazdığımıza göre, bir sonraki adım onu HelloWorld.js bileşenimizde çağırmaktır.

connectWallet işlevini HelloWorld.js Kullanıcı Arayüzü Bileşeninize Ekleyin

HelloWorld.js içindeki connectWalletPressed işlevine gidin ve onu aşağıdaki gibi güncelleyin:

// HelloWorld.js

const connectWalletPressed = async () => {
  const walletResponse = await connectWallet()
  setStatus(walletResponse.status)
  setWallet(walletResponse.address)
}

İşlevselliğimizin çoğunun interact.js dosyasından HelloWorld.js bileşenimizden nasıl soyutlandığına dikkat ettiniz mi? Bu, M-V-C paradigmasına uymamız içindir!

connectWalletPressed içinde, içe aktarılan connectWallet işlevimize basitçe bir await çağrısı yaparız ve yanıtını kullanarak status ve walletAddress değişkenlerimizi durum hook'ları aracılığıyla güncelleriz.

Şimdi, her iki dosyayı da (HelloWorld.js ve interact.js) kaydedelim ve şu ana kadarki kullanıcı arayüzümüzü test edelim.

Tarayıcınızı http://localhost:3000/ (opens in a new tab) sayfasında açın ve sayfanın sağ üst köşesindeki "Connect Wallet" (Cüzdanı Bağla) düğmesine basın.

MetaMask yüklüyse, cüzdanınızı dapp'inize bağlamanız istenecektir. Bağlanma davetini kabul edin.

Cüzdan düğmesinin artık adresinizin bağlı olduğunu yansıttığını görmelisiniz! Eveeeet 🔥

Ardından, sayfayı yenilemeyi deneyin... bu garip. Cüzdan düğmemiz, zaten bağlı olmasına rağmen bizden MetaMask'ı bağlamamızı istiyor...

Ancak korkmayın! Bir adresin dapp'imize zaten bağlı olup olmadığını kontrol edecek ve kullanıcı arayüzümüzü buna göre güncelleyecek olan getCurrentWalletConnected işlevini uygulayarak bunu kolayca çözebiliriz!

getCurrentWalletConnected işlevi

interact.js dosyasındaki getCurrentWalletConnected işlevinizi aşağıdaki gibi güncelleyin:

Bu kod, bir önceki adımda yazdığımız connectWallet işlevine çok benzer.

Temel fark, kullanıcının cüzdanını bağlaması için MetaMask'ı açan eth_requestAccounts yöntemini çağırmak yerine, burada basitçe şu anda dapp'imize bağlı olan MetaMask adreslerini içeren bir dizi döndüren eth_accounts yöntemini çağırmamızdır.

Bu işlevi çalışırken görmek için, onu HelloWorld.js bileşenimizin useEffect işlevinde çağıralım:

walletAddress ve status durum değişkenlerimizi güncellemek için getCurrentWalletConnected çağrımızın yanıtını kullandığımıza dikkat edin.

Bu kodu eklediğinize göre, tarayıcı penceremizi yenilemeyi deneyelim.

Harikaaaa! Düğme bağlı olduğunuzu söylemeli ve yeniledikten sonra bile bağlı cüzdanınızın adresinin bir önizlemesini göstermelidir!

addWalletListener işlevini uygulayın

Dapp cüzdan kurulumumuzdaki son adım, kullanıcının bağlantıyı kesmesi veya hesap değiştirmesi gibi cüzdanımızın durumu değiştiğinde kullanıcı arayüzümüzün güncellenmesi için cüzdan dinleyicisini uygulamaktır.

HelloWorld.js dosyanızda, addWalletListener işlevinizi aşağıdaki gibi değiştirin:

Eminim bu noktada burada neler olup bittiğini anlamak için yardımımıza bile ihtiyacınız yoktur, ancak eksiksiz olması adına hızlıca inceleyelim:

  • İlk olarak, işlevimiz window.ethereum nesnesinin etkin olup olmadığını (yani MetaMask'ın yüklü olup olmadığını) kontrol eder.
    • Eğer değilse, status durum değişkenimizi kullanıcıdan MetaMask'ı yüklemesini isteyen bir JSX dizesine ayarlarız.
    • Etkinse, 3. satırda kullanıcının dapp'e ek bir hesap bağlaması, hesap değiştirmesi veya bir hesabın bağlantısını kesmesi gibi MetaMask cüzdanındaki durum değişikliklerini dinleyen window.ethereum.on("accountsChanged") dinleyicisini kurarız. Bağlı en az bir hesap varsa, walletAddress durum değişkeni, dinleyici tarafından döndürülen accounts dizisindeki ilk hesap olarak güncellenir. Aksi takdirde, walletAddress boş bir dize olarak ayarlanır.

Son olarak, onu useEffect işlevimizde çağırmalıyız:

Ve işte bu kadar! Tüm cüzdan işlevselliğimizi programlamayı başarıyla tamamladık! Şimdi son görevimize geçelim: akıllı sözleşmemizde saklanan mesajı güncellemek!

Adım 6: updateMessage işlevini uygulayın

Pekala millet, son düzlüğe geldik! interact.js dosyanızın updateMessage işlevinde şunları yapacağız:

  1. Akıllı sözleşmemizde yayınlamak istediğimiz mesajın geçerli olduğundan emin olmak
  2. MetaMask kullanarak işlemimizi imzalamak
  3. Bu işlevi HelloWorld.js önyüz bileşenimizden çağırmak

Bu çok uzun sürmeyecek; hadi bu dapp'i bitirelim!

Girdi hatası işleme

Doğal olarak, işlevin başında bir tür girdi hatası işleme mekanizmasına sahip olmak mantıklıdır.

MetaMask uzantısı yüklü değilse, bağlı bir cüzdan yoksa (yani geçirilen address boş bir dizeyse) veya message boş bir dizeyse işlevimizin erken dönmesini isteyeceğiz. updateMessage işlevine aşağıdaki hata işleme kodunu ekleyelim:

Artık uygun bir girdi hatası işleme mekanizmasına sahip olduğuna göre, işlemi MetaMask aracılığıyla imzalama zamanı geldi!

İşlemimizi imzalama

Geleneksel web3 Ethereum işlemlerine zaten aşinaysanız, bir sonraki yazacağımız kod çok tanıdık gelecektir. Girdi hatası işleme kodunuzun altına, updateMessage işlevine aşağıdakini ekleyin:

Neler olduğunu inceleyelim. İlk olarak, işlem parametrelerimizi ayarlıyoruz, burada:

  • to alıcı adresini (akıllı sözleşmemizi) belirtir
  • from işlemin imzalayıcısını, işlevimize geçirdiğimiz address değişkenini belirtir
  • data, message dize değişkenimizi girdi olarak alan Hello World akıllı sözleşmemizin update yöntemine yapılan çağrıyı içerir

Ardından, MetaMask'tan işlemi imzalamasını istediğimiz bir await çağrısı olan window.ethereum.request çağrısını yaparız. 11. ve 12. satırlarda eth yöntemimiz olan eth_sendTransaction yöntemini belirttiğimize ve transactionParameters parametremizi geçirdiğimize dikkat edin.

Bu noktada, tarayıcıda MetaMask açılacak ve kullanıcıdan işlemi imzalamasını veya reddetmesini isteyecektir.

  • İşlem başarılı olursa, işlev, status JSX dizesinin kullanıcıdan işlemi hakkında daha fazla bilgi için Etherscan'i kontrol etmesini istediği bir JSON nesnesi döndürecektir.
  • İşlem başarısız olursa, işlev, status dizesinin hata mesajını ilettiği bir JSON nesnesi döndürecektir.

Sonuç olarak, updateMessage işlevimiz şu şekilde görünmelidir:

Son olarak, updateMessage işlevimizi HelloWorld.js bileşenimize bağlamamız gerekiyor.

updateMessage işlevini HelloWorld.js önyüzüne bağlayın

onUpdatePressed işlevimiz, içe aktarılan updateMessage işlevine bir await çağrısı yapmalı ve işlemimizin başarılı olup olmadığını yansıtmak için status durum değişkenini değiştirmelidir:

// HelloWorld.js

const onUpdatePressed = async () => {
  const { status } = await updateMessage(walletAddress, newMessage)
  setStatus(status)
}

Son derece temiz ve basit. Ve bilin bakalım ne oldu... DAPP'İNİZ TAMAMLANDI!!!

Devam edin ve Update (Güncelle) düğmesini test edin!

Kendi özel dapp'inizi yapın

Vay canına, eğitimin sonuna geldiniz! Özetlemek gerekirse, şunları nasıl yapacağınızı öğrendiniz:

  • Dapp projenize bir MetaMask cüzdanı bağlamak
  • Alchemy Web3 (opens in a new tab) API'sini kullanarak akıllı sözleşmenizden veri okumak
  • MetaMask kullanarak Ethereum işlemlerini imzalamak

Artık kendi özel dapp projenizi oluşturmak için bu eğitimdeki becerileri uygulamak üzere tam donanımlısınız! Her zaman olduğu gibi, herhangi bir sorunuz varsa, yardım için Alchemy Discord (opens in a new tab) üzerinden bize ulaşmaktan çekinmeyin. 🧙‍♂️

Bu eğitimi tamamladığınızda, Twitter'da @alchemyplatform (opens in a new tab) hesabımızı etiketleyerek deneyiminizin nasıl olduğunu veya herhangi bir geri bildiriminiz olup olmadığını bize bildirin!