diff --git a/public/content/translations/tr/developers/docs/standards/tokens/index.md b/public/content/translations/tr/developers/docs/standards/tokens/index.md index 2a937811b34..96a00d1cab1 100644 --- a/public/content/translations/tr/developers/docs/standards/tokens/index.md +++ b/public/content/translations/tr/developers/docs/standards/tokens/index.md @@ -1,39 +1,41 @@ --- -title: Token Standartları -description: +title: "Token Standartları" +description: "Misli ve eşsiz jetonlar için ERC-20, ERC-721 ve ERC-1155 dahil olmak üzere Ethereum jeton standartlarını keşfedin." lang: tr incomplete: true --- ## Giriş {#introduction} -Birçok Ethereum geliştirme standardı, jeton arayüzlerine odaklanır. Bu standartlar akıllı sözleşmelerin birleştirilebilir kalmasını sağlamaya yardımcı olur: Örneğin yeni bir proje bir token çıkardığı zaman token'ın mevcut merkeziyetsiz borsalarla uyumlu kalması gibi. +Birçok Ethereum geliştirme standardı, jeton arayüzlerine odaklanır. Bu standartlar, akıllı sözleşmelerin birleştirilebilir kalmasını sağlamaya yardımcı olur; böylece yeni bir proje bir jeton çıkardığında, jeton mevcut merkeziyetsiz borsalar ve uygulamalarla uyumlu kalır. + +Jeton standartları, jetonların Ethereum ekosistemi genelinde nasıl davrandığını ve etkileşime girdiğini tanımlar. Bu standartlar, geliştiricilerin tekerleği yeniden icat etmeden geliştirme yapmalarını kolaylaştırır ve jetonların cüzdanlar, borsalar ve DeFi platformları ile sorunsuz bir şekilde çalışmasını sağlar. İster oyun, ister yönetişim veya diğer kullanım durumlarında olsun, bu standartlar tutarlılık sağlar ve Ethereum'u daha birbiriyle bağlantılı hâle getirir. ## Ön Koşullar {#prerequisites} - [Ethereum geliştirme standartları](/developers/docs/standards/) - [Akıllı sözleşmeler](/developers/docs/smart-contracts/) -## Token standartları {#token-standards} +## Jeton standartları {#token-standards} Bunlar Ethereum'daki en popüler token standartlarından bazılarıdır: -- [ERC-20](/developers/docs/standards/tokens/erc-20/) - Oylama token'ları, stake etme token'ları veya sanal para birimleri gibi değiştirilebilir (birbirinin yerine geçebilir) token'lar için standart bir arayüz. +- [ERC-20](/developers/docs/standards/tokens/erc-20/) - Oylama jetonları, hisseleme jetonları veya sanal para birimleri gibi değiştirilebilir (birbiri yerine kullanılabilir) jetonlar için standart bir arayüz. ### NFT standartları {#nft-standards} -- [ERC-721](/developers/docs/standards/tokens/erc-721/) - Bir şarkı veya sanat eserinin telif hakkı gibi değiştirilemez token'lar için standart bir arayüz. -- [ERC-1155](/developers/docs/standards/tokens/erc-1155/) - ERC-1155, daha verimli alım satımlara ve işlemlerin gruplandırılmasına olanak tanır: Böylece maliyetlerden tasarruf sağlar. Bu jeton standardı, hem yardımcı jetonların ($BNB veya $BAT gibi) hem de CryptoPunks gibi Eşsiz Jetonların oluşturulmasına olanak tanır. +- [ERC-721](/developers/docs/standards/tokens/erc-721/) - Bir sanat eseri veya şarkı için bir tapu gibi, değiştirilemez jetonlar için standart bir arayüz. +- [ERC-1155](/developers/docs/standards/tokens/erc-1155/) - ERC-1155, daha verimli alım satımlara ve işlemlerin gruplandırılmasına olanak tanıyarak maliyetlerden tasarruf sağlar. Bu jeton standardı, hem yardımcı jetonların ($BNB veya $BAT gibi) hem de CryptoPunks gibi Eşsiz Jetonların oluşturulmasına olanak tanır. -[ERC](https://eips.ethereum.org/erc) önerilerinin tam listesi. +[ERC](https://eips.ethereum.org/erc) tekliflerinin tam listesi. -## daha fazla okuma {#further-reading} +## Daha fazla kaynak {#further-reading} -_Size yardımcı olan bir topluluk kaynağı biliyor musunuz? Bu sayfayı düzenleyin ve ekleyin!_ +_Size yardımcı olan bir topluluk kaynağı mı biliyorsunuz? Bu sayfayı düzenleyin ve onu ekleyin!_ ## İlgili öğreticiler {#related-tutorials} -- [Token entegrasyonu kontrol listesi](/developers/tutorials/token-integration-checklist/) _– Token'larla etkileşim kurarken göz önünde bulundurulması gerekenleri içeren bir kontrol listesi._ -- [ERC20 token akıllı sözleşmesini anlayın](/developers/tutorials/understand-the-erc-20-token-smart-contract/) _– İlk akıllı sözleşmenizi bir Ethereum test ağında dağıtmaya giriş._ -- [ERC20 token'larının bir Solidity akıllı sözleşmesinden transferleri ve onaylanması](/developers/tutorials/transfers-and-approval-of-erc-20-tokens-from-a-solidity-smart-contract/) _– Solidity dilini kullanarak bir token'la etkileşim kurmak için bir akıllı sözleşme nasıl kullanılır?_ -- [Bir ERC721 pazarının uygulanması [nasıl yapılır kılavuzu]](/developers/tutorials/how-to-implement-an-erc721-market/) _– Merkeziyetsiz bir ilan panosunda token'laştırılmış ürünler nasıl satışa sunulur?_ +- [Jeton entegrasyon kontrol listesi](/developers/tutorials/token-integration-checklist/) _– Jetonlarla etkileşim kurarken göz önünde bulundurulması gerekenleri içeren bir kontrol listesi._ +- [ERC20 jeton akıllı sözleşmesini anlama](/developers/tutorials/understand-the-erc-20-token-smart-contract/) _– İlk akıllı sözleşmenizi bir Ethereum test ağında dağıtmaya giriş._ +- [ERC20 jetonlarının bir Solidity akıllı sözleşmesinden transferleri ve onaylanması](/developers/tutorials/transfers-and-approval-of-erc-20-tokens-from-a-solidity-smart-contract/) _– Solidity dilini kullanarak bir jetonla etkileşim kurmak için bir akıllı sözleşme nasıl kullanılır._ +- [Bir ERC721 pazarının uygulanması [nasıl yapılır kılavuzu]](/developers/tutorials/how-to-implement-an-erc721-market/) _– Merkeziyetsiz bir ilan panosunda jetonlaştırılmış ürünler nasıl satışa sunulur._ diff --git a/public/content/translations/tr/developers/docs/storage/index.md b/public/content/translations/tr/developers/docs/storage/index.md index 7765950f7b2..81515a62c32 100644 --- a/public/content/translations/tr/developers/docs/storage/index.md +++ b/public/content/translations/tr/developers/docs/storage/index.md @@ -1,12 +1,12 @@ --- title: Merkeziyetsiz Depolama -description: Merkeziyetsiz depolamanın ne olduğuna ve onu bir dapp'ye entegre etmeye yarayan mevcut araçlara genel bakış. +description: "Merkeziyetsiz depolamanın ne olduğuna ve onu bir dapp'ye entegre etmeye yarayan mevcut araçlara genel bakış." lang: tr --- Tek bir şirket veya kuruluş tarafından işletilen merkezi bir sunucunun aksine, merkeziyetsiz depolama sistemleri, genel verilerin bir bölümünü tutan ve esnek bir dosya depolama paylaşım sistemi oluşturan eşler arası bir kullanıcı operatörleri ağından oluşur. Bunlar, blok zinciri tabanlı bir uygulamada veya herhangi bir eşler arası tabanlı ağda olabilir. -Tüm akıllı sözleşmelerde kod depolaması söz konusu olduğunda, Ethereum'un kendisi merkeziyetsiz bir depolama sistemi olarak kullanılabilir. Ancak, büyük miktarda veri söz konusu olduğunda, Ethereum'un tasarımı buna uygun değildir. Zincir istikrarlı bir şekilde büyüse de bu yazının yazıldığı sırada Ethereum zinciri 500 GB - 1 TB ([istemciye bağlı olarak](https://etherscan.io/chartsync/chaindefault)) civarında bir boyuta sahiptir ve ağdaki her düğümün tüm verileri depolayabilmesi gerekir. Zincir büyük miktarda veriye (diyelim ki 5 TB) genişleyecek olsaydı, tüm düğümlerin çalışmaya devam etmesi mümkün olmazdı. Ayrıca, bu kadar çok veriyi Mainnet'e dağıtmanın maliyeti, [gaz](/developers/docs/gas) ücretleri nedeniyle aşırı derecede pahalı olurdu. +Tüm akıllı sözleşmelerde kod depolaması söz konusu olduğunda, Ethereum'un kendisi merkeziyetsiz bir depolama sistemi olarak kullanılabilir. Ancak, büyük miktarda veri söz konusu olduğunda, Ethereum'un tasarımı buna uygun değildir. Zincir istikrarlı bir şekilde büyüyor, ancak bu yazının yazıldığı sırada Ethereum zinciri yaklaşık 500 GB - 1 TB ([istemciye bağlı olarak](https://etherscan.io/chartsync/chaindefault)) ve ağdaki her düğümün tüm verileri depolayabilmesi gerekiyor. Zincir büyük miktarda veriye (diyelim ki 5 TB) genişleyecek olsaydı, tüm düğümlerin çalışmaya devam etmesi mümkün olmazdı. Ayrıca, bu kadar çok veriyi Ana Ağ'a dağıtmanın maliyeti, [gaz](/developers/docs/gas) ücretleri nedeniyle aşırı derecede pahalı olacaktır. Bu kısıtlamalar nedeniyle, büyük miktarda veriyi merkeziyetsiz bir şekilde depolamak için farklı bir zincire veya metodolojiye ihtiyacımız var. @@ -25,7 +25,7 @@ Bir veri parçasının sonsuza kadar kalıcı olması için bir kalıcılık mek Bu, **blok zinciri tabanlı** kalıcılık olarak bilinir. -Blok zinciri tabanlı kalıcılık ile ilgili sıkıntı, zincirin muhafaza edilemeyecek ve tüm verinin makul bir şekilde depolanamayacak kadar büyüyebilecek olmasıdır (örneğin [birçok kaynak](https://healthit.com.au/how-big-is-the-internet-and-how-do-we-measure-it/), internetin 40 Zetabayttan fazla depolama kapasitesine gerek duyacağını tahmin ediyor). +Blok zinciri tabanlı kalıcılıkla ilgili sorun, zincirin, tüm verilerin bakımının yapılamayacağı ve makul bir şekilde depolanamayacağı kadar büyüyebilmesidir (örneğin, [birçok kaynak](https://healthit.com.au/how-big-is-the-internet-and-how-do-we-measure-it/), İnternet'in 40 Zettabayttan fazla depolama kapasitesi gerektireceğini tahmin etmektedir). Blok zinciri ayrıca bir tür teşvik yapısına sahip olmalıdır. Block zincir tabanlı süreklilik için, doğrulayıcıya ödeme yapılır. Veri zincire eklendiğinde, doğrulayıcılar zincire eklenmesi için ödeme yapar. @@ -36,40 +36,40 @@ Blok zinciri tabanlı kalıcılığa sahip platformlar: ### Sözleşme tabanlı {#contract-based} -**Sözleşme tabanlı** kalıcılık, verinin her düğüm tarafından kopyalanıp sonsuza kadar depolanamayacağını öngörür, buna göre bunun yerine sözleşme anlaşmaları ile idame edilmelidir. Bunlar, belirli bir süre için bir veri parçasını tutma sözü veren birden fazla düğümle yapılan sözleşmelerdir. Verilerin kalıcı olmasını sağlamak için bittiklerinde iade edilmeleri veya yenilenmeleri gerekir. +**Sözleşme tabanlı** kalıcılık, verilerin her düğüm tarafından kopyalanamayacağı ve sonsuza kadar saklanamayacağı, bunun yerine sözleşme anlaşmalarıyla sürdürülmesi gerektiği anlayışına dayanır. Bunlar, belirli bir süre için bir veri parçasını tutma sözü veren birden fazla düğümle yapılan sözleşmelerdir. Verilerin kalıcı olmasını sağlamak için bittiklerinde iade edilmeleri veya yenilenmeleri gerekir. -Çoğu durumda, tüm verileri zincir üzerinde depolamak yerine, verilerin bir zincirde bulunduğu yerin hash değeri depolanır. Bu şekilde, tüm verileri tutmak için tüm zincirin ölçeklenmesi gerekmez. +Çoğu durumda, tüm verileri zincir üstünde depolamak yerine, verilerin bir zincirde bulunduğu yerin hash değeri depolanır. Bu şekilde, tüm verileri tutmak için tüm zincirin ölçeklenmesi gerekmez. Sözleşme tabanlı kalıcılığa sahip platformlar: -- [Filecoin](https://docs.filecoin.io/about-filecoin/what-is-filecoin/) -- [Skynet](https://siasky.net/) +- [Filecoin](https://docs.filecoin.io/basics/what-is-filecoin) +- [Skynet](https://sia.tech/) - [Storj](https://storj.io/) - [Züs](https://zus.network/) - [Crust Network](https://crust.network) - [Swarm](https://www.ethswarm.org/) - [4EVERLAND](https://www.4everland.org/) -### Göz önüne almanız gereken ek kavramlar {#additional-consideration} +### Ek hususlar {#additional-consideration} IPFS; dosyaları, web sitelerini, uygulamaları ve verileri depolamaya ve bunlara erişmeye yarayan dağıtılmış bir sistemdir. Dahili bir teşvik düzenine sahip değildir ama bunun yerine yukarıdaki sözleşme esaslı teşvik çözümlerinin herhangi biriyle daha uzun süreli kalıcılık için kullanılabilir. IPFS üzerinde veriyi kalıcı kılmanın başka bir yolu ise verinizi sizin için "iliştirecek" bir iliştirme hizmeti ile çalışmaktır. Kendinizin ve/veya başkalarının verilerini kalıcı kılmak için kendi IPFS düğümünüzü bile çalıştırıp ağa katkı sağlayabilirsiniz! - [IPFS](https://docs.ipfs.io/concepts/what-is-ipfs/) -- [Pinata](https://www.pinata.cloud/) _(IPFS iliştirme hizmeti)_ -- [web3.storage](https://web3.storage/) _(IPFS/Filecoin iliştirme hizmeti)_ -- [Infura](https://infura.io/product/ipfs) _(IPFS iliştirme hizmeti)_ -- [IPFS Tarama](https://ipfs-scan.io) _(IPFS iliştime arayıcı)_ -- [4EVERLAND](https://www.4everland.org/) _ (IPFS iliştirme hizmeti)_ -- [Filebase](https://filebase.com) _(IPFS İliştirme Hizmeti)_ -- [Spheron Ağı](https://spheron.network/) _(IPFS/Filecoin pimleme servisi)_ +- [Pinata](https://www.pinata.cloud/) _(IPFS sabitleme hizmeti)_ +- [web3.storage](https://web3.storage/) _(IPFS/Filecoin sabitleme hizmeti)_ +- [Infura](https://infura.io/product/ipfs) _(IPFS sabitleme hizmeti)_ +- [IPFS Scan](https://ipfs-scan.io) _(IPFS sabitleme gezgini)_ +- [4EVERLAND](https://www.4everland.org/)_(IPFS sabitleme hizmeti)_ +- [Filebase](https://filebase.com) _(IPFS Sabitleme Hizmeti)_ +- [Spheron Network](https://spheron.network/) _(IPFS/Filecoin sabitleme hizmeti)_ SWARM, bir depolama teşvik sistemi ve bir depolama fiyatı kahinine sahip merkeziyetsiz bir veri depolama dağıtım teknolojisidir. -## Veri tutma {#data-retention} +## Veri saklama {#data-retention} Sistemlerin verileri tutmak için verilerin tutulduğundan emin olmalarını sağlayan bir tür mekanizmaya sahip olmaları gerekir. -### Zorluk mekanizması {#challenge-mechanism} +### Meydan okuma mekanizması {#challenge-mechanism} Verilerin tutulduğundan emin olmanın en popüler yollarından biri, hâlâ verilere sahip olduklarından emin olmak için düğümlere verilen bir tür kriptografik sorgulama kullanmaktır. Arweave'in erişim ispatına bakarak basit bir yöntemi görebilirsiniz. Hem en son blokta hem de geçmişte rastgele bir blokta verilere sahip olup olmadıklarını görmek için düğümlere bir meydan okuma gönderirler. Düğüm, cevabı bulamazsa cezalandırılır. @@ -88,7 +88,6 @@ Platformların merkeziyetsizlik düzeyini ölçmek için pek iyi araçlar olmasa KYC'siz merkeziyetsiz araçlar: -- Züs (KYC'siz bir sürüm kullanır) - Skynet - Arweave - Filecoin @@ -99,7 +98,7 @@ KYC'siz merkeziyetsiz araçlar: ### Mutabakat {#consensus} -Bu araçların çoğu kendi [mutabakat mekanizması](/developers/docs/consensus-mechanisms/) versiyonuna sahiptir ancak genellikle ya [**iş ispatı (PoW)**](/developers/docs/consensus-mechanisms/pow/) ya da [**hisse ispatı (PoS)**](/developers/docs/consensus-mechanisms/pos/) üzerine kuruludur. +Bu araçların çoğunun kendi [mutabakat mekanizması](/developers/docs/consensus-mechanisms/) sürümü vardır, ancak bunlar genellikle ya [**İş İspatı'na (PoW)**](/developers/docs/consensus-mechanisms/pow/) ya da [**Hisse İspatı'na (PoS)**](/developers/docs/consensus-mechanisms/pos/) dayanır. İş ispatı tabanlı: @@ -115,103 +114,103 @@ Hisse ispatı tabanlı: ## İlgili araçlar {#related-tools} -**IPFS - _InterPlanetary File System (Gezegenler Arası Dosya Sistemi), Ethereum için merkeziyetsiz bir depolama ve dosya referans sistemidir._** +**IPFS - _InterPlanetary File System (Gezegenlerarası Dosya Sistemi), Ethereum için merkeziyetsiz bir depolama ve dosya referanslama sistemidir._** - [Ipfs.io](https://ipfs.io/) -- [Belgeler](https://docs.ipfs.io/) +- [Dökümanlar](https://docs.ipfs.io/) - [GitHub](https://github.com/ipfs/ipfs) -**Storj DCS - _Geliştiriciler için güvenli, özel ve S3 uyumlu merkeziyetsiz bulut nesnesi deposu._** +**Storj DCS - _Geliştiriciler için güvenli, özel ve S3 uyumlu merkeziyetsiz bulut nesne depolaması._** - [Storj.io](https://storj.io/) -- [Belgeler](https://docs.storj.io/) +- [Dökümanlar](https://docs.storj.io/) - [GitHub](https://github.com/storj/storj) -**Skynet - _Skynet, merkeziyetsiz bir ağa özel, merkeziyetsiz bir iş ispatı zinciridir._** +**Sia - _Alıcıların ve satıcıların doğrudan işlem yapmasına olanak tanıyan, güven gerektirmeyen bir bulut depolama pazar yeri oluşturmak için kriptografiden yararlanır._** -- [Skynet.net](https://siasky.net/) -- [Belgeler](https://siasky.net/docs/) -- [GitHub](https://github.com/SkynetLabs/) +- [Skynet.net](https://sia.tech/) +- [Dökümanlar](https://docs.sia.tech/) +- [GitHub](https://github.com/SiaFoundation/) -**Filecoin - _Filecoin, IPFS'nin ardındaki aynı ekip tarafından oluşturuldu. IPFS ideallerine ek olarak bir teşvik katmanıdır._** +**Filecoin - _Filecoin, IPFS'nin ardındaki aynı ekip tarafından oluşturuldu._** IPFS ideallerine ek olarak bir teşvik katmanıdır._\*\* - [Filecoin.io](https://filecoin.io/) -- [Belgeler](https://docs.filecoin.io/) +- [Dökümanlar](https://docs.filecoin.io/) - [GitHub](https://github.com/filecoin-project/) **Arweave - _Arweave, veri depolamaya yarayan bir dStorage platformudur._** - [Arweave.org](https://www.arweave.org/) -- [Belgeler](https://docs.arweave.org/info/) +- [Dökümanlar](https://docs.arweave.org/info/) - [Arweave](https://github.com/ArweaveTeam/arweave/) -**Züs - _Züs, parçalama ve balonlayıcılara (blobber) sahip bir hisse ispatı dStorage platformudur._** +**Züs - _Züs, parçalama ve blobber'lara sahip, bir hisse ispatı dStorage platformudur._** - [zus.network](https://zus.network/) -- [Belgeler](https://0chaindocs.gitbook.io/zus-docs) +- [Dökümanlar](https://docs.zus.network/zus-docs/) - [GitHub](https://github.com/0chain/) -**Crust Network - _Crust IPFS üzerine kurulmuş bir merkeziyetsiz depolama platformudur_** +**Crust Network - _Crust, IPFS üzerine kurulu bir dStorage platformudur._** -- [Crust ağı](https://crust.network) -- [Belgeler](https://wiki.crust.network) +- [Crust.network](https://crust.network) +- [Dökümanlar](https://wiki.crust.network) - [GitHub](https://github.com/crustio) **Swarm - _Ethereum web3 yığını için dağıtılmış bir depolama platformu ve içerik dağıtım hizmeti._** - [EthSwarm.org](https://www.ethswarm.org/) -- [Belgeler](https://docs.ethswarm.org/docs/) +- [Dökümanlar](https://docs.ethswarm.org/) - [GitHub](https://github.com/ethersphere/) -**OrbitDB - _IPFS'ye ek olarak merkeziyetsiz bir eşler arası veri tabanı._** +**OrbitDB - _IPFS üzerinde çalışan, merkeziyetsiz bir eşler arası veritabanı._** - [OrbitDB.org](https://orbitdb.org/) -- [Belgeler](https://github.com/orbitdb/field-manual/) +- [Dökümanlar](https://github.com/orbitdb/field-manual/) - [GitHub](https://github.com/orbitdb/orbit-db/) -**Aleph.im - _Merkeziyetsiz bulut projesi (veri tabanı, dosya depolama, bilgi işlem ve DID). Zincir dışı ve zincir üstü eşler arası teknolojinin benzersiz bir karışımı. IPFS ve çoklu zincir uyumluluğu._** +**Aleph.im - _Merkeziyetsiz bulut projesi (veritabanı, dosya depolama, bilgi işlem ve DID)._** Zincir dışı ve zincir üstü eşler arası teknolojinin benzersiz bir karışımı. IPFS ve çoklu zincir uyumluluğu._\*\* -- [Aleph.im](https://aleph.im/) -- [Belgeler](https://aleph.im/#/developers/) +- [Aleph.im](https://aleph.cloud/) +- [Dökümanlar](https://docs.aleph.cloud/) - [GitHub](https://github.com/aleph-im/) -**Ceramic - _Veri açısından zengin ve etkileşimli uygulamalar için kullanıcı kontrollü IPFS veri tabanı depolaması._** +**Ceramic - _Veri açısından zengin ve etkileşimli uygulamalar için kullanıcı kontrollü IPFS veritabanı depolaması._** - [Ceramic.network](https://ceramic.network/) -- [Belgeler](https://developers.ceramic.network/learn/welcome/) +- [Dökümanlar](https://developers.ceramic.network/) - [GitHub](https://github.com/ceramicnetwork/js-ceramic/) -**Filebase - _ S3 uyumlu merkeziyetsiz depolama ve coğrafi olarak yedekli IPFS iliştirme hizmetidir. Filebase aracılığıyla IPFS'e yüklenen tüm dosyalar, dünya çapında 3x kopyalanarak otomatik olarak Filebase altyapısına eklenir._** +**Filebase - _S3 uyumlu merkeziyetsiz depolama ve coğrafi olarak yedekli IPFS sabitleme hizmeti. Filebase aracılığıyla IPFS'ye yüklenen tüm dosyalar, dünya çapında 3 kat çoğaltma ile otomatik olarak Filebase altyapısına sabitlenir._** - [Filebase.com](https://filebase.com/) - [Dökümanlar](https://docs.filebase.com/) - [GitHub](https://github.com/filebase) -**4EVERLAND - _Depolama, hesaplama ve ağ çekirdek kabiliyetlerini entegre eden, S3 uyumlu ve IPFS ve Arweave gibi merkeziyetsiz depolama ağlarında senkronize veri depolaması sağlayan bir Web 3.0 bulut bilişimi platformu._** +**4EVERLAND - _Depolama, hesaplama ve ağ oluşturma temel yeteneklerini entegre eden, S3 uyumlu olan ve IPFS ve Arweave gibi merkeziyetsiz depolama ağlarında senkronize veri depolaması sağlayan bir Web 3.0 bulut bilişim platformu._** - [4everland.org](https://www.4everland.org/) -- [Dokümanlar](https://docs.4everland.org/) +- [Dökümanlar](https://docs.4everland.org/) - [GitHub](https://github.com/4everland) -**Kaleido - _Tek tıkla IPFS düğümleri olan bir servis olarak blok zincir platformu_** +**Kaleido - _Tek tıkla çalışan IPFS Düğümlerine sahip bir Hizmet Olarak Blok Zinciri platformu_** - [Kaleido](https://kaleido.io/) -- [Dokümanlar](https://docs.kaleido.io/kaleido-services/ipfs/) +- [Dökümanlar](https://docs.kaleido.io/kaleido-services/ipfs/) - [GitHub](https://github.com/kaleido-io) -**Spheron Ağı- _Spheron, uygulamalarını merkeziyetsiz altyapı üzerinde en iyi performansla başlatmak isteyen merkeziyetsiz uygulamalar için tasarlanmış bir platform servisidir (PaaS). Anında hesaplama, merkeziyetsiz depolama, CDN ve web barındırma hizmeti sunar._** +**Spheron Network - _Spheron, uygulamalarını en iyi performansla merkeziyetsiz altyapıda başlatmak isteyen merkeziyetsiz uygulamalar için tasarlanmış bir hizmet olarak platformdur (PaaS). Anında hesaplama, merkeziyetsiz depolama, CDN ve web barındırma hizmeti sunar._** - [spheron.network](https://spheron.network/) -- [Dokümanlar](https://docs.spheron.network/) +- [Dökümanlar](https://docs.spheron.network/) - [GitHub](https://github.com/spheronFdn) -## Daha fazla bilgi {#further-reading} +## Daha fazla kaynak {#further-reading} -- [Merkeziyetsiz Depolama Nedir?](https://coinmarketcap.com/alexandria/article/what-is-decentralized-storage-a-deep-dive-by-filecoin) - _CoinMarketCap_ -- [Merkeziyetsiz Depolamayla İlgili Beş Yaygın Mitin Çürütülmesi](https://www.storj.io/blog/busting-five-common-myths-about-decentralized-storage) - _Storj_ +- [Merkeziyetsiz Depolama Nedir?](https://coinmarketcap.com/academy/article/what-is-decentralized-storage-a-deep-dive-by-filecoin) - _CoinMarketCap_ +- [Merkeziyetsiz Depolama Hakkında Beş Yaygın Efsaneyi Çürütmek](https://www.storj.io/blog/busting-five-common-myths-about-decentralized-storage) - _Storj_ -_Size yardımcı olan bir topluluk kaynağı biliyor musunuz? Bu sayfayı düzenleyin ve ekleyin!_ +_Size yardımcı olan bir topluluk kaynağı biliyor musunuz? Bu sayfayı düzenleyin ve onu ekleyin!_ -## İlgili konular {#related-topics} +## Alakalı başlıklar {#related-topics} - [Geliştirme çerçeveleri](/developers/docs/frameworks/) diff --git a/public/content/translations/tr/developers/docs/transactions/index.md b/public/content/translations/tr/developers/docs/transactions/index.md index 44dc747dc0e..c0ddbd789c3 100644 --- a/public/content/translations/tr/developers/docs/transactions/index.md +++ b/public/content/translations/tr/developers/docs/transactions/index.md @@ -1,12 +1,12 @@ --- -title: İşlemler -description: Ethereum işlemlerine genel bir bakış - nasıl çalışırlar, veri yapıları ve bir uygulama aracılığıyla nasıl gönderilirler. +title: "İşlemler" +description: "Ethereum işlemlerine genel bir bakış - nasıl çalışırlar, veri yapıları ve bir uygulama aracılığıyla nasıl gönderilirler." lang: tr --- -İşlemler, hesaplardan kriptografik olarak imzalanmış talimatlardır. Bir hesap, Ethereum ağının durumunu güncellemek için bir işlem başlatacaktır. En basit işlem ETH'yi bir hesaptan diğerine aktarmaktır. +İşlemler, hesaplardan gelen kriptografik olarak imzalanmış talimatlardır. Bir hesap, Ethereum ağının durumunu güncellemek için bir işlem başlatacaktır. En basit işlem ETH'yi bir hesaptan diğerine aktarmaktır. -## Ön koşullar {#prerequisites} +## Ön Koşullar {#prerequisites} Bu sayfayı daha iyi anlamanıza yardımcı olmak için önce [Hesaplar](/developers/docs/accounts/) ve [Ethereum'a giriş](/developers/docs/intro-to-ethereum/) bölümlerini okumanızı öneririz. @@ -14,7 +14,8 @@ Bu sayfayı daha iyi anlamanıza yardımcı olmak için önce [Hesaplar](/develo Bir Ethereum işlemi, harici olarak sahiplenilmiş bir hesap tarafından başlatılan bir eylemi ifade eder, başka bir deyişle, bir sözleşme değil, bir insan tarafından yönetilen bir hesap. Örneğin Bob, Alice'e 1 ETH gönderirse, Bob'un hesabı borçlandırılmalı ve Alice'inki alacaklandırılmalıdır. Bu durum değiştirme eylemi bir işlem içinde gerçekleşir. -![Bir işlemin durum değişikliği yaptığını gösteren diyagram](./tx.png) _Diyagram [Ethereum EVM resmediciden](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf) uyarlanmıştır_ +![Bir işlemin durum değişikliğine neden olduğunu gösteren diyagram](./tx.png) +_[Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf) kaynağından uyarlanan diyagram_ EVM'nin durumunu değiştiren işlemlerin tüm ağa yayınlanması gerekir. Herhangi bir düğüm, Ethereum Sanal Makinesinde ugulanacak işlemleri yayınlamak için talepte bulunabilir, bu olduktan sonra da, doğrulayıcı işlemi uygulayacak ve ortaya çıkan durum değişikliğini ağın geri kalanına yayacaktır. @@ -22,17 +23,17 @@ EVM'nin durumunu değiştiren işlemlerin tüm ağa yayınlanması gerekir. Herh Gönderilen bir işlem aşağıdaki bilgileri içerir: -- `from` - işlemi imzalayacak olan göndericinin adresi. Bu sözleşme hesapları işlem gönderemeyeceği için harici olarak sahiplenilmiş bir hesap olacaktır. -- `to` - alıcı adres (harici olarak sahiplenilmiş bir hesapsa, işlem değeri aktaracaktır. Eğer bir sözleşme hesabıysa, işlem sözleşme kodunu yürütecektir) -- `signature` - gönderenin tanımlayıcısı. Bu, gönderenin özel anahtarı işlemi imzaladığında ve gönderenin bu işleme yetki verdiğini doğruladığında oluşturulur +- `from` – işlemi imzalayacak olan göndericinin adresi. Bu sözleşme hesapları işlem gönderemeyeceği için harici olarak sahiplenilmiş bir hesap olacaktır +- `to` – alıcı adres (harici olarak sahiplenilmiş bir hesapsa, işlem değeri aktaracaktır. Eğer bir sözleşme hesabıysa, işlem sözleşme kodunu yürütecektir) +- `signature` – gönderenin tanımlayıcısı. Bu, gönderenin özel anahtarı işlemi imzaladığında ve gönderenin bu işleme yetki verdiğini doğruladığında oluşturulur - `nonce` - hesabın işlem sayısını belirten ve ardışık olarak artan bir sayaç -- `value` - göndericiden alıcıya aktarılacak ETH miktarı (WEI şeklinde birimlendirilmiştir, 1ETH 1e+18wei'ye eşittir) -- `giriş verileri` - keyfi verileri dahil etmek için opsiyonel alan -- `gasLimit` - işlem tarafından tüketilebilecek maksimum gaz birimi miktarı. [EVM](/developers/docs/evm/opcodes) her bir hesaplık adım için gereken gaz birimini belirtir +- `value` – göndericiden alıcıya aktarılacak ETH miktarı (WEI şeklinde birimlendirilmiştir, 1ETH 1e+18wei'ye eşittir) +- `input data` – keyfi verileri dahil etmek için isteğe bağlı alan +- `gasLimit` – işlem tarafından tüketilebilecek maksimum gaz birimi miktarı. [EVM](/developers/docs/evm/opcodes), her bir hesaplama adımı için gereken gaz birimlerini belirtir - `maxPriorityFeePerGas` - doğrulayıcıya bir bahşiş olarak eklenmesi için harcanan gazın maksimum fiyatı -- `maxFeePerGas` - işlem için ödenebilecek gaz birimi başına maksimum ücret (`baseFeePerGas` ve `maxPriorityFeePerGas`'ı kapsayıcıdır) +- `maxFeePerGas` - işlem için ödenecek gaz birimi başına maksimum ücret (`baseFeePerGas` ve `maxPriorityFeePerGas` dahil) -Gaz, işlemin bir doğrulayıcı tarafından işlenmesi için gereken hesaplamaya bir referanstır. Kullanıcılar bu hesaplama için bir ücret ödemek zorundadır. `gasLimit` ve `maxPriorityFeePerGas` doğrulayıcıya ödenen maksimum işlem ücretini belirler. [Gaz hakkında daha fazla bilgi](/developers/docs/gas/). +Gaz, işlemin bir doğrulayıcı tarafından işlenmesi için gereken hesaplamaya bir referanstır. Kullanıcılar bu hesaplama için bir ücret ödemek zorundadır. `gasLimit` ve `maxPriorityFeePerGas`, doğrulayıcıya ödenen maksimum işlem ücretini belirler. [Gaz hakkında daha fazla bilgi](/developers/docs/gas/). İşlem nesnesi biraz şuna benzer: @@ -52,7 +53,7 @@ Ancak, gönderenin özel anahtarı kullanılarak bir işlem nesnesinin imzalanma Geth gibi bir Ethereum istemcisi bu imzalama sürecini yerine getirir. -[JSON-RPC](/developers/docs/apis/json-rpc) çağrısı örneği: +Örnek [JSON-RPC](/developers/docs/apis/json-rpc) çağrısı: ```json { @@ -99,22 +100,26 @@ Yanıt örneği: } ``` -- `raw` [Özyinelemeli Uzunluk Ön Eki (RLP)](/developers/docs/data-structures-and-encoding/rlp) şeklinde şifrelenmiş imzalı işlemdir -- `tx`, imzalanmış işlemin JSON biçimidir +- `raw`, [Tekrarlamalı Uzunluk Öneki (RLP)](/developers/docs/data-structures-and-encoding/rlp) kodlanmış formdaki imzalı işlemdir +- `tx`, JSON formundaki imzalı işlemdir İmza hash değeri ile işlemin göndericiden geldiği ve ağa gönderildiği kriptografik olarak kanıtlanabilir. ### Veri alanı {#the-data-field} -İşlemlerin büyük bir çoğunluğu, bir sözleşmeye dıştan sahiplenilmiş bir hesaptan erişir. Çoğu sözleşme Solidity ile yazılmıştır ve veri alanlarını [uygulama ikili arayüzü (ABI)](/glossary/#abi) ile uyumlu olacak şekilde yorumlar. +İşlemlerin büyük bir çoğunluğu, bir sözleşmeye dıştan sahiplenilmiş bir hesaptan erişir. +Çoğu sözleşme Solidity ile yazılmıştır ve veri alanlarını [uygulama ikili arayüzü (ABI)](/glossary/#abi) ile uyumlu olacak şekilde yorumlar. -İlk dört bayt, fonksiyonun isminin ve argümanlarının hash değerini kullanarak hangi fonksiyonun çağrılacağını belirler. Bazen seçiciden [bu veri tabanını](https://www.4byte.directory/signatures/) kullanarak fonksiyonu tespit edebilirsiniz. +İlk dört bayt, fonksiyonun isminin ve argümanlarının hash değerini kullanarak hangi fonksiyonun çağrılacağını belirler. +Bazen [bu veritabanını](https://www.4byte.directory/signatures/) kullanarak seçiciden işlevi tanımlayabilirsiniz. -Çağrı verisinin geri kalanı, [ABI şartnamesine uygun şekilde şifrelenmiş olan](https://docs.soliditylang.org/en/latest/abi-spec.html#formal-specification-of-the-encoding) argümanlardır. +Çağrı verisinin geri kalanı, [ABI özelliklerinde belirtildiği gibi kodlanmış](https://docs.soliditylang.org/en/latest/abi-spec.html#formal-specification-of-the-encoding) bağımsız değişkenlerdir. -Örnek olarak, [bu işleme](https://etherscan.io/tx/0xd0dcbe007569fcfa1902dae0ab8b4e078efe42e231786312289b1eee5590f6a1) bakalım. Çağrı verisini görmek için **Click to see More** düğmesini kullanın. +Örneğin, [şu işleme](https://etherscan.io/tx/0xd0dcbe007569fcfa1902dae0ab8b4e078efe42e231786312289b1eee5590f6a1) bir bakalım. +Çağrı verisini görmek için **Click to see More** seçeneğini kullanın. -`0xa9059cbb` fonksiyon seçicisidir. [Bu imza ile bilinen birkaç fonksiyon](https://www.4byte.directory/signatures/?bytes4_signature=0xa9059cbb) var. Bu durumda [sözleşme kaynak kodu](https://etherscan.io/address/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48#code) Etherscan'e yüklenmiş, yani fonksiyonun `transfer(address,uint256)` olduğunu biliyoruz. +İşlev seçici `0xa9059cbb`'dir. Bu imzaya sahip birkaç [bilinen işlev](https://www.4byte.directory/signatures/?bytes4_signature=0xa9059cbb) vardır. +Bu durumda [sözleşme kaynak kodu](https://etherscan.io/address/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48#code) Etherscan'e yüklenmiştir, bu nedenle işlevin `transfer(address,uint256)` olduğunu biliyoruz. Verinin geri kalanı: @@ -123,7 +128,9 @@ Verinin geri kalanı: 000000000000000000000000000000000000000000000000000000003b0559f4 ``` -ABI koşullarına göre, tamsayı değerleri (20 bayt tamsayılar olan adresler gibi) ABI içinde 32 bayt kelimelerin önü sıfırlarla doldurulmuş şekilde bulunurlar. Yani `to` adresinin [`4f6742badb049791cd9a37ea913f2bac38d01279`](https://etherscan.io/address/0x4f6742badb049791cd9a37ea913f2bac38d01279) olduğunu biliyoruz. `value` ise 0x3b0559f4 = 990206452'dir. +ABI koşullarına göre, tamsayı değerleri (20 bayt tamsayılar olan adresler gibi) ABI içinde 32 bayt kelimelerin önü sıfırlarla doldurulmuş şekilde bulunurlar. +Yani `to` adresinin [`4f6742badb049791cd9a37ea913f2bac38d01279`](https://etherscan.io/address/0x4f6742badb049791cd9a37ea913f2bac38d01279) olduğunu biliyoruz. +`value` değeri 0x3b0559f4 = 990206452'dir. ## İşlem türleri {#types-of-transactions} @@ -135,9 +142,9 @@ Ethereum'da birkaç farklı işlem türü vardır: ### Gaz hakkında {#on-gas} -Belirtildiği gibi, işlemlerin yürütülmesi [gaz](/developers/docs/gas/) harcar. Basit transfer işlemleri 21.000 birim Gaz gerektirir. +Belirtildiği gibi, işlemlerin yürütülmesi için [gaz](/developers/docs/gas/) gerekir. Basit transfer işlemleri 21.000 birim Gaz gerektirir. -Dolayısıyla Bob'un 1 ETH'yi Alice'e 190 gwei `baseFeePerGas` ve 10 gwei `maxPriorityFeePerGas` ile göndermesi için Bob'un aşağıdaki ücreti ödemesi gerekir: +Dolayısıyla Bob'un Alice'e 1 ETH'yi 190 gwei `baseFeePerGas` ve 10 gwei `maxPriorityFeePerGas` ile göndermesi için aşağıdaki ücreti ödemesi gerekir: ``` (190 + 10) * 21.000 = 4.200.000 gwei @@ -147,14 +154,14 @@ Dolayısıyla Bob'un 1 ETH'yi Alice'e 190 gwei `baseFeePerGas` ve 10 gwei `maxPr Bob'un hesabı **-1,0042 ETH** borçlandırılacaktır (Alice için 1 ETH + gaz ücretleri için 0,0042 ETH) -Alice'in hesabı **+1,0 ETH** alacaklandırılır +Alice'in hesabına **+1,0 ETH** alacak kaydedilecektir Taban ücret yakılacaktır **-0,00399 ETH** -Doğrulayıcı **+0,000210 ETH** bahşişi tutar +Doğrulayıcı bahşişi tutar **+0,000210 ETH** - -![Kullanılmayan gazın nasıl iade edildiğini gösteren diyagram](./gas-tx.png) _Diyagram [Ethereum EVM resmediciden](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf) uyarlanmıştır_ +![Kullanılmayan gazın nasıl iade edildiğini gösteren diyagram](./gas-tx.png) +_[Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf) kaynağından uyarlanan diyagram_ İşlemde kullanılmayan gaz, kullanıcı hesabına iade edilir. @@ -162,34 +169,37 @@ Doğrulayıcı **+0,000210 ETH** bahşişi tutar Akıllı sözleşme içeren herhangi bir işlem için gaz gereklidir. -Akıllı sözleşmeler, sözleşmenin durumunu değiştirmeyen [`view`](https://docs.soliditylang.org/en/latest/contracts.html#view-functions) ya da [`pure`](https://docs.soliditylang.org/en/latest/contracts.html#pure-functions) olarak adlandırılan fonksiyonlar da içerebilir. Bu nedenle bu fonksiyonların bir EOA tarafından çağrılması için herhangi bir gaz gerekmez. Bu senaryoda kullanılan temel RPC çağrısı [`"eth_call"`](/developers/docs/apis/json-rpc#eth_call) olarak adlandırılır +Akıllı sözleşmeler, sözleşmenin durumunu değiştirmeyen [`view`](https://docs.soliditylang.org/en/latest/contracts.html#view-functions) veya [`pure`](https://docs.soliditylang.org/en/latest/contracts.html#pure-functions) işlevleri olarak bilinen işlevleri de içerebilir. Bu nedenle bu fonksiyonların bir EOA tarafından çağrılması için herhangi bir gaz gerekmez. Bu senaryo için temel RPC çağrısı [`eth_call`](/developers/docs/apis/json-rpc#eth_call) şeklindedir. -Bu `view` veya `pure` fonksiyonları, `eth_call` kullanılarak erişildiği durumun aksine, genellikle dahili olarak (yani sözleşmenin kendisinden veya başka bir sözleşmeden) çağrılır ve bu da gaz maliyetine yol açmaz. +`eth_call` kullanılarak erişilmesinin aksine, bu `view` veya `pure` işlevleri dahili olarak da (yani sözleşmenin kendisinden veya başka bir sözleşmeden) yaygın olarak çağrılır ve bu da gaza mal olur. ## İşlem yaşam döngüsü {#transaction-lifecycle} İşlem gönderildikten sonra aşağıdakiler gerçekleşir: -1. Bir işlem şifresi kriptografik olarak oluşturulur: `0x97d99bc7729211111a21b12c933c949d4f31684f1d6954ff477d0477538ff017` +1. Bir işlem karması kriptografik olarak oluşturulur: + `0x97d99bc7729211111a21b12c933c949d4f31684f1d6954ff477d0477538ff017` 2. İşlem sonrasında ağa yayınlanır ve diğer bekleyen ağ işlemlerinden oluşan işlem havuzuna eklenir. 3. Bir doğrulayıcı, işlemi doğrulamak ve "başarılı" olarak değerlendirmek için işleminizi seçmeli ve bir bloka eklemelidir. -4. Zaman geçtikçe işleminizi taşıyan blok önce "kanıtlanmış" sonrasında "kesinleştirilmiş" şeklinde güncellenecektir. Bu yükseltmeler işleminizin başarılı olduğunu ve asla değiştirilemeyeceğini daha netleştirir. Bir blok "kesinleştirildikten" sonra sadece milyarlarca dolar maliyetinde ağ seviyesinde bir saldırı ile değiştirilebilir. +4. Zaman geçtikçe işleminizi taşıyan blok önce "kanıtlanmış" sonrasında "kesinleştirilmiş" şeklinde güncellenecektir. Bu yükseltmeler, işleminizin başarılı olduğunu ve asla değiştirilmeyeceğini çok + daha netleştirir. Bir blok "kesinleştirildikten" sonra, yalnızca milyarlarca dolara mal olacak bir + ağ düzeyindeki saldırı ile değiştirilebilir. ## Görsel bir demo {#a-visual-demo} -Austin'in işlemlerde, gazda ve madencilikte size yol göstermesini izleyin. +Austin'in işlemleri, gazı ve madenciliği açıklamasını izleyin. -## Yazılan İşlem Zarfı {#typed-transaction-envelope} +## Tür Belirtilmiş İşlem Zarfı {#typed-transaction-envelope} -Ethereum'un başlangıçta işlemler için tek bir formatı vardı. Her işlem, adres, değer, veri, v, r ve s için nonce, gaz fiyatı, gaz limiti içeriyordu. Bu alanlar [RLP ile şifrelenmiştir](/developers/docs/data-structures-and-encoding/rlp/), şuna benzer bir şekilde görünür: +Ethereum'un başlangıçta işlemler için tek bir formatı vardı. Her işlem, adres, değer, veri, v, r ve s için nonce, gaz fiyatı, gaz limiti içeriyordu. Bu alanlar, şuna benzer bir görünüme sahip olacak şekilde [RLP kodludur](/developers/docs/data-structures-and-encoding/rlp/): `RLP([nonce, gasPrice, gasLimit, to, value, data, v, r, s])` -Ethereum, erişim listelerini ve [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)'un eski işlem formatlarını etkilemeden uygulanmasını mümkün kılmak için birçok işlem türünü destekleyecek şekilde evrildi. +Ethereum, eski işlem formatlarını etkilemeden erişim listeleri ve [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) gibi yeni özelliklerin uygulanmasına olanak tanımak için birden fazla işlem türünü destekleyecek şekilde gelişmiştir. -[EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) bu davranışa izin verendir. İşlemler şu şekilde yorumlanır: +Bu davranışa izin veren [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718)'dir. İşlemler şu şekilde yorumlanır: `TransactionType || TransactionPayload` @@ -198,24 +208,26 @@ Burada alanlar şu şekilde tanımlanır: - `TransactionType` - toplam 128 olası işlem türü için 0 ile 0x7f arasında bir sayı. - `TransactionPayload` - işlem türü tarafından tanımlanan rastgele bir bayt dizisi. -`TransactionType` değerine göre, bir işlem şöyle sınıflandırılabilir +`TransactionType` değerine bağlı olarak, bir işlem şu şekilde sınıflandırılabilir: -1. **Tip 0 (Eski) İşlemler:** Ethereum'un başlatılmasından itibaren kullanılan orijinal işlem formatıdır. [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)'dan gelen dinamik gaz ücreti hesaplamaları veya akıllı sözleşmeler için erişim listeleri gibi özellikler içermezler. Eski işlemler, [Tekrarlamalı Uzunluk Öneki (RLP)](/developers/docs/data-structures-and-encoding/rlp) kodlaması kullanıldığında `0xf8` baytıyla başlayarak serileştirilmiş formlarında türlerini belirten belirli bir öneke sahip değildir. Bu işlemler için TransactionType değeri `0x0`'dır. +1. **Tip 0 (Eski) İşlemler:** Ethereum'un lansmanından bu yana kullanılan orijinal işlem formatı. Akıllı sözleşmeler için dinamik gaz ücreti hesaplamaları veya erişim listeleri gibi [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) özellikleri içermezler. Eski işlemler, serileştirilmiş biçimlerinde türlerini belirten özel bir önekten yoksundur ve [Tekrarlamalı Uzunluk Öneki (RLP)](/developers/docs/data-structures-and-encoding/rlp) kodlaması kullanıldığında `0xf8` baytı ile başlarlar. Bu işlemler için TransactionType değeri `0x0`'dır. -2. **Tip 1 İşlemler:** Ethereum'un [Berlin Yükseltmesi](/ethereum-forks/#berlin)'nin bir parçası olarak [EIP-2930](https://eips.ethereum.org/EIPS/eip-2930)'da kullanıma açılan bu işlemler bir `accessList` parametresi içerir. Bu liste, işlemin erişmeyi beklediği adresleri ve depolama anahtarlarını belirtir, bu da akıllı sözleşmelerle ilgili karmaşık işlemler için [gaz](/developers/docs/gas/) maliyetlerinin potansiyel olarak azaltılmasına yardımcı olur. EIP-1559 ücret piyasası değişiklikleri Tip 1 işlemlere dahil değildir. Tip 1 işlemler buna ek olarak, secp256k1 imzasının y değerinin paritesini gösteren `0x0` veya `0x1` olabilen bir `yParity` parametresi de içerir. Bu işlemler, `0x01` baytıyla başladıkları için kolayca tanınır ve TransactionType değerleri `0x1`'dir. +2. **Tip 1 İşlemler:** Ethereum'un [Berlin Yükseltmesi](/ethereum-forks/#berlin) kapsamında [EIP-2930](https://eips.ethereum.org/EIPS/eip-2930) ile tanıtılan bu işlemler bir `accessList` parametresi içerir. Bu liste, işlemin erişmeyi beklediği adresleri ve depolama anahtarlarını belirtir ve akıllı sözleşmeleri içeren karmaşık işlemler için [gaz](/developers/docs/gas/) maliyetlerini potansiyel olarak azaltmaya yardımcı olur. EIP-1559 ücret piyasası değişiklikleri Tip 1 işlemlere dahil değildir. Tip 1 işlemler ayrıca, secp256k1 imzasının y-değerinin paritesini gösteren `0x0` veya `0x1` olabilen bir `yParity` parametresi içerir. `0x01` baytı ile başlamalarıyla tanımlanırlar ve TransactionType değerleri `0x1`'dir. -3. **Tip 2 İşlemler**, sıklıkla EIP-1559 işlemleri olarak adlandırılır ve Ethereum'un [Londra Yükseltmesi](/ethereum-forks/#london)'nde [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) dahilinde tanıtılan işlemlerdir. Bu işlemler, Ethereum ağında standart işlem tipi haline gelmiştir. Bu işlemler, işlem ücretini ana ücret ve öncelik ücreti olarak ayıran öngörülebilirliği artıran yeni bir ücret piyasası mekanizması sunar. `0x02` baytı ile başlarlar ve `maxPriorityFeePerGas` ile `maxFeePerGas` gibi alanları içerirler. Tip 2 işlemler, esneklikleri ve verimlilikleri nedeniyle varsayılan seçenek durumuna gelmiştir. Özellikle yüksek ağ tıkanıklığı dönemlerinde kullanıcıların işlem ücretlerini daha öngörülebilir şekilde yönetmelerine yardımcı olma yetenekleri nedeniyle tercih edilirler. Bu işlemler için TransactionType değeri `0x2`'dir. +3. Genellikle EIP-1559 işlemleri olarak adlandırılan **Tip 2 İşlemler**, Ethereum'un [Londra Yükseltmesi](/ethereum-forks/#london) kapsamında [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) ile tanıtılan işlemlerdir. Bu işlemler, Ethereum ağında standart işlem tipi haline gelmiştir. Bu işlemler, işlem ücretini ana ücret ve öncelik ücreti olarak ayıran öngörülebilirliği artıran yeni bir ücret piyasası mekanizması sunar. `0x02` baytı ile başlarlar ve `maxPriorityFeePerGas` ile `maxFeePerGas` gibi alanlar içerirler. Tip 2 işlemler, esneklikleri ve verimlilikleri nedeniyle varsayılan seçenek durumuna gelmiştir. Özellikle yüksek ağ tıkanıklığı dönemlerinde kullanıcıların işlem ücretlerini daha öngörülebilir şekilde yönetmelerine yardımcı olma yetenekleri nedeniyle tercih edilirler. Bu işlemler için TransactionType değeri `0x2`'dir. +4. **Tip 3 (Blob) İşlemler**, Ethereum'un [Dencun Yükseltmesi](/ethereum-forks/#dencun) kapsamında [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) ile tanıtılmıştır. Bu işlemler, "blob" verilerini (İkili Büyük Nesneler) daha verimli bir şekilde işlemek için tasarlanmıştır ve özellikle Ethereum ağına daha düşük bir maliyetle veri göndermenin bir yolunu sağlayarak Katman 2 toplamalarına fayda sağlar. Blob işlemleri, `blobVersionedHashes`, `maxFeePerBlobGas` ve `blobGasPrice` gibi ek alanlar içerir. `0x03` baytı ile başlarlar ve TransactionType değerleri `0x3`'tür. Blob işlemleri, Ethereum'un veri kullanılabilirliği ve ölçeklendirme yeteneklerinde önemli bir gelişmeyi temsil eder. +5. **Tip 4 İşlemler**, Ethereum'un [Pectra Yükseltmesi](/roadmap/pectra/) kapsamında [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) ile tanıtılmıştır. Bu işlemler, hesap soyutlaması ile ileriye dönük uyumlu olacak şekilde tasarlanmıştır. EOA'ların orijinal işlevselliklerinden ödün vermeden geçici olarak akıllı sözleşme hesapları gibi davranmalarına olanak tanırlar. EOA'nın yetkisini devrettiği akıllı sözleşmeyi belirten bir `authorization_list` parametresi içerirler. İşlemden sonra, EOA'nın kod alanı, yetki devredilen akıllı sözleşmenin adresine sahip olacaktır. -## Daha fazla bilgi {#further-reading} +## Daha fazla kaynak {#further-reading} -- [EIP-2718: Yazılan İşlem Zarfı](https://eips.ethereum.org/EIPS/eip-2718) +- [EIP-2718: Tür Belirtilmiş İşlem Zarfı](https://eips.ethereum.org/EIPS/eip-2718) -_Size yardımcı olan bir topluluk kaynağı mı biliyorsunuz? Bu sayfayı düzenleyin ve ekleyin!_ +_Size yardımcı olan bir topluluk kaynağı mı biliyorsunuz? Bu sayfayı düzenleyin ve onu ekleyin!_ -## İlgili konular {#related-topics} +## Alakalı başlıklar {#related-topics} - [Hesaplar](/developers/docs/accounts/) -- [Ethereum sanal makinesi (EVM)](/developers/docs/evm/) +- [Ethereum Sanal Makinesi (EVM)](/developers/docs/evm/) - [Gaz](/developers/docs/gas/) diff --git a/public/content/translations/tr/developers/docs/web2-vs-web3/index.md b/public/content/translations/tr/developers/docs/web2-vs-web3/index.md index 0dec277786c..1b3ecfce1f1 100644 --- a/public/content/translations/tr/developers/docs/web2-vs-web3/index.md +++ b/public/content/translations/tr/developers/docs/web2-vs-web3/index.md @@ -1,14 +1,14 @@ --- title: Web2 ve Web3 -description: +description: "Merkezi Web2 hizmetlerini, Ethereum blokzincir teknolojisi üzerine kurulu merkeziyetsiz Web3 uygulamaları ile karşılaştırın." lang: tr --- Web2, bugün bir çoğumuzun bildiği internet sürümünü ifade eder. Kişisel verilerinizin karşılığında, size hizmet sağlayan şirketlerin hakim olduğu bir internet. Web3 ise Ethereum bağlamında, blok zincirinde çalışan merkeziyetsiz uygulamaları ifade eder. Bu uygulamalar, kişisel verileri parasallaştırmadan, herkesin katılmasına izin veren uygulamalardır. -Yeni başlayanlar için daha uygun bir kaynak mı arıyorsunuz? [web3'e girişimize](/web3/) bakın. +Yeni başlayanlar için daha uygun bir kaynak mı arıyorsunuz? [Web3'e giriş](/web3/) yazımıza bakın. -## Web3'ün faydaları {#web3-benefits} +## Web3 avantajları {#web3-benefits} Birçok Web3 geliştiricisi, Ethereum'un yerleşik merkeziyetsizliği nedeniyle dapp'ler oluşturmaya karar verdi: @@ -19,15 +19,15 @@ Birçok Web3 geliştiricisi, Ethereum'un yerleşik merkeziyetsizliği nedeniyle ## Pratik karşılaştırmalar {#practical-comparisons} -| Web2 | Web3 | -| --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | -| Twitter herhangi bir hesabı veya tweeti sansürleyebilir | Web3 tweet'leri, kontrol merkeziyetsiz olduğu için sansürlenemez | -| Ödeme hizmeti, belirli iş türleri için ödeme yapılmasına izin vermemeye karar verebilir | Web3 ödeme uygulamaları hiçbir kişisel veri gerektirmez ve ödemeleri engelleyemez | +| Web2 | Web3 | +| --------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| Twitter herhangi bir hesabı veya tweeti sansürleyebilir | Web3 tweet'leri, kontrol merkeziyetsiz olduğu için sansürlenemez | +| Ödeme hizmeti, belirli iş türleri için ödeme yapılmasına izin vermemeye karar verebilir | Web3 ödeme uygulamaları hiçbir kişisel veri gerektirmez ve ödemeleri engelleyemez | | Tek seferlik iş uygulamalarının sunucuları çökebilir ve çalışan gelirini etkileyebilir | Web3 sunucuları çökemez: Arka uç olarak 1000'lerce bilgisayardan oluşan merkeziyetsiz bir ağ olan Ethereum'u kullanırlar | Bu, tüm hizmetlerin bir dapp'ee dönüştürülmesi gerektiği anlamına gelmez. Bu örnekler, web2 ve web3 hizmetleri arasındaki temel farklı açıklamaktadır. -## Web3 sınırlamaları {#web3-limitations} +## Web3 sınırlılıkları {#web3-limitations} Web3'ün şu anda bazı sınırlamaları var: @@ -36,27 +36,27 @@ Web3'ün şu anda bazı sınırlamaları var: - Erişilebilirlik - modern web tarayıcılarındaki entegrasyon eksikliği, web3'ü birçok kullanıcı için daha az erişilebilir kılar. - Maliyet – çoğu başarılı dapp, pahalı olduğu için kodlarının çok küçük kısımlarını blok zincirine koyar. -## Merkezilik ve Merkeziyetsizlik karşılaştırması {#centralization-vs-decentralization} +## Merkeziyet ve merkeziyetsizlik {#centralization-vs-decentralization} Aşağıdaki tabloda, merkezi ve merkeziyetsiz dijital ağların geniş kapsamlı avantaj ve dezavantajlarından bazılarını listeledik. -| Merkezi Sistemler | Merkeziyetsiz Sistemler | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Düşük ağ çapı (tüm katılımcılar merkezi bir otoriteye bağlıdır); yayma işlemi çok sayıda bilgi işlem kaynağına sahip merkezi bir otorite tarafından yapıldığından, bilgi hızla yayılır. | Ağdaki en uzaktaki katılımcılar, potansiyel olarak birbirinden çok uzakta olabilir. Ağın bir tarafından yayınlanan bilgilerin diğer tarafa ulaşması uzun zaman alabilir. | -| Genellikle daha yüksek performans (daha yüksek verim, daha az toplam bilgi işlem kaynağı harcaması) ve daha kolay uygulama. | Genellikle daha düşük performans (daha düşük verim, daha fazla toplam bilgi işlem kaynağı harcaması) ve daha karmaşık uygulama. | -| Verilerin çelişmesi durumunda çözüm açık ve kolaydır: gerçeğin nihai kaynağı merkezi otoritedir. | Eşler, katılımcıların senkronize olması gereken verilerin durumu hakkında çelişkili iddiaları bulunursa, anlaşmazlık çözümü için bir protokol (genellikle karmaşıktır) gereklidir. | -| Tek başarısızlık noktası: Kötü niyetli aktörler, merkezi otoriteyi hedef alarak ağı çökertebilir. | Tek bir başarısızlık noktası yok: Katılımcıların büyük bir kısmı saldırıya uğrasa/alt edilse bile ağ hâlâ çalışabilir. | +| Merkezi Sistemler | Merkeziyetsiz Sistemler | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Düşük ağ çapı (tüm katılımcılar merkezi bir otoriteye bağlıdır); yayma işlemi çok sayıda bilgi işlem kaynağına sahip merkezi bir otorite tarafından yapıldığından, bilgi hızla yayılır. | Ağdaki en uzaktaki katılımcılar, potansiyel olarak birbirinden çok uzakta olabilir. Ağın bir tarafından yayınlanan bilgilerin diğer tarafa ulaşması uzun zaman alabilir. | +| Genellikle daha yüksek performans (daha yüksek verim, daha az toplam bilgi işlem kaynağı harcaması) ve daha kolay uygulama. | Genellikle daha düşük performans (daha düşük verim, daha fazla toplam bilgi işlem kaynağı harcaması) ve daha karmaşık uygulama. | +| Verilerin çelişmesi durumunda çözüm açık ve kolaydır: gerçeğin nihai kaynağı merkezi otoritedir. | Eşler, katılımcıların senkronize olması gereken verilerin durumu hakkında çelişkili iddiaları bulunursa, anlaşmazlık çözümü için bir protokol (genellikle karmaşıktır) gereklidir. | +| Tek başarısızlık noktası: Kötü niyetli aktörler, merkezi otoriteyi hedef alarak ağı çökertebilir. | Tek bir başarısızlık noktası yok: Katılımcıların büyük bir kısmı saldırıya uğrasa/alt edilse bile ağ hâlâ çalışabilir. | | Ağ katılımcıları arasındaki koordinasyon çok daha kolaydır ve merkezi bir otorite tarafından yürütülür. Merkezi otorite, ağ katılımcılarını çok az sürtüşmeyle yükseltmeleri, protokol güncellemelerini vb. benimsemeye zorlayabilir. | Ağ düzeyindeki kararlarda, protokol yükseltmelerinde vb. konularda son söz hiçbir aracıya ait olmadığı için koordinasyon genellikle zordur. En kötü durumda, protokol değişiklikleriyle ilgili anlaşmazlıklar olduğunda ağ kırılmaya eğilimlidir. | -| Merkezi otorite verileri sansürleyebilir, potansiyel olarak ağın bölümlerinin ağın geri kalanıyla etkileşimini kesebilir. | Bilginin ağda yayılmasının birçok yolu olduğundan sansürlemek çok daha zordur. | -| Ağa katılım, merkezi otorite tarafından kontrol edilir. | Ağa herkes katılabilir; "kapı bekçileri" yoktur. İdeal olarak, katılım maliyeti çok düşüktür. | +| Merkezi otorite verileri sansürleyebilir, potansiyel olarak ağın bölümlerinin ağın geri kalanıyla etkileşimini kesebilir. | Bilginin ağda yayılmasının birçok yolu olduğundan sansürlemek çok daha zordur. | +| Ağa katılım, merkezi otorite tarafından kontrol edilir. | Ağa herkes katılabilir; "kapı bekçileri" yoktur. İdeal olarak, katılım maliyeti çok düşüktür. | Bunların, her ağda geçerli olmayabilecek genel kalıplar olduğunu unutmayın. Ayrıca, gerçekte bir ağın merkezileşme/merkeziyetsizlik derecesi bir spektrumda yer alır; hiçbir ağ tamamen merkezileştirilmiş veya tamamen merkeziyetsiz değildir. -## Daha fazla bilgi {#further-reading} +## Daha fazla kaynak {#further-reading} -- [Web3 nedir?](/web3/) - _ethereum.org_ +- [Web3 Nedir?](/web3/) - _ethereum.org_ - [Bir Web 3.0 uygulamasının mimarisi](https://www.preethikasireddy.com/post/the-architecture-of-a-web-3-0-application) - _Preethi Kasireddy_ -- [Merkeziyetsizliğin Anlamı](https://medium.com/@VitalikButerin/the-meaning-of-decentralization-a0c92b76a274) _ 6 Şubat 2017 - Vitalik Buterin_ -- [Merkeziyetsizlik Neden Önemlidir](https://medium.com/s/story/why-decentralization-matters-5e3f79f7638e) _18 Şubat 2018 - Chris Dixon_ +- [Merkeziyetsizliğin Anlamı](https://medium.com/@VitalikButerin/the-meaning-of-decentralization-a0c92b76a274) _6 Şubat 2017 - Vitalik Buterin_ +- [Merkeziyetsizlik Neden Önemlidir](https://onezero.medium.com/why-decentralization-matters-5e3f79f7638e) _18 Şubat 2018 - Chris Dixon_ - [Web 3.0 Nedir ve Neden Önemlidir](https://medium.com/fabric-ventures/what-is-web-3-0-why-it-matters-934eb07f3d2b) _31 Aralık 2019 - Max Mersch ve Richard Muirhead_ -- [Neden Web 3.0'a İhtiyacımız Var?](https://medium.com/@gavofyork/why-we-need-web-3-0-5da4f2bf95ab)_12 Eylül 2018 - Gavin Wood_ +- [Neden Web 3.0'a İhtiyacımız Var?](https://gavofyork.medium.com/why-we-need-web-3-0-5da4f2bf95ab) _12 Eylül 2018 - Gavin Wood_ diff --git a/public/content/translations/tr/developers/docs/wrapped-eth/index.md b/public/content/translations/tr/developers/docs/wrapped-eth/index.md index df42b98d3ac..825a7316dd2 100644 --- a/public/content/translations/tr/developers/docs/wrapped-eth/index.md +++ b/public/content/translations/tr/developers/docs/wrapped-eth/index.md @@ -1,6 +1,6 @@ --- -title: Sarılı ETH (WETH) Nedir? -description: Ether (ETH) için ERC20 uyumlu bir sarıcı olan Sarılı ethere (WETH) giriş. +title: "Sarılı ETH (WETH) Nedir?" +description: "Ether (ETH) için ERC20 uyumlu bir sarıcı olan Sarılı ethere (WETH) giriş." lang: tr --- @@ -35,19 +35,16 @@ WETH akıllı sözleşmesini kullanarak WETH'yi ETH'ye çevirebilirsiniz. WETH a WETH sözleşmesini kullanarak ETH'yi sarmak veya çözmek için gaz ücreti ödersiniz. - WETH, basit ve test edilmiş bir akıllı sözleşmeye dayandığı için genellikle güvenli kabul edilir. WETH sözleşmesi resmen doğrulanmıştır. Bu, Ethereum'da akıllı sözleşmelere yönelik en yüksek güvenlik standardıdır. - Bu sayfada açıklanan [WETH'nin kanonik uygulamasının](https://etherscan.io/token/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2) yanı sıra, başka varyantları da vardır. Bunlar, uygulama geliştiricileri tarafından oluşturulan özel jetonlar veya diğer blokzincirlerde yayımlanmış sürümler olabilir ve farklı davranabilir ya da farklı güvenlik özelliklerine sahip olabilir. **Hangi WETH uygulaması ile etkileşimde olduğunuzu öğrenmek için jeton bilgilerini her zaman iki kez kontrol edin.** - @@ -55,7 +52,6 @@ Bu sayfada açıklanan [WETH'nin kanonik uygulamasının](https://etherscan.io/t - [Ethereum Ana Ağı](https://etherscan.io/token/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2) - [Arbitrum](https://arbiscan.io/token/0x82af49447d8a07e3bd95bd0d56f35241523fbab1) - [Optimism](https://optimistic.etherscan.io/token/0x4200000000000000000000000000000000000006) - ## Daha fazla kaynak {#further-reading} diff --git a/public/content/translations/tr/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md b/public/content/translations/tr/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md index c347785407d..deac665eea4 100644 --- a/public/content/translations/tr/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md +++ b/public/content/translations/tr/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md @@ -1,33 +1,32 @@ --- -title: Python Geliştiricileri için Ethereum'a Giriş, Bölüm 1 -description: Özellikle Python programlama dili hakkında bilgi sahibi olanlar için yararlı olan Ethereum geliştirmeye giriş +title: "Bir Python geliştiricisi için Ethereum'a giriş, bölüm 1" +description: "Özellikle Python programlama dilini bilenler için faydalı olan Ethereum geliştirmeye bir giriş." author: Marc Garreau lang: tr -tags: - - "python" - - "web3.js" +tags: [ "python", "web3.py" ] skill: beginner published: 2020-09-08 source: Snake charmers sourceUrl: https://snakecharmers.ethereum.org/a-developers-guide-to-ethereum-pt-1/ --- -Şu Ethereum denen şeyi duydunuz ve konuya daha derinlemesine inmeye hazır mı hissediyorsunuz? Bu gönderi, bazı blok zinciri temellerini hızlı bir şekilde ele alacak, ardından sizi simüle edilmiş bir Ethereum düğümü ile etkileşime sokarak blok verilerini okuyacak, hesap bakiyelerini kontrol edecek ve işlemleri gönderecektir. Bu arada, uygulama oluşturmanın geleneksel yolları ile bu yeni merkeziyetsiz paradigma arasındaki farkları vurgulayacağız. +Şu Ethereum denen şeyi duydunuz ve konuya daha derinlemesine inmeye hazır mı hissediyorsunuz? Bu gönderi, bazı blokzinciri temellerini hızlıca ele alacak, ardından simüle edilmiş bir Ethereum düğümü ile etkileşim kurarak blok verilerini okumanızı, hesap bakiyelerini kontrol etmenizi ve işlem göndermenizi sağlayacaktır. Bu arada, uygulama oluşturmanın geleneksel yolları ile bu yeni merkeziyetsiz paradigma arasındaki farkları vurgulayacağız. -## (Hafif) ön koşullar {#soft-prerequisites} +## (Esnek) Ön Koşullar {#soft-prerequisites} -Bu gönderi, birçok türden geliştiricileri için ulaşılabilir olmayı arzulamaktadır. [Python araçları](/developers/docs/programming-languages/python/) kullanılacaktır, ama sadece fikirler için bir araç olacaklardır: Bir Python geliştiricisi değilseniz de sorun olmaz. Gelgelelim, Ethereum ile ilgili kısımlara hızlıca geçebilmemiz için bazı şeyleri bildiğinizi varsayacağım. +Bu gönderi, geniş bir geliştirici yelpazesi için erişilebilir olmayı hedeflemektedir. [Python araçları](/developers/docs/programming-languages/python/) kullanılacaktır, ama sadece fikirler için bir araç olacaklardır: Bir Python geliştiricisi değilseniz de sorun olmaz. Gelgelelim, Ethereum ile ilgili kısımlara hızlıca geçebilmemiz için bazı şeyleri bildiğinizi varsayacağım. Varsayımlar: - Bir terminalde gezinebildiğiniz, - Birkaç satır Python kodu yazdığınız, -- Python'un 3.6 ya da daha yüksek bir sürümü cihazınızda yüklüdür (bir [sanal ortam](https://realpython.com/effective-python-environment/#virtual-environments) kullanılması teşvik edilmektedir), ve -- Python’un paket indiricisi `pip`'i kullandığınız varsayılır. Buna karşın, eğer varsayımlardan herhangi biri doğru değilse, veya bu makaledeki kodu yeniden uygulamayı düşünmüyorsanız, büyük ihtimalle yine de gayet iyi şekilde takip edebilirsiniz. +- Python'un 3.6 ya da daha yüksek bir sürümü cihazınızda yüklüdür (bir [sanal ortam](https://realpython.com/effective-python-environment/#virtual-environments) kullanılması şiddetle tavsiye edilir), ve +- Python’un paket yükleyicisi olan `pip`'i kullandığınız varsayılır. + Buna karşın, eğer varsayımlardan herhangi biri doğru değilse veya bu makaledeki kodu yeniden uygulamayı düşünmüyorsanız, büyük ihtimalle yine de gayet iyi şekilde takip edebilirsiniz. -## Kısaca blok zincirleri {#blockchains-briefly} +## Kısaca Blokzincirler {#blockchains-briefly} -Ethereum'u tanımlamanın birçok yolu bulunsa da Ethereum, özünde bir blok zinciridir. Blok zincirleri bir dizi bloktan oluşur, bu yüzden oradan başlayalım. En basit şekilde, Ethereum blok zincirindeki her bir blok sadece birtakım meta veri ve bir dizi işlemdir. JSON formatında, şöyle bir şeye benzer: +Ethereum'u tanımlamanın birçok yolu bulunsa da Ethereum, özünde bir blokzincirdir. Blokzincirler bir dizi bloktan oluşur, bu yüzden oradan başlayalım. En basit şekilde, Ethereum blokzincirindeki her bir blok sadece birtakım meta veri ve bir işlemler listesidir. JSON formatında, şöyle bir şeye benzer: ```json { @@ -39,39 +38,39 @@ Ethereum'u tanımlamanın birçok yolu bulunsa da Ethereum, özünde bir blok zi } ``` -Her [blok](/developers/docs/blocks/) kendinden önceki bloğa doğru bir referansa sahiptir; `parentHash` kısaca önceki bloğun hash değeridir. +Her [blok](/developers/docs/blocks/) kendinden önceki bloğa doğru bir referansa sahiptir; `parentHash` kısaca önceki bloğun karmasıdır. -Not: Ethereum, hash fonksiyonlarını sürekli sabit büyüklükteki değerler ("hash değerleri") oluşturmak için kullanır. Hash değerleri, Ethereum'da büyük bir rol oynar ama şimdilik onları benzersiz kimlikler olarak düşünebilirsiniz. +Not: Ethereum, sabit boyutlu değerler ("karmalar") üretmek için düzenli olarak karma fonksiyonlarını kullanır. Karmalar, Ethereum'da önemli bir rol oynar, ancak şimdilik onları benzersiz kimlikler olarak düşünebilirsiniz. -![Her bloğun içindeki verileri içeren bir blok zincirini gösteren bir diyagram](./blockchain-diagram.png) +![Her bloğun içindeki verileri içeren bir blokzincirini gösteren bir diyagram](./blockchain-diagram.png) -_Bir blok zinciri aslen bağlantılı bir dizidir; her bir blok önceki bloğa doğru bir referansa sahiptir._ +_Bir blokzincir esasen bağlantılı bir listedir; her blok, önceki bloğa bir referans içerir._ Bu veri yapısı yeni bir şey değildir ama ağı yöneten kurallar (yani eşler arası protokoller) öyledir. Merkezi bir otorite yoktur; eşler ağı, ağı sürdürmek için iş birliği yapmalı ve bir sonraki bloğa hangi işlemlerin dahil edileceğine karar vermek için rekabet etmelidir. Bu nedenle, bir arkadaşınıza biraz para göndermek istediğinizde, bu işlemi ağa yayınlamanız ve ardından gelecek bir bloğa eklenmesini beklemeniz gerekir. -Blok zincirinin, paranın bir kullanıcıdan diğerine gerçekten gönderildiğini doğrulamasının tek yolu, o blok zincirine özgü (yani, blok zinciri tarafından oluşturulan ve yönetilen) bir para birimi kullanmaktır. Ethereum'da bu para birimine ether denir ve Ethereum blok zinciri, hesap bakiyelerinin tek resmi kaydını içerir. +Blokzincirinin, paranın bir kullanıcıdan diğerine gerçekten gönderildiğini doğrulamasının tek yolu, o blokzincirine özgü (yani, blokzinciri tarafından oluşturulan ve yönetilen) bir para birimi kullanmaktır. Ethereum'da bu para birimine ether denir ve Ethereum blokzinciri, hesap bakiyelerinin tek resmi kaydını içerir. ## Yeni bir paradigma {#a-new-paradigm} Bu merkeziyetsiz yeni teknoloji yığını, yeni geliştirici araçları ortaya çıkardı. Bu tür araçlar birçok programlama dilinde mevcuttur, ancak biz Python merceğinden bakacağız. Tekrarlamak gerekirse: Python tercih ettiğiniz dil olmasa bile, takip etmek çok zor olmayacaktır. -Ethereum ile etkileşim kurmak isteyen Python geliştiricilerinin [Web3.py](https://web3py.readthedocs.io/).'ye ulaşması muhtemeldir. Web3.py, bir Ethereum düğümüne bağlanma ve ondan veri gönderme ve alma şeklinizi büyük ölçüde basitleştiren bir kütüphanedir. +Ethereum ile etkileşim kurmak isteyen Python geliştiricileri büyük ihtimalle [Web3.py](https://web3py.readthedocs.io/) kullanacaktır. Web3.py, bir Ethereum düğümüne bağlanma ve ondan veri gönderme ve alma şeklinizi büyük ölçüde basitleştiren bir kütüphanedir. -Not: “Ethereum düğümü” ve “Ethereum istemcisi” birbirinin yerine kullanılan terimlerdir. Her iki durumda da, Ethereum ağındaki bir katılımcının çalıştırdığı yazılım ifade edilir. Bu yazılım blok verilerini okuyabilir, zincire yeni bloklar eklendiğinde güncellemeler alabilir, yeni işlemler yayımlayabilir ve daha fazlasını yapabilir. Teknik olarak istemci yazılımdır, düğüm ise yazılımı çalıştıran bilgisayardır. +Not: “Ethereum düğümü” ve “Ethereum istemcisi” birbirinin yerine kullanılabilir. Her iki durumda da, Ethereum ağındaki bir katılımcının çalıştırdığı yazılım ifade edilir. Bu yazılım blok verilerini okuyabilir, zincire yeni bloklar eklendiğinde güncellemeler alabilir, yeni işlemler yayımlayabilir ve daha fazlasını yapabilir. Teknik olarak istemci yazılımdır, düğüm ise yazılımı çalıştıran bilgisayardır. -[Ethereum istemcileri](/developers/docs/nodes-and-clients/); [IPC](https://wikipedia.org/wiki/Inter-process_communication), HTTP veya Websocket'ler tarafından erişilebilir olacak şekilde yapılandırılabilir, bu nedenle Web3.py'nin bu yapılandırmayı yansıtması gerekecek. Web3.py, bu bağlanma seçeneklerini **sağlayıcı** (provider) olarak ifade eder. Web3.py örneğini düğümünüze bağlamak için üç sağlayıcıdan birini seçmeniz gerekir. +[Ethereum istemcileri](/developers/docs/nodes-and-clients/), [IPC](https://wikipedia.org/wiki/Inter-process_communication), HTTP veya Websocket'ler tarafından erişilebilir olacak şekilde yapılandırılabilir, bu nedenle Web3.py'nin bu yapılandırmayı yansıtması gerekir. Web3.py bu bağlantı seçeneklerine **sağlayıcılar** adını verir. Web3.py örneğini düğümünüze bağlamak için üç sağlayıcıdan birini seçmeniz gerekir. ![Web3.py'nin uygulamanızı bir Ethereum düğümüne bağlamak için IPC'yi nasıl kullandığını gösteren bir diyagram](./web3py-and-nodes.png) _Ethereum düğümünü ve Web3.py'yi aynı protokol aracılığıyla iletişim kuracak şekilde yapılandırın, örneğin bu şemadaki IPC gibi._ -Web3.py uygun şekilde yapılandırıldıktan sonra blok zinciri ile etkileşime başlayabilirsiniz. İşte karşılaşacaklarımızın bir ön izlemesi olarak birkaç Web3.py kullanım örneği: +Web3.py uygun şekilde yapılandırıldıktan sonra blokzinciri ile etkileşime başlayabilirsiniz. İşte karşılaşacaklarımızın bir ön izlemesi olarak birkaç Web3.py kullanım örneği: ```python -# read block data: +# blok verisini oku: w3.eth.get_block('latest') -# send a transaction: +# bir işlem gönder: w3.eth.send_transaction({'from': ..., 'to': ..., 'value': ...}) ``` @@ -79,9 +78,9 @@ w3.eth.send_transaction({'from': ..., 'to': ..., 'value': ...}) Bu örnekte, sadece bir Python yorumlayıcısı içinde çalışacağız. Herhangi bir dizin, dosya, sınıf veya fonksiyon oluşturmayacağız. -Not: Aşağıdaki örneklerde "$" ile başlayan komutların terminalde çalıştırılması amaçlanmıştır. ("$" işaretini yazmayınız, bu sadece satır başlangıcını belli etmek içindir.) +Not: Aşağıdaki örneklerde `$` ile başlayan komutların terminalde çalıştırılması amaçlanmıştır. (`$` işaretini yazmayın, bu sadece satırın başlangıcını belirtir.) -İlk olarak, deney yapabileceğiniz kullanıcı dostu bir ortam yaratmak için [IPython](https://ipython.org/) indirin. IPython, diğer özelliklerin yanı sıra tab tuşu ile tamamlama özelliği sunarak Web3.py içinde nelerin mümkün olduğunu görmeyi çok daha kolaylaştırır. +İlk olarak, içinde keşif yapabileceğiniz kullanıcı dostu bir ortam için [IPython](https://ipython.org/) yükleyin. IPython, diğer özelliklerin yanı sıra sekme ile tamamlama özelliği sunarak Web3.py içinde nelerin mümkün olduğunu görmeyi çok daha kolaylaştırır. ```bash pip install ipython @@ -93,7 +92,7 @@ Web3.py, `web3` adı altında yayınlanmıştır. Şu şekilde kurun: pip install web3 ``` -Bir şey daha: Daha sonra birkaç bağımlılık gerektiren bir blok zinciri simüle edeceğiz. Bunları şu şekilde yükleyebilirsiniz: +Bir şey daha var: Daha sonra birkaç bağımlılık gerektiren bir blokzinciri simüle edeceğiz. Bunları şu şekilde yükleyebilirsiniz: ```bash pip install 'web3[tester]' @@ -101,11 +100,11 @@ pip install 'web3[tester]' Başlamaya hazırsınız! -Not: `web3[tester]` paketi Python 3.10.xx sürümüne kadar çalışır +Not: `web3[tester]` paketi Python 3.10.xx sürümüne kadar çalışır. -## Bir sanal alan (sandbox) başlatın {#spin-up-a-sandbox} +## Bir sanal alan başlatın {#spin-up-a-sandbox} -Terminalinizde `ipython` çalıştırarak yeni bir Python ortamı açın. Bu, `python` çalıştırmakla benzerdir ancak başka kullanışlı özellikleri de beraberinde getirir. +Terminalinizde `ipython` çalıştırarak yeni bir Python ortamı açın. Bu, `python` çalıştırmaya benzer, ancak daha fazla kullanışlı özellikle birlikte gelir. ```bash ipython @@ -123,24 +122,24 @@ In [1]: In [1]: from web3 import Web3 ``` -## Web3 modülü ile tanışın {#introducing-the-web3-module} +## Web3 modülüne giriş {#introducing-the-web3-module} -[Web3](https://web3py.readthedocs.io/en/stable/overview.html#base-api) modülü, Ethereum'a bir geçit olmanın yanı sıra birkaç kolaylık fonksiyonu sunar. Birkaçını keşfedelim. +Ethereum'a bir geçit olmasının yanı sıra, [Web3](https://web3py.readthedocs.io/en/stable/overview.html#base-api) modülü birkaç kolaylaştırıcı fonksiyon sunar. Birkaçını keşfedelim. -Bir Ethereum uygulamasında, genellikle para birimlerini dönüştürmeniz gerekir. Web3 modülü bunun için birkaç yardımcı yöntem sağlar: [wei_den](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.from_wei) ve [wei_ye](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.to_wei). +Bir Ethereum uygulamasında, genellikle para birimi birimlerini dönüştürmeniz gerekir. Web3 modülü, tam da bunun için birkaç yardımcı metot sunar: [from_wei](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.from_wei) ve [to_wei](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.to_wei). -Not: Bilgisayarlar, ondalık matematiği işlemede çok kötüdür. Bunu aşmak için geliştiriciler genellikle dolar tutarlarını sent olarak saklar. Örneğin fiyatı $5,99 olan bir ürün veritabanında 599 olarak saklanabilir. +Not: Bilgisayarlar, ondalık matematiği işlemede çok kötüdür. Bunu aşmak için geliştiriciler genellikle dolar tutarlarını sent olarak saklar. Örneğin fiyatı $5.99 olan bir ürün veritabanında 599 olarak saklanabilir. -Ether bazındaki işlemler işlenirken benzer bir model kullanılır. Ancak, ether'da iki ondalık nokta yerine 18 ondalık nokta bulunur! Ether'ın en küçük birimine wei denir, bu nedenle işlem gönderirken belirtilen değer budur. +ether cinsinden işlemler gerçekleştirilirken de benzer bir düzen kullanılır. Ancak ether, iki ondalık basamak yerine 18 ondalık basamağa sahiptir! Ether'ın en küçük birimine wei denir, bu nedenle işlem gönderirken belirtilen değer budur. 1 ether = 1000000000000000000 wei -1 wei = 0,000000000000000001 ether +1 wei = 0.000000000000000001 ether -Bazı değerleri wei'ye ve wei'den dönüştürmeyi deneyin. Ether ve wei [arasındaki çok sayıda birim için isimler olduğunu](https://web3py.readthedocs.io/en/stable/troubleshooting.html#how-do-i-convert-currency-denominations) unutmayın. Bunlar arasında daha iyi bilinenlerden biri **gwei**'dir, çünkü genellikle işlem ücretleri bu şekilde gösterilir. +Bazı değerleri wei'ye ve wei'den dönüştürmeyi deneyin. Ether ve wei arasında [birçok para birimi birimi için isimler olduğunu](https://web3py.readthedocs.io/en/stable/troubleshooting.html#how-do-i-convert-currency-denominations) unutmayın. Bunlar arasında daha iyi bilinenlerden biri **gwei**'dir, çünkü genellikle işlem ücretleri bu şekilde gösterilir. ```python In [2]: Web3.to_wei(1, 'ether') @@ -150,7 +149,7 @@ In [3]: Web3.from_wei(500000000, 'gwei') Out[3]: Decimal('0.5') ``` -Web3 modülündeki diğer yardımcı program yöntemleri arasında veri formatı dönüştürücüleri (örneğin, [`toHex`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.toHex)), adres yardımcıları (örneğin, [`isAddress`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.isAddress)) ve karma fonksiyonları (örneğin, [`keccak`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.keccak)) bulunur. Bunların çoğu serinin devamında ele alınacaktır. Kullanılabilir tüm yöntemleri ve özellikleri görüntülemek için `Web3`. yazıp noktadan sonra iki kez tab tuşuna basarak IPython'un otomatik tamamlama özelliğinden faydalanın. +Web3 modülündeki diğer yardımcı metotlar arasında veri biçimi dönüştürücüleri (örneğin, [`toHex`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.toHex)), adres yardımcıları (örneğin, [`isAddress`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.isAddress)) ve karma fonksiyonları (örneğin, [`keccak`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.keccak)) bulunur. Bunların çoğu serinin devamında ele alınacaktır. Kullanılabilir tüm yöntemleri ve özellikleri görüntülemek için `Web3.` yazıp noktadan sonra iki kez sekme tuşuna basarak IPython'un otomatik tamamlama özelliğinden faydalanın. ## Zincirle konuşun {#talk-to-the-chain} @@ -158,37 +157,38 @@ Kolaylık sağlayan bu yöntemler güzel olsa da artık blokzincire geçelim. So Bu yolu kullanmayacağız ancak HTTP Sağlayıcısını kullanan eksiksiz bir iş akışı örneği şöyle görünebilir: -- Bir Ethereum düğümü indirin, örneğin [Geth](https://geth.ethereum.org/). -- Geth'i bir terminal penceresinde başlatın ve ağı senkronize etmesini bekleyin. Varsayılan HTTP portu `8545`'tir, ancak bu değiştirilebilir. -- Web3.py'ye `localhost:8545` üzerindeki HTTP aracılığıyla düğüme bağlanmasını söyleyin. `w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545'))` -- Düğüm ile etkileşime geçmek için `w3` oluşumunu kullanın. +- Bir Ethereum düğümü indirin, örneğin, [Geth](https://geth.ethereum.org/). +- Geth'i bir terminal penceresinde başlatın ve ağı senkronize etmesini bekleyin. Varsayılan HTTP bağlantı noktası `8545`'tir, ancak yapılandırılabilir. +- Web3.py'ye HTTP aracılığıyla `localhost:8545` üzerindeki düğüme bağlanmasını söyleyin. + `w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545'))` +- Düğümle etkileşim kurmak için `w3` örneğini kullanın. -Bu, bunu yapmanın "gerçek" bir yolu olsa da, senkronizasyon işlemi saatler sürer ve yalnızca bir geliştirme ortamı istiyorsanız gereksizdir. Web3.py bu amaç için dördüncü bir sağlayıcı sunar: **EthereumTesterProvider**. Bu test sağlayıcısı, rahat izinlere ve oynamak için sahte para birimine sahip simüle edilmiş bir Ethereum düğümüne bağlanır. +Bu, bunu yapmanın "gerçek" bir yolu olsa da, senkronizasyon işlemi saatler sürer ve yalnızca bir geliştirme ortamı istiyorsanız gereksizdir. Web3.py bu amaçla dördüncü bir sağlayıcı sunar: **EthereumTesterProvider**. Bu test sağlayıcısı, rahat izinlere ve oynamak için sahte para birimine sahip simüle edilmiş bir Ethereum düğümüne bağlanır. -![Web3.py uygulamanızı simüle edilmiş bir Ethereum düğümüne bağlayan EthereumTesterProvider'ı gösteren bir diyagram](./ethereumtesterprovider.png) +![web3.py uygulamanızı simüle edilmiş bir Ethereum düğümüne bağlayan EthereumTesterProvider'ı gösteren bir diyagram](./ethereumtesterprovider.png) _EthereumTesterProvider, simüle edilmiş bir düğüme bağlanır ve hızlı geliştirme ortamları için kullanışlıdır._ -Bu simüle edilmiş düğüme [eth-tester](https://github.com/ethereum/eth-tester) denir; bu düğümü, `pip install web3[tester]` komutunun bir parçası olarak kurduk. Web3.py'yi bu test sağlayıcısını kullanacak şekilde yapılandırmak şu kadar basittir: +Bu simüle edilmiş düğüme [eth-tester](https://github.com/ethereum/eth-tester) denir ve biz onu `pip install 'web3[tester]'` komutunun bir parçası olarak kurduk. Web3.py'yi bu test sağlayıcısını kullanacak şekilde yapılandırmak şu kadar basittir: ```python In [4]: w3 = Web3(Web3.EthereumTesterProvider()) ``` -Artık zincirde sörf yapmaya hazırsınız! İnsanlar buna sörf yapmak demezler. Bunu az önce kafamdan uydurdum. Hadi hızlı bir tur atalım. +Artık zincirde sörf yapmaya hazırsınız! İnsanlar böyle bir şey söylemez. Bunu az önce kafamdan uydurdum. Hadi hızlı bir tur atalım. ## Hızlı tur {#the-quick-tour} -İlk önce önemli bir şeyi aradan çıkaralım, bir akıl sağlığı kontrolü: +Her şeyden önce, hızlı bir kontrol yapalım: ```python -In [5]: w3.isConnected() +In [5]: w3.is_connected() Out[5]: True ``` -Test sağlayıcısını kullandığımız için bu çok değerli bir test değildir ancak başarısız olursa, muhtemelen `w3` değişkenini başlatırken yanlış bir şeyler yazmışsınızdır. İç parantezleri dahil ettiğinizi iki kez kontrol edin, yani `Web3.EthereumTesterProvider()` şeklinde olsun. +Test sağlayıcısını kullandığımız için bu çok değerli bir test değildir ancak başarısız olursa, muhtemelen `w3` değişkenini başlatırken yanlış bir şeyler yazmışsınızdır. İç parantezleri eklediğinizden emin olun, yani `Web3.EthereumTesterProvider()`. -## 1. tur durağı: [hesaplar](/developers/docs/accounts/) {#tour-stop-1-accounts} +## Tur durağı #1: [hesaplar](/developers/docs/accounts/) {#tour-stop-1-accounts} Kolaylık sağlamak için test sağlayıcısı bazı hesaplar oluşturdu ve bunları test ether'i ile önceden yükledi. @@ -201,7 +201,7 @@ Out[6]: ['0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', '0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69', ...] ``` -Bu komutu çalıştırırsanız, `0x` ile başlayan on dizelik bir liste görmelisiniz. Her biri bir **herkese açık adrestir** ve bazı yönlerden çek hesabındaki hesap numarasına benzer. Bu adresi size ether göndermek isteyen birine verirsiniz. +Bu komutu çalıştırırsanız `0x` ile başlayan on diziden oluşan bir liste görmelisiniz. Her biri bir **açık adrestir** ve bazı yönlerden bir çek hesabındaki hesap numarasına benzer. Bu adresi size ether göndermek isteyen birine verirsiniz. Belirtildiği gibi, test sağlayıcısı bu hesapların her birine bir miktar test ether'ini önceden yüklemiştir. İlk hesapta ne kadar olduğunu öğrenelim: @@ -210,18 +210,18 @@ In [7]: w3.eth.get_balance(w3.eth.accounts[0]) Out[7]: 1000000000000000000000000 ``` -Bir sürü sıfır var! Güle oynaya sahte bankaya doğru gitmeden önce para birimleriyle ilgili eski dersi hatırlayın. Ether değerleri, en küçük birim olan wei ile temsil edilir. Bunu ether'e çevirin: +Bir sürü sıfır var! Güle oynaya sahte bankaya gitmeden önce, daha önceki para birimi birimleri dersini hatırlayın. Ether değerleri, en küçük birim olan wei ile temsil edilir. Bunu ether'e çevirin: ```python In [8]: w3.from_wei(1000000000000000000000000, 'ether') Out[8]: Decimal('1000000') ``` -Bir milyon test ether'ı, yine de az buz para değil. +Bir milyon test ether'i — yine de fena değil. -## 2. tur durağı: blok verisi {#tour-stop-2-block-data} +## Tur durağı #2: blok verisi {#tour-stop-2-block-data} -Simüle edilmiş blok zincirinin durumuna bir göz atalım: +Simüle edilmiş blokzincirinin durumuna bir göz atalım: ```python In [9]: w3.eth.get_block('latest') @@ -236,13 +236,13 @@ Out[9]: AttributeDict({ Bir blok hakkında birçok bilgi döndürülür, ancak burada dikkat edeceğimiz sadece birkaç şey var: -- Test cihazı sağlayıcısını ne kadar süre önce yapılandırmış olursanız olun, blok numarası sıfırdır . Yaklaşık her 12 saniyede bir yeni bir blok oluşturan gerçek Ethereum ağının aksine, bu simülasyon, siz ona biraz iş verene kadar bekleyecektir. -- Henüz hiçbir şey yapmadığımız için `transactions` da aynı nedenden dolayı boş bir listedir. Bu ilk blok, sadece zinciri başlatmak için kullanılan bir **boş bloktur**. -- `parentHash`'in sadece birkaç tane boş bayt olduğuna dikkat edin. Bu, **başlangıç bloğu** (genesis block) olarak da bilinen, zincirdeki ilk blok olduğu anlamına gelir. +- Test sağlayıcısını ne kadar süre önce yapılandırmış olursanız olun, blok numarası sıfırdır. Her 12 saniyede bir yeni blok ekleyen gerçek Ethereum ağının aksine, bu simülasyon siz ona yapacak bir iş verene kadar bekleyecektir. +- `transactions` boş bir listedir, aynı nedenle: henüz hiçbir şey yapmadık. Bu ilk blok, sadece zinciri başlatmak için kullanılan bir **boş bloktur**. +- `parentHash`'in sadece bir yığın boş bayttan ibaret olduğuna dikkat edin. Bu, zincirdeki ilk blok olduğunu ve **genesis blok** olarak da bilindiğini gösterir. -## 3. tur durağı: [işlemler](/developers/docs/transactions/) {#tour-stop-3-transactions} +## Tur durağı #3: [işlemler](/developers/docs/transactions/) {#tour-stop-3-transactions} -Bekleyen bir işlem olana kadar sıfır blokta kalacağımız için ona bir işlem verelim. Bir hesaptan diğerine birkaç test ether'ı gönderin: +Bekleyen bir işlem olana kadar sıfırıncı blokta kalacağımız için ona bir işlem verelim. Bir hesaptan diğerine birkaç test ether'ı gönderin: ```python In [10]: tx_hash = w3.eth.send_transaction({ @@ -255,9 +255,12 @@ In [10]: tx_hash = w3.eth.send_transaction({ Bu noktada genellikle işleminizin yeni bir bloğa dahil edilmesi için birkaç saniye beklersiniz. Tam süreç hemen hemen şöyle işler: -1. Bir işlem gönderin ve işlem hash değerini tutun. İşlemi içeren blok oluşturulup yayınlanıncaya kadar işlem "beklemede" kalır. `tx_hash = w3.eth.send_transaction({ … })` -2. İşlemin bir bloğa dahil edilmesini bekleyin: `w3.eth.wait_for_transaction_receipt(tx_hash)` -3. Uygulama mantığına devam edin. Başarılı işlemi görüntülemek için: `w3.eth.get_transaction(tx_hash)` +1. Bir işlem gönderin ve işlem karmasını saklayın. İşlemi içeren blok oluşturulup yayınlanıncaya kadar işlem "beklemede" kalır. + `tx_hash = w3.eth.send_transaction({ … })` +2. İşlemin bir bloğa dahil edilmesini bekleyin: + `w3.eth.wait_for_transaction_receipt(tx_hash)` +3. Uygulama mantığına devam edin. Başarılı işlemi görüntülemek için: + `w3.eth.get_transaction(tx_hash)` Simüle edilmiş ortamımız, işlemi anında yeni bir bloğa ekleyecektir, böylece işlemi hemen görebiliriz: @@ -274,7 +277,7 @@ Out[11]: AttributeDict({ }) ``` -Burada bazı tanıdık ayrıntılar göreceksiniz: `from`, `to`, ve ` value` alanları, `send_transaction` çağrımızın girdileriyle eşleşmelidir. Diğer güven verici kısım, bu işlemin 1 numaralı blok içindeki ilk işlem (`'transactionIndex': 0`) olarak dahil edilmiş olmasıdır. +Burada bazı tanıdık ayrıntılar göreceksiniz: `from`, `to` ve `value` alanları `send_transaction` çağrımızın girdileriyle eşleşmelidir. Diğer güven verici kısım ise bu işlemin 1 numaralı blok içindeki ilk işlem (`'transactionIndex': 0`) olarak dahil edilmiş olmasıdır. Ayrıca, ilgili iki hesabın bakiyelerini kontrol ederek bu işlemin başarısını kolayca doğrulayabiliriz. Üç ether, birinden diğerine geçmiş olmalıdır. @@ -286,12 +289,12 @@ In [13]: w3.eth.get_balance(w3.eth.accounts[1]) Out[13]: 1000003000000000000000000 ``` -İkincisi iyi gözüküyor! Bakiye, 1.000.000'dan 1.000.003 ether'a döndü. Peki ilk hesaba ne oldu? Üç ether'dan biraz daha fazlasını kaybetmiş görünüyor. Ne yazık ki, hayatta hiçbir şey bedava değildir ve Ethereum genel ağını kullanmak, eşlerinizi destekleyici rolleri için tazmin etmenizi gerektirir. İşlemi gönderen hesaptan küçük bir işlem ücreti kesildi - bu ücret, yakılan gaz miktarı (ETH transferi için 21000 birim gaz), ağ etkinliğine göre değişen bir taban ücret ile çarpılır ve işlemi bloğa ekleyen doğrulayıcıya giden bir bahşiş eklenerek hesaplanır. +İkincisi iyi gözüküyor! Bakiye, 1.000.000'dan 1.000.003 ether'a döndü. Peki ilk hesaba ne oldu? Üç ether'dan biraz daha fazlasını kaybetmiş görünüyor. Ne yazık ki, hayatta hiçbir şey bedava değildir ve Ethereum genel ağını kullanmak, eşlerinizi destekleyici rolleri için tazmin etmenizi gerektirir. İşlemi gönderen hesaptan küçük bir işlem ücreti kesildi. Bu ücret, yakılan gaz miktarı (bir ETH transferi için 21.000 birim gaz) ile ağ etkinliğine göre değişen bir taban ücretin çarpımına, işlemi bloğa dahil eden doğrulayıcıya giden bir bahşişin eklenmesiyle hesaplanır. [Gaz](/developers/docs/gas/#post-london) hakkında daha fazla bilgi -Not: Genel ağda işlem ücretleri, ağ talebine ve bir işlemin ne kadar hızlı işlenmesini istediğinize göre değişir. Ücretlerin nasıl hesaplandığına dair bir belge görmek istiyorasanız, işlemlerin bir bloğa nasıl dahil edildiğine ilişkin önceki gönderime göz atabilirsiniz. +Not: Genel ağda işlem ücretleri, ağ talebine ve bir işlemin ne kadar hızlı işlenmesini istediğinize göre değişir. Ücretlerin nasıl hesaplandığının ayrıntılı bir dökümüyle ilgileniyorsanız işlemlerin bir bloğa nasıl dahil edildiğiyle ilgili önceki gönderime göz atın. -## Ve derin bir nefes alın {#and-breathe} +## Biraz soluklanalım {#and-breathe} -Bir süredir bu işle uğraştığımız için şu anda biraz mola vermek iyi gelebilir. Derine dalmaya devam ediyoruz ve bu serinin ikinci bölümünde keşfe devam edeceğiz. Yakında ele alacağımız bazı kavramlar: gerçek bir düğüme bağlanma, akıllı sözleşmeler ve jetonlar. Yukarıdakilerle ilgili sorularınız mı var? Bana sorabilirsiniz! Geribildiriminiz konunun ilerleyişini etkileyecektir. [Twitter](https://twitter.com/wolovim) aracılığıyla isteklerinizi iletebilirsiniz. +Bir süredir bu işle uğraştığımız için şu anda biraz mola vermek iyi gelebilir. Derine dalmaya devam ediyoruz ve bu serinin ikinci bölümünde keşfe devam edeceğiz. Yakında ele alacağımız bazı kavramlar: gerçek bir düğüme bağlanma, akıllı sözleşmeler ve jetonlar. Yukarıdakilerle ilgili sorularınız mı var? Bana sorabilirsiniz! Geribildiriminiz konunun ilerleyişini etkileyecektir. İsteklerinizi [Twitter](https://twitter.com/wolovim) üzerinden iletebilirsiniz. diff --git a/public/content/translations/tr/developers/tutorials/all-you-can-cache/index.md b/public/content/translations/tr/developers/tutorials/all-you-can-cache/index.md index 3684fd9b77d..60bde537986 100644 --- a/public/content/translations/tr/developers/tutorials/all-you-can-cache/index.md +++ b/public/content/translations/tr/developers/tutorials/all-you-can-cache/index.md @@ -1,31 +1,28 @@ --- title: "Önbelleğe alabileceğiniz her şey" -description: Daha ucuz toplama işlemleri için önbelleğe alma sözleşmesi oluşturmayı ve kullanmayı öğrenin +description: "Daha ucuz toplama işlemleri için bir önbelleğe alma sözleşmesi oluşturmayı ve kullanmayı öğrenin" author: Ori Pomerantz -tags: - - "katman 2" - - "önbelleğe alma" - - "depolama" +tags: [ "katman 2", "önbelleğe alma", "depolama" ] skill: intermediate published: 2022-09-15 lang: tr --- -İşlemdeki bir baytın maliyeti, toplama kullanırken depolama yuvası kullanımına göre çok daha pahalıdır. Bu nedenle, zincirde mümkün olduğu kadar çok bilgiyi önbelleğe almak mantıklıdır. +Toplamaları kullanırken bir işlemdeki bir baytın maliyeti, bir depolama yuvasının maliyetinden çok daha pahalıdır. Bu nedenle, mümkün olduğunca çok bilgiyi zincir üstünde önbelleğe almak mantıklıdır. -Bu makalede, birden fazla kez kullanılması olası olan herhangi bir parametre değerinin nasıl önbelleğe alınacağını ve daha az bellek (ilk kez kullanıldıktan sonra) kullanacak şekilde nasıl kullanıma hazır hale getirileceğini öğrenecek ve ayrıca bu önbelleği kullanan zincir dışı kodu yazmayı da öğrenmiş olacaksınız. +Bu makalede, birden çok kez kullanılması muhtemel herhangi bir parametre değerinin önbelleğe alınacağı ve (ilk seferden sonra) çok daha az sayıda bayt ile kullanıma sunulacağı şekilde bir önbelleğe alma sözleşmesinin nasıl oluşturulacağını ve kullanılacağını ve bu önbelleği kullanan zincir dışı kodun nasıl yazılacağını öğreneceksiniz. -Makaleyi atlayıp doğrudan kaynak kodunu görmek istiyorsanız [buraya](https://github.com/qbzzt/20220915-all-you-can-cache) tıklayabilirsiniz. Geliştirme yığını [Foundry](https://book.getfoundry.sh/getting-started/installation)'dir. +Makaleyi atlayıp yalnızca kaynak kodunu görmek isterseniz, [buradadır](https://github.com/qbzzt/20220915-all-you-can-cache). Geliştirme yığını [Foundry](https://getfoundry.sh/introduction/installation/)'dir. ## Genel tasarım {#overall-design} -Kolay anlaşılması için tüm işlem parametrelerinin 32 bayt uzunluğunda ve `uint256` tipinde olduğunu varsayacağız. Bir işlem aldığımızda parametreleri şu şekilde ayrıştıracağız: +Basitlik adına, tüm işlem parametrelerinin `uint256` olduğunu ve 32 bayt uzunluğunda olduğunu varsayacağız. Bir işlem aldığımızda, her bir parametreyi şu şekilde ayrıştıracağız: -1. İlk bayt `0xFF` ise, sonraki 32 baytı parametre değeri olarak alın ve önbelleğe yazın. +1. İlk bayt `0xFF` ise sonraki 32 baytı bir parametre değeri olarak alın ve önbelleğe yazın. -2. İlk bayt `0xFE` ise, sonraki 32 baytı parametre değeri olarak alın ancak önbelleğe _yazmayın_. +2. İlk bayt `0xFE` ise sonraki 32 baytı bir parametre değeri olarak alın ancak önbelleğe _yazmayın_. -3. Başka herhangi bir değer için ilk dört biti ek bayt sayısı ve son dört biti önbellek anahtarının en önemli bitleri olarak alın. İşte bazı örnekler: +3. Diğer herhangi bir değer için, ilk dört biti ek bayt sayısı olarak ve son dört biti önbellek anahtarının en anlamlı bitleri olarak alın. İşte bazı örnekler: | Calldata'daki baytlar | Önbellek anahtarı | | :-------------------- | ----------------: | @@ -36,7 +33,7 @@ Kolay anlaşılması için tüm işlem parametrelerinin 32 bayt uzunluğunda ve ## Önbellek manipülasyonu {#cache-manipulation} -Önbellek [`Cache.sol`](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/Cache.sol) içinde uygulanır. Hadi satır satır inceleyelim. +Önbellek, [`Cache.sol`](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/Cache.sol) içinde uygulanmıştır. Satır satır üzerinden geçelim. ```solidity // SPDX-License-Identifier: UNLICENSED @@ -49,22 +46,22 @@ contract Cache { bytes1 public constant DONT_CACHE = 0xFE; ``` -Bu sabitler, tüm bilgileri sağladığımız ve önbelleğe yazılmasını isteyip istemediğimiz özel durumları yorumlamak için kullanılır. Önbelleğe yazdırmak için her birisine 22100 gaz ücreti ödeyerek daha önce kullanılmayan depolama yuvalarına iki [`SSTORE`](https://www.evm.codes/#55) işlemi yapılması gerekir; bu nedenle isteğe bağlı hale getiririz. +Bu sabitler, tüm bilgileri sağladığımız ve önbelleğe yazılmasını isteyip istemediğimiz özel durumları yorumlamak için kullanılır. Önbelleğe yazma, daha önce kullanılmamış depolama yuvalarına her biri 22100 gaz maliyetinde iki [`SSTORE`](https://www.evm.codes/#55) işlemi gerektirir, bu yüzden bunu isteğe bağlı hâle getiriyoruz. ```solidity mapping(uint => uint) public val2key; ``` -Değerler ile anahtarları arasında [eşleme](https://www.geeksforgeeks.org/solidity-mappings/). Bu bilgi, işlemi göndermeden önce değerleri kodlayabilmek için gereklidir. +Değerler ve anahtarları arasında bir [eşleme](https://www.geeksforgeeks.org/solidity/solidity-mappings/). Bu bilgi, işlemi göndermeden önce değerleri kodlamak için gereklidir. ```solidity - // Location n has the value for key n+1, because we need to preserve - // zero as "not in the cache". + // Konum n, n+1 anahtarının değerine sahiptir, çünkü sıfırı "önbellekte değil" olarak + // korumamız gerekir. uint[] public key2val; ``` -Anahtarları atadığımızdan anahtarlardan değerlere eşleme için bir dizi kullanabiliriz ve basitlik için bunu sırayla yaparız. +Anahtarları atadığımız için anahtarlardan değerlere eşleme için bir dizi kullanabiliriz ve basitlik adına bunu sıralı olarak yaparız. ```solidity function cacheRead(uint _key) public view returns (uint) { @@ -73,69 +70,69 @@ Anahtarları atadığımızdan anahtarlardan değerlere eşleme için bir dizi k } // cacheRead ``` -Önbellekten değer okuma. +Önbellekten bir değer okuyun. ```solidity - // Write a value to the cache if it's not there already - // Only public to enable the test to work + // Değer zaten mevcut değilse önbelleğe bir değer yazın + // Testin çalışmasını sağlamak için yalnızca public function cacheWrite(uint _value) public returns (uint) { - // If the value is already in the cache, return the current key + // Değer zaten önbellekteyse mevcut anahtarı döndürün if (val2key[_value] != 0) { return val2key[_value]; } ``` -Aynı değeri önbelleğe birden fazla kez koymanın hiçbir anlamı yoktur. Değer zaten oradaysa mevcut anahtarı döndürmeniz yeterli olur. +Aynı değeri önbelleğe birden fazla kez koymanın bir anlamı yoktur. Değer zaten oradaysa, sadece mevcut anahtarı döndürün. ```solidity - // Since 0xFE is a special case, the largest key the cache can - // hold is 0x0D followed by 15 0xFF's. If the cache length is already that - // large, fail. + // 0xFE özel bir durum olduğundan, önbelleğin tutabileceği en büyük anahtar + // 0x0D ve ardından 15 adet 0xFF'tir. Önbellek uzunluğu zaten bu kadar + // büyükse başarısız olur. // 1 2 3 4 5 6 7 8 9 A B C D E F require(key2val.length+1 < 0x0DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, - "cache overflow"); + "önbellek taşması"); ``` -Hiçbir zaman bu kadar büyük bir önbelleğe sahip olacağımızı sanmıyorum (yaklaşık 1,8\*1037 giriş, yani depolamak için 1027TB gerektirir). Aynı zamanda da ["640 kB her zaman yeterli olacaktır"](https://quoteinvestigator.com/2011/09/08/640k-enough/)lafını da hatırlayacak kadar yaşlıyım. Bu test oldukça ucuz. +Hiçbir zaman bu kadar büyük bir önbelleğe sahip olacağımızı sanmıyorum (yaklaşık 1,8\*1037 giriş, bu da depolamak için yaklaşık 1027 TB gerektirir). Ancak, ["640kB her zaman yeterli olacaktır"](https://quoteinvestigator.com/2011/09/08/640k-enough/) sözünü hatırlayacak kadar yaşlıyım. Bu test çok ucuzdur. ```solidity - // Write the value using the next key + // Değeri bir sonraki anahtarı kullanarak yazın val2key[_value] = key2val.length+1; ``` -Geriye doğru aramayı ekleyin (değerden anahtara doğru). +Ters aramayı ekleyin (değerden anahtara). ```solidity key2val.push(_value); ``` -İleriye doğru aramayı ekleyin (anahtardan değere doğru). Değerleri sırayla atadığımız için onu son dizi değerinden sonra ekleyebiliriz. +İleriye doğru aramayı ekleyin (anahtardan değere). Değerleri sıralı olarak atadığımız için onu son dizi değerinden sonra ekleyebiliriz. ```solidity return key2val.length; } // cacheWrite ``` -Yeni değerin depolandığı hücre olan `key2val`'in yeni uzunluğunu döndürün. +Yeni değerin depolandığı hücre olan `key2val` öğesinin yeni uzunluğunu döndürün. ```solidity function _calldataVal(uint startByte, uint length) private pure returns (uint) ``` -Bu işlev, isteğe bağlı uzunluktaki çağrı verisinden bir değer okur (en fazla 32 bayt, kelime boyutu). +Bu işlev, calldata'dan rastgele uzunlukta (en fazla 32 bayt, kelime boyutu) bir değer okur. ```solidity { uint _retVal; require(length < 0x21, - "_calldataVal length limit is 32 bytes"); + "_calldataVal uzunluk sınırı 32 bayttır"); require(length + startByte <= msg.data.length, - "_calldataVal trying to read beyond calldatasize"); + "_calldataVal calldatasize'ın ötesini okumaya çalışıyor"); ``` -Bu, dahili bir fonksiyondur, yani kodun geri kalanı doğru yazılırsa bu testlere ihtiyaç olmaz. Ancak pek de fazla masraflı değiller, yani yine de kullanabiliriz. +Bu işlev dahili olduğu için kodun geri kalanı doğru yazılırsa bu testler gerekli değildir. Ancak, maliyetleri çok yüksek olmadığı için kullanabiliriz. ```solidity assembly { @@ -143,56 +140,56 @@ Bu, dahili bir fonksiyondur, yani kodun geri kalanı doğru yazılırsa bu testl } ``` -Bu kod [Yul](https://docs.soliditylang.org/en/v0.8.16/yul.html)'da yazılmıştır. Çağrı verisinden 32 baytlık bir değer okur. Bu, çağrı verisi `startByte+32`'den önce dursa bile çalışır, çünkü EVM'de başlatılmamış olan bu alan 0 olarak değerlendilir. +Bu kod [Yul](https://docs.soliditylang.org/en/v0.8.16/yul.html) dilindedir. Calldata'dan 32 baytlık bir değer okur. Bu, calldata `startByte+32`'den önce dursa bile çalışır çünkü EVM'deki başlatılmamış alanın sıfır olduğu kabul edilir. ```solidity _retVal = _retVal >> (256-length*8); ``` -İlla da 32 baytlık bir değer istemiyoruz. Bu kod, fazlalık baytlardan kurtulur. +İlla ki 32 baytlık bir değer istemiyoruz. Bu, fazla baytları ortadan kaldırır. ```solidity return _retVal; } // _calldataVal - // Read a single parameter from the calldata, starting at _fromByte + // Calldata'dan _fromByte'tan başlayarak tek bir parametre okuyun function _readParam(uint _fromByte) internal returns (uint _nextByte, uint _parameterValue) { ``` -Çağrı verisinden tekli bir parametre okuyun. Sadece okuduğumuz değeri değil, ayrıca sonraki baytın da konumunu okumamız gerektiğine dikkat edin, çünkü parametrelerin uzunluğu 1 bayt ile 33 bayt arasında değişebilir. +Calldata'dan tek bir parametre okuyun. Parametreler 1 bayt ile 33 bayt arasında değişebileceğinden, yalnızca okuduğumuz değeri değil, aynı zamanda sonraki baytın konumunu da döndürmemiz gerektiğini unutmayın. ```solidity - // The first byte tells us how to interpret the rest + // İlk bayt bize gerisini nasıl yorumlayacağımızı söyler uint8 _firstByte; _firstByte = uint8(_calldataVal(_fromByte, 1)); ``` -Solidity, tehlikeli olma potansiyeli taşıyan [dahili tip dönüşümleri](https://docs.soliditylang.org/en/v0.8.16/types.html#implicit-conversions) engelleyerek hataların sayısını azaltmaya çalışır. Bir düşürme, örnek olarak 256 bitten 8 bite düşürme açık olmalıdır. +Solidity, potansiyel olarak tehlikeli [örtük tür dönüşümlerini](https://docs.soliditylang.org/en/v0.8.16/types.html#implicit-conversions) yasaklayarak hata sayısını azaltmaya çalışır. Örneğin 256 bitten 8 bite bir tür küçültme işleminin açık olması gerekir. ```solidity - // Read the value, but do not write it to the cache + // Değeri okuyun, ancak önbelleğe yazmayın if (_firstByte == uint8(DONT_CACHE)) return(_fromByte+33, _calldataVal(_fromByte+1, 32)); - // Read the value, and write it to the cache + // Değeri okuyun ve önbelleğe yazın if (_firstByte == uint8(INTO_CACHE)) { uint _param = _calldataVal(_fromByte+1, 32); cacheWrite(_param); return(_fromByte+33, _param); } - // If we got here it means that we need to read from the cache + // Buraya geldiysek, önbellekten okuma yapmamız gerektiği anlamına gelir - // Number of extra bytes to read + // Okunacak ek bayt sayısı uint8 _extraBytes = _firstByte / 16; ``` -Alt [nibble](https://en.wikipedia.org/wiki/Nibble)'ı alın ve önbellekten değeri okuyabilmek için diğer baytlarla birleştirin. +Alt [nibble](https://en.wikipedia.org/wiki/Nibble)'ı alın ve değeri önbellekten okumak için diğer baytlarla birleştirin. ```solidity uint _key = (uint256(_firstByte & 0x0F) << (8*_extraBytes)) + @@ -203,17 +200,17 @@ Alt [nibble](https://en.wikipedia.org/wiki/Nibble)'ı alın ve önbellekten değ } // _readParam - // Read n parameters (functions know how many parameters they expect) + // n parametrelerini okuyun (fonksiyonlar kaç parametre beklediklerini bilirler) function _readParams(uint _paramNum) internal returns (uint[] memory) { ``` -Sahip olduğumuz parametrelerin sayısını çağrı verisinin kendisinden de alabiliriz, fakat bize çağrı yapan fonksiyonlar ne kadar parametre beklediklerini bilmektedir. Onların bize söylemesine izin vermek daha kolaydır. +Sahip olduğumuz parametre sayısını calldata'nın kendisinden alabiliriz, ancak bizi çağıran fonksiyonlar kaç parametre beklediklerini bilir. Bize söylemelerine izin vermek daha kolaydır. ```solidity - // The parameters we read + // Okuduğumuz parametreler uint[] memory params = new uint[](_paramNum); - // Parameters start at byte 4, before that it's the function signature + // Parametreler 4. baytta başlar, ondan öncesi fonksiyon imzasıdır uint _atByte = 4; for(uint i=0; i<_paramNum; i++) { @@ -221,14 +218,14 @@ Sahip olduğumuz parametrelerin sayısını çağrı verisinin kendisinden de al } ``` -İhtiyacınız olan sayıya ulaşana kadar parametreleri okumaya devam edin. Eğer çağrı verisinin sonunun ötesine geçersek, `_readParams` aramayı eski haline döndürecektir. +İhtiyacınız olan sayıya ulaşana kadar parametreleri okuyun. Calldata'nın sonunu geçersek, `_readParams` çağrıyı geri alır. ```solidity return(params); } // readParams - // For testing _readParams, test reading four parameters + // _readParams'ı test etmek için, dört parametrenin okunmasını test edin function fourParam() public returns (uint256,uint256,uint256,uint256) { @@ -238,45 +235,45 @@ Sahip olduğumuz parametrelerin sayısını çağrı verisinin kendisinden de al } // fourParam ``` -Foundry'nin bir büyük faydası testlerin Solidity'de ([aşağıdaki Önbelleğin test edilmesi bölümüne bakın)](#testing-the-cache) yazılmasına izin vermesidir. Bu, birim testlerini çok daha kolay hale getiriyor. Bu, testin doğru olduklarını onaylayabilmesi için dört parametreyi okuyan ve döndüren bir fonksiyondur. +Foundry'nin büyük bir avantajı, testlerin Solidity'de yazılmasına izin vermesidir ([aşağıdaki Önbelleği test etme bölümüne bakın](#testing-the-cache)). Bu, birim testlerini çok daha kolaylaştırır. Bu, testin doğru olduklarını doğrulayabilmesi için dört parametreyi okuyan ve döndüren bir fonksiyondur. ```solidity - // Get a value, return bytes that will encode it (using the cache if possible) + // Bir değer alın, onu kodlayacak baytları döndürün (mümkünse önbelleği kullanarak) function encodeVal(uint _val) public view returns(bytes memory) { ``` -`encodeVal`, zincir dışı kodların önbelleği kullanan çağrı verileri oluşturmak için yardım istediklerinde çağırdığı bir fonksiyondur. Tek bir değer alır ve onu şifreleyen baytları verir. Bu fonksiyon bir `view` fonksiyonudur; bu yüzden bir işleme ihtiyaç duymaz ve harici olarak çağrıldığında hiç gaz harcamaz. +`encodeVal`, önbelleği kullanan calldata oluşturmaya yardımcı olmak için zincir dışı kodun çağırdığı bir fonksiyondur. Tek bir değer alır ve onu kodlayan baytları döndürür. Bu fonksiyon bir `view` fonksiyonudur, bu nedenle bir işlem gerektirmez ve harici olarak çağrıldığında herhangi bir gaz maliyeti yoktur. ```solidity uint _key = val2key[_val]; - // The value isn't in the cache yet, add it + // Değer henüz önbellekte değil, ekleyin if (_key == 0) return bytes.concat(INTO_CACHE, bytes32(_val)); ``` -[EVM](/developers/docs/evm/)'de, başlatılmamış her depolamanın sıfır olduğu varsayılır. Yani eğer orada olmayan bir değerin anahtarını ararsak bir sıfır alırız. Bu durumda şifrelemeyi yapan baytlar, `INTO_CACHE` şeklindedir (yani bir dahaki sefere önbelleğe alınacaktır) ve ardından asıl değer gelir. +[EVM](/developers/docs/evm/)'de tüm başlatılmamış depolamanın sıfır olduğu varsayılır. Yani, orada olmayan bir değerin anahtarını ararsak sıfır elde ederiz. Bu durumda, onu kodlayan baytlar `INTO_CACHE` (böylece bir sonraki sefere önbelleğe alınacaktır), ardından gerçek değer gelir. ```solidity - // If the key is <0x10, return it as a single byte + // Anahtar <0x10 ise tek bir bayt olarak döndürün if (_key < 0x10) return bytes.concat(bytes1(uint8(_key))); ``` -Tek baytlar en kolay olanlardır. Bir `bytes` tipini herhangi bir uzunluktaki bir bayt dizisine dönüştürmek için [`bytes.concat`](https://docs.soliditylang.org/en/v0.8.16/types.html#the-functions-bytes-concat-and-string-concat) kullanırız. İsmine rağmen, sadece bir bağımsız değişken sağlandığında bile normal bir şekilde çalışır. +Tek baytlar en kolay olanlardır. Herhangi bir uzunlukta olabilen bir `bytes` türünü bir bayt dizisine dönüştürmek için [`bytes.concat`](https://docs.soliditylang.org/en/v0.8.16/types.html#the-functions-bytes-concat-and-string-concat) kullanırız. İsmine rağmen, yalnızca bir argümanla sağlandığında gayet iyi çalışır. ```solidity - // Two byte value, encoded as 0x1vvv + // İki baytlık değer, 0x1vvv olarak kodlanmış if (_key < 0x1000) return bytes.concat(bytes2(uint16(_key) | 0x1000)); ``` -163'den daha az bir anahtarımız olduğunda, onu 2 baytta ifade edebiliriz. Önce 256 bitlik bir değer olan `_key` öğesini 16 bitlik değere çevirir ve mantık kullanırız veya ek baytların sayısını ilk bayta ekleriz. Sonra `bytes2` değerine dönüştürürüz, bu da `bytes`'a dönüştürülebilir. +163'ten küçük bir anahtarımız olduğunda, bunu iki baytla ifade edebiliriz. Önce 256 bitlik bir değer olan `_key`'i 16 bitlik bir değere dönüştürürüz ve ilk bayta ek bayt sayısını eklemek için mantıksal veya kullanırız. Sonra onu, `bytes`'a dönüştürülebilen bir `bytes2` değerine dönüştürürüz. ```solidity - // There is probably a clever way to do the following lines as a loop, - // but it's a view function so I'm optimizing for programmer time and - // simplicity. + // Muhtemelen aşağıdaki satırları bir döngü olarak yapmanın zekice bir yolu vardır, + // ancak bu bir view fonksiyonu olduğundan programcı zamanı ve + // basitlik için optimize ediyorum. if (_key < 16*256**2) return bytes.concat(bytes3(uint24(_key) | (0x2 * 16 * 256**2))); @@ -291,14 +288,14 @@ Tek baytlar en kolay olanlardır. Bir `bytes` tipini herhangi bir uzunluktaki return bytes.concat(bytes16(uint128(_key) | (0xF * 16 * 256**15))); ``` -Diğer değerler (3 bayt, 4 bayt, vs.) aynı şekilde, fakat farklı alan boyutlarıyla işlenir. +Diğer değerler (3 bayt, 4 bayt vb.) farklı alan boyutlarıyla aynı şekilde ele alınır. ```solidity - // If we get here, something is wrong. - revert("Error in encodeVal, should not happen"); + // Buraya gelirsek, bir şeyler yanlış demektir. + revert("encodeVal'da hata, olmamalıydı"); ``` -Eğer buraya geldiysek, 16\*25615'ten az olmayan bir anahtar aldık demektir. Fakat `cacheWrite` anahtarları sınırlar, bu yüzden 14\*25616'ya bile çıkamayız (bunun da bir 0xFE tarzında bir ilk baytı olurdu, yani `DONT_CACHE` gibi görünürdü). Fakat ilerde bir programcı girip de bir hata tanımlar diye bir test yapmak bize pek de pahalıya patlamaz. +Buraya gelirsek, 16\*25615'ten küçük olmayan bir anahtar aldığımız anlamına gelir. Ancak `cacheWrite` anahtarları sınırlar, bu yüzden 14\*25616'ya bile ulaşamayız (bunun ilk baytı 0xFE olurdu, yani `DONT_CACHE` gibi görünürdü). Ancak gelecekteki bir programcının bir hata eklemesi durumunda bir test eklemek bize çok pahalıya mal olmaz. ```solidity } // encodeVal @@ -308,7 +305,7 @@ Eğer buraya geldiysek, 16\*25615'ten az olmayan bir anahtar aldık d ### Önbelleği test etme {#testing-the-cache} -Foundry'nin faydalarından biri de, testleri [testleri Solidity'de yazmanıza izin vermesidir](https://book.getfoundry.sh/forge/tests), bu sayede birim testi yazma kolaylaşır. `Cache` sınıfı için olan testler [buradadır](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/test/Cache.t.sol). Test kodu, testlerin kendileri de bu eğilimde olduğu gibi kendini tekrar eden bir konu olduğu için bu belge sadece ilgi çekici kısımları anlatacaktır. +Foundry'nin avantajlarından biri, [testleri Solidity'de yazmanıza izin vermesidir](https://getfoundry.sh/forge/tests/overview/), bu da birim testleri yazmayı kolaylaştırır. `Cache` sınıfının testleri [buradadır](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/test/Cache.t.sol). Test kodu, testlerin olma eğiliminde olduğu gibi tekrarlayıcı olduğundan, bu makale yalnızca ilginç kısımları açıklamaktadır. ```solidity // SPDX-License-Identifier: UNLICENSED @@ -317,17 +314,17 @@ pragma solidity ^0.8.13; import "forge-std/Test.sol"; -// Need to run `forge test -vv` for the console. +// Konsol için `forge test -vv` komutunu çalıştırmanız gerekir. import "forge-std/console.sol"; ``` -Bu, sadece test paketini ve `console.log`'u kullanmak için gerekli bir standarttır. +Bu, sadece test paketini ve `console.log`'u kullanmak için gerekli olan standart bir koddur. ```solidity import "src/Cache.sol"; ``` -Test ettiğimiz sözleşmeyi bilmemiz gerekir. +Test ettiğimiz sözleşmeyi bilmemiz gerekiyor. ```solidity contract CacheTest is Test { @@ -338,13 +335,13 @@ contract CacheTest is Test { } ``` -`setUp` fonksiyonu her testten önce çağrılır. Bu durumda sadece yeni bir önbellek oluşturacağız ki, testlerimiz birbirini etkilemesin. +`setUp` fonksiyonu her testten önce çağrılır. Bu durumda sadece yeni bir önbellek oluştururuz, böylece testlerimiz birbirini etkilemez. ```solidity function testCaching() public { ``` -Testler, adları `test` ile başlayan fonksiyonlardır. Bu fonksiyon, değerler yazarak ve onları tekrar okuyarak temel önbellek işlevselliğini kontrol eder. +Testler, adları `test` ile başlayan fonksiyonlardır. Bu fonksiyon, değerleri yazıp tekrar okuyarak temel önbellek işlevselliğini kontrol eder. ```solidity for(uint i=1; i<5000; i++) { @@ -355,15 +352,15 @@ Testler, adları `test` ile başlayan fonksiyonlardır. Bu fonksiyon, değerler assertEq(cache.cacheRead(i), i*i); ``` -[`assert...` fonksiyonları](https://book.getfoundry.sh/reference/forge-std/std-assertions) kullanarak asıl testi işte böyle yaparsınız. Bu durumda, yazdığımız değerin okuduğumuz değer olduğunu doğrularız. `cache.cacheWrite` sonucunu atabiliriz, çünkü önbellek anahtarlarının doğrusal olarak atandığını biliyoruz. +Gerçek testi [`assert...` fonksiyonlarını](https://getfoundry.sh/reference/forge-std/std-assertions/) kullanarak bu şekilde yaparsınız. Bu durumda, yazdığımız değerin okuduğumuz değer olduğunu kontrol ederiz. `cache.cacheWrite` sonucunu atabiliriz çünkü önbellek anahtarlarının doğrusal olarak atandığını biliyoruz. ```solidity } } // testCaching - // Cache the same value multiple times, ensure that the key stays - // the same + // Aynı değeri birden çok kez önbelleğe alın, anahtarın aynı + // kaldığından emin olun function testRepeatCaching() public { for(uint i=1; i<100; i++) { uint _key1 = cache.cacheWrite(i); @@ -372,7 +369,7 @@ Testler, adları `test` ile başlayan fonksiyonlardır. Bu fonksiyon, değerler } ``` -Önce, her bir değeri önbelleğe yazarız ve anahtarların aynı olduğundan emin oluruz (ikinci yazmanın gerçekleşmediği anlamına gelir). +Önce her değeri önbelleğe iki kez yazarız ve anahtarların aynı olduğundan emin oluruz (yani ikinci yazma işlemi gerçekten gerçekleşmemiştir). ```solidity for(uint i=1; i<100; i+=3) { @@ -382,20 +379,20 @@ Testler, adları `test` ile başlayan fonksiyonlardır. Bu fonksiyon, değerler } // testRepeatCaching ``` -Teoride, ardışık önbellek yazılarını etkilemeyen bir hata mevcut olabilir. Bu yüzden ardışık olmayan bazı yazılar yazacağız ve değerlerin hala yeniden yazılmamış olup olmadığını göreceğiz. +Teoride, ardışık önbellek yazımlarını etkilemeyen bir hata olabilir. Bu yüzden burada ardışık olmayan bazı yazımlar yapıyoruz ve değerlerin hala yeniden yazılmadığını görüyoruz. ```solidity - // Read a uint from a memory buffer (to make sure we get back the parameters - // we sent out) + // Bir bellek arabelleğinden bir uint okuyun (gönderdiğimiz parametreleri + // geri aldığımızdan emin olmak için) function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) ``` -Bir `bytes memory` arabelleğinden 256 bitlik bir kelime okuyun. Bu yardımcı fonksiyon, önbelleği kullanan bir fonksiyon çağrısı yaptığımızda doğru sonuçları aldığımızı onaylamamızı sağlar. +`bytes memory` arabelleğinden 256 bitlik bir kelime okuyun. Bu yardımcı fonksiyon, önbelleği kullanan bir fonksiyon çağrısı çalıştırdığımızda doğru sonuçları aldığımızı doğrulamamızı sağlar. ```solidity { - require(_bytes.length >= _start + 32, "toUint256_outOfBounds"); + require(_bytes.length >= _start + 32, "toUint256_sınır_dışı"); uint256 tempUint; assembly { @@ -403,31 +400,31 @@ Bir `bytes memory` arabelleğinden 256 bitlik bir kelime okuyun. Bu yardımcı f } ``` -Yul `uint256` öğesinin ötesindeki veri yapılarını desteklemez; yani `_bytes` bellek arabelleği gibi daha sofistike bir veri yapısına başvurduğunuzda o yapının adresini alırsınız. Solidity `bytes memory` değerlerini uzunluğu içeren 32 baytlık bir kelime olarak depolar. Ardından asıl baytlar gelir, yani bayt numarasını `_start` almak için `_bytes+32+_start` değerini hesaplamamız gerekir. +Yul, `uint256`'nın ötesindeki veri yapılarını desteklemez, bu nedenle `_bytes` bellek arabelleği gibi daha karmaşık bir veri yapısına atıfta bulunduğunuzda, o yapının adresini alırsınız. Solidity, `bytes memory` değerlerini uzunluğu içeren 32 baytlık bir kelime olarak ve ardından gerçek baytları depolar, bu nedenle `_start` bayt numarasını almak için `_bytes+32+_start`'ı hesaplamamız gerekir. ```solidity return tempUint; } // toUint256 - // Function signature for fourParams(), courtesy of - // https://www.4byte.directory/signatures/?bytes4_signature=0x3edc1e6d + // fourParams() için fonksiyon imzası, + // https://www.4byte.directory/signatures/?bytes4_signature=0x3edc1e6d izniyle bytes4 constant FOUR_PARAMS = 0x3edc1e6d; - // Just some constant values to see we're getting the correct values back + // Doğru değerleri geri aldığımızı görmek için sadece bazı sabit değerler uint256 constant VAL_A = 0xDEAD60A7; uint256 constant VAL_B = 0xBEEF; uint256 constant VAL_C = 0x600D; uint256 constant VAL_D = 0x600D60A7; ``` -Test için ihtiyacımız olan bazı sabit değerler. +Test için ihtiyacımız olan bazı sabitler. ```solidity function testReadParam() public { ``` -`fourParams()` çağrısı, parametreleri doğru okuyabilmemiz için `readParams`'ı kullanan bir fonksiyondur. +Parametreleri doğru bir şekilde okuyabildiğimizi test etmek için `readParams` kullanan bir fonksiyon olan `fourParams()`'ı çağırın. ```solidity address _cacheAddr = address(cache); @@ -436,23 +433,23 @@ Test için ihtiyacımız olan bazı sabit değerler. bytes memory _callOutput; ``` -Önbelleği kullanan bir fonksiyonu çağırmak için normal ABI mekanizmasını kullanamayız, bu yüzden düşük seviye olan [`
.call()`](https://docs.soliditylang.org/en/v0.8.16/types.html#members-of-addresses) mekanizmasını kullanmamız gerekir. Bu mekanizma `bytes memory`'yi girdi olarak alır ve çıktı olarak (bir Boole değeri ile birlikte) verir. +Önbelleği kullanarak bir fonksiyon çağırmak için normal ABI mekanizmasını kullanamayız, bu yüzden düşük seviyeli [`
.call()`](https://docs.soliditylang.org/en/v0.8.16/types.html#members-of-addresses) mekanizmasını kullanmamız gerekir. Bu mekanizma, girdi olarak bir `bytes memory` alır ve bunu (bir Boole değeri ile birlikte) çıktı olarak döndürür. ```solidity - // First call, the cache is empty + // İlk çağrı, önbellek boş _callInput = bytes.concat( FOUR_PARAMS, ``` -Aynı sözleşmenin hem önbelleklenmiş fonksiyonları (işlemlerden doğrudan gelen çağrılar için) hem de önbelleklenmemiş fonksiyonları (diğer akıllı sözleşmelerden gelen çağrılar için) desteklemesi kullanışlıdır. Bunu yapabilmek için Solidity mekanizmasının her şeyi [a `fallback` fonksiyonuna](https://docs.soliditylang.org/en/v0.8.16/contracts.html#fallback-function) koymasının yerine doğru fonksiyonu çağıracağına güvenmeye devam etmemiz gerekir. Bunu yapmak, birleştirilebilirliği çok daha kolay hale getirir. Fonksiyonu tanımlamak için çoğu durumda tek bir bayt yeterlidir, yani üç baytı (16\*3=48 gaz) boşa harcıyoruz. Bununla birlikte, ben bunu yazarken 48 gaz 0,07 sent ediyor, bu da daha basit, daha az hataya yatkın bir kod için makul bir ücrettir. +Aynı sözleşmenin hem önbelleğe alınmış fonksiyonları (doğrudan işlemlerden gelen çağrılar için) hem de önbelleğe alınmamış fonksiyonları (diğer akıllı sözleşmelerden gelen çağrılar için) desteklemesi kullanışlıdır. Bunu yapmak için, her şeyi [bir `fallback` fonksiyonuna](https://docs.soliditylang.org/en/v0.8.16/contracts.html#fallback-function) koymak yerine doğru fonksiyonu çağırmak için Solidity mekanizmasına güvenmeye devam etmemiz gerekir. Bunu yapmak birleştirilebilirliği çok daha kolaylaştırır. Çoğu durumda fonksiyonu tanımlamak için tek bir bayt yeterli olacaktır, bu yüzden üç bayt (16\*3=48 gaz) israf ediyoruz. Ancak, ben bunu yazarken bu 48 gazın maliyeti 0,07 sent, bu da daha basit, daha az hataya açık kod için makul bir maliyettir. ```solidity - // First value, add it to the cache + // İlk değer, önbelleğe ekleyin cache.INTO_CACHE(), bytes32(VAL_A), ``` -İlk değer: Önbelleğe yazılması gerekenin tam bir değer olduğunu söyleyen bir işaret ve ardından gelen değerin 32 baytlık kısmı. `VAL_B`'ın önbelleğe yazılmaması ve `VAL_C`'nin hem üçüncü hem de dördüncü parametre olması dışında diğer üç değer benzerdir. +İlk değer: Önbelleğe yazılması gereken tam bir değer olduğunu söyleyen bir bayrak, ardından değerin 32 baytı. Diğer üç değer benzerdir, ancak `VAL_B` önbelleğe yazılmaz ve `VAL_C` hem üçüncü hem de dördüncü parametredir. ```solidity . @@ -462,20 +459,20 @@ Aynı sözleşmenin hem önbelleklenmiş fonksiyonları (işlemlerden doğrudan (_success, _callOutput) = _cacheAddr.call(_callInput); ``` -Burası, `Cache` sözleşmesini asıl çağıracağımız yerdir. +Burası `Cache` sözleşmesini gerçekten çağırdığımız yerdir. ```solidity assertEq(_success, true); ``` -Çağrının başarılı olmasını umuyoruz. +Çağrının başarılı olmasını bekliyoruz. ```solidity assertEq(cache.cacheRead(1), VAL_A); assertEq(cache.cacheRead(2), VAL_C); ``` -Boş bir önbellekle başlıyor ve ardından `VAL_A` ile `VAL_C` öğelerini ekliyoruz. Birincinin anahtar 1'e, ikincinin de anahtar 2'ye sahip olmasını bekleriz. +Boş bir önbellekle başlarız ve ardından `VAL_A`'yı ve sonrasında `VAL_C`'yi ekleriz. Birincisinin anahtarının 1, ikincisinin ise 2 olmasını bekleriz. ``` assertEq(toUint256(_callOutput,0), VAL_A); @@ -484,25 +481,25 @@ Boş bir önbellekle başlıyor ve ardından `VAL_A` ile `VAL_C` öğelerini ekl assertEq(toUint256(_callOutput,96), VAL_C); ``` -Çıktımız, o 4 parametredir. Burada doğru olduğunu onaylıyoruz. +Çıktı dört parametredir. Burada doğru olduğunu doğruluyoruz. ```solidity - // Second call, we can use the cache + // İkinci çağrı, önbelleği kullanabiliriz _callInput = bytes.concat( FOUR_PARAMS, - // First value in the Cache + // Önbellekteki ilk değer bytes1(0x01), ``` -16'nın altında olan önbellek anahtarları sadece bir bayttır. +16'nın altındaki önbellek anahtarları yalnızca bir bayttır. ```solidity - // Second value, don't add it to the cache + // İkinci değer, önbelleğe eklemeyin cache.DONT_CACHE(), bytes32(VAL_B), - // Third and fourth values, same value + // Üçüncü ve dördüncü değerler, aynı değer bytes1(0x02), bytes1(0x02) ); @@ -512,13 +509,13 @@ Boş bir önbellekle başlıyor ve ardından `VAL_A` ile `VAL_C` öğelerini ekl } // testReadParam ``` -Çağrıdan sonra yapılan testler, ilk çağrıdan sonra yapılanlarla aynı. +Çağrıdan sonraki testler, ilk çağrıdan sonrakilerle aynıdır. ```solidity function testEncodeVal() public { ``` -Bu fonksiyon, `testReadParam` ile benzerdir, parametreleri doğrudan yazmak için `encodeVal()` kullanıyor olmamız dışında. +Bu fonksiyon, `testReadParam`'a benzer, ancak parametreleri açıkça yazmak yerine `encodeVal()` kullanırız. ```solidity . @@ -538,23 +535,23 @@ Bu fonksiyon, `testReadParam` ile benzerdir, parametreleri doğrudan yazmak içi } // testEncodeVal ``` -`testEncodeVal()`'deki tek ekstra test, `_callInput`'un uzunluğunun doğruluğunu onaylamaktır. İlk çağrı için bu değer 4+33\*4'tür. İkinci için ise, zaten tüm değerler önbellekte olduğundan 4+1\*4 şeklindedir. +`testEncodeVal()`'daki tek ek test, `_callInput`'un uzunluğunun doğru olduğunu doğrulamaktır. İlk arama için 4+33\*4'tür. İkincisi için, her değerin zaten önbellekte olduğu durumda, 4+1\*4'tür. ```solidity - // Test encodeVal when the key is more than a single byte - // Maximum three bytes because filling the cache to four bytes takes - // too long. + // Anahtarın tek bir bayttan fazla olduğu durumlarda encodeVal'ı test edin + // Önbelleği dört bayta kadar doldurmak çok uzun sürdüğü için + // en fazla üç bayt. function testEncodeValBig() public { - // Put a number of values in the cache. - // To keep things simple, use key n for value n. + // Önbelleğe bir dizi değer koyun. + // İşleri basit tutmak için, n değeri için n anahtarını kullanın. for(uint i=1; i<0x1FFF; i++) { cache.cacheWrite(i); } ``` -Yukarıdaki `testEncodeVal` fonksiyonu, önbelleğe sadece 4 değer yazarr, bu yüzden [fonksiyonun çoklu bayt değerleriyle ilgilenen kısımları](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/Cache.sol#L144-L171) kontrol edilmez. Fakat o kod karışık ve hataya açıktır. +Yukarıdaki `testEncodeVal` fonksiyonu önbelleğe yalnızca dört değer yazar, bu nedenle [fonksiyonun çok baytlı değerlerle ilgilenen kısmı](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/Cache.sol#L144-L171) kontrol edilmez. Ancak bu kod karmaşık ve hataya açıktır. -Bu fonksiyonun ilk kısmı, önbelleğe 1 ila 0x1FFF değerlerini sırayla yazan bir döngüdür, bu sayede bu değerleri şifreleyebilecek ve nereye gittiklerini bilebileceğiz. +Bu fonksiyonun ilk kısmı, 1'den 0x1FFF'ye kadar olan tüm değerleri sırayla önbelleğe yazan bir döngüdür, böylece bu değerleri kodlayabilir ve nereye gittiklerini bilebiliriz. ```solidity . @@ -563,14 +560,14 @@ Bu fonksiyonun ilk kısmı, önbelleğe 1 ila 0x1FFF değerlerini sırayla yazan _callInput = bytes.concat( FOUR_PARAMS, - cache.encodeVal(0x000F), // One byte 0x0F - cache.encodeVal(0x0010), // Two bytes 0x1010 - cache.encodeVal(0x0100), // Two bytes 0x1100 - cache.encodeVal(0x1000) // Three bytes 0x201000 + cache.encodeVal(0x000F), // Bir bayt 0x0F + cache.encodeVal(0x0010), // İki bayt 0x1010 + cache.encodeVal(0x0100), // İki bayt 0x1100 + cache.encodeVal(0x1000) // Üç bayt 0x201000 ); ``` -Bir bayt, iki bayt ve üç bayt değerlerini test edin. Yeterli yığın girdisini yazmak çok uzun süreceğinden (en az 0x10000000, yaklaşık olarak bir milyarın çeyreği) bunun ötesinde test yapmıyoruz. +Bir bayt, iki bayt ve üç baytlık değerleri test edin. Yeterli yığın girdisi yazmak çok uzun süreceğinden (en az 0x10000000, yaklaşık olarak çeyrek milyar) bunun ötesinde test yapmıyoruz. ```solidity . @@ -580,11 +577,11 @@ Bir bayt, iki bayt ve üç bayt değerlerini test edin. Yeterli yığın girdisi } // testEncodeValBig - // Test what with an excessively small buffer we get a revert + // Aşırı küçük bir arabellekle bir geri alma elde ettiğimizi test edin function testShortCalldata() public { ``` -Yeterli parametrenin olmadığı anormal durumda ne olduğunu test edin. +Yeterli parametre olmadığında anormal durumda ne olduğunu test edin. ```solidity . @@ -595,10 +592,10 @@ Yeterli parametrenin olmadığı anormal durumda ne olduğunu test edin. } // testShortCalldata ``` -Döndüğü için alacağımız sonuç `false` olmalıdır. +Geri döndüğü için alacağımız sonuç `false` olmalıdır. ``` - // Call with cache keys that aren't there + // Orada olmayan önbellek anahtarlarıyla çağrı yapın function testNoCacheKey() public { . . @@ -606,52 +603,52 @@ Döndüğü için alacağımız sonuç `false` olmalıdır. _callInput = bytes.concat( FOUR_PARAMS, - // First value, add it to the cache + // İlk değer, önbelleğe ekleyin cache.INTO_CACHE(), bytes32(VAL_A), - // Second value + // İkinci değer bytes1(0x0F), bytes2(0x1234), bytes11(0xA10102030405060708090A) ); ``` -Bu fonksiyon tamamen meşru dört parametre alır, önbelleğin boş olması sebebiyle okuyacak hiçbir değer olmaması dışında. +Bu fonksiyon dört tamamen meşru parametre alır, ancak önbellek boştur, bu nedenle okunacak değer yoktur. ```solidity . . . - // Test what with an excessively long buffer everything works file + // Aşırı uzun bir arabellekle her şeyin çalıştığını test edin function testLongCalldata() public { address _cacheAddr = address(cache); bool _success; bytes memory _callInput; bytes memory _callOutput; - // First call, the cache is empty + // İlk çağrı, önbellek boş _callInput = bytes.concat( FOUR_PARAMS, - // First value, add it to the cache + // İlk değer, önbelleğe ekleyin cache.INTO_CACHE(), bytes32(VAL_A), - // Second value, add it to the cache + // İkinci değer, önbelleğe ekleyin cache.INTO_CACHE(), bytes32(VAL_B), - // Third value, add it to the cache + // Üçüncü değer, önbelleğe ekleyin cache.INTO_CACHE(), bytes32(VAL_C), - // Fourth value, add it to the cache + // Dördüncü değer, önbelleğe ekleyin cache.INTO_CACHE(), bytes32(VAL_D), - // And another value for "good luck" + // Ve "iyi şans" için başka bir değer bytes4(0x31112233) ); ``` -Bu fonksiyon, 5 değer gönderir. Beşinci değerin görmezden gelindiğini biliyoruz çünkü geçerli bir önbellek girdisi değildir ve dahil edilmemiş olsa geri dönme surumuna neden olurdu. +Bu fonksiyon beş değer gönderir. Beşinci değerin, geçerli bir önbellek girişi olmadığı için yoksayıldığını biliyoruz; dahil edilmeseydi geri dönmeye neden olurdu. ```solidity (_success, _callOutput) = _cacheAddr.call(_callInput); @@ -665,13 +662,13 @@ Bu fonksiyon, 5 değer gönderir. Beşinci değerin görmezden gelindiğini bili ``` -## Bir örnek uygulama {#a-sample-app} +## Örnek bir uygulama {#a-sample-app} -Solidity'de test yazmak çok güzeldir fakat günün sonunda bir merkeziyetsiz uygulamanın kullanışlı olabilmesi için zincirin dışından talepleri işleyebilmesi gerekir. Bu belge "Bir Kez Yaz, Çok Kez Oku" anlamına gelen `WORM` ile bir merkeziyetsiz uygulamada önbelleğe almanın nasıl kullanacağını gösterir. Eğer bir anahtar henüz yazılmamışsa, ona bir değer yazabilirsiniz. Eğer anahtar çoktan yazılmışsa, bir geri dönüş alırsınız. +Solidity'de test yazmak çok iyidir, ancak günün sonunda bir merkeziyetsiz uygulamanın kullanışlı olması için zincir dışından gelen istekleri işleyebilmesi gerekir. Bu makale, "Bir Kez Yaz, Çok Kez Oku" anlamına gelen WORM ile bir merkeziyetsiz uygulamada önbelleğe almanın nasıl kullanılacağını göstermektedir. Bir anahtar henüz yazılmamışsa, ona bir değer yazabilirsiniz. Anahtar zaten yazılmışsa, bir geri alma alırsınız. ### Sözleşme {#the-contract} -[Sözleşme budur](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/WORM.sol). Genel olarak `Cache` ve `CacheTest` ile çoktan yapmış olduğumuz şeyleri tekrar ediyor olduğu için sadece ilgi çekici olan kısımları ele alacağız. +[Bu sözleşmedir](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/WORM.sol). Çoğunlukla `Cache` ve `CacheTest` ile zaten yaptıklarımızı tekrarlar, bu yüzden sadece ilginç olan kısımları ele alacağız. ```solidity import "./Cache.sol"; @@ -679,7 +676,7 @@ import "./Cache.sol"; contract WORM is Cache { ``` -`Cache`'i kullanmanın en kolay yolu, onu kendi sözleşmemize aktarmaktır. +`Cache` kullanmanın en kolay yolu, onu kendi sözleşmemize miras almaktır. ```solidity function writeEntryCached() external { @@ -688,59 +685,59 @@ contract WORM is Cache { } // writeEntryCached ``` -Bu fonksiyon, yukarıdaki `CacheTest`'in içindeki `fourParam`'a benzer. ABI spesifikasyonlarına uymadığımız için bu fonksiyonun içine herhangi bir parametre beyan etmememiz en iyisidir. +Bu fonksiyon, yukarıdaki `CacheTest`'teki `fourParam`'a benzer. ABI spesifikasyonlarını takip etmediğimiz için, fonksiyona herhangi bir parametre bildirmemek en iyisidir. ```solidity - // Make it easier to call us - // Function signature for writeEntryCached(), courtesy of - // https://www.4byte.directory/signatures/?bytes4_signature=0xe4e4f2d3 + // Bizi çağırmayı kolaylaştırın + // writeEntryCached() için Fonksiyon İmzası, + // https://www.4byte.directory/signatures/?bytes4_signature=0xe4e4f2d3 izniyle bytes4 constant public WRITE_ENTRY_CACHED = 0xe4e4f2d3; ``` -ABI spesifikasyonlarına uymadığımız için `writeEntryCached` öğesini çağıran harici kodun çağrı verisini `worm.writeEntryCached` kullanmak yerine manuel olarak yazması gerekecektir. Bu sabit değere sahip olmak yazmayı kolaylaştırıyor. +`writeEntryCached`'i çağıran harici kodun, ABI spesifikasyonlarına uymadığımız için `worm.writeEntryCached`'i kullanmak yerine calldata'yı manuel olarak oluşturması gerekecektir. Bu sabit değere sahip olmak sadece yazmayı kolaylaştırır. -`WRITE_ENTRY_CACHED` değerini bir durum değişkeni olarak tanımlamış olsak da, bunu harici olarak okuyabilmek için `worm.WRITE_ENTRY_CACHED()` getter fonksiyonunu kullanmanın gerekli olduğunu da not edin. +`WRITE_ENTRY_CACHED`'i bir durum değişkeni olarak tanımlasak da, harici olarak okumak için onun alıcı fonksiyonu olan `worm.WRITE_ENTRY_CACHED()`'i kullanmak gerektiğini unutmayın. ```solidity function readEntry(uint key) public view returns (uint _value, address _writtenBy, uint _writtenAtBlock) ``` -Okuma fonksiyonu bir `view`'dır, yani bir işleme ihtiyaç duymaz ve gaz harcamaz. Sonuç olarak, parametre için önbelleği kullanmanın bir faydası yoktur. Görünüm fonksiyonlarında daha basit olan standart mekanizmayı kullanmak en iyisidir. +Okuma fonksiyonu bir `view` fonksiyonudur, bu nedenle bir işlem gerektirmez ve gaz maliyeti yoktur. Sonuç olarak, parametre için önbelleği kullanmanın bir faydası yoktur. View fonksiyonlarında daha basit olan standart mekanizmayı kullanmak en iyisidir. ### Test kodu {#the-testing-code} -[ Bu, sözleşmenin test kodudur](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/test/WORM.t.sol). Yine sadece ilgi çekici olan kısma bakalım. +[Bu, sözleşmenin test kodudur](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/test/WORM.t.sol). Yine, sadece ilginç olanlara bakalım. ```solidity function testWReadWrite() public { worm.writeEntry(0xDEAD, 0x60A7); - vm.expectRevert(bytes("entry already written")); + vm.expectRevert(bytes("giriş zaten yazılmış")); worm.writeEntry(0xDEAD, 0xBEEF); ``` -[Bu (`vm.expectRevert`)](https://book.getfoundry.sh/cheatcodes/expect-revert#expectrevert), yeni çağrının başarısız olması gerektiğini ve bunun için belirtilen sebebi Foundry'de belirtme şeklimizdir. Bu, çağrı verisini oluşturup düşük seviye (`.call()`, vs.) arayüz kullanarak sözleşmeyi çağırmak yerine `.()` söz dizimini kullandığımız durumlarda geçerli olur. +[Bu (`vm.expectRevert`)](https://book.getfoundry.sh/cheatcodes/expect-revert#expectrevert), bir Foundry testinde bir sonraki çağrının başarısız olması gerektiğini ve başarısızlık için bildirilen nedeni bu şekilde belirtiriz. Bu, `.() sözdizimini, calldata'yı oluşturup sözleşmeyi düşük seviyeli arayüzü (`.call()`, vb.) kullanarak çağırmak yerine kullandığımızda geçerlidir. ```solidity function testReadWriteCached() public { uint cacheGoat = worm.cacheWrite(0x60A7); ``` -Burada `cacheWrite`'ın önbellek anahtarını döndürmesi gerçeğinden faydalanıyoruz. Bu, oluşturma sürecinde kullanmayı beklediğimiz bir şey değil, çünkü `cacheWrite` durum değiştirir ve bu yüzden sadece bir işlem sırasında çağrılabilir. İşlemlerin dönüş değerleri yoktur, eğer sonuçları olursa bu sonuçların olaylar olarak ifade edilmiş olmaları gerekir. Yani `cacheWrite` dönüş değerine sadece zincir üstü kod tarafından erişilebilir ve zincir üstü kod, parametre önbelleğe alımını desteklemez. +Burada `cacheWrite`'ın önbellek anahtarını döndürmesi gerçeğini kullanıyoruz. Bu, üretimde kullanmayı bekleyeceğimiz bir şey değildir, çünkü `cacheWrite` durumu değiştirir ve bu nedenle yalnızca bir işlem sırasında çağrılabilir. İşlemlerin dönüş değerleri yoktur, eğer sonuçları varsa bu sonuçların olaylar olarak yayınlanması gerekir. Bu nedenle `cacheWrite` dönüş değerine yalnızca zincir üstü koddan erişilebilir ve zincir üstü kodun parametre önbelleğe almasına gerek yoktur. ```solidity (_success,) = address(worm).call(_callInput); ``` -`.call()`'un iki değeri varken sadece ilk değeri önemsediğimizi Solidity'ye bu şekilde ifade ederiz. +Bu, Solidity'ye `.call()`'un iki dönüş değeri olmasına rağmen, yalnızca ilkiyle ilgilendiğimizi söyleme şeklimizdir. ```solidity (_success,) = address(worm).call(_callInput); assertEq(_success, false); ``` -Düşük seviye `
.call()` fonksiyonunu kullanmamız sebebiyle, `vm.expectRevert()`'ü kullanamayız ve çağrıdan alacağımız boole başarı değerine bakmamız gerekir. +Düşük seviyeli `.call()` fonksiyonunu kullandığımız için, `vm.expectRevert()`'i kullanamayız ve çağrıdan aldığımız boole başarı değerine bakmak zorundayız. ```solidity event EntryWritten(uint indexed key, uint indexed value); @@ -756,13 +753,13 @@ Düşük seviye `
.call()` fonksiyonunu kullanmamız sebebiyle, `vm.expe (_success,) = address(worm).call(_callInput); ``` -Kodun Foundry'de [bir olayı doğru ifade ettiğini](https://book.getfoundry.sh/cheatcodes/expect-emit) bu şekilde doğrularız. +Bu, Foundry'de kodun [bir olayı doğru şekilde yaydığını](https://getfoundry.sh/reference/cheatcodes/expect-emit/) doğrulama şeklimizdir. ### İstemci {#the-client} -Solidity testleriyle sahip olamayacağınız tek şey, kendi uygulamanıza kesip yapıştırabileceğiniz JavaScript kodudur. O kodu yazmak için [Optimism'in](https://www.optimism.io/) yeni test ağı olan [Optimism Goerli](https://community.optimism.io/docs/useful-tools/networks/#optimism-goerli)'ye WORM dağıttım. [`0xd34335b1d818cee54e3323d3246bd31d94e6a78a`](https://goerli-optimism.etherscan.io/address/0xd34335b1d818cee54e3323d3246bd31d94e6a78a) adresindedir. +Solidity testleriyle elde edemeyeceğiniz bir şey, kendi uygulamanıza kesip yapıştırabileceğiniz JavaScript kodudur. Bu kodu yazmak için WORM'u [Optimism'in](https://www.optimism.io/) yeni test ağı olan [Optimism Goerli](https://community.optimism.io/docs/useful-tools/networks/#optimism-goerli)'ye dağıttım. Adresi [`0xd34335b1d818cee54e3323d3246bd31d94e6a78a`](https://goerli-optimism.etherscan.io/address/0xd34335b1d818cee54e3323d3246bd31d94e6a78a)'dır. -[İstemcinin Javascript kodunu burada görebilirsiniz](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/javascript/index.js). Kullanmak için: +[İstemci için JavaScript kodunu burada görebilirsiniz](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/javascript/index.js). Kullanmak için: 1. Git deposunu klonlayın: @@ -777,28 +774,28 @@ Solidity testleriyle sahip olamayacağınız tek şey, kendi uygulamanıza kesip yarn ``` -3. Kurulum dosyasını kopyalayın: +3. Yapılandırma dosyasını kopyalayın: ```sh cp .env.example .env ``` -4. Kurulumunuz için `.env`'i düzenleyin: +4. Yapılandırmanız için `.env` dosyasını düzenleyin: - | Parametre | Değer | - | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - | MNEMONIC-ANIMSATICI | Bir işleme ödeyebilmek için yeterli ETH bulunduran bir hesap için bir anımsatıcı. [You can get free ETH for the Optimism Goerli ağı için bedava ETH'yi buradan alabilirsiniz](https://optimismfaucet.xyz/). | - | OPTIMISM_GOERLI_URL | Optimisim Goerli'ye giden URL. Herkese açık bitiş noktası olan `https://goerli.optimism.io`, oran sınırlıdır fakat ihtiyacımız olan şey için yeterlidir | + | Parametre | Değer | + | ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | + | MNEMONIC | Bir işlemi ödemek için yeterli ETH'ye sahip bir hesabın anımsatıcısı. [Optimism Goerli ağı için ücretsiz ETH'yi buradan alabilirsiniz](https://optimismfaucet.xyz/). | + | OPTIMISM_GOERLI_URL | Optimism Goerli'ye URL. Genel uç nokta, `https://goerli.optimism.io`, hız sınırlıdır ancak burada ihtiyacımız olan şey için yeterlidir | -5. `index.js` komutunu çalıştırın. +5. `index.js`'i çalıştırın. ```sh node index.js ``` - Bu örnek uygulama ilk olarak WORM'a bir girdi yazar ve çağrı verisi ile Etherscan'deki işlemin bağlantısını görüntüler. Sonra da bu girişi geri okur, kullandığı anahtarı ve girdideki değerleri gösterir (değer, blok numarası ve yazarı). + Bu örnek uygulama önce WORM'a bir giriş yazar, calldata'yı ve Etherscan'deki işleme bir bağlantıyı görüntüler. Sonra bu girişi geri okur ve kullandığı anahtarı ve girişteki değerleri (değer, blok numarası ve yazar) görüntüler. -Bu istemcinin çoğu normal Merkeziyetsiz Uygulama JavaScript'idir. Yani yine ilgi çekici kısımları ele alacağız. +İstemcinin çoğu normal merkeziyetsiz uygulama JavaScript'idir. Bu yüzden yine sadece ilginç kısımları ele alacağız. ```javascript . @@ -807,20 +804,20 @@ Bu istemcinin çoğu normal Merkeziyetsiz Uygulama JavaScript'idir. Yani yine il const main = async () => { const func = await worm.WRITE_ENTRY_CACHED() - // Need a new key every time + // Her seferinde yeni bir anahtar gerekir const key = await worm.encodeVal(Number(new Date())) ``` -Verilmiş olan bu yuvanın içine sadece bir kere yazılabildiğinden yuvaları yeniden kullanmadığımızdan emin olmak için zaman damgasını kullanırız. +Belirli bir yuvaya yalnızca bir kez yazılabilir, bu nedenle yuvaları yeniden kullanmadığımızdan emin olmak için zaman damgasını kullanırız. ```javascript const val = await worm.encodeVal("0x600D") -// Write an entry +// Bir giriş yazın const calldata = func + key.slice(2) + val.slice(2) ``` -Ether'ler çağrı verisinin bir onaltılık dizi olmasını, `0x` ve ardından da onaltılık bir çift sayı bekler. Hem `key` hem de `val` `0x` ile başladığından o başlıkları kaldırmamız gerekir. +Ethers, çağrı verisinin onaltılık bir dize, yani `0x` ve ardından çift sayıda onaltılık basamak olmasını bekler. Hem `key` hem de `val` `0x` ile başladığı için bu başlıkları kaldırmamız gerekir. ```javascript const tx = await worm.populateTransaction.writeEntryCached() @@ -829,39 +826,42 @@ tx.data = calldata sentTx = await wallet.sendTransaction(tx) ``` -Solidity test kodunda olduğu gibi, önbelleğe alınmış bir fonksiyonu normal şekilde çağıramayız. Bunun yerine, daha düşük seviyede bir mekanizma kullanmaya ihtiyacımız var. +Solidity test kodunda olduğu gibi, önbelleğe alınmış bir fonksiyonu normal şekilde çağıramayız. Bunun yerine daha düşük seviyeli bir mekanizma kullanmamız gerekiyor. ```javascript . . . - // Read the entry just written - const realKey = '0x' + key.slice(4) // remove the FF flag + // Az önce yazılan girişi okuyun + const realKey = '0x' + key.slice(4) // FF bayrağını kaldırın const entryRead = await worm.readEntry(realKey) . . . ``` -Girdileri okumak için normal mekanizmayı kullanabiliriz. Parametre önbelleklemesini `view` fonksiyonlarıyla kullanmaya gerek yoktur. +Girişleri okumak için normal mekanizmayı kullanabiliriz. `view` fonksiyonlarıyla parametre önbelleğe alma kullanmaya gerek yoktur. ## Sonuç {#conclusion} -Bu belgedeki kod, bir kavram ispatıdır; amaç, fikrin anlaşılmasını kolaylaştırmaktır. Oluşturmaya hazır bir sistem için biraz ilave işlevsellik eklemek isteyebilirsiniz: +Bu makaledeki kod bir kavram kanıtıdır, amaç fikri anlaşılır kılmaktır. Üretime hazır bir sistem için bazı ek işlevler uygulamak isteyebilirsiniz: -- `uint256` olmayan değerleri işleyin. Örnek olarak, dizeler. -- Küresel önbellek yerine belki kullanıcılar ile önbellekler arasında bir eşlemeye sahip olmak. Farklı kullanıcılar farklı değerler kullanır. -- Adresler için kullanılan değerler farklı amaçlar için kullanılanlardan bağımsızdır. Sadece adresler için ayrı bir önbelleğe sahip olmak mantıklı olabilir. -- Güncel olarak, önbellek anahtarları "ilk gelene en küçük anahtar" algoritmasına göre çalışmaktadır. İlk on altı değer tek bir bayt olarak gönderilebilir. Sonraki 4080 değer iki bayt olarak gönderilebilir. Sonraki yaklaşık bir milyon değer ise 3 bayt olarak gönderilebilir, vs. Bir oluşturma sistemi, önbellek girişleri için kullanım sayaçları tutmalıdır ve onları, _en yaygın_ on altı değerin bir bayt, sonraki 4080 en yaygın değerin iki bayt olacağı şekilde yeniden düzenlemelidir. +- `uint256` olmayan değerleri işleyin. Örneğin, dizeler. +- Genel bir önbellek yerine, belki kullanıcılar ve önbellekler arasında bir eşleme olabilir. Farklı kullanıcılar farklı değerler kullanır. +- Adresler için kullanılan değerler, diğer amaçlar için kullanılanlardan farklıdır. Sadece adresler için ayrı bir önbelleğe sahip olmak mantıklı olabilir. +- Şu anda, önbellek anahtarları "ilk gelen, en küçük anahtar" algoritmasına göredir. İlk on altı değer tek bir bayt olarak gönderilebilir. Sonraki 4080 değer iki bayt olarak gönderilebilir. Sonraki yaklaşık bir milyon değer üç bayttır, vb. Bir üretim sistemi, önbellek girişlerinde kullanım sayaçları tutmalı ve bunları, en yaygın on altı değerin bir bayt, sonraki 4080 en yaygın değerin iki bayt vb. olacak şekilde yeniden düzenlemelidir. - Yine de, bu risk barındıran bir işlemdir. Aşağıdaki olay dizisini hayal edin: + Ancak, bu potansiyel olarak tehlikeli bir işlemdir. Aşağıdaki olaylar dizisini hayal edin: - 1. Noam Naive, jeton göndermek istediği adresi şifrelemek için `encodeVal`'ı çağırır. O adres, uygulamada kullanan ilk adreslerden biridir, bu yüzden şifrelenmiş değer 0x06 olur. Bu, bir işlem değil, bir `view` fonksiyonudur. Yani Noam ile kullandığı düğüm arasındadır ve başka hiç kimse, hakkında bir bilgiye sahip değildir + 1. Noam Naive, jeton göndermek istediği adresi kodlamak için `encodeVal`'ı çağırır. Bu adres, uygulamada kullanılan ilklerden biridir, bu nedenle kodlanmış değer 0x06'dır. Bu bir `view` fonksiyonudur, bir işlem değildir, bu yüzden Noam ve kullandığı düğüm arasındadır ve başka kimse bunu bilmez - 2. Owen Owner, önbelleği yeniden düzenleme işlemini çalıştırıyor. Çok az kişi gerçek anlamda bu adresi kullanıyor, bu yüzden artık 0x201122 diye şifreleniyor. 0x06, farklı bir değere 1018 atanmış. + 2. Owen Owner, önbellek yeniden sıralama işlemini çalıştırır. Çok az insan bu adresi gerçekten kullanıyor, bu yüzden şimdi 0x201122 olarak kodlanıyor. Farklı bir değer olan 1018, 0x06'ya atanır. - 3. Noam Naive, jetonlarını 0x06'ya gönderiyor. `0x0000000000000000000000000de0b6b3a7640000` adresine gidiyorlar ve kimse bu adresin özel kodunu bilmediği için orada takılıp kalıyorlar. Noam _mutlu değil_. + 3. Noam Naive, jetonlarını 0x06'ya gönderir. Jetonlar `0x0000000000000000000000000de0b6b3a7640000` adresine gider ve kimse bu adresin özel anahtarını bilmediği için orada takılıp kalırlar. Noam _mutlu değil_. - Önbelleği yeniden düzenleme işlemi sırasında bu ve bellek havuzundaki bununla bağlantılı işlemler problemini çözmenin çok sayıda yolu olsa da, bunun farkında olmalısınız. + Bu sorunu ve önbellek yeniden sıralaması sırasında mempool'da bulunan işlemlerin ilgili sorununu çözmenin yolları vardır, ancak bunun farkında olmalısınız. + +Burada Optimism ile önbelleğe almayı gösterdim, çünkü ben bir Optimism çalışanıyım ve bu en iyi bildiğim toplamadır. Ancak, dahili işleme için minimum bir maliyet talep eden herhangi bir toplamayla çalışmalıdır, böylece karşılaştırmalı olarak işlem verilerini L1'e yazmak ana masraf olur. + +[Çalışmalarımdan daha fazlası için buraya bakın](https://cryptodocguy.pro/). -Burada Optimism ile önbelleklemeyi gösterdim, çünkü ben bir Optimism çalışanıyım ve bu da benim en iyi bildiğim toplamadır. Fakat dahili işlemeye minimum maliyet yükleyen her toplama için çalışması gerekir. Dolayısıyla karşılaştırma yaptığımızda işlem verilerini L1'e yazmak daha büyük maliyettir. diff --git a/public/content/translations/tr/developers/tutorials/app-plasma/index.md b/public/content/translations/tr/developers/tutorials/app-plasma/index.md new file mode 100644 index 00000000000..e08ad69ae66 --- /dev/null +++ b/public/content/translations/tr/developers/tutorials/app-plasma/index.md @@ -0,0 +1,1255 @@ +--- +title: "Gizliliği koruyan uygulamaya özel bir plazma yazın" +description: "Bu öğreticide, para yatırma işlemleri için yarı gizli bir banka oluşturuyoruz. Banka merkezi bir bileşendir; her kullanıcının bakiyesini bilir. Ancak bu bilgi zincir üstünde saklanmaz. Bunun yerine, banka durumun bir karmasını yayınlar. Bir işlem her gerçekleştiğinde, banka yeni karmayı, karma durumunu yeni duruma değiştiren imzalı bir işleme sahip olduğuna dair bir sıfır bilgi ispatı ile birlikte yayınlar. Bu öğreticiyi okuduktan sonra, sadece sıfır bilgi ispatlarının nasıl kullanılacağını değil, aynı zamanda neden kullanıldığını ve bunun nasıl güvenli bir şekilde yapılacağını da anlayacaksınız." +author: Ori Pomerantz +tags: [ "sıfır bilgi", "sunucu", "zincir dışında", "gizlilik" ] +skill: advanced +lang: tr +published: 2025-10-15 +--- + +## Giriş {#introduction} + +[Rollup'ların](/developers/docs/scaling/zk-rollups/) aksine, [plazmalar](/developers/docs/scaling/plasma) bütünlük için Ethereum ana ağını kullanır, ancak kullanılabilirlik için kullanmaz. Bu makalede, Ethereum'un bütünlüğü (yetkisiz değişiklikler olmaması) garanti ettiği ancak kullanılabilirliği (merkezi bir bileşen çökebilir ve tüm sistemi devre dışı bırakabilir) garanti etmediği, plazma gibi davranan bir uygulama yazıyoruz. + +Burada yazdığımız uygulama, gizliliği koruyan bir bankadır. Farklı adreslerin bakiyeli hesapları vardır ve diğer hesaplara para (ETH) gönderebilirler. Banka, durumun (hesaplar ve bakiyeleri) ve işlemlerin karmalarını yayınlar, ancak gerçek bakiyeleri gizli kalabilecekleri zincir dışında tutar. + +## Tasarım {#design} + +Bu, üretime hazır bir sistem değil, bir öğretim aracıdır. Bu nedenle, birkaç basitleştirici varsayımla yazılmıştır. + +- Sabit hesap havuzu. Belirli sayıda hesap vardır ve her hesap önceden belirlenmiş bir adrese aittir. Bu, çok daha basit bir sistem oluşturur çünkü sıfır bilgi ispatlarında değişken boyutlu veri yapılarını işlemek zordur. Üretime hazır bir sistem için, durum karması olarak [Merkle kökünü](/developers/tutorials/merkle-proofs-for-offline-data-integrity/) kullanabilir ve gerekli bakiyeler için Merkle ispatları sağlayabiliriz. + +- Bellek depolama. Bir üretim sisteminde, yeniden başlatma durumunda korumak için tüm hesap bakiyelerini diske yazmamız gerekir. Burada, bilginin basitçe kaybolması sorun değildir. + +- Sadece transferler. Bir üretim sistemi, bankaya varlık yatırmak ve bunları çekmek için bir yol gerektirir. Ancak buradaki amaç sadece konsepti göstermektir, bu nedenle bu banka transferlerle sınırlıdır. + +### Sıfır bilgi ispatları {#zero-knowledge-proofs} + +Temel düzeyde, bir sıfır bilgi ispatı, kanıtlayıcının bazı _Dataprivate_ verilerini bildiğini gösterir; öyle ki, bazı herkese açık veriler, _Datapublic_ ile _Dataprivate_ arasında bir _Relationship_ ilişkisi vardır. Doğrulayıcı, _Relationship_ ve _Datapublic_ bilir. + +Gizliliği korumak için, durumların ve işlemlerin gizli olması gerekir. Ancak bütünlüğü sağlamak için durumların [kriptografik karmasının](https://en.wikipedia.org/wiki/Cryptographic_hash_function) herkese açık olması gerekir. İşlem gönderen kişilere bu işlemlerin gerçekten gerçekleştiğini kanıtlamak için, işlem karmalarını da yayınlamamız gerekir. + +Çoğu durumda, _Dataprivate_, sıfır bilgi ispatı programının girdisi ve _Datapublic_ ise çıktısıdır. + +_Dataprivate_ içindeki bu alanlar: + +- _Staten_, eski durum +- _Staten+1_, yeni durum +- _İşlem_, eski durumdan yeni duruma geçen bir işlem. Bu işlem şu alanları içermelidir: + - Transferi alan _Hedef adres_ + - Transfer edilen _Tutar_ + - Her işlemin yalnızca bir kez işlenebilmesini sağlamak için _Nonce_. + Kaynak adresin işlemde olması gerekmez, çünkü imzadan kurtarılabilir. +- _İmza_, işlemi gerçekleştirmeye yetkili bir imza. Bizim durumumuzda, bir işlemi gerçekleştirmeye yetkili tek adres kaynak adrestir. Sıfır bilgi sistemimiz bu şekilde çalıştığı için, Ethereum imzasına ek olarak hesabın açık anahtarına da ihtiyacımız var. + +_Datapublic_ içindeki alanlar şunlardır: + +- _Karma(Durumn)_ eski durumun karması +- _Karma(Durumn+1)_ yeni durumun karması +- _Karma(İşlem)_ durumu _Durumn_ konumundan _Durumn+1_ konumuna değiştiren işlemin karması. + +İlişki birkaç koşulu kontrol eder: + +- Herkese açık karmalar gerçekten de özel alanlar için doğru karmalardır. +- İşlem, eski duruma uygulandığında yeni durumla sonuçlanır. +- İmza, işlemin kaynak adresinden gelir. + +Kriptografik karma işlevlerinin özellikleri nedeniyle, bu koşulları kanıtlamak bütünlüğü sağlamak için yeterlidir. + +### Veri yapıları {#data-structures} + +Birincil veri yapısı, sunucu tarafından tutulan durumdur. Her hesap için sunucu, [tekrarlama saldırılarını](https://en.wikipedia.org/wiki/Replay_attack) önlemek için kullanılan hesap bakiyesini ve bir [nonce'ı](https://en.wikipedia.org/wiki/Cryptographic_nonce) takip eder. + +### Bileşenler {#components} + +Bu sistem iki bileşen gerektirir: + +- İşlemleri alan, bunları işleyen ve sıfır bilgi ispatlarıyla birlikte zincire karmaları gönderen _sunucu_. +- Durum geçişlerinin meşru olduğundan emin olmak için karmaları depolayan ve sıfır bilgi ispatlarını doğrulayan bir _akıllı sözleşme_. + +### Veri ve kontrol akışı {#flows} + +Bunlar, çeşitli bileşenlerin bir hesaptan diğerine transfer için iletişim kurma yollarıdır. + +1. Bir web tarayıcısı, imzalayanın hesabından farklı bir hesaba transfer talebinde bulunan imzalı bir işlem gönderir. + +2. Sunucu, işlemin geçerli olduğunu doğrular: + + - İmzalayanın bankada yeterli bakiyeye sahip bir hesabı vardır. + - Alıcının bankada bir hesabı vardır. + +3. Sunucu, transfer edilen tutarı imzalayanın bakiyesinden çıkarıp alıcının bakiyesine ekleyerek yeni durumu hesaplar. + +4. Sunucu, durum değişikliğinin geçerli olduğuna dair bir sıfır bilgi ispatı hesaplar. + +5. Sunucu, Ethereum'a şunları içeren bir işlem gönderir: + + - Yeni durum karması + - İşlem karması (böylece işlem göndericisi işlendiğini bilebilir) + - Yeni duruma geçişin geçerli olduğunu kanıtlayan sıfır bilgi ispatı + +6. Akıllı sözleşme, sıfır bilgi ispatını doğrular. + +7. Sıfır bilgi ispatı kontrol edilirse, akıllı sözleşme şu eylemleri gerçekleştirir: + - Mevcut durum karmasını yeni durum karmasına güncelle + - Yeni durum karması ve işlem karması ile bir günlük girdisi yayınla + +### Araçlar {#tools} + +İstemci tarafı kodu için [Vite](https://vite.dev/), [React](https://react.dev/), [Viem](https://viem.sh/) ve [Wagmi](https://wagmi.sh/) kullanacağız. Bunlar endüstri standardı araçlardır; onlara aşina değilseniz [bu öğreticiyi](/developers/tutorials/creating-a-wagmi-ui-for-your-contract/) kullanabilirsiniz. + +Sunucunun büyük bir kısmı [Node](https://nodejs.org/en) kullanılarak JavaScript ile yazılmıştır. Sıfır bilgi kısmı [Noir](https://noir-lang.org/) dilinde yazılmıştır. `1.0.0-beta.10` sürümüne ihtiyacımız var, bu yüzden [Noir'ı talimatlara göre yükledikten](https://noir-lang.org/docs/getting_started/quick_start) sonra şunu çalıştırın: + +``` +noirup -v 1.0.0-beta.10 +``` + +Kullandığımız blokzincir, [Foundry](https://getfoundry.sh/introduction/installation)nin bir parçası olan yerel bir test blokzinciri olan `anvil`'dir. + +## Uygulama {#implementation} + +Bu karmaşık bir sistem olduğu için, onu aşamalar halinde uygulayacağız. + +### Aşama 1 - Manuel sıfır bilgi {#stage-1} + +İlk aşama için, tarayıcıda bir işlemi imzalayacak ve ardından bilgiyi manuel olarak sıfır bilgi ispatına sağlayacağız. Sıfır bilgi kodu, bu bilgiyi `server/noir/Prover.toml` dosyasında almayı bekler ([burada](https://noir-lang.org/docs/getting_started/project_breakdown#provertoml-1) belgelenmiştir). + +Çalışırken görmek için: + +1. [Node](https://nodejs.org/en/download) ve [Noir](https://noir-lang.org/install) uygulamasının yüklü olduğundan emin olun. Tercihen, bunları macOS, Linux veya [WSL](https://learn.microsoft.com/en-us/windows/wsl/install) gibi bir UNIX sistemine yükleyin. + +2. Aşama 1 kodunu indirin ve istemci kodunu sunmak için web sunucusunu başlatın. + + ```sh + git clone https://github.com/qbzzt/250911-zk-bank.git -b 01-manual-zk + cd 250911-zk-bank + cd client + npm install + npm run dev + ``` + + Burada bir web sunucusuna ihtiyacınız olmasının nedeni, belirli dolandırıcılık türlerini önlemek için birçok cüzdanın (MetaMask gibi) doğrudan diskten sunulan dosyaları kabul etmemesidir + +3. Cüzdanı olan bir tarayıcı açın. + +4. Cüzdanda yeni bir parola girin. Bunun mevcut parolanızı sileceğini unutmayın, bu yüzden _bir yedeğiniz olduğundan emin olun_. + + Parola, anvil için varsayılan test parolası olan `test test test test test test test test test test test junk`'tır. + +5. [İstemci tarafı koduna](http://localhost:5173/) göz atın. + +6. Cüzdana bağlanın ve hedef hesabınızı ve tutarınızı seçin. + +7. **İmzala**'ya tıklayın ve işlemi imzalayın. + +8. **Prover.toml** başlığı altında metin bulacaksınız. `server/noir/Prover.toml` dosyasını bu metinle değiştirin. + +9. Sıfır bilgi ispatını yürütün. + + ```sh + cd ../server/noir + nargo execute + ``` + + Çıktı şuna benzer olmalıdır: + + ``` + ori@CryptoDocGuy:~/noir/250911-zk-bank/server/noir$ nargo execute + + [zkBank] Circuit witness successfully solved + [zkBank] Witness saved to target/zkBank.gz + [zkBank] Circuit output: (0x199aa62af8c1d562a6ec96e66347bf3240ab2afb5d022c895e6bf6a5e617167b, 0x0cfc0a67cb7308e4e9b254026b54204e34f6c8b041be207e64c5db77d95dd82d, 0x450cf9da6e180d6159290554ae3d8787, 0x6d8bc5a15b9037e52fb59b6b98722a85) + ``` + +10. Mesajın doğru bir şekilde karıştırılıp karıştırılmadığını görmek için son iki değeri web tarayıcısında gördüğünüz karma ile karşılaştırın. + +#### `server/noir/Prover.toml` {#server-noir-prover-toml} + +[Bu dosya](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/server/noir/Prover.toml), Noir tarafından beklenen bilgi biçimini gösterir. + +```toml +mesaj="send 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 500 finney (milliEth) 0 " +``` + +Mesaj, kullanıcının anlamasını (imzalama sırasında gereklidir) ve Noir kodunun ayrıştırmasını kolaylaştıran metin biçimindedir. Tutar, bir yandan kesirli transferlere olanak sağlamak, diğer yandan kolayca okunabilir olmak için finney cinsinden belirtilmiştir. Son sayı [nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce)'tır. + +Dize 100 karakter uzunluğundadır. Sıfır bilgi ispatları değişken boyutlu verileri iyi işlemez, bu yüzden genellikle verileri doldurmak gerekir. + +```toml +pubKeyX=["0x83",...,"0x75"] +pubKeyY=["0x35",...,"0xa5"] +signature=["0xb1",...,"0x0d"] +``` + +Bu üç parametre, sabit boyutlu bayt dizileridir. + +```toml +[[accounts]] +address="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" +balance=100_000 +nonce=0 + +[[accounts]] +address="0x70997970C51812dc3A010C7d01b50e0d17dc79C8" +balance=100_000 +nonce=0 +``` + +Bu, bir yapı dizisini belirtmenin yoludur. Her giriş için adresi, bakiyeyi (milliETH yani [finney](https://cryptovalleyjournal.com/glossary/finney/)) ve bir sonraki nonce değerini belirtiriz. + +#### `client/src/Transfer.tsx` {#client-src-transfer-tsx} + +[Bu dosya](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/client/src/Transfer.tsx) istemci tarafı işlemeyi uygular ve `server/noir/Prover.toml` dosyasını (sıfır bilgi parametrelerini içeren) oluşturur. + +İşte daha ilginç kısımların açıklaması. + +```tsx +export default attrs => { +``` + +Bu işlev, diğer dosyaların içe aktarabileceği `Transfer` React bileşenini oluşturur. + +```tsx + const accounts = [ + "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", + "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", + "0x90F79bf6EB2c4f870365E785982E1f101E93b906", + "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65", + ] +``` + +Bunlar hesap adresleridir, `test ...` tarafından oluşturulan adreslerdir. test junk` parolası. Kendi adreslerinizi kullanmak istiyorsanız, sadece bu tanımı değiştirin. + +```tsx + const account = useAccount() + const wallet = createWalletClient({ + transport: custom(window.ethereum!) + }) +``` + +Bu [Wagmi kancaları](https://wagmi.sh/react/api/hooks) [viem](https://viem.sh/) kütüphanesine ve cüzdana erişmemizi sağlar. + +```tsx + const message = `send ${toAccount} ${ethAmount*1000} finney (milliEth) ${nonce}`.padEnd(100, " ") +``` + +Bu, boşluklarla doldurulmuş mesajdır. [`useState`](https://react.dev/reference/react/useState) değişkenlerinden biri her değiştiğinde, bileşen yeniden çizilir ve `message` güncellenir. + +```tsx + const sign = async () => { +``` + +Bu işlev, kullanıcı **İmzala** düğmesine tıkladığında çağrılır. Mesaj otomatik olarak güncellenir, ancak imza cüzdanda kullanıcı onayı gerektirir ve gerekmedikçe bunu istemeyiz. + +```tsx + const signature = await wallet.signMessage({ + account: fromAccount, + message, + }) +``` + +Cüzdandan [mesajı imzalamasını](https://viem.sh/docs/accounts/local/signMessage) isteyin. + +```tsx + const hash = hashMessage(message) +``` + +Mesaj karmasını alın. Kullanıcıya (Noir kodunun) hata ayıklaması için sağlamak yararlıdır. + +```tsx + const pubKey = await recoverPublicKey({ + hash, + signature + }) +``` + +[Açık anahtarı alın](https://viem.sh/docs/utilities/recoverPublicKey). Bu, [Noir `ecrecover`](https://github.com/colinnielsen/ecrecover-noir) işlevi için gereklidir. + +```tsx + setSignature(signature) + setHash(hash) + setPubKey(pubKey) +``` + +Durum değişkenlerini ayarlayın. Bunu yapmak, bileşeni yeniden çizer (`sign` işlevi çıktıktan sonra) ve kullanıcıya güncellenmiş değerleri gösterir. + +```tsx + let proverToml = ` +``` + +`Prover.toml` için metin. + +```tsx +message="${message}" + +pubKeyX=${hexToArray(pubKey.slice(4,4+2*32))} +pubKeyY=${hexToArray(pubKey.slice(4+2*32))} +``` + +Viem bize açık anahtarı 65 baytlık bir onaltılık dize olarak sağlar. İlk bayt `0x04`, bir sürüm işaretçisidir. Bunu, açık anahtarın `x` değeri için 32 bayt ve ardından açık anahtarın `y` değeri için 32 bayt takip eder. + +Ancak Noir, bu bilgiyi biri `x` için ve diğeri `y` için olmak üzere iki baytlık diziler olarak almayı bekler. Bunu sıfır bilgi ispatının bir parçası olarak ayrıştırmak yerine burada istemcide ayrıştırmak daha kolaydır. + +Bunun genel olarak sıfır bilgi alanında iyi bir uygulama olduğunu unutmayın. Sıfır bilgi ispatı içindeki kod pahalıdır, bu nedenle sıfır bilgi ispatı dışında yapılabilecek herhangi bir işleme sıfır bilgi ispatı _dışında_ yapılmalıdır. + +```tsx +signature=${hexToArray(signature.slice(2,-2))} +``` + +İmza ayrıca 65 baytlık bir onaltılık dize olarak da sağlanır. Ancak, son bayt yalnızca açık anahtarı kurtarmak için gereklidir. Açık anahtar zaten Noir koduna sağlanacağından, imzayı doğrulamak için ona ihtiyacımız yoktur ve Noir kodu bunu gerektirmez. + +```tsx +${accounts.map(accountInProverToml).reduce((a,b) => a+b, "")} +` +``` + +Hesapları sağlayın. + +```tsx + setProverToml(proverToml) + } + + return ( + <> +

Transfer

+``` + +Bu, bileşenin HTML (daha doğrusu, [JSX](https://react.dev/learn/writing-markup-with-jsx)) biçimidir. + +#### `server/noir/src/main.nr` {#server-noir-src-main-nr} + +[Bu dosya](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/server/noir/src/main.nr) gerçek sıfır bilgi kodudur. + +``` +use std::hash::pedersen_hash; +``` + +[Pedersen karması](https://rya-sge.github.io/access-denied/2024/05/07/pedersen-hash-function/), [Noir standart kütüphanesi](https://noir-lang.org/docs/noir/standard_library/cryptographic_primitives/hashes#pedersen_hash) ile sağlanır. Sıfır bilgi ispatları genellikle bu karma işlevini kullanır. [Aritmetik devrelerde](https://rareskills.io/post/arithmetic-circuit) hesaplamak, standart karma işlevlerine kıyasla çok daha kolaydır. + +``` +use keccak256::keccak256; +use dep::ecrecover; +``` + +Bu iki işlev, [`Nargo.toml`](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/server/noir/Nargo.toml) dosyasında tanımlanan harici kütüphanelerdir. Bunlar tam olarak adlandırıldıkları şeydir, [keccak256 karmasını](https://emn178.github.io/online-tools/keccak_256.html) hesaplayan bir işlev ve Ethereum imzalarını doğrulayan ve imzalayanın Ethereum adresini kurtaran bir işlev. + +``` +global ACCOUNT_NUMBER : u32 = 5; +``` + +Noir, [Rust](https://www.rust-lang.org/) dilinden esinlenmiştir. Değişkenler varsayılan olarak sabittir. Genel yapılandırma sabitlerini bu şekilde tanımlarız. Özellikle, `ACCOUNT_NUMBER` sakladığımız hesap sayısıdır. + +`u` adlı veri türleri, o sayıdaki bitsiz, işaretsizdir. Desteklenen tek türler `u8`, `u16`, `u32`, `u64` ve `u128`'dir. + +``` +global FLAT_ACCOUNT_FIELDS : u32 = 2; +``` + +Bu değişken, aşağıda açıklandığı gibi, hesapların Pedersen karması için kullanılır. + +``` +global MESSAGE_LENGTH : u32 = 100; +``` + +Yukarıda açıklandığı gibi, mesaj uzunluğu sabittir. Burada belirtilmiştir. + +``` +global ASCII_MESSAGE_LENGTH : [u8; 3] = [0x31, 0x30, 0x30]; +global HASH_BUFFER_SIZE : u32 = 26+3+MESSAGE_LENGTH; +``` + +[EIP-191 imzaları](https://eips.ethereum.org/EIPS/eip-191), 26 baytlık bir önek, ardından ASCII cinsinden mesaj uzunluğu ve son olarak mesajın kendisiyle birlikte bir arabellek gerektirir. + +``` +struct Account { + balance: u128, + address: Field, + nonce: u32, +} +``` + +Bir hesap hakkında sakladığımız bilgiler. [`Field`](https://noir-lang.org/docs/noir/concepts/data_types/fields), sıfır bilgi ispatını uygulayan [aritmetik devrede](https://rareskills.io/post/arithmetic-circuit) doğrudan kullanılabilen, tipik olarak 253 bite kadar olan bir sayıdır. Burada, 160 bitlik bir Ethereum adresini depolamak için `Field` kullanıyoruz. + +``` +struct TransferTxn { + from: Field, + to: Field, + amount: u128, + nonce: u32 +} +``` + +Bir transfer işlemi için sakladığımız bilgiler. + +``` +fn flatten_account(account: Account) -> [Field; FLAT_ACCOUNT_FIELDS] { +``` + +Bir işlev tanımı. Parametre `Account` bilgisidir. Sonuç, uzunluğu `FLAT_ACCOUNT_FIELDS` olan bir `Field` değişkenleri dizisidir + +``` + let flat = [ + account.address, + ((account.balance << 32) + account.nonce.into()).into(), + ]; +``` + +Dizideki ilk değer hesap adresidir. İkincisi hem bakiyeyi hem de nonce'u içerir. `.into()` çağrıları bir sayıyı olması gereken veri türüne değiştirir. `account.nonce`, bir `u32` değeridir, ancak onu bir `u128` değeri olan `account.balance « 32`'ye eklemek için bir `u128` olması gerekir. Bu ilk `.into()`'dur. İkincisi, `u128` sonucunu diziye sığacak şekilde bir `Field`'e dönüştürür. + +``` + flat +} +``` + +Noir'da, işlevler yalnızca sonda bir değer döndürebilir (erken dönüş yoktur). Dönüş değerini belirtmek için, onu işlevin kapanış parantezinden hemen önce değerlendirirsiniz. + +``` +fn flatten_accounts(accounts: [Account; ACCOUNT_NUMBER]) -> [Field; FLAT_ACCOUNT_FIELDS*ACCOUNT_NUMBER] { +``` + +Bu işlev, hesaplar dizisini bir Petersen Karması'nın girdisi olarak kullanılabilecek bir `Field` dizisine dönüştürür. + +``` + let mut flat: [Field; FLAT_ACCOUNT_FIELDS*ACCOUNT_NUMBER] = [0; FLAT_ACCOUNT_FIELDS*ACCOUNT_NUMBER]; +``` + +Bu, bir sabit _olmayan_, yani değişken bir değişkeni belirtmenin yoludur. Noir'daki değişkenlerin her zaman bir değeri olmalıdır, bu nedenle bu değişkeni tümü sıfır olarak başlatırız. + +``` + for i in 0..ACCOUNT_NUMBER { +``` + +Bu bir `for` döngüsüdür. Sınırların sabit olduğunu unutmayın. Noir döngülerinin sınırlarının derleme zamanında bilinmesi gerekir. Bunun nedeni, aritmetik devrelerin akış kontrolünü desteklememesidir. Bir `for` döngüsünü işlerken, derleyici içindeki kodu, her yineleme için bir tane olmak üzere, birden çok kez koyar. + +``` + let fields = flatten_account(accounts[i]); + for j in 0..FLAT_ACCOUNT_FIELDS { + flat[i*FLAT_ACCOUNT_FIELDS + j] = fields[j]; + } + } + + flat +} + +fn hash_accounts(accounts: [Account; ACCOUNT_NUMBER]) -> Field { + pedersen_hash(flatten_accounts(accounts)) +} +``` + +Sonunda, hesaplar dizisini karma haline getiren işleve ulaştık. + +``` +fn find_account(accounts: [Account; ACCOUNT_NUMBER], address: Field) -> u32 { + let mut account : u32 = ACCOUNT_NUMBER; + + for i in 0..ACCOUNT_NUMBER { + if accounts[i].address == address { + account = i; + } + } + +``` + +Bu işlev, belirli bir adrese sahip hesabı bulur. Bu işlev standart kodda çok verimsiz olurdu çünkü adresi bulduktan sonra bile tüm hesaplar üzerinde yinelenir. + +Ancak sıfır bilgi ispatlarında akış kontrolü yoktur. Bir koşulu kontrol etmemiz gerekirse, her seferinde kontrol etmemiz gerekir. + +`if` ifadeleriyle benzer bir şey olur. Yukarıdaki döngüdeki `if` ifadesi bu matematiksel ifadelere çevrilir. + +_koşulsonuç = hesaplar[i].adres == adres_ // eşitlerse bir, değilse sıfır + +_hesapyeni = koşulsonuç\*i + (1-koşulsonuç)\*hesapeski_ + +```rust + assert (account < ACCOUNT_NUMBER, f"{address} does not have an account"); + + account +} +``` + +[`assert`](https://noir-lang.org/docs/dev/noir/concepts/assert) işlevi, iddia yanlışsa sıfır bilgi ispatının çökmesine neden olur. Bu durumda, ilgili adrese sahip bir hesap bulamazsak. Adresi bildirmek için bir [biçim dizesi](https://noir-lang.org/docs/noir/concepts/data_types/strings#format-strings) kullanırız. + +```rust +fn apply_transfer_txn(accounts: [Account; ACCOUNT_NUMBER], txn: TransferTxn) -> [Account; ACCOUNT_NUMBER] { +``` + +Bu işlev bir transfer işlemi uygular ve yeni hesaplar dizisini döndürür. + +```rust + let from = find_account(accounts, txn.from); + let to = find_account(accounts, txn.to); + + let (txnFrom, txnAmount, txnNonce, accountNonce) = + (txn.from, txn.amount, txn.nonce, accounts[from].nonce); +``` + +Noir'da bir biçim dizesi içindeki yapı elemanlarına erişemeyiz, bu yüzden kullanılabilir bir kopya oluştururuz. + +```rust + assert (accounts[from].balance >= txn.amount, + f"{txnFrom} does not have {txnAmount} finney"); + + assert (accounts[from].nonce == txn.nonce, + f"Transaction has nonce {txnNonce}, but the account is expected to use {accountNonce}"); +``` + +Bunlar bir işlemi geçersiz kılabilen iki koşuldur. + +```rust + let mut newAccounts = accounts; + + newAccounts[from].balance -= txn.amount; + newAccounts[from].nonce += 1; + newAccounts[to].balance += txn.amount; + + newAccounts +} +``` + +Yeni hesaplar dizisini oluşturun ve sonra onu döndürün. + +```rust +fn readAddress(messageBytes: [u8; MESSAGE_LENGTH]) -> Field +``` + +Bu işlev, adresi mesajdan okur. + +```rust +{ + let mut result : Field = 0; + + for i in 7..47 { +``` + +Adres her zaman 20 bayt (yani 40 onaltılık basamak) uzunluğundadır ve 7. karakterde başlar. + +```rust + result *= 0x10; + if messageBytes[i] >= 48 & messageBytes[i] <= 57 { // 0-9 + result += (messageBytes[i]-48).into(); + } + if messageBytes[i] >= 65 & messageBytes[i] <= 70 { // A-F + result += (messageBytes[i]-65+10).into() + } + if messageBytes[i] >= 97 & messageBytes[i] <= 102 { // a-f + result += (messageBytes[i]-97+10).into() + } + } + + result +} + +fn readAmountAndNonce(messageBytes: [u8; MESSAGE_LENGTH]) -> (u128, u32) +``` + +Tutar ve nonce'u mesajdan okuyun. + +```rust +{ + let mut amount : u128 = 0; + let mut nonce: u32 = 0; + let mut stillReadingAmount: bool = true; + let mut lookingForNonce: bool = false; + let mut stillReadingNonce: bool = false; +``` + +Mesajda, adresten sonraki ilk sayı transfer edilecek finney (yani ETH'nin binde biri) miktarıdır. İkinci sayı nonce'dır. Aralarındaki metinler dikkate alınmaz. + +```rust + for i in 48..MESSAGE_LENGTH { + if messageBytes[i] >= 48 & messageBytes[i] <= 57 { // 0-9 + let digit = (messageBytes[i]-48); + + if stillReadingAmount { + amount = amount*10 + digit.into(); + } + + if lookingForNonce { // We just found it + stillReadingNonce = true; + lookingForNonce = false; + } + + if stillReadingNonce { + nonce = nonce*10 + digit.into(); + } + } else { + if stillReadingAmount { + stillReadingAmount = false; + lookingForNonce = true; + } + if stillReadingNonce { + stillReadingNonce = false; + } + } + } + + (amount, nonce) +} +``` + +Bir [demet](https://noir-lang.org/docs/noir/concepts/data_types/tuples) döndürmek, Noir'ın bir işlevden birden çok değer döndürme yoludur. + +```rust +fn readTransferTxn(message: str) -> TransferTxn +{ + let mut txn: TransferTxn = TransferTxn { from: 0, to: 0, amount:0, nonce:0 }; + let messageBytes = message.as_bytes(); + + txn.to = readAddress(messageBytes); + let (amount, nonce) = readAmountAndNonce(messageBytes); + txn.amount = amount; + txn.nonce = nonce; + + txn +} +``` + +Bu işlev, mesajı baytlara dönüştürür, ardından tutarları bir `TransferTxn`'e dönüştürür. + +```rust +// The equivalent to Viem's hashMessage +// https://viem.sh/docs/utilities/hashMessage#hashmessage +fn hashMessage(message: str) -> [u8;32] { +``` + +Hesaplar için Pedersen Karması'nı kullanabildik çünkü bunlar yalnızca sıfır bilgi ispatı içinde karmalanır. Ancak, bu kodda tarayıcı tarafından oluşturulan mesajın imzasını kontrol etmemiz gerekiyor. Bunun için, [EIP 191](https://eips.ethereum.org/EIPS/eip-191)'deki Ethereum imzalama biçimini izlememiz gerekir. Bu, standart bir önek, ASCII cinsinden mesaj uzunluğu ve mesajın kendisiyle birleşik bir arabellek oluşturmamız ve onu karmalamak için Ethereum standardı olan keccak256'yı kullanmamız gerektiği anlamına gelir. + +```rust + // ASCII prefix + let prefix_bytes = [ + 0x19, // \x19 + 0x45, // 'E' + 0x74, // 't' + 0x68, // 'h' + 0x65, // 'e' + 0x72, // 'r' + 0x65, // 'e' + 0x75, // 'u' + 0x6D, // 'm' + 0x20, // ' ' + 0x53, // 'S' + 0x69, // 'i' + 0x67, // 'g' + 0x6E, // 'n' + 0x65, // 'e' + 0x64, // 'd' + 0x20, // ' ' + 0x4D, // 'M' + 0x65, // 'e' + 0x73, // 's' + 0x73, // 's' + 0x61, // 'a' + 0x67, // 'g' + 0x65, // 'e' + 0x3A, // ':' + 0x0A // '\n' + ]; +``` + +Bir uygulamanın kullanıcıdan bir işlem olarak veya başka bir amaçla kullanılabilecek bir mesajı imzalamasını istediği durumları önlemek için, EIP 191, tüm imzalı mesajların 0x19 karakteri (geçerli bir ASCII karakteri değil) ve ardından `Ethereum Signed Message:` ve bir yeni satır ile başlamasını belirtir. + +```rust + let mut buffer: [u8; HASH_BUFFER_SIZE] = [0u8; HASH_BUFFER_SIZE]; + for i in 0..26 { + buffer[i] = prefix_bytes[i]; + } + + let messageBytes : [u8; MESSAGE_LENGTH] = message.as_bytes(); + + if MESSAGE_LENGTH <= 9 { + for i in 0..1 { + buffer[i+26] = ASCII_MESSAGE_LENGTH[i]; + } + + for i in 0..MESSAGE_LENGTH { + buffer[i+26+1] = messageBytes[i]; + } + } + + if MESSAGE_LENGTH >= 10 & MESSAGE_LENGTH <= 99 { + for i in 0..2 { + buffer[i+26] = ASCII_MESSAGE_LENGTH[i]; + } + + for i in 0..MESSAGE_LENGTH { + buffer[i+26+2] = messageBytes[i]; + } + } + + if MESSAGE_LENGTH >= 100 { + for i in 0..3 { + buffer[i+26] = ASCII_MESSAGE_LENGTH[i]; + } + + for i in 0..MESSAGE_LENGTH { + buffer[i+26+3] = messageBytes[i]; + } + } + + assert(MESSAGE_LENGTH < 1000, "Messages whose length is over three digits are not supported"); +``` + +999'a kadar olan mesaj uzunluklarını ele alın ve daha büyükse başarısız olun. Mesaj uzunluğu sabit olmasına rağmen bu kodu ekledim, çünkü değiştirmeyi kolaylaştırıyor. Bir üretim sisteminde, muhtemelen daha iyi performans için `MESSAGE_LENGTH`'in değişmediğini varsayarsınız. + +```rust + keccak256::keccak256(buffer, HASH_BUFFER_SIZE) +``` + +Ethereum standardı `keccak256` işlevini kullanın. + +```rust +fn signatureToAddressAndHash( + message: str, + pubKeyX: [u8; 32], + pubKeyY: [u8; 32], + signature: [u8; 64] + ) -> (Field, Field, Field) // address, first 16 bytes of hash, last 16 bytes of hash +{ +``` + +Bu işlev, mesaj karmasını gerektiren imzayı doğrular. Daha sonra bize imzalayan adresi ve mesaj karmasını sağlar. Mesaj karması, programın geri kalanında bayt dizisinden daha kolay kullanılabildiği için iki `Field` değeri olarak verilir. + +İki `Alan` değeri kullanmamız gerekiyor çünkü alan hesaplamaları büyük bir sayıya [modulo](https://en.wikipedia.org/wiki/Modulo) yapılarak yapılır, ancak bu sayı genellikle 256 bitten azdır (aksi takdirde bu hesaplamaları EVM'de yapmak zor olurdu). + +```rust + let hash = hashMessage(message); + + let mut (hash1, hash2) = (0,0); + + for i in 0..16 { + hash1 = hash1*256 + hash[31-i].into(); + hash2 = hash2*256 + hash[15-i].into(); + } +``` + +`hash1` ve `hash2`'yi değiştirilebilir değişkenler olarak belirtin ve karmayı bayt bayt bunlara yazın. + +```rust + ( + ecrecover::ecrecover(pubKeyX, pubKeyY, signature, hash), +``` + +Bu, [Solidity'nin `ecrecover`](https://docs.soliditylang.org/en/v0.8.30/cheatsheet.html#mathematical-and-cryptographic-functions) işlevine benzer, ancak iki önemli farkı vardır: + +- İmza geçerli değilse, çağrı bir `assert`'i başarısız kılar ve program iptal edilir. +- Açık anahtar, imzadan ve karmadan kurtarılabilse de, bu harici olarak yapılabilecek bir işlemdir ve bu nedenle sıfır bilgi ispatı içinde yapmaya değmez. Biri bizi burada aldatmaya çalışırsa, imza doğrulaması başarısız olur. + +```rust + hash1, + hash2 + ) +} + +fn main( + accounts: [Account; ACCOUNT_NUMBER], + message: str, + pubKeyX: [u8; 32], + pubKeyY: [u8; 32], + signature: [u8; 64], + ) -> pub ( + Field, // Hash of old accounts array + Field, // Hash of new accounts array + Field, // First 16 bytes of message hash + Field, // Last 16 bytes of message hash + ) +``` + +Sonunda `main` işlevine ulaştık. Hesapların karmasını eski değerden yeni değere geçerli bir şekilde değiştiren bir işlemimiz olduğunu kanıtlamamız gerekiyor. Ayrıca, gönderen kişinin işleminin işlendiğini bilmesi için bu belirli işlem karmasına sahip olduğunu kanıtlamamız gerekir. + +```rust +{ + let mut txn = readTransferTxn(message); +``` + +`txn`'in değiştirilebilir olması gerekir çünkü gönderen adresini mesajdan değil, imzadan okuyoruz. + +```rust + let (fromAddress, txnHash1, txnHash2) = signatureToAddressAndHash( + message, + pubKeyX, + pubKeyY, + signature); + + txn.from = fromAddress; + + let newAccounts = apply_transfer_txn(accounts, txn); + + ( + hash_accounts(accounts), + hash_accounts(newAccounts), + txnHash1, + txnHash2 + ) +} +``` + +### Aşama 2 - Bir sunucu ekleme {#stage-2} + +İkinci aşamada, tarayıcıdan transfer işlemlerini alan ve uygulayan bir sunucu ekliyoruz. + +Çalışırken görmek için: + +1. Çalışıyorsa Vite'i durdurun. + +2. Sunucuyu içeren dalı indirin ve gerekli tüm modüllere sahip olduğunuzdan emin olun. + + ```sh + git checkout 02-add-server + cd client + npm install + cd ../server + npm install + ``` + + Noir kodunu derlemeye gerek yok, aşama 1 için kullandığınız kodla aynı. + +3. Sunucuyu başlatın. + + ```sh + npm run start + ``` + +4. Ayrı bir komut satırı penceresinde, tarayıcı kodunu sunmak için Vite'i çalıştırın. + + ```sh + cd client + npm run dev + ``` + +5. [http://localhost:5173](http://localhost:5173) adresindeki istemci koduna göz atın + +6. Bir işlem yapmadan önce, gönderebileceğiniz tutarın yanı sıra nonce'u da bilmeniz gerekir. Bu bilgiyi almak için **Hesap verilerini güncelle**'ye tıklayın ve mesajı imzalayın. + + Burada bir ikilemimiz var. Bir yandan, yeniden kullanılabilecek bir mesajı imzalamak istemiyoruz (bir [tekrarlama saldırısı](https://en.wikipedia.org/wiki/Replay_attack)), bu yüzden ilk etapta bir nonce istiyoruz. Ancak, henüz bir nonce'umuz yok. Çözüm, yalnızca bir kez kullanılabilecek ve her iki tarafta da zaten sahip olduğumuz bir nonce seçmektir, örneğin geçerli zaman. + + Bu çözümün sorunu, zamanın mükemmel bir şekilde senkronize olmayabileceğidir. Bu yüzden, her dakika değişen bir değer imzalıyoruz. Bu, tekrarlama saldırılarına karşı güvenlik açığı penceremizin en fazla bir dakika olduğu anlamına gelir. Üretimde imzalanan isteğin TLS tarafından korunacağı ve tünelin diğer tarafının - sunucunun - zaten bakiyeyi ve nonce'u ifşa edebileceği (çalışmak için bunları bilmesi gerekir) göz önüne alındığında, bu kabul edilebilir bir risktir. + +7. Tarayıcı bakiye ve nonce'u geri aldığında, transfer formunu gösterir. Hedef adresi ve tutarı seçin ve **Transfer**'e tıklayın. Bu isteği imzalayın. + +8. Transferi görmek için ya **Hesap verilerini güncelle**'yi kullanın ya da sunucuyu çalıştırdığınız pencereye bakın. Sunucu, her değiştiğinde durumu günlüğe kaydeder. + + ``` + ori@CryptoDocGuy:~/x/250911-zk-bank/server$ npm run start + + > server@1.0.0 start + > node --experimental-json-modules index.mjs + + Listening on port 3000 + Txn send 0x90F79bf6EB2c4f870365E785982E1f101E93b906 36000 finney (milliEth) 0 işlendi + Yeni durum: + 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 64000 (1) var + 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 100000 (0) var + 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC 100000 (0) var + 0x90F79bf6EB2c4f870365E785982E1f101E93b906 136000 (0) var + 0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65 100000 (0) var + Txn send 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 7200 finney (milliEth) 1 işlendi + Yeni durum: + 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 56800 (2) var + 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 107200 (0) var + 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC 100000 (0) var + 0x90F79bf6EB2c4f870365E785982E1f101E93b906 136000 (0) var + 0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65 100000 (0) var + Txn send 0x90F79bf6EB2c4f870365E785982E1f101E93b906 3000 finney (milliEth) 2 işlendi + Yeni durum: + 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 53800 (3) var + 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 107200 (0) var + 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC 100000 (0) var + 0x90F79bf6EB2c4f870365E785982E1f101E93b906 139000 (0) var + 0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65 100000 (0) var + ``` + +#### `server/index.mjs` {#server-index-mjs-1} + +[Bu dosya](https://github.com/qbzzt/250911-zk-bank/blob/02-add-server/server/index.mjs) sunucu sürecini içerir ve [`main.nr`](https://github.com/qbzzt/250911-zk-bank/blob/02-add-server/server/noir/src/main.nr) adresindeki Noir kodu ile etkileşime girer. İşte ilginç kısımların açıklaması. + +```js +import { Noir } from '@noir-lang/noir_js' +``` + +[noir.js](https://www.npmjs.com/package/@noir-lang/noir_js) kütüphanesi JavaScript kodu ile Noir kodu arasında arayüz oluşturur. + +```js +const circuit = JSON.parse(await fs.readFile("./noir/target/zkBank.json")) +const noir = new Noir(circuit) +``` + +Aritmetik devreyi - önceki aşamada oluşturduğumuz derlenmiş Noir programını - yükleyin ve yürütmeye hazırlanın. + +```js +// We only provide account information in return to a signed request +const accountInformation = async signature => { + const fromAddress = await recoverAddress({ + hash: hashMessage("Get account data " + Math.floor((new Date().getTime())/60000)), + signature + }) +``` + +Hesap bilgilerini sağlamak için sadece imzaya ihtiyacımız var. Bunun nedeni, mesajın ne olacağını ve dolayısıyla mesaj karmasını zaten biliyor olmamızdır. + +```js +const processMessage = async (message, signature) => { +``` + +Bir mesajı işleyin ve kodladığı işlemi yürütün. + +```js + // Get the public key + const pubKey = await recoverPublicKey({ + hash, + signature + }) +``` + +Artık sunucuda JavaScript çalıştırdığımıza göre, açık anahtarı istemci yerine orada alabiliriz. + +```js + let noirResult + try { + noirResult = await noir.execute({ + message, + signature: signature.slice(2,-2).match(/.{2}/g).map(x => `0x${x}`), + pubKeyX, + pubKeyY, + accounts: Accounts + }) +``` + +`noir.execute` Noir programını çalıştırır. Parametreler [`Prover.toml`](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/server/noir/Prover.toml) dosyasında sağlananlara eşdeğerdir. Uzun değerlerin, Viem'in yaptığı gibi tek bir onaltılık değer (`0x60A7`) olarak değil, onaltılık dizelerden oluşan bir dizi (`["0x60", "0xA7"]`) olarak sağlandığını unutmayın. + +```js + } catch (err) { + console.log(`Noir error: ${err}`) + throw Error("Invalid transaction, not processed") + } +``` + +Bir hata varsa, onu yakalayın ve ardından basitleştirilmiş bir sürümünü istemciye iletin. + +```js + Accounts[fromAccountNumber].nonce++ + Accounts[fromAccountNumber].balance -= amount + Accounts[toAccountNumber].balance += amount +``` + +İşlemi uygulayın. Bunu zaten Noir kodunda yaptık, ancak sonucu oradan çıkarmak yerine burada tekrar yapmak daha kolay. + +```js +let Accounts = [ + { + address: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + balance: 5000, + nonce: 0, + }, +``` + +Başlangıçtaki `Hesaplar` yapısı. + +### Aşama 3 - Ethereum akıllı sözleşmeleri {#stage-3} + +1. Sunucu ve istemci süreçlerini durdurun. + +2. Akıllı sözleşmeleri içeren dalı indirin ve gerekli tüm modüllere sahip olduğunuzdan emin olun. + + ```sh + git checkout 03-smart-contracts + cd client + npm install + cd ../server + npm install + ``` + +3. `anvil`'i ayrı bir komut satırı penceresinde çalıştırın. + +4. Doğrulama anahtarını ve solidity doğrulayıcısını oluşturun, ardından doğrulayıcı kodunu Solidity projesine kopyalayın. + + ```sh + cd noir + bb write_vk -b ./target/zkBank.json -o ./target --oracle_hash keccak + bb write_solidity_verifier -k ./target/vk -o ./target/Verifier.sol + cp target/Verifier.sol ../../smart-contracts/src + ``` + +5. Akıllı sözleşmelere gidin ve `anvil` blokzincirini kullanmak için ortam değişkenlerini ayarlayın. + + ```sh + cd ../../smart-contracts + export ETH_RPC_URL=http://localhost:8545 + ETH_PRIVATE_KEY=ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 + ``` + +6. `Verifier.sol`'u dağıtın ve adresi bir ortam değişkeninde saklayın. + + ```sh + VERIFIER_ADDRESS=`forge create src/Verifier.sol:HonkVerifier --private-key $ETH_PRIVATE_KEY --optimize --broadcast | awk '/Deployed to:/ {print $3}'` + echo $VERIFIER_ADDRESS + ``` + +7. `ZkBank` sözleşmesini dağıtın. + + ```sh + ZKBANK_ADDRESS=`forge create ZkBank --private-key $ETH_PRIVATE_KEY --broadcast --constructor-args $VERIFIER_ADDRESS 0x199aa62af8c1d562a6ec96e66347bf3240ab2afb5d022c895e6bf6a5e617167b | awk '/Deployed to:/ {print $3}'` + echo $ZKBANK_ADDRESS + ``` + + `0x199..67b` değeri, `Hesaplar`ın başlangıç durumunun Pederson karmasıdır. Bu başlangıç durumunu `server/index.mjs`'de değiştirirseniz, sıfır bilgi ispatı tarafından bildirilen başlangıç karmasını görmek için bir işlem çalıştırabilirsiniz. + +8. Sunucuyu çalıştırın. + + ```sh + cd ../server + npm run start + ``` + +9. İstemciyi farklı bir komut satırı penceresinde çalıştırın. + + ```sh + cd client + npm run dev + ``` + +10. Bazı işlemler çalıştırın. + +11. Durumun zincir üzerinde değiştiğini doğrulamak için sunucu sürecini yeniden başlatın. `ZkBank`'in artık işlemleri kabul etmediğini görün, çünkü işlemlerdeki orijinal karma değeri, zincir üzerinde saklanan karma değerinden farklıdır. + + Bu beklenen hata türüdür. + + ``` + ori@CryptoDocGuy:~/x/250911-zk-bank/server$ npm run start + + > server@1.0.0 start + > node --experimental-json-modules index.mjs + + Listening on port 3000 + Doğrulama hatası: ContractFunctionExecutionError: The contract function "processTransaction" reverted with the following reason: + Yanlış eski durum karması + + Contract Call: + adres: 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 + işlev: processTransaction(bytes _proof, bytes32[] _publicInputs) + args: (0x0000000000000000000000000000000000000000000000042ab5d6d1986846cf00000000000000000000000000000000000000000000000b75c020998797da7800000000000000000000000000000000000000000000000 + ``` + +#### `server/index.mjs` {#server-index-mjs-2} + +Bu dosyadaki değişiklikler çoğunlukla gerçek kanıtı oluşturmak ve zincir üstünde göndermekle ilgilidir. + +```js +import { exec } from 'child_process' +import util from 'util' + +const execPromise = util.promisify(exec) +``` + +Zincir üstünde gönderilecek gerçek kanıtı oluşturmak için [Barretenberg paketini](https://github.com/AztecProtocol/aztec-packages/tree/next/barretenberg) kullanmamız gerekiyor. Bu paketi komut satırı arayüzünü (`bb`) çalıştırarak veya [JavaScript kütüphanesi olan `bb.js`](https://www.npmjs.com/package/@aztec/bb.js) kullanarak kullanabiliriz. JavaScript kütüphanesi, kodu yerel olarak çalıştırmaktan çok daha yavaştır, bu yüzden burada komut satırını kullanmak için [`exec`](https://nodejs.org/api/child_process.html#child_processexeccommand-options-callback) kullanıyoruz. + +`bb.js` kullanmaya karar verirseniz, kullandığınız Noir sürümüyle uyumlu bir sürüm kullanmanız gerektiğini unutmayın. Bu yazının yazıldığı sırada, mevcut Noir sürümü (1.0.0-beta.11) `bb.js` sürüm 0.87'yi kullanıyor. + +```js +const zkBankAddress = process.env.ZKBANK_ADDRESS || "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" +``` + +Buradaki adres, temiz bir `anvil` ile başlayıp yukarıdaki yönergeleri izlediğinizde elde ettiğiniz adrestir. + +```js +const walletClient = createWalletClient({ + chain: anvil, + transport: http(), + account: privateKeyToAccount("0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6") +}) +``` + +Bu özel anahtar, `anvil`'deki varsayılan önceden finanse edilmiş hesaplardan biridir. + +```js +const generateProof = async (witness, fileID) => { +``` + +`bb` yürütülebilir dosyasını kullanarak bir kanıt oluşturun. + +```js + const fname = `witness-${fileID}.gz` + await fs.writeFile(fname, witness) +``` + +Tanığı bir dosyaya yazın. + +```js + await execPromise(`bb prove -b ./noir/target/zkBank.json -w ${fname} -o ${fileID} --oracle_hash keccak --output_format fields`) +``` + +Aslında kanıtı yaratın. Bu adım aynı zamanda genel değişkenleri içeren bir dosya oluşturur, ancak buna ihtiyacımız yok. Bu değişkenleri zaten `noir.execute`'den aldık. + +```js + const proof = "0x" + JSON.parse(await fs.readFile(`./${fileID}/proof_fields.json`)).reduce((a,b) => a+b, "").replace(/0x/g, "") +``` + +Kanıt, her biri onaltılık bir değer olarak temsil edilen `Alan` değerlerinden oluşan bir JSON dizisidir. Ancak, bunu işlemde tek bir `bayt` değeri olarak göndermemiz gerekiyor, bu da Viem'in büyük bir onaltılık dize ile temsil ettiği bir şey. Burada, tüm değerleri birleştirerek, tüm `0x`'leri kaldırarak ve ardından sonunda bir tane ekleyerek biçimi değiştiriyoruz. + +```js + await execPromise(`rm -r ${fname} ${fileID}`) + + return proof +} +``` + +Temizleyin ve kanıtı geri döndürün. + +```js +const processMessage = async (message, signature) => { + . + . + . + + const publicFields = noirResult.returnValue.map(x=>'0x' + x.slice(2).padStart(64, "0")) +``` + +Genel alanların 32 baytlık değerlerden oluşan bir dizi olması gerekir. Ancak, işlem karmasını iki `Alan` değeri arasında bölmemiz gerektiği için, 16 baytlık bir değer olarak görünür. Burada Viem'in aslında 32 bayt olduğunu anlaması için sıfırlar ekliyoruz. + +```js + const proof = await generateProof(noirResult.witness, `${fromAddress}-${nonce}`) +``` + +Her adres her nonce'u yalnızca bir kez kullanır, böylece `fromAddress` ve `nonce` kombinasyonunu tanık dosyası ve çıktı dizini için benzersiz bir tanımlayıcı olarak kullanabiliriz. + +```js + try { + await zkBank.write.processTransaction([ + proof, publicFields]) + } catch (err) { + console.log(`Verification error: ${err}`) + throw Error("Can't verify the transaction onchain") + } + . + . + . +} +``` + +İşlemi zincire gönderin. + +#### `smart-contracts/src/ZkBank.sol` {#smart-contracts-src-zkbank-sol} + +Bu, işlemi alan zincir üstü koddur. + +```solidity +// SPDX-License-Identifier: MIT + +pragma solidity >=0.8.21; + +import {HonkVerifier} from "./Verifier.sol"; + +contract ZkBank { + HonkVerifier immutable myVerifier; + bytes32 currentStateHash; + + constructor(address _verifierAddress, bytes32 _initialStateHash) { + currentStateHash = _initialStateHash; + myVerifier = HonkVerifier(_verifierAddress); + } +``` + +Zincir üstü kodun iki değişkeni takip etmesi gerekir: doğrulayıcı (`nargo` tarafından oluşturulan ayrı bir sözleşme) ve mevcut durum karması. + +```solidity + event TransactionProcessed( + bytes32 indexed transactionHash, + bytes32 oldStateHash, + bytes32 newStateHash + ); +``` + +Durum her değiştiğinde, bir `TransactionProcessed` olayı yayınlarız. + +```solidity + function processTransaction( + bytes calldata _proof, + bytes32[] calldata _publicFields + ) public { +``` + +Bu işlev işlemleri işler. Kanıtı (`bayt` olarak) ve genel girdileri (`bayt32` dizisi olarak), doğrulayıcının gerektirdiği biçimde alır (zincir üstü işlemeyi ve dolayısıyla gaz maliyetlerini en aza indirmek için). + +```solidity + require(_publicInputs[0] == currentStateHash, + "Wrong old state hash"); +``` + +Sıfır bilgi ispatının, işlemin mevcut karmamızdan yeni bir karma değerine değişmesi olması gerekir. + +```solidity + myVerifier.verify(_proof, _publicFields); +``` + +Sıfır bilgi ispatını doğrulamak için doğrulayıcı sözleşmesini çağırın. Bu adım, sıfır bilgi ispatı yanlışsa işlemi geri alır. + +```solidity + currentStateHash = _publicFields[1]; + + emit TransactionProcessed( + _publicFields[2]<<128 | _publicFields[3], + _publicFields[0], + _publicFields[1] + ); + } +} +``` + +Her şey yolundaysa, durum karmasını yeni değere güncelleyin ve bir `TransactionProcessed` olayı yayınlayın. + +## Merkezi bileşen tarafından yapılan suistimaller {#abuses} + +Bilgi güvenliği üç özellikten oluşur: + +- _Gizlilik_, kullanıcılar okumaya yetkili olmadıkları bilgileri okuyamazlar. +- _Bütünlük_, bilgi yalnızca yetkili kullanıcılar tarafından yetkili bir şekilde değiştirilebilir. +- _Kullanılabilirlik_, yetkili kullanıcılar sistemi kullanabilir. + +Bu sistemde bütünlük, sıfır bilgi ispatları aracılığıyla sağlanır. Kullanılabilirliği garanti etmek çok daha zordur ve gizlilik imkansızdır, çünkü bankanın her hesabın bakiyesini ve tüm işlemleri bilmesi gerekir. Bilgi sahibi bir varlığın bu bilgiyi paylaşmasını engellemenin bir yolu yoktur. + +[Gizli adresler](https://vitalik.eth.limo/general/2023/01/20/stealth.html) kullanarak gerçekten gizli bir banka oluşturmak mümkün olabilir, ancak bu bu makalenin kapsamı dışındadır. + +### Yanlış bilgi {#false-info} + +Sunucunun bütünlüğü ihlal etmesinin bir yolu, [veri istendiğinde](https://github.com/qbzzt/250911-zk-bank/blob/03-smart-contracts/server/index.mjs#L278-L291) yanlış bilgi sağlamaktır. + +Bunu çözmek için, hesapları özel bir girdi olarak ve bilgi istenen adresi genel bir girdi olarak alan ikinci bir Noir programı yazabiliriz. Çıktı, o adresin bakiyesi ve nonce'u ile hesapların karmasıdır. + +Elbette, bu kanıt zincir üstünde doğrulanamaz, çünkü nonce'ları ve bakiyeleri zincir üstünde yayınlamak istemiyoruz. Ancak, tarayıcıda çalışan istemci kodu tarafından doğrulanabilir. + +### Zorunlu işlemler {#forced-txns} + +L2'lerde kullanılabilirliği sağlamak ve sansürü önlemek için kullanılan normal mekanizma [zorunlu işlemlerdir](https://docs.optimism.io/stack/transactions/forced-transaction). Ancak zorunlu işlemler sıfır bilgi ispatlarıyla birleştirilmez. Sunucu, işlemleri doğrulayabilen tek varlıktır. + +`smart-contracts/src/ZkBank.sol` dosyasını, zorunlu işlemleri kabul edecek ve sunucunun işlenene kadar durumu değiştirmesini önleyecek şekilde değiştirebiliriz. Ancak bu, bizi basit bir hizmet reddi saldırısına açık hale getirir. Zorunlu bir işlem geçersizse ve bu nedenle işlenmesi imkansızsa ne olur? + +Çözüm, zorunlu bir işlemin geçersiz olduğuna dair bir sıfır bilgi ispatına sahip olmaktır. Bu, sunucuya üç seçenek sunar: + +- Zorunlu işlemi işleyin, işlendiğine dair bir sıfır bilgi ispatı ve yeni durum karmasını sağlayın. +- Zorunlu işlemi reddedin ve sözleşmeye işlemin geçersiz olduğuna (bilinmeyen adres, kötü nonce veya yetersiz bakiye) dair bir sıfır bilgi ispatı sağlayın. +- Zorunlu işlemi yoksayın. Sunucuyu işlemi gerçekten işlemeye zorlamanın bir yolu yoktur, ancak bu tüm sistemin kullanılamaz olduğu anlamına gelir. + +#### Kullanılabilirlik tahvilleri {#avail-bonds} + +Gerçek hayattaki bir uygulamada, muhtemelen sunucuyu çalışır durumda tutmak için bir tür kar amacı güdüsü olurdu. Sunucunun, zorunlu bir işlemin belirli bir süre içinde işlenmemesi durumunda herkesin yakabileceği bir kullanılabilirlik tahvili göndermesini sağlayarak bu teşviki güçlendirebiliriz. + +### Kötü Noir kodu {#bad-noir-code} + +Normalde, insanların bir akıllı sözleşmeye güvenmesini sağlamak için kaynak kodunu bir [blok gezginine](https://eth.blockscout.com/address/0x7D16d2c4e96BCFC8f815E15b771aC847EcbDB48b?tab=contract) yükleriz. Ancak, sıfır bilgi ispatları durumunda bu yetersizdir. + +`Verifier.sol`, Noir programının bir işlevi olan doğrulama anahtarını içerir. Ancak bu anahtar bize Noir programının ne olduğunu söylemez. Gerçekten güvenilir bir çözüme sahip olmak için, Noir programını (ve onu oluşturan sürümü) yüklemeniz gerekir. Aksi takdirde, sıfır bilgi ispatları farklı bir programı, arka kapısı olan bir programı yansıtabilir. + +Blok gezginleri Noir programlarını yüklememize ve doğrulamamıza izin vermeye başlayana kadar, bunu kendiniz yapmalısınız (tercihen [IPFS](/developers/tutorials/ipfs-decentralized-ui/)'e). Daha sonra gelişmiş kullanıcılar kaynak kodunu indirebilecek, kendileri derleyebilecek, `Verifier.sol` dosyasını oluşturabilecek ve zincir üzerindekiyle aynı olduğunu doğrulayabilecekler. + +## Sonuç {#conclusion} + +Plazma tipi uygulamalar, bilgi depolama olarak merkezi bir bileşen gerektirir. Bu, potansiyel güvenlik açıklarını ortaya çıkarır, ancak karşılığında blokzincirinin kendisinde bulunmayan şekillerde gizliliği korumamıza olanak tanır. Sıfır bilgi ispatlarıyla bütünlüğü sağlayabilir ve merkezi bileşeni çalıştıran kişinin kullanılabilirliği sürdürmesini ekonomik olarak avantajlı hale getirebiliriz. + +[Çalışmalarımdan daha fazlası için buraya bakın](https://cryptodocguy.pro/). + +## Teşekkürler {#acknowledgements} + +- Josh Crites bu makalenin bir taslağını okudu ve bana çetrefilli bir Noir konusunda yardım etti. + +Kalan hatalar benim sorumluluğumdadır. diff --git a/public/content/translations/tr/developers/tutorials/calling-a-smart-contract-from-javascript/index.md b/public/content/translations/tr/developers/tutorials/calling-a-smart-contract-from-javascript/index.md index 09d8b7ef258..258e781ff17 100644 --- a/public/content/translations/tr/developers/tutorials/calling-a-smart-contract-from-javascript/index.md +++ b/public/content/translations/tr/developers/tutorials/calling-a-smart-contract-from-javascript/index.md @@ -1,12 +1,8 @@ --- -title: JavaScript'ten bir akıllı sözleşme çağırmak -description: Dai token'ı örneğini kullanarak JavaScript'ten bir akıllı sözleşme fonksiyonu nasıl çağrılır +title: "JavaScript'ten bir akıllı sözleşme çağırmak" +description: "Dai jetonu örneğini kullanarak JavaScript'ten bir akıllı sözleşme işlevi nasıl çağrılır" author: jdourlens -tags: - - "İşlemler" - - "ön yüz" - - "JavaScript" - - "web3.js" +tags: [ "işlemler", "ön uç", "JavaScript", "web3.js" ] skill: beginner lang: tr published: 2020-04-19 @@ -15,15 +11,15 @@ sourceUrl: https://ethereumdev.io/calling-a-smart-contract-from-javascript/ address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" --- -Bu öğreticide, JavaScript'ten bir [akıllı sözleşme](/developers/docs/smart-contracts/) fonksiyonunun nasıl çağrılacağını göreceğiz. İlk önce bir akıllı sözleşmenin durumunu okuyoruz (örneğin bir ERC20 sahibinin bakiyesi), ardından bir token transferi yaparak blok zincirinin durumunu değiştireceğiz. [Blok zinciri ile etkileşim kurmak için bir JavaScript ortamı kurmaya](/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/) önceden aşina olmalısınız. +Bu öğreticide, JavaScript'ten bir [akıllı sözleşme](/developers/docs/smart-contracts/) işlevinin nasıl çağrılacağını göreceğiz. İlk olarak bir akıllı sözleşmenin durumunu okuyacağız (örneğin bir ERC20 sahibinin bakiyesi), ardından bir jeton transferi yaparak blokzincirin durumunu değiştireceğiz. [Blokzincir ile etkileşim kurmak için bir JS ortamı kurma](/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/) konusuna zaten aşina olmalısınız. -Bu örnekler için DAI token'ını ele alacağız, test amacıyla ganache-cli kullanarak blok zincirini çatallayacağız ve zaten çok fazla DAI içeren bir adresin kilidini açacağız: +Bu örnek için DAI jetonu ile oynayacağız, test amacıyla ganache-cli kullanarak blokzinciri çatallayacağız ve halihazırda çok fazla DAI'si olan bir adresin kilidini açacağız: ```bash -ganache-cli -f https://mainnet.infura.io/v3/[YOUR INFURA KEY] -d -i 66 1 --unlock 0x4d10ae710Bd8D1C31bd7465c8CBC3add6F279E81 +ganache-cli -f https://mainnet.infura.io/v3/[INFURA ANAHTARINIZ] -d -i 66 1 --unlock 0x4d10ae710Bd8D1C31bd7465c8CBC3add6F279E81 ``` -Akıllı bir sözleşmeyle etkileşim kurmak için bir adrese ve ABI'ye ihtiyacımız olacak: +Bir akıllı sözleşme ile etkileşim kurmak için adresine ve ABI'sine ihtiyacımız olacak: ```js const ERC20TransferABI = [ @@ -74,9 +70,9 @@ const ERC20TransferABI = [ const DAI_ADDRESS = "0x6b175474e89094c44da98b954eedeac495271d0f" ``` -Bu proje için, sadece `balanceOf` ve `transfer` fonksiyonunu korumak için tam ERC20 ABI'den bazı şeyleri çıkardık, ancak [eksiksiz ERC20 ABI'ye buradan](https://ethereumdev.io/abi-for-erc20-contract-on-ethereum/) ulaşabilirsiniz. +Bu proje için, yalnızca `balanceOf` ve `transfer` işlevini tutmak üzere ERC20 ABI'sinin tamamını çıkardık, ancak [tam ERC20 ABI'sini burada](https://ethereumdev.io/abi-for-erc20-contract-on-ethereum/) bulabilirsiniz. -Daha sonra akıllı sözleşmemizi somutlaştırmamız gerekiyor: +Daha sonra akıllı sözleşmemizin bir örneğini oluşturmamız gerekiyor: ```js const web3 = new Web3("http://localhost:8545") @@ -84,7 +80,7 @@ const web3 = new Web3("http://localhost:8545") const daiToken = new web3.eth.Contract(ERC20TransferABI, DAI_ADDRESS) ``` -Ayrıca iki adres kuracağız: +Ayrıca iki adres ayarlayacağız: - transferi alacak olan ve - zaten kilidini açtığımız, gönderecek olan: @@ -94,42 +90,42 @@ const senderAddress = "0x4d10ae710Bd8D1C31bd7465c8CBC3add6F279E81" const receiverAddress = "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" ``` -Sonraki bölümde, her iki adresin de tuttuğu mevcut token miktarını almak için `balanceOf` fonksiyonunu çağıracağız. +Sonraki bölümde, her iki adresin de sahip olduğu mevcut jeton miktarını almak için `balanceOf` işlevini çağıracağız. -## Call: Bir akıllı sözleşmeden değer okuma {#call-reading-value-from-a-smart-contract} +## Çağrı: Akıllı sözleşmeden değer okuma {#call-reading-value-from-a-smart-contract} -İlk satır bir "sabit" yöntemi getirecek ve akıllı sözleşme yöntemini herhangi bir işlem göndermeden EVM'de çalıştıracaktır. Bunun için bir adresin ERC20 bakiyesini okuyacağız. [ERC20 token'ları hakkındaki makalemizi okuyun](/developers/tutorials/understand-the-erc-20-token-smart-contract/). +İlk örnek, "sabit" bir metodu çağıracak ve akıllı sözleşme metodunu herhangi bir işlem göndermeden EVM'de yürütecektir. Bunun için bir adresin ERC20 bakiyesini okuyacağız. [ERC20 jetonları hakkındaki makalemizi okuyun](/developers/tutorials/understand-the-erc-20-token-smart-contract/). -ABI'yi sağladığınız somutlaştırılmış akıllı sözleşme yöntemlerine aşağıdaki şekilde erişebilirsiniz: `yourContract.methods.methodname`. `call` fonksiyonunu kullanarak fonksiyonu yürütmenin sonucunu alacaksınız. +ABI'sini sağladığınız, örneği oluşturulmuş bir akıllı sözleşmenin metotlarına şu şekilde erişebilirsiniz: `yourContract.methods.methodname`. `call` işlevini kullanarak, işlevi yürütmenin sonucunu alırsınız. ```js daiToken.methods.balanceOf(senderAddress).call(function (err, res) { if (err) { - console.log("An error occurred", err) + console.log("Bir hata oluştu", err) return } - console.log("The balance is: ", res) + console.log("Bakiye: ", res) }) ``` -DAI ERC20'nin 18 ondalık basamağa sahip olduğunu unutmayın; bu, doğru miktarı elde etmek için 18 sıfırı kaldırmanız gerektiği anlamına gelir. uint256, JavaScript büyük sayısal değerleri işlemediğinden dizgi olarak döndürülür. [JS'de büyük sayılarla nasıl başa çıkacağınızdan emin değilseniz, bignumber.js hakkındaki öğreticimize bakın](https://ethereumdev.io/how-to-deal-with-big-numbers-in-javascript/). +DAI ERC20'nin 18 ondalık basamağa sahip olduğunu unutmayın; bu, doğru miktarı elde etmek için 18 sıfırı kaldırmanız gerektiği anlamına gelir. JavaScript büyük sayısal değerleri işlemediğinden `uint256` değerleri dizge olarak döndürülür. JS'de büyük sayılarla nasıl başa çıkacağınızdan emin değilseniz, [bignumber.js hakkındaki öğreticimize göz atın](https://ethereumdev.io/how-to-deal-with-big-numbers-in-javascript/). -## Send: Akıllı sözleşme fonksiyonuna bir işlem gönderme {#send-sending-a-transaction-to-a-smart-contract-function} +## Gönderme: Bir akıllı sözleşme işlevine işlem gönderme {#send-sending-a-transaction-to-a-smart-contract-function} -İkinci örnek için, ikinci adresimize 10 DAI göndermek için DAI akıllı sözleşmesinin transfer fonksiyonunu çağıracağız. Transfer fonksiyonu 2 parametreyi kabul eder: alıcı adres ve transfer edilcek token miktarı: +İkinci örnek için, ikinci adresimize 10 DAI göndermek üzere DAI akıllı sözleşmesinin transfer işlevini çağıracağız. Transfer işlevi iki parametre kabul eder: alıcı adresi ve transfer edilecek jeton miktarı: ```js daiToken.methods .transfer(receiverAddress, "100000000000000000000") .send({ from: senderAddress }, function (err, res) { if (err) { - console.log("An error occurred", err) + console.log("Bir hata oluştu", err) return } - console.log("Hash of the transaction: " + res) + console.log("İşlemin karması: " + res) }) ``` -Çağırma fonksiyonu, blok zincirine kazılacak işlemin hash değerini döndürür. Ethereum'da işlem hash değerleri tahmin edilebilirdir: Bu sayede işlem yapılmadan önce işlemin hash değerini alabiliriz ([hash değerinin nasıl hesaplandığını buradan öğrenebilirsiniz](https://ethereum.stackexchange.com/questions/45648/how-to-calculate-the-assigned-txhash-of-a-transaction)). +Çağrı işlevi, blokzincire kazılacak olan işlemin karmasını döndürür. Ethereum'da, işlem karmaları tahmin edilebilirdir - bu sayede, bir işlemin karmasını daha yürütülmeden alabiliriz ([karmaların nasıl hesaplandığını buradan öğrenin](https://ethereum.stackexchange.com/questions/45648/how-to-calculate-the-assigned-txhash-of-a-transaction)). -Fonksiyon yalnızca işlemi blok zincirine gönderdiğinden, ne zaman çıkarıldığını ve blok zincirine dahil edildiğini öğrenene kadar sonucu göremeyiz. Bir sonraki öğreticide, [bir işlemin hash değerini öğrenerek işlemin blok zincirinde yürütülmesinin nasıl bekleneceğini](https://ethereumdev.io/waiting-for-a-transaction-to-be-mined-on-ethereum-with-js/) öğreneceğiz. +İşlev, işlemi yalnızca blokzincire gönderdiğinden, ne zaman kazıldığını ve blokzincire dahil edildiğini bilene kadar sonucu göremeyiz. Sonraki öğreticide, [karmasını bilerek bir işlemin blokzincirde yürütülmesini nasıl bekleyeceğimizi](https://ethereumdev.io/waiting-for-a-transaction-to-be-mined-on-ethereum-with-js/) öğreneceğiz. diff --git a/public/content/translations/tr/developers/tutorials/creating-a-wagmi-ui-for-your-contract/index.md b/public/content/translations/tr/developers/tutorials/creating-a-wagmi-ui-for-your-contract/index.md new file mode 100644 index 00000000000..b979392b4ac --- /dev/null +++ b/public/content/translations/tr/developers/tutorials/creating-a-wagmi-ui-for-your-contract/index.md @@ -0,0 +1,585 @@ +--- +title: "Sözleşmeniz için bir kullanıcı arayüzü oluşturma" +description: "TypeScript, React, Vite ve Wagmi gibi modern bileşenleri kullanarak modern ama minimal bir kullanıcı arayüzünü inceleyeceğiz ve bir cüzdanı kullanıcı arayüzüne bağlamayı, bilgi okumak için bir akıllı sözleşmeyi çağırmayı, bir akıllı sözleşmeye işlem göndermeyi ve değişiklikleri belirlemek için bir akıllı sözleşmedeki olayları izlemeyi öğreneceğiz." +author: Ori Pomerantz +tags: [ "typescript", "react", "vite", "wagmi", "ön uç" ] +skill: beginner +published: 2023-11-01 +lang: tr +sidebarDepth: 3 +--- + +Ethereum ekosisteminde ihtiyaç duyduğumuz bir özelliği buldunuz. Bunu uygulamak için akıllı sözleşmeleri ve hatta zincir dışında çalışan bazı ilgili kodları yazdınız. Bu harika! Maalesef, bir kullanıcı arayüzü olmadan herhangi bir kullanıcınız olmayacak ve son web sitesi yazdığınızda insanlar çevirmeli modem kullanıyordu ve JavaScript yeniydi. + +Bu makale sizin için. Programlama bildiğinizi, hatta belki biraz JavaScript ve HTML bildiğinizi, ancak kullanıcı arayüzü becerilerinizin körelmiş ve güncelliğini yitirmiş olduğunu varsayıyorum. Bugünlerde işlerin nasıl yapıldığını görmeniz için birlikte basit ve modern bir uygulamayı inceleyeceğiz. + +## Bu neden önemli {#why-important} + +Teoride, sözleşmelerinizle etkileşim kurmaları için insanların [Etherscan](https://holesky.etherscan.io/address/0x432d810484add7454ddb3b5311f0ac2e95cecea8#writeContract) veya [Blockscout](https://eth-holesky.blockscout.com/address/0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8?tab=write_contract) kullanmasını sağlayabilirsiniz. Bu, deneyimli Ethereum'cular için harika olacaktır. Ancak biz [bir milyar insana daha](https://blog.ethereum.org/2021/05/07/ethereum-for-the-next-billion) hizmet vermeye çalışıyoruz. Bu, harika bir kullanıcı deneyimi olmadan gerçekleşmez ve kullanıcı dostu bir arayüz bunun büyük bir parçasıdır. + +## Greeter uygulaması {#greeter-app} + +Modern bir kullanıcı arayüzünün nasıl çalıştığının arkasında pek çok teori ve [bunu açıklayan](https://wagmi.sh/core/getting-started) [birçok iyi site](https://react.dev/learn/thinking-in-react) var. Bu sitelerin yaptığı güzel işleri tekrarlamak yerine, yaparak öğrenmeyi tercih ettiğinizi varsayacağım ve oynayabileceğiniz bir uygulamayla başlayacağım. İşleri halletmek için yine de teoriye ihtiyacınız var ve buna da geleceğiz - sadece kaynak dosyadan kaynak dosyaya gideceğiz ve karşılaştıkça konuları tartışacağız. + +### Kurulum {#installation} + +1. Gerekirse, [Holesky blokzincirini](https://chainlist.org/?search=holesky&testnets=true) cüzdanınıza ekleyin ve [test ETH'si alın](https://www.holeskyfaucet.io/). + +2. Github deposunu klonlayın. + + ```sh + git clone https://github.com/qbzzt/20230801-modern-ui.git + ``` + +3. Gerekli paketleri yükleyin. + + ```sh + cd 20230801-modern-ui + pnpm install + ``` + +4. Uygulamayı başlatın. + + ```sh + pnpm dev + ``` + +5. Uygulamanın gösterdiği URL'ye gidin. Çoğu durumda bu [http://localhost:5173/](http://localhost:5173/) adresidir. + +6. Sözleşme kaynak kodunu, Hardhat'in Greeter'ının biraz değiştirilmiş bir sürümünü [bir blokzincir gezgininde](https://eth-holesky.blockscout.com/address/0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8?tab=contract) görebilirsiniz. + +### Dosya incelemesi {#file-walk-through} + +#### `index.html` {#index-html} + +Bu dosya, betik dosyasını içeri aktaran bu satır dışında standart bir HTML basmakalıp kodudur. + +```html + +``` + +#### `src/main.tsx` {#main-tsx} + +Dosya uzantısı bize bu dosyanın, [tür denetimini](https://en.wikipedia.org/wiki/Type_system#Type_checking) destekleyen bir JavaScript uzantısı olan [TypeScript](https://www.typescriptlang.org/) ile yazılmış bir [React bileşeni](https://www.w3schools.com/react/react_components.asp) olduğunu söyler. TypeScript, JavaScript'e derlenir, bu nedenle istemci tarafında yürütme için kullanabiliriz. + +```tsx +import '@rainbow-me/rainbowkit/styles.css' +import { RainbowKitProvider } from '@rainbow-me/rainbowkit' +import * as React from 'react' +import * as ReactDOM from 'react-dom/client' +import { WagmiConfig } from 'wagmi' +import { chains, config } from './wagmi' +``` + +İhtiyacımız olan kütüphane kodunu içe aktarın. + +```tsx +import { App } from './App' +``` + +Uygulamayı uygulayan React bileşenini içe aktarın (aşağıya bakın). + +```tsx +ReactDOM.createRoot(document.getElementById('root')!).render( +``` + +Kök React bileşenini oluşturun. `render` parametresi, hem HTML hem de JavaScript/TypeScript kullanan bir uzantı dili olan [JSX](https://www.w3schools.com/react/react_jsx.asp)'tir. Buradaki ünlem işareti, TypeScript bileşenine şunu söyler: "`document.getElementById('root')` ifadesinin `ReactDOM.createRoot` için geçerli bir parametre olacağını bilmiyorsun, ama endişelenme - ben geliştiriciyim ve sana olacağını söylüyorum". + +```tsx + +``` + +Uygulama, [bir `React.StrictMode` bileşeninin](https://react.dev/reference/react/StrictMode) içine giriyor. Bu bileşen, React kütüphanesine, geliştirme sırasında yararlı olan ek hata ayıklama kontrolleri eklemesini söyler. + +```tsx + +``` + +Uygulama ayrıca [bir `WagmiConfig` bileşeninin](https://wagmi.sh/react/api/WagmiProvider) içindedir. [wagmi (başaracağız) kütüphanesi](https://wagmi.sh/), bir Ethereum merkeziyetsiz uygulaması yazmak için React UI tanımlarını [viem kütüphanesi](https://viem.sh/) ile birleştirir. + +```tsx + +``` + +Ve son olarak, [bir `RainbowKitProvider` bileşeni](https://www.rainbowkit.com/). Bu bileşen, oturum açmayı ve cüzdan ile uygulama arasındaki iletişimi yönetir. + +```tsx + +``` + +Şimdi, kullanıcı arayüzünü gerçekten uygulayan uygulama bileşenine sahip olabiliriz. Bileşenin sonundaki `/>`, XML standardına göre bu bileşenin içinde herhangi bir tanım olmadığını React'e bildirir. + +```tsx + + + , +) +``` + +Elbette diğer bileşenleri de kapatmamız gerekiyor. + +#### `src/App.tsx` {#app-tsx} + +```tsx +import { ConnectButton } from '@rainbow-me/rainbowkit' +import { useAccount } from 'wagmi' +import { Greeter } from './components/Greeter' + +export function App() { +``` + +Bu, bir React bileşeni oluşturmanın standart yoludur - her işlenmesi gerektiğinde çağrılan bir işlev tanımlayın. Bu işlevin genellikle en üstünde TypeScript veya JavaScript kodu bulunur, ardından JSX kodunu döndüren bir `return` ifadesi gelir. + +```tsx + const { isConnected } = useAccount() +``` + +Burada, bir cüzdan aracılığıyla bir blokzincire bağlı olup olmadığımızı kontrol etmek için [`useAccount`](https://wagmi.sh/react/api/hooks/useAccount) kullanıyoruz. + +Geleneksel olarak, React'ta `use...` olarak adlandırılan işlevler, bir tür veri döndüren [kancalardır](https://www.w3schools.com/react/react_hooks.asp). Bu tür kancaları kullandığınızda, bileşeniniz yalnızca verileri almakla kalmaz, aynı zamanda bu veriler değiştiğinde bileşen güncellenmiş bilgilerle yeniden oluşturulur. + +```tsx + return ( + <> +``` + +Bir React bileşeninin JSX'i tek bir bileşen döndürmek _zorundadır_. Birden çok bileşenimiz olduğunda ve bunları "doğal olarak" saran bir şeyimiz olmadığında, boş bir bileşen kullanırız (`<> ...` `) onları tek bir bileşen haline getirmek için. + +```tsx +

Greeter

+ +``` + +[`ConnectButton` bileşenini](https://www.rainbowkit.com/docs/connect-button) RainbowKit'ten alıyoruz. Bağlı olmadığımızda, cüzdanları açıklayan ve hangisini kullandığınızı seçmenize izin veren bir kalıp açan bir `Cüzdan Bağla` düğmesi verir. Bağlandığımızda, kullandığımız blokzinciri, hesap adresimizi ve ETH bakiyemizi görüntüler. Ağı değiştirmek veya bağlantıyı kesmek için bu ekranları kullanabiliriz. + +```tsx + {isConnected && ( +``` + +Gerçek JavaScript'i (veya JavaScript'e derlenecek TypeScript'i) bir JSX'e eklememiz gerektiğinde, parantez (`{}`) kullanırız. + +`a && b` sözdizimi, [`a ?` için kısadır. b : a`](https://www.w3schools.com/react/react_es6_ternary.asp). Yani, `a`doğruysa`b`olarak değerlendirilir, aksi takdirde`a` olarak değerlendirilir (`false`, `0` vb. olabilir). Bu, React'e bir bileşenin yalnızca belirli bir koşul yerine getirildiğinde görüntülenmesi gerektiğini söylemenin kolay bir yoludur. + +Bu durumda, kullanıcıyı `Greeter` yalnızca kullanıcı bir blokzincire bağlıysa göstermek istiyoruz. + +```tsx + + )} + + ) +} +``` + +#### `src/components/Greeter.tsx` {#greeter-tsx} + +Bu dosya, kullanıcı arayüzü işlevselliğinin çoğunu içerir. Normalde birden çok dosyada olacak tanımları içerir, ancak bu bir öğretici olduğu için program, performans veya bakım kolaylığından ziyade ilk seferde anlaşılması kolay olacak şekilde optimize edilmiştir. + +```tsx +import { useState, ChangeEventHandler } from 'react' +import { useNetwork, + useReadContract, + usePrepareContractWrite, + useContractWrite, + useContractEvent + } from 'wagmi' +``` + +Bu kütüphane fonksiyonlarını kullanıyoruz. Yine, kullanıldıkları yerde aşağıda açıklanmıştır. + +```tsx +import { AddressType } from 'abitype' +``` + +[`abitype` kütüphanesi](https://abitype.dev/) bize [`AddressType`](https://abitype.dev/config#addresstype) gibi çeşitli Ethereum veri türleri için TypeScript tanımları sağlar. + +```tsx +let greeterABI = [ + . + . + . +] as const // greeterABI +``` + +`Greeter` sözleşmesi için ABI. +Sözleşmeleri ve kullanıcı arayüzünü aynı anda geliştiriyorsanız, normalde bunları aynı depoya koyar ve Solidity derleyicisi tarafından oluşturulan ABI'yi uygulamanızda bir dosya olarak kullanırsınız. Ancak, sözleşme zaten geliştirildiği ve değişmeyeceği için burada bu gerekli değildir. + +```tsx +type AddressPerBlockchainType = { + [key: number]: AddressType +} +``` + +TypeScript güçlü bir şekilde yazılmıştır. `Greeter` sözleşmesinin farklı zincirlerde dağıtıldığı adresi belirtmek için bu tanımı kullanırız. Anahtar bir sayıdır (chainId) ve değer bir `AddressType`'tır (bir adres). + +```tsx +const contractAddrs: AddressPerBlockchainType = { + // Holesky + 17000: '0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8', + + // Sepolia + 11155111: '0x7143d5c190F048C8d19fe325b748b081903E3BF0' +} +``` + +Desteklenen iki ağdaki sözleşmenin adresi: [Holesky](https://eth-holesky.blockscout.com/address/0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8?tab=contact_code) ve [Sepolia](https://eth-sepolia.blockscout.com/address/0x7143d5c190F048C8d19fe325b748b081903E3BF0?tab=contact_code). + +Not: Aslında Redstone Holesky için üçüncü bir tanım var, aşağıda açıklanacaktır. + +```tsx +type ShowObjectAttrsType = { + name: string, + object: any +} +``` + +Bu tür, `ShowObject` bileşenine (daha sonra açıklanacaktır) bir parametre olarak kullanılır. Hata ayıklama amacıyla görüntülenen nesnenin adını ve değerini içerir. + +```tsx +type ShowGreetingAttrsType = { + greeting: string | undefined +} +``` + +Herhangi bir zamanda, ya selamlamanın ne olduğunu biliyor olabiliriz (çünkü onu blokzincirden okuduk) ya da bilmiyor olabiliriz (çünkü henüz almadık). Bu nedenle, bir dize veya hiçbir şey olabilen bir türe sahip olmak yararlıdır. + +##### `Greeter` bileşeni {#greeter-component} + +```tsx +const Greeter = () => { +``` + +Sonunda bileşeni tanımlayacağız. + +```tsx + const { chain } = useNetwork() +``` + +[wagmi](https://wagmi.sh/react/hooks/useNetwork) sayesinde kullandığımız zincir hakkındaki bilgiler. +Bu bir kanca (`use...`) olduğu için, bu bilgi her değiştiğinde bileşen yeniden çizilir. + +```tsx + const greeterAddr = chain && contractAddrs[chain.id] +``` + +Greeter sözleşmesinin adresi, zincire göre değişir (ve zincir bilgimiz yoksa veya bu sözleşmenin olmadığı bir zincirdeysek `undefined` olur). + +```tsx + const readResults = useReadContract({ + address: greeterAddr, + abi: greeterABI, + functionName: "greet" , // No arguments + watch: true + }) +``` + +[`useReadContract` kancası](https://wagmi.sh/react/api/hooks/useReadContract), bir sözleşmeden bilgi okur. Kullanıcı arayüzünde `readResults`'ı genişleterek tam olarak hangi bilgileri döndürdüğünü görebilirsiniz. Bu durumda, selamlama değiştiğinde bilgilendirilmek için bakmaya devam etmesini istiyoruz. + +**Not:** Selamlamanın ne zaman değiştiğini bilmek ve bu şekilde güncelleme yapmak için [`setGreeting` olaylarını](https://eth-holesky.blockscout.com/address/0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8?tab=logs) dinleyebiliriz. Ancak, daha verimli olsa da, her durumda geçerli olmayacaktır. Kullanıcı farklı bir zincire geçtiğinde selamlama da değişir, ancak bu değişikliğe bir olay eşlik etmez. Kodun bir kısmı olayları dinlerken, diğeri zincir değişikliklerini belirlemek için kullanılabilir, ancak bu, sadece [`watch` parametresini](https://wagmi.sh/react/api/hooks/useReadContract#watch-optional) ayarlamaktan daha karmaşık olurdu. + +```tsx + const [ newGreeting, setNewGreeting ] = useState("") +``` + +React'in [`useState` kancası](https://www.w3schools.com/react/react_usestate.asp), değeri bileşenin bir oluşturulmasından diğerine devam eden bir durum değişkeni belirtmemizi sağlar. Başlangıç değeri, bu durumda boş dize olan parametredir. + +`useState` kancası iki değer içeren bir liste döndürür: + +1. Durum değişkeninin geçerli değeri. +2. Gerektiğinde durum değişkenini değiştirmek için bir işlev. Bu bir kanca olduğu için, her çağrıldığında bileşen yeniden oluşturulur. + +Bu durumda, kullanıcının ayarlamak istediği yeni selamlama için bir durum değişkeni kullanıyoruz. + +```tsx + const greetingChange : ChangeEventHandler = (evt) => + setNewGreeting(evt.target.value) +``` + +Bu, yeni selamlama giriş alanı değiştiğinde olay işleyicisidir. Tür, [`ChangeEventHandler`](https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/forms_and_events/), bunun bir HTML giriş öğesinin değer değişikliği için bir işleyici olduğunu belirtir. `` kısmı, bunun bir [genel tür](https://www.w3schools.com/typescript/typescript_basic_generics.php) olması nedeniyle kullanılır. + +```tsx + const preparedTx = usePrepareContractWrite({ + address: greeterAddr, + abi: greeterABI, + functionName: 'setGreeting', + args: [ newGreeting ] + }) + const workingTx = useContractWrite(preparedTx.config) +``` + +Bu, istemci perspektifinden bir blokzincir işlemini gönderme sürecidir: + +1. [`eth_estimateGas`](https://docs.alchemy.com/reference/eth-estimategas) kullanarak işlemi blokzincirdeki bir düğüme gönderin. +2. Düğümden bir yanıt bekleyin. +3. Yanıt alındığında, kullanıcıdan işlemi cüzdan aracılığıyla imzalamasını isteyin. Bu adım, düğüm yanıtı alındıktan sonra gerçekleşmek _zorundadır_, çünkü kullanıcıya işlemi imzalamadan önce işlemin gaz maliyeti gösterilir. +4. Kullanıcının onaylamasını bekleyin. +5. İşlemi bu kez [`eth_sendRawTransaction`](https://docs.alchemy.com/reference/eth-sendrawtransaction) kullanarak tekrar gönderin. + +Adım 2'nin algılanabilir bir süre alması muhtemeldir; bu süre zarfında kullanıcılar, komutlarının kullanıcı arayüzü tarafından gerçekten alınıp alınmadığını ve neden zaten işlemi imzalamaları istenmediğini merak ederler. Bu kötü bir kullanıcı deneyimi (UX) yaratır. + +Çözüm, [hazırlık kancalarını](https://wagmi.sh/react/prepare-hooks) kullanmaktır. Bir parametre her değiştiğinde, düğüme hemen `eth_estimateGas` isteğini gönderin. Ardından, kullanıcı işlemi gerçekten göndermek istediğinde (bu durumda **Selamlamayı güncelle**'ye basarak), gaz maliyeti bilinir ve kullanıcı cüzdan sayfasını hemen görebilir. + +```tsx + return ( +``` + +Şimdi nihayet döndürülecek gerçek HTML'yi oluşturabiliriz. + +```tsx + <> +

Greeter

+ { + !readResults.isError && !readResults.isLoading && + + } +
+``` + +Bir `ShowGreeting` bileşeni oluşturun (aşağıda açıklanmıştır), ancak yalnızca selamlama blokzincirden başarıyla okunduysa. + +```tsx + +``` + +Bu, kullanıcının yeni bir selamlama ayarlayabileceği giriş metin alanıdır. Kullanıcı bir tuşa her bastığında, `setNewGreeting`'i çağıran `greetingChange`'i çağırırız. `setNewGreeting`, `useState` kancasından geldiği için, `Greeter` bileşeninin yeniden oluşturulmasına neden olur. Bunun anlamı şudur: + +- Yeni selamlamanın değerini korumak için `değer` belirtmemiz gerekiyor, çünkü aksi takdirde varsayılan olan boş dizeye geri dönerdi. +- `usePrepareContractWrite`, `newGreeting` her değiştiğinde çağrılır, bu da hazırlanan işlemde her zaman en son `newGreeting`'e sahip olacağı anlamına gelir. + +```tsx + +``` + +`workingTx.write` yoksa, selamlama güncellemesini göndermek için gerekli bilgileri hâlâ bekliyoruz demektir, bu nedenle düğme devre dışı bırakılır. Bir `workingTx.write` değeri varsa, bu, işlemi göndermek için çağrılacak fonksiyondur. + +```tsx +
+ + + + + ) +} +``` + +Son olarak, ne yaptığımızı görmenize yardımcı olması için kullandığımız üç nesneyi gösterin: + +- `readResults` +- `preparedTx` +- `workingTx` + +##### `ShowGreeting` bileşeni {#showgreeting-component} + +Bu bileşen gösterir + +```tsx +const ShowGreeting = (attrs : ShowGreetingAttrsType) => { +``` + +Bir bileşen işlevi, bileşenin tüm özniteliklerini içeren bir parametre alır. + +```tsx + return {attrs.greeting} +} +``` + +##### `ShowObject` bileşeni {#showobject-component} + +Bilgi amaçlı olarak, önemli nesneleri (`readResults` selamlamayı okumak için ve `preparedTx` ve `workingTx` oluşturduğumuz işlemler için) göstermek için `ShowObject` bileşenini kullanırız. + +```tsx +const ShowObject = (attrs: ShowObjectAttrsType ) => { + const keys = Object.keys(attrs.object) + const funs = keys.filter(k => typeof attrs.object[k] == "function") + return <> +
+``` + +Kullanıcı arayüzünü tüm bilgilerle doldurmak istemiyoruz, bu nedenle bunları görüntülemeyi veya kapatmayı mümkün kılmak için bir [`ayrıntılar`](https://www.w3schools.com/tags/tag_details.asp) etiketi kullanıyoruz. + +```tsx + {attrs.name} +
+        {JSON.stringify(attrs.object, null, 2)}
+```
+
+Alanların çoğu [`JSON.stringify`](https://www.w3schools.com/js/js_json_stringify.asp) kullanılarak görüntülenir.
+
+```tsx
+      
+ { funs.length > 0 && + <> + Functions: +
    +``` + +İstisna, [JSON standardının](https://www.json.org/json-en.html) bir parçası olmayan işlevlerdir, bu nedenle ayrı olarak görüntülenmeleri gerekir. + +```tsx + {funs.map((f, i) => +``` + +JSX içinde, `{` küme parantezleri `}` içindeki kod, JavaScript olarak yorumlanır. Daha sonra, `(` normal parantezler `)` içindeki kod, tekrar JSX olarak yorumlanır. + +```tsx + (
  • {f}
  • ) + )} +``` + +React, [DOM Ağacındaki](https://www.w3schools.com/js/js_htmldom.asp) etiketlerin ayrı tanımlayıcılara sahip olmasını gerektirir. Bu, aynı etiketin alt öğelerinin (bu durumda, [sırasız liste](https://www.w3schools.com/tags/tag_ul.asp)) farklı `anahtar` özniteliklerine ihtiyaç duyduğu anlamına gelir. + +```tsx +
+ + } +
+ +} +``` + +Çeşitli HTML etiketlerini sonlandırın. + +##### Son `export` {#the-final-export} + +```tsx +export { Greeter } +``` + +`Greeter` bileşeni, uygulama için dışa aktarmamız gereken bileşendir. + +#### `src/wagmi.ts` {#wagmi-ts} + +Son olarak, WAGMI ile ilgili çeşitli tanımlar `src/wagmi.ts` içindedir. Burada her şeyi açıklamayacağım, çünkü çoğu değiştirmeniz gerekmeyecek basmakalıp bir koddur. + +Buradaki kod, [github'daki](https://github.com/qbzzt/20230801-modern-ui/blob/main/src/wagmi.ts) kodla tam olarak aynı değil, çünkü makalenin ilerleyen bölümlerinde başka bir zincir ekliyoruz ([Redstone Holesky](https://redstone.xyz/docs/network-info)). + +```ts +import { getDefaultWallets } from '@rainbow-me/rainbowkit' +import { configureChains, createConfig } from 'wagmi' +import { holesky, sepolia } from 'wagmi/chains' +``` + +Uygulamanın desteklediği blokzincirleri içe aktarın. Desteklenen zincirlerin listesini [viem github'da](https://github.com/wagmi-dev/viem/tree/main/src/chains/definitions) görebilirsiniz. + +```ts +import { publicProvider } from 'wagmi/providers/public' + +const walletConnectProjectId = 'c96e690bb92b6311e8e9b2a6a22df575' +``` + +[WalletConnect](https://walletconnect.com/) kullanabilmek için uygulamanız için bir proje kimliğine ihtiyacınız var. [cloud.walletconnect.com](https://cloud.walletconnect.com/sign-in) adresinden alabilirsiniz. + +```ts +const { chains, publicClient, webSocketPublicClient } = configureChains( + [ holesky, sepolia ], + [ + publicProvider(), + ], +) + +const { connectors } = getDefaultWallets({ + appName: 'My wagmi + RainbowKit App', + chains, + projectId: walletConnectProjectId, +}) + +export const config = createConfig({ + autoConnect: true, + connectors, + publicClient, + webSocketPublicClient, +}) + +export { chains } +``` + +### Başka bir blokzincir ekleme {#add-blockchain} + +Bu günlerde çok sayıda [L2 ölçeklendirme çözümü](/layer-2/) var ve viem'in henüz desteklemediği bazılarını desteklemek isteyebilirsiniz. Bunu yapmak için `src/wagmi.ts` dosyasını değiştirin. Bu talimatlar, [Redstone Holesky](https://redstone.xyz/docs/network-info) nasıl ekleneceğini açıklar. + +1. Viem'den `defineChain` türünü içe aktarın. + + ```ts + import { defineChain } from 'viem' + ``` + +2. Ağ tanımını ekleyin. + + ```ts + const redstoneHolesky = defineChain({ + id: 17_001, + name: 'Redstone Holesky', + network: 'redstone-holesky', + nativeCurrency: { + decimals: 18, + name: 'Ether', + symbol: 'ETH', + }, + rpcUrls: { + default: { + http: ['https://rpc.holesky.redstone.xyz'], + webSocket: ['wss://rpc.holesky.redstone.xyz/ws'], + }, + public: { + http: ['https://rpc.holesky.redstone.xyz'], + webSocket: ['wss://rpc.holesky.redstone.xyz/ws'], + }, + }, + blockExplorers: { + default: { name: 'Explorer', url: 'https://explorer.holesky.redstone.xyz' }, + }, + }) + ``` + +3. Yeni zinciri `configureChains` çağrısına ekleyin. + + ```ts + const { chains, publicClient, webSocketPublicClient } = configureChains( + [ holesky, sepolia, redstoneHolesky ], + [ publicProvider(), ], + ) + ``` + +4. Uygulamanın yeni ağdaki sözleşmelerinizin adresini bildiğinden emin olun. Bu durumda, `src/components/Greeter.tsx` dosyasını değiştiriyoruz: + + ```ts + const contractAddrs : AddressPerBlockchainType = { + // Holesky + 17000: '0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8', + + // Redstone Holesky + 17001: '0x4919517f82a1B89a32392E1BF72ec827ba9986D3', + + // Sepolia + 11155111: '0x7143d5c190F048C8d19fe325b748b081903E3BF0' + } + ``` + +## Sonuç {#conclusion} + +Elbette, `Greeter` için bir kullanıcı arayüzü sağlamakla gerçekten ilgilenmiyorsunuz. Kendi sözleşmeleriniz için bir kullanıcı arayüzü oluşturmak istiyorsunuz. Kendi uygulamanızı oluşturmak için şu adımları uygulayın: + +1. Bir wagmi uygulaması oluşturmayı belirtin. + + ```sh copy + pnpm create wagmi + ``` + +2. Uygulamayı adlandırın. + +3. **React** çerçevesini seçin. + +4. **Vite** varyantını seçin. + +5. [Rainbow kit ekleyebilirsiniz](https://www.rainbowkit.com/docs/installation#manual-setup). + +Şimdi gidin ve sözleşmelerinizi tüm dünyada kullanılabilir hale getirin. + +[Çalışmalarımdan daha fazlası için buraya bakın](https://cryptodocguy.pro/). + diff --git a/public/content/translations/tr/developers/tutorials/deploying-your-first-smart-contract/index.md b/public/content/translations/tr/developers/tutorials/deploying-your-first-smart-contract/index.md index e7a8ce5772c..03fb326af17 100644 --- a/public/content/translations/tr/developers/tutorials/deploying-your-first-smart-contract/index.md +++ b/public/content/translations/tr/developers/tutorials/deploying-your-first-smart-contract/index.md @@ -1,12 +1,8 @@ --- -title: İlk akıllı sözleşmenizi dağıtın -description: Ethereum test ağında ilk akıllı sözleşmenizi dağıtmaya giriş +title: "İlk akıllı sözleşmeni dağıtma" +description: "Bir Ethereum test ağında ilk akıllı sözleşmeni dağıtmaya giriş" author: "jdourlens" -tags: - - "akıllı sözleşmeler" - - "karışım" - - "katılık" - - "dağıtma" +tags: [ "akıllı kontratlar", "remix", "katılık", "dağıtma" ] skill: beginner lang: tr published: 2020-04-03 @@ -15,17 +11,17 @@ sourceUrl: https://ethereumdev.io/deploying-your-first-smart-contract/ address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" --- -Ethereum blok zincirinde ilk [akıllı sözleşmenizi](/developers/docs/smart-contracts/) [dağıtmak](/developers/docs/smart-contracts/deploying/) ve onunla etkileşimde bulunmak için eminiz ki siz de en az bizim kadar heyecanlısınızdır. +Sanırım sen de Ethereum blokzincirinde ilk [akıllı sözleşmeni](/developers/docs/smart-contracts/) [dağıtmaya](/developers/docs/smart-contracts/deploying/) ve onunla etkileşime geçmeye bizim kadar heveslisin. -Endişelenmeyin; bu sözleşmeyi [yerel test ağında](/developers/docs/networks/) yayınlayacağımız için size herhangi bir bedele mal olmayacak. Üzerinde dilediğiniz şekilde oynayabilirsiniz. +Endişelenme, bu ilk akıllı sözleşmemiz olduğu için onu [yerel bir test ağında](/developers/docs/networks/) dağıtacağız, böylece dağıtmak ve onunla dilediğince oynamak sana hiçbir maliyeti olmayacak. -## Sözleşmemizi yazmaya başlayalım {#writing-our-contract} +## Sözleşmemizi yazma {#writing-our-contract} -İlk adım olarak [Remix'e](https://remix.ethereum.org/) gidin ve yeni bir dosya oluşturun. Remix arayüzünün sol üst köşesinde yer alan yeni dosya simgesini kullanarak yeni bir dosya oluşturun ve dosyanıza isim verin. +İlk adım olarak [Remix'i ziyaret edip](https://remix.ethereum.org/) yeni bir dosya oluştur. Remix arayüzünün sol üst kısmından yeni bir dosya ekle ve istediğin dosya adını gir. -![Remix arayüzünde yeni dosya oluşturma](./remix.png) +![Remix arayüzünde yeni bir dosya ekleme](./remix.png) -Bu yeni dosyaya aşağıdaki kodu yapıştırıyoruz. +Yeni dosyaya aşağıdaki kodu yapıştıracağız. ```solidity // SPDX-License-Identifier: MIT @@ -33,15 +29,15 @@ pragma solidity >=0.5.17; contract Counter { - // Public variable of type unsigned int to keep the number of counts + // Sayım sayısını tutmak için işaretsiz tamsayı türünde herkese açık değişken uint256 public count = 0; - // Function that increments our counter + // Sayacımızı artıran fonksiyon function increment() public { count += 1; } - // Not necessary getter to get the count value + // Sayım değerini almak için gerekli olmayan alıcı function getCount() public view returns (uint256) { return count; } @@ -49,51 +45,51 @@ contract Counter { } ``` -Programlama konusunda bilgisi olanlar, bu programın ne yaptığını tahmin edeceklerdir. Satır satır açıklayacak olursak: +Programlamaya aşinaysan bu programın ne yaptığını kolayca tahmin edebilirsin. Satır satır açıklaması şöyledir: -- Satır 4: `Counter` adında yeni bir sözleşme tanımlıyoruz. -- Satır 7: Sözleşmemiz, ilk değeri 0 olan `count` adında bir işaretsiz tam sayı depoluyor. -- Satır 10: İlk fonksiyon, sözleşmenin durumunu değiştirir ve değişken `count` değerine `increment()` uygular. -- Satır 15: İkinci fonksiyon, basitçe `count` değerini akıllı sözleşmenin dışından okumamızı sağlayan bir alıcıdır. Aslında `count` değişkenini zaten herkesin erişime açık (public) tanımladığımız için bunu yapmamıza gerek yoktu ama sadece örnek olarak göstermek istedik. +- 4. Satır: `Counter` adıyla bir sözleşme tanımlıyoruz. +- 7. Satır: Sözleşmemiz, 0'dan başlayan `count` adında işaretsiz bir tamsayı depolar. +- 10. Satır: İlk fonksiyon, sözleşmenin durumunu değiştirir ve `count` değişkenimizi artırır. +- 15. Satır: İkinci fonksiyon, akıllı sözleşmenin dışından `count` değişkeninin değerini okuyabilmek için kullanılan bir alıcıdır. `count` değişkenimizi herkese açık (public) olarak tanımladığımız için bunun gerekli olmadığını, yalnızca örnek olarak gösterildiğini unutma. -İlk akıllı sözleşmemiz için hepsi bu kadar. Bildiğiniz gibi, Java veya C++ gibi OOP (Nesne Odaklı Programlama) dillerinden bir sınıfa benziyor. Şimdi sözleşmemizle oynamaya başlayalım. +İlk basit akıllı sözleşmemiz için hepsi bu kadar. Bilebileceğin üzere, bu Java veya C++ gibi OOP (Nesne Yönelimli Programlama) dillerindeki bir sınıfa benziyor. Şimdi sözleşmemizle oynama zamanı. ## Sözleşmemizi dağıtma {#deploying-our-contract} -Sözleşmemizle etkileşimde bulunabilmek için öncelikle onu blok zincirinde dağıtacağız. +İlk akıllı sözleşmemizi yazdığımıza göre, şimdi onunla oynayabilmek için blokzincirine dağıtacağız. -Bir [sözleşmeyi blok zincirinde dağıtmak](/developers/docs/smart-contracts/deploying/), aslında sadece sözleşme kodunun derlenmiş halini, herhangi bir alıcı belirtmeden, işlem olarak ağa göndermekten ibarettir. +[Akıllı sözleşmeyi blokzincirinde dağıtmak](/developers/docs/smart-contracts/deploying/), aslında derlenmiş akıllı sözleşmenin kodunu içeren bir işlemi herhangi bir alıcı belirtmeden göndermekten ibarettir. -Öncelikle sol tarafta yer alan derle simgesini kullanarak [sözleşmemizi derleyeceğiz](/developers/docs/smart-contracts/compiling/): +Önce, sol taraftaki derleme simgesine tıklayarak [sözleşmeyi derleyeceğiz](/developers/docs/smart-contracts/compiling/): ![Remix araç çubuğundaki derleme simgesi](./remix-compile-button.png) -Ardından Compile butonuna tıklayın: +Ardından derle düğmesine tıkla: -![Remix solidity derleyicisindeki compile (derle) düğmesi](./remix-compile.png) +![Remix Solidity derleyicisindeki derle düğmesi](./remix-compile.png) -Dilerseniz "Auto compile" seçeneğini seçebilirsiniz. Böylece sözleşmenizi güncellediğiniz zaman sözleşmeinz otomatik olarak derlenir. +İçeriği metin düzenleyiciye kaydettiğinde sözleşmenin her zaman derlenmesi için “Otomatik derle” seçeneğini tercih edebilirsin. -Ardından "deploy and run transactions" ekranına gidin: +Ardından "Dağıt ve işlemleri çalıştır" ekranına git: -![Remix araç çubuğundaki yayınla simgesi](./remix-deploy.png) +![Remix araç çubuğundaki dağıtma simgesi](./remix-deploy.png) -Bu ekranda öncelikle sözleşmeye verdiğimiz ismin göründüğünden emin olmalısınız. Sözleşme adını görüyorsanız Deploy butonuna tıklayın. Sayfanın üst kısmında görebileceğiniz gibi, mevcut ortam “Javascript VM”, yani bu daha hızlı ve herhangi bir ücret ödemeden test edebilmek için akıllı sözleşmemizi yerel bir test blok zincirinde dağıtıp etkileşime geçeceğimiz anlamına geliyor. +"Dağıt ve işlemleri çalıştır" ekranına geldiğinde, sözleşme adının göründüğünü kontrol et ve Dağıt'a tıkla. Sayfanın üst kısmında görebileceğin gibi, mevcut ortam “JavaScript VM”dir. Bu, daha hızlı ve hiçbir ücret ödemeden test edebilmek için akıllı sözleşmemizi yerel bir test blokzincirinde dağıtacağımız ve etkileşime gireceğimiz anlamına gelir. -![Remix solidity derleyicisindeki deploy (dağıt) düğmesi](./remix-deploy-button.png) +![Remix Solidity derleyicisindeki dağıt düğmesi](./remix-deploy-button.png) -"Deploy" düğmesine tıkladıktan sonra akıllı sözleşmemiz alt kısımda görünecek. Sol başındaki ok simgesini kullanarak sözleşmemizin içeriğini görüntüleyebiliriz. Bu, değişken `counter`'ımız (sayaç), `increment()` (artış) fonksiyonumuz ve alıcımız `getCounter()`'dır. +“Dağıt” düğmesine tıkladıktan sonra sözleşmenin en altta belirdiğini göreceksin. Sözleşmemizin içeriğini görmek için solundaki oka tıklayarak genişlet. Bu bizim `counter` değişkenimiz, `increment()` fonksiyonumuz ve `getCounter()` alıcımızdır. -Burada `count` veya `getCount` düğmelerine tıklarsanız, sözleşmede tanımlamış olduğumuz `count` değişkeninin içeriğini alıp görüntüleyebilirsiniz. Şu ana dek `increment` fonksiyonunu hiç çağırmadığımız için göreceğimiz değer 0 olmalı. +`count` veya `getCount` düğmesine tıklarsan sözleşmenin `count` değişkeninin içeriğini alır ve görüntüler. Henüz `increment` fonksiyonunu çağırmadığımız için 0 göstermesi gerekir. -![Remix solidity derleyicisindeki function (fonksiyon) düğmesi](./remix-function-button.png) +![Remix Solidity derleyicisindeki fonksiyon düğmesi](./remix-function-button.png) -Şimdi de düğmeye tıklayarak `increment` fonksiyonunu çağıralım. Ekranın alt kısmında gerçekleşmekte olan işleme ait işlem dökümlerini göreceksiniz. `increment` düğmesi yerine verileri alma düğmesine tıkladığınızda kayıtların farklı olduğunu göreceksiniz. Bunun sebebi, blok zincirindeki herhangi bir veriyi okumanın masrafsız ve işlem gerektirmeyen (kaydetmek anlamında) olmasıdır. Sadece blok zincirinin durumunu güncelleyen eylemler işlem olarak nitelendirilir: +Şimdi düğmeye tıklayarak `increment` fonksiyonunu çağıralım. Pencerenin en altında, yapılan işlemlerin kayıtlarının belirdiğini göreceksin. `increment` düğmesi yerine veriyi almak için olan düğmeye bastığında kayıtların farklı olduğunu göreceksin. Bunun nedeni, blokzincirinden veri okumanın herhangi bir işlem (yazma) veya ücret gerektirmemesidir. Çünkü sadece blokzincirinin durumunu değiştirmek bir işlem yapmayı gerektirir: -![İşlemlerin kaydı](./transaction-log.png) +![İşlemlerin bir kaydı](./transaction-log.png) -`increment()` fonksiyonumuzu çağırmak için bir işlem oluşturan increment düğmesine bastıktan sonra tekrar count veya getCount düğmelerine basarsak akıllı sözleşmemizin yeni güncellenmiş durumunu count değişkeninin 0'dan büyük olduğu hâliyle görebiliriz. +`increment()` fonksiyonumuzu çağırmak için bir işlem oluşturan increment düğmesine bastıktan sonra `count` veya `getCount` düğmelerine tekrar tıkladığımızda, akıllı sözleşmemizin yeni güncellenmiş durumunu `count` değişkeni 0'dan büyük olacak şekilde okuyacağız. ![Akıllı sözleşmenin yeni güncellenmiş durumu](./updated-state.png) -Sonraki öğreticimizde [akıllı sözleşmelere nasıl olay ekleyebileceğimizden](/developers/tutorials/logging-events-smart-contracts/) bahsedeceğiz. Olayları kayıt altına alarak akıllı sözleşmemizin hata ayıklamasını yapabilir ve fonksiyonları çağırdığımızda neler olduğunu ayrıntılı bir şekilde görebiliriz. +Bir sonraki öğreticide, [akıllı sözleşmelerinize nasıl olay ekleyebileceğinizi](/developers/tutorials/logging-events-smart-contracts/) ele alacağız. Olayları kaydetmek, akıllı sözleşmendeki hataları ayıklamak ve bir fonksiyonu çağırırken neler olduğunu anlamak için uygun bir yoldur. diff --git a/public/content/translations/tr/developers/tutorials/develop-and-test-dapps-with-a-multi-client-local-eth-testnet/index.md b/public/content/translations/tr/developers/tutorials/develop-and-test-dapps-with-a-multi-client-local-eth-testnet/index.md new file mode 100644 index 00000000000..56597b2b53d --- /dev/null +++ b/public/content/translations/tr/developers/tutorials/develop-and-test-dapps-with-a-multi-client-local-eth-testnet/index.md @@ -0,0 +1,372 @@ +--- +title: "Yerel, çok istemcili bir test ağında bir merkeziyetsiz uygulama nasıl geliştirilir ve test edilir" +description: "Bu kılavuz, test ağını bir merkeziyetsiz uygulamayı dağıtmak ve test etmek için kullanmadan önce, size çok istemcili bir yerel Ethereum test ağını nasıl somutlaştıracağınız ve yapılandıracağınız konusunda yol gösterecektir." +author: "Tedi Mitiku" +tags: + [ + "istemciler", + "düğümler", + "akıllı kontratlar", + "birleştirilebilirlik", + "mutabakat katmanı", + "yürütme katmanı", + "test etmek" + ] +skill: intermediate +lang: tr +published: 2023-04-11 +--- + +## Giriş {#introduction} + +Bu kılavuz, yapılandırılabilir bir yerel Ethereum test ağını somutlaştırma, ona bir akıllı sözleşme dağıtma ve merkeziyetsiz uygulamanıza karşı testler yürütmek için test ağını kullanma sürecinde size yol gösterir. Bu kılavuz, canlı bir test ağına veya ana ağa dağıtım yapmadan önce merkeziyetsiz uygulamalarını farklı ağ yapılandırmalarına karşı yerel olarak geliştirmek ve test etmek isteyen merkeziyetsiz uygulama geliştiricileri için tasarlanmıştır. + +Bu kılavuzda şunları yapacaksınız: + +- [Kurtosis](https://www.kurtosis.com/) kullanarak [`eth-network-package`](https://github.com/kurtosis-tech/eth-network-package) ile yerel bir Ethereum test ağı oluşturun, +- Bir merkeziyetsiz uygulamayı derlemek, dağıtmak ve test etmek için Hardhat merkeziyetsiz uygulama geliştirme ortamınızı yerel test ağına bağlayın ve +- Çeşitli ağ yapılandırmalarına karşı geliştirme ve test iş akışlarını etkinleştirmek için düğüm sayısı ve belirli YK/MK istemci eşleşmeleri gibi parametreler de dahil olmak üzere yerel test ağını yapılandırın. + +### Kurtosis nedir? {#what-is-kurtosis} + +[Kurtosis](https://www.kurtosis.com/), çok kapsayıcılı test ortamlarını yapılandırmak için tasarlanmış birleştirilebilir bir yapı sistemidir. Geliştiricilerin, blokzincir test ağları gibi dinamik kurulum mantığı gerektiren yeniden üretilebilir ortamlar oluşturmasını özellikle sağlar. + +Bu kılavuzda, Kurtosis eth-network-package, [`geth`](https://geth.ethereum.org/) Yürütme Katmanı (YK) istemcisinin yanı sıra [`teku`](https://consensys.io/teku), [`lighthouse`](https://lighthouse.sigmaprime.io/) ve [`lodestar`](https://lodestar.chainsafe.io/) Mutabakat Katmanı (MK) istemcileri desteğiyle yerel bir Ethereum test ağı oluşturur. Bu paket, Hardhat Network, Ganache ve Anvil gibi çerçevelerdeki ağlara yapılandırılabilir ve birleştirilebilir bir alternatif olarak hizmet eder. Kurtosis, geliştiricilere kullandıkları test ağları üzerinde daha fazla kontrol ve esneklik sunar; bu da [Ethereum Vakfı'nın Birleşim'i test etmek için Kurtosis'i kullanmasının](https://www.kurtosis.com/blog/testing-the-ethereum-merge) ve ağ yükseltmelerini test etmek için kullanmaya devam etmesinin önemli bir nedenidir. + +## Kurtosis'i kurma {#setting-up-kurtosis} + +Devam etmeden önce, şunlara sahip olduğunuzdan emin olun: + +- Yerel makinenizde [Docker motorunu kurun ve başlatın](https://docs.kurtosis.com/install/#i-install--start-docker) +- [Kurtosis CLI'yi yükleyin](https://docs.kurtosis.com/install#ii-install-the-cli) (veya CLI zaten yüklüyse en son sürüme yükseltin) +- [Node.js](https://nodejs.org/en), [yarn](https://classic.yarnpkg.com/lang/en/docs/install/#mac-stable) ve [npx](https://www.npmjs.com/package/npx) (merkeziyetsiz uygulama ortamınız için) yükleyin + +## Yerel bir Ethereum test ağı oluşturma {#instantiate-testnet} + +Yerel bir Ethereum test ağı başlatmak için şunu çalıştırın: + +```python +kurtosis --enclave local-eth-testnet run github.com/kurtosis-tech/eth-network-package +``` + +Not: Bu komut, `--enclave` bayrağını kullanarak ağınızı "local-eth-testnet" olarak adlandırır. + +Kurtosis, talimatları yorumlamak, doğrulamak ve ardından yürütmek için çalışırken perde arkasında attığı adımları yazdıracaktır. Sonunda, aşağıdakine benzer bir çıktı görmelisiniz: + +```python +INFO[2023-04-04T18:09:44-04:00] ====================================================== +INFO[2023-04-04T18:09:44-04:00] || Enclave oluşturuldu: local-eth-testnet || +INFO[2023-04-04T18:09:44-04:00] ====================================================== +Name: local-eth-testnet +UUID: 39372d756ae8 +Status: RUNNING +Creation Time: Tue, 04 Apr 2023 18:09:03 EDT + +========================================= Dosya Yapıtları ========================================= +UUID Name +d4085a064230 cl-genesis-data +1c62cb792e4c el-genesis-data +bd60489b73a7 genesis-generation-config-cl +b2e593fe5228 genesis-generation-config-el +d552a54acf78 geth-prefunded-keys +5f7e661eb838 prysm-password +054e7338bb59 validator-keystore-0 + +========================================== Kullanıcı Hizmetleri ========================================== +UUID Name Ports Status +e20f129ee0c5 cl-client-0-beacon http: 4000/tcp -> RUNNING + metrics: 5054/tcp -> + tcp-discovery: 9000/tcp -> 127.0.0.1:54263 + udp-discovery: 9000/udp -> 127.0.0.1:60470 +a8b6c926cdb4 cl-client-0-validator http: 5042/tcp -> 127.0.0.1:54267 RUNNING + metrics: 5064/tcp -> +d7b802f623e8 el-client-0 engine-rpc: 8551/tcp -> 127.0.0.1:54253 RUNNING + rpc: 8545/tcp -> 127.0.0.1:54251 + tcp-discovery: 30303/tcp -> 127.0.0.1:54254 + udp-discovery: 30303/udp -> 127.0.0.1:53834 + ws: 8546/tcp -> 127.0.0.1:54252 +514a829c0a84 prelaunch-data-generator-1680646157905431468 STOPPED +62bd62d0aa7a prelaunch-data-generator-1680646157915424301 STOPPED +05e9619e0e90 prelaunch-data-generator-1680646157922872635 STOPPED + +``` + +Tebrikler! Docker üzerinde bir MK (`lighthouse`) ve YK istemcisi (`geth`) ile yerel bir Ethereum test ağı oluşturmak için Kurtosis'i kullandınız. + +### Gözden Geçirme {#review-instantiate-testnet} + +Bu bölümde, bir Kurtosis [Enclave](https://docs.kurtosis.com/advanced-concepts/enclaves/) içinde yerel bir Ethereum test ağı başlatmak için Kurtosis'i GitHub'da uzaktan barındırılan [`eth-network-package`](https://github.com/kurtosis-tech/eth-network-package) kullanmaya yönlendiren bir komut yürüttünüz. Enclave'inizin içinde hem "dosya yapıtları" hem de "kullanıcı hizmetleri" bulacaksınız. + +Enclave'inizdeki [Dosya Yapıtları](https://docs.kurtosis.com/advanced-concepts/files-artifacts/), YK ve MK istemcilerini önyüklemek için oluşturulan ve kullanılan tüm verileri içerir. Veriler, bu [Docker görüntüsünden](https://github.com/ethpandaops/ethereum-genesis-generator) oluşturulan `prelaunch-data-generator` hizmeti kullanılarak oluşturuldu. + +Kullanıcı hizmetleri, enclave'inizde çalışan tüm kapsayıcılı hizmetleri görüntüler. Hem bir YK istemcisi hem de bir MK istemcisi içeren tek bir düğümün oluşturulduğunu fark edeceksiniz. + +## Merkeziyetsiz uygulama geliştirme ortamınızı yerel Ethereum test ağına bağlama {#connect-your-dapp} + +### Merkeziyetsiz uygulama geliştirme ortamını kurma {#set-up-dapp-env} + +Artık çalışan bir yerel test ağınız olduğuna göre, yerel test ağınızı kullanmak için merkeziyetsiz uygulama geliştirme ortamınızı bağlayabilirsiniz. Bu kılavuzda, yerel test ağınıza bir blackjack merkeziyetsiz uygulaması dağıtmak için Hardhat çerçevesi kullanılacaktır. + +Merkeziyetsiz uygulama geliştirme ortamınızı kurmak için, örnek merkeziyetsiz uygulamamızı içeren depoyu klonlayın ve bağımlılıklarını yükleyin, şunu çalıştırın: + +```python +git clone https://github.com/kurtosis-tech/awesome-kurtosis.git && cd awesome-kurtosis/smart-contract-example && yarn +``` + +Burada kullanılan [smart-contract-example](https://github.com/kurtosis-tech/awesome-kurtosis/tree/main/smart-contract-example) klasörü, [Hardhat](https://hardhat.org/) çerçevesini kullanan bir merkeziyetsiz uygulama geliştiricisi için tipik kurulumu içerir: + +- [`contracts/`](https://github.com/kurtosis-tech/awesome-kurtosis/tree/main/smart-contract-example/contracts) bir Blackjack merkeziyetsiz uygulaması için birkaç basit akıllı sözleşme içerir +- [`scripts/`](https://github.com/kurtosis-tech/awesome-kurtosis/tree/main/smart-contract-example/scripts) yerel Ethereum ağınıza bir jeton sözleşmesi dağıtmak için bir betik içerir +- [`test/`](https://github.com/kurtosis-tech/awesome-kurtosis/tree/main/smart-contract-example/test) Blackjack merkeziyetsiz uygulamamızdaki her oyuncu için 1000 jetonun basıldığını doğrulamak amacıyla jeton sözleşmeniz için basit bir .js testi içerir +- [`hardhat.config.ts`](https://github.com/kurtosis-tech/awesome-kurtosis/blob/main/smart-contract-example/hardhat.config.ts) Hardhat kurulumunuzu yapılandırır + +### Hardhat'i yerel test ağını kullanacak şekilde yapılandırma {#configure-hardhat} + +Merkeziyetsiz uygulama geliştirme ortamınız kurulduktan sonra, Kurtosis kullanılarak oluşturulan yerel Ethereum test ağını kullanmak için Hardhat'i bağlayacaksınız. Bunu başarmak için, `hardhat.config.ts` yapılandırma dosyanızdaki `localnet` yapısındaki `<$YOUR_PORT>` öğesini herhangi bir `el-client-` hizmetinden gelen rpc uri çıktısının bağlantı noktasıyla değiştirin. Bu örnek durumda, bağlantı noktası `64248` olacaktır. Sizin bağlantı noktanız farklı olacaktır. + +`hardhat.config.ts` içinde örnek: + +```js +localnet: { +url: 'http://127.0.0.1:<$YOUR_PORT>',// TODO: $YOUR_PORT'U ETH AĞI KURTOSIS PAKETİNİN ÜRETTİĞİ BİR DÜĞÜM URI'SİNİN BAĞLANTI NOKTASIYLA DEĞİŞTİRİN + +// Bunlar, eth-network-package tarafından oluşturulan önceden finanse edilmiş test hesaplarıyla ilişkili özel anahtarlardır +// +accounts: [ + "ef5177cd0b6b21c87db5a0bf35d4084a8a57a9d6a064f86d51ac85f2b873a4e2", + "48fcc39ae27a0e8bf0274021ae6ebd8fe4a0e12623d61464c498900b28feb567", + "7988b3a148716ff800414935b305436493e1f25237a2a03e5eebc343735e2f31", + "b3c409b6b0b3aa5e65ab2dc1930534608239a478106acf6f3d9178e9f9b00b35", + "df9bb6de5d3dc59595bcaa676397d837ff49441d211878c024eabda2cd067c9f", + "7da08f856b5956d40a72968f93396f6acff17193f013e8053f6fbb6c08c194d6", + ], +}, +``` + +Dosyanızı kaydettiğinizde, Hardhat merkeziyetsiz uygulama geliştirme ortamınız artık yerel Ethereum test ağınıza bağlanmış olur! Test ağınızın çalıştığını şu komutu çalıştırarak doğrulayabilirsiniz: + +```python +npx hardhat balances --network localnet +``` + +Çıktı şuna benzer görünmelidir: + +```python +0x878705ba3f8Bc32FCf7F4CAa1A35E72AF65CF766 has balance 10000000000000000000000000 +0x4E9A3d9D1cd2A2b2371b8b3F489aE72259886f1A has balance 10000000000000000000000000 +0xdF8466f277964Bb7a0FFD819403302C34DCD530A has balance 10000000000000000000000000 +0x5c613e39Fc0Ad91AfDA24587e6f52192d75FBA50 has balance 10000000000000000000000000 +0x375ae6107f8cC4cF34842B71C6F746a362Ad8EAc has balance 10000000000000000000000000 +0x1F6298457C5d76270325B724Da5d1953923a6B88 has balance 10000000000000000000000000 +``` + +Bu, Hardhat'in yerel test ağınızı kullandığını ve `eth-network-package` tarafından oluşturulan önceden finanse edilmiş hesapları algıladığını doğrular. + +### Merkeziyetsiz uygulamanızı yerel olarak dağıtın ve test edin {#deploy-and-test-dapp} + +Merkeziyetsiz uygulama geliştirme ortamı yerel Ethereum test ağına tamamen bağlandığında, artık yerel test ağını kullanarak merkeziyetsiz uygulamanıza karşı geliştirme ve test iş akışlarını çalıştırabilirsiniz. + +Yerel prototipleme ve geliştirme için `ChipToken.sol` akıllı sözleşmesini derlemek ve dağıtmak için şunu çalıştırın: + +```python +npx hardhat compile +npx hardhat run scripts/deploy.ts --network localnet +``` + +Çıktı şuna benzer görünmelidir: + +```python +ChipToken şuraya dağıtıldı: 0xAb2A01BC351770D09611Ac80f1DE076D56E0487d +``` + +Şimdi, Blackjack merkeziyetsiz uygulamamızdaki her oyuncu için 1000 jeton basıldığını doğrulamak için yerel merkeziyetsiz uygulamanıza karşı `simple.js` testini çalıştırmayı deneyin: + +Çıktı şuna benzer görünmelidir: + +```python +npx hardhat test --network localnet +``` + +Çıktı şuna benzer görünmelidir: + +```python +ChipToken + mint + ✔ PLAYER ONE için 1000 fiş basmalı + + 1 başarılı (654ms) +``` + +### Gözden Geçirme {#review-dapp-workflows} + +Bu noktada, bir merkeziyetsiz uygulama geliştirme ortamı kurdunuz, onu Kurtosis tarafından oluşturulan yerel bir Ethereum ağına bağladınız ve merkeziyetsiz uygulamanıza karşı basit bir test derlediniz, dağıttınız ve çalıştırdınız. + +Şimdi de, merkeziyetsiz uygulamalarımızı değişken ağ yapılandırmaları altında test etmek için temel ağı nasıl yapılandırabileceğinizi keşfedelim. + +## Yerel Ethereum test ağını yapılandırma {#configure-testnet} + +### İstemci yapılandırmalarını ve düğüm sayısını değiştirme {#configure-client-config-and-num-nodes} + +Yerel Ethereum test ağınız, geliştirmek veya test etmek istediğiniz senaryoya ve belirli ağ yapılandırmasına bağlı olarak, farklı YK ve MK istemci çiftlerinin yanı sıra değişen sayıda düğüm kullanacak şekilde yapılandırılabilir. Bu, kurulduktan sonra özelleştirilmiş bir yerel test ağı oluşturabileceğiniz ve aynı iş akışlarını (dağıtım, testler vb.) çalıştırmak için kullanabileceğiniz anlamına gelir. her şeyin beklendiği gibi çalıştığından emin olmak için çeşitli ağ yapılandırmaları altında. Değiştirebileceğiniz diğer parametreler hakkında daha fazla bilgi edinmek için bu bağlantıyı ziyaret edin. + +Deneyin! Bir JSON dosyası aracılığıyla `eth-network-package`'a çeşitli yapılandırma seçenekleri iletebilirsiniz. Bu ağ parametreleri JSON dosyası, Kurtosis'in yerel Ethereum ağını kurmak için kullanacağı belirli yapılandırmaları sağlar. + +Varsayılan yapılandırma dosyasını alın ve farklı YK/MK çiftlerine sahip üç düğüm başlatmak için düzenleyin: + +- Düğüm 1, `geth`/`lighthouse` ile +- Düğüm 2, `geth`/`lodestar` ile +- Düğüm 3, `geth`/`teku` ile + +Bu yapılandırma, merkeziyetsiz uygulamanızı test etmek için heterojen bir Ethereum düğüm uygulamaları ağı oluşturur. Yapılandırma dosyanız şimdi şöyle görünmelidir: + +```yaml +{ + "participants": + [ + { + "el_client_type": "geth", + "el_client_image": "", + "el_client_log_level": "", + "cl_client_type": "lighthouse", + "cl_client_image": "", + "cl_client_log_level": "", + "beacon_extra_params": [], + "el_extra_params": [], + "validator_extra_params": [], + "builder_network_params": null, + }, + { + "el_client_type": "geth", + "el_client_image": "", + "el_client_log_level": "", + "cl_client_type": "lodestar", + "cl_client_image": "", + "cl_client_log_level": "", + "beacon_extra_params": [], + "el_extra_params": [], + "validator_extra_params": [], + "builder_network_params": null, + }, + { + "el_client_type": "geth", + "el_client_image": "", + "el_client_log_level": "", + "cl_client_type": "teku", + "cl_client_image": "", + "cl_client_log_level": "", + "beacon_extra_params": [], + "el_extra_params": [], + "validator_extra_params": [], + "builder_network_params": null, + }, + ], + "network_params": + { + "preregistered_validator_keys_mnemonic": "giant issue aisle success illegal bike spike question tent bar rely arctic volcano long crawl hungry vocal artwork sniff fantasy very lucky have athlete", + "num_validator_keys_per_node": 64, + "network_id": "3151908", + "deposit_contract_address": "0x4242424242424242424242424242424242424242", + "seconds_per_slot": 12, + "genesis_delay": 120, + "capella_fork_epoch": 5, + }, +} +``` + +Her `participants` yapısı ağdaki bir düğüme karşılık gelir, bu nedenle 3 `participants` yapısı Kurtosis'e ağınızda 3 düğüm başlatmasını söyleyecektir. Her `participants` yapısı, o belirli düğüm için kullanılan YK ve MK çiftini belirtmenize olanak tanır. + +`network_params` yapısı, her düğüm için başlangıç dosyalarını oluşturmak için kullanılan ağ ayarlarını ve ağın yuva başına saniyesi gibi diğer ayarları yapılandırır. + +Düzenlenen parametreler dosyanızı istediğiniz herhangi bir dizine kaydedin (aşağıdaki örnekte masaüstüne kaydedilmiştir) ve ardından Kurtosis paketinizi çalıştırmak için şunu çalıştırın: + +```python +kurtosis clean -a && kurtosis run --enclave local-eth-testnet github.com/kurtosis-tech/eth-network-package "$(cat ~/eth-network-params.json)" +``` + +Not: `kurtosis clean -a` komutu, Kurtosis'e yeni bir tane başlatmadan önce eski test ağını ve içeriğini yok etmesi talimatını vermek için burada kullanılır. + +Yine Kurtosis bir süre çalışacak ve gerçekleşen adımları tek tek yazdıracaktır. Sonunda, çıktı şuna benzer görünmelidir: + +```python +Starlark kodu başarıyla çalıştırıldı. Çıktı döndürülmedi. +INFO[2023-04-07T11:43:16-04:00] ========================================================== +INFO[2023-04-07T11:43:16-04:00] || Enclave oluşturuldu: local-eth-testnet || +INFO[2023-04-07T11:43:16-04:00] ========================================================== +Name: local-eth-testnet +UUID: bef8c192008e +Status: RUNNING +Creation Time: Fri, 07 Apr 2023 11:41:58 EDT + +========================================= Dosya Yapıtları ========================================= +UUID Name +cc495a8e364a cl-genesis-data +7033fcdb5471 el-genesis-data +a3aef43fc738 genesis-generation-config-cl +8e968005fc9d genesis-generation-config-el +3182cca9d3cd geth-prefunded-keys +8421166e234f prysm-password +d9e6e8d44d99 validator-keystore-0 +23f5ba517394 validator-keystore-1 +4d28dea40b5c validator-keystore-2 + +========================================== Kullanıcı Hizmetleri ========================================== +UUID Name Ports Status +485e6fde55ae cl-client-0-beacon http: 4000/tcp -> http://127.0.0.1:65010 RUNNING + metrics: 5054/tcp -> http://127.0.0.1:65011 + tcp-discovery: 9000/tcp -> 127.0.0.1:65012 + udp-discovery: 9000/udp -> 127.0.0.1:54455 +73739bd158b2 cl-client-0-validator http: 5042/tcp -> 127.0.0.1:65016 RUNNING + metrics: 5064/tcp -> http://127.0.0.1:65017 +1b0a233cd011 cl-client-1-beacon http: 4000/tcp -> 127.0.0.1:65021 RUNNING + metrics: 8008/tcp -> 127.0.0.1:65023 + tcp-discovery: 9000/tcp -> 127.0.0.1:65024 + udp-discovery: 9000/udp -> 127.0.0.1:56031 + validator-metrics: 5064/tcp -> 127.0.0.1:65022 +949b8220cd53 cl-client-1-validator http: 4000/tcp -> 127.0.0.1:65028 RUNNING + metrics: 8008/tcp -> 127.0.0.1:65030 + tcp-discovery: 9000/tcp -> 127.0.0.1:65031 + udp-discovery: 9000/udp -> 127.0.0.1:60784 + validator-metrics: 5064/tcp -> 127.0.0.1:65029 +c34417bea5fa cl-client-2 http: 4000/tcp -> 127.0.0.1:65037 RUNNING + metrics: 8008/tcp -> 127.0.0.1:65035 + tcp-discovery: 9000/tcp -> 127.0.0.1:65036 + udp-discovery: 9000/udp -> 127.0.0.1:63581 +e19738e6329d el-client-0 engine-rpc: 8551/tcp -> 127.0.0.1:64986 RUNNING + rpc: 8545/tcp -> 127.0.0.1:64988 + tcp-discovery: 30303/tcp -> 127.0.0.1:64987 + udp-discovery: 30303/udp -> 127.0.0.1:55706 + ws: 8546/tcp -> 127.0.0.1:64989 +e904687449d9 el-client-1 engine-rpc: 8551/tcp -> 127.0.0.1:64993 RUNNING + rpc: 8545/tcp -> 127.0.0.1:64995 + tcp-discovery: 30303/tcp -> 127.0.0.1:64994 + udp-discovery: 30303/udp -> 127.0.0.1:58096 + ws: 8546/tcp -> 127.0.0.1:64996 +ad6f401126fa el-client-2 engine-rpc: 8551/tcp -> 127.0.0.1:65003 RUNNING + rpc: 8545/tcp -> 127.0.0.1:65001 + tcp-discovery: 30303/tcp -> 127.0.0.1:65000 + udp-discovery: 30303/udp -> 127.0.0.1:57269 + ws: 8546/tcp -> 127.0.0.1:65002 +12d04a9dbb69 prelaunch-data-generator-1680882122181135513 STOPPED +5b45f9c0504b prelaunch-data-generator-1680882122192182847 STOPPED +3d4aaa75e218 prelaunch-data-generator-1680882122201668972 STOPPED +``` + +Tebrikler! Yerel test ağınızı 1 yerine 3 düğüme sahip olacak şekilde başarıyla yapılandırdınız. Merkeziyetsiz uygulamanıza karşı daha önce yaptığınız iş akışlarını (dağıtma ve test etme) çalıştırmak için, `hardhat.config.ts` yapılandırma dosyanızdaki `localnet` yapısındaki `<$YOUR_PORT>` öğesini yeni, 3 düğümlü yerel test ağınızdaki herhangi bir `el-client-` hizmetinden gelen rpc uri çıktısının bağlantı noktasıyla değiştirerek daha önce yaptığımız işlemlerin aynısını gerçekleştirin. + +## Sonuç {#conclusion} + +İşte bu kadar! Bu kısa kılavuzu özetlemek gerekirse, şunları yaptınız: + +- Kurtosis kullanarak Docker üzerinde yerel bir Ethereum test ağı oluşturdunuz +- Yerel merkeziyetsiz uygulama geliştirme ortamınızı yerel Ethereum ağına bağladınız +- Yerel Ethereum ağında bir merkeziyetsiz uygulama dağıttınız ve ona karşı basit bir test çalıştırdınız +- Temel Ethereum ağını 3 düğüme sahip olacak şekilde yapılandırdınız + +Sizin için neyin iyi gittiğini, neyin iyileştirilebileceğini veya sorularınızı yanıtlamak için sizden haber bekliyoruz. [GitHub](https://github.com/kurtosis-tech/kurtosis/issues/new/choose) üzerinden ulaşmaktan veya [bize e-posta göndermekten](mailto:feedback@kurtosistech.com) çekinmeyin! + +### Diğer örnekler ve kılavuzlar {#other-examples-guides} + +Postgres veritabanı ve üzerine bir API oluşturacağınız [hızlı başlangıcımıza](https://docs.kurtosis.com/quickstart) ve harika örnekler bulacağınız [awesome-kurtosis depomuzdaki](https://github.com/kurtosis-tech/awesome-kurtosis) diğer örneklerimize göz atmanızı öneririz, bunlar arasında şunlar için paketler bulunur: + +- İşlemleri simüle etmek için bir işlem spam göndericisi, bir çatal izleyicisi ve bağlı bir Grafana ve Prometheus örneği gibi ek hizmetlerle bağlı olan [aynı yerel Ethereum test ağını başlatma](https://github.com/kurtosis-tech/eth2-package) +- Aynı yerel Ethereum ağına karşı bir [alt ağ testi](https://github.com/kurtosis-tech/awesome-kurtosis/tree/main/ethereum-network-partition-test) gerçekleştirme diff --git a/public/content/translations/tr/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md b/public/content/translations/tr/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md index d6c50a05428..15c954b0b89 100644 --- a/public/content/translations/tr/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md +++ b/public/content/translations/tr/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md @@ -1,12 +1,9 @@ --- title: "Sözleşme boyutu sınırıyla mücadele etmek için sözleşmelerin küçültülmesi" -description: Akıllı sözleşmelerinizin çok fazla büyümesini önlemek için ne yapabilirsiniz? +description: "Akıllı sözleşmelerinizin çok fazla büyümesini önlemek için ne yapabilirsiniz?" author: Markus Waas lang: tr -tags: - - "solidity" - - "akıllı kontratlar" - - "depolama" +tags: [ "katılık", "akıllı kontratlar", "depolama" ] skill: intermediate published: 2020-06-26 source: soliditydeveloper.com @@ -15,13 +12,13 @@ sourceUrl: https://soliditydeveloper.com/max-contract-size ## Neden bir sınır var? {#why-is-there-a-limit} -[22 Kasım 2016](https://blog.ethereum.org/2016/11/18/hard-fork-no-4-spurious-dragon/)'da Spurious Dragon sert çatalı 24,576 kb akıllı sözleşme boyutu sınırı ekleyen [EIP-170](https://eips.ethereum.org/EIPS/eip-170)'i tanıttı. Bir Solidity geliştiricisi olarak sizin için bu, sözleşmenize giderek daha fazla işlevsellik eklediğinizde, bir noktada sınıra ulaşacağınız ve dağıtım sırasında şu hatayı göreceğiniz anlamına gelir: +[22 Kasım 2016](https://blog.ethereum.org/2016/11/18/hard-fork-no-4-spurious-dragon/) tarihinde Sahte Ejderha sert çatallanması, 24,576 kb'lık bir akıllı sözleşme boyutu sınırı ekleyen [EIP-170](https://eips.ethereum.org/EIPS/eip-170)'i getirdi. Bir Solidity geliştiricisi olarak sizin için bu, sözleşmenize giderek daha fazla işlevsellik eklediğinizde, bir noktada sınıra ulaşacağınız ve dağıtım sırasında şu hatayı göreceğiniz anlamına gelir: `Warning: Contract code size exceeds 24576 bytes (a limit introduced in Spurious Dragon). Bu sözleşme Mainnet'te dağıtılamayabilir. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries.` Bu sınır, hizmet reddi (DOS) saldırılarını önlemek için getirildi. Bir sözleşmeye yapılan herhangi bir çağrı, gaz açısından nispeten ucuzdur. Bununla birlikte, Ethereum düğümleri için bir sözleşme çağrısının etkisi, çağrılan sözleşme kodunun boyutuna bağlı olarak orantısız bir şekilde artar (kodu diskten okumak, kodu önceden işlemek, Merkle kanıtına veri eklemek). Saldırganın başkaları için çok iş yapmak için az kaynağa ihtiyaç duyduğu böyle bir durumunuz olduğunda, DOS saldırıları potansiyeli elde edersiniz. -Bir doğal sözleşme boyutu limiti, blok gaz limiti olduğu için başlangıçta bu çok da büyük bir problem değildi. Açıkça görülüyor ki bir sözleşmenin, sözleşmenin tüm bit kodunu tutan bir işlem içinde dağıtılması gerekir. Bir bloğa yalnızca bir işlemi dahil ederseniz bu gazın tamamını kullanabilirsiniz, ancak bu sonsuz değildir. [Londra Yükseltmesi](/ethereum-forks/#london)'nden bu yana blok gaz limiti, ağ talebine bağlı olarak 15 milyon ile 30 milyon birim arasında değişti. +Bir doğal sözleşme boyutu limiti, blok gaz limiti olduğu için başlangıçta bu çok da büyük bir problem değildi. Açıkça görülüyor ki bir sözleşmenin, sözleşmenin tüm bit kodunu tutan bir işlem içinde dağıtılması gerekir. Bir bloğa yalnızca bir işlemi dahil ederseniz bu gazın tamamını kullanabilirsiniz, ancak bu sonsuz değildir. [Londra Yükseltmesi](/ethereum-forks/#london)'nden bu yana blok gaz limiti, ağ talebine bağlı olarak 15 milyon ile 30 milyon birim arasında değişebilmektedir. Aşağıda, potansiyel etkilerine göre sıralanan bazı yöntemlere bakacağız. Bunu, kilo verme gibi düşünün. Birinin hedef kilosuna (bizim durumumuzda 24 kb) ulaşması için en iyi strateji, önce büyük etkiye sahip yöntemlere odaklanmaktır. Çoğu zaman sadece diyeti düzeltmek amaca ulaştırır ancak bazen biraz daha fazlası gerekir. Sonra biraz egzersiz (orta etki) veya hatta takviye besinler (küçük etki) ekleyebilirsiniz. @@ -37,11 +34,11 @@ Bu her zaman ilk yaklaşımınız olmalıdır. Sözleşmeyi birden çok küçük ### Kütüphaneler {#libraries} -Fonksiyon kodunu depolama alanından uzaklaştırmanın basit bir yolu, bir [kütüphane](https://solidity.readthedocs.io/en/v0.6.10/contracts.html#libraries) kullanmaktır. Kütüphane fonksiyonları derleme esnasında doğrudan [sözleşmeye ekleneceği](https://ethereum.stackexchange.com/questions/12975/are-internal-functions-in-libraries-not-covered-by-linking) için onları dahili olarak duyurmayın. Ancak genel fonksiyonları kullanırsanız, bunlar aslında ayrı bir kütüphane sözleşmesinde olacaktır. Kütüphanelerin kullanımını daha uygun hâle getirmek için [using for](https://solidity.readthedocs.io/en/v0.6.10/contracts.html#using-for)'u göz önüne alın. +İşlevsellik kodunu depolamadan uzaklaştırmanın basit bir yolu, bir [kütüphane](https://solidity.readthedocs.io/en/v0.6.10/contracts.html#libraries) kullanmaktır. Kütüphane fonksiyonlarını `internal` olarak bildirmeyin, çünkü bunlar derleme sırasında doğrudan [sözleşmeye eklenecektir](https://ethereum.stackexchange.com/questions/12975/are-internal-functions-in-libraries-not-covered-by-linking). Ancak genel fonksiyonları kullanırsanız, bunlar aslında ayrı bir kütüphane sözleşmesinde olacaktır. Kütüphanelerin kullanımını daha kolay hale getirmek için [`using for`](https://solidity.readthedocs.io/en/v0.6.10/contracts.html#using-for) kullanmayı düşünün. ### Proxy'ler {#proxies} -Proxy sistemi, daha gelişmiş bir stratejidir. Kütüphaneler arka planda, çağıran sözleşmenin durumuyla başka bir sözleşmenin fonksiyonunu yürüten `DELEGATECALL` kullanır. Proxy'ler hakkında dahasını öğrenmek için [bu blog gönderisine](https://hackernoon.com/how-to-make-smart-contracts-upgradable-2612e771d5a2) bakın. Yükseltilebilirliği sağlamak gibi daha fazla işlevsellik sağlarlar ancak aynı zamanda çok fazla karmaşıklık da eklerler. Herhangi bir nedenle tek seçeneğiniz olmadıkça, bunları yalnızca sözleşme boyutlarını azaltmak için eklenmesini tavsiye etmem. +Proxy sistemi, daha gelişmiş bir stratejidir. Kütüphaneler arka planda, çağıran sözleşmenin durumuyla başka bir sözleşmenin fonksiyonunu yürüten DELEGATECALL kullanır. Proxy sistemleri hakkında daha fazla bilgi edinmek için [bu blog gönderisine](https://hackernoon.com/how-to-make-smart-contracts-upgradable-2612e771d5a2) göz atın. Yükseltilebilirliği sağlamak gibi daha fazla işlevsellik sağlarlar ancak aynı zamanda çok fazla karmaşıklık da eklerler. Herhangi bir nedenle tek seçeneğiniz olmadıkça, bunları yalnızca sözleşme boyutlarını azaltmak için eklenmesini tavsiye etmem. ## Orta etki {#medium-impact} @@ -54,8 +51,6 @@ Bu bariz bir yöntem. Fonksiyonlar, sözleşme boyutunu biraz artırır. ### Ek değişkenlerden kaçının {#avoid-additional-variables} -Bunun gibi küçük bir değişim: - ```solidity function get(uint id) returns (address,address) { MyStruct memory myStruct = myStructs[id]; @@ -69,7 +64,7 @@ function get(uint id) returns (address,address) { } ``` -**0,28kb**'lık bir fark yaratır. Muhtemelen sözleşmelerinizde birçok benzer durum vardır ve bunlar gerçekten önemli miktarlara ulaşabilir. +Bunun gibi basit bir değişiklik **0,28kb**'lık bir fark yaratır. Muhtemelen sözleşmelerinizde birçok benzer durum vardır ve bunlar gerçekten önemli miktarlara ulaşabilir. ### Hata mesajını kısaltın {#shorten-error-message} @@ -77,7 +72,6 @@ Uzun geri dönüş mesajları ve özellikle birçok farklı geri dönüş mesaj ```solidity require(msg.sender == owner, "Only the owner of this contract can call this function"); - ``` ```solidity @@ -96,15 +90,15 @@ if (msg.sender != owner) { } ``` -### Optimize edicide düşük bir çalıştırma değerini göz önünde bulundurun {#consider-a-low-run-value-in-the-optimizer} +### Optimize edicide düşük bir çalıştırma değeri düşünün {#consider-a-low-run-value-in-the-optimizer} -Optimize edici ayarlarını da değiştirebilirsiniz. 200 varsayılan değeri, bit kodunu bir fonksiyon 200 kez çağrılmış gibi optimize etmeye çalıştığı anlamına gelir. 1 olarak değiştirirseniz, temel olarak optimize ediciye her fonksiyonu yalnızca bir kez çalıştırma durumu için optimize etmesini söylersiniz. Yalnızca bir kez çalışmak için optimize edilmiş bir fonksiyon, dağıtımın kendisi için optimize edildiği anlamına gelir. Bunun, **işlevleri çalıştırmak için gereken [gaz maliyetlerini](/developers/docs/gas/) artırdığını unutmayın**, yani bunu yapmamak daha iyi olabilir. +Optimize edici ayarlarını da değiştirebilirsiniz. 200 varsayılan değeri, bit kodunu bir fonksiyon 200 kez çağrılmış gibi optimize etmeye çalıştığı anlamına gelir. 1 olarak değiştirirseniz, temel olarak optimize ediciye her fonksiyonu yalnızca bir kez çalıştırma durumu için optimize etmesini söylersiniz. Yalnızca bir kez çalışmak için optimize edilmiş bir fonksiyon, dağıtımın kendisi için optimize edildiği anlamına gelir. **Bunun, fonksiyonları çalıştırmak için gereken [gaz maliyetlerini](/developers/docs/gas/) artırdığını unutmayın**, bu yüzden bunu yapmak istemeyebilirsiniz. ## Küçük etki {#small-impact} -### Fonksiyonlara yapılar aktarmaktan kaçının {#avoid-passing-structs-to-functions} +### Yapıları (structs) fonksiyonlara geçirmekten kaçının {#avoid-passing-structs-to-functions} -Eğer [ABIEncoderV2](https://solidity.readthedocs.io/en/v0.6.10/layout-of-source-files.html#abiencoderv2) kullanıyorsanız bu, fonksiyonlara yapı aktarmamanıza yardımcı olabilir. Parametreyi bir yapı olarak aktarmaktansa... +[ABIEncoderV2](https://solidity.readthedocs.io/en/v0.6.10/layout-of-source-files.html#abiencoderv2) kullanıyorsanız, bir fonksiyona yapıları (structs) geçirmemek yardımcı olabilir. Parametreyi bir yapı (struct) olarak geçmek yerine gerekli parametreleri doğrudan geçin. Bu örnekte **0,1kb** daha kazandık. ```solidity function get(uint id) returns (address,address) { @@ -126,12 +120,10 @@ function _get(address addr1, address addr2) private view returns(address,address } ``` -...gerekli parametreleri doğrudan aktarın. Bu örnekte **0,1 kb** daha kazandık. - -### Fonksiyonlar ve değişkenler için doğru görünürlük duyurun {#declare-correct-visibility-for-functions-and-variables} +### Fonksiyonlar ve değişkenler için doğru görünürlüğü bildirin {#declare-correct-visibility-for-functions-and-variables} -- Yalnızca dışarıdan çağrılan fonksiyonlar veya değişkenler ne olacak? Onları `public` yerine `external` olarak duyurun. -- Yalnızca sözleşmenin içinden çağrılan fonksiyonlar veya değişkenler ne olacak? Onları `public` yerine `private` veya `external` olarak duyurun. +- Yalnızca dışarıdan çağrılan fonksiyonlar veya değişkenler ne olacak? Onları `public` yerine `external` olarak bildirin. +- Yalnızca sözleşmenin içinden çağrılan fonksiyonlar veya değişkenler ne olacak? Onları `public` yerine `private` veya `internal` olarak bildirin. ### Niteleyicileri kaldırın {#remove-modifiers} diff --git a/public/content/translations/tr/developers/tutorials/eip-1271-smart-contract-signatures/index.md b/public/content/translations/tr/developers/tutorials/eip-1271-smart-contract-signatures/index.md index d24ea9bd10e..8afc0384334 100644 --- a/public/content/translations/tr/developers/tutorials/eip-1271-smart-contract-signatures/index.md +++ b/public/content/translations/tr/developers/tutorials/eip-1271-smart-contract-signatures/index.md @@ -1,20 +1,22 @@ --- title: "EIP-1271: Akıllı Sözleşme İmzalarını İmzalama ve Doğrulama" -description: EIP-1271 ile Akıllı sözleşme imzası oluşturmaya ve doğrulamaya yönelik bir genel görünüm. Ayrıca akıllı sözleşme geliştiricilerinin üzerine geliştirme yapmaları amaçlı somut bir örnek sağlamak için "Safe"te (önceden adı Gnosis Safe'ti) kullanılan EIP-1271 uygulamasının üstünden geçeceğiz. +description: "EIP-1271 ile Akıllı sözleşme imzası oluşturmaya ve doğrulamaya yönelik bir genel görünüm. Ayrıca akıllı sözleşme geliştiricilerinin üzerine geliştirme yapmaları amaçlı somut bir örnek sağlamak için \"Safe\"te (önceden adı Gnosis Safe'ti) kullanılan EIP-1271 uygulamasının üstünden geçeceğiz." author: Nathan H. Leung lang: tr tags: - - "eip-1271" - - "akıllı sözleşmeler" - - "doğrulama" - - "imzalama" + [ + "eip-1271", + "akıllı kontratlar", + "doğrulama", + "imzalama" + ] skill: intermediate published: 2023-01-12 --- -[EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) standardı, akıllı sözleşmelerin imzaları doğrulayabilmesini sağlar. +[EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) standardı, akıllı sözleşmelerin imzaları doğrulamasına olanak tanır. -Bu öğreticide dijital imzalar, EIP-1271in arka planı ve [Safe](https://safe.global/)(önceden adı Gnosis Safe'ti) tarafından kullanılan spesifik EIP-1271 uygulaması hakkında genel bilgiler vereceğiz. Kısaca bu, EIP-1271'i kendi sözleşmelerinizde uygulayabilmek için bir başlangıç noktası olarak hizmet edebilir. +Bu öğreticide, dijital imzalara, EIP-1271'in arka planına ve [Safe](https://safe.global/) (eski adıyla Gnosis Safe) tarafından kullanılan özel EIP-1271 uygulamasına genel bir bakış sunuyoruz. Kısaca bu, EIP-1271'i kendi sözleşmelerinizde uygulayabilmek için bir başlangıç noktası olarak hizmet edebilir. ## İmza nedir? @@ -23,8 +25,8 @@ Bu bağlamda imza (daha doğrusu “dijital imza”), bir mesaj ve onunla birlik Örnek olarak, bir dijital imza şu şekilde görünebilir: 1. Mesaj: "Bu siteye Ethereum cüzdanımla girmek istiyorum". -2. İmzalayıcı: Benim adresim `0x000…` -3. Kanıt: İşte benim, `0x000…`, bu mesajın tamamını gerçekten oluşturduğumu gösteren kanıt (bu genelde kriptografik bir şeydir). +2. İmzalayıcı: Adresim `0x000…` +3. Kanıt: İşte ben, `0x000…`, bu mesajın tamamını gerçekten oluşturduğumun kanıtı (bu genellikle kriptografik bir şeydir). Dijital imzanın hem "mesaj" hem de "imza" içerdiğini tekrar hatırlatmakta fayda var. @@ -36,11 +38,11 @@ Aynı nedenle, dijital imzalar da ilişkili bir mesaj olmadan bir hiçtir! Ethereum tabanlı blokzincirlerde kullanılacak bir dijital imza oluşturmak için genelde kimsenin bilmediği gizli bir özel anahtara ihtiyacınız vardır. Bu, imzanızı sizin yapan şeydir (kimse gizli anahtarı bilmeden aynı imzayı yaratamaz). -Ethereum hesabınızın (harici olarak sahiplenilmiş hesabınız/EOA) kendisine bağlı bir özel anahtarı vardır ve bu, bir site veya merkeziyetsiz uygulama sizden bir imza istediğinizde tipik olarak kullandığınız anahtardır (örnek: "Ethereum ile giriş yapın" için). +Ethereum hesabınızın (yani harici olarak sahip olunan hesabınızın/EOA) ilişkili bir özel anahtarı vardır ve bu, bir web sitesi veya merkeziyetsiz uygulama sizden bir imza istediğinde (ör. “Ethereum ile Oturum Aç” için) genellikle kullanılan özel anahtardır. -Bir uygulama, [özel anahtarınızı bilmeden](https://en.wikipedia.org/wiki/Public-key_cryptography) ethers.js gibi bir üçüncü taraf kullanarak oluşturduğunuz bir [imzayı onaylayabilir](https://docs.alchemy.com/docs/how-to-verify-a-message-signature-on-ethereum)ve imzayı yaratanın _siz_ olduğunuza güvenebilir. +Bir uygulama, ethers.js gibi bir üçüncü taraf kütüphanesi kullanarak oluşturduğunuz bir imzayı [özel anahtarınızı bilmeden](https://en.wikipedia.org/wiki/Public-key_cryptography) [doğrulayabilir](https://www.alchemy.com/docs/how-to-verify-a-message-signature-on-ethereum) ve imzanın _sizin_ tarafınızdan oluşturulduğundan emin olabilir. -> EOA dijital imzaları, herkese açık anahtar kriptografisi kullandığı için **zincir dışında** oluşturulabilir ve doğrulanabilir! Gazsız DAO oylaması bu şekilde çalışır; oyları zincir üstünde göndermek yerine, kriptografik kütüphaneler kullanılarak zincir dışında dijital imzalar oluşturulabilir ve doğrulanabilir. +> Aslında, EOA dijital imzaları açık anahtar kriptografisi kullandığından, **zincir dışı** olarak oluşturulabilir ve doğrulanabilirler! Gazsız DAO oylaması bu şekilde çalışır — oyları zincir üstünde göndermek yerine, dijital imzalar kriptografik kütüphaneler kullanılarak zincir dışında oluşturulabilir ve doğrulanabilir. EOA hesapları bir özel anahtara sahipken, akıllı sözleşme hesaplarının bu türde bir özel ya da gizli anahtarı yoktur (yani "Ethereum'la giriş yapın" ve benzerleri, akıllı sözleşme hesaplarınızla yerel biçimde çalışamaz). @@ -50,17 +52,17 @@ EIP-1271'in çözmeyi hedeflediği problem: Eğer bir akıllı sözleşmenin imz Akıllı sözleşmelerin mesaj imzalamak için kullanabilecekleri özel anahtarları yoktur. O zaman bir imzanın özgün olduğunu nasıl anlayabiliriz? -Bir yolu, imzanın özgün olup olmadığını doğrudan akıllı sözleşmeye _sormak_ olabilir! +Bir fikir de, bir imzanın orijinal olup olmadığını doğrudan akıllı sözleşmeye _sormaktır_! EIP'nin yaptığı şey, bir akıllı sözleşmeye belirli bir imzanın geçerli olup olmadığını sorma fikrini standart hale getirmektir. -EIP-1271'i uygulayan bir sözleşmenin bir mesaj ve imzayı alan `isValidSignature` adında bir fonksiyonu olması gerekir. Sözleşme, sonrasında bir tür doğrulama mantığı yürütüp (burada spesifikasyon belirli bir şeyi uygulatmaz) ve imzanın geçerli olup olmadığını belirten bir değer döndürebilir. +EIP-1271'i uygulayan bir sözleşmenin, bir mesaj ve bir imza alan `isValidSignature` adında bir fonksiyonu olmalıdır. Sözleşme, sonrasında bir tür doğrulama mantığı yürütüp (burada spesifikasyon belirli bir şeyi uygulatmaz) ve imzanın geçerli olup olmadığını belirten bir değer döndürebilir. -Eğer `isValidSignature` geçerli bir sonuç döndürürse, sözleşmenin hemen hemen "evet, bu imzayı + mesajı onaylıyorum" dediği sonucuna ulaşılabilir! +Eğer `isValidSignature` geçerli bir sonuç döndürürse, bu, sözleşmenin “evet, bu imzayı + mesajı onaylıyorum!” dediği anlamına gelir. ### Arayüz -EIP-1271 spesifikasyonundaki arayüz tam olarak budur (aşağıda `hash` parametresi hakkında konuşacağız, fakat şimdilik bunu doğrulanmakta olan mesaj gibi düşünün): +İşte EIP-1271 spesifikasyonundaki arayüzün tam hali (aşağıda `_hash` parametresinden bahsedeceğiz, ancak şimdilik bunu doğrulanan mesaj olarak düşünebilirsiniz): ```jsx pragma solidity ^0.5.0; @@ -71,13 +73,13 @@ contract ERC1271 { bytes4 constant internal MAGICVALUE = 0x1626ba7e; /** - * @dev Should return whether the signature provided is valid for the provided hash - * @param _hash Hash of the data to be signed - * @param _signature Signature byte array associated with _hash + * @dev Sağlanan imzanın, sağlanan karma için geçerli olup olmadığını döndürmelidir + * @param _hash İmzalanacak verinin karması + * @param _signature _hash ile ilişkili imza bayt dizisi * - * MUST return the bytes4 magic value 0x1626ba7e when function passes. - * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5) - * MUST allow external calls + * Fonksiyon başarılı olduğunda 0x1626ba7e sihirli bytes4 değerini döndürmelidir. + * Durumu değiştirmemelidir (solc < 0.5 için STATICCALL, solc > 0.5 için view değiştiricisi kullanılır) + * Harici çağrılara izin vermelidir */ function isValidSignature( bytes32 _hash, @@ -90,28 +92,28 @@ contract ERC1271 { ## Örnek EIP-1271 Uygulaması: Safe -Sözleşmeler, `isValidSignature`'ı farklı şekillerde uygulayabilir; spesifikasyon kendi başına uygulama hakkında pek bir şey demez. +Sözleşmeler `isValidSignature` fonksiyonunu birçok farklı şekilde uygulayabilir — spesifikasyon tam olarak nasıl uygulanacağı hakkında pek bir şey söylemez. EIP-1271'i uygulayan göze çarpan sözleşmelerden biri Safe'tir (önceden adı Gnosis Safe'ti). -Safe'in kodunda `isValidSignature` [uygulanır](https://github.com/safe-global/safe-contracts/blob/main/contracts/handler/CompatibilityFallbackHandler.sol), bu sayede imzalar [iki farklı şekilde](https://ethereum.stackexchange.com/questions/122635/signing-messages-as-a-gnosis-safe-eip1271-support) oluşturulabilir ve doğrulanabilir: +Safe'in kodunda `isValidSignature`, imzaların [iki şekilde](https://ethereum.stackexchange.com/questions/122635/signing-messages-as-a-gnosis-safe-eip1271-support) oluşturulup doğrulanabilmesi için [şu şekilde uygulanmıştır](https://github.com/safe-global/safe-contracts/blob/main/contracts/handler/CompatibilityFallbackHandler.sol): 1. Zincir üstü mesajlar - 1. Oluşturma: bir Safe sahibi bir mesajı "imzalamak" için yeni bir Safe işlemi oluşturarak mesajı veri olarak işleme aktarır. Çoklu imza eşiğine ulaşabilmek için yeterli sayıda sahip işlemi imzaladığında, işlem yayımlanır ve çalıştırılır. İşlemde, mesajı onaylanmış mesajlar listesine ekleyen, çağrılan güvenli bir fonksiyon vardır. - 2. Doğrulama: Safe sözleşmesinde `isValidSignature`'ı çağırın ve mesajı, mesaj parametresi ve [imza parametresi için boş bir değer olarak doğrulamak üzere aktarın](https://github.com/safe-global/safe-contracts/blob/main/contracts/handler/CompatibilityFallbackHandler.sol#L32) (yani `0x`). Safe, imza parametresinin boş olduğunu görecek ve kriptografik olarak imzayı doğrulamak yerine, sadece devam etmesi ve mesajın "onaylanmış" mesajlar listesi içinde olup olmadığını kontrol etmesi gerektiğini bilecektir. + 1. Oluşturma: bir Safe sahibi bir mesajı "imzalamak" için yeni bir Safe işlemi oluşturarak mesajı veri olarak işleme aktarır. Çoklu imza eşiğine ulaşabilmek için yeterli sayıda sahip işlemi imzaladığında, işlem yayımlanır ve çalıştırılır. İşlemde, mesajı “onaylanmış” mesajlar listesine ekleyen `signMessage(bytes calldata _data)` adında bir Safe fonksiyonu bulunur. + 2. Doğrulama: Safe sözleşmesinde `isValidSignature` fonksiyonunu çağırın ve mesaj parametresi olarak doğrulanacak mesajı ve [imza parametresi için boş bir değeri](https://github.com/safe-global/safe-contracts/blob/main/contracts/handler/CompatibilityFallbackHandler.sol#L32) (yani `0x`) geçin. Safe, imza parametresinin boş olduğunu görecek ve kriptografik olarak imzayı doğrulamak yerine, sadece devam etmesi ve mesajın "onaylanmış" mesajlar listesi içinde olup olmadığını kontrol etmesi gerektiğini bilecektir. 2. Zincir dışı mesajlar: - 1. Oluşturma: bir Safe sahibi zincir dışı bir mesaj oluşturur, sonra da diğer Safe sahiplerin her birinin çoklu imza onaylanma eşiğine gelene kadar mesajı imzalamasını sağlar. - 2. Doğrulama: `isValidSignature`'ı çağırın. Mesaj parametresinde, doğrulanması gereken mesajı aktarın. İmza parametresinde, Safe sahiplerinin her birinin bireysel imzalarını sıralanmış şekilde arka arkaya aktarın. Safe, eşiğe ulaşmak için gerekli sayıda imza olup olmadığını **ve** her bir imzanın geçerli olup olmadığını kontrol edecektir. Eğer geçerliyse, imza doğrulamasının başarılı olduğunu belirten bir değer döndürecektir. + 1. Oluşturma: Bir Safe sahibi zincir dışı bir mesaj oluşturur, ardından çoklu imza onay eşiğini aşmak için yeterli imza olana kadar diğer Safe sahiplerinin her birinin mesajı ayrı ayrı imzalamasını sağlar. + 2. Doğrulama: `isValidSignature` fonksiyonunu çağırın. Mesaj parametresinde, doğrulanması gereken mesajı aktarın. İmza parametresinde, Safe sahiplerinin her birinin bireysel imzalarını sıralanmış şekilde arka arkaya aktarın. Safe, eşiği karşılamak için yeterli imza olup olmadığını **ve** her imzanın geçerli olup olmadığını kontrol edecektir. Eğer geçerliyse, imza doğrulamasının başarılı olduğunu belirten bir değer döndürecektir. ## `_hash` parametresi tam olarak nedir? Neden tüm mesajı aktarmıyoruz? -[EIP-1271 arayüzündeki](https://eips.ethereum.org/EIPS/eip-1271) `isValidSignature` fonksiyonunun mesaj yerine bir `_hash` parametresini aldığını fark etmiş olabilirsiniz. Bunun anlamı, `isValidSignature`'a keyfi uzunluktaki mesajın tamamını aktarmak yerine, mesajın 32 baytlık bir düğümünü (genelde keccak256) aktarıyor olmamızdır. +[EIP-1271 arayüzündeki](https://eips.ethereum.org/EIPS/eip-1271) `isValidSignature` fonksiyonunun mesajın kendisini değil, bunun yerine bir `_hash` parametresi aldığını fark etmiş olabilirsiniz. Bunun anlamı, `isValidSignature`'a değişken uzunluktaki mesajın tamamını geçmek yerine, mesajın 32 baytlık bir karmasını (genellikle keccak256) geçmemizdir. -Çağrı verisinin her baytı, yani bir akıllı sözleşmeye aktarılan fonksiyon parametresi verilerinin maliyeti [16 gazdır (sıfır baytsa 4 gaz)](https://eips.ethereum.org/EIPS/eip-2028), yani bir mesaj uzunsa gazdan ciddi şekilde tasarruf edilebilir. +`calldata`nın her baytı — yani, bir akıllı sözleşme fonksiyonuna geçirilen fonksiyon parametre verileri — [16 gaz maliyetindedir (sıfır bayt ise 4 gaz)](https://eips.ethereum.org/EIPS/eip-2028), bu nedenle bir mesaj uzunsa çok fazla gaz tasarrufu sağlayabilir. ### Önceki EIP-1271 Spesifikasyonları -Etrafta ilk parametresi `bytes` (sabit uzunluk yerine keyfi uzunlukta `bytes32`) olan ve parametre ismi `message` olan `isValidSignature` fonksiyonlu EIP-1271 spesifikasyonları mevcuttur. Bu, EIP-1271 standardının [eski](https://github.com/safe-global/safe-contracts/issues/391#issuecomment-1075427206) bir versiyonudur. +Piyasada, `isValidSignature` fonksiyonunun ilk parametresinin `message` adında ve `bytes` türünde (sabit uzunluklu `bytes32` yerine değişken uzunluklu) olduğu EIP-1271 spesifikasyonları bulunmaktadır. Bu, EIP-1271 standardının [eski bir sürümüdür](https://github.com/safe-global/safe-contracts/issues/391#issuecomment-1075427206). ## EIP-1271 benim sözleşmelerime nasıl uygulanmalıdır? @@ -124,4 +126,4 @@ Sonuçta, bu sözleşme geliştiricisi olarak size kalmış! ## Sonuç -[EIP-1271](https://eips.ethereum.org/EIPS/eip-1271), akıllı sözleşmelerin imzaları doğrulayabilmelerini sağlayan çok yönlü bir standarttır. Akıllı sözleşmelerin EOA'lar gibi hareket edebilmelerini sağlar; örnek olarak, "Ethereum'la giriş yapın" ifadesinin akıllı sözleşmelerle çalışabilmesine olanak tanır ve birçok farklı şekilde uygulanabilir (Safe'in anlaşılması zor ve ilginç uygulamasını da göz önünde bulundurarak). +[EIP-1271](https://eips.ethereum.org/EIPS/eip-1271), akıllı sözleşmelerin imzaları doğrulamasına olanak tanıyan çok yönlü bir standarttır. Akıllı sözleşmelerin EOA'lar gibi hareket edebilmelerini sağlar; örnek olarak, "Ethereum'la giriş yapın" ifadesinin akıllı sözleşmelerle çalışabilmesine olanak tanır ve birçok farklı şekilde uygulanabilir (Safe'in anlaşılması zor ve ilginç uygulamasını da göz önünde bulundurarak). diff --git a/public/content/translations/tr/developers/tutorials/erc-721-vyper-annotated-code/index.md b/public/content/translations/tr/developers/tutorials/erc-721-vyper-annotated-code/index.md index 25254b47a84..78e6ba0ceac 100644 --- a/public/content/translations/tr/developers/tutorials/erc-721-vyper-annotated-code/index.md +++ b/public/content/translations/tr/developers/tutorials/erc-721-vyper-annotated-code/index.md @@ -1,31 +1,32 @@ --- title: "Vyper ERC-721 Sözleşmesine Genel Bakış" -description: Ryuya Nakamura'nın ERC-721 sözleşmesi ve nasıl çalıştığı +description: "Ryuya Nakamura'nın ERC-721 sözleşmesi ve nasıl çalıştığı" author: Ori Pomerantz lang: tr -tags: - - "vyper" - - "erc-721" - - "python" +tags: [ "vyper", "erc-721", "python" ] skill: beginner published: 2021-04-01 --- ## Giriş {#introduction} -[ERC-721](/developers/docs/standards/tokens/erc-721/) standardı, Değiştirilemez Token'ların (NFT) sahipliğini tutmak için kullanılır. [ERC-20](/developers/docs/standards/tokens/erc-20/) token'ları, bireysel token'lar arasında bir fark olmadığı için bir emtia gibidir. Bunun aksine ERC-721 token'ları, farklı [kedi karikatürleri](https://www.cryptokitties.co/) veya farklı gayrimenkul parçalarına verilen unvanlar gibi benzer ancak aynı olmayan varlıklar için tasarlanmıştır. +[ERC-721](/developers/docs/standards/tokens/erc-721/) standardı, Değiştirilemez Jetonların (NFT) sahipliğini tutmak için kullanılır. +[ERC-20](/developers/docs/standards/tokens/erc-20/) jetonları, bireysel jetonlar arasında bir fark olmadığı için bir emtia gibi davranır. +Bunun aksine, ERC-721 jetonları, farklı kedi +çizgi filmleri veya farklı gayrimenkullerin tapuları gibi benzer ancak birebir aynı olmayan varlıklar için tasarlanmıştır. -Bu makalede [Ryuya Nakamura'nın ERC-721 sözleşmesini](https://github.com/vyperlang/vyper/blob/master/examples/tokens/ERC721.vy) analiz edeceğiz. Bu sözleşme, güvensiz kod yazmayı Solidity'de olduğundan daha zorlaştırmak için dizayn edilmiş Python benzeri bir sözleşme dili olan [Vyper](https://vyper.readthedocs.io/en/latest/index.html) ile yazılmıştır. +Bu makalede [Ryuya Nakamura'nın ERC-721 sözleşmesini](https://github.com/vyperlang/vyper/blob/master/examples/tokens/ERC721.vy) analiz edeceğiz. +Bu sözleşme, güvensiz kod yazmayı Solidity'de olduğundan daha zorlaştırmak için tasarlanmış Python benzeri bir sözleşme dili olan [Vyper](https://vyper.readthedocs.io/en/latest/index.html) ile yazılmıştır. ## Sözleşme {#contract} ```python -# @dev Implementation of ERC-721 non-fungible token standard. -# @author Ryuya Nakamura (@nrryuya) -# Modified from: https://github.com/vyperlang/vyper/blob/de74722bf2d8718cca46902be165f9fe0e3641dd/examples/tokens/ERC721.vy +# @dev ERC-721 değiştirilemez jeton standardının uygulaması. +# @yazar Ryuya Nakamura (@nrryuya) +# Şuradan değiştirildi: https://github.com/vyperlang/vyper/blob/de74722bf2d8718cca46902be165f9fe0e3641dd/examples/tokens/ERC721.vy ``` -Python'da olduğu gibi Vyper'da da yorumlar bir hash (`#`) ile başlar ve satırın sonuna kadar devam eder. `@` içeren yorumlar insan tarafından okunabilir belgeler oluşturmak için [NatSpec](https://vyper.readthedocs.io/en/latest/natspec.html) tarafından kullanılır. +Python'da olduğu gibi Vyper'da da yorumlar bir kare işareti (`#`) ile başlar ve satırın sonuna kadar devam eder. `@` içeren yorumlar, [NatSpec](https://vyper.readthedocs.io/en/latest/natspec.html) tarafından insanlar tarafından okunabilir belgeler oluşturmak için kullanılır. ```python from vyper.interfaces import ERC721 @@ -33,37 +34,40 @@ from vyper.interfaces import ERC721 implements: ERC721 ``` -ERC-721 arayüzü, Vyper dilinde yerleşiktir. [Kod tanımlamasını burada görebilirsiniz](https://github.com/vyperlang/vyper/blob/master/vyper/builtin_interfaces/ERC721.py). Arayüz tanımı Vyper yerine Python'da yazılmıştır, çünkü arayüzler yalnızca blok zinciri içinde değil, blok zincirine Python'da yazılabilen harici bir istemciden bir işlem gönderirken de kullanılır. +ERC-721 arayüzü, Vyper dilinde yerleşiktir. +[Kod tanımını burada görebilirsiniz](https://github.com/vyperlang/vyper/blob/master/vyper/builtin_interfaces/ERC721.py). +Arayüz tanımı Vyper yerine Python'da yazılmıştır, çünkü arayüzler yalnızca blokzincir içinde değil, blokzincire Python ile yazılabilen harici bir istemciden bir işlem gönderilirken de kullanılır. İlk satır, arayüzü içe aktarır ve ikincisi onu burada uyguladığımızı belirtir. ### ERC721Receiver Arayüzü {#receiver-interface} ```python -# Interface for the contract called by safeTransferFrom() +# safeTransferFrom() tarafından çağrılan sözleşme için arayüz interface ERC721Receiver: def onERC721Received( ``` ERC-721 iki tür aktarımı destekler: -- `transferFrom`, gönderenin herhangi bir hedef adresi belirlemesine izin verir ve transfer sorumluluğunu gönderene yükler. Bu, geçersiz bir adrese transfer yapabileceğiniz anlamına gelir, bu durumda NFT tamamen kaybolur. -- Hedef adresin bir sözleşme olduğunu kontrol eden `safeTransferFrom`. Eğer öyleyse, ERC-721 sözleşmesi alıcı sözleşmeye NFT'yi almak isteyip istemediğini sorar. +- `transferFrom`, göndericinin herhangi bir hedef adresi belirtmesine olanak tanır ve aktarım sorumluluğunu göndericiye yükler. Bu, geçersiz bir adrese aktarım yapabileceğiniz anlamına gelir, bu durumda + NFT tamamen kaybolur. +- `safeTransferFrom`, hedef adresin bir sözleşme olup olmadığını kontrol eder. Eğer öyleyse, ERC-721 sözleşmesi alıcı sözleşmeye NFT'yi almak isteyip istemediğini sorar. -`safeTransferFrom` isteklerini yanıtlamak için bir alıcı sözleşmesinin `ERC721Receiver` uygulaması gerekir. +`safeTransferFrom` isteklerine yanıt vermek için alıcı bir sözleşmenin `ERC721Receiver`'ı uygulaması gerekir. ```python _operator: address, _from: address, ``` -`_from` adresi token'ın mevcut sahibidir. `_operator` adresi, transferi talep eden adrestir (ödenekler nedeniyle bu ikisi aynı olmayabilir). +`_from` adresi jetonun mevcut sahibidir. `_operator` adresi, aktarımı talep eden adrestir (ödenekler nedeniyle bu ikisi aynı olmayabilir). ```python _tokenId: uint256, ``` -ERC-721 token ID'leri 256 bittir. Tipik olarak, token'ın temsil ettiği şeyin bir açıklamasının hash edilmesiyle oluşturulurlar. +ERC-721 jeton ID'leri 256 bittir. Tipik olarak, jetonun temsil ettiği şeyin bir açıklamasının hash edilmesiyle oluşturulurlar. ```python _data: Bytes[1024] @@ -75,113 +79,117 @@ ERC-721 token ID'leri 256 bittir. Tipik olarak, token'ın temsil ettiği şeyin ) -> bytes32: view ``` -Bir sözleşmenin yanlışlıkla bir transferi kabul ettiği durumları önlemek için, dönüş değeri bir boolean değil, belirli bir değere sahip 256 bittir. +Bir sözleşmenin yanlışlıkla bir aktarımı kabul ettiği durumları önlemek için, dönüş değeri bir boole değil, belirli bir değere sahip 256 bittir. -Bu işlev bir `view`'dur, yani blok zincirinin durumunu okuyabilir, ancak değiştiremez. +Bu işlev bir `view`'dur, yani blokzincirin durumunu okuyabilir, ancak değiştiremez. -### Etkinlikler {#events} +### Olaylar {#events} -[Olaylar](https://media.consensys.net/technical-introduction-to-events-and-logs-in-ethereum-a074d65dd61e) blok zincirinin dışındaki kullanıcıları ve sunucuları bilgilendirmek için yayınlanır. Olayların içeriğinin blok zincirindeki sözleşmeler için mevcut olmadığını unutmayın. +[Olaylar](https://media.consensys.net/technical-introduction-to-events-and-logs-in-ethereum-a074d65dd61e) blokzincir dışındaki kullanıcıları ve sunucuları olaylar hakkında bilgilendirmek için yayınlanır. Olayların içeriğinin blokzincirdeki sözleşmeler için mevcut olmadığını unutmayın. ```python -# @dev Emits when ownership of any NFT changes by any mechanism. This event emits when NFTs are -# created (`from` == 0) and destroyed (`to` == 0). Exception: during contract creation, any -# number of NFTs may be created and assigned without emitting Transfer. At the time of any -# transfer, the approved address for that NFT (if any) is reset to none. -# @param _from Sender of NFT (if address is zero address it indicates token creation). -# @param _to Receiver of NFT (if address is zero address it indicates token destruction). -# @param _tokenId The NFT that got transferred. +# @dev Herhangi bir NFT'nin mülkiyeti herhangi bir mekanizma ile değiştiğinde yayınlanır. Bu olay, NFT'ler +# oluşturulduğunda (`from` == 0) ve yok edildiğinde (`to` == 0) yayınlanır. İstisna: sözleşme oluşturma sırasında, herhangi +# bir sayıda NFT, Transfer yayınlanmadan oluşturulabilir ve atanabilir. Herhangi bir +# aktarım sırasında, o NFT için onaylanmış adres (varsa) sıfırlanır. +# @param _from NFT'nin göndericisi (adres sıfır adresi ise jeton oluşturmayı belirtir). +# @param _to NFT'nin alıcısı (adres sıfır adresi ise jeton yok etmeyi belirtir). +# @param _tokenId Aktarılan NFT. event Transfer: sender: indexed(address) receiver: indexed(address) tokenId: indexed(uint256) ``` -Bu, bir miktar yerine bir `tokenId` bildirmemiz dışında, ERC-20 Transfer olayına benzer. Hiç kimse sıfır adresine sahip değildir, bu nedenle geleneksel olarak onu token'ların oluşturulmasını ve yok edilmesini bildirmek için kullanırız. +Bu, bir miktar yerine bir `tokenId` bildirmemiz dışında, ERC-20 Transfer olayına benzer. +Hiç kimse sıfır adresine sahip değildir, bu nedenle geleneksel olarak onu jetonların oluşturulmasını ve yok edilmesini bildirmek için kullanırız. ```python -# @dev This emits when the approved address for an NFT is changed or reaffirmed. The zero -# address indicates there is no approved address. When a Transfer event emits, this also -# indicates that the approved address for that NFT (if any) is reset to none. -# @param _owner Owner of NFT. -# @param _approved Address that we are approving. -# @param _tokenId NFT which we are approving. +# @dev Bu, bir NFT için onaylanmış adres değiştirildiğinde veya yeniden onaylandığında yayınlanır. Sıfır +# adresi, onaylanmış bir adres olmadığını gösterir. Bir Transfer olayı yayınlandığında, bu aynı zamanda +# o NFT için onaylanmış adresin (varsa) sıfırlandığını gösterir. +# @param _owner NFT'nin sahibi. +# @param _approved Onayladığımız adres. +# @param _tokenId Onayladığımız NFT. event Approval: owner: indexed(address) approved: indexed(address) tokenId: indexed(uint256) ``` -ERC-721 onayı, ERC-20 ödeneğine benzer. Belirli bir adresin belirli bir token'ı aktarmasına izin verilir. Bu, sözleşmelerin bir token'ı kabul ettiklerinde yanıt vermeleri için bir mekanizma sağlar. Sözleşmeler olayları dinleyemez, bu nedenle token'ı onlara aktarırsanız bunu "bilmezler". Bu şekilde, mal sahibi önce bir onay gönderir ve ardından sözleşmeye bir istek gönderir: "X token'ını aktarmanız için onay verdim, lütfen yapın...". +ERC-721 onayı, ERC-20 ödeneğine benzer. Belirli bir adresin belirli bir +jetonu aktarmasına izin verilir. Bu, sözleşmelerin bir jetonu kabul ettiklerinde yanıt vermeleri için bir mekanizma sağlar. Sözleşmeler olayları +dinleyemez, bu nedenle jetonu onlara aktarırsanız bunu "bilmezler". Bu şekilde, mal sahibi önce bir onay gönderir ve ardından sözleşmeye bir istek gönderir: "X jetonunu aktarmanız için onay verdim, lütfen yapın ...". -Bu, ERC-721 standardını ERC-20 standardına benzer kılmak için yapılmış bir tasarım tercihidir. ERC-721 token'ları değiştirilemez olduğundan, bir sözleşme token'ın mülkiyetine bakarak belirli bir token aldığını da belirleyebilir. +Bu, ERC-721 standardını ERC-20 standardına benzer kılmak için yapılmış bir tasarım tercihidir. ERC-721 jetonları değiştirilemez olduğundan, bir sözleşme, jetonun mülkiyetine bakarak belirli bir jeton aldığını da belirleyebilir. ```python -# @dev This emits when an operator is enabled or disabled for an owner. The operator can manage -# all NFTs of the owner. -# @param _owner Owner of NFT. -# @param _operator Address to which we are setting operator rights. -# @param _approved Status of operator rights(true if operator rights are given and false if -# revoked). +# @dev Bu, bir operatör bir sahip için etkinleştirildiğinde veya devre dışı bırakıldığında yayınlanır. Operatör, sahibinin tüm NFT'lerini +# yönetebilir. +# @param _owner NFT'nin sahibi. +# @param _operator Operatör haklarını ayarladığımız adres. +# @param _approved Operatör haklarının durumu (operatör hakları verilmişse true, geri alınmışsa +# false). event ApprovalForAll: owner: indexed(address) operator: indexed(address) approved: bool ``` -Bir hesabın, adeta bir vekaletname gibi belirli bir türdeki (belirli bir sözleşmeyle yönetilenler) tüm simgelerini yönetebilen bir _operatöre_ sahip olmak bazen yararlıdır. Örneğin, altı aydır iletişime geçmediğimi kontrol eden ve varsa mal varlığımı mirasçılarıma dağıtan bir sözleşmeye öyle bir yetki vermek isteyebilirim (eğer bir sözleşme bunu isterse, bir işlem tarafından çağrılmadan herhangi bir şey yapamaz). ERC-20'de bir miras sözleşmesine sadece yüksek bir ödenek verebiliriz ancak bu, ERC-721 için işe yaramaz çünkü token'lar değiştirilebilir değildir. Bu, bunun dengidir. +Bir hesabın, adeta bir vekaletname gibi belirli bir türdeki (belirli bir sözleşmeyle yönetilenler) tüm jetonlarını yönetebilen bir _operatöre_ sahip olmak bazen yararlıdır. Örneğin, altı aydır temas kurup kurmadığımı kontrol eden ve kurmadıysam varlıklarımı mirasçılarıma dağıtan bir sözleşmeye böyle bir yetki vermek isteyebilirim (mirasçılardan biri talep ederse, sözleşmeler bir işlemle çağrılmadan hiçbir şey yapamaz). ERC-20'de bir miras sözleşmesine sadece yüksek bir ödenek verebiliriz ancak bu, ERC-721 için işe yaramaz çünkü jetonlar değiştirilemezdir. Bu, bunun dengidir. `approved` değeri bize etkinliğin bir onay için mi yoksa bir onayın geri çekilmesi için mi olduğunu söyler. ### Durum Değişkenleri {#state-vars} -Bu değişkenler, token'ların mevcut durumunu içerir: hangilerinin mevcut olduğu ve onlara kimin sahip olduğu. Bunların çoğu, [iki tür arasında var olan tek yönlü eşleştirmeler](https://vyper.readthedocs.io/en/latest/types.html#mappings) olan `HashMap` nesneleridir. +Bu değişkenler, jetonların mevcut durumunu içerir: hangilerinin mevcut olduğu ve onlara kimin sahip olduğu. Bunların çoğu, [iki tür arasında var olan tek yönlü eşlemeler](https://vyper.readthedocs.io/en/latest/types.html#mappings) olan `HashMap` nesneleridir. ```python -# @dev Mapping from NFT ID to the address that owns it. +# @dev NFT ID'sinden sahibinin adresine eşleme. idToOwner: HashMap[uint256, address] -# @dev Mapping from NFT ID to approved address. +# @dev NFT ID'sinden onaylanan adrese eşleme. idToApprovals: HashMap[uint256, address] ``` -Ethereum'daki kullanıcı ve sözleşme kimlikleri 160 bitlik adreslerle temsil edilir. Bu iki değişken, token ID'lerinden sahiplerine ve bunları aktarmak için onaylananlara eşleştirilir (her biri için en fazla bir tane). Ethereum'da, başlatılmamış veriler her zaman sıfırdır, bu nedenle herhangi bir sahip veya onaylanmış aktarıcı yoksa, o token'ın değeri sıfırdır. +Ethereum'daki kullanıcı ve sözleşme kimlikleri 160 bitlik adreslerle temsil edilir. Bu iki değişken, jeton ID'lerinden sahiplerine ve bunları aktarmak için onaylananlara eşleştirilir (her biri için en fazla bir tane). Ethereum'da, başlatılmamış veriler her zaman sıfırdır, bu nedenle herhangi bir sahip veya onaylanmış aktarıcı yoksa, o jetonun değeri sıfırdır. ```python -# @dev Mapping from owner address to count of his tokens. +# @dev Sahip adresinden sahip olduğu jeton sayısına eşleme. ownerToNFTokenCount: HashMap[address, uint256] ``` -Bu değişken, her sahip için token sayısını tutar. Sahiplerden token'lara eşleştirme yoktur, bu nedenle belirli bir sahibin sahip olduğu token'ları tanımlamanın tek yolu blok zincirinin olay geçmişine bakmak ve uygun `Transfer` olaylarını görmektir. Bu değişkeni, tüm NFT'lere ne zaman sahip olduğumuzu ve zamanda daha fazla aramamıza gerek olmadığını bilmek için kullanabiliriz. +Bu değişken, her sahip için jeton sayısını tutar. Sahiplerden jetonlara eşleştirme yoktur, bu nedenle belirli bir sahibin sahip olduğu jetonları tanımlamanın tek yolu blokzincirin olay geçmişine bakmak ve uygun `Transfer` olaylarını görmektir. Bu değişkeni, tüm NFT'lere ne zaman sahip olduğumuzu ve zamanda daha fazla aramamıza gerek olmadığını bilmek için kullanabiliriz. -Bu algoritmanın yalnızca kullanıcı arayüzleri ve harici sunucular için çalıştığını unutmayın. Blok zincirinde çalışan kod, geçmiş olayları okuyamaz. +Bu algoritmanın yalnızca kullanıcı arayüzleri ve harici sunucular için çalıştığını unutmayın. Blokzincirinin +kendisinde çalışan kod geçmiş olayları okuyamaz. ```python -# @dev Mapping from owner address to mapping of operator addresses. +# @dev Sahip adresinden operatör adreslerinin eşlemesine eşleme. ownerToOperators: HashMap[address, HashMap[address, bool]] ``` Bir hesap birden fazla operatöre sahip olabilir. Basit bir `HashMap` onları takip etmek için yetersizdir, çünkü her anahtar tek bir değere bağlıdır. Bunun yerine, değer olarak `HashMap[address, bool]` kullanabilirsiniz. Varsayılan olarak, her adresin değeri `False`'dur, bu da bir operatör olmadığı anlamına gelir. Değerleri gerektiği gibi `True` olarak ayarlayabilirsiniz. ```python -# @dev Address of minter, who can mint a token +# @dev Bir jeton basabilen minter'ın adresi minter: address ``` -Yeni token'lar bir şekilde oluşturulmalıdır. Bu sözleşmede bunu yapmasına izin verilen tek bir varlık vardır: `minter`. Bu, örneğin bir oyun için yeterli olabilir. Diğer amaçlar için daha karmaşık bir iş mantığı oluşturmak gerekebilir. +Yeni jetonlar bir şekilde oluşturulmalıdır. Bu sözleşmede bunu yapmasına izin verilen tek bir varlık vardır, `minter`. Bu, örneğin bir oyun için yeterli olabilir. Diğer amaçlar için daha karmaşık bir iş mantığı oluşturmak gerekebilir. ```python -# @dev Mapping of interface id to bool about whether or not it's supported +# @dev Arayüz kimliğinden desteklenip desteklenmediğine dair bool'a eşleme supportedInterfaces: HashMap[bytes32, bool] -# @dev ERC165 interface ID of ERC165 +# @dev ERC165'in ERC165 arayüzü ID'si ERC165_INTERFACE_ID: constant(bytes32) = 0x0000000000000000000000000000000000000000000000000000000001ffc9a7 -# @dev ERC165 interface ID of ERC721 +# @dev ERC721'in ERC165 arayüzü ID'si ERC721_INTERFACE_ID: constant(bytes32) = 0x0000000000000000000000000000000000000000000000000000000080ac58cd ``` -[ERC-165](https://eips.ethereum.org/EIPS/eip-165), uygulamaların kendisiyle nasıl iletişim kurabileceğini ve hangi ERC'lere uyduğunu ifşa etmek için bir sözleşme için bir mekanizma belirtir. Bu durumda sözleşme ERC-165 ve ERC-721'e uygundur. +[ERC-165](https://eips.ethereum.org/EIPS/eip-165) bir sözleşmenin, uygulamaların onunla nasıl iletişim kurabileceğini, yani hangi ERC'lere uyduğunu açıklaması için bir mekanizma belirtir. Bu durumda sözleşme ERC-165 ve ERC-721'e uygundur. ### Fonksiyonlar {#functions} @@ -194,15 +202,15 @@ Bunlar, ERC-721'i gerçekten uygulayan fonksiyonlardır. def __init__(): ``` -Vyper'da, Python'da olduğu gibi yapıcı fonksiyona `__init__` adı verilir. +Vyper'da, Python'da olduğu gibi, yapıcı fonksiyona `__init__` adı verilir. ```python """ - @dev Contract constructor. + @dev Sözleşme yapıcısı. """ ``` -Python'da ve Vyper'da, çok satırlı bir dize (`"""` ile başlayan ve biten) belirterek ve onu hiçbir şekilde kullanmayarak bir yorum oluşturabilirsiniz. Bu yorumlar ayrıca [NatSpec](https://vyper.readthedocs.io/en/latest/natspec.html) içerebilir. +Python'da ve Vyper'da, çok satırlı bir dize (`"""` ile başlayan ve biten) belirterek ve onu hiçbir şekilde kullanmayarak bir yorum oluşturabilirsiniz. Bu yorumlar [NatSpec](https://vyper.readthedocs.io/en/latest/natspec.html) de içerebilir. ```python self.supportedInterfaces[ERC165_INTERFACE_ID] = True @@ -210,32 +218,35 @@ Python'da ve Vyper'da, çok satırlı bir dize (`"""` ile başlayan ve biten) be self.minter = msg.sender ``` -Durum değişkenlerine erişmek için `self.` kullanırsınız (yine Python'da olduğu gibi). +Durum değişkenlerine erişmek için `self.` kullanırsınız` (yine Python'daki gibi). -#### Fonksiyonları gör {#views} +#### Görünüm Fonksiyonları {#views} -Bunlar blok zincirinin durumunu değiştirmeyen fonksiyonlardır ve bu nedenle dışarıdan çağrıldıklarında ücretsiz olarak yürütülebilirler. Görünüm fonksiyonları bir sözleşme ile çağrılırsa, yine de her düğümde yürütülmeleri gerekir ve bu nedenle gaz harcarlar. +Bunlar blokzincirin durumunu değiştirmeyen fonksiyonlardır ve bu nedenle dışarıdan çağrıldıklarında ücretsiz olarak yürütülebilirler. Görünüm fonksiyonları bir sözleşme ile çağrılırsa, yine de her düğümde yürütülmeleri gerekir ve bu nedenle gaz harcarlar. ```python @view @external ``` -Bir `@` işaretiyle başlayan bir fonksiyon tanımından önceki bu anahtar kelimelere _dekorasyon_ denir. Bir fonksiyonun çağrılabileceği durumları belirtirler. +Bir at işareti (`@`) ile başlayan bir fonksiyon tanımından önceki bu anahtar kelimelere _dekoratörler_ denir. Bir fonksiyonun çağrılabileceği durumları belirtirler. -- `@view` bu fonksiyonun bir view olduğunu belirtir. +- `@view` bu fonksiyonun bir görünüm olduğunu belirtir. - `@external` bu fonksiyonun işlemler ve diğer sözleşmeler tarafından çağrılabileceğini belirtir. ```python def supportsInterface(_interfaceID: bytes32) -> bool: ``` -Python'un aksine, Vyper [statik türlendirilmiş bir dildir](https://wikipedia.org/wiki/Type_system#Static_type_checking). [Veri türünü](https://vyper.readthedocs.io/en/latest/types.html) tanımlamadan bir değişken veya fonksiyon parametresi bildiremezsiniz. Bu durumda giriş parametresi 256 bitlik bir değer olan `bytes32`'dir, (256 bit, [Ethereum Sanal Makinesi](/developers/docs/evm/)'nin yerel kelime boyutudur). Çıktı boolean bir değerdir. Kural olarak, fonksiyon parametrelerinin adları bir alt çizgi (`_`) ile başlar. +Python'un aksine Vyper [statik tipli bir dildir](https://wikipedia.org/wiki/Type_system#Static_type_checking). +[veri türünü](https://vyper.readthedocs.io/en/latest/types.html) belirtmeden bir değişken veya fonksiyon parametresi bildiremezsiniz. Bu durumda giriş parametresi, 256 bitlik bir değer olan `bytes32`'dir +(256 bit, [Ethereum Sanal Makinesi'nin](/developers/docs/evm/) doğal kelime boyutudur). Çıktı bir boole +değeridir. Kural olarak, fonksiyon parametrelerinin adları bir alt çizgi (`_`) ile başlar. ```python """ - @dev Interface identification is specified in ERC-165. - @param _interfaceID Id of the interface + @dev Arayüz kimliği ERC-165'te belirtilmiştir. + @param _interfaceID Arayüzün kimliği """ return self.supportedInterfaces[_interfaceID] ``` @@ -243,96 +254,99 @@ Python'un aksine, Vyper [statik türlendirilmiş bir dildir](https://wikipedia.o Değeri, yapıcıda (`__init__`) belirlenmiş olan `self.supportedInterfaces` HashMap'inden döndürün. ```python -### VIEW FUNCTIONS ### +### GÖRÜNÜM FONKSİYONLARI ### + ``` -Bunlar, token'lar hakkında bilgileri kullanıcılara ve diğer sözleşmelere sunan görüntüleme fonksiyonlarıdır. +Bunlar, jetonlar hakkında bilgileri kullanıcılara ve diğer sözleşmelere sunan görünüm fonksiyonlarıdır. ```python @view @external def balanceOf(_owner: address) -> uint256: """ - @dev Returns the number of NFTs owned by `_owner`. - Throws if `_owner` is the zero address. NFTs assigned to the zero address are considered invalid. - @param _owner Address for whom to query the balance. + @dev `_owner`'ın sahip olduğu NFT sayısını döndürür. + `_owner` sıfır adresi ise hata verir. Sıfır adresine atanan NFT'ler geçersiz kabul edilir. + @param _owner Bakiyenin sorgulanacağı adres. """ assert _owner != ZERO_ADDRESS ``` -Bu satır `_owner`'ın sıfır olmadığını [teyit eder](https://vyper.readthedocs.io/en/latest/statements.html#assert). Eğer öyleyse, bir hata vardır ve işlem geri alınır. +Bu satır, `_owner`'ın sıfır olmadığını [denetler](https://vyper.readthedocs.io/en/latest/statements.html#assert). Eğer öyleyse, bir hata vardır ve işlem geri alınır. ```python - return self.ownerToNFTokenCount[_owner] - @view @external def ownerOf(_tokenId: uint256) -> address: """ - @dev Returns the address of the owner of the NFT. - Throws if `_tokenId` is not a valid NFT. - @param _tokenId The identifier for an NFT. + @dev NFT'nin sahibinin adresini döndürür. + `_tokenId` geçerli bir NFT değilse hata verir. + @param _tokenId Bir NFT'nin tanımlayıcısı. """ owner: address = self.idToOwner[_tokenId] - # Throws if `_tokenId` is not a valid NFT + # `_tokenId` geçerli bir NFT değilse hata verir assert owner != ZERO_ADDRESS return owner ``` -Ethereum Sanal Makinesinde (evm), içinde depolanmış bir değeri olmayan herhangi bir depolama sıfırdır. Eğer `_tokenId` yerinde bir token yoksa `self.idToOwner[_tokenId]` değeri sıfırdır. Bu durumda fonksiyon geri dönüş yapar. +Ethereum Sanal Makinesinde (EVM) içinde depolanmış bir değeri olmayan herhangi bir depolama sıfırdır. +Eğer `_tokenId` yerinde bir jeton yoksa `self.idToOwner[_tokenId]` değeri sıfırdır. Bu +durumda fonksiyon geri alınır. ```python @view @external def getApproved(_tokenId: uint256) -> address: """ - @dev Get the approved address for a single NFT. - Throws if `_tokenId` is not a valid NFT. - @param _tokenId ID of the NFT to query the approval of. + @dev Tek bir NFT için onaylanmış adresi alın. + `_tokenId` geçerli bir NFT değilse hata verir. + @param _tokenId Onayını sorgulamak için NFT'nin ID'si. """ - # Throws if `_tokenId` is not a valid NFT + # `_tokenId` geçerli bir NFT değilse hata verir assert self.idToOwner[_tokenId] != ZERO_ADDRESS return self.idToApprovals[_tokenId] ``` -`getApproved`'un sıfır _döndürebileceğini_ unutmayın. Eğer token geçerliyse `self.idToApprovals[_tokenId]` döndürür. Onaylayan yoksa bu değer sıfırdır. +`getApproved`'un sıfır _döndürebileceğini_ unutmayın. Eğer jeton geçerliyse `self.idToApprovals[_tokenId]` döndürür. +Onaylayan yoksa bu değer sıfırdır. ```python @view @external def isApprovedForAll(_owner: address, _operator: address) -> bool: """ - @dev Checks if `_operator` is an approved operator for `_owner`. - @param _owner The address that owns the NFTs. - @param _operator The address that acts on behalf of the owner. + @dev `_operator`'ın `_owner` için onaylı bir operatör olup olmadığını kontrol eder. + @param _owner NFT'lerin sahibi olan adres. + @param _operator Sahip adına hareket eden adres. """ return (self.ownerToOperators[_owner])[_operator] ``` -Bu fonksiyon, `_operator`'un bu sözleşmedeki tüm `_owner` token'larını yönetmesine izin verilip verilmediğini kontrol eder. Birden fazla operatör olabileceğinden, bu iki seviyeli bir HashMap'tir. +Bu fonksiyon, `_operator`'un bu sözleşmedeki tüm `_owner` jetonlarını yönetmesine izin verilip verilmediğini kontrol eder. +Birden fazla operatör olabileceğinden, bu iki seviyeli bir HashMap'tir. -#### Transfer Yardımcı Fonksiyonları {#transfer-helpers} +#### Aktarım Yardımcı Fonksiyonları {#transfer-helpers} -Bu fonksiyonlar, token'ları transfer etmenin veya yönetmenin parçası olan işlemleri uygular. +Bu fonksiyonlar, jetonları aktarmanın veya yönetmenin parçası olan işlemleri uygular. ```python -### TRANSFER FUNCTION HELPERS ### +### AKTARIM FONKSİYONU YARDIMCILARI ### @view @internal ``` -Bu dekorasyon, `@internal`, fonksiyona yalnızca aynı sözleşmedeki diğer fonksiyonlardan erişilebilir olduğu anlamına gelir. Kural olarak, bu fonksiyon adları ayrıca bir alt çizgi (`_`) ile başlar. +Bu dekoratör, `@internal`, fonksiyonun yalnızca aynı sözleşme içindeki diğer fonksiyonlardan erişilebilir olduğu anlamına gelir. Kural olarak, bu fonksiyon adları ayrıca bir alt çizgi (`_`) ile başlar. ```python def _isApprovedOrOwner(_spender: address, _tokenId: uint256) -> bool: """ - @dev Returns whether the given spender can transfer a given token ID - @param spender address of the spender to query - @param tokenId uint256 ID of the token to be transferred - @return bool whether the msg.sender is approved for the given token ID, - is an operator of the owner, or is the owner of the token + @dev Verilen harcayıcının belirli bir jeton kimliğini aktarıp aktaramayacağını döndürür + @param spender sorgulanacak harcayıcının adresi + @param tokenId aktarılacak jetonun uint256 ID'si + @return bool msg.sender'ın verilen jeton ID'si için onaylanıp onaylanmadığını, + sahibin bir operatörü olup olmadığını veya jetonun sahibi olup olmadığını belirtir """ owner: address = self.idToOwner[_tokenId] spenderIsOwner: bool = owner == _spender @@ -341,22 +355,22 @@ def _isApprovedOrOwner(_spender: address, _tokenId: uint256) -> bool: return (spenderIsOwner or spenderIsApproved) or spenderIsApprovedForAll ``` -Bir adresin bir token'ı transfer etmesine izin vermenin üç yolu vardır: +Bir adresin bir jetonu aktarmasına izin verilmesinin üç yolu vardır: -1. Adres, token'ın sahibidir -2. Adresin bu token'ı harcaması onaylanmıştır -3. Adres, token'ın sahibi için bir operatördür +1. Adres, jetonun sahibidir +2. Adresin bu jetonu harcaması onaylanmıştır +3. Adres, jetonun sahibi için bir operatördür -Durumu değiştirmediği için yukarıdaki fonksiyon bir görünüm olabilir. İşletim maliyetlerini azaltmak için, bir görünüm _olabilen_ herhangi bir fonksiyon bir görünüm _olmalıdır_. +Durumu değiştirmediği için yukarıdaki fonksiyon bir görünüm olabilir. İşletim maliyetlerini azaltmak için, görünüm _olabilen_ herhangi bir fonksiyon görünüm _olmalıdır_. ```python @internal def _addTokenTo(_to: address, _tokenId: uint256): """ - @dev Add a NFT to a given address - Throws if `_tokenId` is owned by someone. + @dev Belirli bir adrese bir NFT ekle + `_tokenId`'nin bir sahibi varsa hata verir. """ - # Throws if `_tokenId` is owned by someone + # `_tokenId`'nin bir sahibi varsa hata verir assert self.idToOwner[_tokenId] == ZERO_ADDRESS # Change the owner self.idToOwner[_tokenId] = _to @@ -367,10 +381,10 @@ def _addTokenTo(_to: address, _tokenId: uint256): @internal def _removeTokenFrom(_from: address, _tokenId: uint256): """ - @dev Remove a NFT from a given address - Throws if `_from` is not the current owner. + @dev Belirli bir adresten bir NFT'yi kaldır + `_from` mevcut sahip değilse hata verir. """ - # Throws if `_from` is not the current owner + # `_from` mevcut sahip değilse hata verir assert self.idToOwner[_tokenId] == _from # Change the owner self.idToOwner[_tokenId] = ZERO_ADDRESS @@ -378,38 +392,38 @@ def _removeTokenFrom(_from: address, _tokenId: uint256): self.ownerToNFTokenCount[_from] -= 1 ``` -Transfer ile ilgili bir sorun olduğunda isteği geri çeviriyoruz. +Aktarım ile ilgili bir sorun olduğunda çağrıyı geri alırız. ```python @internal def _clearApproval(_owner: address, _tokenId: uint256): """ - @dev Clear an approval of a given address - Throws if `_owner` is not the current owner. + @dev Belirli bir adresin onayını temizle + `_owner` mevcut sahip değilse hata verir. """ - # Throws if `_owner` is not the current owner + # `_owner` mevcut sahip değilse hata verir assert self.idToOwner[_tokenId] == _owner if self.idToApprovals[_tokenId] != ZERO_ADDRESS: # Reset approvals self.idToApprovals[_tokenId] = ZERO_ADDRESS ``` -Değeri sadece gerekirse değiştirin. Durum değişkenleri depolamada yaşar. Depolamaya yazmak, EVM'nin (Ethereum Sanal Makinesi) yaptığı en pahalı işlemlerden biridir ([gaz](/developers/docs/gas/) açısından). Bu nedenle en aza indirmek iyi bir fikirdir, mevcut değeri yazmanın bile maliyeti yüksektir. +Değeri sadece gerekirse değiştirin. Durum değişkenleri depolamada yaşar. Depolama alanına yazmak, EVM'nin (Ethereum Sanal Makinesi) gerçekleştirdiği en pahalı işlemlerden biridir ([gaz](/developers/docs/gas/) açısından). Bu nedenle en aza indirmek iyi bir fikirdir, mevcut değeri yazmanın bile maliyeti yüksektir. ```python @internal def _transferFrom(_from: address, _to: address, _tokenId: uint256, _sender: address): """ - @dev Execute transfer of a NFT. - Throws unless `msg.sender` is the current owner, an authorized operator, or the approved - address for this NFT. (NOTE: `msg.sender` not allowed in private function so pass `_sender`.) - Throws if `_to` is the zero address. - Throws if `_from` is not the current owner. - Throws if `_tokenId` is not a valid NFT. + @dev Bir NFT'nin aktarımını gerçekleştirin. + `msg.sender` mevcut sahip, yetkili bir operatör veya bu NFT için onaylanmış + adres değilse hata verir. (NOT: `msg.sender`'a özel fonksiyonda izin verilmez, bu yüzden `_sender`'ı geçin.) + `_to` sıfır adresi ise hata verir. + `_from` mevcut sahip değilse hata verir. + `_tokenId` geçerli bir NFT değilse hata verir. """ ``` -Token'ları aktarmanın iki yolu olduğu için (düzenli ve güvenli) bu dahili fonksiyona sahibiz ancak denetimi kolaylaştırmak için kodda yalnızca tek bir konum istiyoruz. +Jetonları aktarmanın iki yolu olduğu için (normal ve güvenli) bu dahili fonksiyona sahibiz ancak denetimi kolaylaştırmak için kodda yalnızca tek bir konum istiyoruz. ```python # Check requirements @@ -426,32 +440,32 @@ Token'ları aktarmanın iki yolu olduğu için (düzenli ve güvenli) bu dahili log Transfer(_from, _to, _tokenId) ``` -Vyper'da bir olay yaymak için `log` ifadesi kullanırsınız ([daha fazla detay için buraya bakınız](https://vyper.readthedocs.io/en/latest/event-logging.html#event-logging)). +Vyper'da bir olay yayınlamak için bir `log` ifadesi kullanırsınız ([daha fazla ayrıntı için buraya bakın](https://vyper.readthedocs.io/en/latest/event-logging.html#event-logging)). -#### Transfer Fonksiyonları {#transfer-funs} +#### Aktarım Fonksiyonları {#transfer-funs} ```python -### TRANSFER FUNCTIONS ### +### AKTARIM FONKSİYONLARI ### @external def transferFrom(_from: address, _to: address, _tokenId: uint256): """ - @dev Throws unless `msg.sender` is the current owner, an authorized operator, or the approved - address for this NFT. - Throws if `_from` is not the current owner. - Throws if `_to` is the zero address. - Throws if `_tokenId` is not a valid NFT. - @notice The caller is responsible to confirm that `_to` is capable of receiving NFTs or else - they maybe be permanently lost. - @param _from The current owner of the NFT. - @param _to The new owner. - @param _tokenId The NFT to transfer. + @dev `msg.sender` mevcut sahip, yetkili bir operatör veya bu NFT için onaylanmış + adres değilse hata verir. + `_from` mevcut sahip değilse hata verir. + `_to` sıfır adresi ise hata verir. + `_tokenId` geçerli bir NFT değilse hata verir. + @notice Çağıran, `_to`'nun NFT'leri alabileceğinden emin olmaktan sorumludur, aksi takdirde + kalıcı olarak kaybolabilirler. + @param _from NFT'nin mevcut sahibi. + @param _to Yeni sahip. + @param _tokenId Aktarılacak NFT. """ self._transferFrom(_from, _to, _tokenId, msg.sender) ``` -Bu fonksiyon, isteğe bağlı bir adrese aktarım yapmanızı sağlar. Adres bir kullanıcı veya token'ların nasıl transfer edileceğini bilen bir sözleşme olmadığı sürece, transfer ettiğiniz herhangi bir token o adrese takılıp işe yaramaz olacaktır. +Bu fonksiyon, isteğe bağlı bir adrese aktarım yapmanızı sağlar. Adres bir kullanıcı veya jetonların nasıl aktarılacağını bilen bir sözleşme olmadığı sürece, aktardığınız herhangi bir jeton o adreste takılıp kalır ve işe yaramaz hale gelir. ```python @external @@ -462,63 +476,65 @@ def safeTransferFrom( _data: Bytes[1024]=b"" ): """ - @dev Transfers the ownership of an NFT from one address to another address. - Throws unless `msg.sender` is the current owner, an authorized operator, or the - approved address for this NFT. - Throws if `_from` is not the current owner. - Throws if `_to` is the zero address. - Throws if `_tokenId` is not a valid NFT. - If `_to` is a smart contract, it calls `onERC721Received` on `_to` and throws if - the return value is not `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. - NOTE: bytes4 is represented by bytes32 with padding - @param _from The current owner of the NFT. - @param _to The new owner. - @param _tokenId The NFT to transfer. - @param _data Additional data with no specified format, sent in call to `_to`. + @dev Bir NFT'nin mülkiyetini bir adresten başka bir adrese aktarır. + `msg.sender` mevcut sahip, yetkili bir operatör veya bu NFT için + onaylanmış adres değilse hata verir. + `_from` mevcut sahip değilse hata verir. + `_to` sıfır adresi ise hata verir. + `_tokenId` geçerli bir NFT değilse hata verir. + `_to` bir akıllı sözleşme ise, `_to` üzerinde `onERC721Received`'ı çağırır ve + dönüş değeri `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` değilse hata verir. + NOT: bytes4, dolgu ile bytes32 ile temsil edilir + @param _from NFT'nin mevcut sahibi. + @param _to Yeni sahip. + @param _tokenId Aktarılacak NFT. + @param _data Belirtilen bir formatı olmayan, `_to`'ya yapılan çağrıda gönderilen ek veriler. """ self._transferFrom(_from, _to, _tokenId, msg.sender) ``` -Önce transferi yapmakta bir sakınca yok çünkü bir sorun olursa yine geri döneceğiz, bu yüzden çağrıda yapılan her şey iptal edilecek. +Önce transferi yapmakta bir sakınca yok çünkü bir sorun olursa yine de geri döneceğiz, bu yüzden çağrıda yapılan her şey iptal edilecek. ```python - if _to.is_contract: # check if `_to` is a contract address + if _to.is_contract: # `_to`'nun bir sözleşme adresi olup olmadığını kontrol et ``` -İlk önce adresin bir sözleşme olup olmadığını kontrol edin (kodu varsa). Değilse, bunun bir kullanıcı adresi olduğunu varsayın ve kullanıcı token'ı kullanabilecek veya aktarabilecektir. Ama bunun yüzünden yalancı bir güvenlik duygusuna kapılmayın. Token'ları, özel anahtarı kimsenin bilmediği bir adrese aktarırsanız `safeTransferFrom` ile bile kaybedebilirsiniz. +İlk önce adresin bir sözleşme olup olmadığını kontrol edin (kodu varsa). Değilse, bunun bir kullanıcı adresi olduğunu +varsayın ve kullanıcı jetonu kullanabilecek veya aktarabilecektir. Ama bunun yüzünden yalancı bir +güvenlik duygusuna kapılmayın. Jetonları, özel anahtarı kimsenin bilmediği bir adrese aktarırsanız `safeTransferFrom` ile bile kaybedebilirsiniz. ```python returnValue: bytes32 = ERC721Receiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data) ``` -ERC-721 token'larını alıp alamayacağını görmek için hedef sözleşmeyi çağırın. +ERC-721 jetonlarını alıp alamayacağını görmek için hedef sözleşmeyi çağırın. ```python - # Throws if transfer destination is a contract which does not implement 'onERC721Received' + # Aktarım hedefi 'onERC721Received' uygulamayan bir sözleşme ise hata verir assert returnValue == method_id("onERC721Received(address,address,uint256,bytes)", output_type=bytes32) ``` -Hedef bir sözleşmeyse, ancak ERC-721 token'larını kabul etmeyen (veya bu özel aktarımı kabul etmemeye karar veren) bir sözleşmeyse, geri döndürün. +Hedef bir sözleşmeyse, ancak ERC-721 jetonlarını kabul etmeyen (veya bu özel aktarımı kabul etmemeye karar veren) bir sözleşmeyse, işlemi geri alın. ```python @external def approve(_approved: address, _tokenId: uint256): """ - @dev Set or reaffirm the approved address for an NFT. The zero address indicates there is no approved address. - Throws unless `msg.sender` is the current NFT owner, or an authorized operator of the current owner. - Throws if `_tokenId` is not a valid NFT. (NOTE: This is not written the EIP) - Throws if `_approved` is the current owner. (NOTE: This is not written the EIP) - @param _approved Address to be approved for the given NFT ID. - @param _tokenId ID of the token to be approved. + @dev Bir NFT için onaylanmış adresi ayarlayın veya yeniden onaylayın. Sıfır adresi, onaylanmış bir adres olmadığını gösterir. + `msg.sender` mevcut NFT sahibi veya mevcut sahibin yetkili bir operatörü değilse hata verir. + `_tokenId` geçerli bir NFT değilse hata verir. (NOT: Bu, EIP'de yazılmamıştır) + `_approved` mevcut sahip ise hata verir. (NOT: Bu, EIP'de yazılmamıştır) + @param _approved Verilen NFT ID'si için onaylanacak adres. + @param _tokenId Onaylanacak jetonun ID'si. """ owner: address = self.idToOwner[_tokenId] - # Throws if `_tokenId` is not a valid NFT + # `_tokenId` geçerli bir NFT değilse hata verir assert owner != ZERO_ADDRESS - # Throws if `_approved` is the current owner + # `_approved` mevcut sahip ise hata verir assert _approved != owner ``` -Normalde, bir onaylayıcıya sahip olmak istemiyorsanız sıfır adresini kendiniz atmazsınız. +Geleneksel olarak, bir onaylayıcınız olmasını istemiyorsanız, kendinizi değil, sıfır adresini atarsınız. ```python # Check requirements @@ -538,25 +554,25 @@ Bir onay ayarlamak için, sahibi veya sahibi tarafından yetkilendirilmiş bir o @external def setApprovalForAll(_operator: address, _approved: bool): """ - @dev Enables or disables approval for a third party ("operator") to manage all of - `msg.sender`'s assets. It also emits the ApprovalForAll event. - Throws if `_operator` is the `msg.sender`. (NOTE: This is not written the EIP) - @notice This works even if sender doesn't own any tokens at the time. - @param _operator Address to add to the set of authorized operators. - @param _approved True if the operators is approved, false to revoke approval. + @dev Üçüncü bir taraf ("operatör") için `msg.sender`'ın tüm varlıklarını yönetme onayını etkinleştirir veya devre dışı bırakır. + Ayrıca ApprovalForAll olayını da yayınlar. + `_operator`'ın `msg.sender` olması durumunda hata verir. (NOT: Bu, EIP'de yazılmamıştır) + @notice Bu, göndericinin o anda hiçbir jetona sahip olmasa bile çalışır. + @param _operator Yetkili operatörler kümesine eklenecek adres. + @param _approved Operatör onaylanmışsa True, onayı iptal etmek için false. """ - # Throws if `_operator` is the `msg.sender` + # `_operator`'ın `msg.sender` olması durumunda hata verir assert _operator != msg.sender self.ownerToOperators[msg.sender][_operator] = _approved log ApprovalForAll(msg.sender, _operator, _approved) ``` -#### Yeni Token'lar Basma ve Mevcut Olanları Yok Etme {#mint-burn} +#### Yeni Jetonlar Basma ve Mevcut Olanları Yok Etme {#mint-burn} -Sözleşmeyi oluşturan hesap, yeni NFT'leri basmaya yetkili süper kullanıcı olan `minter`'dır. Ancak, onun bile mevcut token'ları yakmasına izin verilmez. Bunu yalnızca mal sahibi veya mal sahibi tarafından yetkilendirilmiş bir varlık yapabilir. +Sözleşmeyi oluşturan hesap, yeni NFT'leri basmaya yetkili süper kullanıcı olan `minter`'dır. Ancak, onun bile mevcut jetonları yakmasına izin verilmez. Bunu yalnızca mal sahibi veya mal sahibi tarafından yetkilendirilmiş bir varlık yapabilir. ```python -### MINT & BURN FUNCTIONS ### +### BASMA VE YAKMA FONKSİYONLARI ### @external def mint(_to: address, _tokenId: uint256) -> bool: @@ -566,22 +582,22 @@ Bu fonksiyon her zaman `True` döndürür, çünkü işlem başarısız olursa g ```python """ - @dev Function to mint tokens - Throws if `msg.sender` is not the minter. - Throws if `_to` is zero address. - Throws if `_tokenId` is owned by someone. - @param _to The address that will receive the minted tokens. - @param _tokenId The token id to mint. - @return A boolean that indicates if the operation was successful. + @dev Jeton basma fonksiyonu + `msg.sender` minter değilse hata verir. + `_to` sıfır adresi ise hata verir. + `_tokenId`'nin bir sahibi varsa hata verir. + @param _to Basılan jetonları alacak olan adres. + @param _tokenId Basılacak jeton kimliği. + @return İşlemin başarılı olup olmadığını gösteren bir boole değeri. """ - # Throws if `msg.sender` is not the minter + # `msg.sender` minter değilse hata verir assert msg.sender == self.minter ``` -Yalnızca "minter" (ERC-721 sözleşmesini oluşturan hesap) yeni token'lar basabilir. Bu, "minter"ın kimliğini değiştirmek istersek gelecekte bir sorun yaratabilir. Bir üretim sözleşmesinde, muhtemelen minter'ın minter ayrıcalıklarını başka birine devretmesine izin veren bir fonksiyonun olmasını istersiniz. +Yalnızca minter (ERC-721 sözleşmesini oluşturan hesap) yeni jetonlar basabilir. Bu, gelecekte minter'ın kimliğini değiştirmek istersek bir sorun yaratabilir. Bir üretim sözleşmesinde, muhtemelen minter'ın minter ayrıcalıklarını başka birine devretmesine izin veren bir fonksiyonun olmasını istersiniz. ```python - # Throws if `_to` is zero address + # `_to` sıfır adresi ise hata verir assert _to != ZERO_ADDRESS # Add NFT. Throws if `_tokenId` is owned by someone self._addTokenTo(_to, _tokenId) @@ -589,44 +605,49 @@ Yalnızca "minter" (ERC-721 sözleşmesini oluşturan hesap) yeni token'lar basa return True ``` -Geleneksel olarak, yeni token'ların basımı sıfır adresinden bir transfer olarak sayılır. +Geleneksel olarak, yeni jetonların basımı sıfır adresinden bir aktarım olarak sayılır. ```python @external def burn(_tokenId: uint256): """ - @dev Burns a specific ERC721 token. - Throws unless `msg.sender` is the current owner, an authorized operator, or the approved - address for this NFT. - Throws if `_tokenId` is not a valid NFT. - @param _tokenId uint256 id of the ERC721 token to be burned. + @dev Belirli bir ERC721 jetonunu yakar. + `msg.sender` mevcut sahip, yetkili bir operatör veya bu NFT için onaylanmış + adres değilse hata verir. + `_tokenId` geçerli bir NFT değilse hata verir. + @param _tokenId Yakılacak ERC721 jetonunun uint256 id'si. """ # Check requirements assert self._isApprovedOrOwner(msg.sender, _tokenId) owner: address = self.idToOwner[_tokenId] - # Throws if `_tokenId` is not a valid NFT + # `_tokenId` geçerli bir NFT değilse hata verir assert owner != ZERO_ADDRESS self._clearApproval(owner, _tokenId) self._removeTokenFrom(owner, _tokenId) log Transfer(owner, ZERO_ADDRESS, _tokenId) ``` -Bir token'ı transfer etmesine izin verilen herkesin onu yakmasına izin verilir. Bir yakma işlemi, sıfır adresine aktarıma eş değer görünse de, sıfır adresi aslında token'ı almaz. Bu, token için kullanılan tüm depolama alanını boşaltmamızı sağlar ve bu da işlemin gasz maliyetini azaltabilir. +Bir jetonu aktarmasına izin verilen herkesin onu yakmasına izin verilir. Bir yakma işlemi, sıfır adresine aktarıma eş değer görünse de, sıfır adresi aslında jetonu almaz. Bu, jeton için kullanılan tüm depolama alanını boşaltmamızı sağlar ve bu da işlemin gaz maliyetini azaltabilir. -## Bu Sözleşmeyi Kullanmak {#using-contract} +## Bu Sözleşmeyi Kullanma {#using-contract} -Solidity'nin aksine, Vyper'ın kalıtımı yoktur. Bu, kodu daha net hâle getirmek ve dolayısıyla güvenliğini sağlamak için bilinçli bir tasarım seçimidir. Bu nedenle, kendi Vyper ERC-721 sözleşmenizi oluşturmak için [bu sözleşmeyi](https://github.com/vyperlang/vyper/blob/master/examples/tokens/ERC721.vy) alın ve istediğiniz iş mantığını uygulamak için değiştirin. +Solidity'nin aksine, Vyper'ın kalıtımı yoktur. Bu, kodu daha net hâle getirmek ve dolayısıyla güvenliğini sağlamak için bilinçli bir tasarım seçimidir. Yani kendi Vyper ERC-721 sözleşmenizi oluşturmak için bu +sözleşmeyi alır ve istediğiniz iş mantığını uygulamak için değiştirirsiniz. -### Sonuç {#conclusion} +## Sonuç {#conclusion} İnceleme için, bu sözleşmedeki en önemli fikirlerden bazıları şunlardır: -- ERC-721 token'larını güvenli bir aktarımla almak için sözleşmelerin `ERC721Receiver` arayüzünü uygulaması gerekir. -- Güvenli transfer kullansanız bile, özel anahtarı bilinmeyen bir adrese gönderirseniz token'lar takılıp kalabilir. -- Bir operasyonla ilgili bir sorun olduğunda çağrıyı `revert` etmek, bir başarısızlık değeri döndürmekten daha iyi bir fikirdir. -- ERC-721 token'ları, bir sahibi olduğunda var olurlar. -- Bir NFT'yi transfer etme yetkisine sahip olmanın üç yolu vardır. Sahibi olabilir, belirli bir token için onay alabilir veya sahibinin tüm token'ları için operatör olabilirsiniz. -- Geçmiş olaylar sadece blok zincirinin dışında görülebilir. Blok zincirinin içinde çalışan kod onları göremez. +- ERC-721 jetonlarını güvenli bir aktarımla almak için sözleşmelerin `ERC721Receiver` arayüzünü uygulaması gerekir. +- Güvenli aktarım kullansanız bile, özel anahtarı bilinmeyen bir adrese gönderirseniz jetonlar takılıp kalabilir. +- Bir işlemle ilgili bir sorun olduğunda yalnızca bir hata değeri döndürmek yerine çağrıyı `geri almak` iyi bir fikirdir. +- ERC-721 jetonları, bir sahibi olduğunda var olurlar. +- Bir NFT'yi aktarma yetkisine sahip olmanın üç yolu vardır. Sahibi olabilir, belirli bir jeton için onay alabilir + veya sahibinin tüm jetonları için operatör olabilirsiniz. +- Geçmiş olaylar sadece blokzincirin dışında görülebilir. Blokzincirin içinde çalışan kod onları göremez. Artık güvenli Vyper sözleşmelerini uygulayabilirsiniz. + +[Çalışmalarımdan daha fazlası için buraya bakın](https://cryptodocguy.pro/). + diff --git a/public/content/translations/tr/developers/tutorials/erc20-annotated-code/index.md b/public/content/translations/tr/developers/tutorials/erc20-annotated-code/index.md index 17bb723621f..2e9d9a8bbfa 100644 --- a/public/content/translations/tr/developers/tutorials/erc20-annotated-code/index.md +++ b/public/content/translations/tr/developers/tutorials/erc20-annotated-code/index.md @@ -1,30 +1,29 @@ --- title: "ERC-20 Sözleşmesine Genel Bakış" -description: OpenZeppelin ERC-20 sözleşmesinde neler var ve neden var? +description: "OpenZeppelin ERC-20 sözleşmesinde ne var ve neden var?" author: Ori Pomerantz lang: tr -tags: - - "solidity" - - "erc-20" +tags: [ "katılık", "erc-20" ] skill: beginner published: 2021-03-09 --- ## Giriş {#introduction} -Ethereum'un en yaygın kullanımlarından biri, bir grubun bir anlamda kendi para birimi olan ticareti yapılabilen bir token oluşturmasıdır. Bu token'lar genelde bir standarda, yani [ERC-20](/developers/docs/standards/tokens/erc-20/)'ye uyumludur. Bu standart, tüm ERC-20 token'larıyla çalışan likidite havuzları ve cüzdanlar gibi araçlar yazmayı mümkün kılar. Bu makalede [OpenZeppelin Solidity ERC20 uygulamasını](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol) ve [arayüz tanımını](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol) analiz edeceğiz. +Ethereum'un en yaygın kullanımlarından biri, bir grubun bir anlamda kendi para birimi olan ticareti yapılabilen bir token oluşturmasıdır. Bu jetonlar genellikle bir standardı takip eder, +[ERC-20](/developers/docs/standards/tokens/erc-20/). Bu standart, likidite havuzları ve cüzdanlar gibi tüm ERC-20 jetonlarıyla çalışan araçlar yazmayı mümkün kılar. Bu makalede [OpenZeppelin Solidity ERC20 uygulamasını](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol) ve [arayüz tanımını](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol) analiz edeceğiz. -Bu, açıklanmış kaynak koddur. Eğer ERC-20 kullanmak isterseniz, [bu öğreticiyi okuyun](https://docs.openzeppelin.com/contracts/2.x/erc20-supply). +Bu, açıklamalı bir kaynak kodudur. ERC-20'yi uygulamak istiyorsanız [bu eğitimi okuyun](https://docs.openzeppelin.com/contracts/2.x/erc20-supply). ## Arayüz {#the-interface} -ERC-20 gibi bir standardın amacı, cüzdanlar ve merkeziyetsiz borsalar gibi uygulamalar arasında birlikte çalışabilen birçok token uygulamasına izin vermektir. Bunu sağlamak için, bir [arayüz](https://www.geeksforgeeks.org/solidity-basics-of-interface/) oluştururuz. Token sözleşmesini kullanması gereken herhangi bir kod, arayüzde aynı tanımları kullanabilir ve onu kullanan tüm token sözleşmeleriyle uyumlu olarak, MetaMask gibi bir cüzdan, etherscan.io gibi bir dapp veya likidite havuzu gibi farklı bir sözleşme olabilir. +ERC-20 gibi bir standardın amacı, cüzdanlar ve merkeziyetsiz borsalar gibi uygulamalar arasında birlikte çalışabilen birçok jeton uygulamasını mümkün kılmaktır. Bunu başarmak için bir [arayüz](https://www.geeksforgeeks.org/solidity/solidity-basics-of-interface/) oluştururuz. Jeton sözleşmesini kullanması gereken herhangi bir kod, arayüzdeki aynı tanımları kullanabilir ve onu kullanan tüm jeton sözleşmeleriyle uyumlu olabilir; bu MetaMask gibi bir cüzdan, etherscan.io gibi bir dapp veya bir likidite havuzu gibi farklı bir sözleşme olabilir. ![ERC-20 arayüzünün çizimi](erc20_interface.png) -Deneyimli bir programcıysanız, muhtemelen [Java](https://www.w3schools.com/java/java_interface.asp)'da ve hatta [C header dosyalarında](https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html) benzer yapılar gördüğünüzü hatırlıyorsunuzdur. +Deneyimli bir programcıysanız, [Java](https://www.w3schools.com/java/java_interface.asp) veya hatta [C başlık dosyalarında](https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html) benzer yapılar gördüğünüzü muhtemelen hatırlarsınız. -Bu, OpenZeppelin'in yaptığı bir [ERC-20 Arayüzü](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol) tanımıdır. [İnsan tarafından okunabilir standardın](https://eips.ethereum.org/EIPS/eip-20) Solidity koduna çevirisidir. Elbette, arayüzün kendisi herhangi bir şeyi _nasıl_ yapacağını tanımlamaz. Bu, aşağıdaki sözleşme kaynak kodunda açıklanmıştır. +Bu, OpenZeppelin'den alınan [ERC-20 Arayüzünün](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol) bir tanımıdır. [İnsan tarafından okunabilir standardın](https://eips.ethereum.org/EIPS/eip-20) Solidity koduna çevirisidir. Elbette arayüzün kendisi, herhangi bir şeyin _nasıl_ yapılacağını tanımlamaz. Bu, aşağıdaki sözleşme kaynak kodunda açıklanmıştır.   @@ -32,7 +31,7 @@ Bu, OpenZeppelin'in yaptığı bir [ERC-20 Arayüzü](https://github.com/OpenZep // SPDX-License-Identifier: MIT ``` -Solidity dosyalarının bir lisans tanımlayıcısı içermesi gerekir. [Burada lisansların bir listesini görebilirsiniz](https://spdx.org/licenses/). Farklı bir lisansa ihtiyacınız varsa, bunu yorumlarda açıklamanız yeterlidir. +Solidity dosyalarının bir lisans tanımlayıcısı içermesi gerekir. [Lisansların listesini burada görebilirsiniz](https://spdx.org/licenses/). Farklı bir lisansa ihtiyacınız varsa bunu yorumlarda açıklamanız yeterlidir.   @@ -40,17 +39,17 @@ Solidity dosyalarının bir lisans tanımlayıcısı içermesi gerekir. [Burada pragma solidity >=0.6.0 <0.8.0; ``` -Solidity dili hâlâ hızla gelişiyor ve yeni sürümler eski kodla uyumlu olmayabilir ([buraya bakın](https://docs.soliditylang.org/en/v0.7.0/070-breaking-changes.html)). Bu nedenle, dilin yalnızca minimum sürümünü değil, aynı zamanda kodu test ettiğiniz en son sürüm olan maksimum sürümünü de belirtmek iyi bir fikirdir. +Solidity dili hâlâ hızla gelişiyor ve yeni sürümler eski kodlarla uyumlu olmayabilir ([buraya bakın](https://docs.soliditylang.org/en/v0.7.0/070-breaking-changes.html)). Bu nedenle, yalnızca dilin minimum sürümünü değil, aynı zamanda kodu test ettiğiniz en son sürüm olan maksimum sürümünü de belirtmek iyi bir fikirdir.   ```solidity /** - * @dev ERC20 standardının EIP'de tanımlandığı gibi arayüzü. + * @dev EIP'de tanımlandığı şekliyle ERC20 standardının arayüzü. */ ``` -Yorumdaki `@dev`, kaynak kodundan belge oluşturmak için kullanılan [NatSpec formatının](https://docs.soliditylang.org/en/develop/natspec-format.html) bir parçasıdır. +Yorumdaki `@dev`, kaynak kodundan doküman üretmek için kullanılan [NatSpec formatının](https://docs.soliditylang.org/en/develop/natspec-format.html) bir parçasıdır.   @@ -58,84 +57,90 @@ Yorumdaki `@dev`, kaynak kodundan belge oluşturmak için kullanılan [NatSpec f interface IERC20 { ``` -Kural olarak, arayüz isimleri `I` ile başlar. +Kural gereği, arayüz adları `I` ile başlar.   ```solidity /** - * @dev Mevcudiyetteki token miktarını döndürür. + * @dev Mevcut jeton miktarını döndürür. */ function totalSupply() external view returns (uint256); ``` -Bu fonksiyon `external`'dır (harici), yani [sadece sözleşmenin dışından çağrılabilir](https://docs.soliditylang.org/en/v0.7.0/cheatsheet.html#index-2). Sözleşmedeki toplam token arzını döndürür. Bu değer, Ethereum'daki en yaygın tür olan imzasız 256 bit kullanılarak döndürülür (256 bit, EVM'nin yerel kelime boyutudur). Bu fonksiyon aynı zamanda bir `view`'dur, yani durumu değiştirmez, bu nedenle blok zincirindeki her düğümün çalıştırması yerine tek bir düğümde yürütülebilir. Bu tür bir fonksiyon bir işlem oluşturmaz ve fonksiyonun [gaz](/developers/docs/gas/) maliyeti yoktur. +Bu fonksiyon `external`'dır, yani [yalnızca sözleşmenin dışından çağrılabilir](https://docs.soliditylang.org/en/v0.7.0/cheatsheet.html#index-2). +Sözleşmedeki toplam jeton arzını döndürür. Bu değer, Ethereum'daki en yaygın tür olan işaretsiz 256 bit kullanılarak döndürülür (256 bit, EVM'nin yerel kelime boyutudur). Bu fonksiyon aynı zamanda bir `view`'dır, yani durumu değiştirmez, bu nedenle blokzincirindeki her düğümün çalıştırması yerine tek bir düğümde yürütülebilir. Bu tür bir fonksiyon bir işlem oluşturmaz ve [gaz](/developers/docs/gas/) maliyeti yoktur. -**Not:** Teoride, bir sözleşmeyi oluşturan kişinin, gerçek değerden daha küçük bir toplam arz döndürerek, her bir token'ın gerçekte olduğundan daha değerli görünmesini sağlayarak hile yapabileceği görünebilir. Ancak, bu korku blok zincirinin gerçek doğasını görmezden geliyor. Blok zincirinde olan her şey, her düğüm tarafından doğrulanabilir. Bunu başarmak için, her sözleşmenin makine dili kodu ve depolaması her düğümde mevcuttur. Sözleşmenizin Solidity kodunu yayınlamanız gerekmese de, sağladığınız makina dili koduna karşı doğrulanabilmesi için kaynak kodunu ve derlendiği Solidity versiyonunu paylaşana kadar kimse sizi ciddiye almaz. Örnek olarak, [bu sözleşmeye](https://etherscan.io/address/0xa530F85085C6FE2f866E7FdB716849714a89f4CD#code) bakın. +**Not:** Teoride, bir sözleşmeyi oluşturan kişinin, gerçek değerden daha küçük bir toplam arz döndürerek her bir jetonun gerçekte olduğundan daha değerli görünmesini sağlayarak hile yapabileceği düşünülebilir. Ancak bu korku, blokzincirin gerçek doğasını göz ardı eder. Blokzincirinde olan her şey her düğüm tarafından doğrulanabilir. Bunu başarmak için, her sözleşmenin makine dili kodu ve depolaması her düğümde mevcuttur. Sözleşmeniz için Solidity kodunu yayınlamanız gerekmese de, sağladığınız makine dili koduna karşı doğrulanabilmesi için kaynak kodunu ve derlendiği Solidity sürümünü yayınlamadığınız sürece kimse sizi ciddiye almaz. +Örneğin, [bu sözleşmeye](https://eth.blockscout.com/address/0xa530F85085C6FE2f866E7FdB716849714a89f4CD?tab=contract) bakın.   ```solidity /** - * @dev `account` tarafından sahip olunan token miktarını döndürür. + * @dev `account`un sahip olduğu jeton miktarını döndürür. */ function balanceOf(address account) external view returns (uint256); ``` -Adından da anlaşılacağı üzere, `balanceOf` (bakiyesi) bir hesabın bakiyesini döndürür. Ethereum hesapları, 160 bit tutan `address` türü kullanılarak Solidity'de tanımlanır. Ayrıca `external` ve `view`'dur. +Adından da anlaşılacağı gibi, `balanceOf` bir hesabın bakiyesini döndürür. Ethereum hesapları, 160 bit tutan `address` türü kullanılarak Solidity'de tanımlanır. +Ayrıca `external` ve `view`'dur.   ```solidity /** - * @dev `amount` tokeni çağıranın hesabından `recipient` hesabına hareket ettirir. + * @dev Arayan kişinin hesabından `recipient`a `amount` kadar jeton taşır. * - * İşlemin başarılı olup olmadığını gösteren bir boole değeri döndürür. + * İşlemin başarılı olup olmadığını gösteren bir boolean değeri döndürür. * * Bir {Transfer} olayı yayar. */ function transfer(address recipient, uint256 amount) external returns (bool); ``` -`transfer` fonksiyonu çağırandan farklı bir adrese token'ları aktarır. Bu bir durum değişikliği içerir, yani `view` değildir. Bir kullanıcı bu fonksiyonu çağırdığında bir işlem oluşturur ve gaz harcar. Ayrıca, blok zincirindeki herkese olay hakkında bilgi vermek için `Transfer` adlı bir olay yayar. +`transfer` fonksiyonu, jetonları arayandan farklı bir adrese aktarır. Bu bir durum değişikliği içerir, dolayısıyla bir `view` değildir. +Bir kullanıcı bu fonksiyonu çağırdığında bir işlem oluşturur ve gaz harcar. Ayrıca, blokzincirindeki herkese olay hakkında bilgi vermek için `Transfer` adlı bir olay yayar. -Fonksiyon, iki farklı türde çağıran için iki tür çıktıya sahiptir: +Fonksiyonun, iki farklı türde arayan için iki tür çıktısı vardır: -- Fonksiyonu doğrudan bir kullanıcı arabiriminden çağıran kullanıcılar. Tipik olarak, kullanıcı bir işlem gönderir ve ne zaman geleceği belli olmayan yanıtın gelmesini beklemez. Kullanıcı, işlem makbuzunu (işlem hash değeri ile tanımlanır) arayarak veya `Transfer` olayını arayarak ne olduğunu görebilir. -- Genel bir işlemin parçası olarak fonksiyonu çağıran diğer sözleşmeler. Bu sözleşmeler, aynı işlemde çalıştıkları için sonucu hemen alırlar, böylece fonksiyon dönüş değerini kullanabilirler. +- Fonksiyonu doğrudan bir kullanıcı arayüzünden çağıran kullanıcılar. Genellikle kullanıcı bir işlem gönderir ve süresiz olarak sürebilecek bir yanıt beklemez. Kullanıcı, işlem makbuzunu (işlem karması ile tanımlanır) arayarak veya `Transfer` olayını arayarak ne olduğunu görebilir. +- Fonksiyonu genel bir işlemin parçası olarak çağıran diğer sözleşmeler. Bu sözleşmeler, aynı işlemde çalıştıkları için sonucu hemen alır, böylece fonksiyon dönüş değerini kullanabilirler. Aynı tür çıktı, sözleşmenin durumunu değiştiren diğer fonksiyonlar tarafından oluşturulur.   -Ödenekler, bir hesabın farklı bir sahibine ait olan bazı token'ları harcamasına izin verir. Bu, örneğin satıcı olarak hareket eden sözleşmeler için kullanışlıdır. Sözleşmeler olayları izleyemez, bu nedenle bir alıcı token'ları doğrudan satıcı sözleşmesine aktarırsa, bu sözleşme ödendiğini bilemez. Bunun yerine alıcı, satıcı sözleşmesinin belirli bir miktarı harcamasına izin verir ve satıcı bu tutarı transfer eder. Bu, satıcı sözleşmesinin çağırdığı bir fonksiyon aracılığıyla yapılır, böylece satıcı sözleşmesinin başarılı olup olmadığını anlayabilir. +Ödenekler, bir hesabın farklı bir sahibine ait olan bazı jetonları harcamasına izin verir. +Bu, örneğin satıcı olarak hareket eden sözleşmeler için kullanışlıdır. Sözleşmeler olayları izleyemez, bu nedenle bir alıcı jetonları doğrudan satıcı sözleşmesine aktarırsa bu sözleşme ödendiğini bilemez. Bunun yerine alıcı, satıcı sözleşmesinin belirli bir miktarı harcamasına izin verir ve satıcı bu tutarı transfer eder. +Bu, satıcı sözleşmesinin çağırdığı bir fonksiyon aracılığıyla yapılır, böylece satıcı sözleşmesi başarılı olup olmadığını anlayabilir. ```solidity /** - * @dev, `spender` adresinin `owner` adına {transferFrom} - * aracılığıyla harcayabileceği kalan token miktarını döndürür. Bu - * varsayılan olarak sıfırdır. + * @dev `spender`ın {transferFrom} aracılığıyla `owner` adına harcamasına + * izin verilecek kalan jeton sayısını döndürür. Bu varsayılan + * olarak sıfırdır. * - * Bu değer {approve} veya {transferFrom} çağırıldığında değişir. + * Bu değer, {approve} veya {transferFrom} çağrıldığında değişir. */ function allowance(address owner, address spender) external view returns (uint256); ``` -`allowance` fonksiyonu, herkesin bir adresin (`owner`) başka bir adresin (`spender`) harcamasına izin verdiği ödeneği görmek için sorgulama yapmasına olanak tanır. +`allowance` fonksiyonu, herkesin bir adresin (`owner`) başka bir adresin (`spender`) harcamasına izin verdiği ödeneği sorgulamasına olanak tanır.   ```solidity /** - * @dev Çağıranın token'ları üzerinde `spender` ödeneğini `amount` olarak belirler. + * @dev Arayanın jetonları üzerinde `spender`ın ödeneği olarak `amount`u ayarlar. * - * İşlemin başarılı olup olmadığını gösteren bir boolean değeri döndürür. + * İşlemin başarılı olup olmadığını gösteren bir boole değeri döndürür. * - * ÖNEMLİ: Bu yöntemle bir ödeneği değiştirmenin, talihsiz işlem sıralaması ile - * birinin hem eski hem de yeni ödeneği kullanması riskini - * taşıdığına dikkat edin. Bu yarış koşulunun etkisini azaltmanın muhtemel bir yolu, - * ilk olarak harcayanın ödeneğini 0'a ayarlayıp arzulanan değeri - * daha sonra belirlemektir: + * ÖNEMLİ: Bu yöntemle bir ödeneği değiştirmenin, + * birisinin şanssız bir işlem sıralamasıyla hem eski hem de yeni ödeneği + * kullanma riski taşıdığına dikkat edin. Bu yarış + * durumunu azaltmak için olası bir çözüm, önce harcama yapanın ödeneğini 0'a + * indirmek ve ardından istenen değeri ayarlamaktır: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Bir {Approval} olayı yayar. @@ -143,40 +148,40 @@ Aynı tür çıktı, sözleşmenin durumunu değiştiren diğer fonksiyonlar tar function approve(address spender, uint256 amount) external returns (bool); ``` -`approve` fonksiyonu bir ödenek oluşturur. Nasıl kötüye kullanılabileceğine dair mesajı okuduğunuzdan emin olun. Ethereum'da kendi işlemlerinizin sırasını kontrol edersiniz, ancak diğer tarafın işleminin gerçekleştiğini görene kadar kendi işleminizi göndermediğiniz sürece diğer kişilerin işlemlerinin yürütüleceği sırayı kontrol edemezsiniz. +`approve` fonksiyonu bir ödenek oluşturur. Nasıl kötüye kullanılabileceğiyle ilgili mesajı okuduğunuzdan emin olun. Ethereum'da kendi işlemlerinizin sırasını kontrol edersiniz, ancak diğer tarafın işleminin gerçekleştiğini görene kadar kendi işleminizi göndermezseniz, diğer kişilerin işlemlerinin yürütüleceği sırayı kontrol edemezsiniz.   ```solidity /** - * @dev Ödenek mekanizmasını kullanarak `amount` token'ı `sender` adresinden `recipient` - * adresine aktarır. `amount` bunun sonrasında çağıranın ödeneğinden - * kesilir. + * @dev Ödenek mekanizmasını kullanarak `sender`dan `recipient`a `amount` + * kadar jeton taşır. `amount` daha sonra arayanın + * ödeneğinden düşülür. * - * İşlemin başarılı olup olmadığını gösteren bir boolean değeri döndürür. + * İşlemin başarılı olup olmadığını gösteren bir boole değeri döndürür. * * Bir {Transfer} olayı yayar. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); ``` -Son olarak `transferFrom`, harcayan tarafından ödeneği gerçekten harcamak için kullanılır. +Son olarak, `transferFrom` harcayan tarafından ödeneği gerçekten harcamak için kullanılır.   ```solidity /** - * @dev `value` token bir hesaptan (`from`) diğerine (`to`) hareket - * ettirildiğinde yayılır. + * @dev Bir hesaptan (`from`) diğerine (`to`) + * `value` kadar jeton taşındığında yayılır. * - * `value` sıfır olabilir, bunu unutmayın. + * `value`un sıfır olabileceğini unutmayın. */ event Transfer(address indexed from, address indexed to, uint256 value); /** - * @dev Emitted when the allowance of a `spender` for an `owner` is set by - * a call to {approve}. `value` yeni ödenektir. + * @dev Bir `owner` için bir `spender` ödeneği, {approve} çağrısıyla + * ayarlandığında yayılır. `value` yeni ödenektir. */ event Approval(address indexed owner, address indexed spender, uint256 value); } @@ -186,7 +191,8 @@ Bu olaylar, ERC-20 sözleşmesinin durumu değiştiğinde yayılır. ## Asıl Sözleşme {#the-actual-contract} -Bu, [buradan alınan](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol) ERC-20 standardını uygulayan asıl sözleşmedir. Olduğu gibi kullanılması için yapılmamıştır, ancak onu kullanılabilir bir hâle getirmek için [kalıtım](https://www.tutorialspoint.com/solidity/solidity_inheritance.htm) şeklinde alabilirsiniz. +Bu, [buradan alınan](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol) ERC-20 standardını uygulayan asıl sözleşmedir. +Olduğu gibi kullanılması amaçlanmamıştır, ancak onu kullanılabilir bir şeye genişletmek için ondan [kalıtım alabilirsiniz](https://www.tutorialspoint.com/solidity/solidity_inheritance.htm). ```solidity // SPDX-License-Identifier: MIT @@ -195,7 +201,7 @@ pragma solidity >=0.6.0 <0.8.0;   -### İfadeleri İçe Aktarın {#import-statements} +### İçe Aktarma İfadeleri {#import-statements} Yukarıdaki arayüz tanımlarına ek olarak, sözleşme tanımı diğer iki dosyayı içe aktarır: @@ -206,8 +212,8 @@ import "./IERC20.sol"; import "../../math/SafeMath.sol"; ``` -- `GSN/Context.sol`, ether'siz kullanıcıların blok zincirini kullanmasına izin veren bir sistem olan [OpenGSN](https://www.opengsn.org/)'yi kullanmak için gereken tanımlardır. Bunun eski bir sürüm olduğun unutmayın, OpenGSN ile entegre olmak istiyorsanız [bu öğreticiyi kullanın](https://docs.opengsn.org/javascript-client/tutorial.html). -- [SafeMath kütüphanesi](https://ethereumdev.io/using-safe-math-library-to-prevent-from-overflows/), taşma olmadan toplama ve çıkarma yapmak için kullanılır. Aksi takdirde bir kişinin bir şekilde bir token'ı varken iki token harcayarak 2^256-1 token'a sahip olabileceği için bu gereklidir. +- `GSN/Context.sol`, ether'i olmayan kullanıcıların blokzincirini kullanmasına olanak tanıyan bir sistem olan [OpenGSN](https://www.opengsn.org/)'yi kullanmak için gereken tanımlardır. Bunun eski bir sürüm olduğunu unutmayın, OpenGSN ile entegre olmak istiyorsanız [bu eğitimi kullanın](https://docs.opengsn.org/javascript-client/tutorial.html). +- Solidity'nin **<0.8.0** sürümleri için aritmetik taşmaları/eksik kalmaları önleyen [SafeMath kütüphanesi](https://ethereumdev.io/using-safe-math-library-to-prevent-from-overflows/). Solidity ≥0.8.0'da, aritmetik işlemler taşma/eksik kalma durumunda otomatik olarak geri döner, bu da SafeMath'i gereksiz kılar. Bu sözleşme, eski derleyici sürümleriyle geriye dönük uyumluluk için SafeMath kullanır.   @@ -217,26 +223,26 @@ Bu yorum, sözleşmenin amacını açıklar. /** * @dev {IERC20} arayüzünün uygulanması. * - * Bu uygulama, token'ların oluşturulma şekline karşı agnostiktir. Bu, - * {_mint} kullanılarak türetilmiş bir sözleşmeye bir tedarik mekanizmasının eklenmesi gerektiği anlamına gelir. - * Kapsamlı bir mekanizma için bkz. {ERC20PresetMinterPauser}. + * Bu uygulama, jetonların oluşturulma şeklinden bağımsızdır. Bu, {_mint} kullanılarak + * türetilmiş bir sözleşmeye bir arz mekanizmasının eklenmesi gerektiği anlamına gelir. + * Genel bir mekanizma için bkz. {ERC20PresetMinterPauser}. * * İPUCU: Ayrıntılı bir yazı için rehberimize bakın - * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[Tedarik + * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[Arz * mekanizmaları nasıl uygulanır]. * - * Genel OpenZeppelin talimatlarını izledik: fonksiyonlar, başarısızlık durumunda - * `false` döndürmek yerine geri alınırlar. Bu davranış yine de gelenekseldir + * Genel OpenZeppelin yönergelerini takip ettik: fonksiyonlar başarısız olduğunda + * `false` döndürmek yerine geri döner. Bu davranış yine de gelenekseldir * ve ERC20 uygulamalarının beklentileriyle çelişmez. * * Ek olarak, {transferFrom} çağrılarında bir {Approval} olayı yayılır. - * Bu, söz konusu olayları dinleyerek uygulamaların tüm hesaplar için - * ödeneği yeniden yapılandırmasına izin verir. EIP'nin diğer uygulamaları, şartname gerektirmediği için - * bu olayları yaymayabilir. + * Bu, uygulamaların sadece bu olayları dinleyerek tüm hesaplar için + * ödeneği yeniden oluşturmasına olanak tanır. EIP'nin diğer uygulamaları, spesifikasyonda + * gerekli olmadığı için bu olayları yaymayabilir. * - * Son olarak, ödenek ayarlama ile ilgili bilinen sorunları azaltmak için - * standart olmayan {decreaseAllowance} ve {increaseAllowance} fonksiyonları - * eklenmiştir. Bakınız {IERC20-approve}. + * Son olarak, standart dışı {decreaseAllowance} ve {increaseAllowance} + * fonksiyonları, ödenekleri ayarlamayla ilgili bilinen sorunları azaltmak + * için eklenmiştir. Bkz. {IERC20-approve}. */ ``` @@ -257,19 +263,19 @@ Bu satır, bu durumda OpenGSN için yukarıdaki `IERC20`'den ve `Context`'ten ka ``` -Bu satır `SafeMath` kütüphanesini `uint256` türüne bağlar. Bu kütüphaneyi [burada](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol) bulabilirsiniz. +Bu satır, `SafeMath` kütüphanesini `uint256` türüne bağlar. Bu kütüphaneyi [burada](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol) bulabilirsiniz. ### Değişken Tanımları {#variable-definitions} -Bu tanımlar, sözleşmenin durum değişkenlerini belirtir. Değişkenler `private` olarak bildirilir, ancak bu yalnızca blok zincirindeki diğer sözleşmelerin onları okuyamayacağı anlamına gelir. _Blok zinciri üzerinde sır yoktur_, her düğümdeki yazılım her bloktaki her sözleşmenin durumunu bulundurur. Kural olarak, durum değişkenleri `_` olarak isimlendirilir. +Bu tanımlar, sözleşmenin durum değişkenlerini belirtir. Bu değişkenler `private` olarak bildirilmiştir, ancak bu yalnızca blokzincirindeki diğer sözleşmelerin onları okuyamayacağı anlamına gelir. _Blokzincirinde sır yoktur_, her düğümdeki yazılım, her bloktaki her sözleşmenin durumuna sahiptir. Kural olarak, durum değişkenleri `_` olarak adlandırılır. -İlk iki değişken, anahtarların sayısal değerler olması dışında, [ilişkisel dizilerle](https://wikipedia.org/wiki/Associative_array) kabaca aynı şekilde davrandıkları anlamına gelen [eşleştirmelerdir](https://www.tutorialspoint.com/solidity/solidity_mappings.htm). Depolama, yalnızca varsayılandan (sıfır) farklı değerlere sahip girdiler için tahsis edilir. +İlk iki değişken [eşlemelerdir](https://www.tutorialspoint.com/solidity/solidity_mappings.htm), yani anahtarların sayısal değerler olması dışında kabaca [ilişkisel dizilerle](https://wikipedia.org/wiki/Associative_array) aynı şekilde davranırlar. Depolama, yalnızca varsayılandan (sıfır) farklı değerlere sahip girdiler için tahsis edilir. ```solidity mapping (address => uint256) private _balances; ``` -İlk eşleme, `_balances`, adresler ve bu token'ın ilgili bakiyeleridir. Bakiyeye erişmek için, bu söz dizimini kullanın: `_balances[
]`. +İlk eşleme olan `_balances`, adresleri ve bu jetonun ilgili bakiyelerini içerir. Bakiyeye erişmek için şu söz dizimini kullanın: `_balances[]`.   @@ -277,7 +283,7 @@ Bu tanımlar, sözleşmenin durum değişkenlerini belirtir. Değişkenler `priv mapping (address => mapping (address => uint256)) private _allowances; ``` -Bu değişken, `_allowances`, daha önce açıklanan ödenekleri saklar. İlk endeks, token'ların sahibidir ve ikincisi, ödeneğin olduğu sözleşmedir. A adresinin B adresinin hesabından harcayabileceği miktara erişmek için `_allowances[B][A]` kullanın. +Bu değişken, `_allowances`, daha önce açıklanan ödenekleri saklar. İlk dizin jetonların sahibidir ve ikincisi ödeneğe sahip olan sözleşmedir. A adresinin B adresinin hesabından harcayabileceği miktara erişmek için `_allowances[B][A]` kullanın.   @@ -285,7 +291,7 @@ Bu değişken, `_allowances`, daha önce açıklanan ödenekleri saklar. İlk en uint256 private _totalSupply; ``` -Adından da anlaşılacağı gibi, bu değişken toplam token arzını takip eder. +Adından da anlaşılacağı gibi, bu değişken toplam jeton arzını takip eder.   @@ -297,124 +303,126 @@ Adından da anlaşılacağı gibi, bu değişken toplam token arzını takip ede Bu üç değişken okunabilirliği artırmak için kullanılır. İlk ikisi kendini açıklayıcıdır, ancak `_decimals` farklıdır. -Bir yandan, ethereum'un kayan nokta veya kesirli değişkenleri yoktur. Diğer taraftan, insanlar token'ları bölebilmeyi sever. İnsanların para birimi olarak altını seçmesinin bir nedeni, birisi bir ördeğin değerinde inek almak istediğinde değişiklik yapmanın zor olmasıydı. +Bir yandan, Ethereum'da kayan noktalı veya kesirli değişkenler yoktur. Diğer yandan, insanlar jetonları bölebilmeyi sever. İnsanların para birimi olarak altını seçmesinin bir nedeni, birisi bir ördeğin değerinde inek almak istediğinde para üstü vermenin zor olmasıydı. -Çözüm, tam sayıları takip etmektir ancak gerçek token yerine neredeyse değersiz olan kesirli bir token saymaktır. Ether durumunda, kesirli token wei olarak adlandırılır ve 10^18 wei bir ETH'ye eşittir. Yazarken, 10.000.000.000.000.000 wei yaklaşık olarak bir ABD veya Euro sentidir. +Çözüm, tam sayıları takip etmek, ancak gerçek jeton yerine neredeyse değersiz olan kesirli bir jetonu saymaktır. Ether durumunda, kesirli jetona wei denir ve 10^18 wei bir ETH'ye eşittir. Bu yazı yazıldığı sırada, 10.000.000.000.000 wei yaklaşık bir ABD veya Euro sentine eşittir. -Uygulamalar token bakiyesini nasıl göstereceklerini bilmelidir. Bir kullanıcının 3.141.000.000.000.000.000 wei'si varsa, bu 3,14 ETH midir? 31.41 ETH? 3,141 ETH? Ether durumunda, ETH'ye 10^18 wei olarak tanımlanır ancak kendi token'ınız için farklı bir değer seçebilirsiniz. Eğer token'ı bölmek mantıklı gelmiyorsa sıfır değerinde bir `_decimals` kullanabilirsiniz. ETH ile aynı standardı kullanmak istiyorsanız, **18** değerini kullanın. +Uygulamaların jeton bakiyesini nasıl göstereceklerini bilmeleri gerekir. Bir kullanıcının 3.141.000.000.000.000.000 wei'si varsa, bu 3,14 ETH midir? 31,41 ETH mi? 3.141 ETH mi? Ether durumunda, ETH'ye 10^18 wei olarak tanımlanır ancak kendi jetonunuz için farklı bir değer seçebilirsiniz. Jetonu bölmek mantıklı değilse, sıfır değerinde bir `_decimals` kullanabilirsiniz. ETH ile aynı standardı kullanmak istiyorsanız, **18** değerini kullanın. -### Yapıcı {#the-constructor} +### Oluşturucu {#the-constructor} ```solidity /** - * @dev {name} ve {symbol} için değerleri belirler, varsayılan 18 değeriyle - * {decimals} oluşturur. + * @dev {name} ve {symbol} için değerleri ayarlar, {decimals}'i + * varsayılan 18 değeriyle başlatır. * - * {decimals} için farklı bir değer seçmek için, {_setupDecimals} kullanın. + * {decimals} için farklı bir değer seçmek için {_setupDecimals} kullanın. * - * Bu değerlerin üçü de değişmezdir: yalnızca oluşturma sırasında bir kez - * ayarlanabilirler. + * Bu üç değerin tümü sabittir: yalnızca oluşturma sırasında + * bir kez ayarlanabilirler. */ constructor (string memory name_, string memory symbol_) public { + // Solidity ≥0.7.0'da, 'public' örtüktür ve atlanabilir. + _name = name_; _symbol = symbol_; _decimals = 18; } ``` -Yapıcı, sözleşme ilk oluşturulduğunda çağrılır. Kural olarak, fonksiyon parametreleri `_` olarak isimlendirilir. +Oluşturucu, sözleşme ilk oluşturulduğunda çağrılır. Kural gereği, fonksiyon parametreleri `_` olarak adlandırılır. ### Kullanıcı Arayüzü Fonksiyonları {#user-interface-functions} ```solidity /** - * @dev Token'ın adını döndürür. + * @dev Jetonun adını döndürür. */ function name() public view returns (string memory) { return _name; } /** - * @dev Returns the symbol of the token, usually a shorter version of the - * name. + * @dev Genellikle adın daha kısa bir versiyonu olan jetonun sembolünü + * döndürür. */ function symbol() public view returns (string memory) { return _symbol; } /** - * @dev Returns the number of decimals used to get its user representation. - * Örnek olarak, eğer `decimals` eşittir `2` ise, `505` token'lık bakiye - * kullanıcıya `5,05` olarak gösterilmelidir (`505 / 10 ** 2`). + * @dev Kullanıcı gösterimini elde etmek için kullanılan ondalık sayısını döndürür. + * Örneğin, `decimals` `2`'ye eşitse, `505` jetonluk bir bakiye + * kullanıcıya `5,05` (`505 / 10 ** 2`) olarak gösterilmelidir. * - * Token'lar genellikle ether ve wei arasındaki ilişkiyi taklit ederek - * 18 değerini seçer. Bu, {_setupDecimals} çağrılmadıysa {ERC20} tarafından kullanılan - * değerdir. + * Jetonlar genellikle ether ve wei arasındaki ilişkiyi taklit ederek 18 değerini + * tercih ederler. Bu, {_setupDecimals} çağrılmadığı sürece {ERC20}'nin + * kullandığı değerdir. * - * NOT: Bu bilgi yalnızca _görüntüleme_ amacıyla kullanılır: - * {IERC20-balanceOf} ve {IERC20-transfer} dahil olmak üzere hiçbir şekilde sözleşmenin - * aritmetiğini etkilemez. + * NOT: Bu bilgi yalnızca _gösterim_ amacıyla kullanılır: hiçbir + * şekilde {IERC20-balanceOf} ve {IERC20-transfer} dahil olmak üzere + * sözleşmenin aritmetiğini etkilemez. */ function decimals() public view returns (uint8) { return _decimals; } ``` -Bu fonksiyonlar; `name`, `symbol` ve `decimals`, kullanıcı arayüzlerinin sözleşmeniz hakkında bilgi sahibi olmalarına yardımcı olur, böylece sözleşmenizi düzgün bir şekilde görüntüleyebilirler. +Bu fonksiyonlar, `name`, `symbol` ve `decimals`, kullanıcı arayüzlerinin sözleşmeniz hakkında bilgi sahibi olmalarına yardımcı olur, böylece sözleşmenizi düzgün bir şekilde görüntüleyebilirler. Dönüş türü `string memory`'dir, yani bellekte depolanan bir dize döndürür. Dizeler gibi değişkenler üç konumda saklanabilir: -| | Geçerlilik Süresi | Sözleşme Erişimi | Gaz Bedeli | -| ------------ | ----------------- | ---------------- | ------------------------------------------------------------------------------------------- | -| Bellek | Fonksiyon çağrısı | Okunur/Yazılır | Onlarca veya yüzlerce (daha yüksek konumlar için daha yüksek) | -| Çağrı Verisi | Fonksiyon çağrısı | Salt Okunur | Dönüş türü olarak kullanılamaz, yalnızca bir fonksiyon parametre türü olarak kullanılabilir | -| Depolama | Değişene kadar | Okunur/Yazılır | Yüksek (Okuma için 800, yazma için 20 bin) | +| | Geçerlilik Süresi | Sözleşme Erişimi | Gaz Bedeli | +| -------- | ----------------- | ---------------- | ------------------------------------------------------------------------------------------- | +| Bellek | Fonksiyon çağrısı | Okunur/Yazılır | Onlarca veya yüzlerce (daha yüksek konumlar için daha yüksek) | +| Calldata | Fonksiyon çağrısı | Salt Okunur | Dönüş türü olarak kullanılamaz, yalnızca bir fonksiyon parametre türü olarak kullanılabilir | +| Depolama | Değişene kadar | Okunur/Yazılır | Yüksek (Okuma için 800, yazma için 20 bin) | -Bu durumda, `memory` en iyi seçenektir. +Bu durumda `memory` en iyi seçenektir. -### Token Bilgisini Okuyun {#read-token-information} +### Jeton Bilgilerini Oku {#read-token-information} -Bunlar, toplam arz veya bir hesabın bakiyesi gibi token hakkında bilgi sağlayan fonksiyonlardır. +Bunlar, toplam arz veya bir hesabın bakiyesi gibi jeton hakkında bilgi sağlayan fonksiyonlardır. ```solidity /** - * @dev See {IERC20-totalSupply}. + * @dev Bkz. {IERC20-totalSupply}. */ function totalSupply() public view override returns (uint256) { return _totalSupply; } ``` -`totalSupply` fonksiyonu, toplam token arzını döndürür. +`totalSupply` fonksiyonu, toplam jeton arzını döndürür.   ```solidity /** - * @dev See {IERC20-balanceOf}. + * @dev Bkz. {IERC20-balanceOf}. */ function balanceOf(address account) public view override returns (uint256) { return _balances[account]; } ``` -Bir hesabın bakiyesini okuyun. Herkesin başka birinin hesap bakiyesini almasına izin verildiğini unutmayın. Zaten her düğümde mevcut olduğu için bu bilgiyi saklamaya çalışmanın bir anlamı yoktur. _Blok zincirinde sır yoktur._ +Bir hesabın bakiyesini okuyun. Herkesin başka birinin hesap bakiyesini almasına izin verildiğini unutmayın. Zaten her düğümde mevcut olduğu için bu bilgiyi saklamaya çalışmanın bir anlamı yoktur. _Blokzincirinde sır yoktur._ -### Token Transfer Edin {#transfer-tokens} +### Jetonları Aktar {#transfer-tokens} ```solidity /** - * @dev See {IERC20-transfer}. + * @dev Bkz. {IERC20-transfer}. * - * Gereksinimler: + * Gereklilikler: * - * - `recipient` sıfır adresi olamaz. - * - arayan kişinin en az `amount bakiyesi olmalıdır. + * - `recipient` sıfır adres olamaz. + * - arayan en az `amount` bakiyeye sahip olmalıdır. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { ``` -`transfer` fonksiyonu, token'ları gönderenin hesabından farklı bir hesaba aktarmak için çağrılır. Bir boolean değeri döndürmesine rağmen, bu değerin her zaman **true** olduğunu unutmayın. Transfer başarısız olursa, sözleşme çağrıyı geri alır. +`transfer` fonksiyonu, jetonları gönderenin hesabından farklı bir hesaba aktarmak için çağrılır. Bir boole değeri döndürmesine rağmen, bu değerin **her zaman doğru** olduğunu unutmayın. Aktarım başarısız olursa sözleşme çağrıyı geri alır.   @@ -424,19 +432,19 @@ Bir hesabın bakiyesini okuyun. Herkesin başka birinin hesap bakiyesini alması } ``` -`_transfer` fonksiyonu asıl işi yapar. Yalnızca diğer sözleşme fonksiyonları tarafından çağrılabilen özel bir fonksiyondur. Konvansiyonel olarak özel fonksiyonlar, durum değişkenleriyle aynı şekilde `_` olarak adlandırılır. +`_transfer` fonksiyonu asıl işi yapar. Yalnızca diğer sözleşme fonksiyonları tarafından çağrılabilen özel bir fonksiyondur. Kural olarak özel fonksiyonlar, durum değişkenleriyle aynı şekilde `_` olarak adlandırılır. -Normalde Solidity'de mesajı gönderen için `msg.sender` kullanırız. Ancak bu, [OpenGSN](http://opengsn.org/)'i bozar. Eğer token'ımızla ether'sız işlemlere izin vermek istiyorsak, `_msgSender()` kullanmalıyız. Normal işlemler için `msg.sender` döndürür, ancak ether'sız işlemler için mesajı ileten sözleşmeyi değil, orijinal imzalayanı döndürür. +Normalde Solidity'de mesajı gönderen için `msg.sender` kullanırız. Ancak bu, [OpenGSN](http://opengsn.org/)'yi bozar. Jetonumuzla ether'sız işlemlere izin vermek istiyorsak, `_msgSender()` kullanmalıyız. Normal işlemler için `msg.sender` döndürür, ancak ether'sız işlemler için mesajı ileten sözleşmeyi değil, orijinal imzalayanı döndürür. ### Ödenek Fonksiyonları {#allowance-functions} -Bunlar, ödenek fonksiyonlarını uygulayan fonksiyonlardır: `allowance`, `approve`, `transferFrom`, ve `_approve`. Ek olarak OpenZeppelin uygulaması, güvenliği artıran bazı özellikleri içerecek şekilde temel standardın ötesine geçer: `increaseAllowance` ve `decreaseAllowance`. +Bunlar, ödenek işlevselliğini uygulayan fonksiyonlardır: `allowance`, `approve`, `transferFrom` ve `_approve`. Ek olarak, OpenZeppelin uygulaması, güvenliği artıran bazı özellikleri içerecek şekilde temel standardın ötesine geçer: `increaseAllowance` ve `decreaseAllowance`. #### Ödenek fonksiyonu {#allowance} ```solidity /** - * @dev See {IERC20-allowance}. + * @dev Bkz. {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; @@ -445,15 +453,15 @@ Bunlar, ödenek fonksiyonlarını uygulayan fonksiyonlardır: `allowance`, `appr `allowance` fonksiyonu herkesin herhangi bir ödeneği kontrol etmesini sağlar. -#### Onaylama fonksiyonu {#approve} +#### approve fonksiyonu {#approve} ```solidity /** - * @dev See {IERC20-approve}. + * @dev Bkz. {IERC20-approve}. + * + * Gereklilikler: * - * Gereksinimler: - * - * - `spender` sıfır adresi olamaz. + * - `spender` sıfır adres olamaz. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { ``` @@ -471,7 +479,7 @@ Bu işlev, bir ödenek oluşturmak için çağrılır. Yukarıdaki `transfer` fo } ``` -Durum değişikliklerinin meydana geldiği yerlerin sayısını en aza indirmek için dahili fonksiyonları kullanıyoruz. _Durumu_ değiştiren herhangi bir fonksiyon, güvenlik için denetlenmesi gereken potansiyel bir güvenlik riskidir. Bu şekilde daha az hata yapma ihtimalimiz olur. +Durum değişikliklerinin meydana geldiği yerlerin sayısını en aza indirmek için dahili fonksiyonları kullanıyoruz. Durumu değiştiren _herhangi bir_ fonksiyon, güvenlik için denetlenmesi gereken potansiyel bir güvenlik riskidir. Bu şekilde daha az hata yapma ihtimalimiz olur. #### transferFrom fonksiyonu {#transferFrom} @@ -479,17 +487,17 @@ Bu, bir harcama yapanın bir ödenek harcamak için çağırdığı fonksiyondur ```solidity /** - * @dev See {IERC20-transferFrom}. + * @dev Bkz. {IERC20-transferFrom}. * - * Güncellenmiş ödeneği gösteren bir {Approval} olayı yayar. Bu - * EIP için gerekmez. {ERC20} başlangıcındaki nota bakınız. + * Güncellenmiş ödeneği gösteren bir {Approval} olayı yayar. Bu, + * EIP tarafından gerekli değildir. {ERC20}'nin başındaki nota bakın. * - * Gereksinimler: + * Gereklilikler: * - * - `sender` ve `recipient` sıfır adresi olamaz. - * - `sender` en az `amount` miktarda bakiyeye sahip olmalıdır. - * - çağıranın ``sender`` token'ları için en az `amount` - * ödeneği olmalıdır. + * - `sender` ve `recipient` sıfır adres olamaz. + * - `sender` en az `amount` bakiyeye sahip olmalıdır. + * - arayan, ``sender``ın jetonları için en az + * `amount` kadar ödeneğe sahip olmalıdır. */ function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { @@ -498,7 +506,8 @@ Bu, bir harcama yapanın bir ödenek harcamak için çağırdığı fonksiyondur   -`a.sub(b, "message")` fonksiyon çağrısı iki şey yapar. İlk olarak, yeni ödenek olan `a-b` hesabını yapar. İkincisi, bu sonucun negatif olmadığını kontrol eder. Negatifse, verilen mesajla çağrı geri döner. Bir çağrı geri döndüğünde, o arama sırasında daha önce yapılmış herhangi bir işlemin yok sayıldığını ve bu nedenle `_transfer` işlemini geri almamız gerekmediğini unutmayın. +`a.sub(b, "message")` fonksiyon çağrısı iki şey yapar. İlk olarak, yeni ödenek olan `a-b` hesabını yapar. +İkincisi, bu sonucun negatif olmadığını kontrol eder. Negatifse, verilen mesajla çağrı geri döner. Bir çağrı geri döndüğünde, o çağrı sırasında daha önce yapılmış herhangi bir işlemin yok sayıldığını ve bu nedenle `_transfer` işlemini geri almamız gerekmediğini unutmayın. ```solidity _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, @@ -509,48 +518,48 @@ Bu, bir harcama yapanın bir ödenek harcamak için çağırdığı fonksiyondur #### OpenZeppelin güvenlik eklemeleri {#openzeppelin-safety-additions} -Sıfırdan farklı başka bir değere sıfırdan farklı bir ödenek ayarlamak tehlikelidir, çünkü başkalarının değil, yalnızca kendi işlemlerinizin sırasını siz kontrol edersiniz. Saf olan Alice ve dürüst olmayan Bill olmak üzere iki kullanıcınız olduğunu hayal edin. Alice, Bill'den beş token'a mal olduğunu düşündüğü bir hizmet istiyor, bu yüzden Bill'e beş token'lık bir ödenek veriyor. +Sıfırdan farklı bir ödeneği başka bir sıfırdan farklı değere ayarlamak tehlikelidir çünkü yalnızca kendi işlemlerinizin sırasını kontrol edersiniz, başkalarınınkini değil. Saf olan Alice ve dürüst olmayan Bill olmak üzere iki kullanıcınız olduğunu hayal edin. Alice, Bill'den beş jetona mal olduğunu düşündüğü bir hizmet istiyor, bu yüzden Bill'e beş jetonluk bir ödenek veriyor. -Sonra bir şeyler değişir ve Bill'in fiyatı on token'a yükselir. Hâlâ hizmeti isteyen Alice, Bill'in ödeneğini 10'a ayarlayan bir işlem gönderir. Bill, işlem havuzunda bu yeni işlemi gördüğü anda, Alice'in beş token'ını harcayan ve çok daha yüksek bir gaz fiyatına sahip olan bir işlem gönderir, böylece işlem daha hızlı kazılır. Bu şekilde Bill, ilk beş token'ı harcayabilir ve ardından, Alice'in yeni ödeneği çıkarıldığında, on beş token'lık toplam fiyat için, Alice'in yetkilendirmek istediğinden daha fazla olacak şekilde on tane daha harcayabilir. Bu tekniğe [front-running](https://consensysdiligence.github.io/smart-contract-best-practices/attacks/#front-running) denir +Sonra bir şeyler değişir ve Bill'in fiyatı on jetona yükselir. Hâlâ hizmeti isteyen Alice, Bill'in ödeneğini ona ayarlayan bir işlem gönderir. Bill, işlem havuzunda bu yeni işlemi gördüğü anda, Alice'in beş jetonunu harcayan ve çok daha yüksek bir gaz fiyatına sahip olan bir işlem gönderir, böylece işlem daha hızlı kazılır. Bu şekilde Bill, ilk beş jetonu harcayabilir ve ardından, Alice'in yeni ödeneği çıkarıldığında, on beş jetonluk toplam fiyat için, Alice'in yetkilendirmek istediğinden daha fazla olacak şekilde on tane daha harcayabilir. Bu tekniğe [önden çalıştırma](https://consensysdiligence.github.io/smart-contract-best-practices/attacks/#front-running) denir -| Alice'in İşlemi | Alice'in Nonce Değeri | Bill'in İşlemi | Bill'in Nonce Değeri | Bill'in Ödeneği | Bill'in Alice'den Toplam Geliri | -| ----------------- | --------------------- | ----------------------------- | -------------------- | --------------- | ------------------------------- | -| approve(Bill, 5) | 10 | | | 5 | 0 | -| | | transferFrom(Alice, Bill, 5) | 10,123 | 0 | 5 | -| approve(Bill, 10) | 11 | | | 10 | 5 | -| | | transferFrom(Alice, Bill, 10) | 10,124 | 0 | 15 | +| Alice'in İşlemi | Alice Nonce | Bill'in İşlemi | Bill Nonce | Bill'in Ödeneği | Bill'in Alice'ten Toplam Geliri | +| ------------------------------------ | ----------- | ------------------------------------------------ | ---------------------- | --------------- | ------------------------------- | +| approve(Bill, 5) | 10 | | | 5 | 0 | +| | | transferFrom(Alice, Bill, 5) | 10.123 | 0 | 5 | +| approve(Bill, 10) | 11 | | | 10 | 5 | +| | | transferFrom(Alice, Bill, 10) | 10.124 | 0 | 15 | -Bu sorunu önlemek için, bu iki fonksiyon (`increaseAllowance` ve `decreaseAllowance`), ödeneği belirli bir miktarda değiştirmenize olanak tanır. Yani Bill zaten beş token harcamışsa, sadece beş tane daha harcayabilecektir. Zamanlamaya bağlı olarak, bunun iki sonucu olabilir ve her ikisinde de Bill yalnızca on token alabilir: +Bu sorunu önlemek için, bu iki fonksiyon (`increaseAllowance` ve `decreaseAllowance`), ödeneği belirli bir miktarda değiştirmenize olanak tanır. Yani Bill zaten beş jeton harcamışsa, sadece beş tane daha harcayabilecektir. Zamanlamaya bağlı olarak, bunun iki sonucu olabilir ve her ikisinde de Bill yalnızca on jeton alabilir: A: -| Alice'in İşlemi | Alice'in Nonce Değeri | Bill'in İşlemi | Bill'in Nonce Değeri | Bill'in Ödeneği | Bill'in Alice'den Toplam Geliri | -| -------------------------- | --------------------: | ---------------------------- | -------------------: | --------------: | ------------------------------- | -| approve(Bill, 5) | 10 | | | 5 | 0 | -| | | transferFrom(Alice, Bill, 5) | 10,123 | 0 | 5 | -| increaseAllowance(Bill, 5) | 11 | | | 0+5 = 5 | 5 | -| | | transferFrom(Alice, Bill, 5) | 10,124 | 0 | 10 | +| Alice'in İşlemi | Alice Nonce | Bill'in İşlemi | Bill Nonce | Bill'in Ödeneği | Bill'in Alice'ten Toplam Geliri | +| --------------------------------------------- | ----------: | ----------------------------------------------- | ---------------------: | --------------: | ------------------------------- | +| approve(Bill, 5) | 10 | | | 5 | 0 | +| | | transferFrom(Alice, Bill, 5) | 10.123 | 0 | 5 | +| increaseAllowance(Bill, 5) | 11 | | | 0+5 = 5 | 5 | +| | | transferFrom(Alice, Bill, 5) | 10.124 | 0 | 10 | B: -| Alice'in İşlemi | Alice'in Nonce Değeri | Bill'in İşlemi | Bill'in Nonce Değeri | Bill'in Ödeneği | Bill'in Alice'den Toplam Geliri | -| -------------------------- | --------------------: | ----------------------------- | -------------------: | --------------: | ------------------------------: | -| approve(Bill, 5) | 10 | | | 5 | 0 | -| increaseAllowance(Bill, 5) | 11 | | | 5+5 = 10 | 0 | -| | | transferFrom(Alice, Bill, 10) | 10,124 | 0 | 10 | +| Alice'in İşlemi | Alice Nonce | Bill'in İşlemi | Bill Nonce | Bill'in Ödeneği | Bill'in Alice'ten Toplam Geliri | +| --------------------------------------------- | ----------: | ------------------------------------------------ | ---------------------: | --------------: | ------------------------------: | +| approve(Bill, 5) | 10 | | | 5 | 0 | +| increaseAllowance(Bill, 5) | 11 | | | 5+5 = 10 | 0 | +| | | transferFrom(Alice, Bill, 10) | 10.124 | 0 | 10 | ```solidity /** - * @dev Çağıran tarafından `spender` için sağlanan ödeneği atomik derecede artırır. + * @dev Arayan tarafından `spender`'a verilen ödeneği atomik olarak artırır. + * + * Bu, {IERC20-approve}'da açıklanan sorunlar için bir azaltma olarak kullanılabilecek + * {approve}'a bir alternatiftir. * - * Bu, {IERC20-approve} bölümünde açıklanan sorunlar için hafifletme olarak kullanılabilecek - * {approve} seçeneğine bir alternatiftir. + * Güncellenmiş ödeneği belirten bir {Approval} olayı yayar. * - * Güncellenmiş ödeneği gösteren bir {Approval} olayı yayar. + * Gereklilikler: * - * Gereksinimler: - * - * - `spender` sıfır adresi olamaz. + * - `spender` sıfır adres olamaz. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); @@ -558,23 +567,23 @@ B: } ``` -`a.add(b)` fonksiyonu güvenli bir toplamadır. `a`+`b`>=`2^256` olan ihtimali düşük durumda, normal toplamanın yaptığı gibi başa dönmez. +`a.add(b)` fonksiyonu güvenli bir toplamadır. `a`+`b`>=`2^256` olması gibi düşük bir ihtimalde, normal toplamanın yaptığı gibi başa dönmez. ```solidity /** - * @dev Çağıran tarafından `spender` için sağlanan ödeneği atomik derecede azaltır. + * @dev Arayan tarafından `spender`'a verilen ödeneği atomik olarak azaltır. * - * Bu, {IERC20-approve} bölümünde açıklanan sorunlar için hafifletme olarak kullanılabilecek - * {approve} seçeneğine bir alternatiftir. + * Bu, {IERC20-approve}'da açıklanan sorunlar için bir azaltma olarak kullanılabilecek + * {approve}'a bir alternatiftir. * - * Güncellenmiş ödeneği gösteren bir {Approval} olayı yayar. + * Güncellenmiş ödeneği belirten bir {Approval} olayı yayar. * - * Gereksinimler: - * - * - `spender` sıfır adresi olamaz. - * - `spender` çağıran için en az `subtractedValue` kadar - * ödeneğe sahip olmalı. + * Gereklilikler: + * + * - `spender` sıfır adres olamaz. + * - `spender`'ın arayan için en az + * `subtractedValue` kadar ödeneği olmalıdır. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, @@ -583,31 +592,31 @@ B: } ``` -### Token Bilgilerini Değiştiren Fonksiyonlar {#functions-that-modify-token-information} +### Jeton Bilgilerini Değiştiren Fonksiyonlar {#functions-that-modify-token-information} Bunlar asıl işi yapan dört fonksiyondur: `_transfer`, `_mint`, `_burn` ve `_approve`. -#### \_transfer fonksiyonu {#_transfer} +#### _transfer fonksiyonu {#_transfer} ```solidity /** - * @dev `amount` token'ı `sender`'dan `recipient`'a hareket ettirir. - * - * Bu dahili fonksiyon {transfer} ile eş değerdir ve şu amaçlarla kullanılabilir: - * örn. otomatik token ücretlerini, kesme mekanizmalarını vb. uygulama. - * - * Bir {Transfer} olayı yayar. - * - * Gereksinimler: - * - * - `sender` sıfır adresi olamaz. - * - `recipient` sıfır adresi olamaz. - * - `sender` en az `amount` miktarda bakiyeye sahip olmalıdır. + * @dev `sender`'dan `recipient`'a `amount` kadar jeton taşır. + * + * Bu dahili fonksiyon {transfer}'a eşdeğerdir ve örneğin + * otomatik jeton ücretlerini, kesme mekanizmalarını vb. uygulamak için kullanılabilir. + * + * Bir {Transfer} olayı yayar. + * + * Gereklilikler: + * + * - `sender` sıfır adres olamaz. + * - `recipient` sıfır adres olamaz. + * - `sender` en az `amount` bakiyeye sahip olmalıdır. */ function _transfer(address sender, address recipient, uint256 amount) internal virtual { ``` -Bu fonksiyon, `_transfer`, token'ları bir hesaptan diğerine aktarır. Hem `transfer` (gönderenin kendi hesabından yapılan transferler için) hem de `transferFrom` (başka birinin hesabından transfer için izinleri kullanmak için) tarafından çağrılır. +Bu fonksiyon, `_transfer`, jetonları bir hesaptan diğerine aktarır. Hem `transfer` (gönderenin kendi hesabından yapılan transferler için) hem de `transferFrom` (başka birinin hesabından transfer için ödenekleri kullanmak için) tarafından çağrılır.   @@ -628,11 +637,11 @@ Ethereum'da hiç kimse aslında sıfır adresine sahip değildir (yani, eşleşe Bu sözleşmeyi kullanmanın iki yolu vardır: 1. Kendi kodunuz için bir şablon olarak kullanın -1. [Ondan kalıtım yoluyla alın](https://www.bitdegree.org/learn/solidity-inheritance) ve yalnızca değiştirmeniz gereken fonksiyonları geçersiz kılın +2. [Ondan kalıtım alın](https://www.bitdegree.org/learn/solidity-inheritance) ve yalnızca değiştirmeniz gereken fonksiyonları geçersiz kılın İkinci yöntem çok daha iyidir çünkü OpenZeppelin ERC-20 kodu zaten denetlenmiş ve güvenli olduğu gösterilmiştir. Kalıtım kullandığınızda, değiştirdiğiniz fonksiyonların ne olduğu açıktır ve sözleşmenize güvenmek için kişilerin yalnızca bu belirli fonksiyonları denetlemesi gerekir. -Token'lar her el değiştirdiğinde bir fonksiyon gerçekleştirmek genellikle yararlıdır. Ancak,`_transfer` çok önemli bir fonksiyondur ve güvenli olmayan bir şekilde yazmak mümkündür (aşağıya bakın), bu nedenle geçersiz kılmamak en iyisidir. Çözüm, bir [kanca fonksiyonu](https://wikipedia.org/wiki/Hooking) olan `_beforeTokenTransfer` fonksiyonudur. Bu fonksiyonu geçersiz kılabilirsiniz ve her aktarımda çağrılacaktır. +Jetonlar her el değiştirdiğinde bir fonksiyon gerçekleştirmek genellikle yararlıdır. Ancak,`_transfer` çok önemli bir fonksiyondur ve güvensiz bir şekilde yazılması mümkündür (aşağıya bakın), bu nedenle onu geçersiz kılmamak en iyisidir. Çözüm, bir [kanca fonksiyonu](https://wikipedia.org/wiki/Hooking) olan `_beforeTokenTransfer`'dır. Bu fonksiyonu geçersiz kılabilirsiniz ve her aktarımda çağrılacaktır.   @@ -641,7 +650,7 @@ Token'lar her el değiştirdiğinde bir fonksiyon gerçekleştirmek genellikle y _balances[recipient] = _balances[recipient].add(amount); ``` -Bunlar aslında aktarımı yapan hatlardır. Aralarında **hiçbir şey** olmadığını ve aktarılan tutarı alıcıya eklemeden önce göndericiden çıkardığımızı unutmayın. Bu, ortada farklı bir sözleşmeye çağrı olsaydı, bu sözleşmeyi aldatmak için kullanılmış olabileceği için önemlidir. Bu şekilde aktarım atomiktir, ortasında hiçbir şey olamaz. +Bunlar aslında aktarımı yapan satırlardır. Aralarında **hiçbir şey** olmadığını ve aktarılan tutarı alıcıya eklemeden önce göndericiden çıkardığımızı unutmayın. Bu önemlidir çünkü ortada farklı bir sözleşmeye çağrı olsaydı, bu sözleşmeyi aldatmak için kullanılabilirdi. Bu şekilde aktarım atomiktir, ortasında hiçbir şey olamaz.   @@ -650,23 +659,25 @@ Bunlar aslında aktarımı yapan hatlardır. Aralarında **hiçbir şey** olmad } ``` -Son olarak, bir `Transfer` olayı yayın. Olaylara akıllı sözleşmelerle erişilemez, ancak blok zincirinin dışında çalışan kod, olayları dinleyebilir ve bunlara tepki verebilir. Örneğin bir cüzdan, sahibinin ne zaman daha fazla token aldığını takip edebilir. +Son olarak, bir `Transfer` olayı yayınlayın. Olaylara akıllı sözleşmelerle erişilemez, ancak blokzincirinin dışında çalışan kod, olayları dinleyebilir ve bunlara tepki verebilir. Örneğin bir cüzdan, sahibinin ne zaman daha fazla jeton aldığını takip edebilir. -#### \_mint ve \_burn fonksiyonları {#_mint-and-_burn} +#### _mint ve _burn fonksiyonları {#_mint-and-_burn} -Bu iki fonksiyon (`_mint` and `_burn`) toplam token arzını düzenler. Bunlar dahilidir ve bu sözleşmede onları çağıran bir fonksiyon yoktur, bu nedenle yalnızca sözleşmeden devralırsanız ve hangi koşullar altında yeni token'lar basacağınıza veya mevcut token'ları yakacağınıza karar vermek için kendi mantığınızı eklerseniz kullanışlıdırlar. +Bu iki fonksiyon (`_mint` ve `_burn`), toplam jeton arzını değiştirir. +Bunlar dahili fonksiyonlardır ve bu sözleşmede onları çağıran bir fonksiyon yoktur, bu nedenle yalnızca sözleşmeden kalıtım alırsanız ve hangi koşullar altında yeni jetonlar basacağınıza veya mevcut olanları yakacağınıza karar vermek için kendi mantığınızı eklerseniz kullanışlıdırlar. -**NOT:** Her ERC-20 token'ının, token yönetimini belirleyen kendi çalışma mantığı vardır. Örneğin, sabit bir arz sözleşmesi, yapıcıda yalnızca `_mint` öğesini çağırabilir ve hiçbir zaman `_burn` öğesini çağıramaz. Token satan bir sözleşme, ödeme yapıldığında `_mint`'i ve kaçak enflasyonu önlemek için bir noktada muhtemelen `_burn`'u arayacaktır. +**NOT:** Her ERC-20 jetonunun, jeton yönetimini belirleyen kendi iş mantığı vardır. +Örneğin, sabit arza sahip bir sözleşme oluşturucusunda yalnızca `_mint`'i çağırabilir ve `_burn`'ü asla çağırmayabilir. Jeton satan bir sözleşme, ödeme yapıldığında `_mint`'i çağırır ve muhtemelen bir noktada enflasyonun kontrolden çıkmasını önlemek için `_burn`'ü çağırır. ```solidity - /** @dev `amount` token yaratır ve onları `account`'a atarak toplam arzı - * artırır. + /** @dev `amount` kadar jeton oluşturur ve bunları `account`a atayarak + * toplam arzı artırır. * - * `from` sıfır adresine ayarlı olacak şekilde bir {Transfer} olayı yayar. + * `from` sıfır adrese ayarlanmış bir {Transfer} olayı yayar. * - * Gereksinimler: + * Gereklilikler: * - * - `to` sıfır adresi olamaz. + * - `to` sıfır adres olamaz. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); @@ -677,21 +688,21 @@ Bu iki fonksiyon (`_mint` and `_burn`) toplam token arzını düzenler. Bunlar d } ``` -Toplam token sayısı değiştiğinde `_totalSupply`'ı güncellediğinizden emin olun. +Toplam jeton sayısı değiştiğinde `_totalSupply`'ı güncellediğinizden emin olun.   -``` +```solidity /** - * @dev `amount` token'ı `account`'tan yok ederek toplam arzı - * azaltır. + * @dev `account`tan `amount` kadar jetonu yok ederek toplam + * arzı azaltır. * - * `to` sıfır adresine ayarlı olacak şekilde bir {Transfer} olayı yayar. + * `to` sıfır adrese ayarlanmış bir {Transfer} olayı yayar. * - * Gereksinimler: + * Gereklilikler: * - * - `account` sıfır adresi olamaz. - * - `account` en az `amount` miktarda token'a sahip olmalı. + * - `account` sıfır adres olamaz. + * - `account` en az `amount` kadar jetona sahip olmalıdır. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); @@ -704,25 +715,25 @@ Toplam token sayısı değiştiğinde `_totalSupply`'ı güncellediğinizden emi } ``` -`_burn` fonksiyonu, diğer yöne gitmesi dışında `_mint` ile hemen hemen aynıdır. +`_burn` fonksiyonu, ters yönde çalışması dışında `_mint` ile neredeyse aynıdır. -#### \_approve fonksiyonu {#_approve} +#### _approve fonksiyonu {#_approve} -Bu aslında ödenekleri belirten fonksiyondur. Sahibin, kendi mevcut bakiyesinden daha yüksek bir ödenek belirlemesine izin verdiğini unutmayın. Bakiye, ödenek oluşturulduğundaki bakiyeden farklı olabileceği transfer sırasında kontrol edildiği için bu sorun yaratmaz. +Bu, ödenekleri gerçekten belirten fonksiyondur. Sahibinin, kendi mevcut bakiyesinden daha yüksek bir ödenek belirlemesine izin verdiğini unutmayın. Bu sorun değil çünkü bakiye, ödenek oluşturulduğundaki bakiyeden farklı olabileceği için transfer sırasında kontrol edilir. ```solidity /** - * @dev `owner` token'ları üzerinde `spender` ödeneğini `amount` olarak belirler. + * @dev `owner`ın jetonları üzerinde `spender`ın ödeneği olarak `amount`u ayarlar. * - * Bu dahili işlev `approve` ile eş değerdir ve şu amaçlarla kullanılabilir: - * örn. belirli alt sistemler için otomatik izinler ayarlama vb. - * - * Bir {Approval} olayı yayar. + * Bu dahili fonksiyon `approve`a eşdeğerdir ve örneğin + * belirli alt sistemler için otomatik ödenekler ayarlamak için kullanılabilir. + * + * Bir {Approval} olayı yayar. * - * Gereksinimler: + * Gereklilikler: * - * - `owner` sıfır adresi olamaz. - * - `spender` sıfır adresi olamaz. + * - `owner` sıfır adres olamaz. + * - `spender` sıfır adres olamaz. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); @@ -733,7 +744,7 @@ Bu aslında ödenekleri belirten fonksiyondur. Sahibin, kendi mevcut bakiyesinde   -Bir `Approval` olayı yayın. Uygulamanın nasıl yazıldığına bağlı olarak, harcayan sözleşmenin sahibi tarafından veya bu olayları dinleyen bir sunucu tarafından onaylanması hakkında bilgi verilebilir. +Bir `Approval` olayı yayınlayın. Uygulamanın nasıl yazıldığına bağlı olarak, harcayan sözleşmeye onay hakkında ya sahibi tarafından ya da bu olayları dinleyen bir sunucu tarafından bilgi verilebilir. ```solidity emit Approval(owner, spender, amount); @@ -741,42 +752,43 @@ Bir `Approval` olayı yayın. Uygulamanın nasıl yazıldığına bağlı olarak ``` -### Ondalık Değişkenini Düzenleyin {#modify-the-decimals-variable} +### Ondalık Değişkenini Değiştir {#modify-the-decimals-variable} ```solidity /** - * @dev {decimals} değerini varsayılan olan 18 harici bir değere ayarlar. + * @dev {decimals}'i varsayılan 18 değerinden başka bir değere ayarlar. * - * UYARI: Bu fonksiyon sadece yapıcıdan çağrılmalıdır. Çoğu - * Token sözleşmeleriyle etkileşime giren uygulama, - * {decimals} değerinin değişmesini beklemez ve değişirse yanlış çalışabilir. + * UYARI: Bu fonksiyon yalnızca oluşturucudan çağrılmalıdır. Jeton + * sözleşmeleriyle etkileşimde bulunan çoğu uygulama + * {decimals}'in hiç değişmesini beklemez ve değişirse yanlış çalışabilir. */ function _setupDecimals(uint8 decimals_) internal { _decimals = decimals_; } ``` -Bu fonksiyon, kullanıcı arabirimlerine miktarın nasıl yorumlanacağını söylemek için kullanılan `_decimals` değişkenini değiştirir. Yapıcıdan çağırmalısınız. Daha sonraki herhangi bir noktada onu çağırmak sahtekârlık olur ve uygulamalar bununla başa çıkmak için tasarlanmamıştır. +Bu fonksiyon, kullanıcı arayüzlerine miktarın nasıl yorumlanacağını söylemek için kullanılan `_decimals` değişkenini değiştirir. +Bunu oluşturucudan çağırmalısınız. Daha sonraki herhangi bir noktada onu çağırmak sahtekârlık olur ve uygulamalar bununla başa çıkmak için tasarlanmamıştır. ### Kancalar {#hooks} ```solidity /** - * @dev Herhangi bir token'ın aktarımı öncesi çağrılan kanca. Buna - * basım ve yakım dahildir. - * - * Çağrı koşulları: - * - * - `from` ve `to` sıfır olmadığında, `from`'un token `amount` değeri - * `to`'ya aktarılır. - * - `from` sıfırken, `amount` token `to` için basılır. - * - `to` sıfırken, ``from``'un `amount` kadar token'ı yakılır. - * - `from` ve `to` asla ikisi birden sıfır olmaz. - * - * Kancalar hakkında daha fazla bilgi edinmek için xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks] sayfasına gidin. + * @dev Herhangi bir jeton transferinden önce çağrılan kanca. Bu, + * basmayı ve yakmayı içerir. + * + * Çağırma koşulları: + * + * - `from` ve `to` ikisi de sıfır değilken, ``from``'un jetonlarından `amount` + * kadarı `to`'ya transfer edilir. + * - `from` sıfırken, `to` için `amount` kadar jeton basılır. + * - `to` sıfırken, ``from``'un jetonlarından `amount` kadarı yakılır. + * - `from` ve `to` ikisi de asla sıfır olmaz. + * + * Kancalar hakkında daha fazla bilgi edinmek için şuraya gidin: xref:ROOT:extending-contracts.adoc#using-hooks[Kancaları Kullanma]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } } @@ -786,12 +798,15 @@ Bu, aktarımlar sırasında çağrılacak kanca fonksiyonudur. Bu örnekte kanca ## Sonuç {#conclusion} -İnceleme için, bu sözleşmedeki en önemli fikirlerden bazıları şunlardır (bence sizinki muhtemelen değişebilir): +İnceleme için, bu sözleşmedeki en önemli fikirlerden bazıları şunlardır (bana göre, sizinki farklılık gösterebilir): + +- _Blokzincirde sır yoktur_. Bir akıllı sözleşmenin erişebileceği herhangi bir bilgi tüm dünya tarafından kullanılabilir. +- Kendi işlemlerinizin sırasını kontrol edebilirsiniz, ancak diğer kişilerin işlemlerinin ne zaman gerçekleşeceğini kontrol edemezsiniz. Bu, bir ödeneği değiştirmenin tehlikeli olabilmesinin nedenidir, çünkü harcayanın her iki ödeneğin toplamını harcamasına izin verir. +- `uint256` türündeki değerler başa döner. Başka bir deyişle, _0-1=2^256-1_. Bu istenen davranış değilse, bunu kontrol etmeniz (veya sizin için yapan SafeMath kütüphanesini kullanmanız) gerekir. Bunun [Solidity 0.8.0](https://docs.soliditylang.org/en/breaking/080-breaking-changes.html)'da değiştiğini unutmayın. +- Belirli bir türdeki tüm durum değişikliklerini belirli bir yerde yapın, çünkü bu denetimi kolaylaştırır. + Örneğin, `approve`, `transferFrom`, `increaseAllowance` ve `decreaseAllowance` tarafından çağrılan `_approve` fonksiyonuna sahip olmamızın nedeni budur. +- Durum değişiklikleri, aralarında başka bir eylem olmaksızın atomik olmalıdır (`_transfer`'da görebileceğiniz gibi). Bunun nedeni, durum değişikliği sırasında tutarsız bir duruma sahip olmanızdır. Örneğin, gönderenin bakiyesinden düşüldüğü zaman ile alıcının bakiyesine eklendiği zaman arasında, var olması gerekenden daha az jeton bulunur. Aralarında işlemler, özellikle farklı bir sözleşmeye yapılan çağrılar varsa, bu potansiyel olarak kötüye kullanılabilir. -- _Blok zincirinde sır yoktur._. Akıllı bir sözleşmenin erişebileceği herhangi bir bilgi tüm dünya tarafından kullanılabilir. -- Başkalarının işlemleri gerçekleştiğinde anlar hariç kendi işlemlerinizin sırasını kontrol edebilirsiniz. Bu, bir ödeneği değiştirmenin tehlikeli olabilmesinin nedenidir, çünkü harcama yapanın her iki ödeneğin toplamını harcamasına izin verir. -- `uint256` türünde değerler döner. Başka bir deyişle, _0-1=2^256-1_. Bu istenen davranış değilse, kontrol etmeniz (veya sizin için yapan SafeMath kütüphanesini kullanmanız) gerekir. Bunun [Solidity 0.8.0](https://docs.soliditylang.org/en/breaking/080-breaking-changes.html) sürümünde değiştiğini unutmayın. -- Denetimi kolaylaştırdığından, belirli bir türdeki tüm durum değişikliklerini belirli bir yerde yapın. Bu, örnek olarak `approve`, `transferFrom`, `increaseAllowance` ve `decreaseAllowance` tarafından çağrılan `_approve` fonksiyonuna sahip olmamızın sebebidir -- Durum değişiklikleri, aralarında başka bir işlem olmaksızın atomik olmalıdır (`_transfer`'da görebileceğiniz gibi). Bunun nedeni, durum değişikliği sırasında tutarsız bir duruma sahip olmanızdır. Örneğin, gönderenin bakiyesinden düştüğünüz süre ile alıcının bakiyesine eklediğiniz zaman arasında olması gerekenden daha az token vardır. Aralarında işlemler, özellikle farklı bir sözleşmeye yapılan çağrılar varsa, bu potansiyel olarak kötüye kullanılabilir. +Artık OpenZeppelin ERC-20 sözleşmesinin nasıl yazıldığını ve özellikle nasıl daha güvenli hâle getirildiğini gördüğünüze göre, gidin ve kendi güvenli sözleşmelerinizi ve uygulamalarınızı yazın. -Artık OpenZeppelin ERC-20 sözleşmesinin nasıl yazıldığını ve özellikle nasıl daha güvenli hâle getirildiğini gördünüz, kendi güvenli sözleşmelerinizi ve uygulamalarınızı yazabilirsiniz. +[Çalışmalarımdan daha fazlası için buraya bakın](https://cryptodocguy.pro/). diff --git a/public/content/translations/tr/developers/tutorials/erc20-with-safety-rails/index.md b/public/content/translations/tr/developers/tutorials/erc20-with-safety-rails/index.md index 3adb8d3bd34..ab990cbbd3c 100644 --- a/public/content/translations/tr/developers/tutorials/erc20-with-safety-rails/index.md +++ b/public/content/translations/tr/developers/tutorials/erc20-with-safety-rails/index.md @@ -1,32 +1,32 @@ --- -title: ERC-20 ve Güvenlik Önlemleri -description: İnsanların aptalca hatalar yapmasını önleme +title: "Güvenlik Önlemli ERC-20" +description: "İnsanların Basit Hatalardan Kaçınmasına Yardımcı Olmak" author: Ori Pomerantz lang: tr -tags: - - "erc-20" +tags: [ "erc-20" ] skill: beginner published: 2022-08-15 --- ## Giriş {#introduction} -Ethereum ile ilgili en güzel şeylerden biri, işlemlerinizi değiştirebilecek veya geri alabilecek merkezi herhangi bir otoritenin olmamasıdır. Ethereum ile ilgili en büyük sorunlardan biri, kullanıcı hatalarını veya yasa dışı işlemleri geri alma yetkisine sahip merkezi bir otoritenin olmamasıdır. Bu makalede, kullanıcıların [ERC-20](/developers/docs/standards/tokens/erc-20/) jetonlarıyla yaptıkları bazı yaygın hataların yanı sıra; kullanıcıların bu hatalardan kaçınmasına yardımcı olan veya merkezi bir otoriteye bir miktar yetki veren (örneğin hesapları dondurmak için) ERC-20 sözleşmelerinin nasıl oluşturulacağını öğreneceksiniz. +Ethereum ile ilgili en güzel şeylerden biri, işlemlerinizi değiştirebilecek veya geri alabilecek merkezi herhangi bir otoritenin olmamasıdır. Ethereum ile ilgili en büyük sorunlardan biri, kullanıcı hatalarını veya yasa dışı işlemleri geri alma yetkisine sahip merkezi bir otoritenin olmamasıdır. Bu makalede, kullanıcıların [ERC-20](/developers/docs/standards/tokens/erc-20/) jetonlarıyla yaptıkları yaygın hatalardan bazılarını ve kullanıcıların bu hatalardan kaçınmasına yardımcı olan veya merkezi bir otoriteye bir miktar yetki (örneğin hesapları dondurmak için) veren ERC-20 sözleşmelerinin nasıl oluşturulacağını öğreneceksiniz. -[Open Zeppelin ERC-20 jeton sözleşmesini](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC20) hala kullanıyor olsak da bu makalenin bunu ayrıntılı olarak açıklamadığını söylemiş olalım. Bu bilgiyi [burada bulabilirsiniz](/developers/tutorials/erc20-annotated-code). +Bu makalede [OpenZeppelin ERC-20 jeton sözleşmesini](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC20) kullanacak olsak da, sözleşmenin bu makalede ayrıntılı olarak açıklanmadığını unutmayın. Bu bilgiyi [burada](/developers/tutorials/erc20-annotated-code) bulabilirsiniz. Bütün kaynak kodunu görmek isterseniz: 1. [Remix IDE](https://remix.ethereum.org/)'yi açın. -2. Github'ı klonla simgesine tıklayın (![clone github icon](icon-clone.png)). -3. Github deposunu kopyalayın `https://github.com/qbzzt/20220815-erc20-safety-rails`. -4. **Sözleşmeler > erc20-safety-rails.sol** öğesini açın. +2. Github klonlama simgesine tıklayın (![github klonlama simgesi](icon-clone.png)). +3. `https://github.com/qbzzt/20220815-erc20-safety-rails` github deposunu klonlayın. +4. **contracts > erc20-safety-rails.sol** dosyasını açın. -## ERC-20 sözleşmesi oluşturma {#creating-an-erc-20-contract} +## Bir ERC-20 sözleşmesi oluşturma {#creating-an-erc-20-contract} -Güvenlik önlemi işlevini eklemeden önce bize bir ERC-20 sözleşmesi lazım. Bu makalede [OpenZeppelin'in Sözleşme Sihirbazı'nı](https://docs.openzeppelin.com/contracts/5.x/wizard) kullanacağız. Başka bir sekmede açın ve şu yönergeleri izleyin: +Güvenlik önlemi işlevselliğini eklemeden önce bir ERC-20 sözleşmesine ihtiyacımız var. Bu makalede [OpenZeppelin Sözleşme Sihirbazı'nı](https://docs.openzeppelin.com/contracts/5.x/wizard) kullanacağız. Başka bir tarayıcıda açın ve şu talimatları izleyin: 1. **ERC20**'yi seçin. + 2. Bu ayarları girin: | Parametre | Değer | @@ -39,26 +39,26 @@ Güvenlik önlemi işlevini eklemeden önce bize bir ERC-20 sözleşmesi lazım. | Yükseltilebilirlik | Hiçbiri | 3. Yukarı kaydırın ve farklı bir ortam kullanmak için **Remix'te Aç**'a (Remix için) veya **İndir**'e tıklayın. Remix kullandığınızı varsayacağım, başka bir şey kullanıyorsanız sadece uygun değişiklikleri yapın. -4. Şimdi tamamen işlevsel bir ERC-20 sözleşmemiz var. İçeri aktarılan kodu görmek için `.deps` > `npm`'yi genişletebilirsiniz. -5. Bir ERC-20 sözleşmesi olarak işlev gördüğünü anlamak için sözleşmeyi derleyin, dağıtın ve sözleşmeyle oynayın. Remix'in nasıl kullanıldığını öğrenmek istiyorsanız [bu rehberi kullanın](https://remix.ethereum.org/?#activate=udapp,solidity,LearnEth). + +4. Artık tamamen işlevsel bir ERC-20 sözleşmemiz var. İçe aktarılan kodu görmek için `.deps` > `npm` yolunu genişletebilirsiniz. + +5. Bir ERC-20 sözleşmesi olarak işlev gördüğünü anlamak için sözleşmeyi derleyin, dağıtın ve sözleşmeyle oynayın. Remix'i nasıl kullanacağınızı öğrenmeniz gerekiyorsa [bu öğreticiyi kullanın](https://remix.ethereum.org/?#activate=udapp,solidity,LearnEth). ## Yaygın hatalar {#common-mistakes} ### Hatalar {#the-mistakes} -Kullanıcılar bazen jetonları yanlış adrese gönderir. Ne yapmak istediklerini anlamak için zihinlerini okuyamasak da sık sık meydana gelen ve tespit edilmesi kolay olan iki hata türü vardır: +Kullanıcılar bazen jetonları yanlış adrese gönderir. Ne yapmak istediklerini bilmek için akıllarını okuyamasak da, sıkça meydana gelen ve tespit edilmesi kolay olan iki hata türü vardır: -1. Jetonları sözleşmenin kendi adresine göndermek. Örneğin, [Optimism'in OP jetonu](https://optimism.mirror.xyz/qvd0WfuLKnePm1Gxb9dpGchPf5uDz5NSMEFdgirDS4c) iki aydan kısa bir sürede [120.000'den](https://optimistic.etherscan.io/address/0x4200000000000000000000000000000000000042#tokentxns) fazla OP jetonu biriktirmeyi başardı. Bu, muhtemelen insanların kaybettiği önemli miktarda bir serveti temsil ediyor. +1. Jetonları sözleşmenin kendi adresine göndermek. Örneğin, [Optimism'in OP jetonu](https://optimism.mirror.xyz/qvd0WfuLKnePm1Gxb9dpGchPf5uDz5NSMEFdgirDS4c) iki aydan kısa bir sürede [120.000'in üzerinde](https://optimism.blockscout.com/address/0x4200000000000000000000000000000000000042) OP jetonu biriktirmeyi başardı. Bu, muhtemelen insanların kaybettiği önemli miktarda bir serveti temsil ediyor. -2. Jetonları harici bir [dışarıdan sahip olunan hesaba](/developers/docs/accounts/#externally-owned-accounts-and-key-pairs) veya [akıllı sözleşmeye](/developers/docs/smart-contracts) karşılık gelmeyen boş bir adrese göndermek. Bunun ne sıklıkla gerçekleştiğine dair istatistiklere sahip olmasam da [tek bir olay 20.000.000 jetona mal olabilir.](https://gov.optimism.io/t/message-to-optimism-community-from-wintermute/2595). +2. Jetonları boş bir adrese, yani bir [Harici Olarak Sahiplenilmiş hesaba](/developers/docs/accounts/#externally-owned-accounts-and-key-pairs) veya bir [akıllı sözleşmeye](/developers/docs/smart-contracts) karşılık gelmeyen bir adrese göndermek. Bunun ne sıklıkla olduğuna dair istatistiklerim olmasa da, [bir olay 20.000.000 jetona mal olabilirdi](https://gov.optimism.io/t/message-to-optimism-community-from-wintermute/2595). ### Transferleri önleme {#preventing-transfers} -OpenZeppelin ERC-20 sözleşmesi, jeton aktarılmadan önce çağrılan bir `_beforeTokenTransfer` +OpenZeppelin ERC-20 sözleşmesi, bir jeton transfer edilmeden önce çağrılan [`_beforeTokenTransfer` adında bir kanca](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol#L364-L368) içerir. Varsayılan olarak bu kanca hiçbir şey yapmaz, ancak bir sorun olduğunda geri dönen kontroller gibi kendi işlevselliğimizi ona bağlayabiliriz. -kancası içerir. Bu kanca çalışırken varsayılan olarak hiçbir şey yapmaz ancak örneğin bir sorun olduğunda geri dönen kontroller gibi kendi işlevselliğimizi içerisine ekleyebiliriz. - -Kancayı kullanmak için oluşturucudan sonra şu işlevi ekleyin: +Kancayı kullanmak için bu işlevi kurucudan sonra ekleyin: ```solidity function _beforeTokenTransfer(address from, address to, uint256 amount) @@ -75,33 +75,33 @@ Solidity'ye pek aşina değilseniz işlevin bazı kısımları sizin için yeni internal virtual ``` -`virtual` anahtar sözcüğü tıpkı bizim `ERC-20`'den işlevsellik devraldığımız ve bu işlevi geçersiz kıldığımız gibi diğer sözleşmelerin de bizden miras alıp bu işlevi geçersiz kılabileceği anlamına gelir. +`virtual` anahtar kelimesi, tıpkı `ERC20`'den işlevsellik devraldığımız ve bu işlevi geçersiz kıldığımız gibi, diğer sözleşmelerin de bizden miras alıp bu işlevi geçersiz kılabileceği anlamına gelir. ```solidity override(ERC20) ``` -`_beforeTokenTransfer`'in ERC-20 jeton tanımını [geçersiz kıldığımızın](https://docs.soliditylang.org/en/v0.8.15/contracts.html#function-overriding) altını çizmeliyiz. Genel olarak net tanımlar örtülü tanımlara göre çok daha iyidir; bir şey gözünüzün tam önündeyse ne yaptığınızı unutmazsınız. Hangi üst sınıfa ait `_beforeTokenTransfer`'i geçersiz kıldığımızı belirtmemizin sebebi de budur. +`_beforeTokenTransfer`'in ERC20 jeton tanımını [geçersiz kıldığımızı](https://docs.soliditylang.org/en/v0.8.15/contracts.html#function-overriding) açıkça belirtmeliyiz. Genel olarak net tanımlar örtülü tanımlara göre çok daha iyidir; bir şey gözünüzün tam önündeyse ne yaptığınızı unutmazsınız. Hangi üst sınıfa ait `_beforeTokenTransfer`'i geçersiz kıldığımızı belirtmemizin sebebi de budur. ```solidity super._beforeTokenTransfer(from, to, amount); ``` -Bu satır, sözleşmenin veya ona sahip olan devraldığımız sözleşmelerin `_beforeTokenTransfer` işlevini çağırır. Bu durumda, bahsettiğimiz sadece `ERC-20`'dir, `Ownable` bu kancaya sahip değildir. Halihazırda `ERC20._beforeTokenTransfer` hiçbir şey yapmasa da, gelecekte işlevsellik eklenmesi durumunda onu çağırabiliriz (ve sonra, dağıtımdan sonra sözleşmeler değişmediği için sözleşmeyi yeniden dağıtmaya karar veririz). +Bu satır, sözleşmenin veya ona sahip olan devraldığımız sözleşmelerin `_beforeTokenTransfer` işlevini çağırır. Bu durumda, bahsettiğimiz sadece `ERC20`'dir, `Ownable` bu kancaya sahip değildir. Halihazırda `ERC20._beforeTokenTransfer` hiçbir şey yapmasa da, gelecekte işlevsellik eklenmesi durumunda onu çağırabiliriz (ve sonra, dağıtımdan sonra sözleşmeler değişmediği için sözleşmeyi yeniden dağıtmaya karar veririz). -### Gereksinimlerin kodlanması {#coding-the-requirements} +### Gereksinimleri kodlama {#coding-the-requirements} Aşağıdaki gereksinimleri işleve eklemek istiyoruz: - `to` adresi, ERC-20 sözleşmesinin kendi adresi olan `address(this)` ile eşit olamaz. - `to` adresi boş olamaz, aşağıdakilerden birisi olmalıdır: - - Dışarıdan sahip olunan hesap (EOA). Bir adresin EOA olup olmadığını doğrudan kontrol edemeyiz ancak bir adresin ETH bakiyesini kontrol edebiliriz. EOA'ların artık kullanılmasalar bile neredeyse her zaman bir bakiyesi vardır; onları son wei'ye kadar temizlemek zordur. - - Akıllı sözleşme. Bir adresin akıllı sözleşme olup olmadığını test etmek biraz daha zordur. Harici kod uzunluğunu kontrol eden, [`EXTCODESIZE`](https://www.evm.codes/#3b) isimli bir işlem kodu vardır ancak doğrudan Solidity'de mevcut değildir. Bunun için EVM derlemesi olan [Yul](https://docs.soliditylang.org/en/v0.8.15/yul.html)'u kullanmamız gerekir. Solidity'den kullanabileceğimiz ([`
.code` ve `
.codehash`](https://docs.soliditylang.org/en/v0.8.15/units-and-global-variables.html#members-of-address-types)) gibi başka değerler de vardır ancak maliyetleri daha yüksektir. + - Bir Harici Olarak Sahiplenilmiş hesap (EOA). Bir adresin EOA olup olmadığını doğrudan kontrol edemeyiz ancak bir adresin ETH bakiyesini kontrol edebiliriz. EOA'ların artık kullanılmasalar bile neredeyse her zaman bir bakiyesi vardır; onları son wei'ye kadar temizlemek zordur. + - Bir akıllı sözleşme. Bir adresin akıllı sözleşme olup olmadığını test etmek biraz daha zordur. Harici kod uzunluğunu kontrol eden, [`EXTCODESIZE`](https://www.evm.codes/#3b) olarak adlandırılan bir işlem kodu vardır, ancak bu doğrudan Solidity'de mevcut değildir. Bunun için EVM assembly'si olan [Yul](https://docs.soliditylang.org/en/v0.8.15/yul.html)'u kullanmalıyız. Solidity'den kullanabileceğimiz başka değerler de var ([`
.code` ve `
.codehash`](https://docs.soliditylang.org/en/v0.8.15/units-and-global-variables.html#members-of-address-types)) ama bunlar daha maliyetli. Gelin yeni kodu satır satır inceleyelim: ```solidity - require(to != address(this), "Can't send tokens to the contract address"); + require(to != address(this), "Jetonlar sözleşme adresine gönderilemez"); ``` `to` ile `this(address)`'in aynı şey olmadığını kontrol edin; bu, ilk gerekliliktir. @@ -113,48 +113,48 @@ Gelin yeni kodu satır satır inceleyelim: } ``` -Biz bir adresin sözleşme olup olmadığını bu şekilde kontrol ederiz. Yul'dan çıktıyı doğrudan alamayız, bunun yerine sonucu tutabilecek bir değişken tanımlarız (bu durumda `isToContract`). Yul'un çalışma şekli, her işlem kodunun bir işlev olarak kabul edilmesidir. Öncelikle sözleşme boyutunu almak için [`EXTCODESIZE`](https://www.evm.codes/#3b)'ı çağırır ve sonra sıfır olmadığını doğrulamak için [`GT`](https://www.evm.codes/#11)'yi kullanırız (negatif olamaz, çünkü işaretsiz tam sayılarla uğraşıyoruz). Sonrasında sonucu, `isToContrac`'a yazarız. +Biz bir adresin sözleşme olup olmadığını bu şekilde kontrol ederiz. Yul'dan çıktıyı doğrudan alamayız, bunun yerine sonucu tutabilecek bir değişken tanımlarız (bu durumda `isToContract`). Yul'un çalışma şekli, her işlem kodunun bir işlev olarak kabul edilmesidir. Öncelikle sözleşme boyutunu almak için [`EXTCODESIZE`](https://www.evm.codes/#3b) öğesini çağırır ve sonra sıfır olmadığını doğrulamak için [`GT`](https://www.evm.codes/#11) kullanırız (negatif olamaz, çünkü işaretsiz tam sayılarla uğraşıyoruz). Sonrasında sonucu, `isToContract`'a yazarız. ```solidity - require(to.balance != 0 || isToContract, "Can't send tokens to an empty address"); + require(to.balance != 0 || isToContract, "Jetonlar boş bir adrese gönderilemez"); ``` Son olarak sırada, boş adresler için gerçek kontrolümüz var. ## Yönetici erişimi {#admin-access} -Hataları geri alabilen bir yöneticiye sahip olmak bazen faydalı olabilir. Kötüye kullanım olasılığını azaltmak için bu yönetici bir [çoklu imza](https://blog.logrocket.com/security-choices-multi-signature-wallets/) olabilir, böylece birden fazla kişinin bir eylem üzerinde anlaşması gerekir. Bu makale içerisinde iki yönetici özelliğinden bahsedeceğiz: +Hataları geri alabilen bir yöneticiye sahip olmak bazen faydalı olabilir. Kötüye kullanım potansiyelini azaltmak için bu yönetici bir [çoklu imza](https://blog.logrocket.com/security-choices-multi-signature-wallets/) olabilir, böylece bir eylem üzerinde birden fazla kişinin anlaşması gerekir. Bu makale içerisinde iki yönetici özelliğinden bahsedeceğiz: 1. Hesapları dondurmak ve çözmek. Bu, örneğin bir hesabın güvenliği ihlal edildiğinde faydalı olabilir. 2. Varlık temizlemesi. - Bazen dolandırıcılar, meşruiyet kazanmak için gerçek jetonun sözleşmesine hileli jetonlar gönderir. Örneğin, [buraya bakın](https://optimistic.etherscan.io/token/0x2348b1a1228ddcd2db668c3d30207c3e1852fbbe?a=0x4200000000000000000000000000000000000042). Meşru ERC-20 sözleşmesi [0x4200....0042](https://optimistic.etherscan.io/address/0x4200000000000000000000000000000000000042)'dir. [0x234....bbe](https://optimistic.etherscan.io/address/0x2348b1a1228ddcd2db668c3d30207c3e1852fbbe) imiş gibi davranan bir dolandırıcılıktır. + Bazen dolandırıcılar, meşruiyet kazanmak için gerçek jetonun sözleşmesine hileli jetonlar gönderir. Örneğin, [buraya bakın](https://optimism.blockscout.com/token/0x2348B1a1228DDCd2dB668c3d30207c3E1852fBbe?tab=holders). Meşru ERC-20 sözleşmesi [0x4200....0042](https://optimism.blockscout.com/token/0x4200000000000000000000000000000000000042)'dir. Onun gibi davranan dolandırıcılık [0x234....bbe](https://optimism.blockscout.com/token/0x2348B1a1228DDCd2dB668c3d30207c3E1852fBbe)'dir. İnsanların sözleşmemize yanlışlıkla başka geçerli jetonlar göndermesi ise onları oradan çıkarmanın bir yolunu bulmamız için başka bir nedendir. -OpenZeppelin, yönetici erişimini etkinleştirmek için iki çeşit mekanizma sunar: +OpenZeppelin, yönetici erişimini etkinleştirmek için iki mekanizma sunar: -- [`Ownable`](https://docs.openzeppelin.com/contracts/5.x/access-control#ownership-and-ownable) sözleşmelerinin sadece bir sahibi vardır. `OnlyOwner`[ özelliğine](https://www.tutorialspoint.com/solidity/solidity_function_modifiers.htm) sahip işlevler yalnızca o sahip tarafından çağrılabilir. Sahipler bu sahipliği bir başkasına devredebilir ya da tamamen sahiplikten feragat edebilir. Tüm diğer hesapların hakları ise genelde aynıdır. -- [`AccessControl`](https://docs.openzeppelin.com/contracts/5.x/access-control#role-based-access-control) sözleşmelerinde [rol tabanlı erişim kontrolü (RBAC) bulunur](https://en.wikipedia.org/wiki/Role-based_access_control). +- [`Ownable`](https://docs.openzeppelin.com/contracts/5.x/access-control#ownership-and-ownable) sözleşmelerinin tek bir sahibi vardır. `onlyOwner` [değiştiricisine](https://www.tutorialspoint.com/solidity/solidity_function_modifiers.htm) sahip işlevler yalnızca o sahip tarafından çağrılabilir. Sahipler bu sahipliği bir başkasına devredebilir ya da tamamen sahiplikten feragat edebilir. Tüm diğer hesapların hakları ise genelde aynıdır. +- [`AccessControl`](https://docs.openzeppelin.com/contracts/5.x/access-control#role-based-access-control) sözleşmeleri [rol tabanlı erişim kontrolüne (RBAC)](https://en.wikipedia.org/wiki/Role-based_access_control) sahiptir. -Basit olması için biz bu makalede `Ownable`'ı kullanacağız. +Basit olması için bu makalede `Ownable` kullanıyoruz. ### Sözleşmeleri dondurma ve çözme {#freezing-and-thawing-contracts} Sözleşmeleri dondurmak ve çözmek, birtakım değişiklikler gerektirir: -- Hangi adreslerin dondurulduğunu takip etmeye yarayan adresler ile [boole değerleri](https://en.wikipedia.org/wiki/Boolean_data_type) [eşlemesi](https://www.tutorialspoint.com/solidity/solidity_mappings.htm). Tüm değerler başlangıçta sıfırdır ve bu boole değerleri için yanlış olarak yorumlanır. Hesaplar varsayılan olarak dondurulmuş halde gelmediği için istediğimiz budur. +- Hangi adreslerin dondurulduğunu takip etmek için adreslerden [boolean'lara](https://en.wikipedia.org/wiki/Boolean_data_type) bir [eşleme](https://www.tutorialspoint.com/solidity/solidity_mappings.htm). Tüm değerler başlangıçta sıfırdır ve bu boole değerleri için yanlış olarak yorumlanır. Hesaplar varsayılan olarak dondurulmuş halde gelmediği için istediğimiz budur. ```solidity mapping(address => bool) public frozenAccounts; ``` -- Bir hesap dondurulduğunda veya çözüldüğünde ilgilenen herkesi bilgilendirmek için [olay akışı](https://www.tutorialspoint.com/solidity/solidity_events.htm). Teknik olarak yaklaşacak olursak olay akışı bu eylemler için gerekli değildir ancak zincir dışı kodların olayı izlemesi ve olan biteni anlamasına yardımcı olurlar. Akıllı bir sözleşmenin başkasıyla alakalı olabilecek bir şey olduğunda bunları yayımlaması iyi bir davranış olarak kabul edilir. +- Bir hesap dondurulduğunda veya çözüldüğünde ilgilenen herkesi bilgilendirmek için [Olaylar](https://www.tutorialspoint.com/solidity/solidity_events.htm). Teknik olarak bu eylemler için olaylar gerekli değildir, ancak zincir dışı kodların bu olayları dinlemesine ve ne olduğunu bilmesine yardımcı olur. Akıllı bir sözleşmenin başkasıyla alakalı olabilecek bir şey olduğunda bunları yayımlaması iyi bir davranış olarak kabul edilir. - Olay akışı dizine eklenir, böylece bir hesabın dondurulduğu veya çözüldüğü tüm zamanları aramak mümkün olur. + Olaylar dizine eklendiğinden, bir hesabın dondurulduğu veya çözüldüğü tüm zamanlar aranabilir. ```solidity - // When accounts are frozen or unfrozen + // Hesaplar dondurulduğunda veya çözüldüğünde event AccountFrozen(address indexed _addr); event AccountThawed(address indexed _addr); ``` @@ -167,27 +167,27 @@ Sözleşmeleri dondurmak ve çözmek, birtakım değişiklikler gerektirir: onlyOwner ``` -[`public`](https://www.tutorialspoint.com/solidity/solidity_contracts.htm) olarak işaretlenmiş işlevler, diğer akıllı sözleşmelerden veya doğrudan bir işlemle çağrılabilir. + [`public`](https://www.tutorialspoint.com/solidity/solidity_contracts.htm) olarak işaretlenen işlevler, diğer akıllı sözleşmelerden veya doğrudan bir işlemle çağrılabilir. -```solidity - { - require(!frozenAccounts[addr], "Account already frozen"); - frozenAccounts[addr] = true; - emit AccountFrozen(addr); - } // freezeAccount -``` + ```solidity + { + require(!frozenAccounts[addr], "Hesap zaten dondurulmuş"); + frozenAccounts[addr] = true; + emit AccountFrozen(addr); + } // freezeAccount + ``` -Hesap önceden dondurulmuşsa, eski haline döndürün. Aksi takdirde, dondurun ve bir olay `emit` edin. + Hesap zaten dondurulmuşsa, geri alın. Aksi takdirde, dondurun ve bir olay `emit` edin. -- Paranın donmuş bir hesaptan taşınmasını önlemek için `_beforeTokenTransfer`'i değiştirin. Donmuş hesaba halen para aktarılabileceğini unutmayın. +- Dondurulmuş bir hesaptan para taşınmasını önlemek için `_beforeTokenTransfer`'i değiştirin. Donmuş hesaba halen para aktarılabileceğini unutmayın. ```solidity - require(!frozenAccounts[from], "The account is frozen"); + require(!frozenAccounts[from], "Hesap dondurulmuş"); ``` -### Varlık temizlemesi {#asset-cleanup} +### Varlık temizleme {#asset-cleanup} -Bu sözleşmede tutulan ERC-20 jetonlarını serbest bırakmak için ait oldukları jeton sözleşmesinde [`transfer`](https://eips.ethereum.org/EIPS/eip-20#transfer) veya [`approve`](https://eips.ethereum.org/EIPS/eip-20#approve) işlevlerinden birini çağırmamız gerekir. Bu durumda ödenekler için gaz harcamaya gerek yoktur, doğrudan transfer edebiliriz. +Bu sözleşme tarafından tutulan ERC-20 jetonlarını serbest bırakmak için, ait oldukları jeton sözleşmesinde [`transfer`](https://eips.ethereum.org/EIPS/eip-20#transfer) veya [`approve`](https://eips.ethereum.org/EIPS/eip-20#approve) işlevlerinden birini çağırmamız gerekir. Bu durumda ödenekler için gaz harcamaya gerek yoktur, doğrudan transfer edebiliriz. ```solidity function cleanupERC20( @@ -200,7 +200,7 @@ Bu sözleşmede tutulan ERC-20 jetonlarını serbest bırakmak için ait oldukla IERC20 token = IERC20(erc20); ``` -Bu, adresi aldığımızda bir sözleşme için nesne oluşturma söz dizimidir. Kaynak kodun bir parçası olarak ERC-20 jetonlarının tanımına sahip olduğumuzdan (bkz. Satır 4) ve bu dosya bir OpenZeppelin ERC-20 sözleşmesinin arayüzü olan [IERC20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol) tanımını içerdiğinden bunu yapabiliriz. +Bu, adresi aldığımızda bir sözleşme için nesne oluşturma söz dizimidir. Bunu yapabiliriz çünkü kaynak kodun bir parçası olarak ERC20 jetonlarının tanımına sahibiz (bkz. satır 4) ve bu dosya, bir OpenZeppelin ERC-20 sözleşmesinin arayüzü olan [IERC20 tanımını](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol) içerir. ```solidity uint balance = token.balanceOf(address(this)); @@ -212,4 +212,6 @@ Bu bir temizleme işlevidir, bu yüzden muhtemelen herhangi bir jeton bırakmak ## Sonuç {#conclusion} -Anlattığımız süreç mükemmel bir çözüm değildir, zaten "kullanıcı bir hata yaptı" sorunları için mükemmel bir çözüm de yoktur. Ancak bu tür kontrollerin kullanılması en azından bazı hataları önleyebilir. Hesapları dondurma yeteneği, tehlikeli olmakla birlikte belirli hacker'ların çaldığı fonları reddederek hacker'ların yarattığı zararı sınırlandırmak için kullanılabilir. +Bu mükemmel bir çözüm değildir; "kullanıcı hata yaptı" sorununun mükemmel bir çözümü yoktur. Ancak bu tür kontrollerin kullanılması en azından bazı hataları önleyebilir. Hesapları dondurma yeteneği, tehlikeli olmakla birlikte belirli hacker'ların çaldığı fonları reddederek hacker'ların yarattığı zararı sınırlandırmak için kullanılabilir. + +[Çalışmalarımdan daha fazlası için buraya bakın](https://cryptodocguy.pro/). diff --git a/public/content/translations/tr/developers/tutorials/ethereum-for-web2-auth/index.md b/public/content/translations/tr/developers/tutorials/ethereum-for-web2-auth/index.md new file mode 100644 index 00000000000..b3c738ba22f --- /dev/null +++ b/public/content/translations/tr/developers/tutorials/ethereum-for-web2-auth/index.md @@ -0,0 +1,886 @@ +--- +title: "web2 kimlik doğrulaması için Ethereum'u kullanma" +description: "Bu öğreticiyi okuduktan sonra, bir Geliştirici, tek oturum açma ve diğer ilgili hizmetleri sağlamak için web2'de kullanılan bir standart olan SAML girişi ile Ethereum girişini (Web3) entegre edebilecektir. Bu, web2 Kaynaklarına erişimin, Kullanıcı nitelikleri Tasdiklerden gelecek şekilde Ethereum imzaları aracılığıyla doğrulanmasına olanak tanır." +author: Ori Pomerantz +tags: [ "web2", "kimlik doğrulama", "eas" ] +skill: beginner +lang: tr +published: 2025-04-30 +--- + +## Giriş + +[SAML](https://www.onelogin.com/learn/saml), bir [kimlik sağlayıcının (IdP)](https://en.wikipedia.org/wiki/Identity_provider#SAML_identity_provider), [hizmet sağlayıcılara (SP)](https://en.wikipedia.org/wiki/Service_provider_\(SAML\)) Kullanıcı bilgileri sağlamasına izin vermek için web2'de kullanılan bir standarttır. + +Bu öğreticide, Kullanıcıların Ethereum'u henüz yerel olarak desteklemeyen web2 hizmetlerinde kimliklerini doğrulamak için Ethereum cüzdanlarını kullanmalarına olanak sağlamak üzere Ethereum imzalarını SAML ile nasıl entegre edeceğinizi öğreneceksiniz. + +Bu öğreticinin iki ayrı kitle için yazıldığını unutmayın: + +- Ethereum'u anlayan ve SAML öğrenmesi gereken Ethereum meraklıları +- SAML ve web2 kimlik doğrulamasını anlayan ve Ethereum öğrenmesi gereken Web2 meraklıları + +Sonuç olarak, zaten bildiğiniz birçok giriş materyali içerecektir. Atlamaktan çekinmeyin. + +### Ethereum meraklıları için SAML + +SAML merkezi bir protokoldür. bir hizmet sağlayıcı (SP), bir kimlik sağlayıcıdan (IdP) gelen iddiaları (örneğin \ + +Örneğin, SP şirketlere seyahat hizmetleri sağlayan bir seyahat acentesi olabilir ve IdP bir şirketin dahili web sitesi olabilir. Çalışanların iş seyahati rezervasyonu yapması gerektiğinde, seyahat acentesi, gerçekten seyahat rezervasyonu yapmalarına izin vermeden önce onları kimlik doğrulaması için şirkete gönderir. + +![Adım adım SAML süreci](./fig-01-saml.png) + +Bu, üç varlığın, tarayıcının, SP'nin ve IdP'nin erişim için müzakere etme şeklidir. SP'nin tarayıcıyı kullanan Kullanıcı hakkında önceden bir şey bilmesine gerek yoktur, sadece IdP'ye güvenmesi yeterlidir. + +### SAML meraklıları için Ethereum + +Ethereum merkeziyetsiz bir sistemdir. + +![Ethereum girişi](./fig-02-eth-logon.png) + +Kullanıcıların bir özel anahtarı vardır (genellikle bir tarayıcı uzantısında tutulur). Özel anahtardan bir açık anahtar ve ondan da 20 baytlık bir adres türetebilirsiniz. Kullanıcıların bir sisteme giriş yapması gerektiğinde, onlardan bir nonce (tek kullanımlık bir değer) ile bir mesaj imzalamaları istenir. Sunucu, imzanın bu adres tarafından oluşturulduğunu doğrulayabilir. + +![Tasdiklerden ekstra veri alma](./fig-03-eas-data.png) + +İmza yalnızca Ethereum adresini doğrular. Diğer kullanıcı niteliklerini almak için genellikle [tasdikleri](https://attest.org/) kullanırsınız. Bir tasdik genellikle şu alanlara sahiptir: + +- **Tasdik eden**, tasdiki yapan adres +- **Alıcı**, tasdikin geçerli olduğu adres +- **Veri**, ad, izinler vb. gibi tasdik edilen veriler. +- **Şema**, verileri yorumlamak için kullanılan şemanın kimliği. + +Ethereum'un merkeziyetsiz doğası nedeniyle, herhangi bir kullanıcı tasdik yapabilir. Tasdik edenin kimliği, hangi tasdikleri güvenilir olarak kabul ettiğimizi belirlemek için önemlidir. + +## Kurulum + +İlk adım, kendi aralarında iletişim kuran bir SAML SP ve bir SAML IdP'ye sahip olmaktır. + +1. Yazılımı indirin. Bu makalenin örnek yazılımı [github'da](https://github.com/qbzzt/250420-saml-ethereum). Farklı aşamalar farklı dallarda saklanır, bu aşama için `saml-only` istersiniz + + ```sh + git clone https://github.com/qbzzt/250420-saml-ethereum -b saml-only + cd 250420-saml-ethereum + pnpm install + ``` + +2. Kendinden imzalı sertifikalarla anahtarlar oluşturun. Bu, anahtarın kendi sertifika yetkilisi olduğu ve hizmet sağlayıcıya manuel olarak içe aktarılması gerektiği anlamına gelir. Daha fazla bilgi için [OpenSSL belgelerine](https://docs.openssl.org/master/man1/openssl-req/) bakın. + + ```sh + mkdir keys + cd keys + openssl req -new -x509 -days 365 -nodes -sha256 -out saml-sp.crt -keyout saml-sp.pem -subj /CN=sp/ + openssl req -new -x509 -days 365 -nodes -sha256 -out saml-idp.crt -keyout saml-idp.pem -subj /CN=idp/ + cd .. + ``` + +3. Sunucuları başlatın (hem SP hem de IdP) + + ```sh + pnpm start + ``` + +4. [http://localhost:3000/](http://localhost:3000/) URL'sindeki SP'ye gidin ve IdP'ye (bağlantı noktası 3001) yönlendirilmek için düğmeye tıklayın. + +5. IdP'ye e-posta adresinizi verin ve **Hizmet sağlayıcıda oturum aç**'a tıklayın. Hizmet sağlayıcıya geri yönlendirildiğinizi (bağlantı noktası 3000) ve sizi e-posta adresinizle tanıdığını görün. + +### Ayrıntılı açıklama + +Adım adım olanlar şunlardır: + +![Ethereum olmadan normal SAML girişi](./fig-04-saml-no-eth.png) + +#### src/config.mts + +Bu dosya hem Kimlik Sağlayıcı hem de Hizmet Sağlayıcı için yapılandırmayı içerir. Normalde bu ikisi farklı varlıklar olurdu, ancak burada basitlik için kodu paylaşabiliriz. + +```typescript +const fs = await import("fs") + +const protocol="http" +``` + +Şimdilik sadece test ediyoruz, bu yüzden HTTP kullanmakta bir sakınca yok. + +```typescript +export const spCert = fs.readFileSync("keys/saml-sp.crt").toString() +export const idpCert = fs.readFileSync("keys/saml-idp.crt").toString() +``` + +Normalde her iki bileşen için de mevcut olan (ve doğrudan güvenilen veya güvenilir bir sertifika yetkilisi tarafından imzalanan) açık anahtarları okuyun. + +```typescript +export const spPort = 3000 +export const spHostname = "localhost" +export const spDir = "sp" + +export const idpPort = 3001 +export const idpHostname = "localhost" +export const idpDir = "idp" + +export const spUrl = `${protocol}://${spHostname}:${spPort}/${spDir}` +export const idpUrl = `${protocol}://${idpHostname}:${idpPort}/${idpDir}` +``` + +Her iki bileşen için URL'ler. + +```typescript +export const spPublicData = { +``` + +Hizmet sağlayıcı için genel veriler. + +```typescript + entityID: `${spUrl}/metadata`, +``` + +Geleneksel olarak SAML'de `entityID`, varlığın meta verilerinin bulunduğu URL'dir. Bu meta veriler, XML biçiminde olması dışında, buradaki genel verilere karşılık gelir. + +```typescript + wantAssertionsSigned: true, + authnRequestsSigned: false, + signingCert: spCert, + allowCreate: true, + assertionConsumerService: [{ + Binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', + Location: `${spUrl}/assertion`, + }] + } +``` + +Amaçlarımız için en önemli tanım `assertionConsumerServer`'dır. Hizmet sağlayıcıya bir şey iddia etmek (örneğin, \ + +```typescript +export const idpPublicData = { + entityID: `${idpUrl}/metadata`, + signingCert: idpCert, + wantAuthnRequestsSigned: false, + singleSignOnService: [{ + Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST", + Location: `${idpUrl}/login` + }], + singleLogoutService: [{ + Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST", + Location: `${idpUrl}/logout` + }], + } +``` + +Kimlik sağlayıcı için genel veriler benzerdir. Bir kullanıcının oturumunu açmak için `http://localhost:3001/idp/login` adresine POST ve bir kullanıcının oturumunu kapatmak için `http://localhost:3001/idp/logout` adresine POST yapmanız gerektiğini belirtir. + +#### src/sp.mts + +Bu, bir hizmet sağlayıcıyı uygulayan koddur. + +```typescript +import * as config from "./config.mts" +const fs = await import("fs") +const saml = await import("samlify") +``` + +SAML'yi uygulamak için [`samlify`](https://www.npmjs.com/package/samlify) kütüphanesini kullanıyoruz. + +```typescript +import * as validator from "@authenio/samlify-node-xmllint" +saml.setSchemaValidator(validator) +``` + +`samlify` kütüphanesi, XML'in doğru olduğunu, beklenen açık anahtarla imzalandığını vb. doğrulayan bir pakete sahip olmayı bekler. Bu amaçla [`@authenio/samlify-node-xmllint`](https://www.npmjs.com/package/@authenio/samlify-node-xmllint) kullanıyoruz. + +```typescript +const express = (await import("express")).default +const spRouter = express.Router() +const app = express() +``` + +Bir [`express`](https://expressjs.com/) [`Router`](https://expressjs.com/en/5x/api.html#router), bir web sitesinin içine monte edilebilen bir \ Bu durumda, tüm hizmet sağlayıcı tanımlarını bir araya getirmek için kullanırız. + +```typescript +const spPrivateKey = fs.readFileSync("keys/saml-sp.pem").toString() + +const sp = saml.ServiceProvider({ + privateKey: spPrivateKey, + ...config.spPublicData +}) +``` + +Hizmet sağlayıcının kendi temsili, tüm genel veriler ve bilgileri imzalamak için kullandığı özel anahtardır. + +```typescript +const idp = saml.IdentityProvider(config.idpPublicData); +``` + +Genel veriler, hizmet sağlayıcının kimlik sağlayıcı hakkında bilmesi gereken her şeyi içerir. + +```typescript +spRouter.get(`/metadata`, + (req, res) => res.header("Content-Type", "text/xml").send(sp.getMetadata()) +) +``` + +Diğer SAML bileşenleriyle birlikte çalışabilirliği sağlamak için, hizmet ve kimlik sağlayıcıların genel verileri (meta veriler olarak adlandırılır) `/metadata` içinde XML biçiminde mevcut olmalıdır. + +```typescript +spRouter.post(`/assertion`, +``` + +Bu, tarayıcının kendini tanıtmak için eriştiği sayfadır. Beyan, kullanıcı tanımlayıcısını (burada e-posta adresi kullanıyoruz) içerir ve ek nitelikler içerebilir. Bu, yukarıdaki sıra diyagramındaki 7. adımın işleyicisidir. + +```typescript + async (req, res) => { + // console.log(`SAML response:\n${Buffer.from(req.body.SAMLResponse, 'base64').toString('utf-8')}`) +``` + +Onayda sağlanan XML verilerini görmek için yorum satırı yapılmış komutu kullanabilirsiniz. [Base64 kodludur](https://en.wikipedia.org/wiki/Base64). + +```typescript + try { + const loginResponse = await sp.parseLoginResponse(idp, 'post', req); +``` + +Kimlik sunucusundan gelen oturum açma isteğini ayrıştırın. + +```typescript + res.send(` + + +

Hello ${loginResponse.extract.nameID}

+ + + `) + res.send(); +``` + +Sadece kullanıcıya giriş yaptığımızı göstermek için bir HTML yanıtı gönderin. + +```typescript + } catch (err) { + console.error('Error processing SAML response:', err); + res.status(400).send('SAML authentication failed'); + } + } +) +``` + +Başarısızlık durumunda kullanıcıyı bilgilendirin. + +```typescript +spRouter.get('/login', +``` + +Tarayıcı bu sayfayı almaya çalıştığında bir oturum açma isteği oluşturun. Bu, yukarıdaki sıra diyagramındaki 1. adımın işleyicisidir. + +```typescript + async (req, res) => { + const loginRequest = await sp.createLoginRequest(idp, "post") +``` + +Bir oturum açma isteği göndermek için bilgileri alın. + +```typescript + res.send(` + + + +``` + +Bu sayfa formu (aşağıya bakın) otomatik olarak gönderir. Bu şekilde kullanıcının yönlendirilmek için herhangi bir şey yapmasına gerek kalmaz. Bu, yukarıdaki sıra diyagramındaki 2. adımdır. + +```typescript +
+``` + +`loginRequest.entityEndpoint`'e (kimlik sağlayıcı uç noktasının URL'si) gönderin. + +```typescript + +``` + +Girdi adı `loginRequest.type`'dır (`SAMLRequest`). Bu alanın içeriği `loginRequest.context`'tir, bu da yine base64 kodlu XML'dir. + +```typescript +
+ + + `) + } +) + +app.use(express.urlencoded({extended: true})) +``` + +[Bu ara katman yazılımı](https://expressjs.com/en/5x/api.html#express.urlencoded), [HTTP isteğinin](https://www.tutorialspoint.com/http/http_requests.htm) gövdesini okur. Varsayılan olarak express bunu yok sayar, çünkü çoğu istek bunu gerektirmez. Buna ihtiyacımız var çünkü POST gövdeyi kullanıyor. + +```typescript +app.use(`/${config.spDir}`, spRouter) +``` + +Yönlendiriciyi hizmet sağlayıcı dizinine (`/sp`) bağlayın. + +```typescript +app.get("/", (req, res) => { + res.send(` + + + + + + `) +}) +``` + +Bir tarayıcı kök dizini almaya çalışırsa, ona oturum açma sayfasına bir bağlantı sağlayın. + +```typescript +app.listen(config.spPort, () => { + console.log(`service provider is running on http://${config.spHostname}:${config.spPort}`) +}) +``` + +Bu express uygulamasıyla `spPort`'u dinleyin. + +#### src/idp.mts + +Bu kimlik sağlayıcıdır. Hizmet sağlayıcıya çok benzer, aşağıdaki açıklamalar farklı olan kısımlar içindir. + +```typescript +const xmlParser = new (await import("fast-xml-parser")).XMLParser( + { + ignoreAttributes: false, // Nitelikleri Koru + attributeNamePrefix: "@_", // Nitelikler için ön ek + } +) +``` + +Hizmet sağlayıcıdan aldığımız XML isteğini okumamız ve anlamamız gerekiyor. + +```typescript +const getLoginPage = requestId => ` +``` + +Bu işlev, yukarıdaki sıra diyagramının 4. adımında döndürülen, otomatik gönderilen formu içeren sayfayı oluşturur. + +```typescript + + + Oturum açma sayfası + + +

Oturum açma sayfası

+
+ + E-posta adresi: +
+ +``` + +Hizmet sağlayıcıya gönderdiğimiz iki alan var: + +1. Yanıtladığımız `requestId`. +2. Kullanıcı tanımlayıcısı (şimdilik kullanıcının verdiği e-posta adresini kullanıyoruz). + +```typescript +
+ + + +const idpRouter = express.Router() + +idpRouter.post("/loginSubmitted", async (req, res) => { + const loginResponse = await idp.createLoginResponse( +``` + +Bu, yukarıdaki sıra diyagramındaki 5. adımın işleyicisidir. [`idp.createLoginResponse`](https://github.com/tngan/samlify/blob/master/src/entity-idp.ts#L73-L125) oturum açma yanıtını oluşturur. + +```typescript + sp, + { + authnContextClassRef: 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport', + audience: sp.entityID, +``` + +Hedef kitle hizmet sağlayıcıdır. + +```typescript + extract: { + request: { + id: req.body.requestId + } + }, +``` + +İstekten çıkarılan bilgiler. İstekte önem verdiğimiz tek parametre, hizmet sağlayıcının istekleri ve yanıtlarını eşleştirmesine olanak tanıyan requestId'dir. + +```typescript + signingKey: { privateKey: idpPrivateKey, publicKey: config.idpCert } // İmzalamayı sağla +``` + +Yanıtı imzalamak için veriye sahip olmak için `signingKey`'e ihtiyacımız var. Hizmet sağlayıcı imzasız isteklere güvenmez. + +```typescript + }, + "post", + { + email: req.body.email +``` + +Bu, hizmet sağlayıcıya geri gönderdiğimiz kullanıcı bilgilerini içeren alandır. + +```typescript + } + ); + + res.send(` + + + + +
+ +
+ + + `) +}) +``` + +Yine, otomatik gönderilen bir form kullanın. Bu, yukarıdaki sıra diyagramındaki 6. adımdır. + +```typescript + +// Oturum açma istekleri için IdP uç noktası +idpRouter.post(`/login`, +``` + +Bu, hizmet sağlayıcıdan bir oturum açma isteği alan uç noktadır. Bu, yukarıdaki sıra diyagramının 3. adımının işleyicisidir. + +```typescript + async (req, res) => { + try { + // parseLoginRequest'i çalıştıramadığım için geçici çözüm. + // const loginRequest = await idp.parseLoginRequest(sp, 'post', req) + const samlRequest = xmlParser.parse(Buffer.from(req.body.SAMLRequest, 'base64').toString('utf-8')) + res.send(getLoginPage(samlRequest["samlp:AuthnRequest"]["@_ID"])) +``` + +Kimlik doğrulama isteğinin kimliğini okumak için [`idp.parseLoginRequest`](https://github.com/tngan/samlify/blob/master/src/entity-idp.ts#L127-L144) kullanabilmeliyiz. Ancak, çalıştıramadım ve üzerinde çok fazla zaman harcamaya değmedi, bu yüzden sadece [genel amaçlı bir XML ayrıştırıcısı](https://www.npmjs.com/package/fast-xml-parser) kullanıyorum. İhtiyacımız olan bilgi, XML'in en üst düzeyinde bulunan `` etiketinin içindeki `ID` özniteliğidir. + +## Ethereum imzalarını kullanma + +Artık hizmet sağlayıcıya bir kullanıcı kimliği gönderebildiğimize göre, bir sonraki adım kullanıcı kimliğini güvenilir bir şekilde elde etmektir. Viem, cüzdandan kullanıcı adresini istememize izin verir, ancak bu, bilgiyi tarayıcıdan istemek anlamına gelir. Tarayıcıyı kontrol etmiyoruz, bu yüzden ondan aldığımız yanıta otomatik olarak güvenemeyiz. + +Bunun yerine, IdP tarayıcıya imzalaması için bir dize gönderecek. Tarayıcıdaki cüzdan bu dizeyi imzalarsa, bu gerçekten o adres olduğu anlamına gelir (yani, adrese karşılık gelen özel anahtarı bilir). + +Bunu çalışırken görmek için mevcut IdP ve SP'yi durdurun ve şu komutları çalıştırın: + +```sh +git checkout eth-signatures +pnpm install +pnpm start +``` + +Ardından [SP'ye](http://localhost:3000) gidin ve yönergeleri izleyin. + +Bu noktada Ethereum adresinden e-posta adresini nasıl alacağımızı bilmediğimizi, bu yüzden SP'ye `@bad.email.address` olarak rapor ettiğimizi unutmayın. + +### Ayrıntılı açıklama + +Değişiklikler önceki diyagramdaki 4-5. adımlardadır. + +![Ethereum imzalı SAML](./fig-05-saml-w-signature.png) + +Değiştirdiğimiz tek dosya `idp.mts`. İşte değiştirilen kısımlar. + +```typescript +import { v4 as uuidv4 } from 'uuid' +import { verifyMessage } from 'viem' +``` + +Bu iki ek kütüphaneye ihtiyacımız var. [nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce) değerini oluşturmak için [`uuid`](https://www.npmjs.com/package/uuid) kullanıyoruz. Değerin kendisi önemli değil, sadece bir kez kullanıldığı gerçeği önemli. + +[`viem`](https://viem.sh/) kütüphanesi Ethereum tanımlarını kullanmamızı sağlar. Burada imzanın gerçekten geçerli olduğunu doğrulamak için buna ihtiyacımız var. + +```typescript +const loginPrompt = \ +``` + +Cüzdan, mesajı imzalamak için kullanıcıdan izin ister. Sadece bir nonce olan bir mesaj kullanıcıların kafasını karıştırabilir, bu yüzden bu istemi ekliyoruz. + +```typescript +// requestID'leri burada tutun +let nonces = {} +``` + +Ona yanıt verebilmek için istek bilgisine ihtiyacımız var. İstekle birlikte gönderebilir (adım 4) ve geri alabiliriz (adım 5). Ancak, potansiyel olarak düşman bir kullanıcının kontrolü altında olan tarayıcıdan aldığımız bilgilere güvenemeyiz. Bu yüzden anahtar olarak nonce ile burada saklamak daha iyidir. + +Bunu burada basitlik adına bir değişken olarak yaptığımızı unutmayın. Ancak, bunun birkaç dezavantajı vardır: + +- Hizmet reddi saldırısına karşı savunmasızız. Kötü niyetli bir kullanıcı birden çok kez oturum açmaya çalışarak belleğimizi doldurabilir. +- IdP işlemi yeniden başlatılması gerekirse, mevcut değerleri kaybederiz. +- Her birinin kendi değişkeni olacağı için birden çok işlem arasında yük dengeleyemeyiz. + +Bir üretim sisteminde bir veritabanı kullanır ve bir tür sona erme mekanizması uygularız. + +```typescript +const getSignaturePage = requestId => { + const nonce = uuidv4() + nonces[nonce] = requestId +``` + +Bir nonce oluşturun ve `requestId`'yi ileride kullanmak üzere saklayın. + +```typescript + return ` + + + + + +

Lütfen imzalayın

+ +
+ + + +` +} +``` + +Gerisi sadece standart HTML. + +```typescript +idpRouter.get("/signature/:nonce/:account/:signature", async (req, res) => { +``` + +Bu, sıra diyagramındaki 5. adımın işleyicisidir. + +```typescript + const requestId = nonces[req.params.nonce] + if (requestId === undefined) { + res.send("Kötü nonce") + return ; + } + + nonces[req.params.nonce] = undefined +``` + +İstek kimliğini alın ve yeniden kullanılamadığından emin olmak için `nonces`'tan nonce'ı silin. + +```typescript + try { +``` + +İmzanın geçersiz olabileceği pek çok yol olduğundan, bunu bir `try ...` içine sararız. `catch` bloğu ile atılan hataları yakalarız. + +```typescript + const validSignature = await verifyMessage({ + address: req.params.account, + message: `${loginPrompt}${req.params.nonce}`, + signature: req.params.signature + }) +``` + +Sıra diyagramında 5.5. adımı uygulamak için [`verifyMessage`](https://viem.sh/docs/actions/public/verifyMessage#verifymessage) kullanın. + +```typescript + if (!validSignature) + throw("Kötü imza") + } catch (err) { + res.send("Hata:" + err) + return ; + } +``` + +İşleyicinin geri kalanı, küçük bir değişiklik dışında, daha önce `/loginSubmitted` işleyicisinde yaptığımızla eşdeğerdir. + +```typescript + const loginResponse = await idp.createLoginResponse( + . + . + . + { + email: req.params.account + "@bad.email.address" + } + ); +``` + +Gerçek e-posta adresimiz yok (bir sonraki bölümde alacağız), bu yüzden şimdilik Ethereum adresini döndürüyoruz ve bir e-posta adresi olmadığını açıkça belirtiyoruz. + +```typescript +// Oturum açma istekleri için IdP uç noktası +idpRouter.post(`/login`, + async (req, res) => { + try { + // parseLoginRequest'i çalıştıramadığım için geçici çözüm. + // const loginRequest = await idp.parseLoginRequest(sp, 'post', req) + const samlRequest = xmlParser.parse(Buffer.from(req.body.SAMLRequest, 'base64').toString('utf-8')) + res.send(getSignaturePage(samlRequest["samlp:AuthnRequest"]["@_ID"])) + } catch (err) { + console.error('SAML yanıtı işlenirken hata:', err); + res.status(400).send('SAML kimlik doğrulaması başarısız oldu'); + } + } +) +``` + +3. adım işleyicisinde `getLoginPage` yerine şimdi `getSignaturePage` kullanın. + +## E-posta adresini alma + +Bir sonraki adım, hizmet sağlayıcı tarafından istenen tanımlayıcı olan e-posta adresini elde etmektir. Bunu yapmak için [Ethereum Tasdik Hizmetini (EAS)](https://attest.org/) kullanıyoruz. + +Tasdik almanın en kolay yolu [GraphQL API'sini](https://docs.attest.org/docs/developer-tools/api) kullanmaktır. Bu sorguyu kullanıyoruz: + +``` +query GetAttestationsByRecipient { + attestations( + where: { + recipient: { equals: "${getAddress(ethAddr)}" } + schemaId: { equals: "0xfa2eff59a916e3cc3246f9aec5e0ca00874ae9d09e4678e5016006f07622f977" } + } + take: 1 + ) { + data + id + attester + } +} +``` + +Bu [`schemaId`](https://optimism.easscan.org/schema/view/0xfa2eff59a916e3cc3246f9aec5e0ca00874ae9d09e4678e5016006f07622f977) yalnızca bir e-posta adresi içerir. Bu sorgu, bu şemanın tasdiklerini ister. Tasdikin konusu `recipient` (alıcı) olarak adlandırılır. Her zaman bir Ethereum adresidir. + +Uyarı: Burada tasdikleri alma şeklimizin iki güvenlik sorunu var. + +- Merkezi bir bileşen olan `https://optimism.easscan.org/graphql` API uç noktasına gidiyoruz. `id` özniteliğini alabilir ve ardından bir tasdikin gerçek olduğunu doğrulamak için zincir üzerinde bir arama yapabiliriz, ancak API uç noktası yine de bize onlardan bahsetmeyerek tasdikleri sansürleyebilir. + + Bu sorunu çözmek imkansız değil, kendi GraphQL uç noktamızı çalıştırabilir ve tasdikleri zincir günlüklerinden alabiliriz, ancak bu amaçlarımız için aşırıdır. + +- Tasdik eden kimliğine bakmıyoruz. Herkes bize yanlış bilgi verebilir. Gerçek bir dünya uygulamasında, bir dizi güvenilir tasdik edicimiz olurdu ve yalnızca onların tasdiklerine bakardık. + +Bunu çalışırken görmek için mevcut IdP ve SP'yi durdurun ve şu komutları çalıştırın: + +```sh +git checkout email-address +pnpm install +pnpm start +``` + +Ardından e-posta adresinizi girin. Bunu yapmanın iki yolu var: + +- Özel bir anahtar kullanarak bir cüzdanı içe aktarın ve `0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80` test özel anahtarını kullanın. + +- Kendi e-posta adresiniz için bir tasdik ekleyin: + + 1. [Tasdik gezginindeki şemaya](https://optimism.easscan.org/schema/view/0xfa2eff59a916e3cc3246f9aec5e0ca00874ae9d09e4678e5016006f07622f977) gidin. + + 2. **Şema ile Tasdik Et**'e tıklayın. + + 3. Alıcı olarak Ethereum adresinizi, e-posta adresi olarak e-posta adresinizi girin ve **Zincir Üstü**'nü seçin. Ardından **Tasdik Oluştur**'a tıklayın. + + 4. Cüzdanınızdaki işlemi onaylayın. Gaz ücretini ödemek için [Optimism Blokzincirinde](https://app.optimism.io/bridge/deposit) bir miktar ETH'ye ihtiyacınız olacak. + +Her iki durumda da, bunu yaptıktan sonra [http://localhost:3000](http://localhost:3000) adresine gidin ve yönergeleri izleyin. Test özel anahtarını içe aktardıysanız, aldığınız e-posta `test_addr_0@example.com`'dur. Kendi adresinizi kullandıysanız, tasdik ettiğiniz ne ise o olmalıdır. + +### Ayrıntılı açıklama + +![Ethereum adresinden e-postaya geçiş](./fig-06-saml-sig-n-email.png) + +Yeni adımlar GraphQL iletişimi, 5.6 ve 5.7. adımlardır. + +Yine, `idp.mts`'nin değiştirilmiş kısımları burada. + +```typescript +import { GraphQLClient } from 'graphql-request' +import { SchemaEncoder } from '@ethereum-attestation-service/eas-sdk' +``` + +İhtiyacımız olan kütüphaneleri içe aktarın. + +```typescript +const graphqlEndpointUrl = "https://optimism.easscan.org/graphql" +``` + +[Her blokzincir için ayrı bir uç nokta](https://docs.attest.org/docs/developer-tools/api) vardır. + +```typescript +const graphqlClient = new GraphQLClient(graphqlEndpointUrl, { fetch }) +``` + +Uç noktayı sorgulamak için kullanabileceğimiz yeni bir `GraphQLClient` istemcisi oluşturun. + +```typescript +const graphqlSchema = 'string emailAddress' +const graphqlEncoder = new SchemaEncoder(graphqlSchema) +``` + +GraphQL bize yalnızca bayt içeren opak bir veri nesnesi verir. Onu anlamak için şemaya ihtiyacımız var. + +```typescript +const ethereumAddressToEmail = async ethAddr => { +``` + +Bir Ethereum adresinden bir e-posta adresine geçmek için bir işlev. + +```typescript + const query = ` + query GetAttestationsByRecipient {` +``` + +Bu bir GraphQL sorgusudur. + +```typescript + tasdikler( +``` + +Tasdikler arıyoruz. + +```typescript + where: { + recipient: { equals: "${getAddress(ethAddr)}" } + schemaId: { equals: "0xfa2eff59a916e3cc3246f9aec5e0ca00874ae9d09e4678e5016006f07622f977" } + } +``` + +İstediğimiz tasdikler, şemamızdaki, alıcının `getAddress(ethAddr)` olduğu tasdiklerdir. [`getAddress`](https://viem.sh/docs/utilities/getAddress#getaddress) işlevi, adresimizin doğru [sağlama toplamına](https://github.com/ethereum/ercs/blob/master/ERCS/erc-55.md) sahip olduğundan emin olur. Bu, GraphQL'in büyük/küçük harfe duyarlı olması nedeniyle gereklidir. ` + +```typescript + take: 1 +``` + +Kaç tane tasdik bulursak bulalım, sadece ilkini istiyoruz. + +```typescript + ) { + data + id + attester + } + }` +``` + +Almak istediğimiz alanlar. + +- `attester`: Tasdiki gönderen adres. Normalde bu, tasdike güvenip güvenmeyeceğine karar vermek için kullanılır. +- `id`: Tasdik kimliği. GraphQL sorgusundan gelen bilgilerin doğru olduğunu doğrulamak için bu değeri [tasdiki zincir üzerinde okumak](https://optimism.blockscout.com/address/0x4200000000000000000000000000000000000021?tab=read_proxy&source_address=0x4E0275Ea5a89e7a3c1B58411379D1a0eDdc5b088#0xa3112a64) için kullanabilirsiniz. +- `data`: Şema verileri (bu durumda, e-posta adresi). + +```typescript + const queryResult = await graphqlClient.request(query) + + if (queryResult.attestations.length == 0) + return "no_address@available.is" +``` + +Tasdik yoksa, açıkça yanlış olan ancak hizmet sağlayıcıya geçerli görünecek bir değer döndürün. + +```typescript + const attestationDataFields = graphqlEncoder.decodeData(queryResult.attestations[0].data) + return attestationDataFields[0].value.value +} +``` + +Bir değer varsa, verileri çözmek için `decodeData` kullanın. Sağladığı meta verilere ihtiyacımız yok, sadece değerin kendisine ihtiyacımız var. + +```typescript + const loginResponse = await idp.createLoginResponse( + sp, + { + . + . + . + }, + "post", + { + email: await ethereumAddressToEmail(req.params.account) + } + ); +``` + +E-posta adresini almak için yeni işlevi kullanın. + +## Peki ya merkeziyetsizlik? + +Bu yapılandırmada, Ethereum'dan e-posta adresine eşleme için güvenilir tasdik edicilere güvendiğimiz sürece, kullanıcılar olmadıkları biri gibi davranamazlar. Ancak, kimlik sağlayıcımız hala merkezi bir bileşendir. Kimlik sağlayıcısının özel anahtarına sahip olan herkes, hizmet sağlayıcıya yanlış bilgi gönderebilir. + +[Çok taraflı hesaplama (MPC)](https://en.wikipedia.org/wiki/Secure_multi-party_computation) kullanarak bir çözüm olabilir. Gelecekteki bir öğreticide bunun hakkında yazmayı umuyorum. + +## Sonuç + +Ethereum imzaları gibi bir oturum açma standardının benimsenmesi, bir tavuk ve yumurta sorunuyla karşı karşıyadır. Hizmet sağlayıcılar mümkün olan en geniş pazara hitap etmek ister. Kullanıcılar, oturum açma standartlarını destekleme konusunda endişelenmeden hizmetlere erişebilmek ister. +Bir Ethereum IdP gibi adaptörler oluşturmak, bu engeli aşmamıza yardımcı olabilir. + +[Çalışmalarımdan daha fazlası için buraya bakın](https://cryptodocguy.pro/). diff --git a/public/content/translations/tr/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md b/public/content/translations/tr/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md index f63f98ac739..714ea1731ac 100644 --- a/public/content/translations/tr/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md +++ b/public/content/translations/tr/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md @@ -1,13 +1,15 @@ --- -title: Ethereum Geliştirmeye Başlarken -description: "Bu, Ethereum geliştirmeye başlamak için bir başlangıç rehberidir. Sizi bir API uç noktasını döndürmekten, bir komut satırı isteğinde bulunmaya ve ilk web3 komut dosyanızı yazmaya kadar götüreceğiz! Blok zinciri geliştirme deneyimi gerekmez!" +title: "Ethereum Geliştirmeye Başlarken" +description: "Bu, Ethereum geliştirmeye başlamak için bir başlangıç rehberidir. Sizi bir API uç noktası kurmaktan, bir komut satırı isteğinde bulunmaya ve ilk web3 betiğinizi yazmaya kadar götüreceğiz! Blokzincir geliştirme deneyimi gerekmez!" author: "Elan Halpern" tags: - - "javascript" - - "ethers.js" - - "düğümler" - - "sorgulama" - - "alchemy" + [ + "javascript", + "ethers.js", + "düğümler", + "sorgulama", + "alchemy" + ] skill: beginner lang: tr published: 2020-10-30 @@ -17,42 +19,42 @@ sourceUrl: https://medium.com/alchemy-api/getting-started-with-ethereum-developm ![Ethereum ve Alchemy logoları](./ethereum-alchemy.png) -Bu, Ethereum geliştirmeye başlamak için bir başlangıç rehberidir. Bu eğitim için; Maker, 0x, MyEtherWallet, Dharma ve Kyber dahil en iyi blok zinciri uygulamalarının %70'inden milyonlarca kullanıcıya destek veren lider blok zinciri geliştirici platformu [Alchemy](https://alchemyapi.io/)'yi kullanacağız. Alchemy, işlemleri okuyup yazabilmemiz için Ethereum zincirindeki bir API uç noktasına erişmemizi sağlayacak. +Bu, Ethereum geliştirmeye başlamak için bir başlangıç rehberidir. Bu eğitim için; Maker, 0x, MyEtherWallet, Dharma ve Kyber dahil en iyi blokzincir uygulamalarının %70'inden milyonlarca kullanıcıya destek veren lider blokzincir geliştirici platformu [Alchemy](https://alchemyapi.io/)'yi kullanacağız. Alchemy, işlemleri okuyup yazabilmemiz için Ethereum zincirindeki bir API uç noktasına erişmemizi sağlayacak. -Sizi Alchemy'ye kaydolmaktan ilk web3 komut dosyanızı yazmaya götüreceğiz! Blok zinciri geliştirme deneyimi gerekmez! +Sizi Alchemy'ye kaydolmaktan ilk web3 betiğinizi yazmaya götüreceğiz! Blokzincir geliştirme deneyimi gerekmez! -## 1. Ücretsiz Alchemy Hesabı için Üye Olun {#sign-up-for-a-free-alchemy-account} +## 1. Ücretsiz Bir Alchemy Hesabına Kaydolun {#sign-up-for-a-free-alchemy-account} -Alchemy ile bir hesap oluşturmak kolaydır, [buradan ücretsiz üye olun](https://auth.alchemyapi.io/signup). +Alchemy ile bir hesap oluşturmak kolaydır, [buradan ücretsiz kaydolun](https://auth.alchemy.com/). ## 2. Bir Alchemy Uygulaması Oluşturun {#create-an-alchemy-app} Ethereum zinciriyle iletişim kurmak ve Alchemy'nin ürünlerini kullanmak amacıyla isteklerinizi doğrulamak için bir API anahtarına ihtiyacınız var. -[Gösterge panelinden API anahtarları oluşturabilirsiniz](http://dashboard.alchemyapi.io/). Yeni bir anahtar oluşturmak için aşağıda gösterildiği gibi "Create App"e (Uygulama Oluştur) gidin: +[Gösterge panelinden API anahtarları oluşturabilirsiniz](https://dashboard.alchemy.com/). Yeni bir anahtar oluşturmak için aşağıda gösterildiği gibi "Create App" (Uygulama Oluştur) bölümüne gidin: -[_ShapeShift_](https://shapeshift.com/)'e _gösterge panelini göstermemize izin verdiği için teşekkür ederiz!_ +_Bize kendi gösterge panellerini gösterme izni verdikleri için [_ShapeShift_](https://shapeshift.com/)'e özel teşekkürler!_ ![Alchemy gösterge paneli](./alchemy-dashboard.png) -Yeni anahtarınızı almak için "Create App" altındaki ayrıntıları doldurun. Ayrıca daha önce yaptığınız uygulamaları ve ekibiniz tarafından yapılanları burada görebilirsiniz. Herhangi bir uygulama için "View Key"ye (Anahtarı Görüntüle) tıklayarak var olan anahtarları alabilirsiniz. +Yeni anahtarınızı almak için "Create App" altındaki ayrıntıları doldurun. Ayrıca daha önce yaptığınız uygulamaları ve ekibiniz tarafından yapılanları burada görebilirsiniz. Herhangi bir uygulama için "View Key" (Anahtarı Görüntüle) seçeneğine tıklayarak mevcut anahtarları alabilirsiniz. ![Alchemy ile uygulama oluşturma ekran görüntüsü](./create-app.png) -Ayrıca, "Apps"in (Uygulamalar) üzerine gelip birini seçerek mevcut API anahtarlarını da alabilirsiniz. Burada anahtarı görüntüleyebilir, belirli alanları beyaz listeye almak için "Edit App"e tıklayabilir, çeşitli geliştirici araçlarını görebilir ve analizleri görüntüleyebilirsiniz. +Ayrıca, "Apps" (Uygulamalar) üzerine gelip birini seçerek mevcut API anahtarlarını da alabilirsiniz. Buradan "View Key" (Anahtarı Görüntüle) ile anahtarı görüntüleyebilir, "Edit App" (Uygulamayı Düzenle) ile belirli alan adlarını beyaz listeye ekleyebilir, çeşitli geliştirici araçlarını görebilir ve analizleri görüntüleyebilirsiniz. ![Bir kullanıcıya API anahtarlarının nasıl alınacağını gösteren GIF](./pull-api-keys.gif) -## 3. Komut Satırından İstekte Bulunun {#make-a-request-from-the-command-line} +## 3. Komut Satırından İstek Yapma {#make-a-request-from-the-command-line} -JSON-RPC ve curl kullanarak Alchemy aracılığıyla Ethereum blok zinciriyle etkileşim kurun. +JSON-RPC ve curl kullanarak Alchemy aracılığıyla Ethereum blokzinciriyle etkileşim kurun. Manuel istekler için `JSON-RPC` ile `POST` istekleri aracılığıyla etkileşim kurmanızı öneririz. `Content-Type: application/json` başlığını ve sorgunuzu aşağıdaki alanlarla birlikte `POST` gövdesi olarak iletmeniz yeterlidir: -- `jsonrpc`: JSON-RPC versiyonu. Şu anda, sadece `2.0` desteklidir. -- `method`: ETH API yöntemi. [API referansına bakınız.](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc) -- `params`: Yönteme geçirilecek parametre listesi. -- `id`: İsteğinizin ID'si. Bir yanıtın hangi isteğe ait olduğunu takip edebilmeniz için yanıt tarafından döndürülür. +- `jsonrpc`: JSON-RPC sürümü—şu anda yalnızca `2.0` desteklenmektedir. +- `method`: ETH API yöntemi. [API referansına bakın.](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc) +- `params`: Yönteme geçirilecek parametrelerin listesi. +- `id`: İsteğinizin ID'si. Bir yanıtın hangi isteğe ait olduğunu takip edebilmeniz için yanıtla birlikte döndürülür. Mevcut gaz fiyatını almak için komut satırından çalıştırabileceğiniz bir örnek: @@ -63,7 +65,7 @@ curl https://eth-mainnet.alchemyapi.io/v2/demo \ -d '{"jsonrpc":"2.0","method":"eth_gasPrice","params":[],"id":73}' ``` -_**NOT:** [https://eth-mainnet.alchemyapi.io/v2/demo](https://eth-mainnet.alchemyapi.io/jsonrpc/demo) bağlantısını kendi API anahtarınızla değiştirin `https://eth-mainnet.alchemyapi.io/v2/**your-api-key`._ +_**NOT:** [https://eth-mainnet.alchemyapi.io/v2/demo](https://eth-mainnet.alchemyapi.io/jsonrpc/demo) adresini kendi API anahtarınızla değiştirin: `https://eth-mainnet.alchemyapi.io/v2/**your-api-key`._ **Sonuçlar:** @@ -71,13 +73,13 @@ _**NOT:** [https://eth-mainnet.alchemyapi.io/v2/demo](https://eth-mainnet.alchem { "id": 73,"jsonrpc": "2.0","result": "0x09184e72a000" // 10000000000000 } ``` -## 4. Web3 İstemcinizi kurun {#set-up-your-web3-client} +## 4. Web3 İstemcinizi Kurun {#set-up-your-web3-client} -**Mevcut bir istemciniz varsa,** API anahtarınızla mevcut düğüm sağlayıcı URL'nizi bir Alchemy URL'si olarak değiştirin: `“https://eth-mainnet.alchemyapi.io/v2/your-api-key"` +**Mevcut bir istemciniz varsa,** mevcut düğüm sağlayıcı URL'nizi API anahtarınızı içeren bir Alchemy URL'siyle değiştirin: `"https://eth-mainnet.alchemyapi.io/v2/your-api-key"` -**_NOT:_** Aşağıdaki komut dosyaları **düğüm bağlamında** çalıştırılmalı veya **bir dosyaya kaydedilmeli**, komut satırından çalıştırılmamalı. Eğer hâlihazırda Node veya npm kurulu değilse, bu hızlı [mac kurulum rehberine](https://app.gitbook.com/@alchemyapi/s/alchemy/guides/alchemy-for-macs) bir göz atın. +**_NOT:_** Aşağıdaki betiklerin, komut satırından değil, bir **düğüm bağlamında** çalıştırılması veya **bir dosyaya kaydedilmesi** gerekir. Eğer Node veya npm zaten kurulu değilse, mac'ler için bu hızlı [kurulum kılavuzuna](https://app.gitbook.com/@alchemyapi/s/alchemy/guides/alchemy-for-macs) göz atın. -Alchemy ile entegre edebileceğiniz tonlarca [Web3 kütüphanesi](https://docs.alchemyapi.io/guides/getting-started#other-web3-libraries) bulunur ancak web3.js'nin yerine bir eklenti olan [Alchemy Web3](https://docs.alchemy.com/reference/api-overview), Alchemy ile sorunsuz çalışacak şekilde oluşturulmuş ve yapılandırılmıştır. Bu, otomatik yeniden denemeler ve güçlü WebSocket desteği gibi birçok avantaj sağlar. +Alchemy ile entegre edebileceğiniz tonlarca [Web3 kütüphanesi](https://docs.alchemyapi.io/guides/getting-started#other-web3-libraries) vardır, ancak biz, web3.js'nin yerine geçen, Alchemy ile sorunsuz çalışacak şekilde oluşturulmuş ve yapılandırılmış olan [Alchemy Web3](https://docs.alchemy.com/reference/api-overview)'ü kullanmanızı öneririz. Bu, otomatik yeniden denemeler ve güçlü WebSocket desteği gibi birçok avantaj sağlar. AlchemyWeb3.js'yi yüklemek için **proje dizininize gidin** ve şunu çalıştırın: @@ -102,11 +104,11 @@ const web3 = createAlchemyWeb3( ) ``` -## 5. İlk Web3 Komut Dosyanızı Yazın! {#write-your-first-web3-script} +## 5. İlk Web3 Betiğinizi Yazın! {#write-your-first-web3-script} -Şimdi web3 programlamasına ufak bir dalış yapmak için Ethereum Mainnet'ten en son blok numarasını yazdıran basit bir komut dosyası yazacağız. +Şimdi web3 programlamasına ufak bir giriş yapmak için Ethereum Ana Ağı'ndan en son blok numarasını yazdıran basit bir betik yazacağız. -**1. Henüz yapmadıysanız, terminalinizde yeni bir proje dizini oluşturun ve içine cd ekleyin:** +**1. Henüz yapmadıysanız, terminalinizde yeni bir proje dizini oluşturun ve `cd` komutuyla o dizine girin:** ``` mkdir web3-example @@ -119,23 +121,23 @@ cd web3-example npm install @alch/alchemy-web3 ``` -**3. `index.js` adlı bir dosya oluşturun ve aşağıdaki içerikleri ekleyin:** +**3. `index.js` adında bir dosya oluşturun ve aşağıdaki içeriği ekleyin:** -> Sonunda `demo`'yu Alchemy HTTP API anahtarınızla değiştirmelisiniz. +> Son olarak `demo`'yu Alchemy HTTP API anahtarınızla değiştirmelisiniz. ```js async function main() { const { createAlchemyWeb3 } = require("@alch/alchemy-web3") const web3 = createAlchemyWeb3("https://eth-mainnet.alchemyapi.io/v2/demo") const blockNumber = await web3.eth.getBlockNumber() - console.log("The latest block number is " + blockNumber) + console.log("En son blok numarası " + blockNumber) } main() ``` -async ile ilgili şeylere aşina değil misiniz? Bu [Medium gönderisine](https://medium.com/better-programming/understanding-async-await-in-javascript-1d81bb079b2c) bir göz atın. +`async` konusuna yabancı mısınız? Bu [Medium gönderisine](https://medium.com/better-programming/understanding-async-await-in-javascript-1d81bb079b2c) göz atın. -**4. Node kullanarak komut satırınızda çalıştırın** +**4. Terminalinizde node kullanarak çalıştırın** ``` node index.js @@ -144,11 +146,11 @@ node index.js **5. Şimdi konsolunuzda en son blok numarası çıktısını görmelisiniz!** ``` -The latest block number is 11043912 +En son blok numarası 11043912 ``` -**Oley! Tebrikler! Alchemy kullanarak ilk web3 komut dosyanızı yazdınız 🎉** +**Harika! Tebrikler! Alchemy'yi kullanarak ilk web3 betiğinizi yazdınız 🎉** -Şimdi ne yapacağınızdan emin değil misiniz? İlk akıllı sözleşmenizi dağıtmayı deneyin ve [Merhaba Dünya Akıllı Sözleşme Kılavuzumuzda](https://docs.alchemyapi.io/tutorials/hello-world-smart-contract) biraz sağlamlık programlamasıyla uğraşın veya [Dashboard Demo App](https://docs.alchemyapi.io/tutorials/demo-app) ile gösterge paneli bilginizi test edin! +Sırada ne yapacağınızdan emin değil misiniz? İlk akıllı sözleşmenizi dağıtmayı deneyin ve [Merhaba Dünya Akıllı Sözleşme Kılavuzumuzda](https://www.alchemy.com/docs/hello-world-smart-contract) biraz Solidity programlamasıyla pratik yapın ya da [Gösterge Paneli Demo Uygulaması](https://docs.alchemyapi.io/tutorials/demo-app) ile gösterge paneli bilginizi test edin! -_[Alchemy'ye ücretsiz kaydolun](https://auth.alchemyapi.io/signup), [belgelerimize](https://docs.alchemyapi.io/) göz atın ve en son haberler için bizi [Twitter](https://twitter.com/AlchemyPlatform) adresinden takip edin_. +_[Alchemy'ye ücretsiz kaydolun](https://auth.alchemy.com/), [dokümanlarımıza](https://www.alchemy.com/docs/) göz atın ve en son haberler için bizi [Twitter](https://twitter.com/AlchemyPlatform)'da takip edin_. diff --git a/public/content/translations/tr/developers/tutorials/guide-to-smart-contract-security-tools/index.md b/public/content/translations/tr/developers/tutorials/guide-to-smart-contract-security-tools/index.md index 64d42058106..14fb1945c31 100644 --- a/public/content/translations/tr/developers/tutorials/guide-to-smart-contract-security-tools/index.md +++ b/public/content/translations/tr/developers/tutorials/guide-to-smart-contract-security-tools/index.md @@ -1,105 +1,102 @@ --- -title: Akıllı sözleşme güvenlik araçlarına yönelik bir kılavuz -description: Üç farklı test ve program analizi tekniğine genel bakış +title: "Akıllı sözleşme güvenlik araçlarına yönelik bir kılavuz" +description: "Üç farklı test ve program analizi tekniğine genel bakış" author: "Trailofbits" lang: tr -tags: - - "solidity" - - "akıllı kontratlar" - - "güvenlik" +tags: [ "katılık", "akıllı kontratlar", "güvenlik" ] skill: intermediate published: 2020-09-07 -source: Güvenli sözleşmeler oluşturmak +source: Building secure contracts sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis --- Üç farklı test ve program analizi tekniği kullanacağız: -- **Slither[ ile statik analiz](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/). **Programın tüm yolları, farklı program sunumları (örn. control-flow-graph) aracılığıyla aynı anda tahmin edilir ve analiz edilir -- **[Echidna](/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/) ile bulandırma.** Kod, işlemlerin sözde rastgele oluşumu ile yürütülür. Bulandırıcı, belirli bir özelliği ihlal etmek için bir dizi işlem bulmaya çalışacaktır. -- **[Manticore](/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/) ile sembolik yürütme.** Her yürütme yolunu matematiksel bir formüle çeviren ve üzerinde en üst kısıtlamaların kontrol edilebileceği resmi bir doğrulama tekniği. +- **[Slither](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/) ile statik analiz.** Programın tüm yolları, farklı program gösterimleri (örn. kontrol akış grafiği) aracılığıyla aynı anda tahmin edilir ve analiz edilir. +- **[Echidna](/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/) ile Bulandırma.** Kod, sahte rastgele işlem üretimi ile yürütülür. Bulandırıcı, belirli bir özelliği ihlal etmek için bir dizi işlem bulmaya çalışacaktır. +- **[Manticore](/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/) ile sembolik yürütme.** Her yürütme yolunu, üzerinde kısıtlamaların kontrol edilebildiği matematiksel bir formüle çeviren resmi bir doğrulama tekniğidir. -Her tekniğin avantajları ve yetersizlikleri vardır ve hepsi [belirli durumlarda](#determining-security-properties) faydalı olacaktır: +Her tekniğin avantajları ve zorlukları vardır ve [belirli durumlarda](#determining-security-properties) faydalı olacaktır: -| Teknik | Araç | Kullanım | Hız | Kaçırılan hatalar | Yanlış Alarmlar | -| ---------------- | --------- | --------------------------------------- | --------- | ----------------- | --------------- | -| Statik Analiz | Slither | CLI ve komut dosyaları | saniyeler | orta seviye | düşük | -| Bulandırma | Echidna | Solidity özellikleri | dakika | düşük | yok | -| Sembolik Yürütme | Manticore | Solidity özellikleri ve komut dosyaları | saat | yok\* | yok | +| Teknik | Araç | Kullanım | Hız | Gözden kaçan hatalar | Yanlış Alarmlar | +| ---------------- | --------- | --------------------------------------- | --------- | -------------------- | --------------- | +| Statik Analiz | Slither | CLI ve komut dosyaları | saniyeler | Orta | Düşük | +| Bulandırma | Echidna | Solidity özellikleri | dakika | Düşük | Yok | +| Sembolik Yürütme | Manticore | Solidity özellikleri ve komut dosyaları | saat | Yok\* | Yok | \* tüm yollar zaman aşımı olmadan araştırılırsa -**Slither**, sözleşmeleri saniyeler içinde analiz eder ancak statik analiz yanlış alarmlara neden olabilir ve karmaşık kontroller (örn. aritmetik kontroller) için daha az uygun olacaktır. Yerleşik algılayıcılara push-button erişimi için API aracılığıyla veya kullanıcı tanımlı kontroller için API aracılığıyla Slither'ı çalıştırın. +**Slither** sözleşmeleri saniyeler içinde analiz eder ancak statik analiz yanlış alarmlara neden olabilir ve karmaşık kontroller (örn. aritmetik kontroller) için daha az uygun olacaktır. Yerleşik algılayıcılara tek tuşla erişim için API aracılığıyla veya kullanıcı tanımlı kontroller için API aracılığıyla Slither'ı çalıştırın. -**Echidna**, birkaç dakika çalışmaya ihtiyaç duyar ve sadece doğru pozitifler üretir. Echidna Solidity'de yazılmış, kullanıcı tarafından sağlanan güvenlik özelliklerini kontrol eder. Rastgele keşfe dayalı olduğu için hataları kaçırabilir. +**Echidna**'nın birkaç dakika çalışması gerekir ve yalnızca doğru pozitifler üretecektir. Echidna, Solidity dilinde yazılmış, kullanıcı tarafından sağlanan güvenlik özelliklerini kontrol eder. Rastgele keşfe dayalı olduğu için hataları gözden kaçırabilir. -**Manticore** "en büyük ağırlık" analizini uygular. Echidna gibi, Manticore da kullanıcı tarafından sağlanan özellikleri doğrular. Çalıştırmak için daha fazla zamana ihtiyacı olacak ancak bir özelliğin geçerliliğini kanıtlayabilir ve yanlış alarmları bildirmez. +**Manticore** "en ağır" analizi gerçekleştirir. Echidna gibi, Manticore da kullanıcı tarafından sağlanan özellikleri doğrular. Çalışması daha fazla zaman alacaktır, ancak bir özelliğin geçerliliğini kanıtlayabilir ve yanlış alarmlar bildirmez. ## Önerilen iş akışı {#suggested-workflow} -Şu anda hiçbir basit hatanın bulunmadığından veya daha sonra tanıtılacağından emin olmak için Slither'ın yerleşik algılayıcılarıyla başlayın. Kalıtım, değişken bağımlılıkları ve yapısal sorunlarla ilgili özellikleri kontrol etmek için Slither'ı kullanın. Kod tabanı büyüdükçe, durum makinesinin daha karmaşık özelliklerini test etmek için Echidna'yı kullanın. Geçersiz kılınan bir fonksiyona karşı koruma gibi, Solidity'de bulunmayan korumalar için özel kontroller geliştirmek için Slither'ı tekrar ziyaret edin. Son olarak, aritmetik işlemler gibi kritik güvenlik özelliklerinin hedefli doğrulamasını gerçekleştirmek için Manticore'u kullanın. +Mevcut veya gelecekte eklenebilecek basit hataların olmadığından emin olmak için Slither'ın yerleşik algılayıcılarıyla başlayın. Kalıtım, değişken bağımlılıkları ve yapısal sorunlarla ilgili özellikleri kontrol etmek için Slither'ı kullanın. Kod tabanı büyüdükçe, durum makinesinin daha karmaşık özelliklerini test etmek için Echidna'yı kullanın. Bir fonksiyonun geçersiz kılınmasına karşı koruma gibi Solidity'de mevcut olmayan korumalar için özel denetimler geliştirmek üzere Slither'a geri dönün. Son olarak, aritmetik işlemler gibi kritik güvenlik özelliklerinin hedeflenmiş doğrulamasını gerçekleştirmek için Manticore'u kullanın. -- Slither'ın CLI'sını yaygın sorunları yakalamak için kullanın +- Sık karşılaşılan sorunları yakalamak için Slither'ın CLI'ını kullanın - Sözleşmenizin üst düzey güvenlik özelliklerini test etmek için Echidna'yı kullanın -- Özel statik kontrolleri yazmak için Slither kullanın +- Özel statik denetimler yazmak için Slither'ı kullanın - Kritik güvenlik özelliklerinin derinlemesine güvencesini istediğinizde Manticore'u kullanın -**Birim testleri üzerine bir not**. Yüksek kaliteli yazılım oluşturmak için birim testleri gereklidir. Ancak, bu teknikler güvenlik açıklarını bulmak için en uygun teknikler değildir. Genellikle kodun olumlu davranışlarını test etmek için kullanılırlar (yani kod normal bağlamda beklendiği gibi çalışır), güvenlik kusurları ise geliştiricilerin dikkate almadığı uç durumlarda bulunma eğilimindedir. Düzinelerce akıllı sözleşme güvenlik incelemesini içeren çalışmamızda [birim test kapsamı, müşterimizin kodunda bulduğumuz güvenlik açıklarının sayısı veya ciddiyeti üzerinde hiçbir etkiye sahip değildi](https://blog.trailofbits.com/2019/08/08/246-findings-from-our-smart-contract-audits-an-executive-summary/). +**Birim testleri üzerine bir not**. Yüksek kaliteli yazılım oluşturmak için birim testleri gereklidir. Ancak bu teknikler, güvenlik kusurlarını bulmak için en uygun olanlar değildir. Bunlar genellikle kodun pozitif davranışlarını test etmek için kullanılır (yani kod normal bağlamda beklendiği gibi çalışır), güvenlik kusurları ise geliştiricilerin dikkate almadığı uç durumlarda bulunma eğilimindedir. Onlarca akıllı sözleşme güvenlik incelemesi üzerine yaptığımız çalışmada, müşterimizin kodunda bulduğumuz [güvenlik kusurlarının sayısı veya ciddiyeti üzerinde birim testi kapsamının hiçbir etkisi olmamıştır](https://blog.trailofbits.com/2019/08/08/246-findings-from-our-smart-contract-audits-an-executive-summary/). -## Güvenlik Özelliklerinin Belirlenmesi {#determining-security-properties} +## Güvenlik Özelliklerini Belirleme {#determining-security-properties} -Kodunuzu etkili bir şekilde test etmek ve doğrulamak için dikkat edilmesi gereken alanları belirlemelisiniz. Güvenlik için harcanan kaynaklarınız sınırlı olduğundan, çabanızı optimize etmek için kod tabanınızın zayıf veya yüksek değerli kısımlarının kapsamını belirlemek önemlidir. Tehdit modelleme yardımcı olabilir. Şunları incelemeyi düşünün: +Kodunuzu etkili bir şekilde test etmek ve doğrulamak için dikkat gerektiren alanları belirlemeniz gerekir. Güvenliğe ayırdığınız kaynaklar sınırlı olduğundan, çabanızı en iyi duruma getirmek için kod tabanınızın zayıf veya değerli kısımlarını belirlemek önemlidir. Tehdit modellemesi yardımcı olabilir. Şunları gözden geçirmeyi düşünün: - [Hızlı Risk Değerlendirmeleri](https://infosec.mozilla.org/guidelines/risk/rapid_risk_assessment.html) (zaman kısıtlı olduğunda tercih ettiğimiz yaklaşım) -- [Veri Merkezli Sistem Tehdit Modelleme Kılavuzu](https://csrc.nist.gov/publications/detail/sp/800-154/draft) (diğer adıyla NIST 800-154) -- [Shostack iş parçacığı modellemesi](https://www.amazon.com/Threat-Modeling-Designing-Adam-Shostack/dp/1118809998) -- [STRIDE]() / [DREAD]() +- [Veri Merkezli Sistem Tehdit Modelleme Rehberi](https://csrc.nist.gov/pubs/sp/800/154/ipd) (diğer adıyla NIST 800-154) +- [Shostack tehdit modellemesi](https://www.amazon.com/Threat-Modeling-Designing-Adam-Shostack/dp/1118809998) +- [STRIDE](https://wikipedia.org/wiki/STRIDE_\(security\)) / [DREAD](https://wikipedia.org/wiki/DREAD_\(risk_assessment_model\)) - [PASTA](https://wikipedia.org/wiki/Threat_model#P.A.S.T.A.) -- [Teyitlerin Kullanımı](https://blog.regehr.org/archives/1091) +- [Onaylamaların Kullanımı](https://blog.regehr.org/archives/1091) ### Bileşenler {#components} -Neyi kontrol etmek istediğinizi bilmek, doğru aracı seçmenize de yardımcı olacaktır. +Neyi denetlemek istediğinizi bilmek, doğru aracı seçmenize de yardımcı olacaktır. -Akıllı sözleşmelerle sıklıkla ilgili olan geniş alanlar şunları içerir: +Akıllı sözleşmeler için sıklıkla geçerli olan geniş alanlar şunları içerir: -- **Durum makinesi.** Çoğu sözleşme bir durum makinesi olarak temsil edilebilir. (1) Hiçbir geçersiz duruma ulaşılıp ulaşılamayacağını, (2) durum, ulaşılabilir olduğu konusunda kesin olup olmadığını ve (3) herhangi bir durumun sözleşmeyi tuzağa düşürüp düşürmediğini kontrol edin. +- **Durum makinesi.** Çoğu sözleşme bir durum makinesi olarak temsil edilebilir. Şunları kontrol etmeyi düşünün: (1) Hiçbir geçersiz duruma ulaşılamayacağı, (2) geçerli bir duruma ulaşılabileceği ve (3) hiçbir durumun sözleşmeyi tuzağa düşürmediği. - - Echidna ve Manticore, durum makinesi özelliklerini test etmek için tercih edilen araçlardır. + - Echidna ve Manticore, durum makinesi belirtimlerini test etmek için tercih edilecek araçlardır. -- **Erişim kontrolleri.** Sisteminizde ayrıcalıklı kullanıcılar varsa (örn. sahip, denetleyiciler vb.), (1) her kullanıcının yalnızca yetkilendirilmiş eylemleri gerçekleştirebildiğinden ve (2) hiçbir kullanıcının daha ayrıcalıklı bir kullanıcının eylemlerini engelleyemediğinden emin olmalısınız. +- **Erişim denetimleri.** Sisteminizde ayrıcalıklı kullanıcılar (ör. bir sahip, denetleyiciler, ...) varsa her kullanıcının yalnızca izin verilen eylemleri gerçekleştirebildiğinden ve (2) hiçbir kullanıcının daha ayrıcalıklı bir kullanıcının eylemlerini engelleyemediğinden emin olmalısınız. - - Slither, Echidna ve Manticore, doğru erişim kontrollerini kontrol edebilir. Örneğin Slither, yalnızca beyaz listeye alınan fonksiyonlarda onlyOwner niteleyicisinin bulunmadığını kontrol edebilir. Echidna ve Manticore, yalnızca sözleşme belirli bir duruma ulaştığında verilen izin gibi daha karmaşık erişim kontrolü için kullanışlıdır. + - Slither, Echidna ve Manticore, erişim denetimlerinin doğruluğunu kontrol edebilir. Örneğin Slither, yalnızca beyaz listeye alınmış işlevlerde `onlyOwner` niteleyicisinin eksik olduğunu kontrol edebilir. Echidna ve Manticore, yalnızca sözleşme belirli bir duruma ulaştığında verilen bir izin gibi daha karmaşık erişim denetimleri için kullanışlıdır. -- **Aritmetik işlemler.** Aritmetik işlemlerin sağlamlığının kontrol edilmesi çok önemlidir. `SafeMath`'i her yerde kullanmak, taşmayı/yetersizlikleri önlemek için iyi bir adımdır ancak yine de yuvarlama sorunları ve sözleşmeyi tuzağa düşüren kusurlar dahil diğer aritmetik kusurları göz önünde bulundurmalısınız. +- **Aritmetik işlemler.** Aritmetik işlemlerin sağlamlığını kontrol etmek kritik öneme sahiptir. Her yerde `SafeMath` kullanmak, taşma/alt taşmayı önlemek için iyi bir adımdır ancak yuvarlama sorunları ve sözleşmeyi tuzağa düşüren kusurlar da dahil olmak üzere diğer aritmetik kusurları yine de göz önünde bulundurmalısınız. - - Manticore en iyi seçimdir. Aritmetik SMT çözücünün kapsamı dışındaysa Echidna kullanılabilir. + - Burada en iyi seçim Manticore'dur. Aritmetik, SMT çözücünün kapsamı dışındaysa Echidna kullanılabilir. -- **Kalıtım doğruluğu.** Solidity sözleşmeleri ağırlıklı olarak çoklu kalıtıma dayalıdır. Bir `super` çağrısının eksik olduğu gölgeleme fonksiyonu ve yanlış yorumlanmış c3 doğrusallaştırma sırası gibi hatalar kolayca ortaya çıkarılabilir. +- **Kalıtım doğruluğu.** Solidity sözleşmeleri büyük ölçüde çoklu kalıtıma dayanır. `super` çağrısı eksik olan bir gölgeleme işlevi ve yanlış yorumlanmış C3 doğrusallaştırma sırası gibi hatalar kolayca yapılabilir. - - Slither, bu sorunların tespit edilmesini sağlayan araçtır. + - Slither bu sorunların tespit edilmesini sağlayan araçtır. -- **Harici etkileşimler.** Sözleşmeler birbirleriyle etkileşime girer ve bazı harici sözleşmelere güvenilmemelidir. Örneğin, sözleşmeniz harici kâhinlere dayalıysa, kullanılan kâhinlerin yarısının tehlikeye girmesi durumunda sözleşme güvende kalacak mı? +- **Harici etkileşimler.** Sözleşmeler birbirleriyle etkileşime girer ve bazı harici sözleşmelere güvenilmemelidir. Örneğin, sözleşmeniz harici kâhinlere dayanıyorsa, mevcut kâhinlerin yarısı tehlikeye atıldığında güvende kalır mı? - - Manticore ve Echidna, sözleşmelerinizle harici etkileşimleri test etmek için en iyi seçimdir. Manticore, harici sözleşmeleri yoklamak için yerleşik bir mekanizmaya sahiptir. + - Manticore ve Echidna, sözleşmelerinizle olan harici etkileşimleri test etmek için en iyi seçimdir. Manticore, harici sözleşmeleri taklit etmek için yerleşik bir mekanizmaya sahiptir. -- **Standart uyum.** Ethereum standartı tasarımlarının (örn. ERC20) geçmişlerinde bir çok hata bulunur. Üzerine inşa ettiğiniz standardın sınırlamalarının farkında olun. +- **Standartlara uygunluk.** Ethereum standartlarının (ör. ERC20) tasarımlarında geçmişten gelen kusurlar vardır. Üzerine inşa ettiğiniz standardın sınırlılıklarının farkında olun. - Slither, Echidna ve Manticore, belirli bir standarttan sapmaları tespit etmenize yardımcı olacaktır. -### Araç seçimi kopya kağıdı {#tool-selection-cheatsheet} +### Araç seçim rehberi {#tool-selection-cheatsheet} -| Bileşen | Araçlar | Örnekler | -| ---------------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Durum makinesi | Echidna, Manticore | | -| Erişim kontrolü | Slither, Echidna, Manticore | [Slither 2. alıştırma](https://github.com/crytic/slither/blob/7f54c8b948c34fb35e1d61adaa1bd568ca733253/docs/src/tutorials/exercise2.md), [Echidna 2. alıştırma](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/exercises/Exercise-2.md) | -| Aritmetik operasyonlar | Manticore, Echidna | [Echidna 1. alıştırma](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/exercises/Exercise-1.md), [Manticore 1.-3. alıştırma](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/exercises) | -| Kalıtım doğruluğu | Slither | [Slither 1. alıştırma](https://github.com/crytic/slither/blob/7f54c8b948c34fb35e1d61adaa1bd568ca733253/docs/src/tutorials/exercise1.md) | -| Harici etkileşimler | Manticore, Echidna | | -| Standart uyum | Slither, Echidna, Manticore | [`slither-erc`](https://github.com/crytic/slither/wiki/ERC-Conformance) | +| Bileşen | Araçlar | Örnekler | +| --------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Durum makinesi | Echidna, Manticore | | +| Erişim denetimi | Slither, Echidna, Manticore | [Slither alıştırma 2](https://github.com/crytic/slither/blob/7f54c8b948c34fb35e1d61adaa1bd568ca733253/docs/src/tutorials/exercise2.md), [Echidna alıştırma 2](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/exercises/Exercise-2.md) | +| Aritmetik işlemler | Manticore, Echidna | [Echidna alıştırma 1](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/exercises/Exercise-1.md), [Manticore alıştırmaları 1 - 3](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/exercises) | +| Kalıtım doğruluğu | Slither | [Slither alıştırma 1](https://github.com/crytic/slither/blob/7f54c8b948c34fb35e1d61adaa1bd568ca733253/docs/src/tutorials/exercise1.md) | +| Harici etkileşimler | Manticore, Echidna | | +| Standartlara uygunluk | Slither, Echidna, Manticore | [`slither-erc`](https://github.com/crytic/slither/wiki/ERC-Conformance) | -Hedeflerinize bağlı olarak diğer alanların kontrol edilmesi gerekecektir, ancak bu kaba taneli odak alanları, herhangi bir akıllı sözleşme sistemi için iyi bir başlangıçtır. +Hedeflerinize bağlı olarak diğer alanların da denetlenmesi gerekecektir, ancak bu genel odak alanları herhangi bir akıllı sözleşme sistemi için iyi bir başlangıçtır. -Herkese açık denetimlerimiz, doğrulanmış veya test edilmiş özelliklerin örneklerini içerir. Gerçek dünyadaki güvenlik özelliklerini incelemek için aşağıdaki raporların `Automated Testing and Verification` bölümlerini okuyun: +Halka açık denetimlerimiz, doğrulanmış veya test edilmiş özelliklerin örneklerini içerir. Gerçek dünyadaki güvenlik özelliklerini gözden geçirmek için aşağıdaki raporların `Otomatik Test ve Doğrulama` bölümlerini okumayı düşünün: - [0x](https://github.com/trailofbits/publications/blob/master/reviews/0x-protocol.pdf) - [Balancer](https://github.com/trailofbits/publications/blob/master/reviews/BalancerCore.pdf) diff --git a/public/content/translations/tr/developers/tutorials/hello-world-smart-contract-fullstack/index.md b/public/content/translations/tr/developers/tutorials/hello-world-smart-contract-fullstack/index.md index 2c82e0bc2a2..7cd432aa499 100644 --- a/public/content/translations/tr/developers/tutorials/hello-world-smart-contract-fullstack/index.md +++ b/public/content/translations/tr/developers/tutorials/hello-world-smart-contract-fullstack/index.md @@ -1,89 +1,92 @@ --- -title: Yeni Başlayanlar İçin Merhaba Dünya Akıllı Sözleşmesi - FullStack -description: Ethereum üzerinde basit bir akıllı sözleşme yazma ve dağıtmaya yönelik giriş seviyesinde öğretici. +title: Hello World Smart Contract for Beginners - Fullstack +description: "Ethereum'da basit bir akıllı sözleşme yazma ve dağıtma üzerine başlangıç seviyesi bir öğretici." author: "nstrike2" tags: - - "solidity" - - "hardhat" - - "alchemy" - - "akıllı sözleşmeler" - - "dağıtma" - - "blok bulucu" - - "ön yüz" - - "İşlemler" + [ + "katılık", + "hardhat", + "alchemy", + "akıllı kontratlar", + "dağıtma", + "block explorer", + "ön uç", + "işlemler" + ] skill: beginner lang: tr published: 2021-10-25 --- -Bu rehber, blokzincir geliştirme konusunda yeniyseniz, nereden başlayacağınızı bilmiyorsanız veya akıllı sözleşmeleri nasıl dağıtacağınızı ya da onlarla nasıl etkileşim kuracağınızı bilmiyorsanız tam size göre. Size, Goerli test ağında [MetaMask](https://metamask.io), [Solidity](https://docs.soliditylang.org/en/v0.8.0/), [Hardhat](https://hardhat.org) ve [Alchemy](https://alchemyapi.io/eth)'yi kullanarak basit bir akıllı sözleşme oluşturmayı ve dağıtmayı öğreteceğiz. +This guide is for you if you are new to blockchain development and don't know where to start or how to deploy and interact with smart contracts. We will walk through creating and deploying a simple, smart contract on the Goerli test network using [MetaMask](https://metamask.io), [Solidity](https://docs.soliditylang.org/en/v0.8.0/), [Hardhat](https://hardhat.org), and [Alchemy](https://alchemy.com/eth). -Bu öğreticiyi tamamlamak için bir Alchemy hesabına ihtiyacınız olacak. [Ücretsiz bir hesap açmak için kaydolun](https://www.alchemy.com/). +You'll need an Alchemy account to complete this tutorial. [Sign up for a free account](https://www.alchemy.com/). -Herhangi bir noktada sorunuz olursa, [Alchemy Discord](https://discord.gg/gWuC7zB)'unu ziyaret etmekten çekinmeyin! +If you have questions at any point, feel free to reach out in the [Alchemy Discord](https://discord.gg/gWuC7zB)! -## 1. Bölüm - Hardhat Kullanarak Akıllı Sözleşmenizi Oluşturma ve Dağıtma {#part-1} +## Part 1 - Create and Deploy your Smart Contract using Hardhat {#part-1} -### Ethereum ağına bağlanın {#connect-to-the-ethereum-network} +### Connect to the Ethereum network {#connect-to-the-ethereum-network} -Ethereum zincirine istek göndermenin birçok yolu vardır. Kolay anlaşılabilmesi için düğümü kendimiz çalıştırmadan Ethereum zinciriyle bağlantı kurabilmemize olanak tanıyan bir blokzincir geliştirme platformu ve API'si olan Alchemy'de açtığımız ücretsiz bir hesabı kullanacağız. Alchemy ayrıca, akıllı sözleşme dağıtımımızda arka planda neler olup bittiğini anlamak için bu öğreticide yararlanacağımız izleme ve analitiğe yönelik geliştirici araçlarına sahiptir. +Ethereum zincirine istek göndermenin birçok yolu vardır. For simplicity, we'll use a free account on Alchemy, a blockchain developer platform and API that allows us to communicate with the Ethereum chain without running a node ourselves. Alchemy also has developer tools for monitoring and analytics; we'll take advantage of these in this tutorial to understand what's going on under the hood in our smart contract deployment. -### Uygulamanızı ve API anahtarınızı oluşturun {#create-your-app-and-api-key} +### Create your app and API key {#create-your-app-and-api-key} -Bir Alchemy hesabı oluşturduktan sonra, bir uygulama yaratarak bir API anahtarı oluşturabilirsiniz. Bu Goerli test ağına taleplerde bulunmanızı sağlayacaktır. Test ağlarıyla ilgili pek bilginiz yoksa [Alchemy'nin ağ seçme rehberini okuyabilirsiniz](https://docs.alchemyapi.io/guides/choosing-a-network). +Once you've created an Alchemy account, you can generate an API key by creating an app. This will allow you to make requests to the Goerli testnet. If you're not familiar with testnets you can [read Alchemy's guide to choosing a network](https://www.alchemy.com/docs/choosing-a-web3-network). -Alchemy'nin sayfasında **Uygulamalar** seçeneğini bulun ve aşağı inip **Uygulama Oluştur**'a tıklayın. +On the Alchemy dashboard, find the **Apps** dropdown in the navigation bar and click **Create App**. ![Merhaba dünya uygulama oluşturma](./hello-world-create-app.png) -Uygulamanıza "_Merhaba Dünya_" ismini verin ve kısa bir açıklama yazın. Ortam olarak **Hazırlama**'yı ve ağ olarak da **Goerli**'yi seçin. +Give your app the name '_Hello World_' and write a short description. Select **Staging** as your environment and **Goerli** as your network. -![merhaba dünya görüntüleme uygulamasını oluşturma](./create-app-view-hello-world.png) +![uygulama oluşturma görünümü merhaba dünya](./create-app-view-hello-world.png) -_Not: **Goerli**'yi seçmezseniz bu öğretici çalışmaz._ +_Note: be sure to select **Goerli**, or this tutorial won't work._ -**Uygulama oluştur**'a tıklayın. Uygulamanız aşağıdaki tabloda görünecektir. +Click **Create app**. Your app will appear in the table below. -### Bir Ethereum hesabı oluşturun {#create-an-ethereum-account} +### Create an Ethereum account {#create-an-ethereum-account} -İşlem göndermek ve almak için bir Ethereum hesabına ihtiyacınız vardır. Kullanıcıların Ethereum hesap adreslerini yönetmelerini sağlayan bir sanal tarayıcı cüzdanı olan MetaMask'i kullanacağız. +You need an Ethereum account to send and receive transactions. We'll use MetaMask, a virtual wallet in the browser that lets users manage their Ethereum account address. -[Buradan](https://metamask.io/download) ücretsiz olarak bir MetaMask hesabı indirebilir ve oluşturabilirsiniz. Bir hesap oluştururken ya da zaten bir hesabınız varsa, sağ üstten "Goerli Test Ağına" geçin (bu sayede gerçek parayla denemeler yapmayız). +MetaMask'ı [buradan](https://metamask.io/download) ücretsiz indirip bir hesap oluşturabilirsiniz. When you are creating an account, or if you already have an account, make sure to switch over to the “Goerli Test Network” in the upper right (so that we’re not dealing with real money). ### Adım 4: Bir Musluktan ether ekleyin {#step-4-add-ether-from-a-faucet} -Akıllı sözleşmenizi test ağına dağıtmak için biraz sahte ETH'ye ihtiyacınız olacak. Goerli ağında ETH alabilmek için bir Goerli musluğuna gidin ve Goerli hesabınızın adresini girin. Goerli musluklarının son zamanlarda biraz güvenilmez olduğunu da dikkate alın; [test ağları sayfası](/developers/docs/networks/#goerli)'ndan denenebilecek seçeneklerin listesine göz atın: +To deploy your smart contract to the test network, you'll need some fake ETH. To get ETH on the Goerli network, go to a Goerli faucet and enter your Goerli account address. Note that Goerli faucets can be a bit unreliable recently - see the [test networks page](/developers/docs/networks/#goerli) for a list of options to try: -_Not: Ağ sıkışıklığı sebebiyle bu biraz zaman alabilir._ `` +_Note: due to network congestion, this might take a while._ +`` -### Adım 5: Bakiyenizi kontrol edin {#step-5-check-your-balance} +### Step 5: Check your Balance {#step-5-check-your-balance} -ETH'nin cüzdanınızda olduğundan emin olmak için [Alchemy'nin derleyici aracını](https://composer.alchemyapi.io/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D) kullanarak bir [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance) isteği oluşturalım. Bu, cüzdanımızdaki ETH miktarını döndürür. Daha fazla bilgi edinmek için [Alchemy'nin derleyici aracını kullanma hakkındaki kısa öğreticisine](https://youtu.be/r6sjRxBZJuU) göz atabilirsiniz. +To double-check the ETH is in your wallet, let’s make an [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance) request using [Alchemy’s composer tool](https://composer.alchemyapi.io/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D). Bu, cüzdanımızdaki ETH miktarını döndürür. To learn more check out [Alchemy's short tutorial on how to use the composer tool](https://youtu.be/r6sjRxBZJuU). -Metamask hesap adresinizi girin ve **İstek Gönder**'e tıklayın. Aşağıdaki ufak kod parçası gibi bir cevap göreceksiniz. +Enter you input your MetaMask account address and click **Send Request**. You will see a response that looks like the code snippet below. ```json { "jsonrpc": "2.0", "id": 0, "result": "0x2B5E3AF16B1880000" } ``` -> _Not: Bu sonuç ETH değil, wei cinsindendir. Wei, ether'ın en küçük birimi olarak kullanılır._ +> _Note: This result is in wei, not ETH. Wei is used as the smallest denomination of ether._ Vay be! Tüm sahte paramız yerli yerinde. -### Adım 6: Projemizi başlatın {#step-6-initialize-our-project} +### Step 6: Initialize our project {#step-6-initialize-our-project} -Önce, projemiz için bir klasör oluşturmamız gerekecek. Komut satırınıza gidin ve aşağıdakini girin. +First, we'll need to create a folder for our project. Navigate to your command line and input the following. ``` 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. +Artık proje klasörümüzün içinde olduğumuza göre projeyi başlatmak için `npm init` komutunu kullanacağız. -> Eğer npm'i hala yüklemediyseniz [Node.js ve npm'i yüklemek için bu talimatları uygulayın](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm). +> If you don’t have npm installed yet, follow [these instructions to install Node.js and npm](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm). -Başlangıç sorularını nasıl cevapladığınız bu öğreticinin amacıyla alakasızdır. Biz referans olarak bu şekilde yaptık: +For the purpose of this tutorial, it doesn't matter how you answer the initialization questions. Here is how we did it for reference: ``` package name: (hello-world) @@ -111,13 +114,13 @@ About to write to /Users/.../.../.../hello-world/package.json: } ``` -package.json'ı onayladıktan sonra hazırız! +package.json dosyasını onaylayın ve artık hazırız! -### 7. Adım: Hardhat'i indirin {#step-7-download-hardhat} +### Step 7: Download Hardhat {#step-7-download-hardhat} 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. Bu geliştiricilere canlı zincirde dağıtmadan önce akıllı sözleşmelerini ve merkeziyetsiz uygulamalarını geliştirirken yardımcı olur. -`hello-world` projemizin içinde şunu yürütün: +`hello-world` projemizin içinde şunu çalıştırın: ``` npm install --save-dev hardhat @@ -125,9 +128,9 @@ npm install --save-dev hardhat [Kurulum talimatları](https://hardhat.org/getting-started/#overview) hakkında daha fazla ayrıntı için bu sayfaya göz atın. -### Adım 8: Hardhat projesi oluşturun {#step-8-create-hardhat-project} +### Step 8: Create Hardhat project {#step-8-create-hardhat-project} -`hello-world` proje klasörümüzde aşağıdaki komutu çalıştırın: +Inside our `hello-world` project folder, run: ``` npx hardhat @@ -153,30 +156,30 @@ Create a sample project Quit ``` -Bu, projenin içinde bir `hardhat.config.js` dosyası oluşturacaktır. Bunu, bu öğreticinin içinde daha sonra projemizin kurulumunu özelleştirmek için kullanacağız. +This will generate a `hardhat.config.js` file in the project. We'll use this later in the tutorial to specify the setup for our project. -### Adım 9: Proje klasörleri ekleyin {#step-9-add-project-folders} +### Step 9: Add project folders {#step-9-add-project-folders} -Bu projeyi düzenli tutmak için iki yeni klasör daha oluşturalım. Komut satırına `hello-world` projenizin kök rehberine gidip şunları yazın: +To keep the project organized, let's create two new folders. In the command line, navigate to the root directory of your `hello-world` project and type: ``` mkdir contracts mkdir scripts ``` -- `contracts/` merhaba dünya akıllı sözleşme kod dosyamızı tutacağımız yerdir -- `scripts/`, sözleşmemizi dağıtmak ve etkileşim kurmak için komut dosyalarını tutacağımız yerdir +- `contracts/`, merhaba dünya akıllı sözleşme kodu dosyamızı tutacağımız yerdir +- `scripts/`, sözleşmemizi dağıtmak ve onunla etkileşim kurmak için komut dosyalarını tutacağımız yerdir -### Adım 10: Sözleşmemizi yazın {#step-10-write-our-contract} +### Step 10: Write our contract {#step-10-write-our-contract} -Kendinize, ne zaman kod yazmaya başlayacağız diye mi soruyorsunuz? İşte o vakit geldi! +You might be asking yourself, when are we going to write code? It's time! -En sevdiğiniz düzenleyicide hello-world projenizi açın. Akıllı sözleşmeler genelde Solidity'de yazılır, biz de akıllı sözleşmemizi yazmak için onu kullanacağız. +Open up the hello-world project in your favorite editor. Smart contracts most commonly are written in Solidity, which we will use to write our smart contract.‌ -1. `contracts` klasörüne gidin ve `HelloWorld.sol` adında bir dosya oluşturun -2. Aşağıda bu öğreticide kullanacağımız örnek bir Hello World akıllı sözleşmesi var. Aşağıdaki içerikleri `HelloWorld.sol` dosyasına kopyalayın. +1. Navigate to the `contracts` folder and create a new file called `HelloWorld.sol` +2. Below is a sample Hello World smart contract that we will be using for this tutorial. Copy the contents below into the `HelloWorld.sol` file. -_Not: Bu sözleşmenin ne yaptığını anlayabilmek için yorumları okuduğunuzdan emin olun._ +_Note: Be sure to read the comments to understand what this contract does._ ``` // Specifies the version of Solidity, using semantic versioning. @@ -212,15 +215,15 @@ contract HelloWorld { } ``` -Bu, oluşturma aşaması tamamlandığında bir mesaj depolayan temel bir akıllı sözleşmedir. `update` fonksiyonunu kullanarak bu akıllı sözleşmeyi güncelleyebiliriz. +This is a basic smart contract that stores a message upon creation. It can be updated by calling the `update` function. -### Adım 11: MetaMask ve Alchemy'i projenize bağlayın {#step-11-connect-metamask-alchemy-to-your-project} +### Step 11: Connect MetaMask & Alchemy to your project {#step-11-connect-metamask-alchemy-to-your-project} -Bir MetaMask cüzdanı ile Alchemy hesabı oluşturduk ve akıllı sözleşmemizi yazdık, şimdi üçünü birleştirme zamanı. +Bir MetaMask cüzdanı ve 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 kendi benzersiz özel anahtarınızı kullanan bir imzaya ihtiyaç duyar. Programımıza bu izni sağlamak için özel anahtarımızı bir ortam dosyasında güvenle saklayabiliriz. Ayrıca burada, Alchemy için bir API anahtarı da depolayacağız. +Every transaction sent from your wallet requires a signature using your unique private key. To provide our program with this permission, we can safely store our private key in an environment file. We will also store an API key for Alchemy here. -> İşlem gönderme hakkında daha fazla bilgi edinmek için web3 kullanarak işlem gönderme ile ilgili [bu öğreticiye](https://docs.alchemyapi.io/alchemy/tutorials/sending-transactions-using-web3-and-alchemy) göz atın. +> To learn more about sending transactions, check out [this tutorial](https://www.alchemy.com/docs/hello-world-smart-contract#step-11-connect-metamask--alchemy-to-your-project) on sending transactions using web3. İlk önce dotenv paketini proje dizininize kurun: @@ -228,14 +231,14 @@ Cüzdanınızdan gönderilen her işlem kendi benzersiz özel anahtarınızı ku npm install dotenv --save ``` -Sonra, projenin kök rehberinde bir `.env` dosyası oluşturun. MetaMask özel anahtarınızı ve HTTP Alchemy API URL'nizi bu dosyaya ekleyin. +Then, create a `.env` file in the root directory of the project. Add your MetaMask private key and HTTP Alchemy API URL to it. -Ortam dosyanızın adı `.env` olmak zorundadır, aksi takdirde ortam dosyası olarak tanınmaz. +Your environment file must be named `.env` or it won't be recognized as an environment file. -Dosyanıza `process.env`, `.env-custom` ya da başka bir isim vermeyin. +Do not name it `process.env` or `.env-custom` or anything else. -- Özel anahtarınızı almak için [şu talimatları](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key) takip edin -- HTTP Alchemy API URL'sini almak için aşağıya göz atın +- Follow [these instructions](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key) to export your private key +- HTTP Alchemy API URL'sini almak için aşağıya bakın ![](./get-alchemy-api-key.gif) @@ -246,13 +249,13 @@ API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key" PRIVATE_KEY = "your-metamask-private-key" ``` -Bunları kodumuza gerçekten bağlamak için, adım 13'te `hardhat.config.js` dosyamızda bu değişkenlere başvuracağız. +Bunları gerçekten kodumuza bağlamak için 13. adımda `hardhat.config.js` dosyamızdaki bu değişkenlere başvuracağız. -### Adım 12: Ethers.js'yi kurun {#step-12-install-ethersjs} +### Adım 12: Ethers.js'i Yükleyin {#step-12-install-ethersjs} -Ethers.js, [standart JSON-RPC yöntemlerini](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc) daha kullanıcı dostu yöntemlerle birleştirerek Ethereum'la etkileşimde bulunmayı ve Ethereum'a istek göndermeyi kolaylaştıran bir kütüphanedir. +Ethers.js is a library that makes it easier to interact and make requests to Ethereum by wrapping [standard JSON-RPC methods](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc) with more user friendly methods. -Hardhat, ek araçlar ve daha fazla işlevsellik için [eklentiler](https://hardhat.org/plugins/) kullanmamıza olanak tanır. Sözleşme dağıtımı için [Ethers eklentisinden](https://hardhat.org/docs/plugins/official-plugins#hardhat-ethers) yararlanacağız. +Hardhat allows us to integrate [plugins](https://hardhat.org/plugins/) for additional tooling and extended functionality. We’ll be taking advantage of the [Ethers plugin](https://hardhat.org/docs/plugins/official-plugins#hardhat-ethers) for contract deployment. Proje klasörünüzde şunu yazın: @@ -260,11 +263,11 @@ Proje klasörünüzde şunu yazın: npm install --save-dev @nomiclabs/hardhat-ethers "ethers@^5.0.0" ``` -### Adım 13: hardhat.config.js'yi güncelleyin {#step-13-update-hardhat-configjs} +### Step 13: Update hardhat.config.js {#step-13-update-hardhat-configjs} -Şimdiye kadar birkaç bağımlılık ve eklenti ekledik, şimdi projemizin bunların hepsini tanıması için `hardhat.config.js`'yi güncellememiz gerekiyor. +Şimdiye kadar birkaç bağımlılık ve eklenti ekledik, şimdi projemizin hepsini tanıması için `hardhat.config.js` dosyasını güncellememiz gerekiyor. -`hardhat.config.js` dosyanızı şöyle görünecek şekilde güncelleyin: +`hardhat.config.js` dosyanızı aşağıdaki gibi görünecek şekilde güncelleyin: ```javascript /** @@ -289,9 +292,9 @@ module.exports = { } ``` -### Adım 14: Sözleşmemizi derleyin {#step-14-compile-our-contract} +### Step 14: Compile our contract {#step-14-compile-our-contract} -Şimdiye kadar yaptığımız her şeyin çalıştığından emin olmak için sözleşmemizi derleyelim. `compile` görevi, yerleşik hardhat görevlerden biridir. +Şimdiye kadar yaptığımız 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 yürütün: @@ -299,13 +302,13 @@ Komut satırından şunu yürütün: npx hardhat compile ``` -`SPDX license identifier not provided in source file` uyarısı alabilirsiniz, ancak bunun için endişelenmenize gerek yok, geri kalan her şey düzgün olacaktır! Düzgün değilse, istediğiniz zaman [Alchemy discord](https://discord.gg/u72VCg3)'da mesaj gönderebilirsiniz. +You might get a warning about `SPDX license identifier not provided in source file`, but no need to worry about that — hopefully everything else looks good! Sorun yaşarsanız [Alchemy Discord](https://discord.gg/u72VCg3) üzerinden her zaman mesaj atabilirsiniz. -### Adım 15: Dağıtım komut dosyamızı yazın {#step-15-write-our-deploy-script} +### Step 15: Write our deploy script {#step-15-write-our-deploy-script} Artık sözleşmemiz yazıldığına ve yapılandırma dosyamız kullanıma hazır olduğuna göre, sözleşme dağıtım komut dosyanızı yazmanın zamanı geldi. -`scripts/` klasörüne gidin ve aşağıdaki içeriği ekleyerek `deploy.js` adlı yeni bir dosya oluşturun: +`scripts/` klasörüne gidin ve `deploy.js` adında yeni bir dosya oluşturup içine aşağıdaki içeriği ekleyin: ```javascript async function main() { @@ -324,23 +327,23 @@ main() }) ``` -Hardhat, bu kod satırlarının her birinin ne işe yaradığını [Sözleşme öğreticisinde](https://hardhat.org/tutorial/testing-contracts.html#writing-tests) harika bir şekilde açıklıyor, Hardhat açıklamalarını buraya aktardık. +Hardhat, [Sözleşmeler öğreticisinde](https://hardhat.org/tutorial/testing-contracts.html#writing-tests) bu kod satırlarının her birinin ne işe yaradığını harika bir şekilde açıklıyor, biz de buraya onların açıklamalarını aldık. ```javascript 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 `HelloWorld`, merhaba dünya sözleşmemizin örnekleri için bir [fabrika]()'dır. `hardhat-ethers` eklentisini kullanırken `ContractFactory` ve `Contract` örnekleri varsayılan olarak ilk imzalayana (sahip) bağlanır. +A `ContractFactory` in ethers.js is an abstraction used to deploy new smart contracts, so `HelloWorld` here is a [factory](https://en.wikipedia.org/wiki/Factory_\(object-oriented_programming\)) for instances of our hello world contract. When using the `hardhat-ethers` plugin `ContractFactory` and `Contract`, instances are connected to the first signer (owner) by default. ```javascript const hello_world = await HelloWorld.deploy() ``` -Bir `ContractFactory` üzerinde `deploy()` öğesinin çağrılması, dağıtımı başlatır ve `Contract` nesnesi olarak çözümlenen bir `Promise` döndürür. Bu, akıllı sözleşme fonksiyonlarımızın her biri için bir yöntemi olan nesnedir. +Calling `deploy()` on a `ContractFactory` will start the deployment, and return a `Promise` that resolves to a `Contract` object. Bu, akıllı sözleşme fonksiyonlarımızın her biri için bir yöntemi olan nesnedir. ### Adım 16: Sözleşmemizi dağıtın {#step-16-deploy-our-contract} -Sonunda akıllı sözleşmemizi uygulamaya hazırız! Komut satırına gidin ve şunu yürütün: +Sonunda akıllı sözleşmemizi uygulamaya hazırız! Komut satırına gidin ve şunu çalıştırın: ```bash npx hardhat run scripts/deploy.js --network goerli @@ -349,36 +352,36 @@ npx hardhat run scripts/deploy.js --network goerli Daha sonra şöyle bir şey görmelisiniz: ```bash -Contract deployed to address: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570 +Sözleşme şu adrese dağıtıldı: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570 ``` -**Bu adresi lütfen kaydedin**. Öğreticide daha sonra kullanacağız. +**Please save this address**. We will be using it later in the tutorial. -[Goerli etherscan](https://goerli.etherscan.io)'e gider ve sözleşme adresimizi aratırsak başarıyla dağıtılmış olduğunu görürüz. İşlem şunun gibi gözükecektir: +If we go to the [Goerli etherscan](https://goerli.etherscan.io) and search for our contract address we should able to see that it has been deployed successfully. İşlem şunun gibi gözükecektir: ![](./etherscan-contract.png) -`From` adresi MetaMask hesap adresinizle eşleşmelidir ve `To` adresi **Sözleşme Oluşturma** ifadesini barındıracaktır. İşleme tıklarsak `To` alanında sözleşme adresimizi görürüz. +The `From` address should match your MetaMask account address and the `To` address will say **Contract Creation**. If we click into the transaction we’ll see our contract address in the `To` field. ![](./etherscan-transaction.png) -Tebrikler! Az önce Ethereum test ağına bir akıllı sözleşme dağıttınız. +Tebrikler! You just deployed a smart contract to an Ethereum testnet. -Perde arkasında neler olduğunu anlamak için [Alchemy gösterge panelimizde](https://dashboard.alchemyapi.io/explorer) Explorer (Gezgin) sekmesine gidelim. Birden fazla Alchemy uygulamanız varsa, uygulamaya göre filtreleme yaptığınızdan ve **Merhaba Dünya**'yı seçtiğinizden emin olun. +To understand what’s going on under the hood, let’s navigate to the Explorer tab in our [Alchemy dashboard](https://dashboard.alchemy.com/explorer). If you have multiple Alchemy apps make sure to filter by app and select **Hello World**. ![](./hello-world-explorer.png) -Burada, `.deploy()` fonksiyonunu çağırdığımızda Hardhat/Ethers'ın bizim için arka planda oluşturduğu bir avuç JSON-RPC yöntemini göreceksiniz. Buradaki iki önemli yöntem, akıllı sözleşmemizi Goerli zincirine yazma isteği olan [`eth_sendRawTransaction`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_sendrawtransaction) ve karma değerine göre işlemimiz hakkındaki bilgileri okuma isteği olan [`eth_getTransactionByHash`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_gettransactionbyhash) öğeleridir. İşlem gönderme hakkında daha fazla bilgi edinmek için [Web3 kullanarak işlem göndermeyle ilgili öğreticimize](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) göz atın. +Here you’ll see a handful of JSON-RPC methods that Hardhat/Ethers made under the hood for us when we called the `.deploy()` function. Two important methods here are [`eth_sendRawTransaction`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_sendrawtransaction), which is the request to write our contract onto the Goerli chain, and [`eth_getTransactionByHash`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_gettransactionbyhash), which is a request to read information about our transaction given the hash. To learn more about sending transactions, check out [our tutorial on sending transactions using Web3](/developers/tutorials/sending-transactions-using-web3-and-alchemy/). -## 2. Bölüm: Akıllı Sözleşmenizle etkileşime geçin {#part-2-interact-with-your-smart-contract} +## Part 2: Interact with your Smart Contract {#part-2-interact-with-your-smart-contract} -Akıllı sözleşmemizi Goerli ağına başarılı bir şekilde dağıttığımıza göre, artık sözleşmeyle nasıl etkileşim kuracağımızı öğrenebiliriz. +Now that we've successfully deployed a smart contract to the Goerli network let's learn how to interact with it. -### Bir interact.js dosyası oluşturun {#create-a-interactjs-file} +### Create a interact.js file {#create-a-interactjs-file} -Bu etkileşim komut dosyamızı yazacağımız dosyadır. Burada, daha önce 1.Bölüm'de yüklemiş olduğunuz Ethers.js kütüphanesini kullancağız. +This is the file where we'll write our interaction script. We'll be using the Ethers.js library that you previously installed in Part 1. -`scripts/` dosyasının içinde `interact.js` adında yeni bir dosya oluşturun ve aşağıdaki kodu ekleyin: +Inside the `scripts/`folder, create a new file named `interact.js` add the following code: ```javascript // interact.js @@ -388,13 +391,13 @@ const PRIVATE_KEY = process.env.PRIVATE_KEY const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS ``` -### .env dosyanızı güncelleyin {#update-your-env-file} +### Update your .env file {#update-your-env-file} -Yeni ortam değişkenleri kullanacağımız için bu değişkenleri [daha önce oluşturduğumuz](#step-11-connect-metamask-&-alchemy-to-your-project) `.env` dosyasında tanımlayacağız. +We will be using new environment variables, so we need to define them in the `.env`file that [we created earlier](#step-11-connect-metamask-&-alchemy-to-your-project). -Alchemy `API_KEY`'imiz ve akıllı sözleşmenizin dağıtıldığı yer olan `CONTRACT_ADDRESS` için bir tanım eklememiz gerekecektir. +We'll need to add a definition for our Alchemy `API_KEY` and the `CONTRACT_ADDRESS` where your smart contract was deployed. -`.env` aşağıdaki gibi görünmelidir: +Your `.env` file should look something like this: ```bash # .env @@ -405,36 +408,36 @@ PRIVATE_KEY = "" CONTRACT_ADDRESS = "0x" ``` -### Sözleşme ABI'nizi alın {#grab-your-contract-ABI} +### Grab your contract ABI {#grab-your-contract-ABI} -Sözleşme [ABI 'miz (Uygulama İkili Arayüzü)](/glossary/#abi), akıllı sözleşmemizle etkileşim kurmak için kullanılan arayüzdür. Hardhat otomatik olarak bir ABI oluşturur ve `HelloWorld.json`'un içine kaydeder. ABI'yi kullanmak için `interact.js` dosyamıza aşağıdaki kod satırlarını ekleyerek içeriği ayrıştırmamız gerekir: +Our contract [ABI (Application Binary Interface)](/glossary/#abi) is the interface to interact with our smart contract. Hardhat automatically generates an ABI and saves it in `HelloWorld.json`. To use the ABI, we'll need to parse out the contents by adding the following lines of code to our `interact.js` file: ```javascript // interact.js const contract = require("../artifacts/contracts/HelloWorld.sol/HelloWorld.json") ``` -ABI'yi görmek istiyorsanız onu konsolunuza yazdırabilirsiniz: +ABI'yi görmek isterseniz konsolunuza yazdırabilirsiniz: ```javascript 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: +To see your ABI printed to the console, navigate to your terminal and run: ```bash npx hardhat run scripts/interact.js ``` -### Sözleşmenizin bir örneğini oluşturun {#create-an-instance-of-your-contract} +### Create an instance of your contract {#create-an-instance-of-your-contract} -Sözleşmenizle etkileşim kurmak için kodumuzda bir sözleşme örneği oluşturmamız gerekir. Bunu Ethers.js ile yapmak için üç konseptle çalışacağız: +To interact with our contract, we need to create a contract instance in our code. To do so with Ethers.js, we'll need to work with three concepts: -1. Sağlayıcı - size blockzincir için okuma ve yazma erişimi veren bir düğüm sağlayıcısıdır -2. İmzalayıcı - işlem imzalayabilen bir Ethereum hesabını gösterir -3. Sözleşme - zincir üstünde dağıtılmış olan spesifik bir sözleşmeyi temsil eden bir Ethers.js objesidir +1. Provider - a node provider that gives you read and write access to the blockchain +2. Signer - represents an Ethereum account that can sign transactions +3. Contract - an Ethers.js object representing a specific contract deployed onchain -Sözleşme örneğimizi oluşturmak için önceki adımdaki sözleşme ABI'mizi kullanacağız: +We'll use the contract ABI from the previous step to create our instance of the contract: ```javascript // interact.js @@ -456,15 +459,15 @@ const helloWorldContract = new ethers.Contract( ) ``` -Sağlayıcı, İmzalayıcı ve Sözleşmelerle ilgili [ethers.js dokümanlarından](https://docs.ethers.io/v5/) daha fazla bilgi edinebilirsiniz. +Learn more about Providers, Signers, and Contracts in the [ethers.js documentation](https://docs.ethers.io/v5/). -### Başlangıç mesajını okuyun {#read-the-init-message} +### Read the init message {#read-the-init-message} -Sözleşmemizi `initMessage = "Hello world!"` ile dağıttığımızı hatırlıyor musunuz? Şimdi akıllı sözleşmemizde depolanmış olan bu mesajı okuyacağız ve konsola yazdıracağız. +Remember when we deployed our contract with the `initMessage = "Hello world!"`? We are now going to read that message stored in our smart contract and print it to the console. -JavaScript'te ağlarla etkileşim kurulurken asenkronize fonksiyonlar kullanılır. Asenkronize fonksiyonlarla ilgili daha fazla bilgi edinmek için [bu medium makalesini okuyun](https://blog.bitsrc.io/understanding-asynchronous-javascript-the-event-loop-74cd408419ff). +In JavaScript, asynchronous functions get used when interacting with networks. To learn more about asynchronous functions, [read this medium article](https://blog.bitsrc.io/understanding-asynchronous-javascript-the-event-loop-74cd408419ff). -Akıllı sözleşmemizdeki `message` fonksiyonunu çağırmak için aşağıdaki kodu kullanın ve başlangıç mesajını okuyun: +Use the code below to call the `message` function in our smart contract and read the init message: ```javascript // interact.js @@ -478,19 +481,19 @@ async function main() { main() ``` -Dosyayı terminaldeki `npx hardhat run scripts/interact.js` öğesini kullanarak çalıştırdıktan sonra şu yanıtı görmeliyiz: +After running the file using `npx hardhat run scripts/interact.js` in the terminal we should see this response: ``` The message is: Hello world! ``` -Tebrikler! Az önce Ethereum blokzincirinden başarıyla bir akıllı sözleşme verisi okudunuz, bravo! +Tebrikler! You've just successfully read smart contract data from the Ethereum blockchain, way to go! -### Mesajı güncelleyin {#update-the-message} +### Update the message {#update-the-message} -Sadece mesajı okumak yerine, `update` fonksiyonunu kullanarak akıllı sözleşmemizde kayıtlı olan mesajı güncelleyebiliriz! Oldukça havalı, değil mi? +Instead of just reading the message, we can also update the message saved in our smart contract using the `update` function! Pretty cool, right? -Bu mesajı güncellemek için somutlaşmış sözleşme nesnemizde doğrudan `update` fonksiyonunu çağırabiliriz: +To update the message, we can directly call the `update` function on our instantiated Contract object: ```javascript // interact.js @@ -508,13 +511,13 @@ async function main() { main() ``` -11. satırda dönen işlem nesnesi için `.wait()` çağrısını yaptığımızı not alın. Bunu yapmak, komut dosyamızın fonksiyondan çıkmadan önce işlemin blokzincirde basılmasını beklediğinden emin olmamızı sağlar. Eğer `.wait()` çağrısı dahil edilmemişse komut dosyası, sözleşmedeki güncellenmiş `message` değerini görmeyebilir. +Note that on line 11, we make a call to `.wait()` on the returned transaction object. This ensures that our script waits for the transaction to get mined on the blockchain before exiting the function. If the `.wait()` call isn't included, the script may not see the updated `message` value in the contract. -### Yeni mesajı okuyun {#read-the-new-message} +### Read the new message {#read-the-new-message} -Güncellenmiş `message` değerini okumak için [önceki adımı](#read-the-init-message) tekrar edebilmelisiniz. Bir saniye durun ve yeni değeri yazdırabilmek için gerekli değişiklikleri yapıp yapamadığınıza bakın! +You should be able to repeat the [previous step](#read-the-init-message) to read the updated `message` value. Take a moment and see if you can make the changes necessary to print out that new value! -Eğer ipucuna ihtiyacınız varsa, bu noktada `interact.js` dosyanız bu şekilde görünmelidir: +If you need a hint, here's what your `interact.js` file should look like at this point: ```javascript // interact.js @@ -556,7 +559,7 @@ async function main() { main() ``` -Şimdi sadece komut dosyasını çalıştırın; eski mesajı, güncelleme durumunu ve yeni mesajı terminalinizde yazdırılmış şekilde görebilmelisiniz! +Now just run the script and you should be able to see the old message, the updating status, and the new message printed out to your terminal! `npx hardhat run scripts/interact.js --network goerli` @@ -566,29 +569,29 @@ Updating the message... The new message is: This is the new message. ``` -Komut dosyasını çalıştırırken, yeni mesaj yüklenmeden önce `Updating the message...` adımının biraz uzun sürdüğünü fark edebilirsiniz. Bunun sebebi madencilik sürecidir; işlemleri çıkarılırken takip etme konusunda meraklıysanız işlemin durumunu görüntülemek için [Alchemy bellek havuzunu](https://dashboard.alchemyapi.io/mempool) ziyaret edebilirsiniz. İşlem düştüyse, [Goerli Etherscan](https://goerli.etherscan.io)'i kontrol etmek ve işlem karmanızı aramak da faydalı olur. +While running that script, you may notice that the `Updating the message...` step takes a while to load before the new message loads. That is due to the mining process; if you are curious about tracking transactions while they are being mined, visit the [Alchemy mempool](https://dashboard.alchemyapi.io/mempool) to see the status of a transaction. If the transaction is dropped, it's also helpful to check [Goerli Etherscan](https://goerli.etherscan.io) and search for your transaction hash. -## 3. Bölüm: Akıllı Sözleşmenizi Etherscan'de yayımlayın {#part-3-publish-your-smart-contract-to-etherscan} +## Part 3: Publish your Smart Contract to Etherscan {#part-3-publish-your-smart-contract-to-etherscan} -Akıllı sözleşmenizi hayata geçirmek için tüm zor işleri hallettiniz, şimdi bunu dünyayla paylaşma zamanı! +You did all the hard work of bringing your smart contract to life; now it's time to share it with the world! -Akıllı sözleşmenizi Etherscan'de doğruladığınızda, herkes kaynak kodunuzu görebilir ve akıllı sözleşmenizle etkileşim kurabilir. Haydi başlayalım! +By verifying your smart contract on Etherscan, anyone can view your source code and interact with your smart contract. Let's get started! -### 1. Adım: Etherscan hesabınızda bir API anahtarı oluşturun {#step-1-generate-an-api-key-on-your-etherscan-account} +### Step 1: Generate an API Key on your Etherscan account {#step-1-generate-an-api-key-on-your-etherscan-account} -Etherscan API anahtarı paylaşmaya çalıştığınız akıllı sözleşmenin sahibinin siz olduğunu onaylamak için gereklidir. +An Etherscan API Key is necessary to verify that you own the smart contract you are trying to publish. -Eğer hala bir Etherscan hesabınız yoksa [hesap oluşturmak için kaydolun](https://etherscan.io/register). +If you don't have an Etherscan account already, [sign up for an account](https://etherscan.io/register). -Hesaba girdiğinizde, gezinti çubuğunda kullanıcı adınızı bulun, imleci üstüne getirin ve **Profilim** butonuna tıklayın. +Once logged in, find your username in the navigation bar, hover over it and select the **My profile** button. -Profil sayfanızda, bir yan gezinti çubuğu görmelisiniz. Yan gezinti çubuğundan **API Anahtarları**'nı seçin. Sonra, yeni bir API anahtarı oluşturmak için "Ekle" butonuna tıklayın, uygulamanıza **hello-world** adını verin ve **Yeni API Anahtarı Oluştur** butonuna tıklayın. +On your profile page, you should see a side navigation bar. From the side navigation bar, select **API Keys**. Next, press the "Add" button to create a new API key, name your app **hello-world**and press the **Create New API Key** button. -Yeni API anahtarınız API anahtar tablosunda görünüyor olmalıdır. API anahtarını panonuza kopyalayın. +Your new API key should appear in the API key table. Copy the API key to your clipboard. -Şimdi, `.env` dosyamıza Etherscan API anahtarını eklemeliyiz. +Next, we need to add the Etherscan API key to our `.env` file. -Ekledikten sonra, `.env` dosyanız şu şekilde görünmelidir: +After adding it, your `.env`file should look like this: ```javascript API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key" @@ -598,17 +601,17 @@ CONTRACT_ADDRESS = "your-contract-address" ETHERSCAN_API_KEY = "your-etherscan-key" ``` -### Hardhat dağıtılmış akıllı sözleşmeler {#hardhat-deployed-smart-contracts} +### Hardhat-deployed smart contracts {#hardhat-deployed-smart-contracts} -#### Hardhat-etherscan'i yükleme {#install-hardhat-etherscan} +#### Install hardhat-etherscan {#install-hardhat-etherscan} -Sözleşmenizi Hardhat kullanarak Etherscan'de yayımlamak basittir. Başlamak için öncelikle `hardhat-etherscan` eklentisini yüklemeniz gerekir. `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` rehberinizde şunu çalıştırın: +Publishing your contract to Etherscan using Hardhat is straightforward. You will first need to install the `hardhat-etherscan` plugin to get started. `hardhat-etherscan` will automatically verify the smart contract's source code and ABI on Etherscan. To add this, in the `hello-world` directory run: ```text npm install --save-dev @nomiclabs/hardhat-etherscan ``` -Yüklendiğinde, aşağıdaki ifadeyi `hardhat.config.js`'nizin en üstüne dahil edin ve Etherscan yapılandırma seçeneklerini ekleyin: +Once installed, include the following statement at the top of your `hardhat.config.js`, and add the Etherscan config options: ```javascript // hardhat.config.js @@ -637,19 +640,19 @@ module.exports = { } ``` -#### Akıllı Sözleşmenizi Etherscan üzerinden doğrulama {#verify-your-smart-contract-on-etherscan} +#### Verify your smart contract on Etherscan {#verify-your-smart-contract-on-etherscan} -Tüm dosyaların kaydedildiğinden ve tüm değişkenlerin `.env` doğru şekilde yapılandırıldığından emin olun. +Ensure all files are saved and all `.env` variables are correctly configured. -`verify` görevini çalıştırarak sözleşme adresinizi ve ağınızı dağıtıldığı konuma aktarın: +Run the `verify` task, passing the contract address, and the network to where it's deployed: ```text npx hardhat verify --network goerli DEPLOYED_CONTRACT_ADDRESS 'Hello World!' ``` -`DEPLOYED_CONTRACT_ADDRESS` adresinin Goerli test ağında dağıtılan akıllı sözleşmenizin adresi olduğundan emin olun. Ayrıca son bağımsız değişken olan (`'Hello World!'`), 1. Bölüm'de dağıtım aşamasında kullanılan dizi değeriyle [ aynı olmak zorundadır](#write-our-deploy-script). +Make sure that `DEPLOYED_CONTRACT_ADDRESS` is the address of your deployed smart contract on the Goerli test network. Also, the final argument (`'Hello World!'`) must be the same string value used [during the deploy step in part 1](#write-our-deploy-script). -Eğer her şey yolunda gittiyse, terminalinizde aşağıdaki mesajı göreceksiniz: +If all goes well, you will see the following message in your terminal: ```text Successfully submitted source code for contract @@ -661,48 +664,48 @@ Successfully verified contract HelloWorld on Etherscan. https://goerli.etherscan.io/address/#contracts ``` -Tebrikler! Akıllı sözleşmeniz artık Etherscan'de! +Tebrikler! Your smart contract code is on Etherscan! -### Akıllı sözleşmenize Etherscan'de göz atın! {#check-out-your-smart-contract-on-etherscan} +### Check out your smart contract on Etherscan! {#check-out-your-smart-contract-on-etherscan} -Terminalinizde sağlanan bağlantıya gittiğinizde, akıllı sözleşme kodunuzun ve ABI'nizin Etherscan'de yayımlandığını göreceksiniz! +When you navigate to the link provided in your terminal, you should be able to see your smart contract code and ABI published on Etherscan! -**Bravo, başardınız! Artık herkes akıllı sözleşmenize yazabilir ya da onu çağırabilir! Bir dahaki sefere ne geliştireceğinizi görmek için sabırsızlanıyoruz!** +**Wahooo - you did it champ! Now anyone can call or write to your smart contract! We can't wait to see what you build next!** -## 4. Bölüm - Akıllı sözleşmenizi ön yüzle entegre etme {#part-4-integrating-your-smart-contract-with-the-frontend} +## Part 4 - Integrating your smart contract with the frontend {#part-4-integrating-your-smart-contract-with-the-frontend} -Bu öğreticinin sonuna geldiğinize, şunları nasıl yapacağınızı biliyor olacaksınız: +By the end of this tutorial, you'll know how to: -- Merkeziyetsiz uygulamanıza bir MetaMask cüzdanı bağlamak -- [Alchemy Web3](https://docs.alchemy.com/alchemy/documentation/alchemy-web3) API'sini kullanarak akıllı sözleşmenizden veri okumak -- MetaMask kullanarak Ethereum işlemlerini imzalamak +- Connect a MetaMask wallet to your dapp +- Read data from your smart contract using the [Alchemy Web3](https://docs.alchemy.com/alchemy/documentation/alchemy-web3) API +- Sign Ethereum transactions using MetaMask -Bu merkeziyetsiz uygulama için ön yüz çerçevemiz olarak [React](https://reactjs.org/)'i kullanacağız, fakat genel olarak projemize Web3 işlevselliğini getirmeye odaklanacağımız için temellerini açıklamaya çok vakit ayırmayacağımızı unutmayın. +For this dapp, we'll be using [React](https://react.dev/) as our frontend framework; however, it's important to note that we won't be spending much time breaking down its fundamentals, as we'll mostly be focusing on bringing Web3 functionality to our project. -Ön şart olarak, React'i yeni başlayan seviyesinde anlıyor olmanız gerekir. Eğer böyle değilse, [Resmi React öğreticisini](https://reactjs.org/tutorial/tutorial.html) bitirmenizi tavsiye ederiz. +As a prerequisite, you should have a beginner-level understanding of React. If not, we recommend completing the official [Intro to React tutorial](https://react.dev/learn). -### Başlangıç ​​dosyalarını klonlayın {#clone-the-starter-files} +### Başlangıç dosyalarını klonlayın {#clone-the-starter-files} -İlk olarak, bu projenin başlangıç dosyalarını almak ve bu kaynağı kendi yerel makinemize klonlamak için [hello-world-part-four GitHub deposuna](https://github.com/alchemyplatform/hello-world-part-four-tutorial) gideceğiz. +First, go to the [hello-world-part-four GitHub repository](https://github.com/alchemyplatform/hello-world-part-four-tutorial) to get the starter files for this project and clone this repository to your local machine. -Klonlanmış depoyu yerel olarak açın. İki klasöre sahip olduğunu göreceksiniz: `starter-files` ve `completed`. +Open the cloned repository locally. Notice that it contains two folders: `starter-files` and `completed`. -- `starter-files`- **bu dizinde çalışacağız**, kullanıcı arayüzünü Ethereum cüzdanınıza ve [3. Bölüm](#part-3)'de Etherscan'de yayımladığımız akıllı sözleşmeye bağlayacağız. -- Bu `completed`, tamamlanmış olan öğreticiyi içerir ve sadece takıldığınızda yararlanacağınız bir kaynak olarak kullanılmalıdır. +- `starter-files`- **we will be working in this directory**, we will connect the UI to your Ethereum wallet and the smart contract we published to Etherscan in [Part 3](#part-3). +- `completed` contains the entire completed tutorial and should only be used as a reference if you get stuck. -Ardından, `starter-files` kopyanızı en sevdiğiniz kod düzenleyicide açın ve `src` klasörüne gidin. +Next, open your copy of `starter-files` to your favorite code editor, and then navigate into the `src` folder. -Yazacağımız tüm kodlar `src` klasörünün altında yer alacaktır. Projemize Web3 işlevselliğini eklemek için `HelloWorld.js` bileşenini ve `util/interact.js` JavaScript dosyalarını düzenleyeceğiz. +Yazacağımız tüm kodlar `src` klasörünün altında yer alacaktır. We'll be editing the `HelloWorld.js` component and the `util/interact.js` JavaScript files to give our project Web3 functionality. -### Başlangıç dosyalarına göz atın {#check-out-the-starter-files} +### Check out the starter files {#check-out-the-starter-files} -Kodlamaya başlamadan önce, başlangıç dosyalarında bize neler sağlandığını öğrenelim. +Before we start coding, let's explore what is provided to us in the starter files. #### React projenizi çalıştırın {#get-your-react-project-running} Tarayıcımızda React projesini ç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. -Projeyi çalıştırmak için `starter-files` klasörünün kök dizinine gidip projenin bağımlılıklarını yüklemek için terminalinizde `npm install`'ı çalıştırın: +To get the project running, navigate to the root directory of the `starter-files` folder, and the run `npm install` in your terminal to install the dependencies of the project: ```bash cd starter-files @@ -715,15 +718,15 @@ Bunların kurulumu tamamlandıktan sonra terminalinizde `npm start` komutunu ça npm start ``` -Bunu yaptığınızda, tarayıcınızda projemizin ön ucunu göreceğiniz [http://localhost:3000/](http://localhost:3000/) adresi açılmalıdır. Bu, bir alandan \(akıllı sözleşmenizde depolanan mesajı güncellemek için bir yer\), bir "Connect Wallet" butonundan ve bir "Udate" butonundan oluşmalıdır. +Doing so should open [http://localhost:3000/](http://localhost:3000/) in your browser, where you'll see the frontend for our project. It should consist of one field \(a place to update the message stored in your smart contract\), a "Connect Wallet" button, and an "Update" button. -Butonlardan birini tıklamayı denediğinizde çalışmadığını göreceksiniz, bunun sebebi hala işlevselliklerini programlamamız gerekmesidir. +If you try clicking either button, you'll notice that they don't work—that's because we still need to program their functionality. -#### `HelloWorld.js` bileşeni {#the-helloworld-js-component} +#### The `HelloWorld.js` component {#the-helloworld-js-component} -Düzenleyicimizdeki `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 çok önemlidir. +Let's go back into the `src` folder in our editor and open the `HelloWorld.js` file. Üzerinde çalışacağımız birincil React bileşeni olduğu için bu dosyadaki her şeyi anlamamız çok önemlidir. -Bu dosyanın en üstünde React kütüphanesini, useEffect ve useState kancalarını, `./util/interact.js`'den bazı öğeleri (bunları yakında daha detaylı anlatacağız!) ve Alchemy logosunu içeren ve projemizi çalışır hale getirmemiz için gerekli olan birkaç önemli içe aktarım ifadeleri olduğunu fark edeceksiniz. +At the top of this file, you'll notice we have several import statements that are necessary to get our project running, including the React library, useEffect and useState hooks, some items from the `./util/interact.js` (we'll describe them in more details soon!), and the Alchemy logo. ```javascript // HelloWorld.js @@ -741,7 +744,7 @@ import { import alchemylogo from "./alchemylogo.svg" ``` -Sırada, belirli olaylardan sonra güncelleyeceğimiz durum değişkenlerimiz var. +Next, we have our state variables that we will update after specific events. ```javascript // HelloWorld.js @@ -753,14 +756,14 @@ const [message, setMessage] = useState("No connection to the network.") const [newMessage, setNewMessage] = useState("") ``` -Değişkenlerin her birinin temsil ettiği şeyler: +Here's what each of the variables represents: -- `walletAddress` - kullanıcının cüzdan adresini saklayan bir dize -- `status`- kullanıcıya, merkeziyetsiz uygulama ile nasıl etkileşim kuracağı konusunda yardımcı olacak mesajlar içeren bir dizi -- `message` - akıllı sözleşmedeki güncel mesajı depolayan bir dizi -- `newMessage` - akıllı sözleşmeye yazılacak yeni mesajı depolayan bir dizi +- `walletAddress` - kullanıcının cüzdan adresini saklayan bir dizedir +- `status`- a string that stores a helpful message that guides the user on how to interact with the dapp +- `message` - a string that stores the current message in the smart contract +- `newMessage` - a string that stores the new message that will be written to the smart contract -Durum değişkenlerinden sonra, beş tane uygulanmamış fonksiyon göreceksiniz: `useEffect` ,`addSmartContractListener`, `addWalletListener`, `connectWalletPressed` ve `onUpdatePressed`. Bu fonksiyonların neler yaptığını aşağıda açıklayacağız: +After the state variables, you'll see five un-implemented functions: `useEffect` ,`addSmartContractListener`, `addWalletListener` , `connectWalletPressed`, and `onUpdatePressed`. We'll explain what they do below: ```javascript // HelloWorld.js @@ -787,11 +790,11 @@ const onUpdatePressed = async () => { } ``` -- [`useEffect`](https://reactjs.org/docs/hooks-effect.html)- bu, bileşeniniz oluşturulduktan sonra çağrılan bir React kancasıdır. İçine geçirilen boş bir `[]` dizisine sahip olduğundan \(4. satıra bakın\), yalnızca bileşenin _ilk_ oluşturmasında çağrılır. Buraya akıllı sözleşmemizde depolanan mesajı yükleyecek, akıllı sözleşmelerimizi ve cüzdan dinleyicilerimizi çağıracak ve kullanıcı arayüzümüzü, bir cüzdanın zaten bağlı olup olmadığını yansıtacak şekilde güncelleyeceğiz. -- `addSmartContractListener`- bu fonksiyon, Merhaba Dünya sözleşmemizin `UpdatedMessages` olayını takip edecek ve akıllı sözleşmemizdeki mesaj değiştiğinde kullanıcı arayüzümüzü güncelleyecek bir dinleyici oluşturur. -- `addWalletListener`- bu fonksiyon, kullanıcının bağlantıyı kesmesi ve adres değişiklikleri yapması gibi MetaMask cüzdan durumundaki değişiklikleri takip eder. -- `connectWalletPressed`- bu fonksiyon, kullanıcının MetaMask cüzdanını merkeziyetsiz uygulamamıza bağlamak için çağrılır. -- `onUpdatePressed` - bu fonksiyon, kullanıcı akıllı sözleşmede depolanan mesajı güncellemek istediğinde çağrılır. +- [`useEffect`](https://legacy.reactjs.org/docs/hooks-effect.html)- this is a React hook that is called after your component is rendered. Because it has an empty array `[]` prop passed into it \(see line 4\), it will only be called on the component's _first_ render. Here we'll load the current message stored in our smart contract, call our smart contract and wallet listeners, and update our UI to reflect whether a wallet is already connected. +- `addSmartContractListener`- this function sets up a listener that will watch for our HelloWorld contract's `UpdatedMessages` event and update our UI when the message is changed in our smart contract. +- `addWalletListener`- this function sets up a listener that detects changes in the user's MetaMask wallet state, such as when the user disconnects their wallet or switches addresses. +- `connectWalletPressed`- this function will be called to connect the user's MetaMask wallet to our dapp. +- `onUpdatePressed` - this function will be called when the user wants to update the message stored in the smart contract. Bu dosyanın sonuna doğru, bileşenimizin kullanıcı arayüzü bulunuyor. @@ -830,32 +833,33 @@ return ( - - + + + ) ``` -Bu kodu dikkatli bir şekilde tararsanız, kullanıcı arayüzümüzde çeşitli durum değişkenleri kullandığımız yeri fark edeceksiniz: +If you scan this code carefully, you'll notice where we use our various state variables in our UI: -- 6 ila 12. satırlar arasında, kullanıcının cüzdanı bağlıysa \(örn.`walletAddress.length > 0`\), "walletButton;" kimlikli butonda kullanıcının `walletAddress`'inin kırpılmış bir versiyonunu gösteririz; aksi takdirde, sadece "Connect Wallet" yazar. -- 17. satırda, akıllı sözleşmemizde depolanan ve `message` dizesinde bulunan güncel mesajımızı görüntüleriz. -- 23-26. satırlar arasında `newMessage` durum değişkenimizi metin alanındaki girdi değiştiğinde güncelleyebilmek için bir [kontrollü bileşen](https://reactjs.org/docs/forms.html#controlled-components) kullanıyoruz. +- On lines 6-12, if the user's wallet is connected \(i.e., `walletAddress.length > 0`\), we display a truncated version of the user `walletAddress` in the button with ID "walletButton;" otherwise it simply says "Connect Wallet." +- On line 17, we display the current message stored in the smart contract, which is captured in the `message` string. +- On lines 23-26, we use a [controlled component](https://legacy.reactjs.org/docs/forms.html#controlled-components) to update our `newMessage` state variable when the input in the text field changes. -Durum değişkenlerimize ek olarak `publishButton` ve `walletButton` butonları sırasıyla tıklandığında `connectWalletPressed` ve `onUpdatePressed` fonksiyonlarının çağrıldığını da göreceksiniz. +In addition to our state variables, you'll also see that `connectWalletPressed` and `onUpdatePressed` functions are called when the buttons with IDs `publishButton` and `walletButton` are clicked respectively. -Son olarak, `HelloWorld.js` bileşeninin nereye eklendiğine değinelim. +Finally, let's address where is this `HelloWorld.js` component added. -React'teki 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ıra enjekte edildiğini görürsünüz. +If you go to the `App.js` file, which is the main component in React that acts as a container for all other components, you'll see that our `HelloWorld.js` component is injected on line 7. -Sonuncu ama diğerleriyle eşit öneme sahip olarak, size sağlanan bir dosyaya daha göz atalım: `interact.js` dosyası. +Last but not least, let's check out one more file provided for you, the `interact.js` file. -#### `interact.js` dosyası {#the-interact-js-file} +#### The `interact.js` file {#the-interact-js-file} -[M-V-C](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) paradigmasını kurala bağlamak istediğimiz için merkeziyetsiz uygulamamızın mantığını, verilerini ve kurallarını yönetmek amacıyla fonksiyonlarımızı içeren ayrı bir dosya oluşturmak ve ardından bu fonksiyonları ön ucumuza \(our `HelloWorld.js` component\) aktarabilmek isteyeceğiz. +Because we want to prescribe to the [M-V-C](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) paradigm, we'll want a separate file that contains all our functions to manage the logic, data, and rules of our dapp, and then be able to export those functions to our frontend \(our `HelloWorld.js` component\). -👆🏽Bu tam olarak `interact.js` dosyamızın amacı! +👆🏽This is the exact purpose of our `interact.js` file! -`src` dizininizde `util` klasörüne gittiğinizde bütün akıllı sözleşme etkileşimlerimizi, cüzdan işlevlerini ve değişkenleri içeren `interact.js` adında bir dosya eklemiş olduğumuzu göreceksiniz. +Navigate to the `util` folder in your `src` directory, and you'll notice we've included a file called `interact.js` that will contain all of our smart contract interaction and wallet functions and variables. ```javascript // interact.js @@ -871,55 +875,55 @@ const getCurrentWalletConnected = async () => {} export const updateMessage = async (message) => {} ``` -Bu dosyanın en üstündeki `helloWorldContract` nesnesine yorum yazdığımızı fark edeceksiniz. Bu öğreticinin ilerleyen kısımlarında, nesnenin yorumkarını kaldıracak, akıllı sözleşmemimizi bu değişkenin içinde oluşturacak ve ardından `HelloWorld.js` bileşenimize aktaracağız. +You'll notice at the top of the file that we've commented out the `helloWorldContract` object. Later in this tutorial, we will uncomment this object and instantiate our smart contract in this variable, which we will then export into our `HelloWorld.js` component. -`helloWorldContract` nesnemiz aşağıdakileri yaptıktan sonra dört uygulanmamış fonksiyon: +The four unimplemented functions after our `helloWorldContract` object do the following: -- `loadCurrentMessage` - bu fonksiyon, akıllı sözleşmede depolanan güncel mesajın yüklenmesinin mantığını işler. Merhaba Dünya akıllı sözleşmesine, [Alchemy Web3 API](https://github.com/alchemyplatform/alchemy-web3)'sini kullanarak bir _okuma_ çağrısı yapacaktır. -- `connectWallet` - bu fonksiyon, kullanıcının MetaMask'ını merkeziyetsiz uygulamamıza bağlar. -- `getCurrentWalletConnected` - bu fonksiyon, sayfa yüklendiğinde merkeziyetsiz uygulamamıza zaten bir Ethereum hesabının bağlı olup olmadığını kontrol eder ve kullanıcı arayüzümüzü buna göre günceller. -- `updateMessage` - bu fonksiyon, akıllı sözleşmede depolanmış olan mesajı günceller. Merhaba Dünya akıllı sözleşmesine bir _write_ çağrısı yapar ve bu sayede kullanıcının MetaMask cüzdanının mesajı güncelleyebilmek için bir Ethereum işlemi imzalaması gerekir. +- `loadCurrentMessage` - this function handles the logic of loading the current message stored in the smart contract. It will make a _read_ call to the Hello World smart contract using the [Alchemy Web3 API](https://github.com/alchemyplatform/alchemy-web3). +- `connectWallet` - this function will connect the user's MetaMask to our dapp. +- `getCurrentWalletConnected` - this function will check if an Ethereum account is already connected to our dapp on page load and update our UI accordingly. +- `updateMessage` - this function will update the message stored in the smart contract. It will make a _write_ call to the Hello World smart contract, so the user's MetaMask wallet will have to sign an Ethereum transaction to update the message. -Ne üzerinde çalıştığımızı anladığımıza göre, akıllı sözleşmemizi nasıl okuyacağımızı öğrenelim! +Now that we understand what we're working with, let's figure out how to read from our smart contract! -### 3. Adım: Akıllı sözleşmenizden okuma {#step-3-read-from-your-smart-contract} +### Step 3: Read from your smart contract {#step-3-read-from-your-smart-contract} -Akıllı sözleşmenizi okuyabilmek için aşağıdakileri başarıyla kurmanız gerekir: +To read from your smart contract, you'll need to successfully set up: -- Ethereum zincirine bir API bağlantısı -- Akıllı sözleşmenizin yüklenmiş bir örneği -- Akıllı sözleşme fonksiyonunuzu çağıran bir fonksiyon -- Akıllı sözleşme değişikliklerinden okuduğunuz verilerin güncellemelerini takip eden bir dinleyici +- An API connection to the Ethereum chain +- A loaded instance of your smart contract +- A function to call to your smart contract function +- A listener to watch for updates when the data you're reading from the smart contract changes -Çok fazla adım varmış gibi görünebilir, fakat endişe etmeyin! Hepsini nasıl yapacağınızı adım adım göstereceğiz! :\) +This may sounds like a lot of steps, but don't worry! We'll walk you through how to do each of them step-by-step! :) -#### Ethereum zincirine bir API bağlantısı kurma {#establish-an-api-connection-to-the-ethereum-chain} +#### Establish an API connection to the Ethereum chain {#establish-an-api-connection-to-the-ethereum-chain} -Bu öğreticinin 2. Bölümü'nde [Alchemy Web3 anahtarını akıllı sözleşmemizi okuyabilmek için kullandığımızı hatırlıyor musunuz](https://docs.alchemy.com/alchemy/tutorials/hello-world-smart-contract/interacting-with-a-smart-contract#step-1-install-web3-library)? Zinciri okuyabilmek için de merkeziyetsiz uygulamanızda bir Alchemy Web3 anahtarına ihtiyacınız olacak. +So remember how in Part 2 of this tutorial, we used our [Alchemy Web3 key to read from our smart contract](https://docs.alchemy.com/alchemy/tutorials/hello-world-smart-contract/interacting-with-a-smart-contract#step-1-install-web3-library)? You'll also need an Alchemy Web3 key in your dapp to read from the chain. -Eğer sizde hala yoksa, ilk olarak kök dizininizin `starter-files` öğesinden [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3)'e gidip yüklemek için aşağıdaki kodu terminalinizde çalıştırın: +If you don't have it already, first install [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) by navigating to the root directory of your `starter-files` and running the following in your terminal: ```text npm install @alch/alchemy-web3 ``` -[Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3), [Web3.js](https://docs.web3js.org/) paketleyicisidir. Bir web3 geliştiricisi olarak hayatınızı kolaylaştıracak 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! +[Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3), [Web3.js](https://docs.web3js.org/) için 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 depolayacağımız güvenli bir yerimiz olması için [dotenv](https://www.npmjs.com/package/dotenv) paketini proje dizinimize yükleyin. +Then, install the [dotenv](https://www.npmjs.com/package/dotenv) package in your project directory, so we have a secure place to store our API key after we fetch it. ```text npm install dotenv --save ``` -Merkeziyetsiz uygulamamız için HTTP API anahtarımız yerine **Websockets API anahtarımızı kullanıyor** olacağız; bu, bizim akıllı sözleşmemizdeki mesajların değişip değişmediğini kontrol eden bir dinleyici kurmamızı sağlayacaktır. +For our dapp, **we'll be using our Websockets API key** instead of our HTTP API key, as it will allow us to set up a listener that detects when the message stored in the smart contract changes. -API anahtarına sahip olduğunuzda, kök dizininizde bir `.env` dosyası oluşturun ve Alchemy Websockets url'nizi içine ekleyin. Sonrasında `.env` dosyanız şu şekilde görünmelidir: +Once you have your API key, create a `.env` file in your root directory and add your Alchemy Websockets url to it. Afterwards, your `.env` file should look like so: ```javascript REACT_APP_ALCHEMY_KEY = wss://eth-goerli.ws.alchemyapi.io/v2/ ``` -Artık Alchemy Web3 uç noktamızı merkeziyetsiz uygulamamıza kurmaya hazırız! `util` klasörümüzde yuvalanmış `interact.js` öğemize geri dönelim ve dosyanın başına aşağıdaki kodu ekleyelim: +Now, we're ready to set up our Alchemy Web3 endpoint in our dapp! Let's go back to our `interact.js`, which is nested inside our `util` folder and add the following code at the top of the file: ```javascript // interact.js @@ -932,23 +936,23 @@ const web3 = createAlchemyWeb3(alchemyKey) //export const helloWorldContract; ``` -Yukarıda, ilk olarak Alchemy anahtarımızı `.env` dosyasından içe aktardık ve sonra da Alchemy Web3 uç noktamızı kurmak için `alchemyKey`'imizi `createAlchemyWeb3`'e gönderdik. +Above, we first imported the Alchemy key from our `.env` file and then passed our `alchemyKey` to `createAlchemyWeb3` to establish our Alchemy Web3 endpoint. -Bu uç nokta hazır olduğuna göre akıllı sözleşmemizi yükleme zamanı! +With this endpoint ready, it's time to load our smart contract! -#### Merhaba Dünya akıllı sözleşmenizi yükleme {#loading-your-hello-world-smart-contract} +#### Loading your Hello World smart contract {#loading-your-hello-world-smart-contract} -Merhaba Dünya akıllı sözleşmenizi yükleyebilmek için sözleşmenin adresine ve ABI'sine ihtiyacınız olacak. [Bu öğreticinin 3. Bölümü'nü](/developers/tutorials/hello-world-smart-contract-fullstack/#part-3-publish-your-smart-contract-to-etherscan-part-3-publish-your-smart-contract-to-etherscan) bitirdiyseniz bunların ikisini de Etherscan'de bulabilirsiniz. +To load your Hello World smart contract, you'll need its contract address and ABI, both of which can be found on Etherscan if you completed [Part 3 of this tutorial.](/developers/tutorials/hello-world-smart-contract-fullstack/#part-3-publish-your-smart-contract-to-etherscan-part-3-publish-your-smart-contract-to-etherscan) -#### Sözleşme ABI'nizi Etherscan'den alma {#how-to-get-your-contract-abi-from-etherscan} +#### How to get your contract ABI from Etherscan {#how-to-get-your-contract-abi-from-etherscan} -Bu öğreticinin 3. Bölüm'ünü atladıysanız, [0x6f3f635A9762B47954229Ea479b4541eAF402A6A](https://goerli.etherscan.io/address/0x6f3f635a9762b47954229ea479b4541eaf402a6a#code) adresli Merhaba Dünya sözleşmesini kullanabilirsiniz. Sözleşmenin ABI'sini [burada](https://goerli.etherscan.io/address/0x6f3f635a9762b47954229ea479b4541eaf402a6a#code) bulabilirsiniz. +If you skipped Part 3 of this tutorial, you can use the HelloWorld contract with address [0x6f3f635A9762B47954229Ea479b4541eAF402A6A](https://goerli.etherscan.io/address/0x6f3f635a9762b47954229ea479b4541eaf402a6a#code). Its ABI can be found [here](https://goerli.etherscan.io/address/0x6f3f635a9762b47954229ea479b4541eaf402a6a#code). -Bir sözleşmenin hangi fonksiyonu çağıracağını belirlemek ve fonksiyonun beklediğiniz biçimde veri döndürmesini sağlamak için bir sözleşme ABI'si gereklidir. Sözleşme ABI'mizi kopyaladıktan sonra onu `src` dizinindeki `contract-abi.json` adlı JSON dosyasına kaydedelim. +A contract ABI is necessary for specifying which function a contract will invoke as well ensuring that the function will return data in the format you're expecting. Once we've copied our contract ABI, let's save it as a JSON file called `contract-abi.json` in your `src` directory. -Contract-abi.json'unuz src klasöründe depolanmış olmalıdır. +Your contract-abi.json should be stored in your src folder. -Sözleşme adresimiz, ABI ve Alchemy Web3 uç noktamız hazır olduğuna göre, sözleşmemizin bir örneğini yüklemek için bu [sözleşme yöntemini](https://docs.web3js.org/api/web3-eth-contract/class/Contract) kullanabiliriz. Sözleşme ABI'nizi `interact.js` dosyasının içine aktarın ve sözleşme adresinizi ekleyin. +Armed with our contract address, ABI, and Alchemy Web3 endpoint, we can use the [contract method](https://docs.web3js.org/api/web3-eth-contract/class/Contract) to load an instance of our smart contract. Import your contract ABI into the `interact.js` file and add your contract address. ```javascript // interact.js @@ -957,7 +961,7 @@ const contractABI = require("../contract-abi.json") const contractAddress = "0x6f3f635A9762B47954229Ea479b4541eAF402A6A" ``` -Sonunda `helloWorldContract` değişkenimizin yorumunu kaldırabilir ve AlchemyWeb3 uç noktasını kullanarak akıllı sözleşmemizi yükleyebiliriz: +We can now finally uncomment our `helloWorldContract` variable, and load the smart contract using our AlchemyWeb3 endpoint: ```javascript // interact.js @@ -967,7 +971,7 @@ export const helloWorldContract = new web3.eth.Contract( ) ``` -Hatırlatma olarak, `interact.js` kodunuzun ilk 12 satırı aşağıdaki gibi görünmelidir: +To recap, the first 12 lines of your `interact.js` should now look like this: ```javascript // interact.js @@ -986,13 +990,13 @@ export const helloWorldContract = new web3.eth.Contract( ) ``` -Sözleşmemizi yüklediğimize göre, artık `loadCurrentMessage` fonksiyonunu uygulayabiliriz! +Now that we have our contract loaded, we can implement our `loadCurrentMessage` function! -#### `interact.js` dosyanıza `loadCurrentMessage`'ı uygulama {#implementing-loadCurrentMessage-in-your-interact-js-file} +#### Implementing `loadCurrentMessage` in your `interact.js` file {#implementing-loadCurrentMessage-in-your-interact-js-file} -Bu fonksiyon aşırı basittir. Sözleşmemizi okumak için basit bir asenkronize web3 çağrısı yapacağız. Fonksiyonumuz akıllı sözleşmede depolanmış olan mesajı döndürecek: +This function is super simple. We're going make a simple async web3 call to read from our contract. Our function will return the message stored in the smart contract: -`interact.js` dosyanızdaki `loadCurrentMessage`'ı aşağıdaki şekilde güncelleyin: +Update the `loadCurrentMessage` in your `interact.js` file to the following: ```javascript // interact.js @@ -1003,7 +1007,7 @@ export const loadCurrentMessage = async () => { } ``` -Kullanıcı arayüzümüzde akıllı sözleşmeyi görüntülemek istediğimiz için `HelloWorld.js` bileşenimizdeki `useEffect` fonksiyonunu aşağıdaki şekilde güncelleyelim: +Since we want to display this smart contract in our UI, let's update the `useEffect` function in our `HelloWorld.js` component to the following: ```javascript // HelloWorld.js @@ -1015,19 +1019,19 @@ useEffect(async () => { }, []) ``` -Bileşenin ilk işlemesinde sadece `loadCurrentMessage`'ın çağrılmasını istediğimize dikkat edin. Yakında akıllı sözleşmedeki mesaj değiştiğinde kullanıcı arayüzünü otomatik olarak güncelleyen `addSmartContractListener`'ı uygulayacağız. +Note, we only want our `loadCurrentMessage` to be called once during the component's first render. We'll soon implement `addSmartContractListener` to automatically update the UI after the message in the smart contract changes. -Dinleyicimize geçmeden önce, şu anda elimizde ne olduğuna bir bakalım! `HelloWorld.js` ve `interact.js` dosyalarınızı kaydedip [http://localhost:3000/](http://localhost:3000/) öğesine gidin +Before we dive into our listener, let's check out what we have so far! Save your `HelloWorld.js` and `interact.js` files, and then go to [http://localhost:3000/](http://localhost:3000/) -Güncel mesajda artık "Ağ bağlantısı yok" yazmadığını göreceksiniz. Onun yerine, akıllı sözleşmede depolanmış olan mesajı yansıtır. İnanılmaz! +You'll notice that the current message no longer says "No connection to the network." Instead it reflects the message stored in the smart contract. Sick! -#### Kullanıcı arayüzünüz artık akıllı sözleşmede depolanan mesajı yansıtıyor olmalı {#your-UI-should-now-reflect-the-message-stored-in-the-smart-contract} +#### Your UI should now reflect the message stored in the smart contract {#your-UI-should-now-reflect-the-message-stored-in-the-smart-contract} -Dinleyiciye gelirsek... +Now speaking of that listener... -#### `addSmartContractListener`'ı uygulayın {#implement-addsmartcontractlistener} +#### Implement `addSmartContractListener` {#implement-addsmartcontractlistener} -[Bu öğretici serisinin 1. Bölümü'nde](https://docs.alchemy.com/alchemy/tutorials/hello-world-smart-contract#step-10-write-our-contract) yazdığımız `HelloWorld.sol` dosyasına dönerseniz, burada akıllı sözleşmemizin `update` fonksiyonunu çağırdıktan sonra meydana gelen `UpdatedMessages` adlı bir olay olduğunu hatırlayacaksınız \(bkz. satır 9 ve 27\): +If you think back to the `HelloWorld.sol` file we wrote in [Part 1 of this tutorial series](https://docs.alchemy.com/alchemy/tutorials/hello-world-smart-contract#step-10-write-our-contract), you'll recall that there is a smart contract event called `UpdatedMessages` that is emitted after our smart contract's `update` function is invoked \(see lines 9 and 27\): ```javascript // HelloWorld.sol @@ -1065,11 +1069,11 @@ contract HelloWorld { } ``` -Akıllı sözleşme olayları sözleşmenizin, ön yüz uygulamanızın blokzinciri üzerinde bir olay olduğunda \(yani bir _olay_ gerçekleştiğinde\) iletişim kurmasının bir yoludur. Bu yol, belli başlı olaylar için bir şeyleri dinlemek ve bu olaylar olduğunda aksiyon almak olabilir. +Smart contract events are a way for your contract to communicate that something happened \(i.e., there was an _event_\) on the blockchain to your front-end application, which can be 'listening' for specific events and take action when they happen. -`addSmartContractListener` fonksiyonu spesifik olarak Merhaba Dünya akıllı sözleşmemizin `UpdatedMessages` olayını dinleyecek ve kullanıcı arayüzümüzü yeni mesajı gösterecek şekilde güncelleyecektir. +The `addSmartContractListener` function is going to specifically listen for our Hello World smart contract's `UpdatedMessages` event, and update our UI to display the new message. -`addSmartContractListener`'ı aşağıdaki gibi değiştirin: +Modify `addSmartContractListener` to the following: ```javascript // HelloWorld.js @@ -1087,12 +1091,12 @@ function addSmartContractListener() { } ``` -Dinleyici bir olay algıladığında olacakları masaya yatıralım: +Let's break down what happens when the listener detects an event: -- Olay yayımlandığında bir hata oluşursa, `status` durum değişkenimiz bu hatayı kullanıcı arayüzüne yansıtır. -- Aksi takdirde döndürülen `data` nesnesini kullanacağız. `data.returnValues` dizinin ilk öğesinin önceki mesajı ve ikinci öğesinin güncellenmiş mesajı depoladığı sıfırdan başlatılan bir dizidir. Bütün olarak bakıldığında, başarılı bir olayda güncellenmiş mesajımıza `message` dizemizi kuracağız, `newMessage` dizesini sileceğiz ve `status` durum değişkenimizi akıllı sözleşmemizde yeni bir mesajın yayımlandığını yansıtacak şekilde güncelleyeceğiz. +- If an error occurs when the event is emitted, it will be reflected in the UI via our `status` state variable. +- Otherwise, we will use the `data` object returned. The `data.returnValues` is an array indexed at zero where the first element in the array stores the previous message and second element stores the updated one. Altogether, on a successful event we'll set our `message` string to the updated message, clear the `newMessage` string, and update our `status` state variable to reflect that a new message has been published on our smart contract. -Son olarak, `useEffect` fonksiyonumuzdaki dinleyicimizi çağırarak `HelloWorld.js` bileşenimizin ilk işlemesini başlatalım. Toparlarsak, `useEffect` fonksiyonunuz şu şekilde görünmelidir: +Finally, let's call our listener in our `useEffect` function so it is initialized on the `HelloWorld.js` component's first render. Altogether, your `useEffect` function should look like this: ```javascript // HelloWorld.js @@ -1104,45 +1108,45 @@ useEffect(async () => { }, []) ``` -Artık akıllı sözleşmemizi okuyabildiğimize göre, ona nasıl bir şeyler yazabileceğimizi öğrenmek de süper olur! Bununla birlikte, merkeziyetsiz uygulamamıza yazabilmek için önce ona bağlı bir Ethereum cüzdanı olmalıdır. +Now that we're able to read from our smart contract, it would be great to figure out how to write to it too! However, to write to our dapp, we must first have an Ethereum wallet connected to it. -Yapacağımız bir sonraki şey ise Ethereum cüzdanımızı \(MetaMask\) kurmak ve merkeziyetsiz uygulamamıza bağlamaktır! +So, next we'll tackle setting up our Ethereum wallet \(MetaMask\) and then connecting it to our dapp! -### 4. Adım: Ethereum cüzdanınızı kurun {#step-4-set-up-your-ethereum-wallet} +### Step 4: Set up your Ethereum wallet {#step-4-set-up-your-ethereum-wallet} -Kullanıcılar, Ethereum zincirine herhangi bir şey yazabilmek için sanal cüzdanlarının özel anahtarlarını kullanarak işlemler imzalamalıdır. Bu öğreticide, Ethereum hesap adresinizi yönetmeniz için tarayıcıda bulunan bir sanal cüzdan olan ve son kullanıcı için işlem imzalamayı çok basit bir hale getiren [MetaMask](https://metamask.io/)'ı kullanacağız. +To write anything to the Ethereum chain, users must sign transactions using their virtual wallet's private keys. For this tutorial, we’ll use [MetaMask](https://metamask.io/), a virtual wallet in the browser used to manage your Ethereum account address, as it makes this transaction signing super easy for the end-user. Ethereum'daki işlemlerin nasıl çalıştığı hakkında daha fazla bilgi edinmek istiyorsanız, Ethereum Vakfı'nın [bu sayfasına](/developers/docs/transactions/) göz atın. -#### MetaMask'i indirin {#download-metamask} +#### MetaMask'ı indirin {#download-metamask} -[Buradan](https://metamask.io/download) ücretsiz olarak bir MetaMask hesabı indirebilir ve oluşturabilirsiniz. Bir hesap oluştururken ya da zaten bir hesabınız varsa, sağ üstten "Goerli Test Ağına" geçin \(bu sayede gerçek parayla denemeler yapmayız\). +MetaMask'ı [buradan](https://metamask.io/download) ücretsiz indirip bir hesap oluşturabilirsiniz. When you are creating an account, or if you already have an account, make sure to switch over to the “Goerli Test Network” in the upper right \(so that we’re not dealing with real money\). -#### Bir Musluktan ether ekleyin {#add-ether-from-a-faucet} +#### Add ether from a Faucet {#add-ether-from-a-faucet} -Ethereum blokzincirinde bir işlem imzalamak için biraz sahte Eth'ye ihtiyacımız olacak. Eth almak için [FaucETH](https://fauceth.komputing.org)'e gidip Goerli hesap adresinizi girebilir, "Fon iste" öğesine tıklayıp açılır menüden "Ethereum Test Ağı Goerli" seçimi yapabilir ve son olarak tekrar "Fon iste" düğmesine tıklayabilirsiniz. Kısa bir süre sonra MetaMask hesabınızda Eth'i görmelisiniz! +To sign a transaction on the Ethereum blockchain, we’ll need some fake Eth. To get Eth you can go to the [FaucETH](https://fauceth.komputing.org) and enter your Goerli account address, click “Request funds”, then select “Ethereum Testnet Goerli” in the dropdown and finally click “Request funds” button again. Kısa bir süre sonra MetaMask hesabınızda Eth'i görmelisiniz! -#### Bakiyenizi kontrol etme {#check-your-balance} +#### Check your Balance {#check-your-balance} -Bakiyemizin yerinde olduğundan emin olmak için [Alchemy'nin düzenleyici aracını](https://composer.alchemyapi.io/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D) kullanarak bir [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance) isteği oluşturalım. Bu, cüzdanımızdaki Eth miktarını döndürür. MetaMask hesap adresinizi girdikten ve "Send Request"e tıkladıktan sonra aşağıdaki gibi bir yanıt görmelisiniz: +Bakiyemizin orada olup olmadığını iki kez kontrol etmek için [Alchemy’nin composer aracını](https://composer.alchemyapi.io/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D) kullanarak bir [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance) isteği yapalım. Bu, cüzdanımızdaki Eth miktarını döndürür. MetaMask hesap adresinizi girdikten ve "Send Request"e tıkladıktan sonra aşağıdaki gibi bir yanıt görmelisiniz: ```text {"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"} ``` -**NOT:** Bu sonuç eth değil wei hâlindedir. Wei, ether'ın en küçük birimi olarak kullanılır. Wei'den eth'e dönüşüm: 1 eth = 10¹⁸ wei. Yani 0xde0b6b3a7640000'ı ondalık sayıya dönüştürürsek 1\*10¹⁸ elde ederiz, bu da 1 eth'e eşittir. +**NOT:** Bu sonuç eth cinsinden değil wei cinsindendir. Wei, ether'ın en küçük birimi olarak kullanılır. Wei'den eth'e dönüşüm: 1 eth = 10¹⁸ wei. Yani 0xde0b6b3a7640000'ı ondalık sayıya dönüştürürsek 1\*10¹⁸ elde ederiz, bu da 1 eth'e eşittir. -Vay be! Tüm sahte paramız yerli yerinde! 🤑 +Vay be! Tüm sahte paramız yerinde! 🤑 -### 5. Adım: MetaMask'ı kullanıcı arayüzünüze bağlayın {#step-5-connect-metamask-to-your-UI} +### Step 5: Connect MetaMask to your UI {#step-5-connect-metamask-to-your-UI} Artık MetaMask cüzdanımız kurulduğuna göre, merkeziyetsiz uygulamamızı ona bağlayalım! -#### `connectWallet` fonksiyonu {#the-connectWallet-function} +#### The `connectWallet` function {#the-connectWallet-function} -`interact.js` dosyamızda `connectWallet` fonksiyonunu uygulayalım, bu fonksiyonu sonrasında `HelloWorld.js` bileşenimizde çağırabiliriz. +In our `interact.js`file, let's implement the `connectWallet` function, which we can then call in our `HelloWorld.js` component. -`connectWallet`'u aşağıdaki gibi değiştirelim: +Let's modify `connectWallet` to the following: ```javascript // interact.js @@ -1183,26 +1187,26 @@ export const connectWallet = async () => { } ``` -Bu dev kod bloğu tam olarak ne yapar? +So what does this giant block of code do exactly? -İlk olarak, tarayıcınızda `window.ethereum`'un etkinleştirilmiş olup olmadığını kontrol eder. +Well, first, it checks if it `window.ethereum` is enabled in your browser. -`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 izin veren küresel bir API'dir. Onaylandıysa, kullanıcının bağlı olduğu blokzincirlerden veri okuyabilir ve kullanıcıya mesajlar ve işlemler imzalamasını önerebilir. Daha fazla bilgi için [MetaMask belgelerine](https://docs.metamask.io/guide/ethereum-provider.html#table-of-contents) göz atın! +`window.ethereum`, MetaMask ve diğer cüzdan sağlayıcıları tarafından eklenen ve web sitelerinin kullanıcıların Ethereum hesaplarını talep etmesine olanak tanıyan küresel bir API'dir. If approved, it can read data from the blockchains the user is connected to, and suggest that the user sign messages and transactions . Daha fazla bilgi için [MetaMask belgelerine](https://docs.metamask.io/guide/ethereum-provider.html#table-of-contents) göz atın! -`window.ethereum` _yoksa_, MetaMask kurulu değil demektir. Bu, bir JSON nesnesinin döndürülmesiyle sonuçlanır; burada döndürülen `address` boş bir dizedir ve `status` JSX nesnesi, kullanıcının MetaMask'i yüklemesi gerektiğini bildirir. +Eğer `window.ethereum` mevcut _değilse_, bu MetaMask'in kurulu olmadığı anlamına gelir. Bu, döndürülen `address`'in boş bir dize olduğu ve `status` JSX nesnesinin kullanıcının MetaMask'i yüklemesi gerektiğini ilettiği bir JSON nesnesinin döndürülmesiyle sonuçlanır. -Şimdi, eğer `window.ethereum` _varsa_, işte o zaman işler ilginçleşiyor. +Eğer `window.ethereum` mevcut _ise_, o zaman işler ilginçleşir. -Bir deneme/yakalama döngüsü ile [`window.ethereum.request({ method: "eth_requestAccounts" });`](https://docs.metamask.io/guide/rpc-api.html#eth-requestaccounts) çağrısı yaparak MetaMask'a bağlanmaya çalışacağız. Bu fonksiyonun çağrılması, tarayıcıda MetaMask'i açar ve bu sayede kullanıcıdan cüzdanını merkeziyetsiz uygulamanıza bağlaması istenir. +Bir try/catch döngüsü kullanarak, [`window.ethereum.request({ method: \"eth_requestAccounts\" });`](https://docs.metamask.io/guide/rpc-api.html#eth-requestaccounts) çağrısı yaparak MetaMask'e bağlanmaya çalışacağız. Bu fonksiyonun çağrılması, tarayıcıda MetaMask'i açar ve bu sayede kullanıcıdan cüzdanını merkeziyetsiz uygulamanıza bağlaması istenir. -- Kullanıcı bağlanmayı seçerse, `method: "eth_requestAccounts"`, kullanıcının merkeziyetsiz uygulamaya bağlı tüm hesap adreslerini içeren bir dizi döndürür. Toplamda, `connectWallet` fonksiyonumuz bu dizideki _ilk_ `address`'i içeren bir JSON nesnesi \(9. satıra bakın\) ve kullanıcıdan akıllı sözleşmeye bir mesaj yazmasını isteyen bir `status` mesajı döndürür. -- 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çerir. +- If the user chooses to connect, `method: "eth_requestAccounts"` will return an array that contains all of the user's account addresses that connected to the dapp. Sonuç olarak, `connectWallet` fonksiyonumuz bu dizideki _ilk_ `address`'i (bkz. satır 9) ve kullanıcıyı akıllı sözleşmeye bir mesaj yazmaya yönlendiren 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çerir. -Artık bu `connectWallet`'ı yazdığımıza göre, sonraki adım onu `HelloWorld.js` bileşenimize çağırmaktır. +Now that we've written this `connectWallet` function, the next step is to call it to our `HelloWorld.js`component. -#### `HelloWorld.js` Kullanıcı Arayüzü Bileşenimize `connectWallet` fonksiyonunu ekleyelim {#add-the-connectWallet-function-to-your-HelloWorld-js-ui-component} +#### Add the `connectWallet` function to your `HelloWorld.js` UI Component {#add-the-connectWallet-function-to-your-HelloWorld-js-ui-component} -`HelloWorld.js` içinde bulunan `connectWalletPressed`'a gidin ve aşağıdaki gibi güncelleyin: +Navigate to the `connectWalletPressed` function in `HelloWorld.js`, and update it to the following: ```javascript // HelloWorld.js @@ -1214,25 +1218,25 @@ const connectWalletPressed = async () => { } ``` -İşlevselliğimizin çoğunun `interact.js` dosyasındaki `HelloWorld.js`'den nasıl da soyutlandığını görebiliyor musunuz? Bu, M-V-C paradigmasına uymamız içindir! +Notice how most of our functionality is abstracted away from our `HelloWorld.js` component from the `interact.js` file? Bu, M-V-C paradigmasına uymamız içindir! -`connectWalletPressed`'de, içe aktarılan `connectWallet` fonksiyonumuza bir bekleme çağrısı yaparız ve yanıtını kullanarak durum kancaları aracılığıyla `status` ve `walletAddress` değişkenlerimizi güncelleriz. +`connectWalletPressed` içinde, içe aktarılan `connectWallet` fonksiyonumuza bir `await` çağrısı yaparız ve yanıtını kullanarak `status` ve `walletAddress` değişkenlerimizi durum kancaları aracılığıyla güncelleriz. -Şimdi, iki dosyayı da \(`HelloWorld.js` and `interact.js`\) kaydedelim ve şu ana kadarki kullanıcı arayüzümüzü test edelim. +Now, let's save both files \(`HelloWorld.js` and `interact.js`\) and test out our UI so far. -[http://localhost:3000/](http://localhost:3000/) sayfasında tarayıcınızı açın ve sayfanın sağ üst tarafında bulunan "Connect Wallet" butonuna tıklayın. +Open your browser on the [http://localhost:3000/](http://localhost:3000/) page, and press the "Connect Wallet" button on the top right of the page. MetaMask yüklüyse, cüzdanınızı merkeziyetsiz uygulamanıza bağlamanız istenecektir. Bağlanmak için daveti kabul edin. -Cüzdan butonunuzun, adresinizin artık bağlı olduğunu gösterdiğini görmeniz beklenir! Eveeet 🔥 +You should see that the wallet button now reflects that your address is connected! Yasssss 🔥 -Ardından, sayfayı yenilemeyi deneyin... Garip. Cüzdan düğmemiz zaten bağlı olmasına rağmen MetaMask'i bağlamamızı istiyor... +Şimdi, sayfayı yenilemeyi deneyin... bu garip. Cüzdan düğmemiz zaten bağlı olmasına rağmen MetaMask'i bağlamamızı istiyor... -Yine de korkmanıza gerek yok! Bunu, `getCurrentWalletConnected`'ı uygulayarak kolaylıkla adresleyebiliriz (anladınız mı)?; bu da merkeziyetsiz uygulamamıza bir adresin bağlı olup olmadığını kontrol edecek ve buna göre kullanıcı arayüzümüzü güncelleyecektir! +However, have no fear! We easily can address that (get it?) by implementing `getCurrentWalletConnected`, which will check if an address is already connected to our dapp and update our UI accordingly! -#### `getCurrentWalletConnected` fonksiyonu {#the-getcurrentwalletconnected-function} +#### The `getCurrentWalletConnected` function {#the-getcurrentwalletconnected-function} -`interact.js` dosyasındaki `getCurrentWalletConnected` fonksiyonunuzu aşağıdaki gibi güncelleyin: +Update your `getCurrentWalletConnected` function in the `interact.js` file to the following: ```javascript // interact.js @@ -1279,11 +1283,11 @@ export const getCurrentWalletConnected = async () => { } ``` -Bu kod, önceki adımda yazdığımız `connectWallet` fonksiyonuna _çok_ benzer. +This code is _very_ similar to the `connectWallet` function we just wrote in the previous step. -Temel fark, kullanıcının cüzdanını bağlaması için MetaMask'i açan `eth_requestAccounts` yöntemini çağırmak yerine, burada yalnızca şu anda merkeziyetsiz uygulamamıza bağlı olan MetaMask adreslerini içeren bir dizi döndüren `eth_accounts` yöntemini çağırmamızdır. +Temel fark, kullanıcının cüzdanını bağlaması için MetaMask'i açan `eth_requestAccounts` yöntemini çağırmak yerine, burada yalnızca merkeziyetsiz uygulamamıza bağlı olan MetaMask adreslerini içeren bir dizi döndüren `eth_accounts` yöntemini çağırıyoruz. -Bu fonksiyonu çalışırken görmek için onu `HelloWorld.js` bileşenimizin `useEffect` fonksiyonuyla çağıralım: +To see this function in action, let's call it in our `useEffect` function of our `HelloWorld.js` component: ```javascript // HelloWorld.js @@ -1299,17 +1303,17 @@ useEffect(async () => { }, []) ``` -Dikkat edin, `walletAddress` ve `status` durum değişkenlerimizi güncellemek için `getCurrentWalletConnected` çağrımızın yanıtını kullanıyoruz. +Dikkat edin, `getCurrentWalletConnected` çağrımızın yanıtını `walletAddress` ve `status` durum değişkenlerimizi güncellemek için kullanıyoruz. -Artık bu kodu eklediğinize göre, sayfayı yenilemeyi deneyin. +Now that you've added this code, let's try refreshing our browser window. -Güzeeeeeel! Düğme, bağlı olduğunuzu söylemeli ve yeniledikten sonra bile bağlı cüzdanınızın adresinin bir önizlemesini göstermelidir! +Niceeeee! 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`'ı uygulayın {#implement-addwalletlistener} +#### Implement `addWalletListener` {#implement-addwalletlistener} Merkeziyetsiz uygulama cüzdanı kurulumumuzun son adımı, örneğin kullanıcı bağlantısını keserek veya hesap değiştirerek cüzdanımızın durumunu değiştirdiğinde kullanıcı arayüzümüzün güncellenmesi için cüzdan dinleyicisini uygulamaktır. -`HelloWorld.js` dosyanızda `addWalletListener` fonksiyonunu aşağıdaki gibi değiştirin: +In your `HelloWorld.js` file, modify your `addWalletListener` function as the following: ```javascript // HelloWorld.js @@ -1338,13 +1342,13 @@ function addWalletListener() { } ``` -Bu noktada ne olup bittiğini anlamak için bizim yardımımıza ihtiyacınız olmadığına bahse girebilirim, fakat hiçbir ayrıntıyı atlamamak adına hızlıca anlatalım: +I bet you don't even need our help to understand what's going on here at this point, but for thoroughness purposes, let's quickly break it down: -- İlk olarak, fonksiyonumuz `window.ethereum`'un etkin olup olmadığını kontrol eder \(yani MetaMask kurulu olup olmadığını\). - - Değilse, `status` durum değişkenimizi, kullanıcının MetaMask'i yüklemesini isteyen bir JSX dizesine ayarlamamız yeterlidir. - - Etkinleştirilirse, 3. satırda `window.ethereum.on("accountsChanged")` dinleyicisini kurarız ve bu dinleyici MetaMask cüzdanındaki, kullanıcının merkeziyetsiz uygulamaya ek bir hesap bağladığı, hesapları değiştirdiği veya bir hesabın bağlantısını kestiği anları da içeren durum değişikliklerini dinler. 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. +- İlk olarak fonksiyonumuz `window.ethereum`'un etkin olup olmadığını kontrol eder (yani MetaMask'in kurulu olup olmadığını). + - Etkin değilse, `status` durum değişkenimizi, kullanıcıyı MetaMask'i yüklemeye yönlendiren bir JSX dizesine ayarlarız. + - Etkinleştirilmişse, kullanıcının merkeziyetsiz uygulamaya ek bir hesap bağlaması, hesapları 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 3. satırda 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 ama bir o kadar da önemli olarak, bunu `useEffect` fonksiyonumuzda çağırmalıyız: +Last but not least, we must call it in our `useEffect` function: ```javascript // HelloWorld.js @@ -1362,23 +1366,23 @@ useEffect(async () => { }, []) ``` -İşte bu kadar! Cüzdan fonksiyonlarımızın tümünün programlanmasını başarıyla tamamladık! Şimdi sıra son görevimizde: akıllı sözleşmemizde depolanan mesajı güncellemek! +İşte bu kadar! We've successfully completed programming all of our wallet functionality! Now onto our last task: updating the message stored in our smart contract! -### 6. Adım: `updateMessage` fonksiyonunu uygulama {#step-6-implement-the-updateMessage-function} +### Step 6: Implement the `updateMessage` function {#step-6-implement-the-updateMessage-function} -Evet dostum, evimizdeki rahatlığa ulaştık! `interact.js` dosyanızın `updateMessage` kısmında şunları yapacağız: +Alrighty fam, we've arrived at the home stretch! In the `updateMessage` of your `interact.js` file, we're going to do the following: -1. Yayımlayamak istediğimiz mesajın geçerli olduğundan emin olmak -2. MetaMask kullanarak işlemimizi imzalamak -3. `HelloWorld.js` ön yüz bileşenimizden bu fonksiyonu çağırmak +1. Make sure the message we wish to publish in our smart contact is valid +2. Sign our transaction using MetaMask +3. Call this function from our `HelloWorld.js` frontend component -Bu, fazla zaman almayacak; hadi bu merkeziyetsiz uygulamayı bitirelim! +This won't take very long; let's finish this dapp! -#### Girdi hatası işleme {#input-error-handling} +#### Giriş hata yönetimi {#input-error-handling} -Doğal olarak, fonksiyonun başında bir çeşit girdi hatasını işlemek mantıklı olur. +Naturally, it makes sense to have some sort of input error handling at the start of the function. -Yüklü bir MetaMask uzantısı veya bağlı bir cüzdan yoksa \(yani aktarılan `address` boş bir dizeyse\) ya da `message` boş bir dizeyse fonksiyonumuzun erken dönüş yapmasını isteriz. Hadi `updateMessage`'a aşağıdaki hata işlemeleri ekleyelim: +We'll want our function to return early if there is no MetaMask extension installed, there is no wallet connected \(i.e., the `address` passed in is an empty string\), or the `message` is an empty string. Let's add the following error handling to `updateMessage`: ```javascript // interact.js @@ -1399,11 +1403,11 @@ export const updateMessage = async (address, message) => { } ``` -Artık düzgün bir girdi hatası işleme sistemimiz olduğuna göre, işlemi MetaMask üzerinden imzalama zamanı geldi demektir! +Now that it have proper input error handling, it's time to sign the transaction via MetaMask! -#### İşlemimizi imzalama {#signing-our-transaction} +#### Signing our transaction {#signing-our-transaction} -Geleneksel web3 Ethereum işlemleri ile haşır neşirseniz, az sonra yazacağımız kod tanıdık gelecektir. Girdi hatası işleme kodunuzun altında `updateMessage`'a şunları ekleyin: +If you're already comfortable with traditional web3 Ethereum transactions, the code we write next will be very familiar. Below your input error handling code, add the following to `updateMessage`: ```javascript // interact.js @@ -1441,20 +1445,20 @@ try { } ``` -Olan biteni açıklayalım. Önce, işlem parametrelerimizi oluşturuyoruz; burada: +Let's breakdown what's happening. First, we set up our transactions parameters, where: -- `to` alıcı adresini belirtir \(akıllı sözleşmemiz\) -- `from`, fonksiyonumuza aktardığımız `address` değişkeni olan işlemin imzalayıcısını belirtir -- `data` ise Merhaba Dünya akıllı sözleşmesinin `update` yöntemlerine yönelik çağrıları içerir ve `message` dizesi değişkenlerini girdi olarak alır +- `to` alıcı adresini belirtir (akıllı sözleşmemiz) +- `from` specifies the signer of the transaction, the `address` variable we passed into our function +- `data` contains the call to our Hello World smart contract's `update` method, receiving our `message` string variable as input -Ardından, MetaMask'ten işlemi imzalamasını istediğimiz bir `window.ethereum.request` bekleme çağrısı yaparız. 11. ve 12. satırlarda eth yöntemimizi, `eth_sendTransaction`, belirttiğimizi ve `transactionParameters`'ımıza aktardığımızı gözdn kaçırmayın. +Then, we make an await call, `window.ethereum.request`, where we ask MetaMask to sign the transaction. Notice, on lines 11 and 12, we're specifying our eth method, `eth_sendTransaction`and passing in our `transactionParameters`. Bu noktada, MetaMask tarayıcıda açılır ve kullanıcıdan işlemi imzalamasını veya reddetmesini ister. -- İşlem başarılı olursa fonksiyon, `status` JSX dizesinin kullanıcıya Etherscan'den işlem hakkında daha fazla bilgi edinmesini anımsattığı bir JSON nesnesi döndürür. -- İşlem başarısız olursa fonksiyon, `status` dizesinin hata mesajını aktardığı bir JSON öğesi döndürür. +- If the transaction is successful, the function will return a JSON object where the `status` JSX string prompts the user to check out Etherscan for more information about their transaction. +- If the transaction fails, the function will return a JSON object where the `status` string relays the error message. -Toparlarsak, `updateMessage` fonksiyonumuz şu şekilde görünmelidir: +Altogether, our `updateMessage` function should look like this: ```javascript // interact.js @@ -1508,11 +1512,11 @@ export const updateMessage = async (address, message) => { } ``` -Son ama bir o kadar da önemli olarak, `updateMessage` fonksiyonumuzu `HelloWorld.js` bileşenimize bağlamalıyız. +Last but not least, we need to connect our `updateMessage` function to our `HelloWorld.js` component. -#### `updateMessage`'ı `HelloWorld.js` ön yüzüne bağlama {#connect-updatemessage-to-the-helloworld-js-frontend} +#### Connect `updateMessage` to the `HelloWorld.js` frontend {#connect-updatemessage-to-the-helloworld-js-frontend} -`onUpdatePressed` fonksiyonumuz içeri aktarılan `updateMessage` fonksiyonuna bir bekleme çağrısı yapmalı ve `status` durum değişkenini işlemimizin başarılı ya da başarısız olduğunu yansıtacak şekilde güncellemelidir: +Our `onUpdatePressed` function should make an await call to the imported `updateMessage` function and modify the `status` state variable to reflect whether our transaction succeeded or failed: ```javascript // HelloWorld.js @@ -1523,18 +1527,18 @@ const onUpdatePressed = async () => { } ``` -Bu çok açık ve basit. Bilin bakalım ne oldu? MERKEZİYETSİZ UYGULAMANIZ TAMAMLANDI!!! +It's super clean and simple. And guess what... YOUR DAPP IS COMPLETE!!! -Devam edin ve **Güncelle** butonunu test edin! +Go ahead and test out the **Update** button! -### Kişiye özel merkeziyetsiz uygulamanızı üretin {#make-your-own-custom-dapp} +### Make your own custom dapp {#make-your-own-custom-dapp} -Tebrikler, öğreticinin sonuna geldiniz! Hatırlatma olarak, burada şunları nasıl yapacağınızı öğrendiniz: +Wooooo, you made it to the end of the tutorial! To recap, you learned how to: -- Merkeziyetsiz uygulama projenize bir MetaMask cüzdanı bağlama -- [Alchemy Web3](https://docs.alchemy.com/alchemy/documentation/alchemy-web3) API'sini kullanarak akıllı sözleşmenizden veri okumak -- MetaMask kullanarak Ethereum işlemlerini imzalamak +- Connect a MetaMask wallet to your dapp project +- Read data from your smart contract using the [Alchemy Web3](https://docs.alchemy.com/alchemy/documentation/alchemy-web3) API +- Sign Ethereum transactions using MetaMask -Artık bu öğreticide size verilmiş olan bu becerileri kullanarak kendi kişisel merkeziyetsiz uygulama projenizi yapabilirsiniz! Her zamanki gibi, herhangi bir sorunuz varsa yardım istemek için bize [Alchemy Discord](https://discord.gg/gWuC7zB) aracılığıyla ulaşmaktan çekinmeyin. 🧙‍♂️ +Now you're fully equipped to apply the skills from this tutorial to build out your own custom dapp project! As always, if you have any questions, don't hesitate to reach out to us for help in the [Alchemy Discord](https://discord.gg/gWuC7zB). 🧙‍♂️ -Bu öğreticiyi bitirdiğinize, yaşadığınız deneyimi ya da yorumlarınızı Twitter'dan [@alchemyplatform](https://twitter.com/AlchemyPlatform) bizi etiketleyerek aktarabilirsiniz! +Once you complete this tutorial, let us know how your experience was or if you have any feedback by tagging us on Twitter [@alchemyplatform](https://twitter.com/AlchemyPlatform)! diff --git a/public/content/translations/tr/developers/tutorials/hello-world-smart-contract/index.md b/public/content/translations/tr/developers/tutorials/hello-world-smart-contract/index.md index 4b6d3489ffc..7dd88af538d 100644 --- a/public/content/translations/tr/developers/tutorials/hello-world-smart-contract/index.md +++ b/public/content/translations/tr/developers/tutorials/hello-world-smart-contract/index.md @@ -1,73 +1,69 @@ --- -title: Yeni Başlayanlar için Merhaba Dünya Akıllı Sözleşmesi -description: Ethereum üzerinde basit bir akıllı sözleşme yazma ve dağıtmaya yönelik giriş seviyesinde öğretici. +title: "Yeni Başlayanlar için Merhaba Dünya Akıllı Sözleşmesi" +description: "Ethereum'da basit bir akıllı sözleşme yazma ve dağıtma üzerine başlangıç seviyesi bir öğretici." author: "elanh" tags: - - "solidity" - - "hardhat" - - "alchemy" - - "akıllı sözleşmeler" - - "dağıtma" + [ + "katılık", + "hardhat", + "alchemy", + "akıllı kontratlar", + "dağıtma" + ] skill: beginner lang: tr published: 2021-03-31 --- -Blok zinciri geliştirme konusunda yeniyseniz ve nereden başlayacağınızı bilmiyorsanız veya akıllı sözleşmelerin nasıl dağıtıldığını ve bunlarla nasıl etkileşime geçileceğini anlamak istiyorsanız bu rehber tam size göre. Size Goerli test ağında [MetaMask](https://metamask.io/), [Solidity](https://docs.soliditylang.org/en/v0.8.0/), [Hardhat](https://hardhat.org/) ve [Alchemy](https://alchemyapi.io/eth)'yi kullanarak basit bir akıllı sözleşme oluşturmayı ve dağıtmayı göstereceğiz (bunların ne anlama geldiğini henüz bilmiyorsanız endişelenmeyin, anlatacağız). +Blok zinciri geliştirme konusunda yeniyseniz ve nereden başlayacağınızı bilmiyorsanız veya sadece akıllı sözleşmelerin nasıl dağıtılacağını ve onlarla nasıl etkileşim kurulacağını anlamak istiyorsanız, bu kılavuz tam size göre. Sanal bir [MetaMask](https://metamask.io/) cüzdanı, [Solidity](https://docs.soliditylang.org/en/v0.8.0/), [Hardhat](https://hardhat.org/) ve [Alchemy](https://www.alchemy.com/eth) kullanarak Sepolia test ağında basit bir akıllı sözleşme oluşturma ve dağıtma sürecini adım adım anlatacağız (bu terimlerin ne anlama geldiğini henüz bilmiyorsanız endişelenmeyin, açıklayacağız). -> **Uyarı** -> -> 🚧 Kullanımdan Kaldırma Bildirimi -> -> Bu rehberin tamamında, sözleşme oluşturmak ve dağıtmak için Goerli test ağı kullanılacaktır. Yine de, Ethereum Foundation'ın [Goerli'nin yakında kullanımdan kaldırılacağını duyurduğunu](https://www.alchemy.com/blog/goerli-faucet-deprecation) lütfen unutmayın. -> -> Bu öğretici için [Sepolia'yı](https://www.alchemy.com/overviews/sepolia-testnet) ve [Sepolia musluğunu](https://sepoliafaucet.com/) kullanmanızı öneriyoruz. +Bu öğreticinin [2. bölümünde](https://docs.alchemy.com/docs/interacting-with-a-smart-contract), akıllı sözleşmemiz dağıtıldıktan sonra onunla nasıl etkileşim kurabileceğimizi ele alacağız ve [3. bölümde](https://www.alchemy.com/docs/submitting-your-smart-contract-to-etherscan) ise Etherscan'de nasıl yayınlayacağımızı anlatacağız. -Bu öğreticinin [2. bölümünde](https://docs.alchemy.com/docs/interacting-with-a-smart-contract) sözleşmemiz burada dağıtıldığında akıllı sözleşmemizle nasıl etkileşim kurabileceğimizi ele alacak ve [3. bölümde](https://docs.alchemy.com/docs/submitting-your-smart-contract-to-etherscan) sözleşmenizi Etherscan'de nasıl yayımlayacağınızı anlatacağız. - -Herhangi bir noktada sorularınız varsa, [Alchemy Discord](https://discord.gg/gWuC7zB)'da bize ulaşmaktan çekinmeyin! +Herhangi bir noktada sorularınız olursa [Alchemy Discord](https://discord.gg/gWuC7zB) üzerinden bize ulaşmaktan çekinmeyin! ## Adım 1: Ethereum ağına bağlanın {#step-1} -Ethereum zincirine istek göndermenin birçok yolu vardır. Basit olması için, kendi düğümlerimizi çalıştırmak zorunda kalmadan Ethereum zinciriyle iletişim kurmamıza izin veren bir blok zinciri geliştirici platformu ve API olan Alchemy'de ücretsiz bir hesap kullanacağız. Platform ayrıca, akıllı sözleşme dağıtımımızda arka planda neler olup bittiğini anlamak için bu öğreticide yararlanacağımız izleme ve analitik için geliştirici araçlarına sahiptir. Henüz bir Alchemy hesabınız yoksa, [buradan ücretsiz kaydolabilirsiniz](https://dashboard.alchemyapi.io/signup). +Ethereum zincirine istek göndermenin birçok yolu vardır. Basit olması için, kendi düğümlerimizi çalıştırmak zorunda kalmadan Ethereum zinciriyle iletişim kurmamıza olanak tanıyan bir blok zinciri geliştirici platformu ve API'si olan Alchemy'de ücretsiz bir hesap kullanacağız. Platform ayrıca, bu öğreticide akıllı sözleşme dağıtımımızın perde arkasında neler olup bittiğini anlamak için yararlanacağımız izleme ve analiz için geliştirici araçlarına da sahiptir. Henüz bir Alchemy hesabınız yoksa, [buradan ücretsiz olarak kaydolabilirsiniz](https://dashboard.alchemy.com/signup). ## Adım 2: Uygulamanızı (ve API anahtarınızı) oluşturun {#step-2} -Bir Alchemy hesabı oluşturduktan sonra, bir uygulama yaratarak bir API anahtarı oluşturabilirsiniz. Bu, Goerli test ağına taleplerde bulunmamızı sağlayacaktır. Eğer test ağlarına aşina değilseniz, [bu sayfaya](/developers/docs/networks/) bakınız. +Bir Alchemy hesabı oluşturduktan sonra, bir uygulama yaratarak bir API anahtarı oluşturabilirsiniz. Bu, Sepolia test ağına istekte bulunmamıza izin verecektir. Test ağlarına aşina değilseniz, [bu sayfaya](/developers/docs/networks/) göz atın. -1. İmlecinizi gezinme çubuğundaki "Apps"in (Uygulamalar) üzerine gelip "Create App"e (Uygulama Oluştur) tıklayarak Alchemy Gösterge Panelinizdeki "Create App" sayfasına gidin +1. Alchemy Panonuzda, gezinme çubuğundan "Bir uygulama seçin" ögesini seçip "Yeni uygulama oluştur" düğmesine tıklayarak "Yeni uygulama oluştur" sayfasına gidin. ![Merhaba dünya uygulama oluşturma](./hello-world-create-app.png) -2. Uygulamanıza "Merhaba Dünya" adını verin, kısa bir açıklama yazın, Ortam için "Hazırlama"yı (uygulama muhasebeniz için kullanılır) seçin ve ağınız olarak da "Goerli"yi seçin. +2. Uygulamanıza “Merhaba Dünya” adını verin, kısa bir açıklama sunun ve örneğin "Altyapı ve Araçlar" gibi bir kullanım durumu seçin. Ardından, "Ethereum" için arama yapın ve ağı seçin. + +![uygulama oluşturma görünümü merhaba dünya](./create-app-view-hello-world.png) -![merhaba dünya görüntüleme uygulamasını oluşturma](./create-app-view-hello-world.png) +3. Devam etmek için "İleri"ye, ardından “Uygulama oluştur”a tıklayın, hepsi bu kadar! Uygulamanız, kopyalanmaya hazır bir API Anahtarı ile birlikte gezinme çubuğundaki açılır menüde görünmelidir. -3. "Create app"e (Uygulama oluştur) tıklamanız yeterlidir! Uygulamanız aşağıdaki tabloda görünmelidir. +## Adım 3: Bir Ethereum hesabı (adres) oluşturun {#step-3} -## Adım 3: Bir Ethereum hesabı oluşturun (adres) {#step-3} +İşlem göndermek ve almak için bir Ethereum hesabına ihtiyacımız var. Bu öğretici için, Ethereum hesap adresinizi yönetmek için kullanılan tarayıcıda sanal bir cüzdan olan MetaMask'ı kullanacağız. [İşlemler](/developers/docs/transactions/) hakkında daha fazla bilgi. -İşlem göndermek ve almak için bir Ethereum hesabına ihtiyacımız var. Bu eğitim için, Ethereum hesap adresinizi yönetmek için kullanılan tarayıcı üstü bir sanal cüzdan olan MetaMask'i kullanacağız. [İşlemler](/developers/docs/transactions/) üzerine dahası. +[Buradan](https://metamask.io/download) MetaMask'ı indirebilir ve ücretsiz bir Ethereum hesabı oluşturabilirsiniz. Bir hesap oluştururken veya zaten bir hesabınız varsa, (gerçek parayla işlem yapmamak için) ağ açılır menüsünü kullanarak "Sepolia" test ağına geçtiğinizden emin olun. -[Buradan](https://metamask.io/download) ücretsiz olarak indirebilir ve bir Metamask hesabı oluşturabilirsiniz. Bir hesap oluştururken ya da zaten bir hesabınız varsa, sağ üstten "Goerli Test Ağına" geçin (bu sayede gerçek parayla denemeler yapmayız). +Sepolia'yı listede görmüyorsanız, menüye, ardından Gelişmiş'e gidin ve "Test ağlarını göster" seçeneğini açmak için aşağı kaydırın. Ağ seçim menüsünde, test ağları listesini bulmak için "Özel" sekmesini seçin ve "Sepolia"yı seçin. -![metamask ropsten örneği](./metamask-ropsten-example.png) +![metamask sepolia örneği](./metamask-sepolia-example.png) -## Adım 4: Bir Musluktan ether ekleyin {#step-4} +## Adım 4: Bir musluktan ether ekleyin {#step-4} -Akıllı sözleşmemizi test ağına dağıtmak için biraz sahte Eth'ye ihtiyacımız olacak. Eth alabilmek için [Goerli musluğuna](https://goerlifaucet.com/) gidip Alchemy hesabınıza giriş yapın ve cüzdan adresinizi girin, sonra da "Bana Eth gönder"e tıklayın. Ağ trafiği nedeniyle sahte Eth'nizi almanız biraz zaman alabilir. (Bunu yazarken denediğimizde, 30 dakika civarı sürdü) Eth'yi kısa süre içinde MetaMask hesabınızda görmelisiniz! +Akıllı sözleşmemizi test ağına dağıtmak için sahte Eth'ye ihtiyacımız olacak. Sepolia ETH almak için, çeşitli muslukların bir listesini görüntülemek üzere [Sepolia ağ ayrıntıları](/developers/docs/networks/#sepolia) sayfasına gidebilirsiniz. Biri çalışmazsa, başka birini deneyin çünkü bazen kaynakları tükenebilir. Ağ trafiği nedeniyle sahte ETH'nizi almanız biraz zaman alabilir. Kısa bir süre sonra MetaMask hesabınızda ETH'yi görmelisiniz! ## Adım 5: Bakiyenizi kontrol edin {#step-5} -Bakiyemizin yerinde olduğundan emin olmak için [Alchemy düzenleyici arayıcını](https://composer.alchemyapi.io?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D) kullanarak bir [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance) talebi oluşturalım. Bu, cüzdanımızdaki ETH miktarını döndürür. MetaMask hesap adresinizi girdikten ve "Send Request"e tıkladıktan sonra aşağıdaki gibi bir yanıt görmelisiniz: +Bakiyemizin orada olup olmadığını iki kez kontrol etmek için, [Alchemy'nin oluşturucu aracını](https://sandbox.alchemy.com/?network=ETH_SEPOLIA&method=eth_getBalance&body.id=1&body.jsonrpc=2.0&body.method=eth_getBalance&body.params%5B0%5D=&body.params%5B1%5D=latest) kullanarak bir [eth_getBalance](/developers/docs/apis/json-rpc/#eth_getbalance) isteği yapalım. Bu, cüzdanımızdaki ETH miktarını döndürür. MetaMask hesap adresinizi girdikten ve "Send Request"e tıkladıktan sonra aşağıdaki gibi bir yanıt görmelisiniz: ```json { "jsonrpc": "2.0", "id": 0, "result": "0x2B5E3AF16B1880000" } ``` -> **NOT:** Bu sonuç ETH değil, wei cinsindendir. Wei, ether'ın en küçük birimi olarak kullanılır. Wei'den ETH'ye dönüştürme: 1 eth = 1018 wei şeklindedir. Yani 0x2B5E3AF16B1880000'ı ondalık sayıya dönüştürürsek 5\*10¹⁸ elde ederiz ve bu da 5 ETH'ye eşittir. +> **NOT:** Bu sonuç ETH değil, wei cinsindendir. Wei, ether'ın en küçük birimi olarak kullanılır. wei'den ETH'ye dönüşüm: 1 eth = 1018 wei'dir. Yani 0x2B5E3AF16B1880000 ondalık sayıya dönüştürürsek, 5 ETH'ye eşit olan 5\*10¹⁸ değerini elde ederiz. > -> Vay be! Tüm sahte paramız yerli yerinde . +> Vay be! Sahte paramızın tamamı burada . ## Adım 6: Projemizi başlatın {#step-6} @@ -78,18 +74,18 @@ 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. Hâlihazırda npm kurulu değilse, [bu talimatları izleyin](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm) (Node.js'ye de ihtiyacımız olacak, onu da indirin!). +Artık proje klasörümüzün içinde olduğumuza göre projeyi başlatmak için `npm init` komutunu kullanacağız. Eğer npm zaten kurulu değilse, [bu talimatları](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm) izleyin (Node.js'e de ihtiyacımız olacak, bu yüzden onu da indirin!). ``` npm init ``` -Kurulum sorularına nasıl cevap verdiğiniz çok önemli değil; referans olması için nasıl yaptığımız aşağıda açıklanmıştır: +Kurulum sorularını nasıl yanıtladığınız gerçekten önemli değil, referans olması için bizim nasıl yaptığımız aşağıda verilmiştir: ``` package name: (hello-world) version: (1.0.0) -description: hello world smart contract +description: merhaba dünya akıllı sözleşmesi entry point: (index.js) test command: git repository: @@ -101,23 +97,23 @@ About to write to /Users/.../.../.../hello-world/package.json: { "name": "hello-world", "version": "1.0.0", - "description": "hello world smart contract", + "description": "merhaba dünya akıllı sözleşmesi", "main": "index.js", "scripts": { - "test": "echo \\"Error: no test specified\\" && exit 1" + "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" } ``` -package.json'ı onayladıktan sonra hazırız! +package.json dosyasını onaylayın ve artık hazırız! -## Adım 7: [Hardhat](https://hardhat.org/getting-started/#overview)'i indirin {#step-7} +## Adım 7: [Hardhat](https://hardhat.org/getting-started/#overview) İndirin {#step-7} 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. Bu geliştiricilere canlı zincirde dağıtmadan önce akıllı sözleşmelerini ve merkeziyetsiz uygulamalarını geliştirirken yardımcı olur. -`hello-world` projemizin içinde şunu yürütün: +`hello-world` projemizin içinde şunu çalıştırın: ``` npm install --save-dev hardhat @@ -145,15 +141,15 @@ Daha sonra bir karşılama mesajı ve ne yapmak istediğinizi seçme seçeneği 888 888 888 888 888 Y88b 888 888 888 888 888 Y88b. 888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888 -👷 Welcome to Hardhat v2.0.11 👷‍? +👷 Hardhat v2.0.11'e Hoş Geldiniz 👷‍? -Ne yapmak istersin? … -Create a sample project -❯ Create an empty hardhat.config.js -Quit +Ne yapmak istersiniz? … +Örnek bir proje oluştur +❯ Boş bir hardhat.config.js oluştur +Çıkış ``` -Bu, bizim için bir `hardhat.config.js` dosyası oluşturacak ve burada projemiz için tüm ayarları belirteceğiz (adım 13'te). +Bu, bizim için projemizin tüm kurulumunu belirleyeceğimiz bir `hardhat.config.js` dosyası oluşturacaktır (13. adımda). ## Adım 9: Proje klasörleri ekleyin {#step-9} @@ -164,55 +160,55 @@ mkdir contracts mkdir scripts ``` -- `contracts/` merhaba dünya akıllı sözleşme kod dosyamızı tutacağımız yerdir -- `scripts/`, sözleşmemizi dağıtmak ve etkileşim kurmak için komut dosyalarını tutacağımız yerdir +- `contracts/`, merhaba dünya akıllı sözleşme kodu dosyamızı tutacağımız yerdir +- `scripts/`, sözleşmemizi dağıtmak ve onunla etkileşim kurmak için komut dosyalarını tutacağımız yerdir ## Adım 10: Sözleşmemizi yazın {#step-10} -Ne zaman kod yazmaya başlayacağınızı merak ediyor olabilirsiniz. Evet, Adım 10'a kadar geldik. +Ne zaman kod yazmaya başlayacağımızı merak ediyor olabilirsiniz?? İşte geldik, 10. adıma. -Favori düzenleyicinizde hello-world projesini açın. (biz [VSCode](https://code.visualstudio.com/)'u tercih ediyoruz). Akıllı sözleşmeler, HelloWorld.sol akıllı sözleşmemizi yazmak için kullanacağımız Solidity adlı bir dilde yazılır.‌ +hello-world projesini favori düzenleyicinizde açın (biz [VSCode](https://code.visualstudio.com/)'u seviyoruz). Akıllı sözleşmeler, HelloWorld.sol akıllı sözleşmemizi yazmak için kullanacağımız Solidity adlı bir dilde yazılır.‌ -1. "Sözleşmeler" klasörüne gidin ve HelloWorld.sol adlı yeni bir dosya oluşturun -2. Aşağıda, bu öğretici için kullanacağımız Ethereum Vakfı'ndan örnek bir Hello World akıllı sözleşmesi bulunmaktadır. Aşağıdaki içeriği kopyalayıp HelloWorld.sol dosyanıza yapıştırın ve bu sözleşmenin ne yaptığını anlamak için yorumları okuduğunuzdan emin olun: +1. “contracts” klasörüne gidin ve HelloWorld.sol adında yeni bir dosya oluşturun. +2. Aşağıda, bu öğretici için kullanacağımız Ethereum Vakfı'ndan örnek bir Merhaba Dünya akıllı sözleşmesi bulunmaktadır. Aşağıdaki içeriği kopyalayıp HelloWorld.sol dosyanıza yapıştırın ve bu sözleşmenin ne yaptığını anlamak için yorumları okuduğunuzdan emin olun: ```solidity -// Specifies the version of Solidity, using semantic versioning. -// Learn more: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma +// Anlamsal sürümleme kullanarak Solidity sürümünü belirtir. +// Daha fazla bilgi edinin: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma pragma solidity ^0.7.0; -// Defines a contract named `HelloWorld`. -// A contract is a collection of functions and data (its state). Once deployed, a contract resides at a specific address on the Ethereum blockchain. Learn more: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html +// `HelloWorld` adında bir sözleşme tanımlar. +// Bir sözleşme, fonksiyonlar ve verilerden (durumundan) oluşan bir koleksiyondur. Dağıtıldıktan sonra, bir sözleşme Ethereum blok zincirinde belirli bir adreste bulunur. Daha fazla bilgi edinin: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html contract HelloWorld { - // Declares a state variable `message` of type `string`. - // State variables are variables whose values are permanently stored in contract storage. The keyword `public` makes variables accessible from outside a contract and creates a function that other contracts or clients can call to access the value. + // `string` türünde `message` adında bir durum değişkeni bildirir. + // Durum değişkenleri, değerleri kalıcı olarak sözleşme depolama alanında saklanan değişkenlerdir. `public` anahtar kelimesi, değişkenleri bir sözleşmenin dışından erişilebilir hale getirir ve diğer sözleşmelerin veya istemcilerin değere erişmek için çağırabileceği bir fonksiyon oluşturur. string public message; - // Similar to many class-based object-oriented languages, a constructor is a special function that is only executed upon contract creation. - // Constructors are used to initialize the contract's data. Learn more:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors + // Birçok sınıf tabanlı nesne yönelimli dilde olduğu gibi, kurucu yalnızca sözleşme oluşturulurken yürütülen özel bir fonksiyondur. + // Kurucular, sözleşmenin verilerini başlatmak için kullanılır. Daha fazla bilgi edinin: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors constructor(string memory initMessage) { - // Accepts a string argument `initMessage` and sets the value into the contract's `message` storage variable). + // `initMessage` dize bağımsız değişkenini kabul eder ve değeri sözleşmenin `message` depolama değişkenine ayarlar). message = initMessage; } - // A public function that accepts a string argument and updates the `message` storage variable. + // Bir dize bağımsız değişkenini kabul eden ve `message` depolama değişkenini güncelleyen bir genel fonksiyon. function update(string memory newMessage) public { message = newMessage; } } ``` -Bu, oluşturulduktan sonra bir mesaj depolayan ve `update` fonksiyonu çağrılarak güncellenebilen süper basit bir akıllı sözleşmedir. +Bu, oluşturma sırasında bir mesaj depolayan ve `update` fonksiyonu çağrılarak güncellenebilen çok basit bir akıllı sözleşmedir. -## Adım 11: MetaMask ve Alchemy'i projenize bağlayın {#step-11} +## Adım 11: MetaMask ve Alchemy'yi projenize bağlayın {#step-11} -Bir MetaMask cüzdanı ile Alchemy hesabı oluşturduk ve akıllı sözleşmemizi yazdık, şimdi üçünü birleştirme zamanı. +Bir MetaMask cüzdanı ve Alchemy hesabı oluşturduk ve akıllı sözleşmemizi yazdık, şimdi bu üçünü birbirine bağlama zamanı. Sanal 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ı (ve Alchemy API anahtarımızı) bir ortam dosyasında güvenle saklayabiliriz. -> İşlem gönderme hakkında daha fazla bilgi edinmek için web3 kullanarak işlem göndermeyle ilgili [bu öğreticiye](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) bakın. +> İşlem gönderme hakkında daha fazla bilgi edinmek için, web3 kullanarak işlem göndermeyle ilgili [bu öğreticiye](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) göz atın. İlk önce dotenv paketini proje dizininize kurun: @@ -220,37 +216,37 @@ Sanal cüzdanınızdan gönderilen her işlem, benzersiz özel anahtarınızı k npm install dotenv --save ``` -Ardından projemizin kök dizininde bir `.env` dosyası oluşturun ve buna Metamask özel anahtarınızı ve HTTP Alchemy API URL'nizi ekleyin. +Ardından, projemizin kök dizininde bir `.env` dosyası oluşturun ve MetaMask özel anahtarınızı ve HTTP Alchemy API URL'nizi buna ekleyin. -- Özel anahtarınızı almak için [şu talimatları](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key) takip edin -- HTTP Alchemy API URL'sini almak için aşağıya göz atın +- Özel anahtarınızı dışa aktarmak için [bu talimatları](https://support.metamask.io/configure/accounts/how-to-export-an-accounts-private-key/) izleyin. +- HTTP Alchemy API URL'sini almak için aşağıya bakın -![alchemy api anahtarı alma](./get-alchemy-api-key.gif) +![alchemy api anahtarını al](./get-alchemy-api-key.png) -Alchemy API URL'sini kopyalayın +Alchemy API URL'sini Kopyalayın `.env` dosyanız şu şekilde görünmelidir: ``` -API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key" +API_URL = "https://eth-sepolia.g.alchemy.com/v2/your-api-key" PRIVATE_KEY = "your-metamask-private-key" ``` -Bunları kodumuza gerçekten bağlamak için, adım 13'te `hardhat.config.js` dosyamızda bu değişkenlere başvuracağız. +Bunları gerçekten kodumuza bağlamak için 13. adımda `hardhat.config.js` dosyamızdaki bu değişkenlere başvuracağız. -.env doyasını taahhüt etmeyin! Lütfen .env dosyanızı asla kimseyle paylaşmadığınızdan veya ifşa etmediğinizden emin olun, çünkü bunu yaparken sırlarınızı tehlikeye atıyorsunuz. Sürüm kontrolü kullanıyorsanız, .env dosyanızı bir gitignore dosyasına ekleyin. +.env dosyasını commit'lemeyin! Lütfen .env dosyanızı asla kimseyle paylaşmadığınızdan veya ifşa etmediğinizden emin olun, çünkü bunu yaparken sırlarınızı tehlikeye atıyorsunuz. Sürüm kontrolü kullanıyorsanız, .env dosyanızı bir gitignore dosyasına ekleyin. -## Adım 12: Ethers.js'yi kurun {#step-12-install-ethersjs} +## Adım 12: Ethers.js'i Yükleyin {#step-12-install-ethersjs} -Ethers.js, [standart JSON-RPC yöntemlerini](/developers/docs/apis/json-rpc/) daha kullanıcı dostu yöntemlerle birleştirerek Ethereum'la etkileşimde bulunmayı ve Ethereum'a istek göndermeyi kolaylaştıran bir kütüphanedir. +Ethers.js, [standart JSON-RPC yöntemlerini](/developers/docs/apis/json-rpc/) daha kullanıcı dostu yöntemlerle sarmalayarak Ethereum ile etkileşim kurmayı ve istek göndermeyi kolaylaştıran bir kütüphanedir. -Hardhat, ek araçlar ve genişletilmiş işlevsellik için [Eklentiler](https://hardhat.org/plugins/)'i entegre etmeyi çok kolaylaştırır. Sözleşme dağıtımı için [Ethers eklentisinden](https://hardhat.org/docs/plugins/official-plugins#hardhat-ethers) yararlanacağız ([Ethers.js](https://github.com/ethers-io/ethers.js/)'nin bazı aşırı temiz sözleşme dağıtım yöntemleri vardır). +Hardhat, ek araçlar ve genişletilmiş işlevsellik için [Eklentileri](https://hardhat.org/plugins/) entegre etmeyi çok kolaylaştırır. Sözleşme dağıtımı için [Ethers eklentisinden](https://hardhat.org/docs/plugins/official-plugins#hardhat-ethers) yararlanacağız ([Ethers.js](https://github.com/ethers-io/ethers.js/) çok temiz sözleşme dağıtım yöntemlerine sahiptir). Proje klasörünüzde şunu yazın: @@ -258,13 +254,13 @@ Proje klasörünüzde şunu yazın: npm install --save-dev @nomiclabs/hardhat-ethers "ethers@^5.0.0" ``` -Bir sonraki adımda `hardhat.config.js`'mizde de ether'lara ihtiyacımız olacak. +Bir sonraki adımda `hardhat.config.js` dosyamızda da ethers gerektireceğiz. -## Adım 13: hardhat.config.js'yi güncelleyin {#step-13-update-hardhatconfigjs} +## Adım 13: hardhat.config.js dosyasını güncelleyin {#step-13-update-hardhatconfigjs} -Şimdiye kadar birkaç bağımlılık ve eklenti ekledik, şimdi projemizin bunların hepsini tanıması için `hardhat.config.js`'yi güncellememiz gerekiyor. +Şimdiye kadar birkaç bağımlılık ve eklenti ekledik, şimdi projemizin hepsini tanıması için `hardhat.config.js` dosyasını güncellememiz gerekiyor. -`hardhat.config.js` dosyanızı şöyle görünecek şekilde güncelleyin: +`hardhat.config.js` dosyanızı aşağıdaki gibi görünecek şekilde güncelleyin: ``` require('dotenv').config(); @@ -277,10 +273,10 @@ const { API_URL, PRIVATE_KEY } = process.env; */ module.exports = { solidity: "0.7.3", - defaultNetwork: "goerli", + defaultNetwork: "sepolia", networks: { hardhat: {}, - goerli: { + sepolia: { url: API_URL, accounts: [`0x${PRIVATE_KEY}`] } @@ -290,7 +286,7 @@ module.exports = { ## Adım 14: Sözleşmemizi derleyin {#step-14-compile-our-contracts} -Şimdiye kadar yaptığımız her şeyin çalıştığından emin olmak için sözleşmemizi derleyelim. `compile` görevi, yerleşik hardhat görevlerden biridir. +Şimdiye kadar yaptığımız 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 yürütün: @@ -298,21 +294,21 @@ Komut satırından şunu yürütün: npx hardhat compile ``` -`SPDX license identifier not provided in source file` uyarısı (Kaynak dosyada verilmeyen SPDX lisans tanımlayıcısı) alabilirsiniz, ancak bunun için endişelenmenize gerek yok, geri kalan her şey düzgün olacaktır! Düzgün değilse, istediğiniz zaman [Alchemy discord](https://discord.gg/u72VCg3)'da mesaj gönderebilirsiniz. +`SPDX license identifier not provided in source file` hakkında bir uyarı alabilirsiniz, ancak bunun için endişelenmenize gerek yok — umarız diğer her şey yolundadır! Sorun yaşarsanız [Alchemy Discord](https://discord.gg/u72VCg3) üzerinden her zaman mesaj atabilirsiniz. -## Adım 15: Dağıtım komut dosyamızı yazın {#step-15-write-our-deploy-scripts} +## Adım 15: Dağıtım betiğimizi yazın {#step-15-write-our-deploy-scripts} Artık sözleşmemiz yazıldığına ve yapılandırma dosyamız kullanıma hazır olduğuna göre, sözleşme dağıtım komut dosyanızı yazmanın zamanı geldi. -`scripts/` klasörüne gidin ve aşağıdaki içeriği ekleyerek `deploy.js` adlı yeni bir dosya oluşturun: +`scripts/` klasörüne gidin ve `deploy.js` adında yeni bir dosya oluşturup içine aşağıdaki içeriği ekleyin: ``` async function main() { const HelloWorld = await ethers.getContractFactory("HelloWorld"); - // Start deployment, returning a promise that resolves to a contract object + // Dağıtımı başlatır, bir sözleşme nesnesine çözümlenen bir promise döndürür const hello_world = await HelloWorld.deploy("Hello World!"); - console.log("Contract deployed to address:", hello_world.address);} + console.log("Sözleşme şu adrese dağıtıldı:", hello_world.address);} main() .then(() => process.exit(0)) @@ -322,48 +318,49 @@ main() }); ``` -Hardhat, bu kod satırlarının her birinin ne işe yaradığını [Sözleşme öğreticisinde](https://hardhat.org/tutorial/testing-contracts.html#writing-tests) harika bir şekilde açıklıyor, Hardhat açıklamalarını buraya aktardık. +Hardhat, [Sözleşmeler öğreticisinde](https://hardhat.org/tutorial/testing-contracts.html#writing-tests) bu kod satırlarının her birinin ne işe yaradığını harika bir şekilde açıklıyor, biz de buraya onların açıklamalarını aldı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 `HelloWorld`, merhaba dünya sözleşmemizin örnekleri için bir fabrikadır. `hardhat-ethers` eklentisini kullanırken `ContractFactory` ve `Contract` örnekleri varsayılan olarak ilk imzalayana bağlanır. +ethers.js'deki bir `ContractFactory`, yeni akıllı sözleşmeler dağıtmak için kullanılan bir soyutlamadır, bu nedenle buradaki `HelloWorld`, bizim merhaba dünya sözleşmemizin örnekleri için bir fabrikadır. `hardhat-ethers` eklentisini kullanırken, `ContractFactory` ve `Contract` örnekleri varsayılan olarak ilk imzalayana bağlanır. ``` const hello_world = await HelloWorld.deploy(); ``` -Bir `ContractFactory` üzerinde `deploy()` öğesinin çağrılması, dağıtımı başlatır ve bir `Contract` olarak çözümlenen bir `Promise` döndürür. Bu, akıllı sözleşme fonksiyonlarımızın her biri için bir yöntemi olan nesnedir. +Bir `ContractFactory` üzerinde `deploy()` çağırmak dağıtımı başlatır ve bir `Contract`'a çözümlenen bir `Promise` döndürür. Bu, akıllı sözleşme fonksiyonlarımızın her biri için bir yöntemi olan nesnedir. ## Adım 16: Sözleşmemizi dağıtın {#step-16-deploy-our-contract} -Sonunda akıllı sözleşmemizi uygulamaya hazırız! Komut satırına gidin ve şunu yürütün: +Sonunda akıllı sözleşmemizi uygulamaya hazırız! Komut satırına gidin ve şunu çalıştırın: ``` -npx hardhat run scripts/deploy.js --network goerli +npx hardhat run scripts/deploy.js --network sepolia ``` Daha sonra şöyle bir şey görmelisiniz: ``` -Contract deployed to address: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570 +Sözleşme şu adrese dağıtıldı: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570 ``` -[Goerli etherscan](https://goerli.etherscan.io/)'e gider ve sözleşme adresimizi aratırsak başarıyla dağıtılmış olduğunu görürüz. İşlem şunun gibi gözükecektir: +[Sepolia etherscan](https://sepolia.etherscan.io/) sitesine gider ve sözleşme adresimizi aratırsak, başarıyla dağıtıldığını görebilmeliyiz. İşlem şunun gibi gözükecektir: ![etherscan sözleşmesi](./etherscan-contract.png) -`From` (gönderen) adresi, MetaMask hesap adresinizle eşleşmelidir ve To (alıcı) adresinde "Contract Creation" (Sözleşme Oluşturma) yazacaktır ancak işleme tıklarsak `To` alanında sözleşme adresimizi göreceğiz: +`From` adresi, MetaMask hesap adresinizle eşleşmelidir ve `To` adresinde “Contract Creation” yazar, ancak işleme tıklarsak `To` alanında sözleşme adresimizi görürüz: ![etherscan işlemi](./etherscan-transaction.png) Tebrikler! Ethereum zincirine bir akıllı sözleşme dağıttınız 🎉 -Perde arkasında neler olduğunu anlamak için [Alchemy gösterge panelimizde](https://dashboard.alchemyapi.io/explorer) Explorer (Gezgin) sekmesine gidelim. Birden fazla Alchemy uygulamanız varsa, uygulamaya göre filtreleme yaptığınızdan ve "Hello World"ü seçtiğinizden emin olun. ![merhaba dünya gezgini](./hello-world-explorer.png) +Perde arkasında neler olduğunu anlamak için [Alchemy gösterge panelimizdeki](https://dashboard.alchemyapi.io/explorer) Explorer sekmesine gidelim. Birden fazla Alchemy uygulamanız varsa, uygulamaya göre filtrelediğinizden ve “Merhaba Dünya”yı seçtiğinizden emin olun. +![merhaba dünya gezgini](./hello-world-explorer.png) -Burada, `.deploy()` fonksiyonunu çağırdığımızda Hardhat/Ethers'ın bizim için arka planda yaptığı bir avuç JSON-RPC çağrısı göreceksiniz. Burada belirtilmesi gereken iki önemli şey, akıllı sözleşmemizi Goerli zincirine yazma isteği olan [`eth_sendRawTransaction`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_sendrawtransaction) ve karma değerine göre işlemimiz hakkındaki bilgileri okuma isteği olan (işlem gönderirken sık kullanılan bir şablon) [`eth_getTransactionByHash`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_gettransactionbyhash) öğeleridir. İşlem gönderme hakkında daha fazlasını öğrenmek için, [Web3 kullanarak işlem gönderme](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) üzerine olan şu öğreticiye göz atın +Burada, `.deploy()` fonksiyonunu çağırdığımızda Hardhat/Ethers'in bizim için perde arkasında yaptığı bir avuç JSON-RPC çağrısı göreceksiniz. Burada dikkat çekilmesi gereken iki önemli çağrı, aslında sözleşmemizi Sepolia zincirine yazma isteği olan [`eth_sendRawTransaction`](https://www.alchemy.com/docs/node/abstract/abstract-api-endpoints/eth-send-raw-transaction) ve karma değeri verildiğinde işlemimiz hakkındaki bilgileri okuma isteği olan [`eth_getTransactionByHash`](https://www.alchemy.com/docs/node/abstract/abstract-api-endpoints/eth-get-transaction-by-hash) çağrısıdır (işlemlerde tipik bir modeldir). İşlem gönderme hakkında daha fazla bilgi edinmek için, [Web3 kullanarak işlem gönderme](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) hakkındaki bu öğreticiye göz atın. -Öğreticinin 1. bölümü bu kadar, 2. bölümde ilk mesajımızı güncelleyerek [akıllı sözleşmemizle gerçekten etkileşime geçeceğiz](https://docs.alchemyapi.io/alchemy/tutorials/hello-world-smart-contract#part-2-interact-with-your-smart-contract) ve 3. bölümde herkesin akıllı sözleşmemizle nasıl [etkileşimde bulunacağını bilmesi için akıllı sözleşmemizi Etherscan'da](https://docs.alchemyapi.io/alchemy/tutorials/hello-world-smart-contract#optional-part-3-publish-your-smart-contract-to-etherscan) yayınlayacağız. +Bu öğreticinin 1. bölümü bu kadar; 2. bölümde, ilk mesajımızı güncelleyerek [akıllı sözleşmemizle gerçekten etkileşime gireceğiz](https://www.alchemy.com/docs/interacting-with-a-smart-contract) ve 3. bölümde herkesin onunla nasıl etkileşim kuracağını bilmesi için [akıllı sözleşmemizi Etherscan'de yayınlayacağız](https://www.alchemy.com/docs/submitting-your-smart-contract-to-etherscan). -**Alchemy hakkında daha fazla bilgi edinmek mi istiyorsunuz? [Web sitemize](https://alchemyapi.io/eth) göz atın. Hiç bir güncellemeyi kaçırmak istemiyor musunuz? Bültenimize [buradan](https://www.alchemyapi.io/newsletter) abone olun! Ayrıca [Twitter'ımızı](https://twitter.com/alchemyplatform) takip ettiğinizden ve [Discord'umuza](https://discord.com/invite/u72VCg3) katıldığınızdan da emin olun**. +**Alchemy hakkında daha fazla bilgi edinmek mi istiyorsunuz?** [Web sitemize](https://www.alchemy.com/eth) göz atın. Hiçbir güncellemeyi kaçırmak istemiyor musunuz? [Buradan](https://www.alchemy.com/newsletter) bültenimize abone olun! [Discord](https://discord.gg/u72VCg3) sunucumuza da katıldığınızdan emin olun.\*\*. diff --git a/public/content/translations/tr/developers/tutorials/how-to-implement-an-erc721-market/index.md b/public/content/translations/tr/developers/tutorials/how-to-implement-an-erc721-market/index.md index ba843f5ffb1..af3b46eae9c 100644 --- a/public/content/translations/tr/developers/tutorials/how-to-implement-an-erc721-market/index.md +++ b/public/content/translations/tr/developers/tutorials/how-to-implement-an-erc721-market/index.md @@ -1,12 +1,14 @@ --- -title: Bir ERC-721 pazarı nasıl uygulanır -description: Merkeziyetsiz bir ilan panosunda token'laştırılmış ürünler nasıl satışa sunulur +title: "Bir ERC-721 pazarı nasıl uygulanır" +description: "Merkeziyetsiz bir ilan panosunda token'laştırılmış ürünler nasıl satışa sunulur" author: "Alberto Cuesta Cañada" tags: - - "akıllı sözleşmeler" - - "erc-721" - - "katılık" - - "token'lar" + [ + "akıllı kontratlar", + "erc-721", + "solidity", + "token'lar" + ] skill: intermediate lang: tr published: 2020-03-19 @@ -22,17 +24,17 @@ Bunların tamamı internet ile değişti. Belirli bir ilan panosunu görebilen k Blok zinciri ile bu pazarlar bir kez daha değişmeye hazır, size nasıl olduğunu göstereyim. -## Para kazanma {#monetization} +## Para Kazanma {#monetization} Halka açık bir blok zinciri ilan panosunun iş modelinin Ebay'den ve bir şirketten farklı olması gerekecektir. -İlk olarak, [merkeziyetsizleşme açısı](/developers/docs/web2-vs-web3/) bulunmaktadır. Mevcut platformların kendi sunucularını sürdürmesi gerekir. Merkeziyetsiz bir platform kullanıcıları tarafından sürdürüldüğü için çekirdek platformu çalıştırmanın maliyeti, platform sahibi için sıfıra düşer. +Öncelikle, [merkeziyetsizleştirme açısı](/developers/docs/web2-vs-web3/) vardır. Mevcut platformların kendi sunucularını sürdürmesi gerekir. Merkeziyetsiz bir platform kullanıcıları tarafından sürdürüldüğü için çekirdek platformu çalıştırmanın maliyeti, platform sahibi için sıfıra düşer. -Ardından, platforma erişim sağlayan ön uç, web sitesi veya arayüz bulunuyor. Burada birçok seçenek bulunur. Platform sahipleri, erişimi kısıtlayabilir ve bir ücret karşılığında herkesi kendi arayüzünü kullanmaya zorlayabilir. Platform sahipleri ayrıca erişimi açmaya karar vererek (Güç İnsanlarda!) herkesin platform için arayüzler oluşturmasına izin verebilir. Veya mal sahipleri, bu aşırı uçların ortasında herhangi bir yaklaşıma karar verebilir. +Ardından, platforma erişim sağlayan ön uç, web sitesi veya arayüz bulunuyor. Burada birçok seçenek bulunur. Platform sahipleri, erişimi kısıtlayabilir ve bir ücret karşılığında herkesi kendi arayüzünü kullanmaya zorlayabilir. Platform sahipleri ayrıca erişimi açmaya karar verebilir (Güç Halkındır!) ve herkesin platforma arayüzler oluşturmasına izin verebilir. Veya mal sahipleri, bu aşırı uçların ortasında herhangi bir yaklaşıma karar verebilir. _Benden daha fazla vizyona sahip iş liderleri bundan nasıl para kazanılacağını bilirler. Tek gördüğüm şey, bunun statükodan farklı olduğu ve büyük ihtimalle bundan para kazanılabileceğidir._ -Bir de otomasyon ve ödeme açısı var. Bazı şeyler gayet [verimli şekilde token'laştırılarak](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com) bir ilan panosunda ticarete açılabilir. Token'laştırılmış varlıklar bir blok zincirinde kolayca aktarılır. Son derece karmaşık ödeme yöntemleri bir blok zincirinde kolayca uygulanabilir. +Bir de otomasyon ve ödeme açısı var. Bazı şeyler çok [etkili bir şekilde tokenleştirilebilir](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com) ve bir seri ilanlar panosunda takas edilebilir. Token'laştırılmış varlıklar bir blok zincirinde kolayca aktarılır. Son derece karmaşık ödeme yöntemleri bir blok zincirinde kolayca uygulanabilir. Burada bir iş fırsatı kokusu alıyorum. İşletme maliyeti olmayan bir ilan panosu, her işleme dahil edilen karmaşık ödeme yollarıyla kolayca uygulanabilir. Eminim birileri bunu ne için kullanacağına dair bir fikir bulacaktır. @@ -40,9 +42,9 @@ Bunu inşa etmenin verdiği mutluluk benim için yeterli. Hadi koda bir göz ata ## Uygulama {#implementation} -Bir süre önce, iş örneği uygulamaları ve başka farklı şeyler içeren bir [açık kaynak deposu](https://github.com/HQ20/contracts?ref=hackernoon.com) başlattık, lütfen bir göz atın. +Bir süre önce, iş durumu örnek uygulamaları ve diğer güzellikleri içeren bir [açık kaynaklı depo](https://github.com/HQ20/contracts?ref=hackernoon.com) başlattık, lütfen bir göz atın. -Bu [Ethereum İlan Panosu](https://github.com/HQ20/contracts/tree/master/contracts/classifieds?ref=hackernoon.com)'nun kodları oradadır, lütfen onları kullanın ve onlardan istediğiniz gibi faydalanın. Sadece kodun denetlenmediğini ve işin içine para katmadan önce kendi durum tespitinizi yapmanız gerektiğini unutmayın. +Bu [Ethereum Seri İlanlar Panosu](https://github.com/HQ20/contracts/tree/master/contracts/classifieds?ref=hackernoon.com) için kod orada, lütfen kullanın ve dilediğiniz gibi faydalanın. Sadece kodun denetlenmediğini ve işin içine para katmadan önce kendi durum tespitinizi yapmanız gerektiğini unutmayın. Panonun temelleri karmaşık değildir. Panodaki tüm reklamlar sadece birkaç alana sahip bir yapı olacaktır: @@ -51,7 +53,7 @@ struct Trade { address poster; uint256 item; uint256 price; - bytes32 status; // Open, Executed, Cancelled + bytes32 status; // Açık, Yürütüldü, İptal Edildi } ``` @@ -67,9 +69,9 @@ Eşleştirme kullanmak, yayınlamadan önce her reklam için bir kimlik bulmamı Ardından, ilgilendiğimiz bu öğelerin neler olduğu ve işlem için ödeme yapmak için kullanılan bu para biriminin ne olduğu sorusu geliyor. -Öğeler için, [dijital varlıklarla en iyi şekilde çalışmasına](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com) rağmen, gerçek dünya öğelerini bir blok zincirinde temsil etmenin bir yolu olan [ERC-721](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721.sol?ref=hackernoon.com) arayüzünü uygulamalarını isteyeceğiz. Yapıcıda kendi ERC721 sözleşmemizi belirteceğiz, yani ilan panomuzdaki herhangi bir varlığın önceden token'laştırılmış olması gerekir. +Öğeler için yalnızca, gerçek dünyadaki öğeleri bir blokzincirde temsil etmenin bir yolu olan [ERC-721](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721.sol?ref=hackernoon.com) arayüzünü uygulamalarını isteyeceğiz; her ne kadar [dijital varlıklarla en iyi şekilde çalışsa da](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com). Yapıcıda kendi ERC721 sözleşmemizi belirteceğiz, yani ilan panomuzdaki herhangi bir varlığın önceden token'laştırılmış olması gerekir. -Ödemeler için de benzer bir şey yapacağız. Birçok blok zinciri projesi, kendi [ERC-20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol?ref=hackernoon.com) kripto parasını tanımlar. Bazıları ise DAI gibi bir ana akım parayı kullanmayı tercih ediyor. Bu ilan panosunda, inşa sırasında para biriminize karar vermeniz yeterli olur. Kolay. +Ödemeler için de benzer bir şey yapacağız. Çoğu blokzincir projesi kendi [ERC-20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol?ref=hackernoon.com) kripto parasını tanımlar. Bazıları ise DAI gibi bir ana akım parayı kullanmayı tercih ediyor. Bu ilan panosunda, inşa sırasında para biriminize karar vermeniz yeterli olur. Kolay. ```solidity constructor ( @@ -108,7 +110,7 @@ function executeTrade(uint256 _trade) public { Trade memory trade = trades[_trade]; - require(trade.status == "Open", "Trade is not Open."); + require(trade.status == "Open", "Ticaret Açık değil."); currencyToken.transferFrom(msg.sender, trade.poster, trade.price); itemToken.transferFrom(address(this), msg.sender, trade.item); trades[_trade].status = "Executed"; @@ -127,16 +129,16 @@ function cancelTrade(uint256 _trade) Trade memory trade = trades[_trade]; require( msg.sender == trade.poster, - "Trade can be cancelled only by poster." + "Ticaret sadece gönderen tarafından iptal edilebilir." ); - require(trade.status == "Open", "Trade is not Open."); + require(trade.status == "Open", "Ticaret Açık değil."); itemToken.transferFrom(address(this), trade.poster, trade.item); trades[_trade].status = "Cancelled"; emit TradeStatusChange(_trade, "Cancelled"); } ``` -Bu kadar. Uygulamanın sonuna geldiniz. Kodla ifade edildiğinde bazı iş kavramlarının ne kadar kısa olduğu oldukça şaşırtıcıdır ve bu da o durumlardan biridir. [Depomuzda](https://github.com/HQ20/contracts/blob/master/contracts/classifieds/Classifieds.sol) tam sözleşmeye bakın. +Bu kadar. Uygulamanın sonuna geldiniz. Kodla ifade edildiğinde bazı iş kavramlarının ne kadar kısa olduğu oldukça şaşırtıcıdır ve bu da o durumlardan biridir. Sözleşmenin tamamını [depomuzda](https://github.com/HQ20/contracts/blob/master/contracts/classifieds/Classifieds.sol) kontrol edin. ## Sonuç {#conclusion} @@ -146,4 +148,4 @@ Bu kadar. Uygulamanın sonuna geldiniz. Kodla ifade edildiğinde bazı iş kavra Bu makalede, bir ilan panosu işinin ticari gerçekliği ile teknolojik uygulama arasında köprü kurmaya çalıştım. Bu bilgi, doğru becerilere sahipseniz, bir vizyon ve uygulama için bir yol haritası oluşturmanıza yardımcı olacaktır. -Her zaman olduğu gibi, eğlenceli bir şey inşa etmek istiyorsanız ve tavsiye almak istiyorsanız, lütfen [bana bir şeyler yazın](https://albertocuesta.es/)! Her zaman yardımcı olmaktan memnuniyet duyarım. +Her zaman olduğu gibi, eğlenceli bir şeyler inşa ediyorsanız ve tavsiye isterseniz, lütfen [bana ulaşın](https://albertocuesta.es/)! Her zaman yardımcı olmaktan memnuniyet duyarım.