3. Adım: Bir Dapp Geliştirici Portalı başlatın

    Üçüncü Adımlar

    Yani, temel bilgileri edindiniz. Önceki bölümde, akıllı bir sözleşme geliştirdiniz ve bunu Truffle kullanarak devreye aldınız. Bununla birlikte, önceki bölümde, akıllı sözleşmeleriniz yerel bir geliştirme ağına dağıtılmıştı ve bu hiç de eğlenceli değil, çünkü yalnızca siz bir şeyleri dağıtabilir ve bu yerel test ağıyla etkileşim kurabilirsiniz! Arkadaş istiyoruz! Ve diğer insanların uyguladığı diğer akıllı sözleşmelere erişim!

    Bu nedenle, bu bölümde, Ethereum ekosisteminde gerçekleşen tüm eylemlere katılabilmeniz için herkese açık bir Ethereum test ağına geçiş yapacağız.!

    Başlayalım!

    İlk olarak, bu halka açık Ethereum ağlarına nasıl erişeceğiniz hakkında konuşacağız..

    Bu ağlara erişmek için, ilgili ağa bağlı bir düğüme bağlanmanız gerekir. Her Ethereum ağını kendi küçük Ethereum dünyası olarak görebilir ve bir Ethereum düğümünü bu dünyaların her birine ağ geçidiniz veya erişim noktanız olarak görüntüleyebilirsiniz! Ethereum dağıtılmış bir ağ olduğu için, her Ethereum düğümü bağlı olduğu ağın tüm durumunu depolar (tam durumu saklaması gerekmeyen ancak şimdilik endişelenmeyin) ve sürekli iletişim kurar. bu durumu güncel tutmak için ağdaki diğer düğümlerle birlikte! Bu nedenle, bu durumdan okuyup yazabilmek için bu düğümlerden birine erişmemiz gerekecek.

    Şu anda mevcut olan birçok Ethereum istemcisinden birini (Hyperledger Besu (ConsenSys tarafından geliştirilen Java istemcisi), Geth (Go istemcisi), Parity (Rust istemcisi), vb.) Kullanarak kendi düğümünüzü çok iyi bir şekilde barındırabilirsiniz – ancak, oldukça fazla Kendi Ethereum düğümünüzü barındırmak ve sürdürmekle birlikte gelen biraz DevOps ek yükü – özellikle de bunu güvenilir bir şekilde yapmak istiyorsanız! Bu nedenle, ConsenSys olarak biz, dünya standartlarında bir Ethereum altyapı teklifi olan Infura’yı inşa ettik. Infura, Ethereum düğüm kümelerine anında, güvenilir ve ölçeklenebilir erişim sağlayarak, sizin için tüm “düğüm yönetimi” parçasını halleder! Infura’yı “Hizmet olarak Ethereum düğümleri” olarak düşünebilirsiniz &# 128578;

    Infura’ya Başlarken

    Infura’yı kullanmaya başlamak için şu adresten bir hesap açmanız gerekir: infura.io. Endişelenmeyin – başlamak tamamen ücretsizdir ve herhangi bir hassas bilgi girmenize gerek kalmaz!

    Kaydolduktan sonra, şuna benzeyen bir sayfaya yönlendirileceksiniz:

    infuraLogin

    Bu sayfanın önerdiği gibi, başlamak için ilk seçeneği “Başlayın ve Ethereum ağına erişmek için ilk projenizi oluşturun!”

    Projenize istediğiniz adı verebilirsiniz – biz bizimkine “test projesi” adını vereceğiz.

    InfuraNP

    Şimdi, Infura düğümlerine erişmeniz için gereken kimlik bilgileri size sunulacak!


    InfuraC

    Bu sayfayı açık tutun! Ona daha sonra geri döneceğiz &# 128578;

    Sonraki yapacağımız şey yeni bir Truffle projesini başlatmak olacak. Truffle’ı kurmak için yardıma ihtiyacınız varsa, lütfen bu belgenin önceki bölümüne bakın..

    Yeni bir Truffle projesini başlatmak için yeni bir klasör oluşturun ve

    yer mantarı başlatma

    Ardından, işlemlerinizi Infura düğümlerine gönderilmeden önce imzalayabilmeniz için yeni başlatılan projenize Truffle HD Cüzdan sağlayıcısını eklemek isteyeceksiniz. Ethereum’da yaptığınız her durum değişikliği bir işlem şeklinde gelir – ister bir sözleşme dağıtmak, ister bir sözleşme dahilinde bir işlevi çağırmak veya bir token göndermek olsun! Her işlemin bir hesap tarafından imzalanması gerekir – bu nedenle, uygulamamızın Ethereum’da durum değişiklikleri yapabilmesi için işlemleri imzalama becerisine ihtiyacı vardır.!

    Her işlemin maliyeti de eterdir. Bu işlem maliyeti “gaz maliyeti” olarak adlandırılır. Bu nedenle, imzalı işlemlerimizin Infura düğümlerine gönderildikten sonra ağ tarafından işlenmesini sağlamak için hesabımıza biraz eter ile para yatırmamız gerekecek. Bunu biraz sonra ele alacağız, ancak bu, bir cüzdana ihtiyacınız olmasının diğer bir önemli nedenidir & cüzdan sağlayıcı!

    Truffle HD Cüzdan sağlayıcısını terminalinizde yeni başlatılan proje türünüze eklemek için:

    npm install –save @ truffle / hdwallet-provider

    Bu bazı uyarılara neden olabilir, ancak yüklendiği sürece gitmekte fayda var!

    Artık uygulamamızın kullanması için bir Ethereum hesabı oluşturabiliriz! Cüzdan sağlayıcımız bir HD (hiyerarşik deterministik) cüzdan olduğundan, aynı tohum cümlesini veya anımsatıcıyı kullanarak belirleyici olarak hesaplar oluşturabiliriz..

    Hesabımızı oluşturmak için önce Ganache’yi başlatmamız gerekecek. Ganache, kendi yerel geliştirme ağımızı kolayca oluşturmamızı sağlayan bir Truffle ürünüdür. Ganache çalıştırmak için şunu yazın:

    Ganache-cli

    Bu kılavuzun 2. Adımını tamamladıysanız, Ganache / ganache-cli’nin zaten kurulu olması gerekir; yüklemediyseniz, npm komutunu kullanarak kurabilirsiniz:

    npm yükleme -g ganache-cli

    Veya iplik kullanıyorsanız 

    iplik global ganache-cli ekle

    Ardından, uygulamamızın Ganache ile konuşmasına izin vermemiz gerekecek. Proje dizininize gidin ve truffle-config.js dosyasını kontrol edin, aşağıdaki satırları ağ altında kaldırın (veya ekleyin):

    geliştirme: {ana bilgisayar: "127.0.0.1", // Localhost (varsayılan: yok) bağlantı noktası: 8545, // Standart Ethereum bağlantı noktası (varsayılan: yok) network_id: "*" // Herhangi bir ağ (varsayılan: yok)},

    alışılmadık

    Güzel! Artık uygulamamız 127.0.0.1:8545’te çalışan Ganache geliştirme ağımızla konuşabilir! Şimdi, yeni bir terminal penceresinde (ancak yine de proje klasörünüzde), komutu çalıştırın.

    trüf konsolu

     Ganache ağınıza bağlanmak için. Endişelenmeyin – daha sonra genel bir ağa bağlanacağız! Anahtarlarımızı oluşturmak için hemen Ganache’ye bağlanmamız gerekiyor &# 128578;

    Not: Sorun yaşıyorsanız, Ganache’de RPC Sunucusu bağlantı noktası numaranızın truffle yapılandırma dosyanızla eşleştiğinden emin olun. Varsayılan durumda 8545 çalışmalıdır, aksi takdirde yapılandırma dosyanızı Ganache ile eşleşecek şekilde değiştirin..

    Şimdi, cüzdanınızı oluşturmak için Truffle konsoluna aşağıdaki komutları girin:

    const HDWalletProvider = required (‘@ truffle / hdwallet-sağlayıcı’);

    Bu, “tanımsız” yanıtıyla sonuçlanmalıdır

    12 kelimelik anımsatıcınız için aşağıdakiler gibi bir anımsatıcı oluşturucu kullanabilirsiniz: Bu Eğer istersen!

    MNEMONIC (TOHUM) CÜMLECİNİZİ SAKLADIĞINIZDAN EMİN OLUN! Ona daha sonra ihtiyacımız olacak &# 128515;

    Ardından, terminalinize aşağıdaki komutu ekleyin (hala trüf mantarı geliştirme aşamasındayken):

    const mnemonic = ‘burada 12 kelime’; const wallet = new HDWalletProvider (anımsatıcı, "http: // localhost: 8545");

    Şimdi, trüf konsolunuzda şu komutu girin: 

    cüzdan

    Yukarı kaydırırsanız, bunun gibi bir hesap listesi görmelisiniz!

    Addy

    Ganache’ye bağlıyken bu hesabın oluşturulmasına rağmen, aynı Ethereum hesaplarını herhangi bir Ethereum ağında kullanabiliriz (ancak, aynı hesap herhangi bir Ethereum ağında, bununla ilgili varlıklar / etkinlikler için kullanılabilir olsa da lütfen unutmayın) hesap ağa özgüdür – örneğin, Ethereum Mainnet’te bir işlem yaparsam, bu işlem yalnızca Ethereum Mainnet’te gerçekleşir ve başka bir ağda gerçekleşmez). Şimdi Ganache (yerel geliştirme ağı) ile etkileşime girmeyi bırakacağız ve bu hesabı bazı genel ağlarla etkileşimde bulunmak için kullanmaya başlayacağız.!!

    Genelde, genel bir ağ ile etkileşim kurarken yapmanız gereken ilk şey, o ağın eterinin bir kısmını elde etmektir. Bizim durumumuzda, Ropsten genel test ağına bağlanacağız, bu yüzden biraz Ropsten eteri (ETH) edinmemiz gerekecek! Endişelenmeyin – net ETH testi ücretsizdir, bol miktarda bulunur ve elde etmesi çok kolaydır &# 128077;

    Test ETH’sini edinme zamanı

    Biraz Ropsten ETH almak için şu adrese gidin: Ropsten musluk. Hesap adresinizi ve viola’yı yapıştırın! Bir miktar Ropsten ETH aldınız ve Ropsten ağına işlem göndermeye (yani durum değişiklikleri yapmaya) başlayabilirsiniz!

    Referans olarak, Ropsten test ağı, kodunuzu Ethereum ana ağını yakından yansıtan bir ortamda test edebileceğiniz halka açık bir Ethereum test ağıdır. Ropsten test ağı (ve diğer halka açık Ethereum test ağları) arasındaki temel fark, testnet bölgesinde ETH’nin bol olması ve gerçek dünya değerinin olmamasıdır! Ethereum ana ağıyla etkileşime girmeye başladığınızda, işlemleriniz için ödeme yapmak için kullandığınız Ether (gaz maliyetleri) GERÇEK dolara mal olacaktır – bu yüzden işleri önceden yaptığımızdan emin olmalıyız, böylece zorluklarımızı kaybetmeyelim – kazanılmış nakit / değerli ana ağımız ETH!

    Ropsten test ağı, diğer herkese açık test ağlarının çoğuyla birlikte, zincirde gerçekleşen etkinliği görüntülemeniz için birçok blok kaşifine sahiptir (https://ropsten.etherscan.io/). Finanse edilen hesabınızı görmek için, hesabınızın adresini gezgine yapıştırmanız yeterlidir – ve onunla ilişkili tüm geçmişi görüntüleyebilirsiniz:

    Ekran Görüntüsü 2020 09 01, 4 34 21 AM

    Peki! Artık cüzdan sağlayıcımız ve Ropsten ETH ile finanse edilen bir hesabımız olduğuna göre, projemize geri dönebilir ve onu Ropsten test ağına bağlı Infura düğümlerine yönlendirebiliriz.

    Yapmak isteyeceğimiz ilk şey, değerli GİZLERİMİZİ barındırmak için bir.env dosyası oluşturmaktır! Bu sırlar arasında Infura API anahtarımız (Infura hesabımızı oluşturduğumuzda oluşturulur) ve anımsatıcı ifademiz yer alır..

    Projenizin kök düzeyinde, yeni bir “.env” dosyası oluşturmanız yeterlidir. Ayrıca, terminalde aşağıdaki komutu girerek dotenv NPM paketini yüklemeniz gerekecektir.

    npm install –save dotenv

    Bu new.env dosyasında iki şeye ihtiyacınız olacak:

    INFURA_API_KEY = API ANAHTARINIZI BURAYA GİRİN (alıntı yok)

    MNEMONIC = ”mercek balina yelpaze tel kabarcık çevrimiçi koltuk ifşa stok numarası cümle kazanan”

    INFURA_API_KEY, infura’da daha önce oluşturduğunuz projenin Proje Kimliğidir:

    Ekran Görüntüsü 2020 09 01 4 37 12 AM

    Ve MNEMONIC, daha önce hesabınızı oluşturmak için kullandığınız 12 kelimelik tohum cümlesidir..

    Dosyanız şimdi şöyle görünmelidir:

    Ekran Görüntüsü 2020 09 01, 4 41 53 AM

    Pekala, yaklaşıyoruz!

    NOT: Bunu bir Github havuzuna gönderecekseniz veya bu projeyi herhangi bir şekilde herkese açık hale getirecekseniz ,.env dosyanızı in.gitignore’da tuttuğunuzdan emin olun, böylece sırlarınız açığa çıkmaz.! 

    Şimdi, truffle-config.js dosyasına gitmemiz gerekecek. Burada, sağlayıcımızı belirtmek için (Infura (daha önce kurduğumuz Truffle HDWallet Sağlayıcısı) ile etkileşim kurmak için kullanılan birkaç şey eklememiz ve uygulamamızı Ropsten Infura düğümlerine yönlendirmemiz gerekecek..

    Dosyanın en üstüne şunu ekleyin:

    gerektirir ("dotenv") .config (); const HDWalletProvider = gerekli ("@ truffle / hdwallet-sağlayıcı");

    Ardından, “ağlar” altında aşağıdaki ağı eklemek isteyeceksiniz:

    ropsten: {sağlayıcı: () => new HDWalletProvider (process.env.MNEMONIC, `https://ropsten.infura.io/v3/$ {process.env.INFURA_API_KEY}`), network_id: 3, // Ropsten’in id gas: 5500000, // Ropsten bir ana ağ onaylarından daha düşük blok sınırı: 2, // konuşlandırmalar arasında beklenecek onay sayısı. (varsayılan: 0) timeoutBlocks: 200, // Bir dağıtım zaman aşımına uğramadan önceki blok sayısı (minimum / varsayılan: 50) skipDryRun: true // Taşıma işlemlerinden önce kuru çalıştırmayı atla? (varsayılan: genel ağlar için yanlış)}

     

    Şimdi truffle-config.js dosyanız şuna benzer!

    Kenar notu:

    Infura uç noktaları kullanıyorsanız, cüzdanları olmadığı için “from” parametresi gereklidir. Ganache veya Geth RPC uç noktaları kullanıyorsanız, bu isteğe bağlı bir parametredir.

    Ekran Görüntüsü 2020 09 01, 4 50 54 AM

    ARTIK BÜYÜYE HAZIRIZ! ROPSTEN için akıllı bir sözleşme yapmanın zamanı geldi!

    Akıllı Sözleşme Oluşturma

    Solidity kurulumu

    Öncelikle, dağıtmak için akıllı bir sözleşme oluşturmak isteyeceğiz! Bu kılavuzun önceki bölümünde geliştirdiğiniz akıllı sözleşmeyi alabilir, kendi akıllı sözleşmenizi oluşturabilir veya yalnızca aşağıdaki (son derece basit) örnek sözleşmeyi kullanabilirsiniz:

    pragma sağlamlığı >= 0.5.8; SimpleStorage {uint256 storedData; işlev kümesi (uint256 x) genel {depolanmışData = x; } işlevi get () genel görünüm döndürür (uint256) {depolanmışVeri döndür; }}

    Bu sözleşme, projenizin “sözleşmeler” klasöründe bir “.sol” (Solidity) dosyası olarak oluşturulmalıdır (bu senaryoda, SimpleStorage sözleşmemiz olan SimpleStorage.sol dosyasını oluşturduk:

    iskele

    Taşıma kurulumu

    Ardından, taşıma dosyamızı oluşturmamız gerekecek!

    Geçişler, sözleşmeleri Ethereum ağına dağıtmanıza yardımcı olan JavaScript dosyalarıdır. Bu dosyalar, dağıtım görevlerinizi aşamalandırmaktan sorumludur ve dağıtım ihtiyaçlarınızın zamanla değişeceği varsayımı altında yazılır. Projeniz geliştikçe, blok zincirindeki bu evrimi ilerletmek için yeni geçiş komut dosyaları oluşturacaksınız. Daha önce çalıştırılan geçişlerin geçmişi, özel bir Geçişler sözleşmesi aracılığıyla zincir üzerinde kaydedilir. Onlar hakkında daha fazla bilgi bulabilirsiniz İşte.

    Sözleşmemizi dağıtmak için taşıma dosyamız şöyle görünecek:

    const SimpleStorage = artifacts.require ("SimpleStorage.sol"); module.exports = işlev (dağıtıcı) {deployer.deploy (SimpleStorage); };

    Bu dosyayı “2_deploy_contracts.js” adı altında “geçişler” klasörüne kaydedin.

    İlk Genel Sözleşmenizi Dağıtma

    Geçiş zamanı

    Artık BÜYÜ OLMAK İÇİN GERÇEKTEN hazırsınız! Konsola geri dönün ve yazın

    truffle migrate –network ropsten

    Boom!&# 128163; Kodunuz halka açık Ropsten Ethereum Test Net’e dağıtıldı!!! 

    Az önce olan şuydu:

    1. Solidity akıllı sözleşmeniz (“sözleşmeler” klasöründe), Ethereum Sanal Makinesi’nin kullanması için makine tarafından okunabilir kod olan bayt koduna göre derlendi.

    2. Bu bayt kodu, + bazı diğer veriler, bir işlemde birlikte paketlendi.

    3. Bu işlem, hesabınız tarafından imzalandı.

    4. Bu işlem, Ropsten’e bağlanan Infura düğümüne gönderildi..

    5. İşlem ağ boyunca yayıldı, bir Ropsten madencisi tarafından alındı ​​ve bir Ropsten bloğuna dahil edildi.

    6. Akıllı sözleşmeniz artık Ropsten blockchain’de CANLI!

    Sözleşmenizi Etherscan kullanarak görüntüleyebilirsiniz: https://ropsten.etherscan.io/ – görüntülemek için sözleşmenin adresini (terminalinizde olmalıdır) yapıştırmanız yeterlidir!

    Ekran Görüntüsü 2020 09 01 5 19 12 AM

    İnanılmaz! İlk akıllı sözleşmemizi bir PUBLIC Ethereum ağına yerleştirdik! &# 129327;

    İşlem, Ethereum ana ağına dağıtım için tamamen aynıdır, ancak truffle-config.js dosyasındaki ağı Ethereum ana ağı için değiştirirsiniz (ve tabii ki, Ropsten yerine mainnet Truffle geçiş komutunu çalıştırın) ! Size bu süreci burada anlatmayacağız, çünkü Ethereum ana ağına konuşlandırmak size gerçek $ ‘lara mal olacak – ancak bu konuda yardım istiyorsanız, şuraya atlayın: ConsenSys Discord ve yardımcı olmaktan çok mutlu oluruz!

    Web3 Ön Uç Oluşturma 

    Artık sözleşmemizi Ropsten’a sunduğumuza göre, onunla etkileşim kurmak için basit bir kullanıcı arayüzü oluşturalım.!

    Not: dApp “ön uçları” yalnızca günlük, normal eski ön uçlarınızdır – bu nedenle, aşina olduğumuz tüm eski araçlarımızı (oluşturma-tepki verme-uygulama vb.) Ön ucumuzu canlandırmak için kullanabiliriz ve sonra ön ucun Ethereum’dan okuması ve Ethereum’a yazması için birkaç şey ekleyin! Bu, tüm eski web geliştirme becerilerinizin doğrudan Ethereum-land / Web3’e aktarılabileceği anlamına gelir.!!

    React projemizi çalıştırın 

    Pekala, haydi başlayalım.

    Öncelikle, depolama sözleşmemiz için yaptığımız tüm bilgileri içeren bir dizine sahip olduğunuzdan emin olun. Klasörüme “geri depolama” adını verdim ve sözleşme kurulumumuzu almak ve dağıtmak için az önce tamamladığımız işi içeriyor. 

    Ekran Görüntüsü 2020 09 01 5 26 33 AM

    Şimdi bir tepki projesi başlatarak başlayacağız, bu örnekte bizimki diyelim “depolama laboratuvarı”

    Terminalimizde projemize başlamak için aşağıdakileri çalıştıralım 

    npx create-react-app storage-lab

    Artık yeni proje şablonumuzu aldığımıza göre, proje dizinine geçelim

    cd depolama laboratuvarı

    Artık projemizin içinde olduğumuza göre, şimdi projemizin Ethereum ile etkileşime girmesini sağlayacak Web3 paketini ekleyeceğiz! Web3 hakkında daha fazlası İşte

    npm web3 yükle

    Web3, kullanabileceğimiz iki ana paketten biridir, diğeri ethers.js. Bu örnek için web3 kullanacağız, ancak ethers.js hakkında daha fazla bilgi edinmek isterseniz bir göz atın İşte 

    İkisinin ayrıntılı bir açıklaması için, bu yazıya bir göz atın. web3 vs eterler

    Harika! Artık tepki projemizin sözleşmemizle etkileşim kurmasına neredeyse hazırız!

    Öncelikle, akıllı sözleşmelerimizi içeren halihazırda yaptığımız işi içeren dizini daha öncekinden alalım (benim için bu “geri depolama”) ve şimdi bunu yeni tepki projemize ekleyelim. Bu, src’mizle aynı seviyede yaşayacak ve şimdi ihtiyacımız olan her şeye react REPO’mızın içinde sahip olmalıyız..

    Ekran Görüntüsü 2020 09 01 5 31 38 AM

    Daha sonra, ABI bilgilerimizi içeren dosyamızı kurmamız gerekecek.

    “ABI?”

    Sordun sevindim! 

    Sözleşme Uygulaması İkili Arayüzü (ABI), Ethereum ekosistemindeki sözleşmelerle hem blok zincirinin dışından hem de sözleşmeden sözleşmeye etkileşim için etkileşime girmenin standart yoludur. SimpleStorage sözleşmemizi daha önceki bir adımda derlediğimizde, bizim için bir JSON dosyası oluşturdu. Kendiniz kontrol edin, yapı / sözleşmelerimizin içinde bir SimpleStorage.json dosyamız var

    Ekran Görüntüsü 2020 09 01, 6 04 20 AM

    Bu dosyaya ilk bakışta çok fazla bilgi ortaya çıkacaktır, şu anda sözleşmemizi geliştirmekte olduğumuz ön uç ile senkronize etmek için sadece ABI’ye odaklanmamız gerekiyor. Bu JSON, sözleşmemizi ön ucumuzla iletmek için ihtiyaç duyduğumuz bilgileri içerir.

    ABI’mız nesneleri tutan bir dizidir. Dosyaya daha yakından baktığınızda, bu nesnelerin her birinin aslında SimpleStorage sözleşmemizin içerdiği işlevler olduğunu görebilirsiniz..

    Ekran Görüntüsü 2020 09 01 5 33 23 AM

    Hızlıca görebilirsin

    “Ad”: “set”

    “Ad”: “almak”

    her ikisi de “tür:” işlev “ile akıllı sözleşmemizi yazarken belirttiğimiz işlevlerin her ikisi de!

    Truffle sonraki birkaç adımı gizlese de, tüm temel bilgileri öğrenmeniz için işleri yapmanın çok daha “manuel” bir yolunu inceleyeceğiz. &# 128578;

    Öncelikle, devam edin ve abi bilgilerinizi kopyalayın – buna birazdan ihtiyacımız olacak. 

    Src’mizin içinde “abi” adında bir klasör oluşturalım..

    Yeni yapılmış abi klasörümüzün içinde şimdi abi.js adında bir dosya yapalım

    Not: Teknik olarak bu ayrıma ihtiyacımız yok ve abi.js’mizi src’ye ekleyebiliriz, ancak abi.js dosyalarımızı içeride tutmak organizasyona yardımcı olur.

    Şimdi daha önce aldığımız abi dizimizi SimpleStorage.JSON dosyasından kopyalayıp yeni yapılan abi.js dosyamıza ekleyeceğiz. Projemizin bilgileri App.js dosyamıza aktarmasına izin vermek için dosyayı biraz değiştireceğiz. Unutmayın, bu bir.js dosyası olduğundan, daha sonra bunu app.js dosyamıza çekebilmemiz için bir dışa aktarma eklememiz gerekir. Konuyu, deve harfleri dışında sözleşmeyle aynı şekilde adlandıralım (aşağıdaki koda bakın):

    Bu, abi.js dosyamızda sakladığımız kod olacaktır

    export const simpleStorage = [{sabit: yanlış, girişler: [{isim: "x", türü: "uint256", },], ad: "Ayarlamak", çıktılar: [], ödenebilir: false, stateMutability: "ödenemez", türü: "işlevi", }, {sabit: doğru, girişler: [], ad: "almak", çıktılar: [{isim: "", türü: "uint256", },], ödenebilir: false, stateMutability: "görünüm", türü: "işlevi", },];

    App.js’mize gitme ve hem web3’ü hem de yeni yapılmış abi.js dosyamızı içe aktarma zamanı.

    Bu örnekte kancaları da kullanacağız (bu yüzden {useState} ‘i de içe aktarıyoruz, useState hakkında daha fazla bilgi edinebilirsiniz. İşte.

    App.js dosyamızın üst kısmı artık şu şekilde görünmelidir:

    React’i içe aktar, {useState} "tepki"; {simpleStorage} dosyasını şuradan içe aktar: "./ abi / abi"; Web3’ü içeri aktar "web3"; ithalat "./App.css";

    Şimdi, herhangi bir rastgele kullanıcının, bir cüzdan sağlayıcısına sahip oldukları sürece, dApp’ımıza bağlanma ve kullanma yeteneğine sahip olduğundan emin olmamız gerekiyor.!

    Ethereum alanında dApp etkileşimi için kullanılan ana cüzdan, Adım 1’de tanıtılan MetaMask’tır..

    MetaMask’ınız yoksa şu adresi ziyaret edin: metamask.io

    MetaMask kurulduğunda, dapp’ımızın içindeki cüzdanımıza şu şekilde erişebiliriz:

    const web3 = yeni Web3 (Web3.givenProvider);

    “Web3.givenProvider” Ethereum destekli bir tarayıcıda ayarlanacaktır.

    (bunun neden gerekli olduğu hakkında daha fazla bilgi edinebilirsiniz İşte)

    Şimdi kodumuz şöyle görünmeli:

    React’i içe aktar, {useState} "tepki"; {simpleStorage} dosyasını şuradan içe aktar: "./ abi / abi"; Web3’ü içeri aktar "web3"; ithalat "./App.css"; const web3 = yeni Web3 (Web3.givenProvider);

    Tamam mı! Şimdiye kadar:

    • Bir React projesi oluşturdu
    • Yüklü Web3
    • Derleme + sözleşme + geçişimizi içeren klasörümüzü React projemize ekledik
    • SimpleStorage.json’dan aldığımız abi verilerini tutan bir abi.js dosyası oluşturuldu
    • Sözleşmemizle etkileşime girmemiz gereken verileri içe aktardık
    • DApp’ımızın kullanıcının cüzdanıyla iletişim kurmasını sağlayan bir değişken oluşturuldu

    Yine, Truffle sonraki birkaç adımı gereksiz kılsa da (size daha sonra çok daha basit bir sürümden geçeceğiz), eğitim amaçlı dApp’ımıza biraz daha manuel karmaşıklık ekleyeceğiz.

    Şimdi yapacağımız şey, iki yeni değişken oluşturmaktır: biri Ropsten’da dağıttığımız sözleşmenin adresini saklamak, diğeri bu sözleşmeyi ABI’mızla eşleştirmek, böylece uygulamamız onunla nasıl konuşulacağını bilir.! 

    Sözleşme adresini bulmak için, daha önce içinde bulunduğumuz JSON dosyasına (ABI (SimpleStorage.json) içerir) gidin ve en alta kaydırın. Adres, buradaki “adres” alanındadır:

    "derleyici": { "isim": "solc", "versiyon": "0.5.8 + commit.23d335f2.Emscripten.clang" }, "ağlar": { "3": { "Etkinlikler": {}, "bağlantılar": {}, "adres": "0x24164F46A62a73de326E55fe46D1239d136851d8", "transactionHash": "0x1f02006b451b9e85f70acdff15a01c6520e4beddfd93a20e88a9b702a607a7b0" }}, "schemaVersion": "3.0.16", "updatedAt": "2020-06-30T20: 45: 38.686Z", "devdoc": { "yöntemler": {}}, "userdoc": { "yöntemler": {}}}

    Alternatif olarak, şuraya da gidebilirsiniz: https://ropsten.etherscan.io/ ve sözleşmeyi uygulayan hesabın adresini arayın! Etherscan’da, “Sözleşme Oluşturma” üzerine tıklamak Sözleşme Adresinin kendisini gösterecektir..

    Ekran Görüntüsü 2020 09 01 5 43 46 AM

    Şimdi sözleşmenizin adresinin kopyasını alıp saklamak için yeni bir değişken oluşturacağız. 

    Bu olmadan, sözleşmeyle iletişim kurma olanağımız olmayacak ve dApp’ımız istendiği gibi çalışmayacaktır..

    Bunu const web3 = new Web3 (Web3.givenProvider) altına ekleyeceksiniz;

    const contractAddress = "burada sözleşme adresiniz";

    Ardından, hem sözleşme adresimizi (böylece uygulamamız sözleşmenin nerede olduğunu bilir) hem de ABI’yi (böylece uygulamamız sözleşmeyle nasıl etkileşim kuracağını bilir) içerecek olan “storageContract” adında başka bir yeni değişken oluşturacağız..

    const storageContract = new web3.eth.Contract (simpleStorage, contractAddress);

    App.js’miz şimdi şöyle görünmelidir

    React’i içe aktar, {useState} "tepki"; {simpleStorage} dosyasını şuradan içe aktar: "./ abi / abi"; Web3’ü içeri aktar "web3"; ithalat "./App.css"; const web3 = yeni Web3 (Web3.givenProvider); const contractAddress = "burada sözleşme adresiniz"; const storageContract = new web3.eth.Contract (simpleStorage, contractAddress);

    Şimdi, sözleşmemiz ve ön uç ile etkileşime girecek değişkenleri tutmak için kancalarımızı almamız gerekiyor. Bunu, uygulama işlevimizde aşağıdakileri bildirerek yapacağız:

    React’i içe aktar, {useState} "tepki"; {simpleStorage} dosyasını şuradan içe aktar: "./ abi / abi"; Web3’ü içeri aktar "web3"; ithalat "./App.css"; const web3 = yeni Web3 (Web3.givenProvider); const contractAddress = "sözleşme adresiniz"; const storageContract = new web3.eth.Contract (simpleStorage, contractAddress); function App () {const [sayı, setUint] = useState (0); const [getNumber, setGet] = useState ("0");

    İlk useState (0) kullanımımız, kullanıcının beyan ettiği uint256’yı tutacaktır..

    (number, setUint, getNumber, setGet adlandırma kuralları umarım neler olduğunu göstermeye yardımcı olur)

    useState (“0”) değeri, imzalanan eylemimiz (beyan ettiğimiz uint256) hakkında onay alana kadar bir yer tutucu görevi görür.

    setUint yakında geri dönüşümüzde arayacağız (bununla ilgili daha sonra daha fazlası)

    Mantığımızın zamanı

    Daha sonra numberSet ve NumberGet mantığımızı ekleyeceğiz (işlev Uygulamamıza numberSet ekliyoruz)

    const numberSet = eşzamansız (t) => {t.preventDefault (); const hesapları = bekle window.ethereum.enable (); const hesabı = hesaplar [0]; const gas = await storageContract.methods.set (sayı) .estimateGas (); const post = await storageContract.methods.set (sayı) .send ({from: account, gas,}); }; const numberGet = eşzamansız (t) => {t.preventDefault (); const post = await storageContract.methods.get (). call (); setGet (post); };

    Bir preventDefault ayarladık (preventDefault hakkında ayrıntılar bulundu İşte)

    Ayrıca sözleşme için get üzerinde eşzamansız çağrı kullanıyoruz (eşzamansız ile ilgili ayrıntılar bulundu İşte)

    Kanca setGet (), başlangıçta görüntülediğimiz varsayılan değeri saklar (“0”)

    const hesapları = bekle window.ethereum.enable ();

    bağlı adresimizi MetaMask aracılığıyla aradığımızdan emin olur.

    const hesabı = hesaplar [0];

    Connect hesabını çeker

    Neler olduğunu merak ediyor olabilirsiniz 

    const gas = await storageContract.methods.set (sayı) .estimateGas ();

    Uygulamamızın, testnet veya ana ağda olmasına bakılmaksızın, gaz ücretlerini ve eter isteyen herhangi bir işlevi ödemek için kullanıcı fonlarına erişmek için izne ihtiyacı var. MetaMask ile bağlantımızın, uint256’mızı ayarlamak ve bunun için ödeme yapmak için bu kullanımı imzalamak için kullanışlı olduğu yer burasıdır (test ETH ile).

    Dolayısıyla, gaza ihtiyaç duyan herhangi bir işlev için, kullanılan potansiyel gazı hesaplamanız gerekir..

    Sözleşmemizin “Ayarla” işlevi benzin gerektiriyor

    “Al” değil.

    (bunun nedeni, “Get” in “Set” ile zaten bildirilmiş olanı görüntülemesidir)

    const post uint256’da geçirileni alacak, işlemi onaylayacak (gaz ücreti ödeyerek) Ropsten ağındaki MetaMask cüzdanınızdan.

    Daha sonra işlev parametrelerini method.set () yoluyla iletiriz ve bildirilen adresimizle (kullanıcı adresi) Set işlevini kullanırız..

    Fonksiyon parametrelerimizi akıllı sözleşme yöntemlerine.set () ve tahmini gaz ve kullanıcı hesabı adresini to.send () ‘e aktararak akıllı sözleşme işlemimizi oluşturuyoruz..

    const post = await storageContract.methods.set (sayı) .send ({from: account, gas,});

    Bu, sayı kümemizi kapsamamız için gereken tüm mantık olmalıdır..

    Şimdi numaramıza ihtiyacımız var

    const numberGet = eşzamansız (t) => {t.preventDefault (); const post = await storageContract.methods.get (). call (); setGet (post); };

    Const gönderimiz set numaramızı alır ve setGet ilan ettiğimiz yeni değeri geçer

    Yani “0” değerimiz onClick bizim numaramıza atıfta bulunacaktırGet ve unint256’mızı oluştur!

     Şimdi app.js’niz şöyle görünmeli

    React’i içe aktar, {useState} "tepki"; {simpleStorage} dosyasını şuradan içe aktar: "./ abi / abi"; Web3’ü içeri aktar "web3"; ithalat "./App.css"; const web3 = yeni Web3 (Web3.givenProvider); const contractAddress = "sözleşme adresiniz"; const storageContract = new web3.eth.Contract (simpleStorage, contractAddress); function App () {const [sayı, setUint] = useState (0); const [getNumber, setGet] = useState ("0"); const numberSet = eşzamansız (t) => {t.preventDefault (); const hesapları = bekle window.ethereum.enable (); const hesabı = hesaplar [0]; const gas = await storageContract.methods.set (sayı) .estimateGas (); const post = await storageContract.methods.set (sayı) .send ({from: account, gas,}); }; const numberGet = eşzamansız (t) => {t.preventDefault (); const post = await storageContract.methods.get (). call (); setGet (post); };

    Oluşturmak için çok basit bir dönüş oluşturalım, böylece yapıp yapamayacağımızı test edelim 

    • unint256 değeri ayarla,
    • Metamask cüzdanımızı açın ve işlemi onaylayın
    • Gaz bedelini öde
    • sonra işlem tamamlandıktan sonra sakladığımız değeri (unint256) alın.

    Dönüşümüz şuna benziyor: 

    return (uint256’nızı ayarlayın: setUint (t.target.value)} /> Onaylamak

    Uint256 {getNumber}) bilginizi alın; } varsayılan Uygulamayı dışa aktar;

    Bazı hızlı CSS

    Şimdi App.css dosyasına gidelim, kazan plakası kodunu silip bunun yerine bunu ekleyelim

    .ana {text-align: center; ekran: esnek; haklı içerik: merkez; arka plan rengi: # f2f1f5; yükseklik: 100vh; } .card {min-yükseklik: 50vh; genişlik: 50vw; ekran: esnek; esnek yön: sütun; hizalama öğeleri: merkez; haklı içerik: merkez; } .form {yükseklik: 20vh; genişlik: 20vw; ekran: esnek; gerekçelendirme içeriği: boşluk eşit olarak; esnek yön: sütun; }. düğmesi {genişlik: 20vw; yükseklik: 5vh; }

    Şimdi test etmeye hazırız!

    Terminal çalışmanızda

    iplik başlangıcı

    Localhost’umuzda: 3000 şöyle görünmeliyiz

     

    Ekran Görüntüsü 2020 09 01, 6 12 49 AM

    Artık girdi alanımıza bir unint256 değeri girebilmeliyiz!

    Numaramızı dApp’ımızda onayladıktan sonra MetaMask aracılığıyla imzalarız (Cüzdanınızın Ropsten ağına ayarlandığından emin olun)

    confrim1

    Yaptık! &# 129303;

    Artık bir ön uca bağlı akıllı sözleşmemiz var ve Set işlevini değiştirme yeteneğine sahibiz (işlem için gaz ücretini ödemek için test ETH’ye sahip olmamız şartıyla). Sonra Get işlevini çağırabilir ve depolanan uint265 değerini alabiliriz.

    Oldukça havalı ha!?!

    Ekstra Şekillendirme 

    Şimdi daha popüler Web2 teknolojisini projemize uygulamanın ne kadar kolay olabileceğini gösterme zamanı..

    Temel stil eklemek için MUI kullanacağız, eğer React ile geliştirirseniz, material-ui’ye aşina olabilirsiniz. (Ayrıntılar bulundu İşte) Material-UI veya kısaca MUI, adlandırma kurallarına uymanız koşuluyla, bir projeyi çok sayıda şekillendirme ile hızlı bir şekilde döndürmenize olanak tanıyan çok popüler bir React çerçevesidir. Yalnızca bir fondöten kullanmak ve oradan özelleştirmek istiyorsanız, manipüle etmek de çok kolaydır.

    * Bu, projemizi Web2 teknolojisiyle olduğu haliyle ne kadar hızlı bir şekilde dahil edebileceğinizi göstermek için küçük eklemelerle bir projeye MUI’nin nasıl ekleneceğinin çok kısa bir örneği olacaktır.. 

    MUI ekleniyor

    Komutu çalıştırarak başlayacağız (hala terminaldeki proje dizinimizdeyken (uygulamanız hala çalışıyorsa, onu kapatmanız (ctrl + c) veya yeni bir sekme açmanız gerekir):

    Npm ile yüklemek için:

    npm install @ material-ui / core

    Veya iplikle:

    iplik ekle @ material-ui / core

    Artık MUI enjekte ettiğimize göre stilimizi değiştirmeye başlayacağız. App.js dosyamızın en üstünde birkaç yeni şeyi içe aktaracağız:

    {simpleStorage} dosyasını şuradan içe aktar: "./ abi / abi"; Düğmeyi içe aktar "@ material-ui / core / Düğme"; TextField’ı içe aktar "@ material-ui / core / TextField"; {makeStyles} öğesini şuradan içe aktar: "@ material-ui / core / styles";

    {MakeStyles} içeriğinin içe aktarılması, varsayılan MUI stilini içe aktarmanın yanı sıra düğmelerimizin ve metin alanımızın stilini (bu durumda) değiştirmemize olanak tanır.. 

    Şimdi MUI’den standart şablon stilini getiren bir değişken (fonksiyonumuzun üstünde) yapacağız.

    const useStyles = makeStyles ((tema) => ({ kök: { "& > *": {margin: theme.spacing (1),},},}));

    Şimdi, Uygulama fonksiyonumuza, yukarıda açıkladığımız tanımlanmış stilleri çeken “sınıflar” adlı bir değişken de ekleyeceğiz..

    function App () {const sınıfları = useStyles (); const [sayı, setUint] = useState (0); const [getNumber, setGet] = useState ("0");

    Bazı alanlarımızı yeni aktardıklarımızla değiştirmek için şimdi iademizde ayarlamalar yapacağız.

    return (setUint (t.target.value)} varyant ="ana hatlarıyla" /> Onaylamak

    Uint256 {getNumber}) bilginizi alın; } varsayılan Uygulamayı dışa aktar;

    Kodunuz şimdi böyle görünmeli

    React’i içe aktar, {useState} "tepki"; {simpleStorage} dosyasını şuradan içe aktar: "./ abi / abi"; Web3’ü içeri aktar "web3"; ithalat "./App.css"; {makeStyles} öğesini şuradan içe aktar: "@ material-ui / core / styles"; Düğmeyi içe aktar "@ material-ui / core / Düğme"; TextField’ı içe aktar "@ material-ui / core / TextField"; const useStyles = makeStyles ((tema) => ({ kök: { "& > *": {margin: theme.spacing (1),},},})); const web3 = yeni Web3 (Web3.givenProvider); const contractAddress = "burada sözleşme adresiniz"; const storageContract = new web3.eth.Contract (simpleStorage, contractAddress); function App () {const sınıfları = useStyles (); const [sayı, setUint] = useState (0); const [getNumber, setGet] = useState ("0"); const numberSet = eşzamansız (t) => {t.preventDefault (); const hesapları = bekle window.ethereum.enable (); const hesabı = hesaplar [0]; const gas = await storageContract.methods.set (sayı) .estimateGas (); const post = await storageContract.methods.set (sayı) .send ({from: account, gas,}); }; const numberGet = eşzamansız (t) => {t.preventDefault (); const post = await storageContract.methods.get (). call (); setGet (post); }; return (setUint (t.target.value)} varyant ="ana hatlarıyla" /> Onaylamak

    Uint256 {getNumber}) bilginizi alın; } varsayılan Uygulamayı dışa aktar;

    Şimdi react projemize bakarsak şöyle görünmeli!

    Ekran Görüntüsü 2020 09 01, 6 48 55 AM

    Aferin!

    Hala önceden sahip olduğumuz tüm işlevlere sahibiz ve şimdi projemizi istediğimiz gibi daha da özelleştirmek için kullanımı kolay bir çerçeve ekledik. MUI’ye bir göz atın dokümantasyon kendi eklemelerinizi / değişikliklerinizi denemek için!

    Bonus Turu 

    Kullanıcılara bağlantı adresini dApp’ımızda göstermek güzel olurdu, değil mi??

    Pekala, tam olarak bunu yapmak için çok hızlı ve basit bir bileşen yapalım!

    App.js dosyamıza geri aktarabileceğimiz ayrı bir bileşen oluşturarak başlayacağız. Mantığımızı ayırmak, yalnızca App.js’mizin gezinmesini kolaylaştırmakla kalmayıp, aynı zamanda ideal olarak yalnızca bir şeyi yapan bir bileşenin uygulamasını da takip etmek iyi bir fikirdir. Büyümeye başlarsa, daha küçük alt bileşenlere ayrıştırılmalıdır..

    Bileşen oluşturma 

    Src ile aynı seviyede bileşenler adında yeni bir klasör oluşturacağız ve bu klasörün içinde bir Nav.js dosyası oluşturacağız. Proje iskelemiz şimdi böyle bir şeye benzemeli

    Ekran Görüntüsü 2020 09 01, 6 47 07

    Ayrıca özellikle Nav bileşenine uyguladığımız stilleri içe aktarmak için bileşenler klasörümüzde bir Nav.css dosyası oluşturacağız..

    Nav.js’mizi açalım ve React, Web3 ve boş.css dosyamızı içeri aktaralım

    React’i içe aktar "tepki"; Web3’ü içeri aktar "web3"; ithalat "./Nav.css"

    Şimdi Nav adında bir sınıf oluşturacağız ve bağlı adresimizi görüntülemek için içine sadece birkaç şey ekleyeceğiz. Durumumuzu hesabı okumaya ayarlayarak başlayacağız

    sınıf Nav, React.Component {state = {hesap: "" };

    Yine de sınıfımızın içinde, async loadAccount mantığımızı ekleyerek okumak için hesabı yükleyeceğiz.

    async loadAccount () {const web3 = new Web3 (Web3.givenProvider || "http: // localhost: 8080"); const network = web3.eth.net.getNetworkType (); const hesapları = web3.eth.getAccounts (); this.setState ({hesap: hesaplar [0]}); }

    Daha sonra bir componentDidMount oluşturacağız (bileşen bağlandıktan hemen sonra çağrılacaktır) bizim durumumuzda yüklenen hesabı çekerek. Daha fazla oku İşte

    componentDidMount () {this.loadAccount (); }

    Kenar notu:

    Bu farklı bir şekilde yapılabilir, bir sınıf yerine bir işlev oluşturabilir ve componentDidMount’un aksine kancalar kullanabiliriz, ancak bu örnek uğruna bu yönteme bağlı kalacağız.

    Daha sonra dönüşümüzün üzerinde bir render oluşturacağız, render, bir sınıf metodu kullanarak bir React bileşeni yazarken gerekli olan bir metottur. İademizde, {this.state.account} kullanarak getirdiğimiz bağlı adresi göstermek için bir p etiketiyle birlikte div’imize (daha sonra temel stil vermek üzere) bir adres sınıfı ekliyoruz.

    render () {return (Bağlı adresiniz: {this.state.account}); }} varsayılan Gezinmeyi dışa aktar;

    Nav.js dosyamız şimdi şöyle görünmelidir

    React’i içe aktar "tepki"; Web3’ü içeri aktar "web3"; ithalat "./Nav.css" sınıf Nav, React.Component {state = {hesap: "" }; async loadAccount () {const web3 = new Web3 (Web3.givenProvider || "http: // localhost: 8080"); const network = web3.eth.net.getNetworkType (); const hesapları = web3.eth.getAccounts (); this.setState ({hesap: hesaplar [0]}); } componentDidMount () {this.loadAccount (); } render () {return (Bağlı adresiniz: {this.state.account}); }} varsayılan Gezinmeyi dışa aktar;

     

    Nav.css dosyasına gidelim ve çok basit bir stil ekleyelim

    .adres {display: flex; haklı içerik: merkez; }

    Bunu teknik olarak App.css dosyasına ekleyebilirsiniz, ancak oldukça hızlı bir şekilde dağınık hale gelebileceğini unutmayın. Bileşenler yeniden kullanılabilir olmalı ve işinizi bölümlere ayırarak mümkün olduğunca fazla sürtünmeyi önlemek için yolun aşağısında baş ağrısından kurtulabilirsiniz..

    Şimdi App.js dosyamıza geri dönelim ve yeni yapılmış bileşenimizi içe aktaralım ve onu görüntülemek için geri dönüşümüze eklediğimizden emin olalım.!

    Bitmiş App.js dosyamız şöyle görünmelidir

    React’i içe aktar, {useState} "tepki"; {simpleStorage} dosyasını şuradan içe aktar: "./ abi / abi"; Web3’ü içeri aktar "web3"; Nav içe aktar "./components/Nav.js"; ithalat "./App.css"; {makeStyles} öğesini şuradan içe aktar: "@ material-ui / core / styles"; Düğmeyi içe aktar "@ material-ui / core / Düğme"; TextField’ı içe aktar "@ material-ui / core / TextField"; const useStyles = makeStyles ((tema) => ({ kök: { "& > *": {margin: theme.spacing (1),},},})); const web3 = yeni Web3 (Web3.givenProvider); const contractAddress = "adresin burada"; const storageContract = new web3.eth.Contract (simpleStorage, contractAddress); function App () {const sınıfları = useStyles (); const [sayı, setUint] = useState (0); const [getNumber, setGet] = useState ("0"); const numberSet = eşzamansız (t) => {t.preventDefault (); const hesapları = bekle window.ethereum.enable (); const hesabı = hesaplar [0]; const gas = await storageContract.methods.set (sayı) .estimateGas (); const post = await storageContract.methods.set (sayı) .send ({from: account, gas,}); }; const numberGet = eşzamansız (t) => {t.preventDefault (); const post = await storageContract.methods.get (). call (); setGet (post); }; dönüş ( setUint (t.target.value)} varyant ="ana hatlarıyla" /> Onaylamak

    Uint256 {getNumber}) bilginizi alın; } varsayılan Uygulamayı dışa aktar;

    Şimdi bağlı adresimizi en üstte görmeli ve tüm işlevlerimizi korumalıyız.!

    bonusV1

    &# 127881; Yaptık! &# 127881;

    Artık sıfırdan oluşturduğumuz bir dApp’imiz var. Akıllı sözleşmemizi bir React projesine aktardık, kullanıcı işlevselliğine sahip olduğumuzdan emin olmak için mantık yazdık, bağlı adresi işlemek için bir bileşen oluşturduk ve hatta projemize popüler bir stil çerçevesi ekledik..

    Aferin! Bu, Web3 geliştirme maceralarınız için sadece bir başlangıç ​​ve zaten sadece yaratmadığınızı göstermekle kalmayıp aynı zamanda başınızı salladığınızı da gösterecek bir şeye sahipsiniz. Discord’da bize ulaşın ve projenizi (özellikle herhangi bir değişiklik veya ekleme yaptıysanız) bizimle paylaşın!

      Geliştiricinin İlk Katılımı: 1. AdımGeliştirici İlk Katılımı Adım 1

      Geliştiricinin İlk Katılımı: 1. Adım

      Geliştiricinin İlk Katılımı: 2. AdımGeliştirici İlk Katılımı 2. Adım

      Geliştiricinin İlk Katılımı: 2. Adım

      10 Dakikalık Ethereum Oryantasyonu10 Dakikalık Ethereum Oryantasyonu

      10 Dakikalık Ethereum Oryantasyonu
    Mike Owergreen Administrator
    Sorry! The Author has not filled his profile.
    follow me
    Like this post? Please share to your friends:
    Adblock
    detector
    map