diff --git a/public/content/translations/tr/developers/tutorials/how-to-mint-an-nft/index.md b/public/content/translations/tr/developers/tutorials/how-to-mint-an-nft/index.md index 8025ea396db..986d03b7c5e 100644 --- a/public/content/translations/tr/developers/tutorials/how-to-mint-an-nft/index.md +++ b/public/content/translations/tr/developers/tutorials/how-to-mint-an-nft/index.md @@ -1,28 +1,26 @@ --- -title: Bir NFT Nasıl Basılır (NFT Eğitim Serisi Bölüm 2/3) -description: Bu öğretici, akıllı sözleşmemizi ve Web3'ü kullanarak Ethereum blok zincirinde bir NFT'nin nasıl basılacağını açıklar. +title: "Bir NFT Nasıl Basılır (NFT Eğitim Serisi Bölüm 2/3)" +description: "Bu öğretici, akıllı sözleşmemizi ve Web3'ü kullanarak Ethereum blokzincirinde bir NFT'nin nasıl basılacağını açıklar." author: "Sumi Mudgil" -tags: - - "ERC-721" - - "alchemy" - - "katılık" - - "akıllı sözleşmeler" -skill: advanced +tags: ["ERC-721", "alchemy", "solidity", "smart contracts"] +skill: beginner lang: tr published: 2021-04-22 --- -[Beeple](https://www.nytimes.com/2021/03/11/arts/design/nft-auction-christies-beeple.html): 69 Milyon ABD Doları[3LAU](https://www.forbes.com/sites/abrambrown/2021/03/03/3lau-nft-nonfungible-tokens-justin-blau/?sh=5f72ef64643b): 11 Milyon ABD Doları [Grimes](https://www.theguardian.com/music/2021/mar/02/grimes-sells-digital-art-collection-non-fungible-tokens): 6 Milyon ABD Doları +[Beeple](https://www.nytimes.com/2021/03/11/arts/design/nft-auction-christies-beeple.html): 69 Milyon Dolar +[3LAU](https://www.forbes.com/sites/abrambrown/2021/03/03/3lau-nft-nonfungible-tokens-justin-blau/?sh=5f72ef64643b): 11 Milyon Dolar +[Grimes](https://www.theguardian.com/music/2021/mar/02/grimes-sells-digital-art-collection-non-fungible-tokens): 6 Milyon Dolar -Hepsi, Alchemy'nin güçlü API'sini kullanarak NFT'lerini bastı. Bu öğreticide, aynısını \<10 dakikada nasıl yapacağınızı size öğreteceğiz. +Hepsi, Alchemy'nin güçlü API'sini kullanarak NFT'lerini bastı. Bu öğreticide, aynısını \<10 dakika içinde nasıl yapacağınızı öğreteceğiz. -“NFT basımı”, blok zincirinde ERC-721 token'ınızın benzersiz bir örneğini yayınlama eylemidir. [NFT eğitim serisinin 1. Bölümündeki](/developers/tutorials/how-to-write-and-deploy-an-nft/) akıllı sözleşmemizi kullanarak Web3 becerilerimizi geliştirelim ve bir NFT basalım. Bu eğitimin sonunda, keyfinizin (ve cüzdanınızın) istediği kadar NFT basabileceksiniz! +“Bir NFT basmak”, ERC-721 jetonunuzun benzersiz bir örneğini blokzincirde yayınlama eylemidir. [Bu NFT öğretici serisinin 1. Bölümündeki](/developers/tutorials/how-to-write-and-deploy-an-nft/) akıllı sözleşmemizi kullanarak Web3 becerilerimizi sergileyelim ve bir NFT basalım. Bu öğreticinin sonunda, gönlünüzün (ve cüzdanınızın) çektiği kadar NFT basabileceksiniz! -Başlayalım! +Hadi başlayalım! -## Adım 1: Web3'ü yükleme {#install-web3} +## Adım 1: Web3'ü yükleyin {#install-web3} -NFT akıllı sözleşmenizi oluşturmaya ilişkin ilk öğreticiyi izlediyseniz, zaten Ethers.js kullanma deneyiminiz vardır. Web3, Ethereum blok zincirine istek oluşturmayı kolaylaştırmak için kullanılan bir kütüphane olduğu için Ethers'a benzer. Bu öğreticide, otomatik yeniden denemeler ve güçlü WebSocket desteği sunan gelişmiş bir Web3 kütüphanesi olan [Alchemy Web3](https://docs.alchemyapi.io/alchemy/documentation/alchemy-web3)'ü kullanacağız. +NFT akıllı sözleşmenizi oluşturmayla ilgili ilk öğreticiyi takip ettiyseniz Ethers.js kullanma konusunda zaten deneyiminiz vardır. Web3, Ethereum blokzincirine istek oluşturmayı kolaylaştırmak için kullanılan bir kütüphane olduğu için Ethers'a benzer. Bu öğreticide, otomatik yeniden denemeler ve sağlam WebSocket desteği sunan gelişmiş bir Web3 kütüphanesi olan [Alchemy Web3](https://docs.alchemyapi.io/alchemy/documentation/alchemy-web3)'ü kullanacağız. Projenizin ana dizininde şunu çalıştırın: @@ -30,7 +28,7 @@ Projenizin ana dizininde şunu çalıştırın: npm install @alch/alchemy-web3 ``` -## Adım 2: Bir `mint-nft.js` dosyası oluşturma {#create-mintnftjs} +## Adım 2: Bir `mint-nft.js` dosyası oluşturun {#create-mintnftjs} Komut dosyaları dizininizin içinde bir `mint-nft.js` dosyası oluşturun ve aşağıdaki kod satırlarını ekleyin: @@ -43,13 +41,13 @@ const web3 = createAlchemyWeb3(API_URL) ## Adım 3: Sözleşme ABI'nizi alın {#contract-abi} -Sözleşme ABI'miz (Uygulama İkili Arayüzü), akıllı sözleşmemizle etkileşim kurmak için kullanılan arayüzdür. Sözleşme ABI'lerı hakkında daha fazlasını [buradan](https://docs.alchemyapi.io/alchemy/guides/eth_getlogs#what-are-ab-is) öğrenebilirsiniz. Hardhat bizim için otomatik olarak bir ABI oluşturur ve bunu `MyNFT.json` dosyasına kaydeder. Bunu kullanmak için `mint-nft.js` dosyamıza aşağıdaki kod satırlarını ekleyerek içeriği ayrıştırmamız gerekir: +Sözleşme ABI'miz (Uygulama İkili Arayüzü), akıllı sözleşmemizle etkileşim kurma arayüzüdür. Sözleşme ABI'leri hakkında daha fazla bilgiyi [buradan](https://docs.alchemyapi.io/alchemy/guides/eth_getlogs#what-are-ab-is) edinebilirsiniz. Hardhat bizim için otomatik olarak bir ABI oluşturur ve bunu `MyNFT.json` dosyasına kaydeder. Bunu kullanabilmek için `mint-nft.js` dosyamıza aşağıdaki kod satırlarını ekleyerek içeriği ayrıştırmamız gerekecek: ```js const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json") ``` -ABI'yi görmek istiyorsanız onu konsolunuza yazdırabilirsiniz: +ABI'yi görmek isterseniz konsolunuza yazdırabilirsiniz: ```js console.log(JSON.stringify(contract.abi)) @@ -61,27 +59,27 @@ console.log(JSON.stringify(contract.abi)) node scripts/mint-nft.js ``` -## Adım 4: IPFS kullanarak NFT'niz için meta verileri yapılandırın {#config-meta} +## Adım 4: IPFS kullanarak NFT'nizin meta verilerini yapılandırın {#config-meta} -Bölüm 1'deki eğitimimizden hatırlarsanız, `mintNFT` akıllı sözleşme işlevimiz, NFT'nin meta verilerini tanımlayan bir JSON belgesine çözümlenmesi gereken bir tokenURI parametresi alır - bu gerçekten NFT'yi hayata geçiren şeydir ve bir ad, açıklama, resim ve diğer nitelikler gibi yapılandırılabilir özelliklere sahip olmasını sağlar. +1. Bölüm'deki öğreticimizden hatırlayacağınız üzere, `mintNFT` akıllı sözleşme fonksiyonumuz, NFT'nin meta verilerini açıklayan bir JSON belgesine çözümlenmesi gereken bir tokenURI parametresi alır. Bu meta veriler, NFT'yi gerçekten hayata geçiren, ad, açıklama, resim ve diğer nitelikler gibi yapılandırılabilir özelliklere sahip olmasını sağlayan şeydir. > _Gezegenler Arası Dosya Sistemi (IPFS), dağıtılmış bir dosya sisteminde veri depolamak ve paylaşmak için merkeziyetsiz bir protokol ve eşler arası ağdır._ -Uygun bir IPFS API'si ve araç takımı olan Pinata'yı, NFT'mizin gerçekten merkeziyetsiz olmasını sağlamak için, NFT varlığımızı ve meta verilerimizi depolamak için kullanacağız. Pinata hesabınız yoksa [buradan](https://app.pinata.cloud) ücretsiz bir hesap açın ve e-postanızı doğrulamak için adımları tamamlayın. +NFT varlığımızı ve meta verilerimizi depolamak ve NFT'mizin gerçekten merkeziyetsiz olmasını sağlamak için kullanışlı bir IPFS API ve araç takımı olan Pinata'yı kullanacağız. Pinata hesabınız yoksa [buradan](https://app.pinata.cloud) ücretsiz bir hesap için kaydolun ve e-postanızı doğrulamak için adımları tamamlayın. -Bir hesap oluşturduğunuzda: +Bir hesap oluşturduktan sonra: -- "Files" (Dosyalar) sayfasına gidin ve sayfanın sol üst köşesindeki mavi "Upload" (Yükle) düğmesine tıklayın. +- "Dosyalar" sayfasına gidin ve sayfanın sol üst köşesindeki mavi "Yükle" düğmesine tıklayın. -- Pinata'ya bir görüntü yükleyin; bu görüntü, NFT'nizin görüntü varlığı olacaktır. Varlığa istediğiniz adı verin +- Pinata'ya bir resim yükleyin — bu, NFT'nizin resim varlığı olacaktır. Varlığa dilediğiniz adı verebilirsiniz -- Yükledikten sonra, dosya bilgilerini "Dosyalar" sayfasındaki tabloda göreceksiniz. Ayrıca bir CID sütunu göreceksiniz. Yanındaki kopyala düğmesine tıklayarak CID'yi kopyalayabilirsiniz. Yüklemenizi `https://gateway.pinata.cloud/ipfs/` adresinde görebilirsiniz. Örnek olarak IPFS üzerinde kullandığımız resmi [burada](https://gateway.pinata.cloud/ipfs/QmZdd5KYdCFApWn7eTZJ1qgJu18urJrP9Yh1TZcZrZxxB5) bulabilirsiniz. +- Yükleme yaptıktan sonra, "Dosyalar" sayfasındaki tabloda dosya bilgilerini göreceksiniz. Ayrıca bir CID sütunu da göreceksiniz. Yanındaki kopyalama düğmesine tıklayarak CID'yi kopyalayabilirsiniz. Yüklemenizi şu adresten görüntüleyebilirsiniz: `https://gateway.pinata.cloud/ipfs/`. Örneğin, IPFS'de kullandığımız görseli [burada](https://gateway.pinata.cloud/ipfs/QmZdd5KYdCFApWn7eTZJ1qgJu18urJrP9Yh1TZcZrZxxB5) bulabilirsiniz. -Görsel olarak daha iyi öğrenenler için yukarıdaki adımlar burada özetlenmiştir: +Görsel öğrenenler için yukarıdaki adımlar burada özetlenmiştir: -![Sürücünüzü Pinata'ya nasıl yüklersiniz](./instructionsPinata.gif) +![Resminizi Pinata'ya nasıl yüklersiniz](./instructionsPinata.gif) -Şimdi Pinata'ya bir belge daha yüklememiz gerekecek. Ama bunu yapmadan önce, onu yaratmamız gerekiyor! +Şimdi Pinata'ya bir belge daha yükleyeceğiz. Ama bunu yapmadan önce onu oluşturmamız gerekiyor! Kök dizininizde `nft-metadata.json` adında yeni bir dosya oluşturun ve aşağıdaki json kodunu ekleyin: @@ -89,35 +87,35 @@ Kök dizininizde `nft-metadata.json` adında yeni bir dosya oluşturun ve aşağ { "attributes": [ { - "trait_type": "Breed", + "trait_type": "Cins", "value": "Maltipoo" }, { - "trait_type": "Eye color", + "trait_type": "Göz Rengi", "value": "Mocha" } ], - "description": "The world's most adorable and sensitive pup.", + "description": "Dünyanın en sevimli ve hassas köpeği.", "image": "ipfs://QmWmvTJmJU3pozR9ZHFmQC2DNDwi2XJtf3QGyYiiagFSWb", "name": "Ramses" } ``` -json'daki veriyi değiştirmekten çekinmeyin. Nitelikler bölümündekileri kaldırabilir veya buraya ekleme yapabilirsiniz. En önemlisi, görüntü alanının IPFS görüntünüzün konumunu gösterdiğinden emin olun: Aksi takdirde NFT'niz (çok sevimli!) bir köpeğin fotoğrafını içerecektir. +json'daki verileri değiştirmekten çekinmeyin. Nitelikler bölümüne ekleme veya çıkarma yapabilirsiniz. En önemlisi, resim alanının IPFS resminizin konumunu gösterdiğinden emin olun — aksi takdirde NFT'niz (çok sevimli!) bir fotoğraf içerecektir köpek. -JSON dosyasını düzenlemeyi tamamladıktan sonra kaydedin ve resmi yüklemek için kullandığımız adımları izleyerek Pinata'ya yükleyin. +JSON dosyasını düzenlemeyi bitirdikten sonra, kaydedin ve resmi yüklemek için yaptığımız adımların aynısını izleyerek Pinata'ya yükleyin. ![nft-metadata.json dosyanızı Pinata'ya nasıl yüklersiniz](./uploadPinata.gif) ## Adım 5: Sözleşmenizin bir örneğini oluşturun {#instance-contract} -Şimdi, sözleşmemizle etkileşime geçmek için, kodumuzda onun bir örneğini oluşturmalıyız. Bunu yapmak için dağıtımdan veya [Etherscan](https://sepolia.etherscan.io/)'den sözleşmeyi dağıtmak amacıyla kullandığınız adresi arayarak alabileceğimiz sözleşme adresimize ihtiyacımız olacak. +Şimdi, sözleşmemizle etkileşim kurmak için kodumuzda onun bir örneğini oluşturmamız gerekiyor. Bunu yapmak için, sözleşmeyi dağıtmak için kullandığınız adresi arayarak dağıtımdan veya [Blockscout](https://eth-sepolia.blockscout.com/) üzerinden alabileceğimiz sözleşme adresimize ihtiyacımız olacak. -![Etherscan'da sözleşme adresinizi görüntüleyin](./view-contract-etherscan.png) +![Sözleşme adresinizi Etherscan'de görüntüleyin](./view-contract-etherscan.png) -Yukarıdaki örnekte, sözleşme adresimiz 0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778'dir. +Yukarıdaki örnekte sözleşme adresimiz 0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778'dir. -Daha sonra, ABI ve adresi kullanarak sözleşmemizi oluşturmak için Web3 [sözleşme yöntemini](https://docs.web3js.org/api/web3-eth-contract/class/Contract) kullanacağız. `mint-nft.js` dosyanıza aşağıdakini ekleyin: +Ardından, ABI ve adresi kullanarak sözleşmemizi oluşturmak için Web3 [sözleşme yöntemini](https://docs.web3js.org/api/web3-eth-contract/class/Contract) kullanacağız. `mint-nft.js` dosyanıza aşağıdakileri ekleyin: ```js const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778" @@ -125,11 +123,11 @@ const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778" const nftContract = new web3.eth.Contract(contract.abi, contractAddress) ``` -## Adım 6: `.env` dosyasını güncelleme {#update-env} +## Adım 6: `.env` dosyasını güncelleyin {#update-env} -Şimdi, Ethereum zincirine işlemler oluşturmak ve göndermek amacıyla, hesap nonce değeri almak için genel Ethereum hesap adresinizi kullanacağız (aşağıda açıklanacaktır). +Şimdi, Ethereum zincirine işlem oluşturmak ve göndermek için, hesap nonce'unu (aşağıda açıklanacaktır) almak üzere halka açık Ethereum hesap adresinizi kullanacağız. -Açık anahtarınızı `.env` dosyanıza ekleyin; öğreticinin 1. bölümünü tamamladıysanız, `.env` dosyamız artık aşağıdaki gibi görünmelidir: +Açık anahtarınızı `.env` dosyanıza ekleyin — öğreticinin 1. bölümünü tamamladıysanız, `.env` dosyanız şimdi şöyle görünmelidir: ```js API_URL = "https://eth-sepolia.g.alchemy.com/v2/your-api-key" @@ -137,27 +135,27 @@ PRIVATE_KEY = "your-private-account-address" PUBLIC_KEY = "your-public-account-address" ``` -## Adım 7: İşleminizi oluşturma {#create-txn} +## Adım 7: İşleminizi oluşturun {#create-txn} -İlk olarak, `mintNFT(tokenData)` isimli bir fonksiyon tanımlayalım ve sıradakileri yaparak işlemimizi oluşturalım: +Öncelikle, `mintNFT(tokenData)` adında bir fonksiyon tanımlayalım ve aşağıdakileri yaparak işlemimizi oluşturalım: -1. _PRIVATE_KEY_ ve _PUBLIC_KEY_ anahtarlarınızı `.env` dosyasından alın. +1. `.env` dosyasından _PRIVATE_KEY_ ve _PUBLIC_KEY_ değerlerinizi alın. -1. Sonrasında, hesap nonce değerini bulmamız gerekecek. Nonce değeri detayı, adresinizden gönderilen işlem sayısını takip etmek için kullanılır: Buna, güvenlik amaçlarından dolayı ve [tekrar saldırılarını](https://docs.alchemyapi.io/resources/blockchain-glossary#account-nonce) engellemek için ihtiyacımız vardır. Adresinizden gönderilmiş işlem sayısını almak için, [getTransactionCount](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc#eth_gettransactioncount) kullanırız. +2. Sırada, hesap nonce'unu bulmamız gerekiyor. Nonce belirtimi, adresinizden gönderilen işlem sayısını takip etmek için kullanılır. Buna güvenlik amacıyla ve [tekrar saldırılarını](https://docs.alchemyapi.io/resources/blockchain-glossary#account-nonce) önlemek için ihtiyacımız vardır. Adresinizden gönderilen işlem sayısını almak için [getTransactionCount](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc#eth_gettransactioncount) kullanırız. -1. Son olarak, işlemimizi aşağıdaki bilgilerle ayarlayacağız: +3. Son olarak işlemimizi aşağıdaki bilgilerle ayarlayacağız: -- `'from': PUBLIC_KEY` — İşleminizin kaynağı, açık adresimizdir +- `'from': PUBLIC_KEY` — İşlemimizin kaynağı, halka açık adresimizdir -- `'to': ContractAddress` — Etkileşimde bulunmak ve işlemi göndermek istediğimiz sözleşme +- `'to': contractAddress` — Etkileşimde bulunmak ve işlemi göndermek istediğimiz sözleşme -- `'nonce': nonce` — Adresimizden gönderilen işlem sayısını içeren hesap nonce değeri +- `'nonce': nonce` — Adresimizden gönderilen işlem sayısını içeren hesap nonce'u -- `'gas': trialGas` — İşlemi tamamlamak için gereken tahmini gaz +- `'gas': estimatedGas` — İşlemi tamamlamak için gereken tahmini gaz -- `'data': nftContract.methods.mintNFT(PUBLIC_KEY, md).encodeABI()` — Bu işlemde gerçekleştirmek istediğimiz hesaplama: Bu durumda bir NFT basımıdır +- `'data': nftContract.methods.mintNFT(PUBLIC_KEY, md).encodeABI()` — Bu işlemde gerçekleştirmek istediğimiz hesaplama, ki bu durumda bir NFT basmaktır -`mint-nft.js` dosyanız artık bu şekilde görünmelidir: +`mint-nft.js` dosyanız şimdi şöyle görünmelidir: ```js require('dotenv').config(); @@ -173,9 +171,9 @@ PUBLIC_KEY = "your-public-account-address" const nftContract = new web3.eth.Contract(contract.abi, contractAddress); async function mintNFT(tokenURI) { - const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, 'latest'); //get latest nonce + const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, 'latest'); //en son nonce'u al - //the transaction + //işlem const tx = { 'from': PUBLIC_KEY, 'to': contractAddress, @@ -186,11 +184,11 @@ PUBLIC_KEY = "your-public-account-address" }​ ``` -## Adım 8: İşlemi imzalama {#sign-txn} +## Adım 8: İşlemi imzalayın {#sign-txn} -Artık işlemimizi oluşturduğumuza göre, göndermek için imzalamamız gerekiyor. Özel anahtarımızı burada kullanacağız. +İşlemimizi oluşturduğumuza göre, göndermek için imzalamamız gerekiyor. İşte burada özel anahtarımızı kullanacağız. -`web3.eth.sendSignedTransaction` bize, işlemimizin kazıldığından ve ağdan düşmediğinden emin olmak için kullanabileceğimiz işlem hash değeri verecektir. İşlem imzalama bölümünde, işlemimizin başarılı olup olmadığını anlamamız için bazı hata kontrolleri eklediğimizi göreceksiniz. +`web3.eth.sendSignedTransaction`, bize işlem hash değerini verir. Bunu, işlemimizin mine edildiğinden ve ağ tarafından düşürülmediğinden emin olmak için kullanabiliriz. İşlem imzalama bölümünde, işlemimizin başarılı olup olmadığını bilmemiz için bazı hata denetimleri eklediğimizi fark edeceksiniz. ```js require("dotenv").config() @@ -206,9 +204,9 @@ const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778" const nftContract = new web3.eth.Contract(contract.abi, contractAddress) async function mintNFT(tokenURI) { - const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") //get latest nonce + const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") //en son nonce'u al - //the transaction + //işlem const tx = { from: PUBLIC_KEY, to: contractAddress, @@ -225,13 +223,13 @@ async function mintNFT(tokenURI) { function (err, hash) { if (!err) { console.log( - "The hash of your transaction is: ", + "İşleminizin hash değeri: ", hash, - "\nCheck Alchemy's Mempool to view the status of your transaction!" + "\nİşleminizin durumunu görüntülemek için Alchemy'nin Mempool'unu kontrol edin!" ) } else { console.log( - "Something went wrong when submitting your transaction:", + "İşleminizi gönderirken bir şeyler ters gitti:", err ) } @@ -239,24 +237,24 @@ async function mintNFT(tokenURI) { ) }) .catch((err) => { - console.log(" Promise failed:", err) + console.log(" Promise başarısız oldu:", err) }) } ``` -## Adım 9: `mintNFT`'yi çağırma ve `mint-nft.js` düğümünü çalıştırma {#call-mintnft-fn} +## Adım 9: `mintNFT`'yi çağırın ve `node mint-nft.js`'yi çalıştırın {#call-mintnft-fn} -Pinata'ya yüklediğiniz `metadata.json`'ı hatırlıyor musunuz? Pinata'dan karma kodunu alın ve aşağıdakileri `mintNFT` `https://gateway.pinata.cloud/ipfs/` işlevine parametre olarak aktarın +Pinata'ya yüklediğiniz `metadata.json`'ı hatırlıyor musunuz? Pinata'dan hash kodunu alın ve `mintNFT` fonksiyonuna parametre olarak şunu geçin: `https://gateway.pinata.cloud/ipfs/` -Karma kodunu şu şekilde alırsınız: +Hash kodu şu şekilde alınır: -![Pinata'da nft meta veri hash kodunuzu nasıl alırsınız](./metadataPinata.gif)_Pinata'da nft meta veri hash kodunuzu nasıl alırsınız_ +![Pinata'da NFT meta veri hash kodunuzu nasıl alırsınız](./metadataPinata.gif)_Pinata'da NFT meta veri hash kodunuzu nasıl alırsınız_ -> Kopyaladığınız hash kodunun **metadata.json**'unuza yönlendirdiğini `https://gateway.pinata.cloud/ipfs/` sayfasını ayrı bir pencereye iki kez kontrol edin. Sayfa aşağıdaki ekran görüntüsüne benzer görünmelidir: +> `https://gateway.pinata.cloud/ipfs/` adresini ayrı bir pencerede yükleyerek kopyaladığınız hash kodunun **metadata.json** dosyanıza bağlandığını iki kez kontrol edin. Sayfa aşağıdaki ekran görüntüsüne benzer görünmelidir: -![Sayfanız json meta verilerini göstermelidir](./metadataJSON.png)_Sayfanız json meta verilerini göstermelidir_ +![Sayfanız json meta verilerini görüntülemelidir](./metadataJSON.png)_Sayfanız json meta verilerini görüntülemelidir_ -Sonuç olarak kodunuz şöyle görünmelidir: +Sonuç olarak, kodunuz şuna benzer görünmelidir: ```js require("dotenv").config() @@ -272,9 +270,9 @@ const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778" const nftContract = new web3.eth.Contract(contract.abi, contractAddress) async function mintNFT(tokenURI) { - const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") //get latest nonce + const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") //en son nonce'u al - //the transaction + //işlem const tx = { from: PUBLIC_KEY, to: contractAddress, @@ -291,13 +289,13 @@ async function mintNFT(tokenURI) { function (err, hash) { if (!err) { console.log( - "The hash of your transaction is: ", + "İşleminizin hash değeri: ", hash, - "\nCheck Alchemy's Mempool to view the status of your transaction!" + "\nİşleminizin durumunu görüntülemek için Alchemy'nin Mempool'unu kontrol edin!" ) } else { console.log( - "Something went wrong when submitting your transaction:", + "İşleminizi gönderirken bir şeyler ters gitti:", err ) } @@ -305,25 +303,27 @@ async function mintNFT(tokenURI) { ) }) .catch((err) => { - console.log("Promise failed:", err) + console.log("Promise başarısız oldu:", err) }) } mintNFT("ipfs://QmYueiuRNmL4MiA2GwtVMm6ZagknXnSpQnB3z2gWbz36hP") ``` -Şimdi, NFT'nizi dağıtmak için `node scripts/mint-nft.js` komutunu çalıştırın. Birkaç saniye sonra terminalinizde şöyle bir yanıt görmelisiniz: +Şimdi, NFT'nizi dağıtmak için `node scripts/mint-nft.js` komutunu çalıştırın. Birkaç saniye sonra, terminalinizde şuna benzer bir yanıt görmelisiniz: - The hash of your transaction is: 0x301791fdf492001fcd9d5e5b12f3aa1bbbea9a88ed24993a8ab2cdae2d06e1e8 + ``` + İşleminizin hash değeri: 0x301791fdf492001fcd9d5e5b12f3aa1bbbea9a88ed24993a8ab2cdae2d06e1e8 + + İşleminizin durumunu görüntülemek için Alchemy'nin Mempool'unu kontrol edin! + ``` - Check Alchemy's Mempool to view the status of your transaction! +Ardından, işleminizin durumunu (beklemede, mine edilmiş veya ağdan düşürülmüş) görmek için [Alchemy mempool'unuzu](https://dashboard.alchemyapi.io/mempool) ziyaret edin. İşleminiz düşürüldüyse, [Blockscout](https://eth-sepolia.blockscout.com/)'u kontrol etmek ve işlem hash değerinizi aramak da yararlıdır. -Sonrasında, işleminizin durumunu (beklemede, kazılmış veya ağdan düşürülmüş) görmek için [Alchemy bellek havuzunuzu](https://dashboard.alchemyapi.io/mempool) ziyaret edin. İşleminiz düştüyse, [Sepolia Etherscan](https://sepolia.etherscan.io/)'i kontrol etmek ve işlem karmanızı aramak da faydalı olur. +![NFT işlem hash değerinizi Etherscan'de görüntüleyin](./view-nft-etherscan.png)_NFT işlem hash değerinizi Etherscan'de görüntüleyin_ -![Etherscan'da NFT işlem hash değerinizi görüntüleyin](./view-nft-etherscan.png)_Etherscan'da NFT işlem hash değerinizi görüntüleyin_ +İşte bu kadar! Artık Ethereum blokzincirinde bir NFT'yi dağıttınız VE bastınız -İşte bu kadar! Ethereum blok zincirinde bir NFT ile dağıtım VE basım yaptınız +`mint-nft.js` kullanarak gönlünüzün (ve cüzdanınızın) çektiği kadar NFT basabilirsiniz! NFT'nin meta verilerini açıklayan yeni bir tokenURI girdiğinizden emin olun (aksi takdirde, farklı kimliklere sahip bir sürü aynı NFT'yi oluşturmuş olursunuz). -`mint-nft.js` kullanarak canınızın (ve cüzdanınızın) istediği kadar NFT basabilirsiniz! NFT'nin meta verilerini açıklayan yeni bir tokenURI'yi ilettiğinizden emin olun (aksi takdirde, sonuç olarak farklı kimliklere sahip bir sürü özdeş NFT oluşturursunuz). - -Büyük ihtimalle cüzdanınızda NFT'nizi gösterebilmek istersiniz: Bu nedenle [3. Bölüm: NFT'nizi Cüzdanınızda Nasıl Görüntüleyebilirsiniz](/developers/tutorials/how-to-view-nft-in-metamask/) kısmına göz atmayı unutmayın! +Muhtemelen NFT'nizi cüzdanınızda sergileyebilmek istersiniz — bu yüzden [Bölüm 3: NFT'nizi Cüzdanınızda Nasıl Görüntülersiniz](/developers/tutorials/how-to-view-nft-in-metamask/) bölümüne göz atmayı unutmayın! diff --git a/public/content/translations/tr/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md b/public/content/translations/tr/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md index 78aceac8dff..95be0831b9d 100644 --- a/public/content/translations/tr/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md +++ b/public/content/translations/tr/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md @@ -1,30 +1,26 @@ --- -title: Solidity akıllı sözleşmeleri test etmek için nasıl taklit edilir? -description: Neden sözleşmelerinizi test ederken dalga geçmelisiniz? +title: "Solidity akıllı sözleşmeleri test etmek için nasıl taklit edilir?" +description: "Neden sözleşmelerinizi test ederken dalga geçmelisiniz?" author: Markus Waas lang: tr -tags: - - "solidity" - - "akıllı kontratlar" - - "test etmek" - - "taklit etme" +tags: ["solidity", "smart contracts", "testing", "mocking"] skill: intermediate published: 2020-05-02 source: soliditydeveloper.com sourceUrl: https://soliditydeveloper.com/mocking-contracts --- -[Taklit nesneler](https://wikipedia.org/wiki/Mock_object) nesne yönelimli programlamada yaygın kullanılan bir tasarım modelidir. Fransızca'dan gelen "mocquer" kelimesi "dalga geçmek" anlamındadır. Bu kelime "gerçek olan bir şeyi taklit etmek" anlamına evrilmiştir ki bu, tam olarak programlamada yaptığımız şeydir. Akıllı sözleşmelerinizle lütfen sadece istediğiniz zaman dalga geçin ama her boş vaktinizde onları taklit edin. Bu, hayatınızı kolaylaştıracak. +[Taklit nesneler](https://wikipedia.org/wiki/Mock_object), nesne yönelimli programlamada yaygın olarak kullanılan bir tasarım modelidir. Fransızca'dan gelen "mocquer" kelimesi "dalga geçmek" anlamındadır. Bu kelime "gerçek olan bir şeyi taklit etmek" anlamına evrilmiştir ki bu, tam olarak programlamada yaptığımız şeydir. Akıllı sözleşmelerinizle lütfen sadece istediğiniz zaman dalga geçin ama her boş vaktinizde onları taklit edin. Bu, hayatınızı kolaylaştıracak. -## Sözleşmelere taklit yoluyla birim testi uygulama {#unit-testing-contracts-with-mocks} +## Taklit nesnelerle sözleşmelerin birim testi {#unit-testing-contracts-with-mocks} -Bir sözleşmeyi taklit etmek, sözleşmenin gerçek hali gibi davranan ve geliştirici tarafından kolayca kontrol edilebilen ikinci bir versiyonunu oluşturmak anlamına gelir. Genelde [sözleşmenin ufak bir bölümüne birim testi](/developers/docs/smart-contracts/testing/) yapmak istediğiniz karmaşık sözleşmelerle karşılaşırsınız. Buradaki sorun, ya bu ufak parçanın test edilmesi çok detaylı bir sözleşme durumu gerektiriyorsa ve buna ulaşmak zorsa? +Bir sözleşmeyi taklit etmek, sözleşmenin gerçek hali gibi davranan ve geliştirici tarafından kolayca kontrol edilebilen ikinci bir versiyonunu oluşturmak anlamına gelir. Çoğu zaman, yalnızca [sözleşmenin küçük kısımlarına birim testi yapmak](/developers/docs/smart-contracts/testing/) istediğiniz karmaşık sözleşmelerle karşılaşırsınız. Buradaki sorun, ya bu ufak parçanın test edilmesi çok detaylı bir sözleşme durumu gerektiriyorsa ve buna ulaşmak zorsa? Her seferinde sözleşmeyi istenen duruma getiren karmaşık bir test yazabilir veya "taklitlerle" işinizi kolayca halledebilirsiniz. Bir sözleşme, kalıtım yöntemiyle kolayca taklit edilebilir. Orijinal sözleşmeyi içeren ikinci bir taklit sözleşme yazın. Şimdi fonksiyonları taklit sözleşmeniz için geçersiz kılabilirsiniz. Bir örnekle görelim. ## Örnek: Özel ERC20 {#example-private-erc20} -Başlangıç özel zamanı olan örnek bir ERC-20 sözleşmesi kullanıyoruz. Sözleşmenin sahibi özel kullanıcıları yönetebilir ve başlangıçta yalnızca bu kullanıcıların jeton almasına izin verir. Belirli bir zaman geçtikten sonra herkes jetonları kullanabilecektir. Eğer merak ediyorsanız, OpenZeppelin sözleşmeleri v3 dahilindeki [`_beforeTokenTransfer`](https://docs.openzeppelin.com/contracts/5.x/extending-contracts#using-hooks)'i kullanıyoruz. +Başlangıç özel zamanı olan örnek bir ERC-20 sözleşmesi kullanıyoruz. Sözleşmenin sahibi özel kullanıcıları yönetebilir ve başlangıçta yalnızca bu kullanıcıların jeton almasına izin verir. Belirli bir zaman geçtikten sonra herkes jetonları kullanabilecektir. Merak ediyorsanız, yeni OpenZeppelin sözleşmeleri v3'ten gelen [`_beforeTokenTransfer`](https://docs.openzeppelin.com/contracts/5.x/extending-contracts#using-hooks) kancasını kullanıyoruz. ```solidity pragma solidity ^0.6.0; @@ -51,7 +47,7 @@ contract PrivateERC20 is ERC20, Ownable { function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override { super._beforeTokenTransfer(from, to, amount); - require(_validRecipient(to), "PrivateERC20: invalid recipient"); + require(_validRecipient(to), "PrivateERC20: geçersiz alıcı"); } function _validRecipient(address to) private view returns (bool) { @@ -87,20 +83,20 @@ contract PrivateERC20Mock is PrivateERC20 { Şu hata mesajlarından birini alacaksınız: -- `PrivateERC20Mock.sol: TypeError: Overriding function is missing "override" specifier.` -- `PrivateERC20.sol: TypeError: Trying to override non-virtual function. Did you forget to add "virtual"?.` +- `PrivateERC20Mock.sol: TypeError: Geçersiz kılan fonksiyon "override" niteleyicisini içermiyor.` +- `PrivateERC20.sol: TypeError: Sanal olmayan bir işlevi geçersiz kılmaya çalışılıyor. "virtual" eklemeyi unuttunuz mu?.` -Yeni 0.6 Solidity sürümünü kullandığımızdan geçersiz kılınabilecek fonksiyonlar için `virtual` anahtar kelimesini ve geçersiz kılma fonksiyonu için geçersiz kıl kelimesini eklememiz gerekir. Şimdi bunları her iki `isPublic` fonksiyonuna ekleyelim. +Yeni Solidity 0.6 sürümünü kullandığımız için, üzerine yazılabilecek fonksiyonlar için `virtual` anahtar kelimesini ve üzerine yazan fonksiyon için de override anahtar kelimesini eklemeliyiz. Öyleyse bunları her iki `isPublic` fonksiyonuna da ekleyelim. -Artık birim testlerinizde bunun yerine `PrivateERC20Mock` kullanabilirsiniz. Özel kullanım zamanlarında nasıl tepki vereceğini test etmek isterseniz, `setIsPublic(false)` komutunu ve `setIsPublic(true)` komutunu da genel kullanım zamanını test etmek için kullanabilirsiniz. Elbette bizim örneğimizde, zamanları buna göre değiştirmek için [zaman yardımcılarını](https://docs.openzeppelin.com/test-helpers/0.5/api#increase) da kullanabiliriz. Ancak taklit amacı artık açık olmalıdır ve bunun sadece zamanı ilerletmek kadar kolay olmadığı durumları hayal edebilirsiniz. +Artık birim testlerinizde bunun yerine `PrivateERC20Mock` kullanabilirsiniz. Özel kullanım süresi sırasındaki davranışı test etmek istediğinizde `setIsPublic(false)` kullanın ve benzer şekilde, genel kullanım süresini test etmek için `setIsPublic(true)` kullanın. Elbette örneğimizde, zamanları buna göre değiştirmek için [zaman yardımcılarını](https://docs.openzeppelin.com/test-helpers/0.5/api#increase) da kullanabiliriz. Ancak taklit amacı artık açık olmalıdır ve bunun sadece zamanı ilerletmek kadar kolay olmadığı durumları hayal edebilirsiniz. -## Çok sayıda sözleşmeyi taklit etme {#mocking-many-contracts} +## Birçok sözleşmeyi taklit etme {#mocking-many-contracts} -Her taklit için ayrı bir sözleşme oluşturmak karışıklık oluşturabilir. Eğer bu sizi rahatsız ediyorsa, [MockContract](https://github.com/gnosis/mock-contract) kütüphanesine bakabilirsiniz. Size anlık olarak sözleşmelerin davranışlarını değiştirme ve geçersiz kılma olanağı sağlar. Ancak, yalnızca diğer bir sözleşmeye yapılan taklitler için çalışır; bu nedenle, örneğimizde işe yaramaz. +Her taklit için ayrı bir sözleşme oluşturmak karışıklık oluşturabilir. Bu durum sizi rahatsız ediyorsa, [MockContract](https://github.com/gnosis/mock-contract) kütüphanesine göz atabilirsiniz. Size anlık olarak sözleşmelerin davranışlarını değiştirme ve geçersiz kılma olanağı sağlar. Ancak, yalnızca diğer bir sözleşmeye yapılan taklitler için çalışır; bu nedenle, örneğimizde işe yaramaz. -## Taklit etme, daha da güçlü olabilir {#mocking-can-be-even-more-powerful} +## Taklit etme daha da güçlü olabilir {#mocking-can-be-even-more-powerful} Taklit etmenin gücü burada bitmiyor. -- Fonksiyon ekleme: Sadece belirli bir işlevi geçersiz kılmak açısından değil, aynı zamanda ilave fonksiyonlar eklemek açısından da kullanışlıdır. Jetonlar için iyi bir örnek, herhangi bir kullanıcının ücretsiz olarak yeni jetonlar almasına izin vermek için ek bir `mint` işlevine sahip olmaktır. +- Fonksiyon ekleme: Sadece belirli bir işlevi geçersiz kılmak açısından değil, aynı zamanda ilave fonksiyonlar eklemek açısından da kullanışlıdır. Jetonlar için iyi bir örnek, herhangi bir kullanıcının ücretsiz olarak yeni jetonlar almasını sağlamak için ek bir `mint` işlevine sahip olmaktır. - Test ağlarında kullanım: Sözleşmelerinizi merkeziyetsiz uygulamalarınızla birlikte test ağlarına dağıtıp test ettiğinizde, taklit sürümlerini kullanmayı düşünün. Mecbur kalmadıkça fonksiyonları geçersiz kılmaktan kaçının. Sonuçta arkasındaki gerçek mantığı test etmek istiyorsunuz. Fakat örneğin, sözleşme durumunu en başa sıfırlayan ve yeni bir dağıtım gerektirmeyen bir sıfırlama işlevi eklemek de yararlı olabilir. Tabii ki de bunu bir Ana Ağ sözleşmesinde kullanmak istemezsiniz. diff --git a/public/content/translations/tr/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md b/public/content/translations/tr/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md index 24a78012d8c..e9f24187e01 100644 --- a/public/content/translations/tr/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md +++ b/public/content/translations/tr/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md @@ -1,17 +1,12 @@ --- -title: Akıllı sözleşmeleri test etmek için Echidna nasıl kullanılır -description: Akıllı sözleşmeleri otomatik olarak test etmek için Echidna nasıl kullanılır +title: "Akıllı sözleşmeleri test etmek için Echidna nasıl kullanılır" +description: "Akıllı sözleşmeleri otomatik olarak test etmek için Echidna nasıl kullanılır" author: "Trailofbits" lang: tr -tags: - - "solidity" - - "akıllı kontratlar" - - "güvenlik" - - "test etmek" - - "bulandırma" +tags: ["solidity", "smart contracts", "security", "testing", "fuzzing"] skill: advanced published: 2020-04-10 -source: Güvenli sözleşmeler oluşturmak +source: Building secure contracts sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/echidna --- @@ -26,7 +21,7 @@ docker pull trailofbits/eth-security-toolbox docker run -it -v "$PWD":/home/training trailofbits/eth-security-toolbox ``` -_Son komut, geçerli dizininize erişimi olan bir docker'da eth-security-toolbox'ı çalıştırır. Dosyaları ana makinenizden değiştirebilir ve dosyalar üzerindeki araçları docker'dan çalıştırabilirsiniz_ +_Son komut, geçerli dizininize erişimi olan bir docker'da eth-security-toolbox'ı çalıştırır. Dosyaları ana makinenizden değiştirebilir ve docker'dan dosyalar üzerindeki araçları çalıştırabilirsiniz_ Docker'ın içinde şunu çalıştırın: @@ -35,37 +30,37 @@ solc-select 0.5.11 cd /home/training ``` -### İkili {#binary} +### İkili dosya {#binary} [https://github.com/crytic/echidna/releases/tag/v1.4.0.0](https://github.com/crytic/echidna/releases/tag/v1.4.0.0) ## Özellik tabanlı bulandırmaya giriş {#introduction-to-property-based-fuzzing} -Echidna, önceki blog yazılarımızda tanımladığımız bir özellik tabanlı bulandırıcıdır ([1](https://blog.trailofbits.com/2018/03/09/echidna-a-smart-fuzzer-for-ethereum/), [2](https://blog.trailofbits.com/2018/05/03/state-machine-testing-with-echidna/), [3](https://blog.trailofbits.com/2020/03/30/an-echidna-for-all-seasons/)). +Echidna, önceki blog yazılarımızda ([1](https://blog.trailofbits.com/2018/03/09/echidna-a-smart-fuzzer-for-ethereum/), [2](https://blog.trailofbits.com/2018/05/03/state-machine-testing-with-echidna/), [3](https://blog.trailofbits.com/2020/03/30/an-echidna-for-all-seasons/)) açıkladığımız gibi özellik tabanlı bir bulandırıcıdır. ### Bulandırma {#fuzzing} -[Bulandırma ](https://wikipedia.org/wiki/Fuzzing) (Fuzzing), güvenlik topluluğunda iyi bilinen bir tekniktir. Programdaki hataları bulmak için hemen hemen rastgele girdiler oluşturmayı içerir. Geleneksel yazılım için bulandırıcılar ([AFL](http://lcamtuf.coredump.cx/afl/) veya [LibFuzzer](https://llvm.org/docs/LibFuzzer.html) gibi) hata tespiti için verimli araçlar olarak bilinirler. +[Bulandırma](https://wikipedia.org/wiki/Fuzzing), güvenlik topluluğunda iyi bilinen bir tekniktir. Programdaki hataları bulmak için aşağı yukarı rastgele girdiler oluşturmayı içerir. Geleneksel yazılımlar için bulandırıcıların ([AFL](http://lcamtuf.coredump.cx/afl/) veya [LibFuzzer](https://llvm.org/docs/LibFuzzer.html) gibi) hata bulmak için etkili araçlar olduğu bilinmektedir. Tamamen rastgele girdi oluşturmanın ötesinde, iyi girdiler üretmek için aşağıdakiler de dahil olmak üzere birçok teknik ve strateji vardır: -- Her yürütmeden geri bildirim alın ve bunu, oluşturmaya rehberlik etmek için kullanın. Örneğin, yeni oluşturulan bir girdi yeni bir yolun keşfine yol açıyorsa, ona yakın yeni girdiler oluşturmak mantıklı olabilir. -- Yapısal bir kısıtlamaya göre girdi oluşturma. Örneğin, girdiniz sağlama toplamı olan bir başlık içeriyorsa, bulandırıcının sağlama toplamını doğrulayan girdi oluşturmasına izin vermek mantıklı olacaktır. -- Yeni girdiler oluşturmak için bilinen girdileri kullanma: Eğer büyük bir geçerli girdi veri setine erişiminiz varsa, bulandırıcınız sıfırdan üretime başlamak yerine onlardan yeni girdiler üretebilir. Bunlara genellikle _tohum_ denir. +- Her yürütmeden geri bildirim alın ve bunu oluşturmaya rehberlik etmek için kullanın. Örneğin, yeni oluşturulan bir girdi yeni bir yolun keşfine yol açarsa, ona yakın yeni girdiler oluşturmak mantıklı olabilir. +- Yapısal bir kısıtlamaya göre girdi oluşturma. Örneğin, girdiniz bir sağlama toplamı içeren bir başlık içeriyorsa, bulandırıcının sağlama toplamını doğrulayan girdi oluşturmasına izin vermek mantıklı olacaktır. +- Yeni girdiler oluşturmak için bilinen girdileri kullanma: Büyük bir geçerli girdi veri kümesine erişiminiz varsa, bulandırıcınız sıfırdan oluşturmaya başlamak yerine bunlardan yeni girdiler üretebilir. Bunlara genellikle _tohumlar_ denir. -### Özellik temelli bulandırma {#property-based-fuzzing} +### Özellik tabanlı bulandırma {#property-based-fuzzing} -Echidna spesifik bir bulandırıcı ailesine mensuptur: özellik temelli bulandırma çoğunlukla [QuickCheck](https://wikipedia.org/wiki/QuickCheck)'ten ilham almıştır. Çökmeleri bulmaya çalışan klasik bulandırıcının aksine Echidna, kullanıcı tanımlı değişmezleri kırmaya çalışacaktır. +Echidna, özel bir bulandırıcı ailesine aittir: büyük ölçüde [QuickCheck](https://wikipedia.org/wiki/QuickCheck)'ten ilham alan özellik tabanlı bir bulandırma. Çökmeleri bulmaya çalışan klasik bulandırıcıların aksine Echidna, kullanıcı tanımlı değişmezleri kırmaya çalışacaktır. -Akıllı sözleşmelerde değişmezler, sözleşmenin ulaşabileceği herhangi bir yanlış veya geçersiz durumu temsil edebilen Solidity fonksiyonlarıdır: +Akıllı sözleşmelerde değişmezler, sözleşmenin ulaşabileceği ve aşağıdakileri içeren herhangi bir yanlış veya geçersiz durumu temsil edebilen Solidity fonksiyonlarıdır: -- Hatalı erişim denetimi: Saldırgan sözleşmenin sahibi oldu. -- Hatalı durum makinesi: Sözleşme duraklatılmışken token'lar aktarılabilir. -- Hatalı aritmetik: Kullanıcı bakiyesini yetersiz gösterip sınırsız ücretsiz token alabilir. +- Yanlış erişim denetimi: Saldırgan sözleşmenin sahibi oldu. +- Yanlış durum makinesi: Sözleşme duraklatılmışken jetonlar aktarılabilir. +- Yanlış aritmetik: kullanıcı bakiyesinde bir aşağı taşma yaratarak sınırsız ücretsiz jeton alabilir. ### Echidna ile bir özelliği test etme {#testing-a-property-with-echidna} -Echidna ile akıllı bir sözleşmenin nasıl test edileceğini göreceğiz. Hedef, aşağıdaki akıllı sözleşme [`token.sol`'dür](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/token.sol): +Echidna ile bir akıllı sözleşmenin nasıl test edileceğini göreceğiz. Hedef, aşağıdaki akıllı sözleşmedir: [`token.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/token.sol): ```solidity contract Token{ @@ -83,26 +78,26 @@ contract Token{ } ``` -Bu token'ın aşağıdaki özelliklere sahip olması gerektiği varsayımını yapacağız: +Bu jetonun aşağıdaki özelliklere sahip olması gerektiği varsayımında bulunacağız: -- Herkes en fazla 1000 token'a sahip olabilir -- Token transfer edilemez (bir ERC20 token'ı değildir) +- Herkes en fazla 1000 jetona sahip olabilir +- Jeton transfer edilemez (bu bir ERC20 jetonu değildir) -### Bir özellik yazın {#write-a-property} +### Bir özellik yazma {#write-a-property} -Echidna özellikleri, Solidity fonksiyonlarıdır. Bir özellikte şunlar bulunmalı: +Echidna özellikleri Solidity fonksiyonlarıdır. Bir özellik şunları yapmalıdır: -- Argümanı olmamalı -- Başarılıysa `true` döndürmeli -- Adı `echidna` ile başlıyor olmalı +- Argümanı olmamalıdır +- Başarılı olursa `true` döndürmelidir +- Adı `echidna` ile başlamalıdır -Echidna şunları yapacaktır: +Echidna şunları yapar: -- Özelliği test etmek için otomatik olarak rastgele işlemler oluşturacak. -- Bir özelliğin `false` döndürmesine veya bir hata vermesine neden olan tüm işlemleri bildirecek. -- Bir özelliği çağırırken yan etkiyi atacak (yani özellik bir durum değişkenini değiştirirse, testten sonra atılır) +- Özelliği test etmek için otomatik olarak rastgele işlemler oluşturur. +- Bir özelliğin `false` döndürmesine veya bir hata atmasına neden olan tüm işlemleri bildirir. +- Bir özelliği çağırırken yan etkiyi atar (yani, özellik bir durum değişkenini değiştirirse, testten sonra atılır) -Aşağıdaki özellik, çağıranın 1000'den fazla token'a sahip olup olmadığını kontrol eder: +Aşağıdaki özellik, çağıranın 1000'den fazla jetona sahip olmadığını kontrol eder: ```solidity function echidna_balance_under_1000() public view returns(bool){ @@ -110,7 +105,7 @@ function echidna_balance_under_1000() public view returns(bool){ } ``` -Sözleşmenizi özelliklerinizden ayırmak için kalıtımı kullanın: +Sözleşmenizi özelliklerinden ayırmak için kalıtım kullanın: ```solidity contract TestToken is Token{ @@ -120,28 +115,28 @@ contract TestToken is Token{ } ``` -[`token.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/token.sol) özelliği uygular ve token'dan kalıtım gerçekleştirir. +[`token.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/token.sol), özelliği uygular ve jetondan miras alır. -### Bir sözleşme başlatın {#initiate-a-contract} +### Bir sözleşme başlatma {#initiate-a-contract} -Echidna, argümanı olmayan bir [yapıcıya](/developers/docs/smart-contracts/anatomy/#constructor-functions) ihtiyaç duyar. Sözleşmenizin özel bir başlatmaya ihtiyacı varsa, bunu yapıcıda yapmanız gerekir. +Echidna'nın argümansız bir [kurucuya](/developers/docs/smart-contracts/anatomy/#constructor-functions) ihtiyacı vardır. Sözleşmenizin belirli bir başlatmaya ihtiyacı varsa, bunu kurucuda yapmanız gerekir. Echidna'da bazı özel adresler vardır: -- `0x00a329c0648769A73afAc7F9381E08FB43dBEA72` yapıcıyı çağırır. -- `0x10000`, `0x20000`, ve `0x00a329C0648769a73afAC7F9381e08fb43DBEA70` diğer fonksiyonları rastgele çağırır. +- `0x00a329c0648769A73afAc7F9381E08FB43dBEA72`, kurucuyu çağırır. +- `0x10000`, `0x20000` ve `0x00a329C0648769a73afAC7F9381e08fb43DBEA70`, diğer fonksiyonları rastgele çağırır. -Mevcut örneğimizde herhangi bir özel başlatmaya ihtiyacımız yok, bu yüzden yapıcımız boş. +Mevcut örneğimizde herhangi bir özel başlatmaya ihtiyacımız yok, bu nedenle kurucumuz boş. -### Echidna'yı çalıştırın {#run-echidna} +### Echidna'yı Çalıştırma {#run-echidna} -Echidna şöyle başlatılır: +Echidna şununla başlatılır: ```bash echidna-test contract.sol ``` -Contract.sol birden fazla sözleşme içeriyorsa hedefi belirtebilirsiniz: +Eğer contract.sol birden fazla sözleşme içeriyorsa, hedefi belirtebilirsiniz: ```bash echidna-test contract.sol --contract MyContract @@ -149,7 +144,7 @@ echidna-test contract.sol --contract MyContract ### Özet: Bir özelliği test etme {#summary-testing-a-property} -Aşağıdaki, örneğimizde echidna'nın çalışmasını özetler: +Aşağıdakiler, Echidna'nın örneğimizde çalıştırılmasını özetlemektedir: ```solidity contract TestToken is Token{ @@ -172,11 +167,12 @@ echidna_balance_under_1000: failed!💥 ... ``` -Echidna, `backdoor` çağrılırsa özelliğin ihlal edildiğini tespit etti. +Echidna, `backdoor` çağrılırsa özelliğin ihlal edildiğini buldu. -## Bir bulandırma işlemi sırasında çağrılacak filtreleme işlevleri {#filtering-functions-to-call-during-a-fuzzing-campaign} +## Bir bulandırma kampanyası sırasında çağrılacak fonksiyonları filtreleme {#filtering-functions-to-call-during-a-fuzzing-campaign} -Bulandırılacak fonksiyonların nasıl filtreleneceğini göreceğiz. Hedef, aşağıdaki akıllı sözleşmedir: +Bulandırmaya tabi tutulacak fonksiyonların nasıl filtreleneceğini göreceğiz. +Hedef, aşağıdaki akıllı sözleşmedir: ```solidity contract C { @@ -227,7 +223,9 @@ contract C { } ``` -Bu küçük örnek, Echidna'yı bir durum değişkenini değiştirmek için belirli bir işlem dizisini bulmaya zorlar. Bu bir bulandırıcı için zordur ([Manticore](https://github.com/trailofbits/manticore) gibi sembolik bir yürütme aracı kullanılması önerilir). Bunu doğrulamak için Echidna'yı çalıştırabiliriz: +Bu küçük örnek, Echidna'yı bir durum değişkenini değiştirmek için belirli bir işlem dizisi bulmaya zorlar. +Bu bir bulandırıcı için zordur ([Manticore](https://github.com/trailofbits/manticore) gibi sembolik bir yürütme aracı kullanılması önerilir). +Bunu doğrulamak için Echidna'yı çalıştırabiliriz: ```bash echidna-test multi.sol @@ -238,28 +236,30 @@ Seed: -3684648582249875403 ### Fonksiyonları filtreleme {#filtering-functions} -Echidna, iki sıfırlama fonksiyonu (`reset1` ve `reset2`) tüm durum değişkenlerini `false` olarak ayarlayacağından, bu sözleşmeyi test etmek için doğru sırayı bulmakta zorlanıyor. Ancak, sıfırlama fonksiyonunu kara listeye almak veya yalnızca `f`, `g`, `h` ve `i` fonksiyonlarını beyaz listeye almak için özel bir Echidna özelliğini kullanabiliriz. +İki sıfırlama fonksiyonu (`reset1` ve `reset2`) tüm durum değişkenlerini `false` olarak ayarlayacağından, Echidna bu sözleşmeyi test etmek için doğru diziyi bulmakta zorlanır. +Ancak, sıfırlama fonksiyonunu kara listeye almak veya yalnızca `f`, `g`, +`h` ve `i` fonksiyonlarını beyaz listeye almak için özel bir Echidna özelliği kullanabiliriz. -İşlevleri kara listeye almak için bu yapılandırma dosyasını kullanabiliriz: +Fonksiyonları kara listeye almak için bu yapılandırma dosyasını kullanabiliriz: ```yaml filterBlacklist: true filterFunctions: ["reset1", "reset2"] ``` -Fonksiyonları filtrelemek için başka bir yaklaşım, beyaz listeye alınan fonksiyonları listelemektir. Bunu yapmak için şu yapılandırma dosyasını kullanabiliriz: +Fonksiyonları filtrelemek için başka bir yaklaşım, beyaz listeye alınmış fonksiyonları listelemektir. Bunu yapmak için şu yapılandırma dosyasını kullanabiliriz: ```yaml filterBlacklist: false filterFunctions: ["f", "g", "h", "i"] ``` -- `filterBlacklist` varsayılan olarak `true` hâldedir. -- Filtreleme sadece ada göre yapılacaktır (parametreler olmadan). Eğer `f()` ve `f(uint256)` varsa, `"f"` filtresi iki fonksiyon ile de eşleşecektir. +- `filterBlacklist` varsayılan olarak `true` değerindedir. +- Filtreleme yalnızca isme göre (parametreler olmadan) gerçekleştirilecektir. `f()` ve `f(uint256)` fonksiyonlarınız varsa, `"f"` filtresi her iki fonksiyonla da eşleşecektir. -### Echidna'yı çalıştırın {#run-echidna-1} +### Echidna'yı Çalıştırma {#run-echidna-1} -Echidna'yı bir `blacklist.yaml` yapılandırma dosyası ile çalıştırmak için: +`blacklist.yaml` yapılandırma dosyasıyla Echidna'yı çalıştırmak için: ```bash echidna-test multi.sol --config blacklist.yaml @@ -272,11 +272,11 @@ echidna_state4: failed!💥 i() ``` -Echidna, özelliği tahrif edecek işlemlerin sırasını neredeyse anında bulacaktır. +Echidna, özelliği yanlışlayacak işlem dizisini neredeyse anında bulacaktır. ### Özet: Fonksiyonları filtreleme {#summary-filtering-functions} -Echidna, aşağıdakileri kullanarak bulanıklaştırma çalışması sırasında çağrılacak fonksiyonları kara veya beyaz listeye alabilir: +Echidna, bir bulandırma kampanyası sırasında çağrılacak fonksiyonları aşağıdakileri kullanarak kara listeye veya beyaz listeye alabilir: ```yaml filterBlacklist: true @@ -288,11 +288,11 @@ echidna-test contract.sol --config config.yaml ... ``` -Echidna, `f1`, `f2` ve `f3`'ü kara listeye alarak veya `filterBlacklist` boolean değerine göre yalnızca bunları çağırarak bir bulanıklaştırma çalışması başlatır. +Echidna, `filterBlacklist` boole değerine göre ya `f1`, `f2` ve `f3`'ü kara listeye alarak ya da sadece bunları çağırarak bir bulandırma kampanyası başlatır. -## Solidity'nin teyidi Echidna ile nasıl test edilir {#how-to-test-soliditys-assert-with-echidna} +## Echidna ile Solidity'nin assert'ünü test etme {#how-to-test-soliditys-assert-with-echidna} -Bu kısa öğreticide, sözleşmelerde teyit kontrolünü test etmek için Echidna'nın nasıl kullanılacağını göstereceğiz. Diyelim ki şuna benzer bir sözleşmemiz var: +Bu kısa öğreticide, sözleşmelerde iddia kontrolünü test etmek için Echidna'nın nasıl kullanılacağını göstereceğiz. Diyelim ki elimizde şöyle bir sözleşme var: ```solidity contract Incrementor { @@ -307,9 +307,10 @@ contract Incrementor { } ``` -### Bir teyit yazın {#write-an-assertion} +### Bir iddia yazma {#write-an-assertion} -Farkını döndürdükten sonra `tmp` öğesinin `counter` değerinden küçük veya eşit olduğundan emin olmak istiyoruz. Bir Echidna özelliği yazabiliriz, ancak `tmp` değerini bir yerde saklamamız gerekecek. Onun yerine, bunun gibi bir teyit kullanabilirdik: +Farklarını döndürdükten sonra `tmp`'nin `counter`'dan küçük veya ona eşit olduğundan emin olmak istiyoruz. Bir +Echidna özelliği yazabiliriz, ancak `tmp` değerini bir yerde saklamamız gerekir. Bunun yerine, şöyle bir iddia kullanabiliriz: ```solidity contract Incrementor { @@ -324,15 +325,15 @@ contract Incrementor { } ``` -### Echidna'yı çalıştırın {#run-echidna-2} +### Echidna'yı Çalıştırma {#run-echidna-2} -Teyit hatası testini etkinleştirmek için bir [Echidna yapılandırma dosyası](https://github.com/crytic/echidna/wiki/Config) `config.yaml` oluşturun: +İddia hatası testini etkinleştirmek için bir [Echidna yapılandırma dosyası](https://github.com/crytic/echidna/wiki/Config) olan `config.yaml` dosyasını oluşturun: ```yaml checkAsserts: true ``` -Bu sözleşmeyi Echidna'da çalıştırdığımızda, beklenen sonuçları elde ediyoruz: +Bu sözleşmeyi Echidna'da çalıştırdığımızda beklenen sonuçları elde ederiz: ```bash echidna-test assert.sol --config config.yaml @@ -346,15 +347,15 @@ assertion in inc: failed!💥 Seed: 1806480648350826486 ``` -Gördüğünüz gibi, Echidna `inc` fonksiyonunda bazı onaylama hataları bildiriyor. Fonksiyon başına birden fazla teyit eklemek mümkündür, ancak Echidna hangi iddianın başarısız olduğunu söyleyemez. +Gördüğünüz gibi, Echidna `inc` fonksiyonunda bir iddia hatası bildiriyor. Fonksiyon başına birden fazla iddia eklemek mümkündür, ancak Echidna hangi iddianın başarısız olduğunu söyleyemez. -### Teyitler nerede ve nasıl kullanılır {#when-and-how-use-assertions} +### İddialar ne zaman ve nasıl kullanılır {#when-and-how-use-assertions} -Teyitler, özellikle kontrol edilecek koşullar bazı `f` işlemlerinin doğru kullanımıyla doğrudan ilgiliyse, açık özelliklere alternatif olarak kullanılabilir. Bazı kodlardan sonra teyitler eklemek, kontrolün yürütüldükten hemen sonra yapılmasını zorunlu kılar: +İddialar, özellikle kontrol edilecek koşullar doğrudan bir `f` işleminin doğru kullanımıyla ilgiliyse, açık özelliklere alternatif olarak kullanılabilir. Bir koddan sonra iddia eklemek, kontrolün kod yürütüldükten hemen sonra gerçekleşmesini sağlar: ```solidity function f(..) public { - // some complex code + // karmaşık bir kod ... assert (condition); ... @@ -362,7 +363,7 @@ function f(..) public { ``` -Aksine, açık bir echidna özelliği kullanmak işlemleri rastgele yürütecektir ve tam olarak ne zaman kontrol edileceğini zorlamanın kolay bir yolu yoktur. Bu geçici çözümü yapmak hâlâ mümkündür: +Aksine, açık bir Echidna özelliği kullanmak işlemleri rastgele yürütecektir ve tam olarak ne zaman kontrol edileceğini zorlamanın kolay bir yolu yoktur. Yine de bu geçici çözümü uygulamak mümkündür: ```solidity function echidna_assert_after_f() public returns (bool) { @@ -371,22 +372,22 @@ function echidna_assert_after_f() public returns (bool) { } ``` -Ancak, bazı sorunlar vardır: +Ancak, bazı sorunlar var: -- `f` `internal` veya `external` olarak duyurulursa başarısız olur. -- `f`'u çağırmak için hangi bağımsız değişkenlerin kullanılması gerektiği açık değil. +- `f` `internal` veya `external` olarak bildirilirse başarısız olur. +- `f` fonksiyonunu çağırmak için hangi argümanların kullanılması gerektiği belirsizdir. - `f` geri dönerse, özellik başarısız olur. -Genel olarak, teyitlerin nasıl kullanılacağına ilişkin [John Regehr'in tavsiyesini](https://blog.regehr.org/archives/1091) izlemenizi öneririz: +Genel olarak, iddiaların nasıl kullanılacağı konusunda [John Regehr'in tavsiyesine](https://blog.regehr.org/archives/1091) uymanızı öneririz: -- Teyit kontrolü sırasında herhangi bir yan etkiyi zorlamayın. Örnek olarak: `assert(ChangeStateAndReturn() == 1)` -- Açık ifadeleri teyit etmeyin. Örnek olarak `var`'ın `uint` olarak duyurulduğu yerde `assert(var >= 0)` olması gibi. +- İddia kontrolü sırasında herhangi bir yan etkiyi zorlamayın. Örneğin: `assert(ChangeStateAndReturn() == 1)` +- Açık ifadeleri iddia etmeyin. Örneğin, `var` `uint` olarak bildirildiğinde `assert(var >= 0)`. -Son olarak, Echidna bunu algılamayacağı (ancak sözleşme yine de geri dönecek) için lütfen `assert` yerine `require` **kullanmayın**. +Son olarak, lütfen `assert` yerine `require` **kullanmayın**, çünkü Echidna bunu tespit edemeyecektir (ancak sözleşme yine de geri dönecektir). -### Özet: Teyit Kontrolü {#summary-assertion-checking} +### Özet: İddia Kontrolü {#summary-assertion-checking} -Aşağıdakiler, örneğimizde echidna'nın çalışmasını özetler: +Aşağıdakiler, Echidna'nın örneğimizde çalıştırılmasını özetlemektedir: ```solidity contract Incrementor { @@ -413,11 +414,11 @@ assertion in inc: failed!💥 Seed: 1806480648350826486 ``` -Echidna, bu fonksiyon büyük argümanlarla birden çok kez çağrılırsa `inc` içindeki teyidin başarısız olabileceğini buldu. +Echidna, bu fonksiyon büyük argümanlarla birden çok kez çağrılırsa `inc` içindeki iddianın başarısız olabileceğini buldu. -## Bir Echidna korpusunu toplama ve değiştirme {#collecting-and-modifying-an-echidna-corpus} +## Bir Echidna korpusu toplama ve değiştirme {#collecting-and-modifying-an-echidna-corpus} -Echidna ile bir işlem korpusunun nasıl toplanıp kullanılacağını göreceğiz. Hedef, aşağıdaki akıllı sözleşme [`magic.sol`'dur](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/magic.sol): +Echidna ile bir işlem korpusunun nasıl toplanacağını ve kullanılacağını göreceğiz. Hedef, aşağıdaki akıllı sözleşmedir: [`magic.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/magic.sol): ```solidity contract C { @@ -437,7 +438,9 @@ contract C { } ``` -Bu küçük örnek, Echidna'yı bir durum değişkenini değiştirmek için belirli değerleri bulmaya zorlar. Bu, bir bulandırıcı için zordur ([Manticore](https://github.com/trailofbits/manticore) gibi sembolik bir yürütme aracı kullanılması önerilir). Bunu doğrulamak için Echidna'yı çalıştırabiliriz: +Bu küçük örnek, Echidna'yı bir durum değişkenini değiştirmek için belirli değerleri bulmaya zorlar. Bu bir bulandırıcı için zordur +([Manticore](https://github.com/trailofbits/manticore) gibi sembolik bir yürütme aracı kullanılması önerilir). +Bunu doğrulamak için Echidna'yı çalıştırabiliriz: ```bash echidna-test magic.sol @@ -448,7 +451,7 @@ echidna_magic_values: passed! 🎉 Seed: 2221503356319272685 ``` -Ancak, bu bulandırma çalışmasını yürütürken korpus toplamak için hâlâ Echidna'yı kullanabiliriz. +Ancak, bu bulandırma kampanyasını yürütürken korpus toplamak için yine de Echidna'yı kullanabiliriz. ### Bir korpus toplama {#collecting-a-corpus} @@ -458,7 +461,7 @@ Korpus toplamayı etkinleştirmek için bir korpus dizini oluşturun: mkdir corpus-magic ``` -Bir [Echidna konfigürasyon dosyası](https://github.com/crytic/echidna/wiki/Config) `config.yaml` da oluşturun: +Ve bir [Echidna yapılandırma dosyası](https://github.com/crytic/echidna/wiki/Config) olan `config.yaml` dosyasını oluşturun: ```yaml coverage: true @@ -471,7 +474,8 @@ corpusDir: "corpus-magic" echidna-test magic.sol --config config.yaml ``` -Echidna hâlâ doğru sihirli değerleri bulamıyor ancak topladığı korpusa bakabiliriz. Örneğin bu dosyalardan biri şuydu: +Echidna hala doğru sihirli değerleri bulamıyor, ancak topladığı korpusa bakabiliriz. +Örneğin, bu dosyalardan biri şuydu: ```json [ @@ -516,17 +520,18 @@ Echidna hâlâ doğru sihirli değerleri bulamıyor ancak topladığı korpusa b ] ``` -Bu girdinin özelliğimizdeki başarısızlığı tetiklemeyeceği açıktır. Ancak bir sonraki adımda bunun için nasıl yapılandırılabileceğini göreceğiz. +Açıkçası, bu girdi özelliğimizdeki başarısızlığı tetiklemeyecektir. Ancak, bir sonraki adımda bunun için nasıl değiştirileceğini göreceğiz. -### Bir korpus tohumlama {#seeding-a-corpus} +### Bir korpusu besleme {#seeding-a-corpus} -Echidna'nın `magic` fonksiyonuyla başa çıkabilmesi için biraz yardıma ihtiyacı var. Bunun için uygun parametreleri kullanmak için girdiyi kopyalayıp değiştireceğiz: +Echidna'nın `magic` fonksiyonuyla başa çıkabilmesi için biraz yardıma ihtiyacı var. Bunun için uygun +parametreleri kullanmak üzere girdiyi kopyalayıp değiştireceğiz: ```bash cp corpus/2712688662897926208.txt corpus/new.txt ``` -`magic(42,129,333,0)` çağırması için `new.txt`'yi düzenleyeceğiz. Şimdi, Echidna'yı yeniden çalıştırabiliriz: +`magic(42,129,333,0)` fonksiyonunu çağırmak için `new.txt` dosyasını değiştireceğiz. Şimdi, Echidna'yı yeniden çalıştırabiliriz: ```bash echidna-test magic.sol --config config.yaml @@ -542,11 +547,11 @@ Seed: -7293830866560616537 ``` -Bu kez, özelliğin ihlal edildiğini hemen tespit etti. +Bu kez, özelliğin anında ihlal edildiğini buldu. -## Yüksek gaz tüketimi olan işlemleri bulma {#finding-transactions-with-high-gas-consumption} +## Yüksek gaz tüketimli işlemleri bulma {#finding-transactions-with-high-gas-consumption} -Echidna ile yüksek gaz tüketimi olan işlemleri nasıl bulacağımızı göreceğiz. Hedef, aşağıdaki akıllı sözleşmedir: +Echidna ile yüksek gaz tüketimli işlemlerin nasıl bulunacağını göreceğiz. Hedef, aşağıdaki akıllı sözleşmedir: ```solidity contract C { @@ -571,9 +576,10 @@ contract C { } ``` -Burada `expensive` büyük bir gaz tüketimine sahip olabilir. +Burada `expensive` yüksek bir gaz tüketimine sahip olabilir. -Şu anda Echidna'nın test etmek için her zaman bir özelliğe ihtiyacı vardır: burada `echidna_test` her zaman `true` değerini döndürür. Bunu doğrulamak için Echidna'yı çalıştırabiliriz: +Şu anda, Echidna'nın test etmek için her zaman bir özelliğe ihtiyacı vardır: burada `echidna_test` her zaman `true` döndürür. +Bunu doğrulamak için Echidna'yı çalıştırabiliriz: ``` echidna-test gas.sol @@ -583,7 +589,7 @@ echidna_test: passed! 🎉 Seed: 2320549945714142710 ``` -### Gaz Tüketimini Hesaplama {#measuring-gas-consumption} +### Gaz Tüketimini Ölçme {#measuring-gas-consumption} Echidna ile gaz tüketimini etkinleştirmek için bir `config.yaml` yapılandırma dosyası oluşturun: @@ -591,16 +597,16 @@ Echidna ile gaz tüketimini etkinleştirmek için bir `config.yaml` yapılandır estimateGas: true ``` -Bu örnekte, sonuçların anlaşılmasını kolaylaştırmak için işlem sırasının boyutunu da azaltacağız: +Bu örnekte, sonuçların daha kolay anlaşılmasını sağlamak için işlem dizisinin boyutunu da azaltacağız: ```yaml seqLen: 2 estimateGas: true ``` -### Echidna'yı çalıştırın {#run-echidna-3} +### Echidna'yı Çalıştırma {#run-echidna-3} -Yapılandırma dosyasını oluşturduktan sonra Echidna'yı şu şekilde çalıştırabiliriz: +Yapılandırma dosyası oluşturulduktan sonra, Echidna'yı şu şekilde çalıştırabiliriz: ```bash echidna-test gas.sol --config config.yaml @@ -617,12 +623,13 @@ Seed: -325611019680165325 ``` -- Gösterilen gaz [HEVM](https://github.com/dapphub/dapptools/tree/master/src/hevm#hevm-) tarafından sağlanan bir tahmindir. +- Gösterilen gaz, [HEVM](https://github.com/dapphub/dapptools/tree/master/src/hevm#hevm-) tarafından sağlanan bir tahmindir. -### Gaz Düşürücü Çağrıları Filtreleme {#filtering-out-gas-reducing-calls} +### Gaz Azaltan Çağrıları Filtreleme {#filtering-out-gas-reducing-calls} -Yukarıdaki **bir bulandırma çalışması sırasında çağrılacak fonksiyonları filtreleme** hakkındaki öğretici, bazı fonksiyonların testinizden nasıl kaldırılacağını gösterir. -Bu, doğru bir gaz tahmini elde etmek için kritik öneme sahiptir. Aşağıdaki örneği göz önünde bulundurun: +Yukarıdaki **bir bulandırma kampanyası sırasında çağrılacak fonksiyonları filtreleme** öğreticisi, testlerinizden bazı fonksiyonları nasıl kaldıracağınızı gösterir. +Bu, doğru bir gaz tahmini elde etmek için kritik olabilir. +Aşağıdaki örneği inceleyin: ```solidity contract C { @@ -648,7 +655,7 @@ contract C { } ``` -Echidna tüm fonksiyonları çağırabilirse yüksek gaz maliyeti olan işlemleri kolayca bulamaz: +Echidna tüm fonksiyonları çağırabilirse, yüksek gaz maliyetli işlemleri kolayca bulamaz: ``` echidna-test pushpop.sol --config config.yaml @@ -662,7 +669,8 @@ clear used a maximum of 35916 gas push used a maximum of 40839 gas ``` -Bunun nedeni, maliyetin `addrs` boyutuna bağlı olması ve rastgele aramaların diziyi neredeyse boş bırakma eğiliminde olmasıdır. Ancak `pop` ve `clear`'ı kara listeye almak bize çok daha iyi sonuçlar verir: +Bunun nedeni, maliyetin `addrs` boyutuna bağlı olması ve rastgele çağrıların diziyi neredeyse boş bırakma eğiliminde olmasıdır. +Ancak, `pop` ve `clear` fonksiyonlarını kara listeye almak bize çok daha iyi sonuçlar verir: ```yaml filterBlacklist: true @@ -677,9 +685,9 @@ push used a maximum of 40839 gas check used a maximum of 1484472 gas ``` -### Özet: Yüksek gaz tüketimi olan işlemleri bulma {#summary-finding-transactions-with-high-gas-consumption} +### Özet: Yüksek gaz tüketimli işlemleri bulma {#summary-finding-transactions-with-high-gas-consumption} -Echidna, `estimateGas` yapılandırma seçeneğini kullanarak yüksek gaz tüketimi olan işlemleri bulabilir: +Echidna, `estimateGas` yapılandırma seçeneğini kullanarak yüksek gaz tüketimli işlemleri bulabilir: ```yaml estimateGas: true @@ -690,4 +698,4 @@ echidna-test contract.sol --config config.yaml ... ``` -Echidna, bulandırma çalışması sona erdiğinde her fonksiyon için maksimum gaz tüketimine sahip bir dizi raporlayacaktır. +Echidna, bulandırma kampanyası bittiğinde her fonksiyon için maksimum gaz tüketimine sahip bir dizi raporlayacaktır. diff --git a/public/content/translations/tr/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md b/public/content/translations/tr/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md index 106290ff162..752cf410b25 100644 --- a/public/content/translations/tr/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md +++ b/public/content/translations/tr/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md @@ -1,17 +1,12 @@ --- -title: Akıllı sözleşme açıkları bulmak için Manticore nasıl kullanılır -description: Akıllı sözleşmeleri test etmek için Echidna otomatik olarak nasıl kullanılır +title: "Akıllı sözleşmelerdeki hataları bulmak için Manticore nasıl kullanılır" +description: "Akıllı sözleşmelerdeki hataları otomatik olarak bulmak için Manticore nasıl kullanılır" author: Trailofbits lang: tr -tags: - - "solidity" - - "akıllı kontratlar" - - "güvenlik" - - "test etmek" - - "resmi doğrulama" -skill: beginner +tags: ["solidity", "smart contracts", "security", "testing", "formal verification"] +skill: advanced published: 2020-01-13 -source: Güvenli sözleşmeler oluşturmak +source: Building secure contracts sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore --- @@ -19,35 +14,35 @@ Bu öğreticinin amacı, akıllı sözleşmelerdeki hataları otomatik olarak bu ## Kurulum {#installation} -Manticore >= python 3.6 gerektirir. Pip veya docker kullanılarak kurulabilir. +Manticore, Python 3.6 veya üzerini gerektirir. Pip veya docker kullanılarak kurulabilir. -### Docker aracılığıyla Manticore {#manticore-through-docker} +### Docker ile Manticore {#manticore-through-docker} ```bash docker pull trailofbits/eth-security-toolbox docker run -it -v "$PWD":/home/training trailofbits/eth-security-toolbox ``` -_Son komut, geçerli dizininize erişimi olan bir docker'da eth-security-toolbox'ı çalıştırır. Dosyaları ana makinenizden değiştirebilir ve dosyalar üzerindeki araçları docker'dan çalıştırabilirsiniz_ +_Son komut, geçerli dizininize erişimi olan bir docker'da eth-security-toolbox'ı çalıştırır. Dosyaları ana makinenizden değiştirebilir ve docker'dan dosyalar üzerindeki araçları çalıştırabilirsiniz_ -Docker'ın içinde şunu çalıştırın: +Docker içinde şunu çalıştırın: ```bash solc-select 0.5.11 cd /home/trufflecon/ ``` -### Pip aracılığıyla Manticore {#manticore-through-pip} +### Pip ile Manticore {#manticore-through-pip} ```bash pip3 install --user manticore ``` -solc 0.5.11 tavsiye edilir. +solc 0.5.11 sürümü tavsiye edilir. -### Bir komut dosyası çalıştırma {#running-a-script} +### Bir betik çalıştırma {#running-a-script} -Python 3 ile bir python komut dosyası çalıştırmak için: +Python 3 ile bir python betiği çalıştırmak için: ```bash python3 script.py @@ -57,58 +52,58 @@ python3 script.py ### Özetle Dinamik Sembolik Yürütme {#dynamic-symbolic-execution-in-a-nutshell} -Dinamik sembolik yürütme (DSE), yüksek derecede semantik farkındalık ile bir durum uzayını araştıran bir program analiz tekniğidir. Bu teknik, `path predicates` (yol belirteçleri) olarak adlandırılan matematiksel formüller olarak temsil edilen "program yollarının" keşfine dayanır. Kavramsal olarak, bu teknik iki adımda yol belirteçleri üzerinde çalışır: +Dinamik sembolik yürütme (DSE), yüksek derecede anlamsal farkındalıkla bir durum uzayını araştıran bir program analizi tekniğidir. Bu teknik, `yol koşulları` (path predicates) olarak adlandırılan matematiksel formüller olarak temsil edilen "program yollarının" keşfine dayanır. Kavramsal olarak, bu teknik yol koşulları üzerinde iki adımda çalışır: -1. Programın girdisi üzerindeki kısıtlamalar kullanılarak oluşturulurlar. +1. Programın girdisindeki kısıtlamalar kullanılarak oluşturulurlar. 2. İlişkili yolların yürütülmesine neden olacak program girdileri oluşturmak için kullanılırlar. -Bu yaklaşım, tanımlanmış tüm program durumlarının somut yürütme sırasında tetiklenmesi şeklinde yanlış pozitifler üretmez. Örneğin, analiz bir tamsayı taşması bulursa, bunun tekrarlanabilir olması garanti edilir. +Bu yaklaşım, tanımlanan tüm program durumları somut yürütme sırasında tetiklenebildiği için yanlış pozitif sonuç üretmez. Örneğin, analiz bir tam sayı taşması bulursa, bunun yeniden üretilebilir olması garanti edilir. -### Yol Belirteci Örneği {#path-predicate-example} +### Yol Koşulu Örneği {#path-predicate-example} -DSE'nin nasıl çalıştığına dair bir fikir edinmek için aşağıdaki örneği göz önünde bulundurun: +DSE'nin nasıl çalıştığına dair bir fikir edinmek için aşağıdaki örneği inceleyin: ```solidity function f(uint a){ if (a == 65) { - // A bug is present + // Bir hata mevcut } } ``` -`f()` iki yol içerdiği için, DSE iki farklı yol belirteci inşa eder: +`f()` iki yol içerdiğinden, bir DSE iki farklı yol koşulu oluşturacaktır: -- Path 1: `a == 65` -- Path 2: `Not (a == 65)` +- Yol 1: `a == 65` +- Yol 2: `Not (a == 65)` -Her yol belirteci, denklemi çözmeye çalışacak sözde [SMT çözücüsüne](https://wikipedia.org/wiki/Satisfiability_modulo_theories) verilebilecek matematiksel bir formüldür. `Path 1` için, çözücü yolun `a = 65` ile keşfedileceğini söyleyecektir. `Path 2` için, çözücü `a`'ya 65'ten farklı herhangi bir değer verebilir, örneğin `a = 0`. +Her yol koşulu, denklemi çözmeye çalışacak olan ve [SMT çözücü](https://wikipedia.org/wiki/Satisfiability_modulo_theories) olarak adlandırılan bir araca verilebilen matematiksel bir formüldür. `Yol 1` için çözücü, yolun `a = 65` ile keşfedilebileceğini söyleyecektir. `Yol 2` için çözücü `a`'ya 65'ten farklı herhangi bir değer verebilir, örneğin `a = 0`. ### Özellikleri doğrulama {#verifying-properties} -Manticore, her yolun tüm yürütülmesi üzerinde tam kontrole izin verir. Sonuç olarak, hemen hemen her şeye keyfi kısıtlamalar eklemenize izin verir. Bu kontrol, sözleşmedeki özelliklerin oluşturulmasına izin verir. +Manticore, her yolun tüm yürütümü üzerinde tam kontrol sağlar. Sonuç olarak, neredeyse her şeye isteğe bağlı kısıtlamalar eklemenize olanak tanır. Bu kontrol, sözleşme üzerinde özellikler oluşturulmasına olanak tanır. -Aşağıdaki örneği göz önünde bulundurun: +Aşağıdaki örneği inceleyin: ```solidity function unsafe_add(uint a, uint b) returns(uint c){ - c = a + b; // no overflow protection + c = a + b; // taşma koruması yok return c; } ``` -Burada fonksiyonda keşfedilecek tek bir yol var: +Burada fonksiyonda keşfedilecek tek bir yol vardır: -- Path 1: `c = a + b` +- Yol 1: `c = a + b` -Manticore'u kullanarak taşma olup olmadığını kontrol edebilir ve yol belirtecine kısıtlamalar ekleyebilirsiniz: +Manticore'u kullanarak taşmayı kontrol edebilir ve yol koşuluna kısıtlamalar ekleyebilirsiniz: - `c = a + b AND (c < a OR c < b)` -`a` ve `b` için yukarıdaki yol belirtecinin uygun olduğu bir değerleme bulmak mümkünse, bir taşma bulmuşsunuz demektir. Örneğin çözücü `a = 10 , b = MAXUINT256` girdisini oluşturabilir. +`a` ve `b` için yukarıdaki yol koşulunun uygulanabilir olduğu bir değerleme bulmak mümkünse bu, bir taşma bulduğunuz anlamına gelir. Örneğin, çözücü `a = 10, b = MAXUINT256` girdisini oluşturabilir. -Sabit bir versiyonu düşünürseniz: +Düzeltilmiş bir sürümü düşünürsek: ```solidity function safe_add(uint a, uint b) returns(uint c){ @@ -119,17 +114,17 @@ function safe_add(uint a, uint b) returns(uint c){ } ``` -Taşma denetimiyle ilişkili formül şöyle olacaktır: +Taşma kontrolü ile ilişkili formül şöyle olacaktır: - `c = a + b AND (c >= a) AND (c=>b) AND (c < a OR c < b)` -Bu formül çözülemez; başka bir deyişle bu, `safe_add`'da `c`'nin her zaman artacağının **ispatıdır**. +Bu formül çözülemez; başka bir deyişle bu, `safe_add` içinde `c`'nin her zaman artacağının bir **kanıtıdır**. -Bu nedenle DSE, kodunuzdaki keyfi kısıtlamaları doğrulayabilen güçlü bir araçtır. +Bu nedenle DSE, kodunuzdaki isteğe bağlı kısıtlamaları doğrulayabilen güçlü bir araçtır. -## Manticore altında çalışma {#running-under-manticore} +## Manticore altında çalıştırma {#running-under-manticore} -Manticore API ile akıllı bir sözleşmeyi nasıl keşfedeceğimizi göreceğiz. Hedef, aşağıdaki akıllı sözleşme [`example.sol`'dür](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol): +Manticore API'si ile bir akıllı sözleşmenin nasıl keşfedileceğini göreceğiz. Hedef, aşağıdaki akıllı sözleşmedir: [`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol): ```solidity pragma solidity >=0.4.24 <0.6.0; @@ -143,62 +138,63 @@ contract Simple { } ``` -### Bağımsız bir keşif çalıştırın {#run-a-standalone-exploration} +### Bağımsız bir keşif çalıştırma {#run-a-standalone-exploration} -Aşağıdaki komutla Manticore'u doğrudan akıllı sözleşme üzerinde çalıştırabilirsiniz (`project` bir Solidity Dosyası veya bir proje dizini olabilir): +Aşağıdaki komutla Manticore'u doğrudan akıllı sözleşme üzerinde çalıştırabilirsiniz (`project` bir Solidity dosyası veya bir proje dizini olabilir): ```bash $ manticore project ``` -Bunun gibi test senaryolarının çıktısını alacaksınız (sıra değişebilir): +Bunun gibi test senaryolarının çıktısını alırsınız (sıra değişebilir): ``` ... -... m.c.manticore:INFO: Generated testcase No. 0 - STOP -... m.c.manticore:INFO: Generated testcase No. 1 - REVERT -... m.c.manticore:INFO: Generated testcase No. 2 - RETURN -... m.c.manticore:INFO: Generated testcase No. 3 - REVERT -... m.c.manticore:INFO: Generated testcase No. 4 - STOP -... m.c.manticore:INFO: Generated testcase No. 5 - REVERT -... m.c.manticore:INFO: Generated testcase No. 6 - REVERT -... m.c.manticore:INFO: Results in /home/ethsec/workshops/Automated Smart Contracts Audit - TruffleCon 2018/manticore/examples/mcore_t6vi6ij3 +... m.c.manticore:INFO: Oluşturulan test senaryosu No. 0 - STOP +... m.c.manticore:INFO: Oluşturulan test senaryosu No. 1 - REVERT +... m.c.manticore:INFO: Oluşturulan test senaryosu No. 2 - RETURN +... m.c.manticore:INFO: Oluşturulan test senaryosu No. 3 - REVERT +... m.c.manticore:INFO: Oluşturulan test senaryosu No. 4 - STOP +... m.c.manticore:INFO: Oluşturulan test senaryosu No. 5 - REVERT +... m.c.manticore:INFO: Oluşturulan test senaryosu No. 6 - REVERT +... m.c.manticore:INFO: Sonuçlar: /home/ethsec/workshops/Automated Smart Contracts Audit - TruffleCon 2018/manticore/examples/mcore_t6vi6ij3 ... ``` -Ek bilgi olmadan Manticore, sözleşmede yeni yollar keşfetmeyene kadar sözleşmeyi yeni sembolik işlemlerle keşfedecektir. Manticore, başarısız bir işlemden sonra (örneğin: bir geri alma işleminden sonra) yeni işlemler çalıştırmaz. +Ek bilgi olmadan Manticore, sözleşmede yeni yollar keşfetmeyene kadar sözleşmeyi yeni sembolik +işlemlerle keşfedecektir. Manticore, başarısız bir işlemden sonra (ör. bir geri döndürmeden sonra) yeni işlemler çalıştırmaz. -Manticore, bilgileri bir `mcore_*` dizininde çıkaracaktır. Diğerlerinin yanı sıra bu dizinde şunları bulacaksınız: +Manticore, bilgileri bir `mcore_*` dizinine çıkaracaktır. Diğerlerinin yanı sıra bu dizinde şunları bulacaksınız: -- `global.summary`: kapsam ve derleme uyarıları -- `test_XXXXX.summary`: kapsam, son talimat, test durumu başına hesap bakiyeleri -- `test_XXXXX.tx`: test durumu başına detaylı işlem listesi +- `global.summary`: kapsam ve derleyici uyarıları +- `test_XXXXX.summary`: kapsam, son talimat, test senaryosu başına hesap bakiyeleri +- `test_XXXXX.tx`: test senaryosu başına ayrıntılı işlem listesi Burada Manticore, aşağıdakilere karşılık gelen 7 test senaryosu bulur (dosya adı sırası değişebilir): -| | İşlem 0 | İşlem 1 | İşlem 2 | Sonuç | -|:--------------------:|:------------------:|:-------------------:| ------------------- |:------:| -| **test_00000000.tx** | Sözleşme oluşturma | f(!=65) | f(!=65) | STOP | -| **test_00000001.tx** | Sözleşme oluşturma | fallback fonksiyonu | | REVERT | -| **test_00000002.tx** | Sözleşme oluşturma | | | RETURN | -| **test_00000003.tx** | Sözleşme oluşturma | f(65) | | REVERT | -| **test_00000004.tx** | Sözleşme oluşturma | f(!=65) | | STOP | -| **test_00000005.tx** | Sözleşme oluşturma | f(!=65) | f(65) | REVERT | -| **test_00000006.tx** | Sözleşme oluşturma | f(!=65) | fallback fonksiyonu | REVERT | +| | İşlem 0 | İşlem 1 | İşlem 2 | Sonuç | +| :-------------------------------------------------------: | :----------------: | :------------------------: | -------------------------- | :----: | +| **test_00000000.tx** | Sözleşme oluşturma | f(!=65) | f(!=65) | STOP | +| **test_00000001.tx** | Sözleşme oluşturma | yedek fonksiyon | | REVERT | +| **test_00000002.tx** | Sözleşme oluşturma | | | RETURN | +| **test_00000003.tx** | Sözleşme oluşturma | f(65) | | REVERT | +| **test_00000004.tx** | Sözleşme oluşturma | f(!=65) | | STOP | +| **test_00000005.tx** | Sözleşme oluşturma | f(!=65) | f(65) | REVERT | +| **test_00000006.tx** | Sözleşme oluşturma | f(!=65) | yedek fonksiyon | REVERT | -_Keşif özeti f(!=65), 65'ten farklı herhangi bir değerle çağrılan f'yi ifade eder._ +_Keşif özeti `f(!=65)`, f'nin 65'ten farklı herhangi bir değerle çağrıldığını belirtir._ -Gördüğünüz üzere, Manticore her başarılı veya geri alınan işlem için benzersiz bir test senaryosu oluşturur. +Fark edebileceğiniz gibi, Manticore her başarılı veya geri döndürülen işlem için benzersiz bir test senaryosu oluşturur. -Eğer hızlı kod keşfi istiyorsanız `--quick-mode` bayrağını kullanın (hata algılayıcıları, gaz hesaplamalarını vb. devre dışarı bırakır) +Hızlı kod keşfi istiyorsanız `--quick-mode` bayrağını kullanın (hata algılayıcılarını, gaz hesaplamasını vb. devre dışı bırakır) -### API aracılığıyla bir akıllı sözleşmeyi değiştirin {#manipulate-a-smart-contract-through-the-api} +### API aracılığıyla bir akıllı sözleşmeyi yönetme {#manipulate-a-smart-contract-through-the-api} -Bu bölüm, Manticore Python API aracılığıyla bir akıllı sözleşmenin nasıl değiştirileceğini açıklar. `*.py` python uzantılı yeni bir dosya oluşturabilir ve bu dosyaya API komutlarını (temelleri aşağıda anlatılacaktır) ekleyerek gerekli kodu yazabilir ve ardından `$ python3 *.py` komutu ile çalıştırabilirsiniz. Ayrıca aşağıdaki komutları doğrudan python konsolunda çalıştırabilirsiniz, konsolu çalıştırmak için `$ python3` komutunu kullanın. +Bu bölüm, Manticore Python API'si aracılığıyla bir akıllı sözleşmenin nasıl yönetileceğini ayrıntılarıyla açıklar. Python uzantısı `*.py` olan yeni bir dosya oluşturabilir ve bu dosyaya API komutlarını (temelleri aşağıda açıklanacaktır) ekleyerek gerekli kodu yazabilir ve ardından `$ python3 *.py` komutuyla çalıştırabilirsiniz. Ayrıca aşağıdaki komutları doğrudan python konsolunda yürütebilirsiniz, konsolu çalıştırmak için `$ python3` komutunu kullanın. -### Hesap oluşturma {#creating-accounts} +### Hesap Oluşturma {#creating-accounts} -Yapmanız gereken ilk şey, aşağıdaki komutlarla yeni bir blok zinciri başlatmaktır: +Yapmanız gereken ilk şey, aşağıdaki komutlarla yeni bir blokzincir başlatmaktır: ```python from manticore.ethereum import ManticoreEVM @@ -225,7 +221,7 @@ contract Simple { } } ''' -# Initiate the contract +# Sözleşmeyi başlat contract_account = m.solidity_create_contract(source_code, owner=user_account) ``` @@ -242,7 +238,7 @@ Manticore iki tür işlemi destekler: #### Ham işlem {#raw-transaction} -Bir ham işlem [m.transaction](https://manticore.readthedocs.io/en/latest/evm.html?highlight=transaction#manticore.ethereum.ManticoreEVM.transaction) ile yürütülür: +Ham bir işlem [m.transaction](https://manticore.readthedocs.io/en/latest/evm.html?highlight=transaction#manticore.ethereum.ManticoreEVM.transaction) kullanılarak yürütülür: ```python m.transaction(caller=user_account, @@ -251,7 +247,7 @@ m.transaction(caller=user_account, value=value) ``` -Çağıran, adres, veri veya işlemin değeri somut veya sembolik olabilir: +Çağıran, adres, veri veya işlemin değeri somut ya da sembolik olabilir: - [m.make_symbolic_value](https://manticore.readthedocs.io/en/latest/evm.html?highlight=make_symbolic_value#manticore.ethereum.ManticoreEVM.make_symbolic_value) sembolik bir değer oluşturur. - [m.make_symbolic_buffer(size)](https://manticore.readthedocs.io/en/latest/evm.html?highlight=make_symbolic_buffer#manticore.ethereum.ManticoreEVM.make_symbolic_buffer) sembolik bir bayt dizisi oluşturur. @@ -267,40 +263,41 @@ m.transaction(caller=user_account, value=symbolic_value) ``` -Veriler sembolik ise, Manticore işlemin yürütülmesi sırasında sözleşmenin tüm fonksiyonlarını keşfedecektir. Fonksiyon seçiminin nasıl çalıştığını anlamak için [Ethernaut CTF Kullanımı](https://blog.trailofbits.com/2017/11/06/hands-on-the-ethernaut-ctf/) makalesindeki Fallback Function açıklamasına göz atmak faydalı olacaktır. +Veri sembolik ise Manticore, işlem yürütme sırasında sözleşmenin tüm fonksiyonlarını keşfedecektir. Fonksiyon seçiminin nasıl çalıştığını anlamak için [Ethernaut CTF'ye Giriş](https://blog.trailofbits.com/2017/11/06/hands-on-the-ethernaut-ctf/) makalesindeki Yedek Fonksiyon açıklamasını görmek faydalı olacaktır. #### Adlandırılmış işlem {#named-transaction} -İşlevler, adları aracılığıyla yürütülebilir. `f(uint var)` komutunu user_account'tan sembolik bir değerle ve 0 ether ile yürütmek için şunu kullanın: +Fonksiyonlar adları aracılığıyla yürütülebilir. +`f(uint var)` öğesini sembolik bir değerle, `user_account`'tan ve 0 ether ile yürütmek için şunu kullanın: ```python symbolic_var = m.make_symbolic_value() contract_account.f(symbolic_var, caller=user_account, value=0) ``` -İşlemin `value` değeri belirtilmemişse, varsayılan olarak 0'dır. +İşlemin `value` değeri belirtilmemişse varsayılan olarak 0'dır. #### Özet {#summary-1} - Bir işlemin argümanları somut veya sembolik olabilir -- Ham işlem tüm fonksiyonları keşfedecek -- Fonksiyonlar, isimleriyle çağrılabilir +- Ham bir işlem tüm fonksiyonları keşfedecektir +- Fonksiyonlar adlarıyla çağrılabilir ### Çalışma Alanı {#workspace} `m.workspace`, oluşturulan tüm dosyalar için çıktı dizini olarak kullanılan dizindir: ```python -print("Results are in {}".format(m.workspace)) +print("Sonuçlar burada: {}".format(m.workspace)) ``` -### Keşfi Durdurma {#terminate-the-exploration} +### Keşfi Sonlandırma {#terminate-the-exploration} -Keşfi durdurmak için [m.finalize()](https://manticore.readthedocs.io/en/latest/evm.html?highlight=finalize#manticore.ethereum.ManticoreEVM.finalize) kullanın. Bu yöntem çağrıldığında ve Manticore keşfedilen yolların her biri için test senaryoları oluşturduğunda başka işlem gönderilmeyecektir. +Keşfi durdurmak için [m.finalize()](https://manticore.readthedocs.io/en/latest/evm.html?highlight=finalize#manticore.ethereum.ManticoreEVM.finalize) kullanın. Bu yöntem çağrıldıktan ve Manticore keşfedilen her yol için test senaryoları oluşturduktan sonra başka işlem gönderilmemelidir. -### Özet: Manticore altında çalışma {#summary-running-under-manticore} +### Özet: Manticore altında çalıştırma {#summary-running-under-manticore} -Önceki tüm adımları bir araya getirerek şunu elde ederiz: +Önceki tüm adımları bir araya getirdiğimizde şunu elde ederiz: ```python from manticore.ethereum import ManticoreEVM @@ -316,15 +313,15 @@ contract_account = m.solidity_create_contract(source_code, owner=user_account) symbolic_var = m.make_symbolic_value() contract_account.f(symbolic_var) -print("Results are in {}".format(m.workspace)) -m.finalize() # stop the exploration +print("Sonuçlar burada: {}".format(m.workspace)) +m.finalize() # keşfi durdur ``` -Yukarıdaki kodların tamamını [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) içinde bulabilirsiniz +Yukarıdaki kodun tamamını [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) dosyasında bulabilirsiniz -## Atış yollarını alma {#getting-throwing-paths} +## Hata Veren Yolları Alma {#getting-throwing-paths} -Şimdi `f()` içinde bir istisna belirten yollar için spesifik girdiler oluşturacağız. Hedef hâlâ şu akıllı sözleşmedir [`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol): +Şimdi `f()` içinde bir istisna oluşturan yollar için belirli girdiler oluşturacağız. Hedef, aşağıdaki akıllı sözleşmedir: [`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol): ```solidity pragma solidity >=0.4.24 <0.6.0; @@ -337,35 +334,35 @@ contract Simple { } ``` -### Durum bilgisini kullanmak {#using-state-information} +### Durum bilgilerini kullanma {#using-state-information} -Yürütülen her yolun kendi blok zinciri durumu vardır. Bir durum ya hazırdır ya da öldürülmüştür, yani bir THROW veya REVERT komutuna ulaştığı anlamına gelir: +Yürütülen her yolun blokzincirde kendi durumu vardır. Bir durum ya hazırdır ya da sonlandırılmıştır, yani bir THROW veya REVERT talimatına ulaşmıştır: -- [m.ready_states](https://manticore.readthedocs.io/en/latest/states.html#accessing): hazır olan durumların listesi (REVERT/INVALID yürütmediler) -- [m.killed_states](https://manticore.readthedocs.io/en/latest/states.html#accessings): öldürülmüş durumların listesi +- [m.ready_states](https://manticore.readthedocs.io/en/latest/states.html#accessing): hazır olan durumların listesi (bir REVERT/INVALID yürütmediler) +- [m.killed_states](https://manticore.readthedocs.io/en/latest/states.html#accessings): sonlandırılmış durumların listesi - [m.all_states](https://manticore.readthedocs.io/en/latest/states.html#accessings): tüm durumlar ```python for state in m.all_states: - # do something with state + # durum ile bir şeyler yap ``` -Durum bilgisine erişebilirsiniz. Örneğin: +Durum bilgilerine erişebilirsiniz. Örneğin: - `state.platform.get_balance(account.address)`: hesabın bakiyesi -- `state.platform.transactions`: işlem listesi -- `state.platform.transactions[-1].return_data`: son işlemden döndürülen veri +- `state.platform.transactions`: işlemlerin listesi +- `state.platform.transactions[-1].return_data`: son işlem tarafından döndürülen veri -Son işlem tarafından döndürülen veriler, ABI.deserialize ile bir değere dönüştürülebilen bir dizidir, örneğin: +Son işlem tarafından döndürülen veri, örneğin `ABI.deserialize` ile bir değere dönüştürülebilen bir dizidir: ```python data = state.platform.transactions[0].return_data data = ABI.deserialize("uint", data) ``` -### Test durumu nasıl oluşturulur {#how-to-generate-testcase} +### Test senaryosu nasıl oluşturulur {#how-to-generate-testcase} -Test durumu oluşturmak için [m.generate_testcase(state, name)](https://manticore.readthedocs.io/en/latest/evm.html?highlight=generate_testcase#manticore.ethereum.ManticoreEVM.generate_testcase) kullanın: +Test senaryosu oluşturmak için [m.generate_testcase(state, name)](https://manticore.readthedocs.io/en/latest/evm.html?highlight=generate_testcase#manticore.ethereum.ManticoreEVM.generate_testcase) kullanın: ```python m.generate_testcase(state, 'BugFound') @@ -373,13 +370,13 @@ m.generate_testcase(state, 'BugFound') ### Özet {#summary-2} -- m.all_states ile durumu yineleyebilirsiniz -- `state.platform.get_balance(account.address)` hesabın bakiyesini döndürür -- `state.platform.transactions` işlemlerin listesini döndürür +- `m.all_states` ile durum üzerinde yineleme yapabilirsiniz +- `state.platform.get_balance(account.address)`, hesabın bakiyesini döndürür +- `state.platform.transactions`, işlemlerin listesini döndürür - `transaction.return_data` döndürülen veridir - `m.generate_testcase(state, name)` durum için girdiler oluşturur -### Özet: Atış Yolunu Almak {#summary-getting-throwing-path} +### Özet: Hata Veren Yolu Alma {#summary-getting-throwing-path} ```python from manticore.ethereum import ManticoreEVM @@ -395,21 +392,23 @@ contract_account = m.solidity_create_contract(source_code, owner=user_account) symbolic_var = m.make_symbolic_value() contract_account.f(symbolic_var) -## Check if an execution ends with a REVERT or INVALID +## Bir yürütmenin REVERT veya INVALID ile bitip bitmediğini kontrol edin + for state in m.terminated_states: last_tx = state.platform.transactions[-1] if last_tx.result in ['REVERT', 'INVALID']: - print('Throw found {}'.format(m.workspace)) + print('Hata bulundu {}'.format(m.workspace)) m.generate_testcase(state, 'ThrowFound') ``` -Yukarıdaki kodların tamamını [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) içinde bulabilirsiniz +Yukarıdaki kodun tamamını [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) dosyasında bulabilirsiniz -_terminated_state tarafından döndürülen tüm durumların sonuçlarında REVERT veya INVALID olduğundan çok daha basit bir komut dosyası oluşturabileceğimizi unutmayın: Bu örnek yalnızca API'nin nasıl değiştirileceğini göstermek içindir._ +_`terminated_state` tarafından döndürülen tüm durumların sonucunda REVERT veya INVALID olduğundan çok daha basit bir betik oluşturabileceğimizi unutmayın: bu örnek yalnızca API'nin nasıl yönetileceğini göstermek içindi._ -## Kısıtlamalar ekleme {#adding-constraints} +## Kısıtlama ekleme {#adding-constraints} -Keşfi nasıl kısıtlayabileceğimizi göreceğiz. `f()` belgesinin, fonksiyonun hiçbir zaman `a == 65` ile çağrılmadığını belirttiği varsayımını yapacağız, bu nedenle `a == 65` ile herhangi bir hata gerçek bir hata değildir. Hedef hâlâ aşağıdaki akıllı sözleşmedir [`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol): +Keşfi nasıl kısıtlayacağımızı göreceğiz. `f()` belgesinin, fonksiyonun asla `a == 65` ile çağrılmadığını +belirttiğini varsayacağız, bu nedenle `a == 65` ile ilgili herhangi bir hata gerçek bir hata değildir. Hedef, aşağıdaki akıllı sözleşmedir: [`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol): ```solidity pragma solidity >=0.4.24 <0.6.0; @@ -424,22 +423,22 @@ contract Simple { ### Operatörler {#operators} -[Operatörler](https://github.com/trailofbits/manticore/blob/master/manticore/core/smtlib/operators.py) modülü, sağladığı diğer şeylerin yanı sıra kısıtlamaların değiştirilmesini kolaylaştırır: +[Operatörler](https://github.com/trailofbits/manticore/blob/master/manticore/core/smtlib/operators.py) modülü, kısıtlamaların yönetimini kolaylaştırır ve diğerlerinin yanı sıra şunları sağlar: - Operators.AND, - Operators.OR, -- Operators.UGT (unsigned greater than), -- Operators.UGE (unsigned greater than or equal to), -- Operators.ULT (unsigned lower than), -- Operators.ULE (unsigned lower than or equal to). +- Operators.UGT (işaretsiz büyüktür), +- Operators.UGE (işaretsiz büyük veya eşittir), +- Operators.ULT (işaretsiz küçüktür), +- Operators.ULE (işaretsiz küçük veya eşittir). -Modülü içe aktarmak için aşağıdakileri kullanın: +Modülü içe aktarmak için aşağıdakini kullanın: ```python from manticore.core.smtlib import Operators ``` -`Operators.CONCAT` bir diziyi bir değerle birleştirmek için kullanılır. Örneğin, bir işlemin return_data'sının başka bir değere karşı kontrol edilmesi için bir değerle değiştirilmesi gerekir: +`Operators.CONCAT`, bir diziyi bir değere birleştirmek için kullanılır. Örneğin, bir işlemin `return_data`'sının başka bir değere karşı kontrol edilmesi için bir değere dönüştürülmesi gerekir: ```python last_return = Operators.CONCAT(256, *last_return) @@ -447,11 +446,12 @@ last_return = Operators.CONCAT(256, *last_return) ### Kısıtlamalar {#state-constraint} -Kısıtlamaları global olarak veya belirli bir durum için kullanabilirsiniz. +Kısıtlamaları genel olarak veya belirli bir durum için kullanabilirsiniz. -#### Global kısıtlama {#state-constraint} +#### Genel kısıtlama {#state-constraint} -Global bir kısıtlama eklemek için `m.constrain(constraint)` kullanın. Örneğin, sembolik bir adresten bir sözleşmeyi arayabilir ve bu adresi belirli değerlerle sınırlandırabilirsiniz: +Genel bir kısıtlama eklemek için `m.constrain(constraint)` kullanın. +Örneğin, sembolik bir adresten bir sözleşme çağırabilir ve bu adresi belirli değerler olacak şekilde kısıtlayabilirsiniz: ```python symbolic_address = m.make_symbolic_value() @@ -464,19 +464,21 @@ m.transaction(caller=user_account, #### Durum kısıtlaması {#state-constraint} -Belirli bir duruma kısıtlama eklemek için [state.constrain(constraint)](https://manticore.readthedocs.io/en/latest/states.html?highlight=StateBase#manticore.core.state.StateBase.constrain) kullanın. Üzerindeki bazı özellikleri kontrol etmek için keşfinden sonra durumu kısıtlamak için kullanılabilir. +Belirli bir duruma kısıtlama eklemek için [state.constrain(constraint)](https://manticore.readthedocs.io/en/latest/states.html?highlight=StateBase#manticore.core.state.StateBase.constrain) kullanın. +Üzerindeki bazı özellikleri kontrol etmek için keşfinden sonra durumu kısıtlamak için kullanılabilir. -### Kısıtlamaları kontrol etmek {#checking-constraint} +### Kısıtlamayı Kontrol Etme {#checking-constraint} -Eğer bir kısıtlamanın hâlâ mümkün olup olmadığını görmek istiyorsanız `solver.check(state.constraints)` kullanın. Örneğin, aşağıdakiler symbolic_value'yu 65'ten farklı olacak şekilde kısıtlar ve durumun hâlâ uygulanabilir olup olmadığını kontrol eder: +Bir kısıtlamanın hala uygulanabilir olup olmadığını öğrenmek için `solver.check(state.constraints)` kullanın. +Örneğin, aşağıdakiler `symbolic_value` değerini 65'ten farklı olacak şekilde kısıtlayacak ve durumun hala uygulanabilir olup olmadığını kontrol edecektir: ```python state.constrain(symbolic_var != 65) if solver.check(state.constraints): - # state is feasible + # durum uygulanabilir ``` -### Özet: Kısıtlamalar Ekleme {#summary-adding-constraints} +### Özet: Kısıtlama Ekleme {#summary-adding-constraints} Önceki koda kısıtlama ekleyerek şunu elde ederiz: @@ -499,18 +501,19 @@ contract_account.f(symbolic_var) no_bug_found = True -## Check if an execution ends with a REVERT or INVALID +## Bir yürütmenin REVERT veya INVALID ile bitip bitmediğini kontrol edin + for state in m.terminated_states: last_tx = state.platform.transactions[-1] if last_tx.result in ['REVERT', 'INVALID']: - # we do not consider the path were a == 65 + # a == 65 olduğu yolu dikkate almıyoruz condition = symbolic_var != 65 if m.generate_testcase(state, name="BugFound", only_if=condition): - print(f'Bug found, results are in {m.workspace}') + print(f'Hata bulundu, sonuçlar burada: {m.workspace}') no_bug_found = False if no_bug_found: - print(f'No bug found') + print(f'Hata bulunamadı') ``` -Yukarıdaki kodların tamamını [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) içinde bulabilirsiniz +Yukarıdaki kodun tamamını [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) dosyasında bulabilirsiniz diff --git a/public/content/translations/tr/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md b/public/content/translations/tr/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md index c38e8510d55..1b969a40271 100644 --- a/public/content/translations/tr/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md +++ b/public/content/translations/tr/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md @@ -1,28 +1,23 @@ --- -title: Akıllı sözleşme hatalarını bulmak için Slither nasıl kullanılır -description: Akıllı sözleşmelerdeki hataları otomatik olarak bulmak için Slither nasıl kullanılır +title: "Akıllı sözleşme hatalarını bulmak için Slither nasıl kullanılır?" +description: "Akıllı sözleşmelerdeki hataları otomatik olarak bulmak için Slither'ı kullanma" author: Trailofbits lang: tr -tags: - - "solidity" - - "akıllı kontratlar" - - "güvenlik" - - "test etmek" - - "statik analiz" +tags: ["solidity", "smart contracts", "security", "testing"] skill: advanced published: 2020-06-09 -source: Güvenli sözleşmeler oluşturmak +source: Building secure contracts sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/slither --- -## Slither nasıl kullanılır {#how-to-use-slither} +## Slither Nasıl Kullanılır? {#how-to-use-slither} Bu öğreticinin amacı, akıllı sözleşmelerdeki hataları otomatik olarak bulmak için Slither'ın nasıl kullanılacağını göstermektir. - [Kurulum](#installation) - [Komut satırı kullanımı](#command-line) -- [Statik analize giriş](#static-analysis): Statik analize kısa giriş -- [API](#api-basics): Python API açıklaması +- [Statik analize giriş](#static-analysis): Statik analize kısa bir giriş +- [API](#api-basics): Python API'si açıklaması ## Kurulum {#installation} @@ -41,18 +36,18 @@ docker pull trailofbits/eth-security-toolbox docker run -it -v "$PWD":/home/trufflecon trailofbits/eth-security-toolbox ``` -_Son komut, geçerli dizininize erişimi olan bir docker'da eth-security-toolbox'ı çalıştırır. Dosyaları ana makinenizden değiştirebilir ve dosyalar üzerindeki araçları docker'dan çalıştırabilirsiniz_ +_Son komut, geçerli dizininize erişimi olan bir docker'da eth-security-toolbox'ı çalıştırır. Dosyaları ana makinenizden değiştirebilir ve docker'dan dosyalar üzerindeki araçları çalıştırabilirsiniz_ -Docker'ın içinde şunu çalıştırın: +Docker içinde şunu çalıştırın: ```bash solc-select 0.5.11 cd /home/trufflecon/ ``` -### Bir komut dosyası çalıştırma {#running-a-script} +### Bir betik çalıştırma {#running-a-script} -Python 3 ile bir python komut dosyası çalıştırmak için: +Python 3 ile bir python betiği çalıştırmak için: ```bash python3 script.py @@ -66,17 +61,17 @@ python3 script.py slither project_paths ``` -Algılayıcılara ek olarak Slither, [yazıcıları](https://github.com/crytic/slither#printers) ve [araçları](https://github.com/crytic/slither#tools) aracılığıyla kod inceleme kabiliyetlerine sahiptir. +Dedektörlere ek olarak Slither, [yazıcıları](https://github.com/crytic/slither#printers) ve [araçları](https://github.com/crytic/slither#tools) aracılığıyla kod inceleme yeteneklerine sahiptir. -Özel algılayıcılara ve GitHub entegrasyonuna erişmek için [crytic.io](https://github.com/crytic) kullanın. +Özel dedektörlere ve GitHub entegrasyonuna erişmek için [crytic.io](https://github.com/crytic) kullanın. ## Statik analiz {#static-analysis} -Slither statik analiz çerçevesinin kabiliyetleri ve dizaynı, blog gönderilerinde ([1](https://blog.trailofbits.com/2018/10/19/slither-a-solidity-static-analysis-framework/), [2](https://blog.trailofbits.com/2019/05/27/slither-the-leading-static-analyzer-for-smart-contracts/)) ve bir [akademik kağıtta](https://github.com/trailofbits/publications/blob/master/papers/wetseb19.pdf) açıklanmıştır. +Slither statik analiz çatısının yetenekleri ve tasarımı, blog gönderilerinde ([1](https://blog.trailofbits.com/2018/10/19/slither-a-solidity-static-analysis-framework/), [2](https://blog.trailofbits.com/2019/05/27/slither-the-leading-static-analyzer-for-smart-contracts/)) ve bir [akademik makalede](https://github.com/trailofbits/publications/blob/master/papers/wetseb19.pdf) açıklanmıştır. -Statik analiz çeşit çeşittir. Büyük olasılıkla [clang](https://clang-analyzer.llvm.org/) ve [gcc](https://lwn.net/Articles/806099/) gibi derleyicilerin bu araştırma tekniklerine bağlı olduğunun farkındasınızdır ancak bu, aynı zamanda [Infer](https://fbinfer.com/), [CodeClimate](https://codeclimate.com/), [FindBugs](http://findbugs.sourceforge.net/) ve [Frama-C](https://frama-c.com/) ve [Polyspace](https://www.mathworks.com/products/polyspace.html) gibi resmî yöntemlere dayalı araçların da önemini vurgular. +Statik analizin farklı türleri mevcuttur. [clang](https://clang-analyzer.llvm.org/) ve [gcc](https://lwn.net/Articles/806099/) gibi derleyicilerin bu araştırma tekniklerine dayandığını büyük olasılıkla fark etmişsinizdir, ancak bu aynı zamanda [Infer](https://fbinfer.com/), [CodeClimate](https://codeclimate.com/), [FindBugs](http://findbugs.sourceforge.net/) ve [Frama-C](https://frama-c.com/) ile [Polyspace](https://www.mathworks.com/products/polyspace.html) gibi resmi yöntemlere dayalı araçların da temelini oluşturur. -Burada statik analiz tekniklerini ve araştırmacıyı etraflıca incelemeyeceğiz. Bunun yerine, hataları bulmak ve kodu anlamak amacıyla onu daha etkili bir şekilde kullanabilmeniz için Slither'ın nasıl çalıştığını anlamak için gerekenlere odaklanacağız. +Burada statik analiz tekniklerini ve araştırmalarını kapsamlı bir şekilde incelemeyeceğiz. Bunun yerine, hataları bulmak ve kodu anlamak amacıyla onu daha etkili bir şekilde kullanabilmeniz için Slither'ın nasıl çalıştığını anlamak için gerekenlere odaklanacağız. - [Kod temsili](#code-representation) - [Kod analizi](#analysis) @@ -84,13 +79,13 @@ Burada statik analiz tekniklerini ve araştırmacıyı etraflıca incelemeyeceğ ### Kod temsili {#code-representation} -Tek bir yürütme yolu hakkında mantık oluşturan dinamik bir analizin aksine, statik analiz aynı anda tüm yollar hakkında mantık oluşturur. Bunu yapmak için farklı bir kod temsiline dayanır. Soyut söz dizimi ağacı (AST) ve kontrol akış grafiği (CFG) en yaygın iki statik analiz yöntemidir. +Tek bir yürütme yolunu değerlendiren dinamik analizin aksine, statik analiz aynı anda tüm yolları değerlendirir. Bunu yapmak için farklı bir kod temsiline dayanır. En yaygın iki tanesi soyut sözdizimi ağacı (AST) ve kontrol akış grafiğidir (CFG). -### Soyut Söz Dizimi Ağaçları (AST) {#abstract-syntax-trees-ast} +### Soyut Sözdizimi Ağaçları (AST) {#abstract-syntax-trees-ast} -AST, derleyici her kod ayrıştırdığında kullanılır. Muhtemelen statik analizin yapılabileceği en temel yapıdır. +AST, derleyici kodu her ayrıştırdığında kullanılır. Bu, muhtemelen statik analizin gerçekleştirilebileceği en temel yapıdır. -Özetle bir AST, genellikle her yaprağın bir değişken veya sabit içerdiği ve dahili düğümlerin işlenenler veya kontrol akışı işlemleri olduğu yapılandırılmış bir ağaçtır. Aşağıdaki kodu göz önünde bulundurun: +Özetle bir AST, genellikle her yaprağın bir değişken veya bir sabit içerdiği ve iç düğümlerin işlenenler veya kontrol akışı işlemleri olduğu yapılandırılmış bir ağaçtır. Aşağıdaki kodu göz önünde bulundurun: ```solidity function safeAdd(uint a, uint b) pure internal returns(uint){ @@ -107,9 +102,9 @@ function safeAdd(uint a, uint b) pure internal returns(uint){ Slither, solc tarafından dışa aktarılan AST'yi kullanır. -Oluşturulması basit olsa da, AST iç içe geçmiş bir yapıdır. Bazen, bunun analiz edilmesi pek kolay olmayabilir. Örnek olarak, `a + b <= a` ifadesi tarafından kullanılan operasyonları tanımlamak için, öncelikle `<=` ve sonrasında `+` analiz etmelisiniz. Yaygın bir yaklaşım, ağaçta yinelemeli olarak gezinen sözde ziyaretçi desenini kullanmaktır. Slither, [`ExpressionVisitor`](https://github.com/crytic/slither/blob/master/slither/visitors/expression/expression.py) içinde genel bir ziyaretçi bulundurur. +Oluşturulması basit olsa da, AST iç içe geçmiş bir yapıdır. Bazen, bunu analiz etmek pek kolay olmayabilir. Örneğin, `a + b <= a` ifadesinin kullandığı işlemleri belirlemek için önce `<=` ve ardından `+`yı analiz etmelisiniz. Yaygın bir yaklaşım, ağaçta özyinelemeli olarak gezinen ziyaretçi desenini kullanmaktır. Slither, [`ExpressionVisitor`](https://github.com/crytic/slither/blob/master/slither/visitors/expression/expression.py) içinde jenerik bir ziyaretçi içerir. -Aşağıdaki kod, ifadenin bir ekleme içerip içermediğini algılamak için `ExpressionVisitor` kullanır: +Aşağıdaki kod, ifadenin bir toplama işlemi içerip içermediğini tespit etmek için `ExpressionVisitor` kullanır: ```python from slither.visitors.expression.expression import ExpressionVisitor @@ -124,58 +119,58 @@ class HasAddition(ExpressionVisitor): if expression.type == BinaryOperationType.ADDITION: self._result = True -visitor = HasAddition(expression) # expression is the expression to be tested -print(f'The expression {expression} has a addition: {visitor.result()}') +visitor = HasAddition(expression) # expression, test edilecek ifadedir +print(f'{expression} ifadesi bir toplama içeriyor: {visitor.result()}') ``` ### Kontrol Akış Grafiği (CFG) {#control-flow-graph-cfg} -İkinci en yaygın kod temsili, kontrol akış grafiğidir (CFG). Adından da anlaşılacağı gibi, tüm yürütme yollarını ortaya çıkaran grafik tabanlı bir gösterimdir. Her düğüm bir veya birden fazla talimat içerir. Grafikteki kenarlar, kontrol akışı işlemlerini temsil eder (if/then/else, loop vb.). Önceki örneğimizin CFG'si: +İkinci en yaygın kod temsili kontrol akış grafiğidir (CFG). Adından da anlaşılacağı gibi, bu, tüm yürütme yollarını ortaya çıkaran graf tabanlı bir gösterimdir. Her düğüm bir veya daha fazla talimat içerir. Grafikteki kenarlar kontrol akışı işlemlerini (if/then/else, döngü vb.) temsil eder. Önceki örneğimizin CFG'si şöyledir: ![CFG](./cfg.png) CFG, analizlerin çoğunun üzerine inşa edildiği temsildir. -Diğer birçok kod temsili mevcuttur. Her temsilin yapmak istediğiniz analize göre avantajları ve dezavantajları vardır. +Daha birçok kod gösterimi mevcuttur. Her bir gösterimin, gerçekleştirmek istediğiniz analize göre avantajları ve dezavantajları vardır. ### Analiz {#analysis} -Slither ile yapabileceğiniz en basit analiz türü söz dizimsel analizdir. +Slither ile gerçekleştirebileceğiniz en basit analiz türleri sözdizimsel analizlerdir. -### Söz Dizimi Analizi {#syntax-analysis} +### Sözdizimi analizi {#syntax-analysis} -Slither, desen eşleştirme benzeri bir yaklaşım kullanarak tutarsızlıkları ve kusurları bulmak için kodun farklı bileşenleri ve temsilleri arasında gezinebilir. +Slither, desen eşleştirme benzeri bir yaklaşım kullanarak tutarsızlıkları ve kusurları bulmak için kodun farklı bileşenleri ve onların gösterimleri arasında gezinebilir. -Örneğin, aşağıdaki algılayıcılar söz dizimi ile ilgili sorunları arar: +Örneğin, aşağıdaki dedektörler söz dizimiyle ilgili sorunları arar: -- [Durum değişkeni gölgelemesi](https://github.com/crytic/slither/wiki/Detector-Documentation#state-variable-shadowing): tüm durum değişkenleri üzerinde yinelenir ve devralınan bir sözleşmeden bir değişkenin gölgelenip gölgelenmediğini kontrol eder ([state.py#L51-L62](https://github.com/crytic/slither/blob/0441338e055ab7151b30ca69258561a5a793f8ba/slither/detectors/shadowing/state.py#L51-L62)) +- [Durum değişkeni gölgeleme](https://github.com/crytic/slither/wiki/Detector-Documentation#state-variable-shadowing): tüm durum değişkenleri üzerinde yinelenir ve herhangi birinin kalıtılmış bir sözleşmeden bir değişkeni gölgeleyip gölgelemediğini kontrol eder ([state.py#L51-L62](https://github.com/crytic/slither/blob/0441338e055ab7151b30ca69258561a5a793f8ba/slither/detectors/shadowing/state.py#L51-L62)) -- [Hatalı ERC20 arayüzü](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-erc20-interface): hatalı ERC20 fonksiyon imzalarını arayın ([incorrect_erc20_interface.py#L34-L55](https://github.com/crytic/slither/blob/0441338e055ab7151b30ca69258561a5a793f8ba/slither/detectors/erc/incorrect_erc20_interface.py#L34-L55)) +- [Hatalı ERC20 arayüzü](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-erc20-interface): hatalı ERC20 fonksiyon imzalarını arar ([incorrect_erc20_interface.py#L34-L55](https://github.com/crytic/slither/blob/0441338e055ab7151b30ca69258561a5a793f8ba/slither/detectors/erc/incorrect_erc20_interface.py#L34-L55)) -### Semantik analiz {#semantic-analysis} +### Anlamsal analiz {#semantic-analysis} -Söz dizimi analizinin aksine, semantik bir analiz daha derine inecek ve kodun "anlamını" analiz edecektir. Bu aile, bazı geniş analiz türlerini içerir. Daha güçlü ve kullanışlı sonuçlara yol açarlar, ancak aynı zamanda bunları yazmak daha karmaşıktır. +Sözdizimi analizinin aksine, anlamsal bir analiz daha derine iner ve kodun "anlamını" analiz eder. Bu aile, bazı genel analiz türlerini içerir. Bunlar daha güçlü ve kullanışlı sonuçlara yol açar, ancak yazılmaları da daha karmaşıktır. -Semantik analiz, en gelişmiş güvenlik açığı tespitleri için kullanılır. +Anlamsal analizler, en gelişmiş güvenlik açığı tespitleri için kullanılır. #### Veri bağımlılığı analizi {#fixed-point-computation} -`variable_a` değerinin `variable_b` tarafından etkilendiği bir yol varsa, `variable_a` değişkeninin `variable_b` değişkenine veri bağımlı olduğu söylenir. +`variable_a`'nın değerinin `variable_b`'den etkilendiği bir yol varsa, `variable_a` değişkeninin `variable_b`'ye veri bağımlı olduğu söylenir. -Sıradaki kodda, `variable_a`, `variable_b`'ye bağımlıdır: +Aşağıdaki kodda `variable_a` değişkeni `variable_b`'ye bağımlıdır: ```solidity // ... variable_a = variable_b + 1; ``` -Slither, ara temsil özelliği sayesinde (sonraki bir bölümde bahsedilecek) yerleşik [veri bağımlılığı](https://github.com/crytic/slither/wiki/data-dependency) kabiliyetleriyle gelir. +Slither, ara gösterimi (ileriki bir bölümde ele alınacaktır) sayesinde yerleşik [veri bağımlılığı](https://github.com/crytic/slither/wiki/data-dependency) yetenekleriyle birlikte gelir. -Veri bağımlılığı kullanımının bir örneği [zararlı katı eşitlik algılayıcısında](https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-strict-equalities) bulunabilir. Burada Slither, tehlikeli bir değerle ([incorrect_strict_equality.py#L86-L87](https://github.com/crytic/slither/blob/6d86220a53603476f9567c3358524ea4db07fb25/slither/detectors/statements/incorrect_strict_equality.py#L86-L87)) katı bir eşitlik karşılaştırması arayacak ve bir saldırganın sözleşmeyi tuzağa düşürmesini önlemek için kullanıcıya `==` yerine `>=` veya `<=` kullanması gerektiğini bildirecektir. Diğerlerinin yanı sıra algılayıcı, `balanceOf(address)` ([incorrect_strict_equality.py#L63-L64](https://github.com/crytic/slither/blob/6d86220a53603476f9567c3358524ea4db07fb25/slither/detectors/statements/incorrect_strict_equality.py#L63-L64)) çağrısının dönüş değerini tehlikeli olarak değerlendirecektir ve kullanımını izlemek için veri bağımlılığı motorunu kullanır. +Veri bağımlılığı kullanımına bir örnek, [tehlikeli katı eşitlik dedektöründe](https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-strict-equalities) bulunabilir. Burada Slither, tehlikeli bir değere katı eşitlik karşılaştırması arar ([incorrect_strict_equality.py#L86-L87](https://github.com/crytic/slither/blob/6d86220a53603476f9567c3358524ea4db07fb25/slither/detectors/statements/incorrect_strict_equality.py#L86-L87)) ve bir saldırganın sözleşmeyi tuzağa düşürmesini önlemek için kullanıcıya `==` yerine `>=` veya `<=` kullanması gerektiğini bildirir. Diğer şeylerin yanı sıra dedektör, `balanceOf(address)` çağrısının dönüş değerini tehlikeli olarak kabul eder ([incorrect_strict_equality.py#L63-L64](https://github.com/crytic/slither/blob/6d86220a53603476f9567c3358524ea4db07fb25/slither/detectors/statements/incorrect_strict_equality.py#L63-L64)) ve kullanımını izlemek için veri bağımlılığı motorunu kullanır. -#### Sabit-nokta hesaplaması {#fixed-point-computation} +#### Sabit nokta hesaplaması {#fixed-point-computation} -Analiziniz CFG'de geziniyor ve kenarları takip ediyorsa, muhtemelen önceden ziyaret edilmiş düğümleri görmeniz olasıdır. Örneğin, aşağıda gösterildiği gibi bir döngü sunulursa: +Analiziniz CFG içinde gezinir ve kenarları takip ederse, daha önce ziyaret edilmiş düğümleri görmeniz olasıdır. Örneğin, bir döngü aşağıda gösterildiği gibi sunulursa: ```solidity for(uint i; i < range; ++){ @@ -183,23 +178,23 @@ for(uint i; i < range; ++){ } ``` -Analizinizin ne zaman duracağını bilmesi gerekecek. Burada iki ana strateji vardır: (1) her bir düğümde sınırlı sayıda yineleme yapın, (2) _düzeltme noktası_ olarak adlandırılan bir noktayı hesaplayın. Bir düzeltme noktası temel olarak, bu düğümü analiz etmenin herhangi bir anlamlı bilgi sağlamadığı anlamına gelir. +Analizinizin ne zaman duracağını bilmesi gerekir. Burada iki ana strateji vardır: (1) her düğümde sonlu sayıda yineleme yapmak, (2) _sabit nokta_ adı verilen bir şeyi hesaplamak. Sabit nokta, temel olarak bu düğümü analiz etmenin artık anlamlı bir bilgi sağlamadığı anlamına gelir. -Kullanılan bir sabitleme noktası örneği yeniden giriş algılayıcılarında bulunabilir: Slither düğümleri araştırır ve harici çağrıları arar, belleğe yazar ve okur. Bir düzeltme noktasına ulaştığında ([reentrancy.py#L125-L131](https://github.com/crytic/slither/blob/master/slither/detectors/reentrancy/reentrancy.py#L125-L131)), keşfi durdurur ve farklı yeniden giriş modelleri aracılığıyla bir yeniden girişin olup olmadığını görmek için sonuçları analiz eder ([reentrancy_benign.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_benign.py), [reentrancy_read_before_write.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_read_before_write.py), [reentrancy_eth.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_eth.py)). +Kullanılan bir sabit nokta örneği, yeniden giriş dedektörlerinde bulunabilir: Slither düğümleri araştırır ve harici çağrıları, depolamaya yazma ve okuma işlemlerini arar. Bir sabit noktaya ulaştığında ([reentrancy.py#L125-L131](https://github.com/crytic/slither/blob/master/slither/detectors/reentrancy/reentrancy.py#L125-L131)), keşfi durdurur ve farklı yeniden giriş desenleri ([reentrancy_benign.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_benign.py), [reentrancy_read_before_write.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_read_before_write.py), [reentrancy_eth.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_eth.py)) aracılığıyla bir yeniden girişin mevcut olup olmadığını görmek için sonuçları analiz eder. -Etkili sabit nokta hesaplama kullanarak analiz yazmak, analizin bilgilerini nasıl yaydığının iyi anlaşılmasını gerektirir. +Verimli sabit nokta hesaplaması kullanarak analizler yazmak, analizin kendi bilgilerini nasıl yaydığını iyi anlamayı gerektirir. ### Ara temsil {#intermediate-representation} -Bir ara temsil (IR), statik analize orijinalinden daha uygun olması amaçlanan bir dildir. Slither, Solidity'yi kendi IR'ına çevirir: [SlithIR](https://github.com/crytic/slither/wiki/SlithIR). +Bir ara temsil (IR), statik analize orijinalinden daha elverişli olması amaçlanan bir dildir. Slither, Solidity'yi kendi IR'si olan [SlithIR](https://github.com/crytic/slither/wiki/SlithIR)'ye çevirir. -Yalnızca temel kontroller yazmak istiyorsanız SlithIR'ı anlamak gerekli değildir. Ancak, ileri düzey anlamsal analiz yazmayı planlıyorsanız kullanışlı olacaktır. [SlithIR](https://github.com/crytic/slither/wiki/Printer-documentation#slithir) ve [SSA](https://github.com/crytic/slither/wiki/Printer-documentation#slithir-ssa) yazıcıları, kodun nasıl çevirildiğini anlamanıza yardımcı olacaktır. +Yalnızca temel kontroller yazmak istiyorsanız SlithIR'ı anlamanız gerekli değildir. Ancak, gelişmiş anlamsal analizler yazmayı planlıyorsanız kullanışlı olacaktır. [SlithIR](https://github.com/crytic/slither/wiki/Printer-documentation#slithir) ve [SSA](https://github.com/crytic/slither/wiki/Printer-documentation#slithir-ssa) yazıcıları, kodun nasıl çevrildiğini anlamanıza yardımcı olacaktır. ## API Temelleri {#api-basics} -Slither, sözleşmenin temel özelliklerini ve fonksiyonlarını keşfetmenizi sağlayan bir API'ye sahiptir. +Slither'ın, sözleşmenin ve fonksiyonlarının temel niteliklerini keşfetmenizi sağlayan bir API'si vardır. -Bir kod temelini yüklemek için: +Bir kod tabanını yüklemek için: ```python from slither import Slither @@ -209,30 +204,30 @@ slither = Slither('/path/to/project') ### Sözleşmeleri ve fonksiyonları keşfetme {#exploring-contracts-and-functions} -Bir `Slither` objesi şunlara sahiptir: +Bir `Slither` nesnesi şunlara sahiptir: - `contracts (list(Contract)`: sözleşme listesi -- `contracts_derived (list(Contract)`: Başka bir sözleşme tarafından kalıtılmayan sözleşmelerin listesi (sözleşmelerin alt kümesi) -- `get_contract_from_name (str)`: İsminden bir sözleşmeyi döndürür +- `contracts_derived (list(Contract)`: başka bir sözleşme tarafından kalıtılmayan sözleşmelerin listesi (sözleşmelerin alt kümesi) +- `get_contract_from_name (str)`: Adından bir sözleşme döndürür -Bir `Contract` objesi şunlara sahiptir: +Bir `Contract` nesnesi şunlara sahiptir: - `name (str)`: Sözleşmenin adı - `functions (list(Function))`: Fonksiyon listesi -- `modifiers (list(Modifier))`: Fonksiyon listesi -- `all_functions_called (list(Function/Modifier))`: Sözleşme tarafından erişilebilen tüm iç fonksiyonların listesi -- `inheritance (list(Contract))`: Kalıtılan sözleşmelerin listesi -- `get_function_from_signature (str)`: İmzasından bir Function döndürür -- `get_modifier_from_signature (str)`: İmzasından bir Modifier döndürür -- `get_state_variable_from_name (str)`: İsminden bir StateVariable döndürür +- `modifiers (list(Modifier))`: Niteleyici listesi +- `all_functions_called (list(Function/Modifier))`: Sözleşme tarafından erişilebilen tüm dahili fonksiyonların listesi +- `inheritance (list(Contract))`: Kalıtılmış sözleşmelerin listesi +- `get_function_from_signature (str)`: İmzasından bir Fonksiyon döndürür +- `get_modifier_from_signature (str)`: İmzasından bir Niteleyici döndürür +- `get_state_variable_from_name (str)`: Adından bir StateVariable (Durum Değişkeni) döndürür -Bir `Function` veya `Modifier` objesi şunlara sahiptir: +Bir `Function` veya `Modifier` nesnesi şunlara sahiptir: - `name (str)`: Fonksiyonun adı -- `contract (contract)`: Fonksiyonun duyurulduğu sözleşmenin adı -- `nodes (list(Node))`: Fonksiyonun/niteleyicinin CFG'sini tutan düğümlerin listesi -- `entry_point (Node)`: CFG giriş noktası +- `contract (contract)`: fonksiyonun bildirildiği sözleşme +- `nodes (list(Node))`: Fonksiyonun/niteleyicinin CFG'sini oluşturan düğümlerin listesi +- `entry_point (Node)`: CFG'nin giriş noktası - `variables_read (list(Variable))`: Okunan değişkenlerin listesi - `variables_written (list(Variable))`: Yazılan değişkenlerin listesi -- `state_variables_read (list(StateVariable))`: Okunan durum değişkenlerinin listesi (okunan değişkenlerin alt kümesi) -- `state_variables_written (list(StateVariable))`: Yazılan durum değişkenlerinin listesi (yazılan değişkenlerin alt kümesi) +- `state_variables_read (list(StateVariable))`: Okunan durum değişkenlerinin listesi (okunan `değişkenlerin` alt kümesi) +- `state_variables_written (list(StateVariable))`: Yazılan durum değişkenlerinin listesi (yazılan `değişkenlerin` alt kümesi) diff --git a/public/content/translations/tr/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md b/public/content/translations/tr/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md index 12d001be4f6..51a7cf8c821 100644 --- a/public/content/translations/tr/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md +++ b/public/content/translations/tr/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md @@ -1,55 +1,52 @@ --- -title: Tellor Kâhininiz olarak nasıl kurulur -description: Tellor kâhinini protokolünüze entegre etmeye başlamak için bir rehber +title: "Tellor'u Kâhininiz Olarak Nasıl Kurarsınız?" +description: "Tellor kâhinini protokolünüze entegre etmeye başlamak için bir rehber" author: "Tellor" lang: tr -tags: - - "solidity" - - "akıllı kontratlar" - - "kâhinler" -skill: intermediate +tags: ["solidity", "smart contracts", "oracles"] +skill: beginner published: 2021-06-29 -source: Tellor Belgeleri +source: Tellor Docs sourceUrl: https://docs.tellor.io/tellor/ --- -Hızlı Soru: Protokolünüz tamamlanmak üzere ancak zincir dışı verilere erişmek için bir kâhine ihtiyacı var... Ne yaparsınız? +Hızlı Soru: Protokolünüz tamamlanmak üzere, ancak zincir dışı verilere erişmek için bir kâhine ihtiyacı var... Ne yaparsınız? -## (Hafif) Ön Koşullar {#soft-prerequisites} +## (Yumuşak) Ön Koşullar {#soft-prerequisites} Bu gönderi, bir kâhin akışına erişmeyi mümkün olduğunca basit ve anlaşılır hâle getirmeyi amaçlamaktadır. Bununla birlikte, kâhin yönüne odaklanmak için kodlama beceri seviyeniz hakkında aşağıdakileri varsayıyoruz. Varsayımlar: -- bir terminalde gezinebildiğiniz, -- npm'yi kurduğunuz -- bağımlılıkları yönetmek için npm'yi nasıl kullanacağınızı bildiğiniz +- bir terminalde gezinebilmeniz +- npm'nin kurulu olması +- bağımlılıkları yönetmek için npm'yi nasıl kullanacağınızı bilmeniz -Tellor, uygulamaya hazır yayınlanmış ve açık kaynaklı bir kâhindir. Bu başlangıç rehberi, projenize tamamen merkeziyetsiz ve sansüre dayanıklı bir kâhin sağlayarak Tellor ile çalışmaya başlamanın kolaylığını gösterme amacı taşır. +Tellor, uygulamaya hazır, canlı ve açık kaynaklı bir kâhindir. Bu başlangıç kılavuzu, projenize tamamen merkeziyetsiz ve sansüre dayanıklı bir kâhin sağlayarak Tellor'u kullanmaya başlamanın ne kadar kolay olduğunu göstermek için hazırlanmıştır. ## Genel Bakış {#overview} -Tellor, tarafların zincir dışı bir veri noktasının (örneğin BTC/USD) değerini talep edebildiği ve raporlayıcıların bu değeri tüm Ethereum akıllı sözleşmeleri tarafından erişilebilen zincir üstü bir veri bankasına eklemek için rekabet ettiği bir kâhin sistemidir. Bu veri bankasına yapılan girdiler, stake edilmiş muhabirlerden oluşan bir ağ tarafından güvence altına alınmıştır. Tellor, raporlayıcılar tarafından sağlanan dürüst veri kayıtlarını ödüllendiren, Tributes (TRB) Tellor jetonunun piyasaya sürülmesi ve uyuşmazlık mekanizması aracılığıyla kötü niyetli davrananları cezalandıran kripto ekonomik teşvik mekanizmalarını kullanır. +Tellor, tarafların zincir dışı bir veri noktasının (ör. BTC/USD) değerini talep edebildiği ve raporlayıcıların bu değeri tüm Ethereum akıllı sözleşmeleri tarafından erişilebilen, zincir üstü bir veri bankasına eklemek için rekabet ettiği bir kâhin sistemidir. Bu veri bankasına yapılan girdiler, stake edilmiş raporlayıcılardan oluşan bir ağ tarafından güvence altına alınır. Tellor; raporlayıcılar tarafından dürüst veri gönderimlerini ödüllendiren ve Tellor'un jetonu olan Tributes (TRB) ihracı ve bir uyuşmazlık mekanizması aracılığıyla kötü niyetli aktörleri cezalandıran, kripto-ekonomik teşvik mekanizmalarından yararlanır. -Bu öğreticide şunların üzerinden geçeceğiz: +Bu öğreticide şunları ele alacağız: -- Kurup çalıştırmanız gereken başlangıç araç setinin kurulumu. -- Basit bir örneğe genel bakış. -- Şu anda Tellor'ı test edebileceğiniz ağların test ağlarının adreslerini listelemek. +- Çalışmaya başlamak için ihtiyacınız olacak ilk araç setinin kurulumu. +- Basit bir örnek üzerinden ilerleme. +- Tellor'ı şu anda test edebileceğiniz ağların test ağı adreslerini listeleme. -## UsingTellor {#usingtellor} +## UsingTellor Kullanımı {#usingtellor} -Yapmak isteyeceğiniz ilk şey, Tellor'ı kâhininiz olarak kullanmak için gerekli olan temel araçları kurmaktır. Tellor Kullanıcı Sözleşmelerini yüklemek için [bu paketi](https://github.com/tellor-io/usingtellor) kullanın: +Yapmak isteyeceğiniz ilk şey, Tellor'u kâhininiz olarak kullanmak için gerekli temel araçları kurmaktır. Tellor Kullanıcı Sözleşmelerini kurmak için [bu paketi](https://github.com/tellor-io/usingtellor) kullanın: `npm install usingtellor` -Kurulduktan sonra bu, sözleşmelerinizin "UsingTellor" sözleşmesinden fonksiyonları devralmasına olanak tanır. +Kurulduktan sonra bu, sözleşmelerinizin 'UsingTellor' sözleşmesinden fonksiyonları devralmasına olanak tanır. -Harika! Artık araçları hazırladığınıza göre, bitcoin fiyatını alacağımız basit bir alıştırmadan geçelim: +Harika! Artık araçlar hazır olduğuna göre, bitcoin fiyatını aldığımız basit bir alıştırma yapalım: ### BTC/USD Örneği {#btcusd-example} -UsingTellor sözleşmesini kalıtım yoluya alarak Tellor adresini bir yapıcı argüman olarak geçirmek: +Tellor adresini bir yapıcı argümanı olarak geçirerek UsingTellor sözleşmesini kalıtın: İşte bir örnek: @@ -59,7 +56,7 @@ import "usingtellor/contracts/UsingTellor.sol"; contract PriceContract is UsingTellor { uint256 public btcPrice; - //This Contract now has access to all functions in UsingTellor + //Bu Sözleşme artık UsingTellor'daki tüm fonksiyonlara erişebilir constructor(address payable _tellorAddress) UsingTellor(_tellorAddress) public {} @@ -77,8 +74,8 @@ function setBtcPrice() public { } ``` -Sözleşme adreslerinin tam listesi için [buraya](https://docs.tellor.io/tellor/the-basics/contracts-reference) başvurun. +Sözleşme adreslerinin tam listesi için [buraya](https://docs.tellor.io/tellor/the-basics/contracts-reference) bakın. -Kullanım kolaylığı sağlamak adına, UsingTellor deposu kolay entegrasyon için [Tellor Playground](https://github.com/tellor-io/TellorPlayground) sözleşmesiyle birlikte sunulur. Yardımcı işlevlerin bir listesini görmek için [buraya](https://github.com/tellor-io/sampleUsingTellor#tellor-playground) bakın. +Kullanım kolaylığı için UsingTellor deposu, daha kolay entegrasyon için [Tellor Playground](https://github.com/tellor-io/TellorPlayground) sözleşmesinin bir sürümünü içerir. Yardımcı fonksiyonların listesi için [buraya](https://github.com/tellor-io/sampleUsingTellor#tellor-playground) bakın. Tellor kâhininin daha sağlam bir uygulaması için mevcut fonksiyonların tam listesine [buradan](https://github.com/tellor-io/usingtellor/blob/master/README.md) göz atın. diff --git a/public/content/translations/tr/developers/tutorials/how-to-view-nft-in-metamask/index.md b/public/content/translations/tr/developers/tutorials/how-to-view-nft-in-metamask/index.md index a8c21ec37bc..4cf687e9d21 100644 --- a/public/content/translations/tr/developers/tutorials/how-to-view-nft-in-metamask/index.md +++ b/public/content/translations/tr/developers/tutorials/how-to-view-nft-in-metamask/index.md @@ -1,36 +1,33 @@ --- -title: NFT'nizi Cüzdanınızda Nasıl Görüntüleyebilirsiniz (NFT Öğretici Serisi Bölüm 3/3) -description: Bu öğretici, MetaMask'ta mevcut bir NFT'nin nasıl görüntüleneceğini açıklar! +title: "NFT'nizi Cüzdanınızda Nasıl Görüntüleyebilirsiniz (NFT Öğretici Serisi Bölüm 3/3)" +description: "Bu öğretici, MetaMask'ta mevcut bir NFT'nin nasıl görüntüleneceğini açıklar!" author: "Sumi Mudgil" -tags: - - "ERC-721" - - "Alchemy" - - "Solidity" -skill: advanced +tags: [ "ERC-721", "Alchemy", "Solidity" ] +skill: beginner lang: tr published: 2021-04-22 --- -Bu öğretici, yeni basılmış NFT'mizi görüntülediğimiz NFT Öğretici serisinin Bölüm 3/3'üdür. Ancak, Mainnet veya herhangi bir test ağı dahil olmak üzere MetaMask kullanan herhangi bir ERC-721 token'ı için genel öğreticiyi kullanabilirsiniz. Ethereum üzerinde kendi NFT'nizi nasıl basacağınızı öğrenmek istiyorsanız, [Bir NFT Nasıl Yazılır ve Dağıtılır](/developers/tutorials/how-to-write-and-deploy-an-nft) kısmına göz atmalısınız! +Bu öğretici, yeni basılmış NFT'mizi görüntülediğimiz NFT Öğretici serisinin Bölüm 3/3'üdür. Ancak, Mainnet veya herhangi bir test ağı dahil olmak üzere MetaMask kullanan herhangi bir ERC-721 token'ı için genel öğreticiyi kullanabilirsiniz. Ethereum üzerinde kendi NFT'nizi nasıl basacağınızı öğrenmek istiyorsanız, Bir NFT Nasıl Yazılır ve Dağıtılır kısmına göz atmalısınız! Tebrikler! NFT öğretici serimizin en kısa ve en basit kısmına geldiniz: Yeni basılmış NFT'nizi sanal bir cüzdanda görüntüleme. Önceki iki bölümde onu kullandığımızdan dolayı bu örnek için MetaMask kullanacağız. -Bir ön koşul olarak, MetaMask'in mobil cihazınızda zaten kurulu olması ve NFT'nizi bastığınız hesabı içermesi gerekir: Uygulamayı [iOS](https://apps.apple.com/us/app/metamask-blockchain-wallet/id1438144202) veya [Android](https://play.google.com/store/apps/details?id=io.metamask&hl=en_US&gl=US) üzerinden ücretsiz edinebilirsiniz. +Ön koşul olarak, mobil cihazınızda MetaMask'in kurulu olması ve NFT'nizi bastığınız hesabın dahil olması gerekir. Uygulamayı [iOS](https://apps.apple.com/us/app/metamask-blockchain-wallet/id1438144202) veya [Android](https://play.google.com/store/apps/details?id=io.metamask&hl=en_US&gl=US) için ücretsiz olarak edinebilirsiniz. -## Adım 1: Ağınızı Sepolia'ya ayarlayın {#set-network-to-sepolia} +## Adım 1: Ağınızı Sepolia olarak ayarlayın {#set-network-to-sepolia} -Uygulamanın üst kısmındaki "Wallet" (Cüzdan) düğmesine basın, ardından bir ağ seçmeniz istenecektir. NFT'miz Sepolia ağında basıldığından, ağınız olarak Sepolia'yı seçmeniz makuldür. +Uygulamanın üst kısmındaki "Wallet" (Cüzdan) düğmesine basın, ardından bir ağ seçmeniz istenecektir. NFT'miz Sepolia ağında basıldığı için ağınız olarak Sepolia'yı seçmelisiniz. -![MetaMask Mobile üzerinde ağınızı Sepolia olarak ayarlama](./goerliMetamask.gif) +![MetaMask Mobile'da ağınızı Sepolia olarak ayarlama](./goerliMetamask.gif) ## Adım 2: Koleksiyon öğenizi MetaMask'e ekleyin {#add-nft-to-metamask} Sepolia ağına girdikten sonra, sağdaki "Collectibles" (Koleksiyon Öğeleri) sekmesini seçip NFT akıllı sözleşme adresini ve NFT'nizin ERC-721 jeton kimliğini ekleyin: Bunu, öğreticimizin 2. Bölümünde dağıtılan NFT'nizin işlem karması temelinde Etherscan'de bulabilirsiniz. -![İşlem hash değerinizi ve ERC-721 token kimliğinizi nasıl bulabilirsiniz](./findNFTEtherscan.png) +![İşlem karmanızı ve ERC-721 jeton kimliğinizi bulma](./findNFTEtherscan.png) -NFT'nizi görüntülemek için birkaç kez yenilemeniz gerekebilir ancak kesinle orada olacaktır! +NFT'nizi görüntülemek için birkaç kez yenilemeniz gerekebilir ancak kesinlikle orada olacaktır ! -![NFT'nizi MetaMask'e nasıl yüklersiniz](./findNFTMetamask.gif) +![NFT'nizi MetaMask'e yükleme](./findNFTMetamask.gif) Tebrikler! Bir NFT'yi başarıyla bastınız ve şimdi onu görüntüleyebilirsiniz! NFT dünyasını nasıl kasıp kavuracağınızı görmek için sabırsızlanıyoruz! diff --git a/public/content/translations/tr/developers/tutorials/how-to-write-and-deploy-an-nft/index.md b/public/content/translations/tr/developers/tutorials/how-to-write-and-deploy-an-nft/index.md index 3ebd559f150..00fdc778644 100644 --- a/public/content/translations/tr/developers/tutorials/how-to-write-and-deploy-an-nft/index.md +++ b/public/content/translations/tr/developers/tutorials/how-to-write-and-deploy-an-nft/index.md @@ -1,13 +1,9 @@ --- -title: Bir NFT Nasıl Yazılır ve Dağıtılır (NFT Öğretici Serisi Bölüm 1/3) -description: Bu öğretici, Ethereum ve Gezegenler Arası Dosya Sistemi (IPFS) kullanarak bir Değiştirilemez Token (ERC-721 token'ı) akıllı sözleşmesinin nasıl yazılacağı ve dağıtılacağı konusunda adım adım yol gösterecek olan NFT'lerle ilgili bir dizinin 1. Bölümüdür. +title: "Bir NFT Nasıl Yazılır ve Dağıtılır (NFT Öğretici Serisi Bölüm 1/3)" +description: "Bu öğretici, Ethereum ve Gezegenler Arası Dosya Sistemi (IPFS) kullanarak bir Değiştirilemez Token (ERC-721 token'ı) akıllı sözleşmesinin nasıl yazılacağı ve dağıtılacağı konusunda adım adım yol gösterecek olan NFT'lerle ilgili bir dizinin 1. Bölümüdür." author: "Sumi Mudgil" -tags: - - "ERC-721" - - "Alchemy" - - "Solidity" - - "akıllı sözleşmeler" -skill: advanced +tags: [ "ERC-721", "Alchemy", "Solidity", "akıllı kontratlar" ] +skill: beginner lang: tr published: 2021-04-22 --- @@ -16,23 +12,23 @@ NFT'lerin blokzinciri geniş kitlelere tanıtmasıyla, Ethereum blokzinciri üze Alchemy; Makersplace (son zamanlarda Christie's'de 69 Milyon ABD Doları değerinde rekor bir dijital sanat eseri satışı gerçekleştirdi), Dapper Labs (NBA Top Shot ve Crypto Kitties'in yaratıcıları), OpenSea (dünyanın en büyük NFT pazarı), Zora, Super Rare, NFTfi, Foundation, Enjin, Origin Protocol, Immutable ve daha fazlası gibi NFT alanındaki büyük isimleri desteklemekten büyük bir gurur duyuyor. -Bu öğreticide; [MetaMask](https://metamask.io/), [Solidity](https://docs.soliditylang.org/en/v0.8.0/), [Hardhat](https://hardhat.org/), [Pinata](https://pinata.cloud/) ve [Alchemy](https://alchemy.com/signup/eth) kullanarak Sepolia test ağında ERC-721 akıllı sözleşmesi oluşturma ve dağıtma adımlarını inceleyeceğiz (ne olduğunu anlamıyorsanız üzülmeyin, açıklayacağız!). +Bu öğreticide, [MetaMask](https://metamask.io/), [Solidity](https://docs.soliditylang.org/en/v0.8.0/), [Hardhat](https://hardhat.org/), [Pinata](https://pinata.cloud/) ve [Alchemy](https://alchemy.com/signup/eth) kullanarak Sepolia test ağında bir ERC-721 akıllı sözleşmesi oluşturma ve dağıtma adımlarını inceleyeceğiz (bunların ne anlama geldiğini henüz anlamıyorsanız endişelenmeyin, açıklayacağız!). Bu öğreticinin 2. Bölümünde, bir NFT'yi basmak için akıllı sözleşmemizi nasıl kullanabileceğimizi inceleyeceğiz ve 3. Bölümde NFT'nizi MetaMask üzerinde nasıl görüntüleyeceğinizi açıklayacağız. -Ve elbette, herhangi bir noktada sorunuz olursa, [Alchemy Discord](https://discord.gg/gWuC7zB)'dan bize ulaşmaktan veya [Alchemy'nin NFT API belgelerini](https://docs.alchemy.com/alchemy/enhanced-apis/nft-api) ziyaret etmekten çekinmeyin! +Ve elbette, herhangi bir noktada sorularınız olursa, [Alchemy Discord](https://discord.gg/gWuC7zB)'dan bize ulaşmaktan veya [Alchemy'nin NFT API belgelerini](https://docs.alchemy.com/alchemy/enhanced-apis/nft-api) ziyaret etmekten çekinmeyin! ## Adım 1: Ethereum ağına bağlanın {#connect-to-ethereum} -Ethereum blok zincirine istek göndermenin birçok yolu vardır, ancak işleri kolaylaştırmak için, kendi düğümlerimizi çalıştırmak zorunda kalmadan Ethereum zinciri ile iletişim kurmamızı sağlayan bir blok zinciri geliştirici platformu ve API'si olan[Alchemy](https://alchemy.com/signup/eth)'de ücretsiz bir hesap kullanacağız. +Ethereum blok zincirine istek göndermenin birçok yolu vardır, ancak işleri kolaylaştırmak için, kendi düğümlerimizi çalıştırmak zorunda kalmadan Ethereum zinciri ile iletişim kurmamızı sağlayan bir blok zinciri geliştirici platformu ve API'si olan [Alchemy](https://alchemy.com/signup/eth)'de ücretsiz bir hesap kullanacağız. Bu eğitimde, akıllı sözleşme dağıtımımızda perde arkasında neler olup bittiğini anlamak için Alchemy'nin izleme ve analitik geliştirici araçlarından da yararlanacağız. Henüz bir Alchemy hesabınız yoksa, [buradan](https://alchemy.com/signup/eth) ücretsiz kaydolabilirsiniz. ## Adım 2: Uygulamanızı (ve API anahtarınızı) oluşturun {#make-api-key} -Bir Alchemy hesabı oluşturduktan sonra, bir uygulama oluşturarak bir API anahtarı oluşturabilirsiniz. Bu, Sepolia test ağına istekte bulunmamıza izin verecektir. Eğer test ağları hakkında daha fazlasını öğrenmeye meraklıysanız [bu rehbere](https://docs.alchemyapi.io/guides/choosing-a-network) göz atın. +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ı hakkında daha fazla bilgi edinmek isterseniz [bu kılavuza](https://docs.alchemyapi.io/guides/choosing-a-network) göz atın. -1. Gezinme çubuğundaki "Uygulamalar"ın üzerine gelip "Uygulama Oluştur"a tıklayarak Simya Panonuzdaki "Uygulama Oluştur" sayfasına gidin +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 ![Uygulamanızı oluşturun](./create-your-app.png) @@ -40,27 +36,29 @@ Bir Alchemy hesabı oluşturduktan sonra, bir uygulama oluşturarak bir API anah ![Uygulamanızı yapılandırın ve yayınlayın](./alchemy-explorer-sepolia.png) -3. "Uygulama oluştur"u tıklayın, işte bu kadar! Uygulamanız aşağıdaki tabloda 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ı oluşturun (adres) {#create-eth-address} -İş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. 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. +İş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. 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. -[Buradan](https://metamask.io/download) ücretsiz olarak bir MetaMask hesabı indirebilir ve oluşturabilirsiniz. Bir hesap oluştururken, ya da bir hesabınız çoktan varsa, sağ üstten Sepolia Test Ağına geçtiğinizden emin olun (bu sayede gerçek parayla denemeler yapmayız). +MetaMask'ı [buradan](https://metamask.io/download) ücretsiz indirip bir hesap oluşturabilirsiniz. Bir hesap oluştururken, ya da bir hesabınız çoktan varsa, sağ üstten Sepolia Test Ağına geçtiğinizden emin olun (bu sayede gerçek parayla denemeler yapmayız). ![Sepolia'yı ağınız olarak ayarlayın](./metamask-goerli.png) ## Adım 4: Bir Musluktan ether ekleyin {#step-4-add-ether-from-a-faucet} -Akıllı sözleşmemizi test ağına dağıtmak için biraz sahte ETH'ye ihtiyacımız olacak. ETH alabilmek için Alchemy tarafından barındırılan [Sepolia Musluğuna](https://sepoliafaucet.com/) gidin, hesabınızın adresini girin, sonra da "Bana ETH gönder"e tıklayın. Kısa bir süre sonra MetaMask hesabınızda ETH'yi görmelisiniz! +Akıllı sözleşmemizi test ağına dağıtmak için biraz sahte ETH'ye ihtiyacımız olacak. ETH almak için Alchemy tarafından barındırılan [Sepolia Musluğuna](https://sepoliafaucet.com/) gidin, oturum açın, hesap adresinizi girin ve “Bana ETH Gönder”e tıklayın. Kısa bir süre sonra Metamask hesabınızda ETH'yi görmelisiniz! ## Adım 5: Bakiyenizi kontrol edin {#check-balance} -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 mevcut 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: + ``` `{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"}` + ``` -> **NOT:** Bu sonuç ETH değil, wei biçimindedir. 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 0xde0b6b3a7640000'ı ondalık sayıya dönüştürürsek 1\*1018 wei elde ederiz, bu da 1 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üştürme 1 eth = 1018 wei şeklindedir. Yani 0xde0b6b3a7640000'ı ondalık sayıya dönüştürürsek 1\*1018 wei elde ederiz, bu da 1 ETH'ye eşittir. Vay be! Tüm sahte paramız yerli yerinde. @@ -68,18 +66,23 @@ Vay be! Tüm sahte paramız yerli yerinde. Öncelikle projemiz için bir klasör oluşturmamız gerekecek. Komut satırınıza gidin ve şunu yazın: + ``` mkdir my-nft cd my-nft + ``` -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](https://nodejs.org/en/download/)'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 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) takip edin ([Node.js](https://nodejs.org/en/download/)'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çıkladık: + ```json package name: (my-nft) version: (1.0.0) - description: My first NFT! + description: İlk NFT'm! entry point: (index.js) test command: git repository: @@ -91,7 +94,7 @@ Kurulum sorularına nasıl cevap verdiğiniz çok önemli değil; referans olmas { "name": "my-nft", "version": "1.0.0", - "description": "My first NFT!", + "description": "İlk NFT'm!", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" @@ -100,15 +103,18 @@ Kurulum sorularına nasıl cevap verdiğiniz çok önemli değil; referans olmas "license": "ISC" } ``` + package.json'ı onaylayın ve artık hazırız! -## Adım 7: [Hardhat](https://hardhat.org/getting-started/#overview)'i kurun {#install-hardhat} +## Adım 7: [Hardhat](https://hardhat.org/getting-started/#overview)'i Kurun {#install-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. my-nft projemizin içinde şunu yürütün: + ``` 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. @@ -116,10 +122,13 @@ my-nft projemizin içinde şunu yürütün: Proje klasörümüzün içinde şunu yürütün: + ``` npx hardhat + ``` Daha sonra bir karşılama mesajı ve ne yapmak istediğinizi seçme seçeneği görmelisiniz. "create an empty hardhat.config.js"yi (boş bir hardhat.config.js oluştur) seçin: + ``` 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 @@ -128,11 +137,12 @@ Daha sonra bir karşılama mesajı ve ne yapmak istediğinizi seçme seçeneği 888 888 .d888888 888 888 888 888 888 .d888888 888 888 888 888 888 888 Y88b 888 888 888 888 888 Y88b. 888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888 - 👷 Hardhat v2.0.11 Hoşgeldin 👷‍ - ? Ne yapmak istersin? … - Create a sample project - ❯ Create an empty hardhat.config.js - Quit + 👷 Hardhat v2.0.11 sürümüne hoş geldiniz 👷‍ + ? Ne yapmak istersiniz? … + Örnek bir proje oluşturun + ❯ Boş bir hardhat.config.js oluşturun + Çı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). @@ -140,8 +150,10 @@ Bu, bizim için bir hardhat.config.js dosyası oluşturacak ve burada projemiz i Projemizi düzenli tutmak için iki yeni klasör oluşturacağız. Komut satırınızda projenizin kök dizinine gidin ve şunu yazın: + ``` mkdir contracts mkdir scripts + ``` - contracts/, NFT akıllı sözleşme kodumuzu tutacağımız yerdir @@ -151,14 +163,14 @@ Projemizi düzenli tutmak için iki yeni klasör oluşturacağız. Komut satır Artık ortamımız hazır olduğuna göre, daha heyecan verici şeylere geçelim: _akıllı sözleşme kodumuzu yazmak!_ -Favori düzenleyicinizde my-nft projesini açın. (biz [VSCode](https://code.visualstudio.com/)'u tercih ediyoruz). Akıllı sözleşmeler, MyNFT.sol akıllı sözleşmemizi yazmak için kullanacağımız Solidity adlı bir dilde yazılır.‌ +`my-nft` projesini tercih ettiğiniz bir düzenleyicide açın (biz [VSCode](https://code.visualstudio.com/)'u tercih ediyoruz). Akıllı sözleşmeler, MyNFT.sol akıllı sözleşmemizi yazmak için kullanacağımız Solidity adlı bir dilde yazılır.‌ -1. `contracts` klasörüne gidin ve MyNFT.sol adlı yeni bir dosya oluşturun +1. `contracts` klasörüne gidin ve `MyNFT.sol` adında yeni bir dosya oluşturun. -2. Aşağıda, [OpenZeppelin](https://docs.openzeppelin.com/contracts/3.x/erc721) kütüphanesinin ERC-721 uygulamasını temel aldığımız NFT akıllı sözleşme kodumuz yer almaktadır. Aşağıdaki içeriği kopyalayıp MyNFT.sol dosyanıza yapıştırın. +2. Aşağıda, [OpenZeppelin](https://docs.openzeppelin.com/contracts/3.x/erc721) kütüphanesinin ERC-721 uygulamasını temel alan NFT akıllı sözleşme kodumuz bulunmaktadır. Aşağıdaki içeriği kopyalayıp MyNFT.sol dosyanıza yapıştırın. ```solidity - //Contract based on [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721) + //Sözleşme [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721)'i temel almıştır. // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -188,68 +200,74 @@ Favori düzenleyicinizde my-nft projesini açın. (biz [VSCode](https://code.vis } ``` -3. Sınıfları OpenZeppelin sözleşme kütüphanesinden aldığımız için, kütüphaneyi klasörümüze kurmak için komut satırınızda `npm install @openzeppelin/contracts` komutunu yürütün. +3. OpenZeppelin sözleşme kütüphanesinden sınıfları miras aldığımız için, komut satırınızda `npm install @openzeppelin/contracts^4.0.0` komutunu çalıştırarak kütüphaneyi klasörümüze kurun. Peki, bu kod tam olarak ne _yapar_? Satır satır inceleyelim. -Akıllı sözleşmemizin en üstüne, üç tane [OpenZeppelin](https://openzeppelin.com/) akıllı sözleşme sınıfını içe aktararak ekliyoruz: +Akıllı sözleşmemizin en üstünde, üç [OpenZeppelin](https://openzeppelin.com/) akıllı sözleşme sınıfını içe aktarıyoruz: -- @openzeppelin/contracts/token/ERC721/ERC721.sol, NFT akıllı sözleşmemizin devralacağı ERC-721 standardının uygulamasını içerir. (Geçerli bir NFT olması için akıllı sözleşmenizin ERC-721 standardının tüm yöntemlerini uygulaması gerekir.) Devralınan ERC-721 fonksiyonları hakkında daha fazla bilgi edinmek için [buradaki](https://eips.ethereum.org/EIPS/eip-721) arayüz tanımına bakın. +- @openzeppelin/contracts/token/ERC721/ERC721.sol, NFT akıllı sözleşmemizin devralacağı ERC-721 standardının uygulamasını içerir. (Geçerli bir NFT olması için akıllı sözleşmenizin ERC-721 standardının tüm yöntemlerini uygulaması gerekir.) Miras alınan ERC-721 fonksiyonları hakkında daha fazla bilgi edinmek için [buradaki](https://eips.ethereum.org/EIPS/eip-721) arayüz tanımına göz atın. - @openzeppelin/contracts/utils/Counters.sol, yalnızca bir artırılabilen veya azaltılabilen sayaçlar sağlar. Akıllı sözleşmemiz, basılan toplam NFT sayısını takip etmek ve yeni NFT'mizde benzersiz kimliği belirlemek için bir sayaç kullanır. (Akıllı bir sözleşme kullanılarak basılan her NFT'ye benzersiz bir kimlik atanmalıdır: Burada benzersiz kimliğimiz yalnızca mevcut toplam NFT sayısı tarafından belirlenir. Örneğin, akıllı sözleşmemizle bastığımız ilk NFT'nin kimliği "1", ikinci NFT'mizin kimliği "2" vb. olacaktır.) -- @openzeppelin/contracts/access/Ownable.sol, akıllı sözleşmemizde sadece akıllı sözleşmenin sahibinin (sizin) NFT basabilmesi için [erişim kontrolü](https://docs.openzeppelin.com/contracts/3.x/access-control) kurulumu yapar. (Erişim kontrolünün dahil edilmesinin tamamen bir tercih olduğunu unutmayın. Herhangi birinin akıllı sözleşmenizi kullanarak bir NFT basabilmesini istiyorsanız, 10. satırdaki Ownable ve 17. satırdaki onlyOwner kelimelerini kaldırın.) +- `@openzeppelin/contracts/access/Ownable.sol`, akıllı sözleşmemizde [erişim kontrolü](https://docs.openzeppelin.com/contracts/3.x/access-control) kurar, böylece yalnızca akıllı sözleşmenin sahibi (yani siz) NFT basabilir. (Erişim kontrolünün dahil edilmesinin tamamen bir tercih olduğunu unutmayın. Herhangi birinin akıllı sözleşmenizi kullanarak bir NFT basabilmesini istiyorsanız, 10. satırdaki Ownable ve 17. satırdaki onlyOwner kelimelerini kaldırın.) -İçe aktarma ifadelerimizden sonra, şaşırtıcı derecede kısa olan özel NFT akıllı sözleşmemiz var: Yalnızca bir sayaç, bir oluşturucu ve tek bir fonksiyon içeriyor! Bu, NFT'nin sahibini döndüren `ownerOf` ve `transferFrom` gibi bir NFT oluşturmak için ihtiyaç duyduğumuz yöntemlerin çoğunu uygulayan devralınan, NFT'nin sahipliğini bir hesaptan diğerine aktaran OpenZeppelin sözleşmelerimiz sayesindedir. +İçe aktarma ifadelerimizden sonra, şaşırtıcı derecede kısa olan özel NFT akıllı sözleşmemiz var: Yalnızca bir sayaç, bir oluşturucu ve tek bir fonksiyon içeriyor! Bu, miras aldığımız OpenZeppelin sözleşmeleri sayesindedir. Bu sözleşmeler, bir NFT oluşturmak için ihtiyaç duyduğumuz yöntemlerin çoğunu uygular; örneğin NFT'nin sahibini döndüren `ownerOf` ve NFT'nin sahipliğini bir hesaptan diğerine aktaran `transferFrom`. ERC-721 oluşturucumuzda, "MyNFT" ve "NFT" olmak üzere 2 dize geçirdiğimizi göreceksiniz. İlk değişken akıllı sözleşmenin adı, ikincisi ise sembolüdür. Bu değişkenlerin her birine dilediğiniz gibi isim verebilirsiniz! Son olarak, bir NFT basmamızı sağlayan `mintNFT(address recipient, string memory tokenURI)` fonksiyonumuz var! Bu fonksiyonun iki değişken aldığını fark edeceksiniz: -- `recipient`, yeni basılmış NFT'nizi alacak adresi belirtir +- `address recipient`, yeni bastığınız NFT'yi alacak adresi belirtir. - `string memory tokenURI`, NFT'nin meta verilerini tanımlayan bir JSON belgesine çözümlenmesi gereken bir dizedir. Bir NFT'nin meta verileri, onu gerçekten hayata geçiren şeydir ve bir ad, açıklama, görüntü ve diğer nitelikler gibi yapılandırılabilir özelliklere sahip olmasını sağlar. Bu öğreticinin 2. bölümünde, bu meta verilerin nasıl yapılandırılacağını açıklayacağız. `mintNFT`, devralınan ERC-721 kitaplığından bazı yöntemleri çağırır ve nihayetinde yeni basılmış NFT'nin kimliğini temsil eden bir sayı döndürür. -## Adım 11: MetaMask ve Alchemy'i projenize bağlayın {#connect-metamask-and-alchemy} +## Adım 11: MetaMask ve Alchemy'yi projenize bağlayın {#connect-metamask-and-alchemy} Artık bir MetaMask cüzdanı ile Alchemy hesabı oluşturduğumuza ve akıllı sözleşmemizi yazdığımıza göre, üçünü birbirine bağlamanın zamanı geldi. 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: + ``` 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ı MetaMask'ten almak için [şu talimatları](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key) takip edin +- MetaMask'ten özel anahtarınızı dışa aktarmak için [bu talimatları](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key) izleyin. - HTTP Alchemy API URL'sini almak ve panonuza kopyalamak için aşağıya göz atın ![Alchemy API URL'nizi kopyalayın](./copy-alchemy-api-url.gif) -`.env` artık şöyle görünmelidir: +`.env` dosyanız şimdi şöyle görünmelidir: + ``` 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. -## Adım 12: Ethers.js'yi kurun {#install-ethers} +## Adım 12: Ethers.js Kurun {#install-ethers} -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: + ``` npm install --save-dev @nomiclabs/hardhat-ethers ethers@^5.0.0 + ``` Bir sonraki adımda hardhat.config.js'mizde de ether'lere ihtiyacımız olacak. @@ -285,24 +303,26 @@ Hardhat.config.js dosyanızı şöyle görünecek şekilde güncelleyin: Komut satırından şunu yürütün: + ``` npx hardhat compile + ``` -Kaynak dosyada verilmeyen SPDX lisans tanımlayıcısı hakkında bir uyarı 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. +Kaynak dosyada verilmeyen SPDX lisans tanımlayıcısı hakkında bir uyarı alabilirsiniz, ancak bunun için endişelenmenize gerek yok, geri kalan her şey düzgün olacaktı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 {#write-deploy} +## Adım 15: Dağıtım betiğimizi yazın {#write-deploy} 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çerikleri ekleyerek `deploy.js` adlı yeni bir dosya oluşturun: +`scripts/` klasörüne gidin ve `deploy.js` adında yeni bir dosya oluşturup aşağıdaki içeriği ekleyin: ```js async function main() { const MyNFT = await ethers.getContractFactory("MyNFT") - // Start deployment, returning a promise that resolves to a contract object + // Dağıtımı başlat, bir sözleşme nesnesine dönüşecek bir promise döndürür const myNFT = await MyNFT.deploy() await myNFT.deployed() - console.log("Contract deployed to address:", myNFT.address) + console.log("Sözleşme şu adrese dağıtıldı:", myNFT.address) } main() @@ -313,13 +333,17 @@ 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 MyNFT = await ethers.getContractFactory("MyNFT"); + ``` Ethers.js'deki ContractFactory, yeni akıllı sözleşmeleri dağıtmak için kullanılan bir soyutlamadır, bu nedenle MyNFT burada, NFT sözleşmemizin örnekleri için bir fabrikadır. Hardhat-ethers eklentisini kullanırken ContractFactory ve Sözleşme örnekleri, varsayılan olarak ilk imzalayana bağlanır. + ``` const myNFT = await MyNFT.deploy(); + ``` Bir ContractFactory üzerinde deploy() öğesinin çağrılması, dağıtımı başlatır ve bir çözümlendiğinde Sözleşme oluşturacak bir Söz döndürür. Bu, akıllı sözleşme fonksiyonlarımızın her biri için bir yöntemi olan nesnedir. @@ -327,26 +351,30 @@ Bir ContractFactory üzerinde deploy() öğesinin çağrılması, dağıtımı b Sonunda akıllı sözleşmemizi uygulamaya hazırız! Proje dizininizin kök dizinine geri dönün ve komut satırında şunu çalıştırın: + ``` npx hardhat --network sepolia run scripts/deploy.js + ``` Daha sonra şöyle bir şey görmelisiniz: - Contract deployed to address: 0x4C5266cCc4b3F426965d2f51b6D910325a0E7650 + ``` + Sözleşme şu adrese dağıtıldı: 0x4C5266cCc4b3F426965d2f51b6D910325a0E7650 + ``` -[Sepolia etherscan](https://sepolia.etherscan.io/)'e gidip sözleşme adresimizi aratığımızda, başarıyla dağıtıldığını görebiliriz. Bu işlem biraz zaman alabileceğinden dolayı hemen göremezseniz lütfen biraz bekleyin. İşlem şunun gibi gözükecektir: +[Sepolia etherscan](https://sepolia.etherscan.io/) adresine gidip sözleşme adresimizi aratırsak, başarıyla dağıtıldığını görebilmeliyiz. Bu işlem biraz zaman alabileceğinden dolayı hemen göremezseniz lütfen biraz bekleyin. İşlem şunun gibi gözükecektir: ![İşlem adresinizi Etherscan'de görüntüleyin](./etherscan-sepoila-contract-creation.png) -Gönderici adresi, MetaMask hesap adresinizle eşleşmelidir ve Alıcı adresinde "Sözleşme Oluşturma" yazacaktır. İşleme tıklarsak, Alıcı alanında sözleşme adresimizi görürüz: +`From` adresi MetaMask hesap adresinizle eşleşmeli ve `To` adresinde “Sözleşme Oluşturma” yazmalıdır. İşleme tıklarsak, Alıcı alanında sözleşme adresimizi görürüz: -![Etherscan'da sözleşme adresinizi görüntüleyin](./etherscan-sepolia-tx-details.png) +![Sözleşme adresinizi Etherscan'de görüntüleyin](./etherscan-sepolia-tx-details.png) Evet! NFT akıllı sözleşmenizi Ethereum (test ağı) zincirinde 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 "MyNFT"yi seçtiğinizden emin olun. +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 filtreleme yaptığınızdan ve "MyNFT"yi seçtiğinizden emin olun. -![Alchemy'nin Gezgin Gösterge Paneli ile "perde arkasında" yapılan çağrıları görüntüleyin](./alchemy-explorer-goerli.png) +![Alchemy'nin Explorer Panosu ile “perde arkasında” yapılan çağrıları görüntüleyin](./alchemy-explorer-goerli.png) -Burada, .deploy() fonksiyonunu çağırdığımızda Hardhat/Ethers'in bizim için arka planda yaptığı birkaç JSON-RPC çağrısı göreceksiniz. Burada belirtilmesi gereken iki önemli şey, akıllı sözleşmemizi Ropsten zincirine yazma isteği olan [eth_sendRawTransaction](/developers/docs/apis/json-rpc/#eth_sendrawtransaction) ve hash 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](/developers/docs/apis/json-rpc/#eth_gettransactionbyhash) öğeleridir. İş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. +Burada, .deploy() fonksiyonunu çağırdığımızda Hardhat/Ethers'in bizim için arka planda yaptığı birkaç JSON-RPC çağrısı göreceksiniz. Burada değinilmesi gereken iki önemli olanı şunlardır: akıllı sözleşmemizi Sepolia zincirine yazma isteği olan [eth_sendRawTransaction](/developers/docs/apis/json-rpc/#eth_sendrawtransaction) ve karma değeri verildiğinde işlemimiz hakkındaki bilgileri okuma isteği olan [eth_getTransactionByHash](/developers/docs/apis/json-rpc/#eth_gettransactionbyhash) (işlem gönderirken tipik bir model). İş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. -Bu öğreticinin 1. Bölümü bu kadardı. [2. Bölümde, bir NFT'yi basarak](/developers/tutorials/how-to-mint-an-nft/) akıllı sözleşmemizle gerçekten etkileşime geçeceğiz ve [3. Bölümde, Ethereum cüzdanınızda NFT'nizi nasıl görüntüleyeceğinizi göstereceğiz](/developers/tutorials/how-to-view-nft-in-metamask/)! +Bu öğreticinin 1. Bölümü bu kadardı. [2. Bölüm'de, bir NFT basarak akıllı sözleşmemizle gerçekten etkileşime gireceğiz](/developers/tutorials/how-to-mint-an-nft/) ve [3. Bölüm'de, NFT'nizi Ethereum cüzdanınızda nasıl görüntüleyeceğinizi göstereceğiz](/developers/tutorials/how-to-view-nft-in-metamask/)! diff --git a/public/content/translations/tr/developers/tutorials/interact-with-other-contracts-from-solidity/index.md b/public/content/translations/tr/developers/tutorials/interact-with-other-contracts-from-solidity/index.md index 0c77ebf3848..abc770cc097 100644 --- a/public/content/translations/tr/developers/tutorials/interact-with-other-contracts-from-solidity/index.md +++ b/public/content/translations/tr/developers/tutorials/interact-with-other-contracts-from-solidity/index.md @@ -1,13 +1,15 @@ --- -title: Solidity'nin diğer sözleşmeleriyle etkileşime geçin -description: Mevcut bir sözleşmeden akıllı bir sözleşme nasıl kurulur ve onunla nasıl etkileşim kurulur +title: "Solidity'den diğer sözleşmelerle etkileşime geçme" +description: "Mevcut bir sözleşmeden akıllı sözleşme dağıtma ve onunla etkileşim kurma" author: "jdourlens" tags: - - "akıllı sözleşmeler" - - "solidity" - - "remix" - - "dağıtma" - - "birleştirilebilirlik" + [ + "akıllı kontratlar", + "katılık", + "remix", + "dağıtma", + "birleştirilebilirlik" + ] skill: advanced lang: tr published: 2020-04-05 @@ -16,9 +18,9 @@ sourceUrl: https://ethereumdev.io/interact-with-other-contracts-from-solidity/ address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" --- -Önceki öğreticilerde [ilk akıllı sözleşmenizi nasıl dağıtacağınızla](/developers/tutorials/deploying-your-first-smart-contract/) ve ona nasıl [niteleyicilerle erişim kontrolü](https://ethereumdev.io/organize-your-code-and-control-access-to-your-smart-contract-with-modifiers/) veya [Solidity'de hata işleme](https://ethereumdev.io/handle-errors-in-solidity-with-require-and-revert/) gibi bazı özellikler ekleyeceğinizle ilgili çok şey öğrendik. Bu öğreticide, mevcut bir sözleşmeden akıllı bir sözleşmenin nasıl dağıtılacağını ve onunla nasıl etkileşime geçileceğini öğreneceğiz. +Önceki öğreticilerde [ilk akıllı sözleşmenizi nasıl dağıtacağınız](/developers/tutorials/deploying-your-first-smart-contract/) gibi pek çok şey öğrendik ve ona [değiştiricilerle erişimi kontrol etme](https://ethereumdev.io/organize-your-code-and-control-access-to-your-smart-contract-with-modifiers/) veya [Solidity'de hata yönetimi](https://ethereumdev.io/handle-errors-in-solidity-with-require-and-revert/) gibi bazı özellikler ekledik. Bu öğreticide mevcut bir sözleşmeden bir akıllı sözleşme dağıtmayı ve onunla etkileşim kurmayı öğreneceğiz. -Bunun için bir fabrika oluşturarak herkesin kendi `Counter` (Sayaç) akıllı sözleşmesine sahip olmasını sağlayan bir sözleşme yapacağız, adı `CounterFactory` (Sayaç Fabrikası) olacak. İlk olarak, ilk `Counter` akıllı sözleşmemizin kodu: +Bunun için bir fabrika oluşturarak herkesin kendi `Counter` akıllı sözleşmesine sahip olmasını sağlayan bir sözleşme yapacağız, adı `CounterFactory` olacak. İlk olarak, ilk `Counter` akıllı sözleşmemizin kodu: ```solidity pragma solidity 0.5.17; @@ -31,12 +33,12 @@ contract Counter { modifier onlyOwner(address caller) { - require(caller == _owner, "You're not the owner of the contract"); + require(caller == _owner, "Sözleşmenin sahibi siz değilsiniz"); _; } modifier onlyFactory() { - require(msg.sender == _factory, "You need to use the factory"); + require(msg.sender == _factory, "Fabrikayı kullanmanız gerekir"); _; } @@ -56,19 +58,19 @@ contract Counter { } ``` -Fabrikanın adresini ve sözleşme sahibinin adresini takip etmek için sözleşme kodunu biraz değiştirdiğimizi unutmayın. Başka bir sözleşmeden bir sözleşme kodunu aradığınızda, msg.sender sözleşmeli fabrikamızın adresine başvuracaktır. Diğer sözleşmelerle etkileşim kurmak için bir sözleşme kullanmak yaygın bir uygulama olduğundan, bu **anlaşılması gerçekten önemli bir noktadır**. Bu nedenle, karmaşık durumlarda gönderenin kim olduğuna dikkat etmelisiniz. +Fabrikanın adresini ve sözleşme sahibinin adresini takip etmek için sözleşme kodunu biraz değiştirdiğimizi unutmayın. Başka bir sözleşmeden bir sözleşme kodu çağırdığınızda, `msg.sender` sözleşme fabrikamızın adresini gösterecektir. Diğer sözleşmelerle etkileşim kurmak için bir sözleşme kullanmak yaygın bir uygulama olduğundan, bu **anlaşılması gerçekten önemli bir noktadır**. Bu nedenle, karmaşık durumlarda göndericinin kim olduğuna dikkat etmelisiniz. -Bunun için ayrıca, durum değiştirme işlevinin yalnızca orijinal çağrı yapan parametre olarak geçirecek olan fabrika tarafından çağrılabilmesini sağlayan bir `onlyFactory` niteleyicisi ekledik. +Bunun için, durum değiştiren fonksiyonun yalnızca orijinal çağırıcıyı parametre olarak geçiren fabrika tarafından çağrılabilmesini sağlayan bir `onlyFactory` değiştiricisi de ekledik. -Diğer tüm Counter'ları yönetecek olan yeni `CounterFactory`'nin içine, bir sahibi karşı sözleşmenin adresiyle ilişkilendirecek bir eşleştirme ekleyeceğiz: +Diğer tüm Sayaçları yönetecek olan yeni `CounterFactory`'mizin içine, bir sahibini kendi sayaç sözleşmesinin adresiyle ilişkilendirecek bir eşleme ekleyeceğiz: ```solidity mapping(address => Counter) _counters; ``` -Ethereum'da eşleştirme, javascript'teki nesnelerin eş değeridir, A tipi bir anahtarı B tipi bir değere eşlemeyi sağlar. Bu durumda, bir sahibinin adresini Counter'ın örneğiyle eşleştiririz. +Ethereum'da, eşlemeler javascript'teki nesnelerin eşdeğeridir; A türünde bir anahtarı B türünde bir değere eşlemeyi sağlarlar. Bu durumda, bir sahibinin adresini onun Counter örneği ile eşleriz. -Birisi için yeni bir Counter başlatmak şöyle görünür: +Birisi için yeni bir Counter örneği oluşturmak şöyle görünür: ```solidity function createCounter() public { @@ -77,9 +79,9 @@ Birisi için yeni bir Counter başlatmak şöyle görünür: } ``` -Önce kişinin zaten bir counter'ı olup olmadığını kontrol ediyoruz. Eğer bir counter'ı yoksa, adresini `Counter` yapıcısına ileterek yeni bir counter başlatırız ve yeni oluşturulan örneği eşleştirmeye atarız. +Önce kişinin zaten bir `Counter`'ı olup olmadığını kontrol ederiz. Eğer bir `Counter`'ı yoksa, adresini `Counter` yapıcısına geçirerek yeni bir `Counter` örneği oluştururuz ve yeni oluşturulan örneği eşlemeye atarız. -Belirli bir Counter'ın sayısını almak için şöyle görünür: +Belirli bir `Counter`'ın sayımını almak şöyle görünür: ```solidity function getCount(address account) public view returns (uint256) { @@ -92,7 +94,7 @@ function getMyCount() public view returns (uint256) { } ``` -İlk işlev, belirli bir adres için Counter sözleşmesinin var olup olmadığını kontrol eder ve ardından örnekten `getCount` yöntemini çağırır. İkinci fonksiyon: `getMyCount` sadece `getCount` fonksiyonuna doğrudan msg.sender geçirmek için bir kısayoldur. +İlk fonksiyon, belirtilen adres için `Counter` sözleşmesinin mevcut olup olmadığını kontrol eder ve ardından örnekten `getCount` metodunu çağırır. İkinci fonksiyon olan `getMyCount`, `msg.sender`'ı doğrudan `getCount` fonksiyonuna geçirmek için kullanılan bir kısayoldur. `increment` fonksiyonu oldukça benzerdir ancak orijinal işlem göndericisini `Counter` sözleşmesine iletir: @@ -103,11 +105,11 @@ function increment() public { } ``` -Birçok kez aranırsa, counter'ımızın muhtemelen bir taşma kurbanı olabileceğini unutmayın. Bu olası durumdan korunmak için mümkün olduğunca [SafeMath kütüphanesini](https://ethereumdev.io/using-safe-math-library-to-prevent-from-overflows/) kullanmalısınız. +Çok fazla kez çağrılırsa, `counter`'ımızın bir taşma hatasına maruz kalabileceğini unutmayın. Bu olası duruma karşı korunmak için [SafeMath kütüphanesini](https://ethereumdev.io/using-safe-math-library-to-prevent-from-overflows/) mümkün olduğunca kullanmalısınız. -Sözleşmemizi dağıtmak için hem `CounterFactory` kodunu hem de `Counter` kodunu sağlamanız gerekir. Örneğin Remix'te dağıtırken CounterFactory'yi seçmeniz gerekir. +Sözleşmemizi dağıtmak için hem `CounterFactory` hem de `Counter` kodunu sağlamanız gerekecektir. Örneğin Remix'te dağıtım yaparken `CounterFactory`'yi seçmeniz gerekecektir. -Tam kod burada: +İşte kodun tamamı: ```solidity pragma solidity 0.5.17; @@ -120,12 +122,12 @@ contract Counter { modifier onlyOwner(address caller) { - require(caller == _owner, "You're not the owner of the contract"); + require(caller == _owner, "Sözleşmenin sahibi siz değilsiniz"); _; } modifier onlyFactory() { - require(msg.sender == _factory, "You need to use the factory"); + require(msg.sender == _factory, "Fabrikayı kullanmanız gerekir"); _; } @@ -170,8 +172,8 @@ contract CounterFactory { } ``` -Derlemeden sonra, Remix dağıtımı bölümünde dağıtılacak fabrikayı seçeceksiniz: +Derleme işleminden sonra, Remix dağıtım bölümünde dağıtılacak fabrikayı seçeceksiniz: -![Remix'te dağıtılacak fabrikanın seçilmesi](./counterfactory-deploy.png) +![Remix'te dağıtılacak fabrikayı seçme](./counterfactory-deploy.png) -Ardından sözleşmeli fabrikanızla oynayabilir ve değerin değiştiğini kontrol edebilirsiniz. Akıllı sözleşmeyi farklı bir adresten aramak isterseniz, Remix'in Hesap seçiminde adresi değiştirmeniz gerekir. +Ardından sözleşme fabrikanızla denemeler yapabilir ve değerin değiştiğini kontrol edebilirsiniz. Akıllı sözleşmeyi farklı bir adresten çağırmak isterseniz Remix'in `Hesap` seçimi bölümündeki adresi değiştirmeniz gerekir. diff --git a/public/content/translations/tr/developers/tutorials/ipfs-decentralized-ui/index.md b/public/content/translations/tr/developers/tutorials/ipfs-decentralized-ui/index.md new file mode 100644 index 00000000000..f9d5776cb3b --- /dev/null +++ b/public/content/translations/tr/developers/tutorials/ipfs-decentralized-ui/index.md @@ -0,0 +1,73 @@ +--- +title: "Merkeziyetsiz kullanıcı arayüzleri için IPFS" +description: "Bu öğretici, okuyucuya bir merkeziyetsiz uygulama için kullanıcı arayüzünü saklamak üzere IPFS'in nasıl kullanılacağını öğretir. Uygulamanın verileri ve iş mantığı merkeziyetsiz olsa da sansüre dayanıklı bir kullanıcı arayüzü olmadan kullanıcılar yine de ona erişimini kaybedebilir." +author: Ori Pomerantz +tags: [ "ipfs" ] +skill: beginner +lang: tr +published: 2024-06-29 +--- + +İnanılmaz yeni bir merkeziyetsiz uygulama yazdınız. Hatta onun için bir [kullanıcı arayüzü](/developers/tutorials/creating-a-wagmi-ui-for-your-contract/) bile yazdınız. Ama şimdi birisinin, bulutta bulunan tek bir sunucu olan kullanıcı arayüzünüzü çökertmek suretiyle onu sansürlemeye çalışacağından korkuyorsunuz. Bu öğreticide, kullanıcı arayüzünüzü **[gezegenler arası dosya sistemine (IPFS)](https://ipfs.tech/developers/)** koyarak sansürden nasıl kaçınacağınızı öğreneceksiniz, böylece ilgilenen herkes gelecekteki erişim için onu bir sunucuya sabitleyebilecek. + +Tüm işi yapmak için [Fleek](https://resources.fleek.xyz/docs/) gibi üçüncü taraf bir hizmeti kullanabilirsiniz. Bu öğretici, daha fazla iş olsa bile ne yaptıklarını anlayacak kadarını yapmak isteyen kişiler içindir. + +## Yerel olarak başlarken {#getting-started-locally} + +Birden fazla [üçüncü taraf IPFS sağlayıcısı](https://docs.ipfs.tech/how-to/work-with-pinning-services/#use-a-third-party-pinning-service) vardır, ancak test için IPFS'i yerel olarak çalıştırarak başlamak en iyisidir. + +1. [IPFS kullanıcı arayüzünü](https://docs.ipfs.tech/install/ipfs-desktop/#install-instructions) kurun. + +2. Web sitenizle bir dizin oluşturun. [Vite](https://vite.dev/) kullanıyorsanız bu komutu kullanın: + + ```sh + pnpm vite build + ``` + +3. IPFS Desktop'ta, **İçe Aktar > Klasör**'e tıklayın ve önceki adımda oluşturduğunuz dizini seçin. + +4. Az önce yüklediğiniz klasörü seçin ve **Yeniden Adlandır**'a tıklayın. Ona daha anlamlı bir isim verin. + +5. Tekrar seçin ve **Bağlantıyı paylaş**'a tıklayın. URL'yi panoya kopyalayın. Bağlantı, `https://ipfs.io/ipfs/QmaCuQ7yN6iyBjLmLGe8YiFuCwnePoKfVu6ue8vLBsLJQJ` gibi olacaktır. + +6. **Durum**'a tıklayın. Ağ geçidi adresini görmek için **Gelişmiş** sekmesini genişletin. Örneğin, benim sistemimde adres `http://127.0.0.1:8080` şeklindedir. + +7. Adresinizi bulmak için bağlantı adımındaki yolu ağ geçidi adresiyle birleştirin. Örneğin, yukarıdaki örnek için URL `http://127.0.0.1:8080/ipfs/QmaCuQ7yN6iyBjLmLGe8YiFuCwnePoKfVu6ue8vLBsLJQJ` şeklindedir. Sitenizi görmek için bu URL'yi bir tarayıcıda açın. + +## Yükleme {#uploading} + +Artık dosyaları yerel olarak sunmak için IPFS kullanabilirsiniz ki bu pek heyecan verici değil. Sonraki adım, çevrimdışıyken onları dünyaya sunmaktır. + +Çok sayıda iyi bilinen [sabitleme hizmetleri](https://docs.ipfs.tech/concepts/persistence/#pinning-services) vardır. Onlardan birini seçin. Hangi hizmeti kullanırsanız kullanın, bir hesap oluşturmanız ve IPFS masaüstünüzdeki **içerik tanımlayıcısını (CID)** ona sağlamanız gerekir. + +Şahsen, [4EVERLAND](https://docs.4everland.org/storage/4ever-pin/guides) uygulamasını kullanımının en kolay olduğunu gördüm. Bunun için talimatlar şunlardır: + +1. [Kontrol paneline](https://dashboard.4everland.org/overview) gidin ve cüzdanınızla giriş yapın. + +2. Sol kenar çubuğunda **Depolama > 4EVER Pin**'e tıklayın. + +3. **Yükle > Seçilen CID**'ye tıklayın. İçeriğinize bir ad verin ve IPFS masaüstünden CID'yi sağlayın. Şu anda bir CID, `QmaCuQ7yN6iyBjLmLGe8YiFuCwnePoKfVu6ue8vLBsLJQJ` gibi [base-58 kodlu](https://medium.com/bootdotdev/base64-vs-base58-encoding-c25553ff4524) bir karmayı temsil eden, `Qm` ile başlayıp 44 harf ve rakamla devam eden bir dizedir, ancak [bunun değişmesi muhtemeldir](https://docs.ipfs.tech/concepts/content-addressing/#version-1-v1). + +4. İlk durum **Sırada**'dır. **Sabitlendi** olarak değişene kadar yeniden yükleyin. + +5. Bağlantıyı almak için CID'nize tıklayın. Uygulamamı [burada](https://bafybeifqka2odrne5b6l5guthqvbxu4pujko2i6rx2zslvr3qxs6u5o7im.ipfs.dweb.link/) görebilirsiniz. + +6. Bir aydan uzun bir süre boyunca sabitlenmesi için hesabınızı etkinleştirmeniz gerekebilir. Hesap etkinleştirme maliyeti yaklaşık 1 dolardır. Kapattıysanız, tekrar etkinleştirme istenmesi için çıkış yapın ve tekrar giriş yapın. + +## IPFS'den kullanma {#using-from-ipfs} + +Bu noktada, IPFS içeriğinizi sunan merkezi bir ağ geçidine bir bağlantınız var. Kısacası, kullanıcı arayüzünüz biraz daha güvenli olabilir ancak hâlâ sansüre dayanıklı değil. Gerçek sansür direnci için, kullanıcıların IPFS'i [doğrudan bir tarayıcıdan](https://docs.ipfs.tech/install/ipfs-companion/#prerequisites) kullanmaları gerekir. + +Bunu kurduktan sonra (ve masaüstü IPFS çalışırken), herhangi bir sitede [/ipfs/``](https://any.site/ipfs/bafybeifqka2odrne5b6l5guthqvbxu4pujko2i6rx2zslvr3qxs6u5o7im) adresine gidebilirsiniz ve bu içeriği merkeziyetsiz bir şekilde sunulmuş olarak alırsınız. + +## Dezavantajlar {#drawbacks} + +IPFS dosyalarını güvenilir bir şekilde silemezsiniz, bu nedenle kullanıcı arayüzünüzü değiştirdiğiniz sürece, onu ya merkezi bırakmak ya da IPFS'nin üzerinde değişkenlik sağlayan bir sistem olan [gezegenler arası isim sistemini (IPNS)](https://docs.ipfs.tech/concepts/ipns/#mutability-in-ipfs) kullanmak muhtemelen en iyisidir. Elbette, değişken olan her şey, IPNS durumunda karşılık geldiği özel anahtara sahip kişiye baskı yaparak sansürlenebilir. + +Ek olarak, bazı paketlerin IPFS ile sorunu vardır, bu nedenle web siteniz çok karmaşıksa bu iyi bir çözüm olmayabilir. Ve tabii ki, sunucu entegrasyonuna dayanan herhangi bir şey, sadece istemci tarafını IPFS üzerinde bulundurarak merkeziyetsiz hale getirilemez. + +## Sonuç {#conclusion} + +Ethereum'un, merkeziyetsiz uygulamanızın veritabanı ve iş mantığı yönlerini merkeziyetsizleştirmenize olanak tanıdığı gibi, IPFS de kullanıcı arayüzünü merkeziyetsizleştirmenize olanak tanır. Bu, merkeziyetsiz uygulamanıza karşı bir saldırı vektörünü daha kapatmanıza olanak tanır. + +[Çalışmalarımdan daha fazlası için buraya bakın](https://cryptodocguy.pro/). diff --git a/public/content/translations/tr/developers/tutorials/kickstart-your-dapp-frontend-development-with-create-eth-app/index.md b/public/content/translations/tr/developers/tutorials/kickstart-your-dapp-frontend-development-with-create-eth-app/index.md index 11e12a931a9..93283f85848 100644 --- a/public/content/translations/tr/developers/tutorials/kickstart-your-dapp-frontend-development-with-create-eth-app/index.md +++ b/public/content/translations/tr/developers/tutorials/kickstart-your-dapp-frontend-development-with-create-eth-app/index.md @@ -1,26 +1,27 @@ --- -title: create-eth-app ile dapp ön uç geliştirmenizi başlatın -description: Create-eth-app ve özelliklerinin nasıl kullanılacağına genel bakış +title: "create-eth-app ile dapp ön uç geliştirmenizi başlatın" +description: "Create-eth-app ve özelliklerinin nasıl kullanılacağına genel bakış" author: "Markus Waas" tags: - - "create-eth-app" - - "ön uç" - - "javascript" - - "ethers.js" - - "the graph" - - "defi" -skill: advanced + [ + "ön uç", + "javascript", + "ethers.js", + "the graph", + "defi" + ] +skill: beginner lang: tr published: 2020-04-27 source: soliditydeveloper.com sourceUrl: https://soliditydeveloper.com/create-eth-app --- -Geçen sefer [Solidity'nin büyük resmine baktık ve](https://soliditydeveloper.com/solidity-overview-2020) hâlihazırda [create-eth-app](https://github.com/PaulRBerg/create-eth-app)'den bahsettik. Şimdi onu nasıl kullanacağınızı, hangi özelliklerin entegre olduğunu ve nasıl genişleteceğinize dair ek fikirleri öğreneceksiniz. [Sablier](http://sablier.com/)'in kurucusu Paul Razvan Berg tarafından başlatılan bu uygulama, ön uç geliştirmenizi başlatacak ve beraberinde aralarından seçim yapabileceğiniz çeşitli isteğe bağlı entegrasyonlar getiriyor. +Geçen sefer [Solidity'nin genel resmine](https://soliditydeveloper.com/solidity-overview-2020) göz atmış ve [create-eth-app]'ten (https://github.com/PaulRBerg/create-eth-app) zaten bahsetmiştik. Şimdi onu nasıl kullanacağınızı, hangi özelliklerin entegre olduğunu ve nasıl genişleteceğinize dair ek fikirleri öğreneceksiniz. [Sablier](http://sablier.com/)'in kurucusu Paul Razvan Berg tarafından başlatılan bu uygulama, ön uç geliştirmenizi başlatacak ve aralarından seçim yapabileceğiniz çeşitli isteğe bağlı entegrasyonlarla birlikte gelir. ## Kurulum {#installation} -Kurulum için Yarn 0.25 veya üstü gerekir (`npm install thread --global`). Şunları çalıştırmak kadar kolaydır: +Kurulum için Yarn 0.25 veya üzeri gereklidir (`npm install yarn --global`). Şunları çalıştırmak kadar basittir: ```bash yarn create eth-app my-eth-app @@ -28,44 +29,44 @@ cd my-eth-app yarn react-app:start ``` -Perde arkasında [create-react-app](https://github.com/facebook/create-react-app) kullanır. Uygulamanızı görmek için, `http://localhost:3000/` bağlantısını açın. Üretime dağıtmaya hazır olduğunuzda, yarn build ile küçültülmüş bir paket oluşturun. Bunu sunmanın kolay yollarından biri [Netlify](https://www.netlify.com/)'dır. Bir Github deposu oluşturmanız, Netlify'a eklemeniz ve build komutunu kurmanız yeterli olur! Uygulamanız barındırılacak ve herkes tarafından kullanılabilir olacak. Ve hepsi ücretsiz. +Arka planda [create-react-app](https://github.com/facebook/create-react-app) kullanır. Uygulamanızı görmek için `http://localhost:3000/` adresini açın. Üretime dağıtmaya hazır olduğunuzda, `yarn build` ile küçültülmüş bir paket oluşturun. Bunu barındırmanın kolay bir yolu [Netlify](https://www.netlify.com/)'dır. Bir GitHub deposu oluşturabilir, onu Netlify'a ekleyebilir, derleme komutunu ayarlayabilir ve işlem tamamdır! Uygulamanız barındırılacak ve herkes tarafından kullanılabilir olacak. Ve hepsi ücretsiz. ## Özellikler {#features} ### React ve create-react-app {#react--create-react-app} -Öncelikle uygulamanın kalbi: React ve _create-react-app_ ile gelen tüm ek özellikler. Sadece bunu kullanmak, Ethereum'u entegre etmek istemiyorsanız harika bir seçenektir. [React](https://reactjs.org/) kendi başına interaktif UI'lar yapmayı gerçekten kolaylaştırır. [Vue](https://vuejs.org/) kadar yeni başlayanlar için uygun olmayabilir, ancak yine de çoğunlukla kullanılmaktadır, daha fazla özelliğe sahiptir ve en önemlisi aralarından seçim yapabileceğiniz binlerce ek kütüphane vardır. _create-react-app_, onunla başlamayı gerçekten kolaylaştırır ve şunları içerir: +Öncelikle uygulamanın kalbi: React ve _create-react-app_ ile gelen tüm ek özellikler. Sadece bunu kullanmak, Ethereum'u entegre etmek istemiyorsanız harika bir seçenektir. [React](https://react.dev/) kendi başına etkileşimli kullanıcı arayüzleri oluşturmayı gerçekten kolaylaştırır. [Vue](https://vuejs.org/) kadar başlangıç seviyesine uygun olmayabilir, ancak yine de çoğunlukla kullanılır, daha fazla özelliğe sahiptir ve en önemlisi aralarından seçim yapabileceğiniz binlerce ek kütüphanesi vardır. _create-react-app_ ile başlamak da gerçekten çok kolaydır ve şunları içerir: - React, JSX, ES6, TypeScript, Flow söz dizimi desteği. - Nesne yayma operatörü gibi ES6'nın ötesinde dil ekstraları. -- Autoprefixer CSS, yani -webkit- veya diğer ön eklere ihtiyacınız yok. +- Otomatik olarak ön eklenen CSS, bu nedenle `-webkit-` veya diğer ön eklere ihtiyacınız olmaz. - Kapsam raporlaması için yerleşik desteğe sahip hızlı etkileşimli birim test çalıştırıcısı. - Yaygın hatalar hakkında uyaran canlı bir geliştirme sunucusu. - Hash değerleri ve kaynak haritaları içeren, üretim için JS, CSS ve görüntüleri bir araya getirmeye yarayan bir derleme komut dosyası. -Özellikle _create-eth-app_, yeni [kanca efektlerini](https://reactjs.org/docs/hooks-effect.html) kullanır. Güçlü, ancak çok küçük sözde fonksiyonel bileşenler yazmak için bir yöntem. _create-eth-app_'de nasıl kullanıldığını öğrenmek için aşağıdaki Apollo hakkındaki bölüme bakın. +Özellikle _create-eth-app_ yeni [hook etkilerinden](https://legacy.reactjs.org/docs/hooks-effect.html) yararlanır. Güçlü, ancak çok küçük sözde fonksiyonel bileşenler yazmak için bir yöntem. _create-eth-app_ içinde nasıl kullanıldıklarını görmek için Apollo ile ilgili aşağıdaki bölüme bakın. ### Yarn Workspaces {#yarn-workspaces} -[Yarn Workspaces](https://classic.yarnpkg.com/en/docs/workspaces/), birden çok pakete sahip olmanızın yanı sıra kök klasörden hepsini aynı anda `yarn install` kullanarak yönetmenize izin verir. Bu, özellikle her ikisi de `create-eth-app`'in bir parçası olan akıllı sözleşme adresleri/ABI yönetimi (hangi akıllı sözleşmeleri nereye yerleştirdiğiniz ve bunlarla nasıl iletişim kuracağınızla ilgili bilgiler) veya grafik entegrasyonu gibi daha küçük ek paketler için mantıklıdır. +[Yarn Workspaces](https://classic.yarnpkg.com/en/docs/workspaces/) birden fazla pakete sahip olmanıza olanak tanır, ancak hepsini kök klasörden yönetebilir ve `yarn install` kullanarak tüm bağımlılıkları tek seferde kurabilirsiniz. Bu, özellikle `create-eth-app`'in bir parçası olan, akıllı sözleşme adresleri/ABI yönetimi (hangi akıllı sözleşmeleri nereye dağıttığınız ve onlarla nasıl iletişim kuracağınız hakkındaki bilgiler) veya grafik entegrasyonu gibi daha küçük ek paketler için mantıklıdır. ### ethers.js {#ethersjs} -Hâlâ çoğunlukla [Web3](https://docs.web3js.org/) kullanılıyor olsa da, [ethers.js](https://docs.ethers.io/) son bir yıl içinde bir alternatif olarak büyük ivme kazanmış ve _create-eth-app_ içine entegre edilmiştir. Bununla çalışabilir, onu Web3 olarak değiştirebilir veya neredeyse beta sürümünden çıkmış olan [ethers.js v5](https://docs.ethers.org/v5/)'e yükseltmeyi düşünebilirsiniz. +[Web3](https://docs.web3js.org/) hala çoğunlukla kullanılıyor olsa da, [ethers.js](https://docs.ethers.io/) son bir yılda bir alternatif olarak çok daha fazla ilgi gördü ve _create-eth-app_'e entegre edilen kütüphanedir. Bununla çalışabilir, Web3'e geçebilir veya neredeyse beta sürümünden çıkmış olan [ethers.js v5](https://docs.ethers.org/v5/)'e yükseltmeyi düşünebilirsiniz. ### The Graph {#the-graph} -[GraphQL](https://graphql.org/), [Restful API](https://restfulapi.net/)'ye kıyasla verileri işlemenin alternatif bir yoludur. Özellikle merkeziyetsiz blok zinciri verileri için Restful Api'lere göre çeşitli avantajları vardır. Eğer bunun ardındaki sebepler konusunda meraklıysanız, [GraphQL Merkeziyetsiz Ağı Güçlendirecek](https://medium.com/graphprotocol/graphql-will-power-the-decentralized-web-d7443a69c69a)'e bir göz atın. +[GraphQL](https://graphql.org/), bir [Restful API](https://restfulapi.net/) ile karşılaştırıldığında verileri işlemek için alternatif bir yoldur. Özellikle merkeziyetsiz blokzincir verileri için Restful API'lere göre çeşitli avantajları vardır. Bunun arkasındaki mantığı merak ediyorsanız, [GraphQL Will Power the Decentralized Web](https://medium.com/graphprotocol/graphql-will-power-the-decentralized-web-d7443a69c69a) makalesine göz atın. -Genellikle akıllı sözleşmenizden doğrudan veri alırsınız. En son işlemin gerçekleştiği zamanı okumak mı istiyorsunuz? Sadece Ethereum düğümünden merkeziyetsiz uygulamanıza veriyi getiren `MyContract.methods.latestTradeTime().call()`'u çağırın. Peki ya yüzlerce farklı veri noktasına ihtiyacınız varsa? Bu, düğüme yüzlerce veri alınmasına yol açar ve bu alımların her biri bir [RTT](https://wikipedia.org/wiki/Round-trip_delay_time) gerektirerek merkeziyetsiz uygulamanızı yavaş ve verimsiz hâle getirir. Bir geçici çözüm, sözleşmenizin içinde aynı anda birden çok veri döndüren bir alıcı çağrı işlevi olabilir. Ancak bu her zaman ideal değildir. +Genellikle akıllı sözleşmenizden doğrudan veri alırsınız. En son işlemin gerçekleştiği zamanı okumak mı istiyorsunuz? Bir Ethereum düğümünden merkeziyetsiz uygulamanıza veri çeken `MyContract.methods.latestTradeTime().call()` fonksiyonunu çağırmanız yeterlidir. Peki ya yüzlerce farklı veri noktasına ihtiyacınız varsa? Bu durum, düğüme yüzlerce veri getirilmesine neden olur ve her seferinde bir [RTT](https://wikipedia.org/wiki/Round-trip_delay_time) gerektirerek merkeziyetsiz uygulamanızı yavaş ve verimsiz hale getirir. Bir geçici çözüm, sözleşmenizin içinde aynı anda birden çok veri döndüren bir alıcı çağrı işlevi olabilir. Ancak bu her zaman ideal değildir. -Tarihsel verilerle de ilgileniyor olabilirsiniz. Yalnızca son işlem zamanını değil, kendi yaptığınız tüm işlemlerin zamanlarını da bilmek istiyorsunuz. _create-eth-app_ alt grafik paketini kullanın, [belgeleri](https://thegraph.com/docs/en/subgraphs/developing/creating/starting-your-subgraph) okuyun ve kendi sözleşmelerinize uyarlayın. Popüler akıllı sözleşmeler arıyorsanız, zaten bir alt grafik bile olabilir. [Alt grafik gezgini](https://thegraph.com/explorer/)'ne bir göz atın. +Tarihsel verilerle de ilgileniyor olabilirsiniz. Yalnızca son işlem zamanını değil, kendi yaptığınız tüm işlemlerin zamanlarını da bilmek istiyorsunuz. _create-eth-app_ subgraph paketini kullanın, [dokümanları](https://thegraph.com/docs/en/subgraphs/developing/creating/starting-your-subgraph) okuyun ve kendi sözleşmelerinize uyarlayın. Popüler akıllı sözleşmeler arıyorsanız, zaten bir alt grafik bile olabilir. [Subgraph explorer](https://thegraph.com/explorer/)'a göz atın. -Bir alt grafiğiniz olduğunda, ihtiyacınız olan geçmiş veriler de dahil olmak üzere tüm önemli blok zinciri verilerini alan merkeziyetsiz uygulamanıza basit bir sorgu yazmanıza olanak tanır, yalnızca tek bir getirme gerekir. +Bir alt grafiğiniz olduğunda, bu, ihtiyacınız olan geçmiş veriler de dahil olmak üzere tüm önemli blokzincir verilerini alan merkeziyetsiz uygulamanıza basit bir sorgu yazmanıza olanak tanır; bunun için yalnızca tek bir getirme işlemi gerekir. ### Apollo {#apollo} -[Apollo Boost](https://www.apollographql.com/docs/react/get-started/) entegrasyonu sayesinde grafiği React merkeziyetsiz uygulamanıza kolayca entegre edebilirsiniz. Özellikle [React hooks ve Apollo](https://www.apollographql.com/blog/apollo-client-now-with-react-hooks) kullanılırken, verileri almak, bileşeninize tek bir GraphQl sorgusu yazmak kadar basittir: +[Apollo Boost](https://www.apollographql.com/docs/react/get-started/) entegrasyonu sayesinde grafiği React merkeziyetsiz uygulamanıza kolayca entegre edebilirsiniz. Özellikle [React hook'larını ve Apollo'yu](https://www.apollographql.com/blog/apollo-client-now-with-react-hooks) kullanırken, veri getirmek bileşeninize tek bir GraphQL sorgusu yazmak kadar basittir: ```js const { loading, error, data } = useQuery(myGraphQlQuery) @@ -79,32 +80,32 @@ React.useEffect(() => { ## Şablonlar {#templates} -Üstte birkaç farklı şablon arasından seçim yapabilirsiniz. Bir Aave, Compound, UniSwap veya sablier entegrasyonu kullanabilirsiniz. Hepsi, önceden yapılmış alt grafik entegrasyonlarının yanı sıra önemli hizmet akıllı sözleşme adresleri ekler. Şablonu, oluşturma komutuna `yarn create eth-app my-eth-app --with-template aave` şeklinde eklemeniz yeterlidir. +Ayrıca birkaç farklı şablon arasından seçim yapabilirsiniz. Şu ana kadar bir Aave, Compound, Uniswap veya Sablier entegrasyonu kullanabilirsiniz. Hepsi, önceden yapılmış alt grafik entegrasyonlarının yanı sıra önemli hizmet akıllı sözleşme adresleri ekler. Şablonu oluşturma komutuna `yarn create eth-app my-eth-app --with-template aave` gibi eklemeniz yeterlidir. ### Aave {#aave} -[Aave](https://aave.com/) merkeziyetsiz bir borç verme piyasasıdır. Mevduat sahipleri pasif bir gelir elde etmek için piyasaya likidite sağlarken, borçlular teminat kullanarak borç alabilirler. Aave'nin benzersiz bir özelliği, krediyi tek işlemde iade ettiğiniz sürece herhangi bir teminat olmadan borç para almanıza olanak tanıyan [hızlı kredilerdir](https://docs.aave.com/developers/guides/flash-loans). Bu, örneğin arbitraj ticaretinde size ekstra nakit vermek için faydalı olabilir. +[Aave](https://aave.com/) merkeziyetsiz bir para borç verme piyasasıdır. Mevduat sahipleri pasif bir gelir elde etmek için piyasaya likidite sağlarken, borçlular teminat kullanarak borç alabilirler. Aave'nin benzersiz özelliklerinden biri, krediyi tek bir işlem içinde iade ettiğiniz sürece, herhangi bir teminat olmadan borç para almanıza olanak tanıyan [hızlı kredilerdir](https://aave.com/docs/developers/flash-loans). Bu, örneğin arbitraj ticaretinde size ekstra nakit vermek için faydalı olabilir. -Size faiz kazandıran takas edilmiş token'lara _aTokens_ denir. +Size faiz kazandıran işlem görmüş token'lara _aTokens_ denir. -Aave'yi _create-eth-app_ ile entegre etmek istediğinizde, bir [alt grafik entegrasyonu](https://docs.aave.com/developers/getting-started/using-graphql) alacaksınız. Aave, The Graph'i kullanır ve size [Ropsten](https://thegraph.com/explorer/subgraph/aave/protocol-ropsten) ve [Mainnet'te](https://thegraph.com/explorer/subgraph/aave/protocol) [saf](https://thegraph.com/explorer/subgraph/aave/protocol-raw) veya [formatlanmış](https://thegraph.com/explorer/subgraph/aave/protocol) olarak birkaç kullanıma hazır alt grafik sağlar. +_create-eth-app_ ile Aave'yi entegre etmeyi seçtiğinizde, bir [subgraph entegrasyonu](https://docs.aave.com/developers/getting-started/using-graphql) elde edersiniz. Aave, The Graph'i kullanır ve size [Ropsten](https://thegraph.com/explorer/subgraph/aave/protocol-ropsten) ve [Ana Ağ](https://thegraph.com/explorer/subgraph/aave/protocol) üzerinde [ham](https://thegraph.com/explorer/subgraph/aave/protocol-raw) veya [biçimlendirilmiş](https://thegraph.com/explorer/subgraph/aave/protocol) biçimde kullanıma hazır birkaç alt grafik sunar. -![Aave Hızlı Kredi meme'i - "Şey, hızlı kredimi 1 işlemden daha uzun süre tutabilseydim, bu müthiş olurdu"](./flashloan-meme.png) +![Aave Hızlı Kredi mem'i – "Evet, hızlı kredimi 1 işlemden daha uzun süre tutabilseydim, harika olurdu"](./flashloan-meme.png) ### Compound {#compound} -[Compound](https://compound.finance/), Aave'ye benzer. Bu entegrasyon hâlihazırda yeni [Compound v2 Alt Grafiğini](https://medium.com/graphprotocol/https-medium-com-graphprotocol-compound-v2-subgraph-highlight-a5f38f094195) kapsar. Burada faiz kazandıran token'lara şaşırtıcı bir şekilde _cTokens_ denir. +[Compound](https://compound.finance/), Aave'ye benzer. Entegrasyon, yeni [Compound v2 Subgraph](https://medium.com/graphprotocol/https-medium-com-graphprotocol-compound-v2-subgraph-highlight-a5f38f094195)'ı zaten içeriyor. Burada faiz kazandıran token'lara şaşırtıcı bir şekilde _cTokens_ denir. ### Uniswap {#uniswap} -[Uniswap](https://uniswap.exchange/), merkeziyetsiz bir borsadır (DEX). Likidite sağlayıcıları, bir ticaretin her iki tarafı için gerekli token'ları veya ether'ı sağlayarak ücret kazanabilir. Yaygın olarak kullanılır ve bu nedenle çok çeşitli token'lar için en yüksek likiditelerden birine sahiptir. Örneğin, kullanıcıların ETH'lerini DAI ile takas etmelerine olanak tanımak için merkeziyetsiz uygulamanıza kolayca entegre edebilirsiniz. +[Uniswap](https://uniswap.exchange/) merkeziyetsiz bir borsadır (DEX). Likidite sağlayıcıları, bir işlemin her iki tarafı için gerekli token'ları veya ether'i sağlayarak ücret kazanabilir. Yaygın olarak kullanılır ve bu nedenle çok çeşitli token'lar için en yüksek likiditelerden birine sahiptir. Örneğin, kullanıcıların ETH'lerini DAI ile takas etmelerine olanak tanımak için merkeziyetsiz uygulamanıza kolayca entegre edebilirsiniz. -Ne yazık ki, bu yazının yazıldığı sırada entegrasyon yalnızca Uniswap v1 içindir ve [yeni yayınlanan v2](https://uniswap.org/blog/uniswap-v2/) için değildir. +Ne yazık ki, bu yazı yazıldığı sırada entegrasyon yalnızca Uniswap v1 içindir, [yeni çıkan v2](https://uniswap.org/blog/uniswap-v2/) için değildir. ### Sablier {#sablier} -[Sablier](https://sablier.com/), kullanıcıların para ödemesi akışlarını yürütmesine olanak tanır. Tek bir ödeme günü yerine, ilk kurulumdan sonra başka bir yönetim olmaksızın paranızı sürekli olarak alırsınız. Bu entegrasyon [kendi alt grafiğini](https://thegraph.com/explorer/subgraph/sablierhq/sablier) içerir. +[Sablier](https://sablier.com/) kullanıcılara sürekli para ödemesi yapma olanağı tanır. Tek bir ödeme günü yerine, ilk kurulumdan sonra başka bir işleme gerek kalmadan paranızı sürekli olarak alırsınız. Entegrasyon, [kendi alt grafiğini](https://thegraph.com/explorer/subgraph/sablierhq/sablier) içerir. ## Sırada ne var? {#whats-next} -_create-eth-app_ hakkında sorularınız varsa, _create-eth-app_'in yazarlarıyla iletişim kurabileceğiniz [Sablier topluluk sunucusuna](https://discord.gg/bsS8T47) gidebilirsiniz. Bir sonraki adım olarak [Material UI](https://material-ui.com/) gibi bir UI çerçevesini entegre edebilir, ihtiyacınız olan veriler için GraphQL sorguları yazabilir ve dağıtımı kurabilirsiniz. +_create-eth-app_ hakkında sorularınız varsa, _create-eth-app_ yazarlarıyla iletişime geçebileceğiniz [Sablier topluluk sunucusuna](https://discord.gg/bsS8T47) gidin. Bir sonraki adım olarak [Material UI](https://mui.com/material-ui/) gibi bir kullanıcı arayüzü (UI) çerçevesi entegre edebilir, gerçekten ihtiyacınız olan veriler için GraphQL sorguları yazabilir ve dağıtımı kurabilirsiniz. diff --git a/public/content/translations/tr/developers/tutorials/learn-foundational-ethereum-topics-with-sql/index.md b/public/content/translations/tr/developers/tutorials/learn-foundational-ethereum-topics-with-sql/index.md index cf065f7196a..07151d690d1 100644 --- a/public/content/translations/tr/developers/tutorials/learn-foundational-ethereum-topics-with-sql/index.md +++ b/public/content/translations/tr/developers/tutorials/learn-foundational-ethereum-topics-with-sql/index.md @@ -1,11 +1,8 @@ --- -title: SQL ile Temel Ethereum Konularını Öğrenin -description: Bu öğretici, okuyucuların Yapılandırılmış Sorgu Dili (SQL) ile zincir verilerini sorgulayarak işlemler, bloklar ve gaz dahil olmak üzere temel Ethereum kavramlarını anlamalarına yardımcı olur. +title: "SQL ile Temel Ethereum Konularını Öğrenin" +description: "Bu öğretici, okuyucuların Yapılandırılmış Sorgu Dili (SQL) ile zincir üstü verileri sorgulayarak işlemler, bloklar ve gaz dahil olmak üzere temel Ethereum kavramlarını anlamalarına yardımcı olur." author: "Paul Apivat" -tags: - - "SQL" - - "Sorgulama" - - "İşlemler" +tags: [ "SQL", "Sorgulama", "İşlemler" ] skill: beginner lang: tr published: 2021-05-11 @@ -13,27 +10,27 @@ source: paulapivat.com sourceUrl: https://paulapivat.com/post/query_ethereum/ --- -Birçok Ethereum öğreticisi geliştiricileri hedefler, ancak veri analisti veya bir istemci veya düğüm çalıştırmadan zincir üstü verileri görmek isteyen kişiler için eğitim kaynağı eksikliği vardır. +Birçok Ethereum öğreticisi geliştiricileri hedeflese de veri analistleri ya da bir istemci veya düğüm çalıştırmadan zincir üstü verileri görmek isteyen kişiler için yeterli eğitim kaynağı bulunmamaktadır. -Bu öğretici, [Dune Analytics](https://dune.xyz/home) tarafından sağlanan bir arayüz aracılığıyla yapılandırılmış sorgu dili (SQL) ile okuyucuların zincir verilerini sorgulayarak işlemler, bloklar ve gaz dahil olmak üzere temel Ethereum kavramlarını anlamalarına yardımcı olur. +Bu öğretici, okuyucuların [Dune Analytics](https://dune.com/) tarafından sağlanan bir arayüz aracılığıyla yapılandırılmış sorgu dili (SQL) ile zincir üstü verileri sorgulayarak işlemler, bloklar ve gaz dahil olmak üzere temel Ethereum kavramlarını anlamalarına yardımcı olur. -Zincir üstü veriler, Ethereum'u bir ağ ve bir bilgi işlem gücü ekonomisi olarak anlamamıza yardımcı olabilir ve bugün Ethereum'un karşılaştığı zorlukları (yani artan gaz fiyatları) ve daha da önemlisi ölçeklendirme çözümleri hakkındaki tartışmaları anlamak için bir temel görevi görebilir. +Zincir üstü veriler, Ethereum'u, ağı ve bir bilgi işlem gücü ekonomisi olarak anlamamıza yardımcı olabilir ve günümüzde Ethereum'un karşılaştığı zorlukları (yani artan gaz fiyatları) ve daha da önemlisi, ölçeklendirme çözümleri etrafındaki tartışmaları anlamak için bir temel oluşturmalıdır. ### İşlemler {#transactions} -Bir kullanıcının Ethereum'daki yolculuğu, kullanıcı tarafından kontrol edilen bir hesabı veya ETH bakiyesi olan bir varlığı başlatmakla başlar. İki hesap türü vardır: Kullanıcı kontrollü hesap veya bir akıllı sözleşme (bkz. [ethereum.org](/developers/docs/accounts/)). +Bir kullanıcının Ethereum'daki yolculuğu, kullanıcı kontrollü bir hesabı veya bir ETH bakiyesine sahip bir varlığı başlatmakla başlar. İki hesap türü vardır: kullanıcı kontrollü veya akıllı sözleşme (bkz. [ethereum.org](/developers/docs/accounts/)). -Herhangi bir hesap, [Etherscan](https://etherscan.io/) gibi bir blok arayıcısında görüntülenebilir. Blok arayıcıları Ethereum'un verisine açılan bir geçittir. Bloklar, işlemler, madenciler, hesaplar ve diğer zincir içi faaliyetlerle ilgili verileri gerçek zamanlı olarak görüntülerler ([buraya](/developers/docs/data-and-analytics/block-explorers/) göz atın). +[Etherscan](https://etherscan.io/) veya [Blockscout](https://eth.blockscout.com/) gibi bir blok arayıcısında herhangi bir hesap görüntülenebilir. Blok arayıcıları, Ethereum'un verilerine açılan bir portaldır. Bloklar, işlemler, madenciler, hesaplar ve diğer zincir üstü etkinliklerle ilgili verileri gerçek zamanlı olarak görüntülerler (bkz. [burası](/developers/docs/data-and-analytics/block-explorers/)). -Bununla birlikte, bir kullanıcı, harici blok arayıcıları tarafından sağlanan bilgileri karşılaştırmak için verileri doğrudan sorgulamak isteyebilir. [Dune Analytics](https://duneanalytics.com/) SQL bilgisi olan herhangi birine bu kabiliyeti sağlar. +Ancak, bir kullanıcı harici blok arayıcıları tarafından sağlanan bilgileri karşılaştırmak için verileri doğrudan sorgulamak isteyebilir. [Dune Analytics](https://dune.com/), SQL hakkında biraz bilgisi olan herkese bu olanağı sağlar. -Referans olarak, Ethereum Vakfı (EF) için akıllı sözleşme hesabı [Etherscan](https://etherscan.io/address/0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae) adresinde görüntülenebilir. +Referans olarak, Ethereum Foundation'ın (EF) akıllı sözleşme hesabı [Blockscout](https://eth.blockscout.com/address/0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe) üzerinde görüntülenebilir. -Unutulmaması gereken bir nokta, Ethereum Vakfı'nınki de dahil olmak üzere tüm hesapların işlem göndermek ve almak için kullanılabilecek bir genel adrese sahip olmasıdır. +Unutulmaması gereken bir nokta, EF'ninki de dahil olmak üzere tüm hesapların, işlem göndermek ve almak için kullanılabilecek bir genel adrese sahip olmasıdır. -Etherscan'daki hesap bakiyesi, düzenli işlemler ve dahili işlemlerden oluşur. Adına rağmen dahili işlemler, zincirin durumunu değiştiren _gerçek_ işlemler değildir. Onlar bir sözleşmenin yürütümünden oluşturulan değer transferleridir ([kaynak](https://ethereum.stackexchange.com/questions/3417/how-to-get-contract-internal-transactions)). Dahili işlemlerin imzası olmadığı için blok zincirine **dahil edilmezler** ve Dune Analytics ile sorgulanamazlar. +Etherscan'deki hesap bakiyesi, normal işlemlerden ve dahili işlemlerden oluşur. Dahili işlemler, adlarına rağmen, zincirin durumunu değiştiren _gerçek_ işlemler değildir. Bunlar, bir sözleşmenin yürütülmesiyle başlatılan değer transferleridir ([kaynak](https://ethereum.stackexchange.com/questions/3417/how-to-get-contract-internal-transactions)). Dahili işlemlerin imzası olmadığından, blokzincirine **dahil edilmezler** ve Dune Analytics ile sorgulanamazlar. -Bu nedenle, bu öğreticide düzenli işlemlere odaklanılacaktır. Bu, şu şekilde sorgulanabilir: +Bu nedenle, bu öğretici normal işlemlere odaklanacaktır. Bu, şu şekilde sorgulanabilir: ```sql WITH temp_table AS ( @@ -61,33 +58,33 @@ SELECT FROM temp_table ``` -Bu, Etherscan'in işlem sayfasında sağlanan bilgilerin aynısını verecektir. Karşılaştırma olarak, burada iki kaynak vardır: +Bu, Etherscan'in işlem sayfasında sağlanan bilgilerin aynısını verecektir. Karşılaştırma için iki kaynak şunlardır: #### Etherscan {#etherscan} ![](./etherscan_view.png) -[Etherscan üzerinde Ethereum Vakfı'nın sözleşme sayfası.](https://etherscan.io/address/0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe) +[EF'nin Blockscout'taki sözleşme sayfası.](https://eth.blockscout.com/address/0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe) #### Dune Analytics {#dune-analytics} ![](./dune_view.png) -Gösterge panelini [burada](https://duneanalytics.com/paulapivat/Learn-Ethereum) bulabilirsiniz. Sorguyu görmek için tabloya tıklayın (yukarıya da bakın). +Panoyu [burada](https://dune.com/paulapivat/Learn-Ethereum) bulabilirsiniz. Sorguyu görmek için tabloya tıklayın (ayrıca yukarıya bakın). -### İşlemleri Parçalara Ayırma {#breaking_down_transactions} +### İşlemleri Ayrıntılandırma {#breaking_down_transactions} -Gönderilen bir işlem, şunlar da dahil olmak üzere çeşitli bilgiler içerir ([kaynak](/developers/docs/transactions/)): +Gönderilen bir işlem, aşağıdakiler de dahil olmak üzere çeşitli bilgiler içerir ([kaynak](/developers/docs/transactions/)): -- **Recipient**: Alıcı adres ("to" olarak sorgulanır) -- **Signature**: Göndericinin özel anahtarları bir işlemi imzalarken, SQL ile sorgulayabileceğimiz şey gönderenin açık adresidir ("from"). -- **Value**: Aktarılan ETH miktarı (`ether` sütununa bakınız). -- **Data**: Bu hash edilmiş olan rastgele veridir (`data` sütununa bakınız) -- **gasLimit** – işlem tarafından tüketilebilecek maksimum gaz birimi miktarı. Gaz birimleri, bilgi işlem adımlarını temsil eder +- **Alıcı**: Alıcı adres ("to" olarak sorgulanır) +- **İmza**: Bir göndericinin özel anahtarı bir işlemi imzalasa da, SQL ile sorgulayabileceğimiz şey göndericinin genel adresidir ("from"). +- **Değer**: Bu, transfer edilen ETH miktarıdır (`ether` sütununa bakın). +- **Veri**: Bu, hash'lenmiş rastgele veridir (`data` sütununa bakın) +- **gasLimit** – işlem tarafından tüketilebilecek maksimum gaz birimi miktarı. Gaz birimleri, hesaplama adımlarını temsil eder - **maxPriorityFeePerGas** - madenciye bahşiş olarak dahil edilecek maksimum gaz miktarı -- **maxFeePerGas** - işlem için ödemeye razı olunan maksimum gaz miktarı (baseFeePerGas ve maxPriorityFeePerGas dahil) +- **maxFeePerGas** - işlem için ödenmeye razı olunan maksimum gaz miktarı (baseFeePerGas ve maxPriorityFeePerGas dahil) -Ethereum Vakfı genel adresine yapılan işlemler için bu belirli bilgileri sorgulayabiliriz: +Ethereum Foundation genel adresine yapılan işlemler için bu özel bilgileri sorgulayabiliriz: ```sql SELECT @@ -106,15 +103,15 @@ ORDER BY block_time DESC ### Bloklar {#blocks} -Her işlem Ethereum sanal makinesinin ([EVM](/developers/docs/evm/)) durumunu değiştirir ([kaynak](/developers/docs/transactions/)). İşlemler doğrulanmak üzere ağa yayınlanır ve bir bloğa dahil edilir. Her işlem bir blok numarası ile ilişkilendirilir. Verileri görmek için belirli bir blok numarasını sorgulayabiliriz: 12396854 (bu yazı itibariyle Ethereum Vakfı işlemleri arasında en son blok, 11/5/21). +Her işlem, Ethereum Sanal Makinesi'nin ([EVM](/developers/docs/evm/)) durumunu değiştirir ([kaynak](/developers/docs/transactions/)). İşlemler doğrulanmak üzere ağa yayınlanır ve bir bloğa dahil edilir. Her işlem bir blok numarası ile ilişkilidir. Verileri görmek için belirli bir blok numarasını sorgulayabiliriz: 12396854 (bu yazının yazıldığı 11/5/21 tarihi itibarıyla Ethereum Foundation işlemleri arasındaki en son blok). -Ayrıca, sonraki iki bloğu sorguladığımızda, her bloğun bir önceki bloğun hash değerini (yani üst hash) içerdiğini görebiliriz, bu da blok zincirinin nasıl oluştuğunu gösterir. +Ayrıca, sonraki iki bloğu sorguladığımızda, her bloğun önceki bloğun hash'ini (yani üst hash) içerdiğini görebiliriz, bu da blok zincirinin nasıl oluştuğunu gösterir. -Her blok, üst bloğa bir referans içerir. Bu, aşağıda `hash` ve `parent_hash` sütunlarının arasında gösterilmektedir ([kaynak](/developers/docs/blocks/)): +Her blok, üst bloğuna bir referans içerir. Bu, aşağıda `hash` ve `parent_hash` sütunları arasında gösterilmektedir ([kaynak](/developers/docs/blocks/)): ![parent_hash](./parent_hash.png) -Dune Analytics üzerinde [sorgu](https://duneanalytics.com/queries/44856/88292): +İşte Dune Analytics'teki [sorgu](https://dune.com/queries/44856/88292): ```sql SELECT @@ -128,18 +125,18 @@ WHERE "number" = 12396854 OR "number" = 12396855 OR "number" = 12396856 LIMIT 10 ``` -Bir bloğu zaman, blok numarası, zorluk, hash değeri, üst hash değeri ve nonce değeri sorgulayarak inceleyebiliriz. +Bir bloğu; zaman, blok numarası, zorluk, hash değeri, üst hash değeri ve nonce değeri sorgulayarak inceleyebiliriz. -Bu sorgunun kapsamadığı tek şey, aşağıda ayrı bir sorgu gerektiren _işlem listesi_ ve _kök durumdur_. Tam veya arşivsel bir düğüm, tüm işlemleri ve durum geçişlerini depolayarak, istemcilerin herhangi bir zamanda zincirin durumunu sorgulamasına olanak tanır. Bu, büyük depolama alanı gerektirdiğinden zincir verilerini durum verilerinden ayırabiliriz: +Bu sorgunun kapsamadığı tek şey, aşağıda ayrı bir sorgu gerektiren _işlem listesi_ ve _durum köküdür_. Tam veya arşiv düğümü, tüm işlemleri ve durum geçişlerini depolayarak istemcilerin herhangi bir zamanda zincirin durumunu sorgulamasına olanak tanır. Bu, büyük depolama alanı gerektirdiğinden, zincir verilerini durum verilerinden ayırabiliriz: - Zincir verisi (blokların, işlemlerin listesi) - Durum verileri (her işlemin durum geçişinin sonucu) -Durum kökü ikinci kategoridedir ve _örtülü_ verilerdir (zincirde depolanmaz), zincir verileri ise açık ve zincirin kendisinde depolanır ([kaynak](https://ethereum.stackexchange.com/questions/359/where-is-the-state-data-stored)). +Durum kökü ikinci kategoriye girer ve _örtük_ veridir (zincir üstünde saklanmaz), zincir verileri ise açıktır ve zincirin kendisinde saklanır ([kaynak](https://ethereum.stackexchange.com/questions/359/where-is-the-state-data-stored)). -Bu eğitimde, Dune Analytics aracılığıyla SQL ile _sorgulanabilecek_ zincir üstü verilere odaklanacağız. +Bu öğreticide, Dune Analytics aracılığıyla SQL ile sorgulan_abilen_ zincir üstü verilere odaklanacağız. -Yukarıda belirtildiği gibi, her blok bir işlem listesi içerir, bunu belirli bir blok için filtreleyerek sorgulayabiliriz. En güncel olan 12396854 bloğunu deneyeceğiz: +Yukarıda belirtildiği gibi, her blok bir işlem listesi içerir; bunu belirli bir bloğa göre filtreleyerek sorgulayabiliriz. En son bloğu deneyeceğiz: 12396854 ```sql SELECT * FROM ethereum."transactions" @@ -147,13 +144,13 @@ WHERE block_number = 12396854 ORDER BY block_time DESC` ``` -Dune üzerindeki SQL çıktısı: +İşte Dune'daki SQL çıktısı: ![](./list_of_txn.png) -Zincire eklenen bu tek blok, Ethereum sanal makinesinin durumunu değiştirir ([EVM](/developers/docs/evm/)). Bazen düzinelerce ve hatta yüzlerce işlem aynı anda doğrulanır. Bu özel durumda, 222 işlem dahil edilmiştir. +Zincire eklenen bu tek blok, Ethereum Sanal Makinesi'nin ([EVM](/developers/docs/evm/)) durumunu değiştirir. Bazen onlarca, bazen de yüzlerce işlem aynı anda doğrulanır. Bu özel durumda 222 işlem dahil edildi. -Kaç tanesinin gerçekten başarılı olduğunu görmek amacıyla başarılı işlemleri saymak için başka bir filtre ekleriz: +Gerçekte kaç tanesinin başarılı olduğunu görmek için, başarılı işlemleri saymak üzere başka bir filtre ekleriz: ```sql WITH temp_table AS ( @@ -166,26 +163,26 @@ SELECT FROM temp_table ``` -12396854 bloğu için toplam 222 işlemden 204'ü başarıyla doğrulandı: +12396854 numaralı blok için, toplam 222 işlemden 204'ü başarıyla doğrulandı: ![](./successful_txn.png) İşlem istekleri saniyede onlarca kez gerçekleşir, ancak bloklar yaklaşık olarak her 15 saniyede bir işlenir ([kaynak](/developers/docs/blocks/)). -Yaklaşık olarak her 15 saniyede bir blok üretildiğini görmek için bir gündeki saniye sayısını (86400) 15'e bölerek tahmini günlük ortalama blok sayısını (yaklaşık 5760) elde edebiliriz. +Yaklaşık her 15 saniyede bir blok üretildiğini görmek için, bir gündeki saniye sayısını (86400) 15'e bölerek tahmini günlük ortalama blok sayısını (~ 5760) elde edebiliriz. -Günde üretilen Ethereum blokları tablosu (2016 - günümüz): +Günlük üretilen Ethereum blokları için grafik (2016 - günümüz) şöyledir: ![](./daily_blocks.png) -Bu süre zarfında günlük olarak üretilen ortalama blok sayısı yaklaşık olarak 5.874'tür: +Bu zaman diliminde günlük üretilen ortalama blok sayısı ~5.874'tür: ![](./avg_daily_blocks.png) -Sorgular: +Sorgular şunlardır: ```sql -# query to visualize number of blocks produced daily since 2016 +# 2016'dan bu yana günlük üretilen blok sayısını görselleştirmek için sorgu SELECT DATE_TRUNC('day', time) AS dt, @@ -194,7 +191,7 @@ FROM ethereum."blocks" GROUP BY dt OFFSET 1 -# average number of blocks produced per day +# günlük üretilen ortalama blok sayısı WITH temp_table AS ( SELECT @@ -209,13 +206,13 @@ SELECT FROM temp_table ``` -2016'dan bu yana günlük üretilen ortalama blok sayısı, 5.874 olarak bu sayının biraz üzerindedir. Alternatif olarak, 86.400 saniyenin 5874 ortalama bloğa bölünmesi 14,7 saniyeye veya her 15 saniyede bir yaklaşık bir bloğa denk gelir. +2016'dan bu yana günde üretilen ortalama blok sayısı, 5.874 ile bu sayının biraz üzerindedir. Alternatif olarak, 86400 saniyeyi 5874 ortalama bloğa bölmek 14,7 saniye veya yaklaşık olarak her 15 saniyede bir blok anlamına gelir. ### Gaz {#gas} -Bloklar boyut olarak sınırlıdır. Maksimum blok boyutu dinamiktir ve ağ talebine göre 12.500.000 ila 25.000.000 birim arasında değişir. Limitler, keyfi olarak çok büyük blok boyutlarınının disk alanı ve hız gereksinimleri ([kaynak](/developers/docs/blocks/)) açısından tam düğümlere baskı uygulamasını engellemek için gereklidir. +Blokların boyutu sınırlıdır. Maksimum blok boyutu dinamiktir ve ağ talebine göre 12.500.000 ila 25.000.000 birim arasında değişir. Keyfi olarak büyük blok boyutlarının disk alanı ve hız gereksinimleri açısından tam düğümlere yük bindirmesini önlemek için sınırlar gereklidir ([kaynak](/developers/docs/blocks/)). -Blok gaz sınırını kavramsallaştırmanın bir yolu, bunu toplu işlemlerin gerçekleştirileceği kullanılabilir blok alanının **arz** olarak düşünmektir. Blok gaz limiti 2016'dan günümüze sorgulanabilir ve görselleştirilebilir: +Blok gaz limitini kavramsallaştırmanın bir yolu, onu işlemleri gruplamak için mevcut blok alanının **arzı** olarak düşünmektir. Blok gaz limiti 2016'dan günümüze sorgulanabilir ve görselleştirilebilir: ![](./avg_gas_limit.png) @@ -228,7 +225,7 @@ GROUP BY dt OFFSET 1 ``` -Ardından, Ethereum zincirinde yapılan hesaplama için günlük olarak kullanılan gerçek gaz vardır (yani: işlem gönderme, akıllı sözleşme çağırma, NFT basma). Bu, kullanılabilir Ethereum blok alanı için **taleptir**: +Ardından, Ethereum zincirinde yapılan hesaplama için günlük olarak kullanılan gerçek gaz vardır (yani, işlem gönderme, bir akıllı sözleşme çağırma, bir NFT basma). Bu, mevcut Ethereum blok alanı için olan **taleptir**: ![](./daily_gas_used.png) @@ -241,17 +238,17 @@ GROUP BY dt OFFSET 1 ``` -Ayrıca, **talep ve arzın** nasıl sıralandığını görmek için bu iki grafiği yan yana koyabiliriz: +**Talep ve arzın** nasıl hizalandığını görmek için bu iki grafiği yan yana da koyabiliriz: ![gas_demand_supply](./gas_demand_supply.png) -Böylece, mevcut arz göz önüne alındığında, gaz fiyatlarını Ethereum blok alanı talebinin bir fonksiyonu olarak anlayabiliriz. +Bu nedenle, mevcut arz göz önüne alındığında, gaz fiyatlarını Ethereum blok alanı talebinin bir fonksiyonu olarak anlayabiliriz. -Son olarak, Ethereum zinciri için ortalama günlük gaz fiyatlarını sorgulamak isteyebiliriz, ancak bunu yapmak özellikle uzun bir sorgulama süresine neden olur. Bu nedenle sorgumuzu Ethereum Vakfı tarafından işlem başına ödenen ortalama gaz miktarına göre filtreleyeceğiz. +Son olarak, Ethereum zinciri için ortalama günlük gaz fiyatlarını sorgulamak isteyebiliriz ancak bu, özellikle uzun bir sorgu süresine neden olacaktır, bu yüzden sorgumuzu Ethereum Foundation tarafından işlem başına ödenen ortalama gaz miktarına göre filtreleyeceğiz. ![](./ef_daily_gas.png) -Yıllar içinde tüm işlemler için Ethereum Foundation adresine ödenmiş gaz ücretlerini görebiliriz. Sorgu burada: +Yıllar boyunca Ethereum Foundation adresine yapılan tüm işlemler için ödenen gaz fiyatlarını görebiliriz. Sorgu şu şekildedir: ```sql SELECT @@ -265,8 +262,8 @@ ORDER BY block_time DESC ### Özet {#summary} -Bu öğretici ile, temel Ethereum kavramlarını ve zincir üzerindeki verileri sorgulayarak ve bunlarla uğraşarak Ethereum blok zincirinin nasıl çalıştığını anlıyoruz. +Bu öğretici ile, temel Ethereum kavramlarını ve zincir üstü verileri sorgulayarak ve kavrayarak Ethereum blokzincirinin nasıl çalıştığını anlıyoruz. -Bu öğreticide kullanılan tüm kodları tutan gösterge paneli [burada](https://duneanalytics.com/paulapivat/Learn-Ethereum) bulunabilir. +Bu öğreticide kullanılan tüm kodları içeren pano [burada](https://dune.com/paulapivat/Learn-Ethereum) bulunabilir. -Verinin web3 keşfi amaçlı daha fazla kullanımı için [bana Twitter'dan ulaşın](https://twitter.com/paulapivat). +Web3'ü keşfetmek için verilerin daha fazla kullanımı hakkında bilgi için [beni Twitter'da bulun](https://twitter.com/paulapivat). diff --git a/public/content/translations/tr/developers/tutorials/logging-events-smart-contracts/index.md b/public/content/translations/tr/developers/tutorials/logging-events-smart-contracts/index.md index ad841eb1911..301e9080f80 100644 --- a/public/content/translations/tr/developers/tutorials/logging-events-smart-contracts/index.md +++ b/public/content/translations/tr/developers/tutorials/logging-events-smart-contracts/index.md @@ -1,12 +1,8 @@ --- -title: Olaylar ile akıllı sözleşmelerden veri toplama -description: Akıllı sözleşmelerde olayların ne olduğu ve veri toplamak için nasıl kullanıldığını öğrenin +title: "Olaylar ile akıllı sözleşmelerden veri kaydetme" +description: "Akıllı sözleşme olaylarına giriş ve bunları veri kaydetmek için nasıl kullanabileceğiniz" author: "jdourlens" -tags: - - "akıllı sözleşmeler" - - "remix" - - "solidity" - - "olaylar" +tags: ["smart contracts", "remix", "solidity", "events"] skill: intermediate lang: tr published: 2020-04-03 @@ -15,19 +11,19 @@ sourceUrl: https://ethereumdev.io/logging-data-with-events/ address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" --- -Solidity'de [olaylar](/developers/docs/smart-contracts/anatomy/#events-and-logs), akıllı sözleşmenin gönderebileceği kaydedilmiş sinyallerdir. Merkeziyetsiz uygulamalar ya da Ethereum JSON-RPC API'sine bağlı herhangi bir şey, bu olayları dinleyip gerektiği şekilde hareket edebilir. Her bir olay endekslenir böylece olay tarihi sonrasında tekrar aranabilir olur. +Solidity'de [olaylar](/developers/docs/smart-contracts/anatomy/#events-and-logs), akıllı sözleşmelerin tetikleyebileceği yayılan sinyallerdir. Merkeziyetsiz uygulamalar ya da Ethereum JSON-RPC API'sine bağlı herhangi bir şey, bu olayları dinleyip gerektiği şekilde hareket edebilir. Bir olay, olay geçmişinin daha sonra aranabilmesi için dizine de eklenebilir. ## Olaylar {#events} -Bu makalenin yazıldığı sırada Ethereum blok zincirindeki en yaygın olay, biri token'ları transfer ettiğinde ERC20 token'ları tarafından yayılan Transfer olayıdır. +Bu makalenin yazıldığı sırada Ethereum blokzincirindeki en yaygın olay, birisi jetonları transfer ettiğinde ERC20 jetonları tarafından yayılan Transfer olayıdır. ```solidity event Transfer(address indexed from, address indexed to, uint256 value); ``` -Olay imzası sözleşme kodu içerisinde tanımlanmıştır ve yayın anahtarıyla yayınlanabilir. Örneğin Transfer olayı, transferi kimin (_from_) gerçekleştirdiğini, kime yönelik (_to_) gerçekleştirdiğini ve ne kadar token (_value_) transfer edildiğini kayıt altına alır. +Olay imzası, sözleşme kodunun içinde bildirilir ve `emit` anahtar kelimesi ile yayılabilir. Örneğin, Transfer olayı; transferi kimin gönderdiğini (_from_), kime gönderildiğini (_to_) ve ne kadar jeton transfer edildiğini (_value_) kaydeder. -Counter (Sayaç) akıllı sözleşmemize geri dönersek ve değer her değiştiğinde oturum açmaya karar verirsek. Bu sözleşmenin dağıtılması değil, kendisini genişleterek başka bir sözleşme oluşturmak için bir temel görevi görmesi hedeflendiğinden buna soyut sözleşme denir. Sayaç örneğimizde şöyle görünür: +Eğer Counter akıllı sözleşmemize geri döner ve değer her değiştiğinde kaydetmeye karar verirsek. Bu sözleşmenin dağıtılması değil, onu genişleterek başka bir sözleşme oluşturmak için bir temel görevi görmesi amaçlandığından, buna soyut sözleşme denir. Counter örneğimizde şöyle görünür: ```solidity pragma solidity 0.5.17; @@ -36,16 +32,16 @@ contract Counter { event ValueChanged(uint oldValue, uint256 newValue); - // Private 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 özel değişken uint256 private count = 0; - // Function that increments our counter + // Sayacımızı artıran işlev function increment() public { count += 1; emit ValueChanged(count - 1, count); } - // Getter to get the count value + // Sayım değerini almak için alıcı işlevi function getCount() public view returns (uint256) { return count; } @@ -53,14 +49,14 @@ contract Counter { } ``` -Şu satırlara dikkat: +Şunlara dikkat edin: -- **Satır 5**: Olayımızı ve içeriğini, eski değeri ve yeni değeri beyan ederiz. +- **5. Satır**: Olayımızı ve içerdiklerini, yani eski değeri ve yeni değeri, bildiririz. -- **Satır 13**: Değişkenimiz count değeri değiştiğinde olayımızı yayınlıyoruz. +- **13. Satır**: `count` değişkenimizi artırdığımızda, olayı yayarız. -Şimdi sözleşmemizi tekrar yayınlar ve increment fonksiyonunu çağırırsak Remix'in kayıtlarında logs dizisi içinde olayımızın gerçekleştiğini görebiliriz. +Şimdi sözleşmeyi dağıtır ve `increment` işlevini çağırırsak, `logs` adlı dizinin içindeki yeni işleme tıkladığınızda Remix'in bunu otomatik olarak görüntülediğini göreceğiz. ![Remix ekran görüntüsü](./remix-screenshot.png) -Kayıtlar, sözleşmelerdeki hataları ayıklamak için çok kullanışlıdır ve aynı zamanda sözleşmenizi kullanacak olan kişilerin nasıl kullandıklarını gözlemleyebilmenizi sağlar. İşlemler tarafından oluşturulan kayıtlar popüler blok arayıcılarında gösterilir ve ayrıca bu kayıtları, örneğin belirli olayları dinlemek ve bu olaylar gerçekleştiğinde harekete geçmek amacıyla zincir dışı komut dosyaları yaratmak için kullanabilirsiniz. +Kayıtlar, akıllı sözleşmelerinizdeki hataları ayıklamak için çok kullanışlıdır. Ayrıca, farklı kişilerin kullandığı uygulamalar geliştiriyorsanız da önemlidirler; akıllı sözleşmenizin nasıl kullanıldığını izlemek ve anlamak üzere analizler yapmayı kolaylaştırırlar. İşlemler tarafından oluşturulan kayıtlar popüler blok arayıcılarında görüntülenir ve ayrıca bunları, örneğin belirli olayları dinlemek ve bu olaylar meydana geldiğinde eyleme geçmek için zincir dışı betikler oluşturmak amacıyla da kullanabilirsiniz. diff --git a/public/content/translations/tr/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md b/public/content/translations/tr/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md index 1e281b1c0df..1ccd8fd1b9c 100644 --- a/public/content/translations/tr/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md +++ b/public/content/translations/tr/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md @@ -1,9 +1,8 @@ --- -title: Çevrimdışı veri bütünlüğü için Merkle ispatları -description: Genellikle zincir dışında saklanan verilerin zincir üstündeki veri bütünlüğünü sağlamak +title: "Çevrimdışı veri bütünlüğü için Merkle ispatları" +description: "Çoğunlukla zincir dışında depolanan veriler için zincir üstünde veri bütünlüğünün sağlanması" author: Ori Pomerantz -tags: - - "depolama" +tags: [ "depolama" ] skill: advanced lang: tr published: 2021-12-30 @@ -13,29 +12,31 @@ published: 2021-12-30 İdeal olarak tüm verileri binlerce bilgisayarda depolanan ve son derece yüksek kullanılabilirlik (veri sansürlenemez) ve bütünlüğe (veri yetkisiz bir şekilde değiştirilemez) sahip olan Ethereum depolaması üzerinde saklamak isteriz ancak 32 bayt büyüklüğünde bir kelime depolamanın maliyeti yaklaşık olarak 20,000 gazdır. Bunu yazarken, bu maliyet $6,60'a eşittir. Bayt başına 21 sentlik ücret birçok kullanıcı için çok pahalıdır. -Bu sorunu çözmek için Ethereum ekosistemi [verileri merkeziyetsiz bir şekilde depolamak için birçok alternatif yol](/developers/docs/storage/) geliştirdi. Eğer ağ müsaitse maliyet daha az olacaktır ancak ağ eğer yoğunsa maliyet daha fazla olacaktır. Ancak ağın bütünlüğü hep aynı olacaktır. +Bu sorunu çözmek için Ethereum ekosistemi, verileri merkeziyetsiz bir +şekilde depolamanın birçok alternatif yolunu geliştirdi. Eğer ağ müsaitse maliyet daha az olacaktır ancak ağ eğer yoğunsa maliyet daha fazla olacaktır. Ancak ağın bütünlüğü hep aynı olacaktır. -Bu makalede blok zinciri üzerinde veri depolamadan [Merkle ispatları](https://computersciencewiki.org/index.php/Merkle_proof) kullanarak **nasıl** veri bütünlüğü sağlanacağını öğreneceksiniz. +Bu makalede, [Merkle ispatlarını](https://computersciencewiki.org/index.php/Merkle_proof) kullanarak verileri blokzincirde depolamadan veri bütünlüğünün **nasıl** sağlanacağını +öğreneceksiniz. ## Nasıl çalışır? {#how-does-it-work} -Teoride verileri şifrelenmiş bir şeklide blok zinciri üzerinde tutup, işlem için gerekli verileri gönderebilirdik. Ancak bu hâlâ çok maliyetlidir. Bir işlem için bir bayt veri yaklaşık 16 gaz harcar. Bu, şu anda yaklaşık yarım sent veya kilobayt başına yaklaşık $5 değerindedir. Megabayt başına $5000, veriyi şifrelemenin maliyetini dahil etmesek bile bir çok kullanım alanı için çok pahalıdır. +Teorik olarak, verinin karmasını zincir üstünde depolayabilir ve tüm verileri gerektiren işlemlerde gönderebiliriz. Ancak bu hâlâ çok maliyetlidir. Bir işlem için bir bayt veri yaklaşık 16 gaz harcar. Bu, şu anda yaklaşık yarım sent veya kilobayt başına yaklaşık $5 değerindedir. Megabayt başına $5000, veriyi şifrelemenin maliyetini dahil etmesek bile bir çok kullanım alanı için çok pahalıdır. Çözüm ise, verilerin farklı alt kümelerini art arda şifrelenmiş hâle getirmektir. Böylece göndermeniz gerekmeyen veriler için sadece bir hash değeri gönderebilirsiniz. Bunu, her düğümün altındaki düğümlerin hash değerlerinden oluştuğu bir ağaç veri yapısı olan bir Merkle ağacını kullanarak yapabilirsiniz: ![Merkle Ağacı](tree.png) -Sadece kök hash değerinin ağ üzerinde depolanmış olması gerekmektedir. Bir değeri kanıtlamak için, o değeri oluşturan tüm hash değerlerini sağlamanız gerekmektedir. Örneğin `C`'yi kanıtlamak için `D`, `H(A-B)` ve `H(E-H)` sağlamak zorundasınız. +Kök karma, zincir üstünde saklanması gereken tek kısımdır. Bir değeri kanıtlamak için, o değeri oluşturan tüm hash değerlerini sağlamanız gerekmektedir. Örneğin, `C`'yi kanıtlamak için `D`, `H(A-B)` ve `H(E-H)` sağlamanız gerekir. ![C değerinin ispatı](proof-c.png) ## Uygulama {#implementation} -[Örnek kod burada sağlanmıştır](https://github.com/qbzzt/merkle-proofs-for-offline-data-integrity). +[Örnek koda buradan ulaşabilirsiniz](https://github.com/qbzzt/merkle-proofs-for-offline-data-integrity). -### Zincir dışı kod {#off-chain-code} +### Zincir dışı kod {#offchain-code} -Bu makalede zincir dışı işlemler için Javascript kullanıyoruz. Çoğu merkeziyetsiz uygulama Javascript'te zincir dışı bileşenlere sahiptir. +Bu makalede, zincir dışı hesaplamalar için JavaScript kullanıyoruz. Çoğu merkeziyetsiz uygulama Javascript'te zincir dışı bileşenlere sahiptir. #### Merkle kökünü oluşturma {#creating-the-merkle-root} @@ -45,61 +46,65 @@ Bu makalede zincir dışı işlemler için Javascript kullanıyoruz. Çoğu merk const ethers = require("ethers") ``` -[Ethers paketindeki hash fonksiyonunu kullanıyoruz](https://docs.ethers.io/v5/api/utils/hashing/#utils-keccak256). +[Ethers paketindeki karma işlevini kullanıyoruz](https://docs.ethers.io/v5/api/utils/hashing/#utils-keccak256). ```javascript -// The raw data whose integrity we have to verify. The first two bytes a -// are a user identifier, and the last two bytes the amount of tokens the -// user owns at present. +// Bütünlüğünü doğrulamamız gereken ham veriler. İlk iki bayt +// bir kullanıcı tanımlayıcısıdır ve son iki bayt kullanıcının +// şu anda sahip olduğu jeton miktarıdır. const dataArray = [ 0x0bad0010, 0x60a70020, 0xbeef0030, 0xdead0040, 0xca110050, 0x0e660060, 0xface0070, 0xbad00080, 0x060d0091, ] ``` -Örneğin her bir girişi 256-bit tam sayı değeri olacak şekilde kodlamak, bir JSON kullanmaktan daha az okunabilir olacaktır. Ancak bu, sözleşmedeki verilere erişmek için kayda değer ölçüde daha az işleme, dolayısıyla çok daha düşük gaz maliyetleri anlamına gelir. [JSON'u blok zinciri üzerinde okuyabilirsiniz](https://github.com/chrisdotn/jsmnSol) ancak bunu yapmak zorunda değilseniz kötü bir fikirdir. +Örneğin her bir girişi 256-bit tam sayı değeri olacak şekilde kodlamak, bir JSON kullanmaktan daha az okunabilir olacaktır. Ancak bu, sözleşmedeki verilere erişmek için kayda değer ölçüde daha az işleme, dolayısıyla çok daha düşük gaz maliyetleri anlamına gelir. [JSON'u zincir üstünde okuyabilirsiniz](https://github.com/chrisdotn/jsmnSol), ancak kaçınılabilecek bir durumsa bu kötü bir fikirdir. ```javascript -// The array of hash values, as BigInts +// BigInts olarak karma değerleri dizisi const hashArray = dataArray ``` Bu durumda veriler başlangıçta 256-bit değerindedir, bu yüzden herhangi bir işleme gerek yoktur. Eğer satır gibi daha karmaşık bir veri yapısı kullanıyor olsaydık, şifrelenmiş bir satır elde etmek için önce verileri şifrelediğimizden emin olmamız gerekirdi. Bunun ayrıca, kullanıcıların diğer kullanıcıların bilgilerini bilip bilmediklerini umursamamamızdan kaynaklandığını unutmayın. Aksi takdirde şifreleme yapmamız gerekecekti, böylece kullanıcı 1 kullanıcı 0'ın değerini; kullanıcı 2 kullanıcı 3'ün değerini bilmeyecekti vb. ```javascript -// Convert between the string the hash function expects and the -// BigInt we use everywhere else. +// Karma işlevinin beklediği dize ile +// başka her yerde kullandığımız BigInt arasında dönüştürür. const hash = (x) => BigInt(ethers.utils.keccak256("0x" + x.toString(16).padStart(64, 0))) ``` -Ethers hash fonksiyonu, `0x60A7` gibi onaltılık bir sayıya sahip bir JavaScript dizesi almayı bekler ve aynı yapıya sahip başka bir dizeyle yanıt verir. Ancak kodun geri kalanı için `BigInt` kullanmak daha kolaydır. Bu yüzden onu onaltılık bir dizeye ve geri eski hâline dönüştürürüz. +Ethers karma işlevi, `0x60A7` gibi onaltılık bir sayıya sahip bir JavaScript dizesi almayı bekler ve aynı yapıya sahip başka bir dizeyle yanıt verir. Ancak kodun geri kalanı için `BigInt` kullanmak daha kolaydır, bu yüzden onaltılık bir dizeye dönüştürüp sonra tekrar geri çeviririz. ```javascript -// Symmetrical hash of a pair so we won't care if the order is reversed. +// Bir çiftin simetrik karması, bu sayede sıranın tersine çevrilip çevrilmediğini önemsemeyiz. const pairHash = (a, b) => hash(hash(a) ^ hash(b)) ``` -Bu fonksiyon simetriktir ([xor](https://en.wikipedia.org/wiki/Exclusive_or) b'nin hash değeri). Bu, Merkle ispatını kontrol ettiğimizde, ispattaki değeri hesaplanan değerden önce mi sonra mı koyacağımız konusunda endişelenmemize gerek olmadığı anlamına gelir. Merkel ispatı kontrolü zincir üstünde gerçekleşir, orada ne kadar az kod kullanırsak o kadar iyi. +Bu işlev simetriktir (a'nın [xor](https://en.wikipedia.org/wiki/Exclusive_or) b'sinin karması). Bu, Merkle ispatını kontrol ettiğimizde, ispattaki değeri hesaplanan değerden önce mi sonra mı koyacağımız konusunda endişelenmemize gerek olmadığı anlamına gelir. Merkle ispatı kontrolü zincir üstünde yapılır, bu yüzden orada ne kadar az şey yapmamız gerekirse o kadar iyidir. -Uyarı: Kriptografi göründüğünden daha zordur. Bu belgenin ilk versiyonu, `hash(a^b)` karma fonksiyonuna sahipti. Bu, `a` ve `b`'nin meşru değerlerini bilmeniz durumunda `b' = a^b^a'` denklemini kullanarak istediğiniz `a'` değerini kanıtlayabileceğiniz anlamına geldiği için **kötü** bir fikirdi. Bu fonksiyonla, `hash(a') ^ hash(b')` değeri, bilinen bir değere (köke giden yolda sonraki dal) eşit olacak şekilde `b'` değerini hesaplamanız gerekecekti ve bu çok daha zordur. +Uyarı: +Kriptografi göründüğünden daha zordur. +Bu makalenin ilk versiyonunda `hash(a^b)` karma işlevi vardı. +Bu **kötü** bir fikirdi çünkü `a` ve `b`'nin meşru değerlerini biliyorsanız, istenen herhangi bir `a'` değerini kanıtlamak için `b' = a^b^a'` kullanabileceğiniz anlamına geliyordu. +Bu işlevle, `hash(a') ^ hash(b')` değerinin bilinen bir değere (köke giden yoldaki bir sonraki dal) eşit olacak şekilde `b'` değerini hesaplamanız gerekir, ki bu çok daha zordur. ```javascript -// The value to denote that a certain branch is empty, doesn't -// have a value +// Belirli bir dalın boş olduğunu, bir değere sahip olmadığını +// belirtmek için kullanılan değer const empty = 0n ``` Değerler ikinin katı tam sayılar olmadığında bunun yerine boş dalları işlememiz gerekir. Program bunu yapmak için boş dallara varsayılan değer olarak 0 atar. -![Dalları eksik olan Merkle ağacı](merkle-empty-hash.png) +![Eksik dalları olan Merkle ağacı](merkle-empty-hash.png) ```javascript -// Calculate one level up the tree of a hash array by taking the hash of -// each pair in sequence +// Her bir çiftin karmasını sırayla alarak bir karma dizisi ağacında +// bir seviye yukarı hesaplar const oneLevelUp = (inputArray) => { var result = [] - var inp = [...inputArray] // To avoid over writing the input // Add an empty value if necessary (we need all the leaves to be // paired) + var inp = [...inputArray] // Girdinin üzerine yazmayı önlemek için // Gerekirse boş bir değer ekleyin (tüm yaprakların eşleştirilmesi gerekir) if (inp.length % 2 === 1) inp.push(empty) @@ -110,13 +115,13 @@ const oneLevelUp = (inputArray) => { } // oneLevelUp ``` -Bu fonksiyon, güncel katmandaki değer çiftlerini karma hâle getirerek bir üst seviyeye "tırmanır". Bunun en verimli uygulama olmadığını unutmayın, girdiyi kopyalamaktan kaçınabilir ve uygun olduğunda döngüye `hashEmpty` ekleyebilirdik, ancak bu kod okunabilirlik için optimize edilmiştir. +Bu fonksiyon, güncel katmandaki değer çiftlerini karma hâle getirerek bir üst seviyeye "tırmanır". Bunun en verimli uygulama olmadığını, girdiyi kopyalamaktan kaçınıp döngüde uygun olduğunda `hashEmpty` ekleyebileceğimizi, ancak bu kodun okunabilirlik için optimize edildiğini unutmayın. ```javascript const getMerkleRoot = (inputArray) => { var result - result = [...inputArray] // Climb up the tree until there is only one value, that is the // root. // // If a layer has an odd number of entries the // code in oneLevelUp adds an empty value, so if we have, for example, // 10 leaves we'll have 5 branches in the second layer, 3 // branches in the third, 2 in the fourth and the root is the fifth + result = [...inputArray] // Ağaçta tek bir değer kalana kadar yukarı tırmanır, bu // köktür. // // Eğer bir katmanın tek sayıda girdisi varsa // oneLevelUp'daki kod boş bir değer ekler, yani örneğin // 10 yaprağımız varsa, ikinci katmanda 5 dal, // üçüncüde 3, dördüncüde 2 dal olur ve kök beşincidir while (result.length > 1) result = oneLevelUp(result) @@ -126,35 +131,33 @@ const getMerkleRoot = (inputArray) => { Ana değere ulaşmak için ağaçta tek bir değer kalana kadar tırmanın. -#### Bir Merkle ispatı oluşturma {#creating-a-merkle-proof} +#### Merkle ispatı oluşturma {#creating-a-merkle-proof} Bir Merkle ispatı, Merkle kökünü geri almak için kanıtlanan değerle birlikte karma hale getirilecek değerlerdir. İspatlanacak olan değer sıklıkla diğer veride bulunabilir. Bu yüzden kodun bir parçası yerine ayrı olarak sağlamayı tercih ederim. ```javascript -// A merkle proof consists of the value of the list of entries to -// hash with. Simetrik bir karma işlevi kullandığımız için, -// kanıtı doğrulamak için öğenin konumuna ihtiyacımız var, yalnızca onu oluşturmak için +// Bir merkle ispatı, birlikte karma alınacak giriş listesinin // değerinden oluşur. // Simetrik bir karma işlevi kullandığımız için, ispatı doğrulamak için öğenin konumuna ihtiyacımız // yoktur, yalnızca oluşturmak için gerekir const getMerkleProof = (inputArray, n) => {     var result = [], currentLayer = [...inputArray], currentN = n -    // Until we reach the top +    // Zirveye ulaşana kadar     while (currentLayer.length > 1) { -        // No odd length layers +        // Tek uzunluklu katmanlar olamaz         if (currentLayer.length % 2)             currentLayer.push(empty)         result.push(currentN % 2 -               // If currentN is odd, add with the value before it to the proof +               // Eğer currentN tekse, ispata ondan önceki değeri ekleyin             ? currentLayer[currentN-1] -               // If it is even, add the value after it +               // Çiftse, sonraki değeri ekleyin             : currentLayer[currentN+1]) ``` -`(v[0],v[1])`, `(v[2],v[3])` vb. şeklinde karma hale getiririz. Yani çift değerler için bir sonrakine, tek değerler için bir öncekine ihtiyacımız vardır. +`(v[0],v[1])`, `(v[2],v[3])` vb. şeklinde karma alırız. Yani çift değerler için bir sonrakine, tek değerler için bir öncekine ihtiyacımız vardır. ```javascript -        // Move to the next layer up +        // Bir üst katmana geç         currentN = Math.floor(currentN/2)         currentLayer = oneLevelUp(currentLayer)     }   // while currentLayer.length > 1 @@ -163,9 +166,9 @@ const getMerkleProof = (inputArray, n) => { }   // getMerkleProof ``` -### Zincir üstü kod {#on-chain-code} +### Zincir üstü kod {#onchain-code} -Nihayet, kanıtları kontrol eden koda ulaştık. Zincir üstü kod, [Solidity](https://docs.soliditylang.org/en/v0.8.11/) ile yazılmıştır. Gaz maliyeti yüksek olduğundan burada optimizasyon çok daha önemlidir. +Nihayet, kanıtları kontrol eden koda ulaştık. Zincir üstü kod [Solidity](https://docs.soliditylang.org/en/v0.8.11/) ile yazılmıştır. Gaz maliyeti yüksek olduğundan burada optimizasyon çok daha önemlidir. ```solidity //SPDX-License-Identifier: Public Domain @@ -174,7 +177,7 @@ pragma solidity ^0.8.0; import "hardhat/console.sol"; ``` -Bunu, [Hardhat geliştirme ortamını kullanarak yazdım](https://hardhat.org/). Bu, geliştirme yaparken [Solidity'den konsol çıktısına](https://hardhat.org/docs/cookbook/debug-logs) sahip olmamızı sağlar. +Bunu, geliştirme yaparken [Solidity'den konsol çıktısı almamızı](https://hardhat.org/docs/cookbook/debug-logs) sağlayan [Hardhat geliştirme ortamını](https://hardhat.org/) kullanarak yazdım. ```solidity @@ -185,15 +188,15 @@ contract MerkleProof {       return merkleRoot;     } -    // Extremely insecure, in production code access to -    // this function MUST BE strictly limited, probably to an -    // owner +    // Son derece güvensiz, üretim kodunda bu işleve +    // erişim MUTLAKA sıkı bir şekilde sınırlandırılmalı, muhtemelen bir +    // sahip (owner) tarafından     function setRoot(uint _merkleRoot) external {       merkleRoot = _merkleRoot;     }   // setRoot ``` -Merkle kökü için ayarlama ve getirme fonksiyonları. Bir üretim sisteminde herkesin Merkle kökünü güncellemesine izin vermek _son derece kötü bir fikirdir_. Örnek kodu basitleştirmek adına bunu burada yapıyorum. **Veri bütünlüğünün önemli olduğu bir sistemde bunu yapmayın**. +Merkle kökü için ayarlama ve getirme fonksiyonları. Bir üretim sisteminde herkesin Merkle kökünü güncellemesine izin vermek _son derece kötü bir fikirdir_. Örnek kodu basitleştirmek adına bunu burada yapıyorum. **Veri bütünlüğünün gerçekten önemli olduğu bir sistemde bunu yapmayın**. ```solidity     function hash(uint _a) internal pure returns(uint) { @@ -205,12 +208,12 @@ Merkle kökü için ayarlama ve getirme fonksiyonları. Bir üretim sisteminde h     } ``` -Bu fonksiyon bir eş karma değeri oluşturur. Bu, sadece `hash` ve `pairHash` için JavaScript kodunun Solidity çevirisidir. +Bu fonksiyon bir eş karma değeri oluşturur. Bu sadece `hash` ve `pairHash` için JavaScript kodunun Solidity çevirisidir. -**Not:** Burada da okunabilirlik için optimizasyon yapılmıştır. [Fonksiyon tanımına](https://www.tutorialspoint.com/solidity/solidity_cryptographic_functions.htm) dayanarak; [`bytes32`](https://docs.soliditylang.org/en/v0.5.3/types.html#fixed-size-byte-arrays) olarak veriyi depolamak ve dönüşümleri önlemek mümkün olabilir. +**Not:** Burada da okunabilirlik için optimizasyon yapılmıştır. [İşlev tanımına](https://www.tutorialspoint.com/solidity/solidity_cryptographic_functions.htm) dayanarak, verileri bir [`bytes32`](https://docs.soliditylang.org/en/v0.5.3/types.html#fixed-size-byte-arrays) değeri olarak depolamak ve dönüşümlerden kaçınmak mümkün olabilir. ```solidity -    // Merkle kanıtını doğrulayın +    // Bir Merkle ispatını doğrulayın     function verifyProof(uint _value, uint[] calldata _proof)         public view returns (bool) {       uint temp = _value; @@ -226,16 +229,18 @@ Bu fonksiyon bir eş karma değeri oluşturur. Bu, sadece `hash` ve `pairHash` i }  // MarkleProof ``` -Matematiksel gösterimde Merkle ispatı şöyle görünür: `H(proof_n, H(proof_n-1, H(proof_n-2, ... H(proof_1, H(proof_0, value))...)))`. Bu kod onu uygular. +Matematiksel gösterimde Merkle ispatı doğrulaması şöyle görünür: `H(proof_n, H(proof_n-1, H(proof_n-2, ...` H(proof_1, H(proof_0, value))...)))`. Bu kod onu uygular. -## Merkle ispatları ve toplamalar uyumlu değildir {#merkle-proofs-and-rollups} +## Merkle ispatları ve toplamalar birbiriyle uyuşmaz {#merkle-proofs-and-rollups} -Merkle ispatları, [toplamalar](/developers/docs/scaling/#rollups) ile iyi çalışmaz. Sebebi ise toplamalarda işlemlerin Katman 1 üzerinde yazılması ancak Katman 2 üzerinde işlenmesidir. Bir işlem ile Merkle ispatı göndermenin maliyeti katman başına ortalama 638 gazdır (güncel olarak çağrı verisinde gaz maliyeti, bayt sıfır değilse 16, sıfır ise 4'tür). Eğer 1024 kelimeden oluşan bir verimiz varsa, bir Merkle ispatı 10 katman veya 6380 gaz gerektirir. +Merkle ispatları [toplamalarla](/developers/docs/scaling/#rollups) iyi çalışmaz. Sebebi ise toplamalarda işlemlerin Katman 1 üzerinde yazılması ancak Katman 2 üzerinde işlenmesidir. Bir işlem ile Merkle ispatı göndermenin maliyeti katman başına ortalama 638 gazdır (güncel olarak çağrı verisinde gaz maliyeti, bayt sıfır değilse 16, sıfır ise 4'tür). Eğer 1024 kelimeden oluşan bir verimiz varsa, bir Merkle ispatı 10 katman veya 6380 gaz gerektirir. -Örneğin [Optimism](https://public-grafana.optimism.io/d/9hkhMxn7z/public-dashboard?orgId=1&refresh=5m)'e bakacak olursak: Katman 1 gaz yazmak ortalama 100 gwei, Katman 2 gaz yazmak ise 0,001 gwei'ye mal olmaktadır (bu, normal fiyattır ve tıkanıklık olursa artabilir). Yani bir Katman 1 gazının bedeli ile Katman 2 işlemeye yüz bin gaz harcayabiliriz. Depolamanın üzerine yazmadığımızı varsayarsak bu, bir Katman 1 gazı fiyatına Katman 2'deki depolamaya yaklaşık beş kelime yazabileceğimiz anlamına gelir. Tek bir Merkle ispatı için 1024 kelimenin tamamını depolamaya yazabiliriz (bir işlemde sağlanmak yerine zincir üzerinde hesaplayabileceklerini varsayarsak) ve hâlâ gaz maliyetinden tasarruf etme imkanımız olur. +Örneğin [Optimism](https://public-grafana.optimism.io/d/9hkhMxn7z/public-dashboard?orgId=1&refresh=5m)'e bakıldığında, L1'e yazmanın gaz maliyeti yaklaşık 100 gwei, L2'nin gaz maliyeti ise 0,001 gwei'dir (bu normal fiyattır ve tıkanıklık durumunda artabilir). Yani bir Katman 1 gazının bedeli ile Katman 2 işlemeye yüz bin gaz harcayabiliriz. Depolamanın üzerine yazmadığımızı varsayarsak bu, bir Katman 1 gazı fiyatına Katman 2'deki depolamaya yaklaşık beş kelime yazabileceğimiz anlamına gelir. Tek bir Merkle ispatı için, 1024 kelimenin tamamını depolamaya yazabilir (başlangıçta bir işlemde sağlanmak yerine zincir üstünde hesaplanabildiklerini varsayarsak) ve yine de gazın çoğu artmış olur. ## Sonuç {#conclusion} Gerçek hayatta, Merkle ağaçlarını hiçbir zaman kendi başınıza uygulamayacak olabilirsiniz. Denetlenmiş ve iyi bilinen kütüphaneler mevcuttur. Genel olarak kendi başınıza ilkel kriptografik yöntemleri uygulamamanız en iyi seçimdir. Fakat Merkle ispatlarını ve ne zaman kullanmaya değer olduklarını umarım daha iyi anlamışsınızdır. -Merkle ispatlarının, _bütünlüğü_ korurken _kullanılabilirlikten_ ödün verdiğini unutmayın. Veri deposuna erişim yoksa ve onlara erişmek için bir Merkle ağacı oluşturamıyorsanız, varlıklarınızı başka kimsenin alamayacağını bilmek küçük bir teselli olur. Yani en iyisi Merkle ağaçlarının IPFS gibi bir merkeziyetsiz depolama ile kullanılmasıdır. +Merkle ispatlarının _bütünlüğü_ korurken _kullanılabilirliği_ korumadığını unutmayın. Veri deposuna erişim yoksa ve onlara erişmek için bir Merkle ağacı oluşturamıyorsanız, varlıklarınızı başka kimsenin alamayacağını bilmek küçük bir teselli olur. Yani en iyisi Merkle ağaçlarının IPFS gibi bir merkeziyetsiz depolama ile kullanılmasıdır. + +[Çalışmalarımdan daha fazlası için buraya bakın](https://cryptodocguy.pro/). diff --git a/public/content/translations/tr/developers/tutorials/monitoring-geth-with-influxdb-and-grafana/index.md b/public/content/translations/tr/developers/tutorials/monitoring-geth-with-influxdb-and-grafana/index.md index e552612058d..67ff83c2df3 100644 --- a/public/content/translations/tr/developers/tutorials/monitoring-geth-with-influxdb-and-grafana/index.md +++ b/public/content/translations/tr/developers/tutorials/monitoring-geth-with-influxdb-and-grafana/index.md @@ -1,10 +1,8 @@ --- -title: InfluxDB ve Grafana ile Geth'i İzleme -description: +title: "InfluxDB ve Grafana ile Geth'i İzleme" +description: "Performansı izlemek ve sorunları belirlemek için InfluxDB ve Grafana'yı kullanarak Geth düğümünüz için izleme ayarlayın." author: "Mario Havel" -tags: - - "istemciler" - - "düğümler" +tags: [ "istemciler", "düğümler" ] skill: intermediate lang: tr published: 2021-01-13 @@ -12,15 +10,15 @@ published: 2021-01-13 Bu öğretici, Geth düğümünüzün performansını daha iyi anlayabilmeniz ve olası sorunları belirleyebilmeniz için izleme kurmanıza yardımcı olacaktır. -## Ön koşullar {#prerequisites} +## Ön Koşullar {#prerequisites} - Zaten bir Geth örneği çalıştırıyor olmalısınız. -- Adımların ve örneklerin çoğu linux ortamı içindir, temel terminal bilgisi yardımcı olacaktır. +- Adımların ve örneklerin çoğu Linux ortamı içindir, temel terminal bilgisi yardımcı olacaktır. - Geth'in ölçüm paketine dair bu genel bakış videosuna göz atın: [Bir Ethereum altyapısını izleme - Péter Szilágyi](https://www.youtube.com/watch?v=cOBab8IJMYI). ## İzleme yığını {#monitoring-stack} -Bir Ethereum istemcisi, kronolojik bir veri tabanı şeklinde okunabilecek çok sayıda veri toplar. İzlemeyi kolaylaştırmak için bunu veri görselleştirme yazılımına aktarabilirsiniz. Birden fazla seçenek mevcuttur: +Bir Ethereum istemcisi, kronolojik bir veritabanı şeklinde okunabilecek çok sayıda veri toplar. İzlemeyi kolaylaştırmak için bunu veri görselleştirme yazılımına aktarabilirsiniz. Birden fazla seçenek mevcuttur: - [Prometheus](https://prometheus.io/) (çekme modeli) - [InfluxDB](https://www.influxdata.com/get-influxdb/) (itme modeli) @@ -29,13 +27,14 @@ Bir Ethereum istemcisi, kronolojik bir veri tabanı şeklinde okunabilecek çok - [Datadog](https://www.datadoghq.com/) - [Chronograf](https://www.influxdata.com/time-series-platform/chronograf/) -Ayrıca InfluxDB ve Grafana ile önceden yapılandırılmış olan bir seçenek olan [Geth Prometheus Exporter](https://github.com/hunterlong/gethexporter) bulunmaktadır. +Ayrıca InfluxDB ve Grafana ile önceden yapılandırılmış bir seçenek olan [Geth Prometheus Exporter](https://github.com/hunterlong/gethexporter) da vardır. -Bu öğreticide, Geth istemcinizi bir veri tabanı oluşturmak için InfluxDB'ye ve verilerin grafik görselleştirmesini oluşturmak için Grafana'ya veri gönderecek şekilde ayarlayacağız. Bunu manuel olarak yapmak; süreci daha iyi anlamanıza, değiştirmenize ve farklı ortamlarda dağıtmanıza yardımcı olacaktır. +Bu öğreticide, Geth istemcinizi bir veritabanı oluşturmak için InfluxDB'ye ve verilerin grafik görselleştirmesini oluşturmak için Grafana'ya veri gönderecek şekilde ayarlayacağız. Bunu manuel olarak yapmak; süreci daha iyi anlamanıza, değiştirmenize ve farklı ortamlarda dağıtmanıza yardımcı olacaktır. -## InfluxDB kurulumu {#setting-up-influxdb} +## InfluxDB'yi Kurma {#setting-up-influxdb} -Öncelikle InfluxDB'yi indirip kuralım. [Influxdata yayın sayfasında](https://portal.influxdata.com/downloads/) çeşitli indirme seçenekleri bulunabilir. Ortamınıza uygun olanı seçin. Ayrıca bir [depodan](https://repos.influxdata.com/) da indirebilirsiniz. Örnek olarak Debian temelli bir dağıtımda: +Öncelikle, InfluxDB'yi indirip kuralım. Çeşitli indirme seçenekleri [Influxdata yayın sayfasında](https://portal.influxdata.com/downloads/) bulunabilir. Ortamınıza uygun olanı seçin. +Ayrıca bir [depodan](https://repos.influxdata.com/) da kurabilirsiniz. Örneğin Debian tabanlı bir dağıtımda: ``` curl -tlsv1.3 --proto =https -sL https://repos.influxdata.com/influxdb.key | sudo apt-key add @@ -48,19 +47,20 @@ sudo systemctl start influxdb sudo apt install influxdb-client ``` -InfluxDB'yi başarıyla yükledikten sonra, arka planda çalıştığından emin olun. Varsayılan olarak, `localhost:8086`'da erişilebilir. `influx` istemcisini kullanmadan önce, admin yetkileri olan yeni bir kullanıcı yaratmalısınız. Bu kullanıcı, üst düzey yönetim, veri tabanları ve kullanıcılar oluşturmaya hizmet edecektir. +InfluxDB'yi başarıyla yükledikten sonra, arka planda çalıştığından emin olun. Varsayılan olarak `localhost:8086` adresinden erişilebilir. +`influx` istemcisini kullanmadan önce, yönetici ayrıcalıklarına sahip yeni bir kullanıcı oluşturmanız gerekir. Bu kullanıcı, üst düzey yönetim, veritabanları ve kullanıcılar oluşturmaya hizmet edecektir. ``` curl -XPOST "http://localhost:8086/query" --data-urlencode "q=CREATE USER username WITH PASSWORD 'password' WITH ALL PRIVILEGES" ``` -Şimdi influx istemcisini bu kullanıcı ile [InfluxDB kabuğuna](https://docs.influxdata.com/influxdb/v1.8/tools/shell/) girmek için kullanabilirsiniz. +Artık bu kullanıcıyla [InfluxDB kabuğuna](https://docs.influxdata.com/influxdb/v1.8/tools/shell/) girmek için `influx` istemcisini kullanabilirsiniz. ``` influx -username 'username' -password 'password' ``` -Kabuğunun içinden InfluxDB ile doğrudan iletişim kurarak, geth ölçümleri için veri tabanı ve kullanıcı oluşturabilirsiniz. +Kabuğunda InfluxDB ile doğrudan iletişim kurarak, Geth ölçümleri için veritabanı ve kullanıcı oluşturabilirsiniz. ``` create database geth @@ -82,9 +82,10 @@ exit InfluxDB, Geth'ten gelen ölçümleri depolamak için çalışıyor ve yapılandırıldı. -## Geth'i hazırlama {#preparing-geth} +## Geth'i Hazırlama {#preparing-geth} -Veri tabanını kurduktan sonra Geth'te ölçüm toplamayı etkinleştirmemiz gerekiyor. `geth --help` içindeki `METRICS AND STATS OPTIONS`'a dikkat edin. Orada birden fazla seçenek bulunabilir, bu durumda Geth'in verileri InfluxDB'ye göndermesini istiyoruz. Temel kurulum, InfluxDB'nin erişilebilir olduğu uç noktayı ve veri tabanı için kimlik doğrulamasını belirtir. +Veritabanını kurduktan sonra Geth'te ölçüm toplamayı etkinleştirmemiz gerekiyor. `geth --help` içindeki `METRICS AND STATS OPTIONS` bölümüne dikkat edin. Orada birden fazla seçenek bulunabilir, bu durumda Geth'in verileri InfluxDB'ye göndermesini istiyoruz. +Temel kurulum, InfluxDB'nin erişilebilir olduğu uç noktayı ve veritabanı için kimlik doğrulamasını belirtir. ``` geth --metrics --metrics.influxdb --metrics.influxdb.endpoint "http://0.0.0.0:8086" --metrics.influxdb.username "geth" --metrics.influxdb.password "chosenpassword" @@ -92,16 +93,17 @@ geth --metrics --metrics.influxdb --metrics.influxdb.endpoint "http://0.0.0.0:80 Bu bayraklar, istemciyi başlatan bir komuta eklenebilir veya yapılandırma dosyasına kaydedilebilir. -Geth'in verileri başarıyla ilettiğini, örneğin veri tabanındaki ölçümleri listeleyerek doğrulayabilirsiniz. InfluxDB kabuğunda: +Geth'in verileri başarıyla gönderdiğini, örneğin veritabanındaki ölçümleri listeleyerek doğrulayabilirsiniz. InfluxDB kabuğunda: ``` use geth show measurements ``` -## Grafana kurulumu {#setting-up-grafana} +## Grafana'yı Kurma {#setting-up-grafana} -Bir sonraki adım, verileri grafiksel olarak yorumlayacak olan Grafana'yı kurmaktır. Grafana belgelerinde ortamınız için kurulum sürecini takip edin. Başka türlü istemiyorsanız, OSS sürümünü yüklediğinizden emin olun. Depo kullanan Debian dağıtımları için örnek kurulum adımları: +Bir sonraki adım, verileri grafiksel olarak yorumlayacak olan Grafana'yı kurmaktır. Grafana belgelerinde ortamınız için kurulum sürecini takip edin. Başka türlü istemiyorsanız, OSS sürümünü yüklediğinizden emin olun. +Depo kullanan Debian dağıtımları için örnek kurulum adımları: ``` curl -tlsv1.3 --proto =https -sL https://packages.grafana.com/gpg.key | sudo apt-key add - @@ -112,15 +114,16 @@ sudo systemctl enable grafana-server sudo systemctl start grafana-server ``` -Grafana'yı çalıştırdığınızda, `localhost:3000` adresinden erişilebilir olmalıdır. Bu yola erişmek için tercih ettiğiniz tarayıcıyı kullanın, ardından varsayılan kimlik bilgileriyle oturum açın (kullanıcı: `admin` ve şifre: `admin`). İstendiğinde, varsayılan şifreyi değiştirin ve kaydedin. +Grafana'yı çalıştırdığınızda, `localhost:3000` adresinden erişilebilir olmalıdır. +Bu yola erişmek için tercih ettiğiniz tarayıcıyı kullanın, ardından varsayılan kimlik bilgileriyle (kullanıcı: `admin` ve şifre: `admin`) oturum açın. İstendiğinde, varsayılan şifreyi değiştirin ve kaydedin. ![](./grafana1.png) -Grafana ana sayfasına yönlendirileceksiniz. İlk olarak, kaynak verinizi hazırlayın. Sol çubuktaki yapılandırma simgesine tıklayın ve "Data sources"'ı (Veri kaynakları) seçin. +Grafana ana sayfasına yönlendirileceksiniz. Öncelikle, kaynak verilerinizi ayarlayın. Sol çubuktaki yapılandırma simgesine tıklayın ve "Data sources" (Veri kaynakları) seçeneğini seçin. ![](./grafana2.png) -Henüz oluşturulmuş veri kaynağı yok, birini tanımlamak için "Add data source"a (Veri kaynağı ekle) tıklayın. +Henüz oluşturulmuş veri kaynağı yok, birini tanımlamak için "Add data source" (Veri kaynağı ekle) seçeneğine tıklayın. ![](./grafana3.png) @@ -128,20 +131,21 @@ Bu kurulum için "InfluxDB"yi seçin ve devam edin. ![](./grafana4.png) -Araçları aynı makinede çalıştırıyorsanız, veri kaynağı yapılandırması oldukça basittir. Veri tabanına erişmek için InfluxDB adresini ve ayrıntılarını ayarlamanız gerekir. Aşağıdaki resme başvurun. +Araçları aynı makinede çalıştırıyorsanız, veri kaynağı yapılandırması oldukça basittir. Veritabanına erişmek için InfluxDB adresini ve ayrıntılarını ayarlamanız gerekir. Aşağıdaki resme başvurun. ![](./grafana5.png) -Her şey tamamlandıysa ve InfluxDB erişilebilir durumdaysa, "Save and test"e (Kaydet ve test et) tıklayın ve onayın görünmesini bekleyin. +Her şey tamamlandıysa ve InfluxDB erişilebilir durumdaysa, "Save and test" (Kaydet ve test et) seçeneğine tıklayın ve onayın görünmesini bekleyin. ![](./grafana6.png) -Grafana artık InfluxDB'den veri okumak üzere ayarlanmıştır. Şimdi, onu yorumlayacak ve gösterecek bir gösterge paneli oluşturmanız gerekiyor. Gösterge paneli özellikleri, herkes tarafından oluşturulabilen ve kolayca içe aktarılabilen JSON dosyalarında kodlanmıştır. Sol çubukta, "Create and Import"a (Oluştur ve İçe Aktar) tıklayın. +Grafana artık InfluxDB'den veri okumak üzere ayarlanmıştır. Şimdi, onu yorumlayacak ve gösterecek bir gösterge paneli oluşturmanız gerekiyor. Gösterge paneli özellikleri, herkes tarafından oluşturulabilen ve kolayca içe aktarılabilen JSON dosyalarında kodlanmıştır. Sol çubukta, "Create and Import" (Oluştur ve İçe Aktar) seçeneğine tıklayın. ![](./grafana7.png) -Bir Geth izleme gösterge paneli için [bu gösterge panelinin](https://grafana.com/grafana/dashboards/13877/) kimliğini kopyalayın ve Grafana'daki "Import page"e (İçe Aktarma sayfası) yapıştırın. Gösterge panelini kaydettikten sonra şöyle görünmelidir: +Bir Geth izleme gösterge paneli için [bu gösterge panelinin](https://grafana.com/grafana/dashboards/13877/) kimliğini kopyalayın ve Grafana'daki "Import page" (İçe Aktarma sayfası) bölümüne yapıştırın. Gösterge panelini kaydettikten sonra şöyle görünmelidir: ![](./grafana8.png) -Gösterge panellerinizi değiştirebilirsiniz. Her panel düzenlenebilir, taşınabilir, kaldırılabilir veya eklenebilir. Yapılandırmalarınızı değiştirebilirsiniz. Size kalmış! Eğer gösterge panellerin nasıl çalıştığı hakkında dahasını öğrenmek istiyorsanız, [Grafana'nın belgelerine](https://grafana.com/docs/grafana/latest/dashboards/) başvurun. Ayrıca [Alerting](https://grafana.com/docs/grafana/latest/alerting/) ilginizi çekebilir. Bu, ölçümler belirli değerlere ulaştığında uyarı bildirimleri ayarlamanıza olanak tanır. Çeşitli iletişim kanalları desteklenir. +Gösterge panellerinizi değiştirebilirsiniz. Her panel düzenlenebilir, taşınabilir, kaldırılabilir veya eklenebilir. Yapılandırmalarınızı değiştirebilirsiniz. Size kalmış! Gösterge panellerinin nasıl çalıştığı hakkında daha fazla bilgi edinmek için [Grafana'nın dökümantasyonuna](https://grafana.com/docs/grafana/latest/dashboards/) başvurun. +[Uyarılar](https://grafana.com/docs/grafana/latest/alerting/) da ilginizi çekebilir. Bu, ölçümler belirli değerlere ulaştığında uyarı bildirimleri ayarlamanıza olanak tanır. Çeşitli iletişim kanalları desteklenir. diff --git a/public/content/translations/tr/developers/tutorials/nft-minter/index.md b/public/content/translations/tr/developers/tutorials/nft-minter/index.md index eef4bf3b35d..706d56fcbf4 100644 --- a/public/content/translations/tr/developers/tutorials/nft-minter/index.md +++ b/public/content/translations/tr/developers/tutorials/nft-minter/index.md @@ -1,14 +1,8 @@ --- -title: NFT Minter Öğreticisi -description: Bu eğitimde, bir NFT minter oluşturacak ve akıllı sözleşmenizi MetaMask ve Web3 araçlarını kullanarak bir React ön ucuna bağlayarak tam yığınlı bir merkeziyetsiz uygulama oluşturmayı öğreneceksiniz. +title: "NFT Minter Öğreticisi" +description: "Bu eğitimde, bir NFT minter oluşturacak ve akıllı sözleşmenizi MetaMask ve Web3 araçlarını kullanarak bir React ön ucuna bağlayarak tam yığınlı bir merkeziyetsiz uygulama oluşturmayı öğreneceksiniz." author: "smudgil" -tags: - - "solidity" - - "NFT" - - "alchemy" - - "akıllı sözleşmeler" - - "ön uç" - - "Pinata" +tags: ["solidity", "NFT", "alchemy", "smart contracts", "frontend", "Pinata"] skill: intermediate lang: tr published: 2021-10-06 @@ -19,51 +13,51 @@ Web2 arka planından gelen geliştiriciler için en büyük zorluklardan biri, a Dijital varlığınıza bir bağlantı, bir başlık ve bir açıklama girebileceğiniz basit bir kullanıcı arayüzü olan bir NFT minter oluşturarak şunları nasıl yapacağınızı öğreneceksiniz: - Ön uç projeniz aracılığıyla MetaMask'a bağlanma -- Ön ucunuzdan akıllı sözleşme yöntemlerini çağırma +- Ön ucunuzdan akıllı sözleşme yöntemlerini arama - MetaMask kullanarak işlemleri imzalama -Bu öğreticide, ön uç çerçevemiz olarak [React](https://reactjs.org/) kullanacağız. Bu eğitim öncelikle Web3 geliştirmeye odaklandığından, React temellerini açıklamak için fazla zaman harcamayacağız. Bunun yerine, projemize işlevsellik getirmeye odaklanacağız. +Bu öğreticide, ön uç çerçevemiz olarak [React](https://react.dev/) kullanacağız. Bu eğitim öncelikle Web3 geliştirmeye odaklandığından, React temellerini açıklamak için fazla zaman harcamayacağız. Bunun yerine, projemize işlevsellik getirmeye odaklanacağız. -Bir ön koşul olarak, başlangıç ​​düzeyinde bir React anlayışına sahip olmalısınız; bileşenlerin, donanımların, useState/useEffect ve temel fonksiyon çağırmanın nasıl çalıştığını bilmeniz gerekir. Bu terimlerden herhangi birini daha önce hiç duymadıysanız, bu [React'e Giriş eğitimine](https://reactjs.org/tutorial/tutorial.html) göz atmak isteyebilirsiniz. Daha görsel öğrenenler için Net Ninja'nın bu mükemmel [Tam Modern React Eğitimi](https://www.youtube.com/playlist?list=PL4cUxeGkcC9gZD-Tvwfod2gaISzfRiP9d) video dizisini şiddetle tavsiye ediyoruz. +Bir ön koşul olarak, başlangıç ​​düzeyinde bir React anlayışına sahip olmalısınız; bileşenlerin, donanımların, useState/useEffect ve temel fonksiyon çağırmanın nasıl çalıştığını bilmeniz gerekir. Bu terimlerden herhangi birini daha önce hiç duymadıysanız, bu [React'e Giriş öğreticisine](https://react.dev/learn/tutorial-tic-tac-toe) göz atmak isteyebilirsiniz. Daha çok görsel öğrenenler için Net Ninja'nın bu mükemmel [Tam Modern React Öğreticisi](https://www.youtube.com/playlist?list=PL4cUxeGkcC9gZD-Tvwfod2gaISzfRiP9d) video serisini şiddetle tavsiye ederiz. Ve henüz yapmadıysanız, bu öğreticiyi tamamlamak ve blok zincirinde herhangi bir şey oluşturmak için kesinlikle bir Alchemy hesabına ihtiyacınız olacak. [Buradan](https://alchemy.com/) ücretsiz bir hesap için kaydolun. Lafı fazla uzatmadan başlayalım! -## NFT Yapma 101 {#making-nfts-101} +## NFT Yapımına Giriş {#making-nfts-101} Herhangi bir koda bakmaya başlamadan önce, bir NFT yapmanın nasıl çalıştığını anlamak önemlidir. İki adım içerir: -### Ethereum blok zincirinde bir NFT akıllı sözleşmesi yayınlayın {#publish-nft} +### Ethereum blokzincirinde bir NFT akıllı sözleşmesi yayımlayın {#publish-nft} İki NFT akıllı iletişim standardı arasındaki en büyük fark, ERC-1155'in çok token'lı bir standart olması ve toplu işlevsellik içermesi; ERC-721'in ise tek token'lı bir standart olması ve bu nedenle bir seferde yalnızca bir token'ın aktarılmasını desteklemesidir. -### Basma fonksiyonunu çağırın {#minting-function} +### Basım fonksiyonunu çağırın {#minting-function} -Genellikle, bu mint (basma) fonksiyonu, parametre olarak iki değişken girmenizi gerektirir: İlk olarak, yeni basılmış NFT'nizi alacak adresi belirten `recipient` ve ikinci olarak NFT'nin meta verilerini açıklayan bir JSON belgesine çözümlenen bir dize olan NFT'nin `tokenURI`'ı. +Genellikle bu basım fonksiyonu, parametre olarak iki değişken iletmenizi gerektirir: birincisi, yeni basılmış NFT'nizi alacak adresi belirten `recipient` ve ikincisi, NFT'nin meta verilerini açıklayan bir JSON belgesine çözümlenen bir dize olan NFT'nin `tokenURI`'sidir. Bir NFT'nin meta verileri gerçekten onu hayata geçiren şeydir ve bir isim, açıklama, görüntü (veya farklı dijital varlık) ve diğer nitelikler gibi özelliklere sahip olmasına izin verir. İşte bir NFT'nin meta verilerini içeren [bir tokenURI örneği](https://gateway.pinata.cloud/ipfs/QmSvBcb4tjdFpajGJhbFAWeK3JAxCdNQLQtr6ZdiSi42V2). Bu öğreticide, React UI'ımızı kullanarak mevcut bir NFT'nin akıllı sözleşme basım fonksiyonunu çağırarak 2. bölüme odaklanacağız. -Bu öğreticide çağıracağımız ERC-721 NFT akıllı sözleşmesinin [bağlantısı](https://ropsten.etherscan.io/address/0x4C4a07F737Bf57F6632B6CAB089B78f62385aCaE). Bunu nasıl yaptığımızı öğrenmek istiyorsanız, diğer öğreticimiz ["Bir NFT Nasıl Oluşturulur"](https://docs.alchemyapi.io/alchemy/tutorials/how-to-create-an-nft)a göz atmanızı şiddetle tavsiye ederiz. +Bu öğreticide çağıracağımız ERC-721 NFT akıllı sözleşmesinin [bağlantısı buradadır](https://ropsten.etherscan.io/address/0x4C4a07F737Bf57F6632B6CAB089B78f62385aCaE). Bunu nasıl yaptığımızı öğrenmek isterseniz, diğer öğreticimiz olan ["Bir NFT Nasıl Oluşturulur"](https://www.alchemy.com/docs/how-to-create-an-nft) belgesine göz atmanızı önemle tavsiye ederiz. Harika, şimdi bir NFT yapmanın nasıl çalıştığını anladığımıza göre, başlangıç ​​dosyalarımızı klonlayalım! -## Başlangıç ​​dosyalarını klonlayın {#clone-the-starter-files} +## Başlangıç dosyalarını klonlayın {#clone-the-starter-files} -İlk olarak, bu proje için başlangıç ​​dosyalarını almak için [nft-minter-tutorial GitHub deposuna](https://github.com/alchemyplatform/nft-minter-tutorial) gidin. Bu depoyu yerel ortamınıza klonlayın.= +Öncelikle, bu projenin başlangıç dosyalarını almak için [nft-minter-tutorial GitHub deposuna](https://github.com/alchemyplatform/nft-minter-tutorial) gidin. Bu depoyu yerel ortamınıza klonlayın. Bu klonlanmış `nft-minter-tutorial` deposunu açtığınızda, iki klasör içerdiğini fark edeceksiniz: `minter-starter-files` ve `nft-minter`. -- `minter-starter-files`, bu proje için başlangıç ​​dosyalarını (esas olarak React UI'ını) içerir. Bu öğreticide, **bu dizinde çalışarak** bu kullanıcı arayüzünü Ethereum cüzdanınıza ve bir NFT akıllı sözleşmesine bağlayarak nasıl hayata geçireceğinizi öğreneceğiz. -- `nft-minter`, tamamlanmış öğreticinin tamamını içerir ve **takılırsanız** size **referans** olması için oradadır. +- `minter-starter-files` bu proje için başlangıç dosyalarını (temel olarak React kullanıcı arayüzünü) içerir. Bu öğreticide, bu kullanıcı arayüzünü Ethereum cüzdanınıza ve bir NFT akıllı sözleşmesine bağlayarak nasıl hayata geçireceğinizi öğrenirken **bu dizinde çalışacağız**. +- `nft-minter`, tamamlanmış öğreticinin tamamını içerir ve **takılırsanız referans olması için** oradadır. -Ardından, kod düzenleyicinizde `minter-starter-files` kopyanızı açın ve ardından `src` klasörünüze gidin. +Ardından, `minter-starter-files` kopyanızı kod düzenleyicinizde açın ve `src` klasörünüze gidin. -Yazacağımız tüm kodlar `src` klasörünün altında yer alacaktır. Projemize Web3 işlevselliği kazandırmak için `Minter.js` bileşenini düzenleyeceğiz ve ek javascript dosyaları yazacağız. +Yazacağımız tüm kodlar `src` klasörünün altında yer alacaktır. Projemize Web3 işlevselliği kazandırmak için `Minter.js` bileşenini düzenleyecek ve ek javascript dosyaları yazacağız. -## 2. Adım: Başlangıç ​​dosyalarımıza göz atın {#step-2-check-out-our-starter-files} +## Adım 2: Başlangıç dosyalarımıza göz atın {#step-2-check-out-our-starter-files} Kodlamaya başlamadan önce, başlangıç ​​dosyalarında bizim için nelerin sağlandığını kontrol etmek önemlidir. @@ -86,18 +80,18 @@ npm start Bunu yapmak, tarayıcınızda projemizin ön ucunu göreceğiniz http://localhost:3000/ adresini açmalıdır. 3 alandan oluşmalıdır: NFT'nizin varlığına bir bağlantı yerleştireceğiniz, NFT'nizin adını gireceğiniz ve bir açıklama sağlayabileceğiniz bir yer. -"Connect Wallet" (Cüzdanı Bağla) veya "Mint NFT" (NFT Bas) düğmelerinE tıklamayı denerseniz, çalışmadıklarını fark edeceksiniz. Çünkü hâlâ işlevlerini kodlamamız gerekiyor! :\) +"Connect Wallet" (Cüzdanı Bağla) veya "Mint NFT" (NFT Bas) düğmelerinE tıklamayı denerseniz, çalışmadıklarını fark edeceksiniz. Çünkü hâlâ işlevlerini kodlamamız gerekiyor! :) -### Minter.js bileşeni {#minter-js} +### `Minter.js` bileşeni {#minter-js} **NOT:** `nft-minter` klasöründe değil, `minter-starter-files` klasöründe olduğunuzdan emin olun! -Editörümüzdeki `src` klasörüne geri dönelim ve `Minter.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. +Düzenleyicimizde `src` klasörüne geri dönelim ve `Minter.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. Bu dosyamızın en üstünde, belirli olaylardan sonra güncelleyeceğimiz durum değişkenlerimiz var. ```javascript -//State variables +//Durum değişkenleri const [walletAddress, setWallet] = useState("") const [status, setStatus] = useState("") const [name, setName] = useState("") @@ -105,135 +99,135 @@ const [description, setDescription] = useState("") const [url, setURL] = useState("") ``` -React durum değişkenlerini veya durum kancalarını hiç duymadınız mı? [Bu](https://reactjs.org/docs/hooks-state.html) belgelere göz atın. +React durum değişkenlerini veya durum kancalarını hiç duymadınız mı? [Bu](https://legacy.reactjs.org/docs/hooks-state.html) belgelere göz atın. Değişkenlerin her birinin temsil ettiği şey: -- `walletAddress` - kullanıcının cüzdan adresini saklayan bir dize -- `status` - kullanıcı arayüzünün altında görüntülenecek bir mesaj içeren bir dize -- `name` - NFT'nin adını saklayan bir dize -- `description` - NFT'nin açıklamasını saklayan bir dize -- `url` - NFT'nin dijital varlığına bağlantı olan bir dize +- `walletAddress` - kullanıcının cüzdan adresini saklayan bir dizedir +- `status` - kullanıcı arayüzünün altında görüntülenecek bir mesaj içeren bir dizedir +- `name` - NFT'nin adını saklayan bir dizedir +- `description` - NFT'nin açıklamasını saklayan bir dizedir +- `url` - NFT'nin dijital varlığına bir bağlantı olan bir dizedir -Durum değişkenlerinden sonra, uygulanmamış üç fonksiyon göreceksiniz: `useEffect`, `connectWalletPressed` ve `onMintPressed`. Tüm bu fonksiyonların `async` olduğunu fark edeceksiniz, çünkü bu fonksiyonlarda eşzamansız API çağrıları yapacağız! Adları, fonksiyonlarıyla aynıdır: +Durum değişkenlerinden sonra, uygulanmamış üç fonksiyon göreceksiniz: `useEffect`, `connectWalletPressed` ve `onMintPressed`. Tüm bu fonksiyonların `async` olduğunu fark edeceksiniz, çünkü içlerinde eşzamansız API çağrıları yapacağız! Adları, fonksiyonlarıyla aynıdır: ```javascript useEffect(async () => { - //TODO: implement + //TODO: uygula }, []) const connectWalletPressed = async () => { - //TODO: implement + //TODO: uygula } const onMintPressed = async () => { - //TODO: implement + //TODO: uygula } ``` -- [`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 (3. satıra bakın), yalnızca bileşenin _ilk_ oluşturmasında çağrılır. Burada, bir cüzdanın zaten bağlı olup olmadığını yansıtacak şekilde kullanıcı arayüzünü güncellemek için cüzdan dinleyicimizi ve başka bir cüzdan fonksiyonunu çağıracağız. -- `connectWalletPressed` - bu fonksiyon, kullanıcının MetaMask cüzdanını merkeziyetsiz uygulamamıza bağlamak için çağrılır. -- `onMintPressed` - bu fonksiyon, kullanıcının NFT'sini basmak için çağrılır. +- [`useEffect`](https://legacy.reactjs.org/docs/hooks-effect.html) - bu, bileşeniniz oluşturulduktan sonra çağrılan bir React kancasıdır. İçine boş bir `[]` dizisi prop'u aktarıldığı için (bkz. 3. satır), yalnızca bileşenin _ilk_ render işleminde çağrılacaktır. Burada, bir cüzdanın zaten bağlı olup olmadığını yansıtacak şekilde kullanıcı arayüzünü güncellemek için cüzdan dinleyicimizi ve başka bir cüzdan fonksiyonunu çağıracağız. +- `connectWalletPressed` - bu fonksiyon, kullanıcının MetaMask cüzdanını merkeziyetsiz uygulamamıza bağlamak için çağrılacaktır. +- `onMintPressed` - bu fonksiyon, kullanıcının NFT'sini basmak için çağrılacaktır. -Bu dosyanın sonuna doğru, bileşenimizin kullanıcı arayüzü bulunuyor. Bu kodu dikkatli bir şekilde tararsanız, `url`, `ad` ve `description` durum değişkenlerimizi, bunlara denk gelen metin alanları değiştiğinde güncellediğimizi fark edeceksiniz. +Bu dosyanın sonuna doğru, bileşenimizin kullanıcı arayüzü bulunuyor. Bu kodu dikkatlice incelerseniz, ilgili metin alanlarındaki girdi değiştiğinde `url`, `name` ve `description` durum değişkenlerimizi güncellediğimizi fark edeceksiniz. -Ayrıca, sırasıyla `mintButton` ve `walletButton` kimliklerine sahip düğmelere tıklandığında `connectWalletPressed` ve `onMintPressed`'in çağrıldığını göreceksiniz. +Ayrıca, sırasıyla `mintButton` ve `walletButton` kimlikli düğmelere tıklandığında `connectWalletPressed` ve `onMintPressed` fonksiyonlarının çağrıldığını göreceksiniz. ```javascript -//the UI of our component +//bileşenimizin kullanıcı arayüzü return (


-

🧙‍♂️ Alchemy NFT Minter

+

🧙‍♂️ Alchemy NFT Basıcısı

- Simply add your asset's link, name, and description, then press "Mint." + Varlığınızın bağlantısını, adını ve açıklamasını ekleyin, ardından "Bas" düğmesine basın.

-

🖼 Link to asset:

+

🖼 Varlık bağlantısı:

setURL(event.target.value)} /> -

🤔 Name:

+

🤔 Ad:

setName(event.target.value)} /> -

✍️ Description:

+

✍️ Açıklama:

setDescription(event.target.value)} />

{status}

-
+ ) ``` Son olarak bu Minter bileşeninin nereye eklendiğine değinelim. -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, Minter bileşenimizin 7. satıra enjekte edildiğini göreceksiniz. +`App.js` dosyasına giderseniz, ki bu dosya React'te diğer tüm bileşenler için bir kapsayıcı görevi gören ana bileşendir, Minter bileşenimizin 7. satıra eklendiğini görürsünüz. -**Bu öğreticide, yalnızca `Minter.js file`'ı düzenleyeceğiz ve `src` klasörümüze dosyalar ekleyeceğiz.** +**Bu öğreticide, yalnızca `Minter.js` dosyasını düzenleyecek ve `src` klasörümüze dosyalar ekleyeceğiz.** Artık ne üzerinde çalıştığımızı anladığımıza göre, Ethereum cüzdanımızı oluşturalım! -## : Ethereum cüzdanınızı kurun {#set-up-your-ethereum-wallet} +## Ethereum cüzdanınızı kurun {#set-up-your-ethereum-wallet} Kullanıcıların akıllı sözleşmenizle etkileşime girebilmeleri için Ethereum cüzdanlarını merkeziyetsiz uygulamanıza bağlamaları gerekir. -### MetaMask'i indirin {#download-metamask} +### MetaMask'ı indirin {#download-metamask} -Bu öğretici için, Ethereum hesap adresinizi yönetmek için kullanılan tarayıcıda sanal bir cüzdan olan MetaMask'ı kullanacağız. Ethereum'daki işlemlerin nasıl çalıştığı hakkında daha fazla bilgi edinmek istiyorsanız, [bu sayfaya](/developers/docs/transactions/) bakın. +Bu öğretici için, Ethereum hesap adresinizi yönetmek için kullanılan tarayıcıda sanal bir cüzdan olan MetaMask'ı kullanacağız. Ethereum'daki işlemlerin nasıl çalıştığı hakkında daha fazla bilgi edinmek isterseniz, [bu sayfaya](/developers/docs/transactions/) göz atın. -[Buradan](https://metamask.io/download) ücretsiz olarak bir MetaMask hesabı indirebilir ve oluşturabilirsiniz. Bir hesap oluşturuyorsanız veya zaten bir hesabınız varsa, sağ üstteki "Ropsten Test Ağı"na geçtiğinizden emin olun \(böylece gerçek parayla uğraşmayız\). +MetaMask'ı [buradan](https://metamask.io/download) ücretsiz indirip bir hesap oluşturabilirsiniz. Bir hesap oluşturuyorsanız veya zaten bir hesabınız varsa, sağ üstteki "Ropsten Test Ağı"na geçtiğinizden emin olun \(böylece gerçek parayla uğraşmayız\). -### Bir Musluktan ether ekleyin {#add-ether-from-faucet} +### Musluktan ether ekleyin {#add-ether-from-faucet} -NFT'lerimizi basmak (veya Ethereum blok zincirindeki herhangi bir işlemi imzalamak) için biraz sahte Eth'e ihtiyacımız olacak. Eth almak için [Ropsten musluğuna](https://faucet.ropsten.be/) gidebilir ve Ropsten hesap adresinizi girip "Send Ropsten Eth"e (Ropsten Eth Gönder) tıklayabilirsiniz Kısa bir süre sonra MetaMask hesabınızda Eth'i görmelisiniz! +NFT'lerimizi basmak (veya Ethereum blok zincirindeki herhangi bir işlemi imzalamak) için biraz sahte Eth'e ihtiyacımız olacak. Eth almak için [Ropsten musluğuna](https://faucet.ropsten.be/) gidip Ropsten hesap adresinizi girebilir, ardından “Send Ropsten Eth” (Ropsten Eth Gönder) düğmesine tıklayabilirsiniz. Kısa bir süre sonra MetaMask hesabınızda Eth'i görmelisiniz! ### Bakiyenizi kontrol edin {#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! -## MetaMask'i kullanıcı arayüzünüze bağlayın {#connect-metamask-to-your-UI} +## MetaMask'ı kullanıcı arayüzünüze bağlayın {#connect-metamask-to-your-UI} Artık MetaMask cüzdanımız kurulduğuna göre, merkeziyetsiz uygulamamızı ona bağlayalım! -[MVC](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şturacağız ve ardından bu fonksiyonları ön ucumuza (Minter.js bileşenimiz) aktaracağız. +[MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) paradigmasına uymak istediğimiz için, merkeziyetsiz uygulamamızın mantığını, verilerini ve kurallarını yöneten fonksiyonlarımızı içeren ayrı bir dosya oluşturacak ve ardından bu fonksiyonları ön uca (Minter.js bileşenimiz) aktaracağız. ### `connectWallet` fonksiyonu {#connect-wallet-function} -Bunu yapmak için `src` dizininizde `utils` adında yeni bir klasör oluşturalım ve içine tüm cüzdan ve akıllı sözleşme etkileşim fonksiyonlarımızı içerecek `interact.js` adlı bir dosya ekleyelim. +Bunu yapmak için `src` dizininizde `utils` adında yeni bir klasör oluşturalım ve içine tüm cüzdan ve akıllı sözleşme etkileşim fonksiyonlarımızı içerecek olan `interact.js` adlı bir dosya ekleyelim. -`interact.js` dosyamızda, bir `connectWallet` fonksiyonu yazacağız ve bunu daha sonra içe aktarıp `Minter.js` bileşenimizde çağıracağız. +`interact.js` dosyamızda bir `connectWallet` fonksiyonu yazacağız, bunu daha sonra `Minter.js` bileşenimize aktarıp çağıracağız. -`interact.js` dosyanıza aşağıdakini ekleyin +`interact.js` dosyanıza aşağıdakileri ekleyin ```javascript export const connectWallet = async () => { @@ -243,7 +237,7 @@ export const connectWallet = async () => { method: "eth_requestAccounts", }) const obj = { - status: "👆🏽 Write a message in the text-field above.", + status: "👆🏽 Yukarıdaki metin alanına bir mesaj yazın.", address: addressArray[0], } return obj @@ -261,8 +255,7 @@ export const connectWallet = async () => {

{" "} 🦊 - You must install MetaMask, a virtual Ethereum wallet, in your - browser. + Tarayıcınıza sanal bir Ethereum cüzdanı olan MetaMask'i yüklemeniz gerekir.

@@ -276,24 +269,24 @@ export const connectWallet = async () => { İlk olarak, fonksiyonumuz tarayıcınızda `window.ethereum`'un etkin olup olmadığını kontrol eder. -`window.ethereum`, MetaMask ve diğer cüzdan sağlayıcıları tarafından enjekte edilen ve web sitelerinin kullanıcıların Ethereum hesaplarını talep etmesine izin veren küresel bir API'dir. Onaylanırsa, kullanıcının bağlı olduğu blok zincirlerinden verileri okuyabilir ve kullanıcının mesajları ve işlemleri 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. Onaylanırsa, kullanıcının bağlı olduğu blok zincirlerinden verileri okuyabilir ve kullanıcının mesajları ve işlemleri 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` _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. -**Yazdığımız fonksiyonların çoğu, durum değişkenlerimizi ve kullanıcı arayüzünü güncellemek için kullanabileceğimiz JSON nesnelerini döndürecek.** +**Yazdığımız fonksiyonların çoğu, durum değişkenlerimizi ve kullanıcı arayüzümüzü güncellemek için kullanabileceğimiz JSON nesneleri döndürecektir.** -Ş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ü kullanarak, `[window.ethereum.request({ method: "eth_requestAccounts" });](https://docs.metamask.io/guide/rpc-api.html#eth-requestaccounts)` öğesini çağırarak 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. +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. +- 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. 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. -### Minter.js UI Bileşeninize connectWallet fonksiyonu ekleyin {#add-connect-wallet} +### `connectWallet` fonksiyonunu `Minter.js` kullanıcı arayüzü bileşeninize ekleyin {#add-connect-wallet} -Şimdi bu `connectWallet` fonksiyonunu yazdığımıza göre, onu `Minter.js.` bileşenimize bağlayalım. +Bu `connectWallet` fonksiyonunu yazdığımıza göre, şimdi onu `Minter.js.` bileşenimize bağlayalım. -İlk olarak, `Minter.js` dosyasının en üstüne `import { connectWallet } from "./utils/interact.js";` öğesini ekleyerek fonksiyonumuzu `Minter.js` dosyamıza aktarmamız gerekecek. `Minter.js` dosyasının ilk 11 satırı şimdi şöyle görünmelidir: +İlk olarak, `Minter.js` dosyasının en üstüne `import { connectWallet } from \"./utils/interact.js\";` satırını ekleyerek fonksiyonumuzu `Minter.js` dosyamıza aktarmamız gerekecek. `Minter.js` dosyanızın ilk 11 satırı şimdi şöyle görünmelidir: ```javascript import { useEffect, useState } from "react"; @@ -301,7 +294,7 @@ import { connectWallet } from "./utils/interact.js"; const Minter = (props) => { - //State variables + //Durum değişkenleri const [walletAddress, setWallet] = useState(""); const [status, setStatus] = useState(""); const [name, setName] = useState(""); @@ -309,7 +302,7 @@ const Minter = (props) => { const [url, setURL] = useState(""); ``` -Ardından, `connectWalletPressed` fonksiyonumuzun içinde, içe aktarılan `connectWallet` fonksiyonumuzu şöyle çağıracağız: +Ardından, `connectWalletPressed` fonksiyonumuzun içinde, içe aktardığımız `connectWallet` fonksiyonunu şu şekilde çağıracağız: ```javascript const connectWalletPressed = async () => { @@ -319,11 +312,11 @@ const connectWalletPressed = async () => { } ``` -Fonksiyonlarımızın çoğunun `interact.js` dosyasındaki `Minter.js` bileşenimizden nasıl soyutlandığını gördünüz mü? Bu, M-V-C paradigmasına uymamız içindir! +İşlevselliğimizin çoğunun `interact.js` dosyasından `Minter.js` bileşenimizden nasıl soyutlandığına dikkat edin. 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, `Minter.js` ve `interact.js` dosyalarını kaydedelim ve şu ana kadarki kullanıcı arayüzümüzü test edelim. +Şimdi, `Minter.js` ve `interact.js` dosyalarını kaydedelim ve şimdiye kadarki kullanıcı arayüzümüzü test edelim. Tarayıcınızı localhost:3000 üzerinde açın ve sayfanın sağ üst köşesindeki "Connect Wallet" düğmesine basın. @@ -331,11 +324,11 @@ MetaMask yüklüyse, cüzdanınızı merkeziyetsiz uygulamanıza bağlamanız is Cüzdan düğmesinin artık adresinizin bağlı olduğunu yansıttığını görmelisiniz. -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... -Ama merak etmeyin! `getCurrentWalletConnected` adlı bir fonksiyonu uygulayarak bunu kolayca düzeltebiliriz; bu, bir adresin merkeziyetsiz uygulamamıza zaten bağlı olup olmadığını kontrol edecek ve kullanıcı arayüzünü buna göre güncelleyecektir! +Ama merak etmeyin! Bunu, bir adresin merkeziyetsiz uygulamamıza zaten bağlı olup olmadığını kontrol edecek ve kullanıcı arayüzümüzü buna göre güncelleyecek olan `getCurrentWalletConnected` adlı bir fonksiyonu uygulayarak kolayca düzeltebiliriz! -### GetCurrentWalletConnected fonksiyonu {#get-current-wallet} +### `getCurrentWalletConnected` fonksiyonu {#get-current-wallet} `interact.js` dosyanıza aşağıdaki `getCurrentWalletConnected` fonksiyonunu ekleyin: @@ -349,12 +342,12 @@ export const getCurrentWalletConnected = async () => { if (addressArray.length > 0) { return { address: addressArray[0], - status: "👆🏽 Write a message in the text-field above.", + status: "👆🏽 Yukarıdaki metin alanına bir mesaj yazın.", } } else { return { address: "", - status: "🦊 Connect to MetaMask using the top right button.", + status: "🦊 Sağ üstteki düğmeyi kullanarak MetaMask'e bağlanın.", } } } catch (err) { @@ -371,8 +364,7 @@ export const getCurrentWalletConnected = async () => {

{" "} 🦊 - You must install MetaMask, a virtual Ethereum wallet, in your - browser. + Tarayıcınıza sanal bir Ethereum cüzdanı olan MetaMask'i yüklemeniz gerekir.

@@ -384,9 +376,9 @@ export const getCurrentWalletConnected = async () => { Bu kod, az önce yazdığımız `connectWallet` fonksiyonuna _çok_ benzer. -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 `Minter.js` bileşenimizin `useEffect` fonksiyonunda çağıralım. +Bu fonksiyonu çalışırken görmek için `Minter.js` bileşenimizin `useEffect` fonksiyonunda çağıralım. `connectWallet` için yaptığımız gibi, bu fonksiyonu `interact.js` dosyamızdan `Minter.js` dosyamıza şu şekilde aktarmalıyız: @@ -394,11 +386,11 @@ Bu fonksiyonu çalışırken görmek için, onu `Minter.js` bileşenimizin `useE import { useEffect, useState } from "react" import { connectWallet, - getCurrentWalletConnected, //import here + getCurrentWalletConnected, //buraya aktar } from "./utils/interact.js" ``` -Şimdi onu `useEffect` fonksiyonumuzda çağırıyoruz: +Şimdi, onu sadece `useEffect` fonksiyonumuzda çağırıyoruz: ```javascript useEffect(async () => { @@ -408,15 +400,15 @@ 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. Bu kodu ekledikten sonra tarayıcı penceremizi yenilemeyi deneyin. 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-add-wallet-listener} +### `addWalletListener` fonksiyonunu uygulayın {#implement-add-wallet-listener} 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. -`Minter.js` dosyanıza aşağıdakine benzeyen bir `addWalletListener` fonksiyonu ekleyin: +`Minter.js` dosyanıza, aşağıdakine benzeyen bir `addWalletListener` fonksiyonu ekleyin: ```javascript function addWalletListener() { @@ -424,10 +416,10 @@ function addWalletListener() { window.ethereum.on("accountsChanged", (accounts) => { if (accounts.length > 0) { setWallet(accounts[0]) - setStatus("👆🏽 Write a message in the text-field above.") + setStatus("👆🏽 Yukarıdaki metin alanına bir mesaj yazın.") } else { setWallet("") - setStatus("🦊 Connect to MetaMask using the top right button.") + setStatus("🦊 Sağ üstteki düğmeyi kullanarak MetaMask'e bağlanın.") } }) } else { @@ -435,7 +427,7 @@ function addWalletListener() {

{" "} 🦊 - You must install MetaMask, a virtual Ethereum wallet, in your browser. + Tarayıcınıza sanal bir Ethereum cüzdanı olan MetaMask'i yüklemeniz gerekir.

) @@ -445,9 +437,9 @@ function addWalletListener() { Burada neler olduğunu hızlıca çözelim: -- İ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 olarak, onu `useEffect` fonksiyonumuzda çağırmalıyız: @@ -463,11 +455,11 @@ useEffect(async () => { İşte oldu! Cüzdan fonksiyonlarımızın tümünü programlamayı tamamladık! Cüzdanımız kurulduğuna göre, şimdi NFT'mizi nasıl basacağımızı bulalım! -## NFT Meta Verileri 101 {#nft-metadata-101} +## NFT Meta Verilerine Giriş {#nft-metadata-101} Bu öğreticinin 0. Adımında bahsettiğimiz NFT meta verilerini hatırlayın; dijital varlık, ad, açıklama ve diğer nitelikler gibi özelliklere sahip olmasını sağlayarak bir NFT'ye hayat verirler. -Bu meta verileri bir JSON nesnesi olarak yapılandırmamız ve saklamamız gerekecek, böylece akıllı sözleşmemizin `mintNFT` fonksiyonunu çağırırken `tokenURI` parametresi olarak iletebiliriz. +Bu meta verileri bir JSON nesnesi olarak yapılandırıp saklamamız gerekecek, böylece akıllı sözleşmemizin `mintNFT` fonksiyonunu çağırırken bunu `tokenURI` parametresi olarak geçirebiliriz. "Link to Asset" (Varlığa Bağlantı), "Name" (Ad) ve "Description" (Açıklama) alanlarındaki metin, NFT'mizin meta verisinin farklı özelliklerini oluşturacaktır. Bu meta verileri bir JSON nesnesi olarak biçimlendireceğiz, ancak bu JSON nesnesini nerede depolayabileceğimiz konusunda birkaç seçenek var: @@ -475,15 +467,15 @@ Bu meta verileri bir JSON nesnesi olarak yapılandırmamız ve saklamamız gerek - AWS veya Firebase gibi merkezi bir sunucuda depolayabiliriz. Ancak bu, merkeziyetsizlik anlayışımızı bozar. - Dağıtılmış bir dosya sisteminde veri depolamak ve paylaşmak için merkeziyetsiz bir protokol ve eşler arası ağ olan IPFS'yi kullanabiliriz. Bu protokol merkeziyetsiz ve ücretsiz olduğu için en iyi seçeneğimizdir! -Meta verilerimizi IPFS'de depolamak için, uygun bir IPFS API'si ve araç takımı olan [Pinata](https://pinata.cloud/)'yı kullanacağız. Bir sonraki adımda, bunun tam olarak nasıl yapılacağını açıklayacağız! +Meta verilerimizi IPFS'de depolamak için, kullanışlı bir IPFS API'si ve araç takımı olan [Pinata](https://pinata.cloud/)'yı kullanacağız. Bir sonraki adımda, bunun tam olarak nasıl yapılacağını açıklayacağız! -## Meta verilerinizi IPFS'ye sabitlemek için Pinata'yı kullanın {#use-pinata-to-pin-your-metadata-to-IPFS} +## Meta verilerinizi IPFS'e sabitlemek için Pinata'yı kullanın {#use-pinata-to-pin-your-metadata-to-IPFS} -[Pinata](https://pinata.cloud/) hesabınız yoksa, [buradan](https://app.pinata.cloud/auth/signup) ücretsiz bir hesap için kaydolun ve e-postanızla hesabınızı doğrulamak için adımları tamamlayın. +Bir [Pinata](https://pinata.cloud/) hesabınız yoksa, [buradan](https://app.pinata.cloud/auth/signup) ücretsiz bir hesap için kaydolun ve e-postanızı ve hesabınızı doğrulamak için adımları tamamlayın. ### Pinata API anahtarınızı oluşturun {#create-pinata-api-key} -[https://pinata.cloud/keys](https://pinata.cloud/keys) sayfasına gidin, ardından üst kısımdaki "New Key" (Yeni Anahtar) düğmesini seçin, Yönetici widget'ını ayarlayın etkinleştirin ve anahtarınızı adlandırın. +[https://pinata.cloud/keys](https://pinata.cloud/keys) sayfasına gidin, ardından üstteki "New Key" (Yeni Anahtar) düğmesini seçin, Yönetici aracını etkinleştirin ve anahtarınızı adlandırın. Ardından, API bilgilerinizi içeren bir açılır pencere gösterilecektir. Bunu güvenli bir yere koyduğunuzdan emin olun. @@ -493,19 +485,19 @@ Artık anahtarımız ayarlandığına göre onu kullanabilmek için projemize ek Pinata anahtarımızı ve sırrımızı bir ortam dosyasında güvenle saklayabiliriz. Proje dizininize [dotenv paketini](https://www.npmjs.com/package/dotenv) yükleyelim. -Terminalinizde \(yerel ana bilgisayarı çalıştırandan ayrı\) yeni bir sekme açın ve `minter-starter-files` klasöründe olduğunuzdan emin olun, ardından terminalinizde aşağıdaki komutu çalıştırın: +Terminalinizde yeni bir sekme açın (yerel ana bilgisayarı çalıştırandan ayrı) ve `minter-starter-files` klasöründe olduğunuzdan emin olun, ardından terminalinizde aşağıdaki komutu çalıştırın: ```text npm install dotenv --save ``` -Ardından, komut satırınıza aşağıdakileri girerek `minter-starter-files` kök dizininde bir `.env` dosyası oluşturun: +Ardından, komut satırınıza aşağıdakileri girerek `minter-starter-files` kök dizininizde bir `.env` dosyası oluşturun: ```javascript vim.env ``` -Bu, `.env` dosyanızı vim \(bir metin editörü\) içinde açacaktır. Kaydetmek için klavyenizdeki "esc" + ":" + "q" tuşlarına bu sırayla basın. +Bu, `.env` dosyanızı vim (bir metin düzenleyici) içinde açacaktır. Kaydetmek için klavyenizdeki "esc" + ":" + "q" tuşlarına bu sırayla basın. Ardından, VSCode'da `.env` dosyanıza gidin ve Pinata API anahtarınızı ve API sırrınızı şu şekilde ekleyin: @@ -516,11 +508,11 @@ REACT_APP_PINATA_SECRET = Dosyayı kaydettikten sonra JSON meta verilerinizi IPFS'ye yüklemek için fonksiyonu yazmaya başlamaya hazırsınız! -### PinJSONToIPFS'yi uygulayın {#pin-json-to-ipfs} +### `pinJSONToIPFS` fonksiyonunu uygulayın {#pin-json-to-ipfs} -Neyse ki, Pinata'nın [özellikle JSON verilerini IPFS'ye yüklemek için bir API'si](https://docs.pinata.cloud/api-reference/endpoint/ipfs/pin-json-to-ipfs#pin-json) ve axios örneğiyle bazı ufak değişiklikler yaparak birlikte kullanabileceğimiz uygun bir JavaScript'i var. +Neyse ki Pinata'nın, JSON verilerini IPFS'ye yüklemek için özel bir [API'si](https://docs.pinata.cloud/api-reference/endpoint/ipfs/pin-json-to-ipfs#pin-json) ve bazı küçük değişikliklerle kullanabileceğimiz, axios içeren kullanışlı bir JavaScript örneği var. -`utils` klasörünüzde `pinata.js` adında başka bir dosya oluşturalım ve ardından .env dosyasından Pinata sırrımızı ve anahtarımızı şu şekilde içe aktaralım: +`utils` klasörünüzde `pinata.js` adında başka bir dosya oluşturalım ve ardından Pinata sırrımızı ve anahtarımızı .env dosyasından şu şekilde içe aktaralım: ```javascript require("dotenv").config() @@ -539,7 +531,7 @@ const axios = require("axios") export const pinJSONToIPFS = async (JSONBody) => { const url = `https://api.pinata.cloud/pinning/pinJSONToIPFS` - //making axios POST request to Pinata ⬇️ + //Pinata'ya axios POST isteği yapılıyor ⬇️ return axios .post(url, JSONBody, { headers: { @@ -566,24 +558,24 @@ export const pinJSONToIPFS = async (JSONBody) => { Peki bu kod tam olarak ne yapıyor? -İlk olarak, Pinata'ya bir istekte bulunmak için kullanacağımız tarayıcı ve node.js için söz tabanlı bir HTTP istemcisi olan [axios](https://www.npmjs.com/package/axios)'u içe aktarır. +İlk olarak, Pinata'ya bir istekte bulunmak için kullanacağımız, tarayıcı ve node.js için promise tabanlı bir HTTP istemcisi olan [axios](https://www.npmjs.com/package/axios) içe aktarılır. -Ardından, `pinJSONToIPFS` API'lerine bir POST isteği yapmak için girişi olarak bir `JSONBody` ve başlığında Pinata api anahtarını ve sırrını alan eş zamansız fonksiyonumuz `pinJSONToIPFS`'ye sahibiz. +Ardından, `pinJSONToIPFS` API'lerine bir POST isteği yapmak için girişi olarak bir `JSONBody` ve başlığında Pinata api anahtarını ve sırrını alan eş zamansız `pinJSONToIPFS` fonksiyonumuz var. -- Bu POST isteği başarılı olursa, işlevimiz `success` boolean'ı true olarak ve meta verilerimizin sabitlendiği `pinataUrl` ile bir JSON nesnesi döndürür. Akıllı sözleşmemizin mint fonksiyonuna `tokenURI` girişi olarak döndürülen bu `pinataUrl` öğesini kullanacağız. -- Bu post isteği başarısız olursa, fonksiyonumuz `success` boolean'ı false olan bir JSON nesnesi ve hatamızı ileten bir `message` dizesi döndürür. +- Bu POST isteği başarılı olursa, fonksiyonumuz `success` boole değeri `true` olan ve meta verilerimizin sabitlendiği `pinataUrl`'yi içeren bir JSON nesnesi döndürür. Akıllı sözleşmemizin mint fonksiyonuna `tokenURI` girdisi olarak döndürülen bu `pinataUrl` öğesini kullanacağız. +- Bu post isteği başarısız olursa, fonksiyonumuz `success` boole değeri `false` olan bir JSON nesnesi ve hatamızı ileten bir `message` dizesi döndürür. -`connectWallet` fonksiyon dönüş türlerimizde olduğu gibi, durum değişkenlerimizi ve kullanıcı arayüzünü güncellemek amacıyla parametrelerini kullanabilmemiz için JSON nesneleri döndürüyoruz. +`connectWallet`fonksiyon dönüş türlerimizde olduğu gibi, durum değişkenlerimizi ve kullanıcı arayüzünü güncellemek amacıyla parametrelerini kullanabilmemiz için JSON nesneleri döndürüyoruz. ## Akıllı sözleşmenizi yükleyin {#load-your-smart-contract} Artık `pinJSONToIPFS` fonksiyonumuz aracılığıyla NFT meta verilerimizi IPFS'ye yüklemenin bir yolu olduğuna göre, `mintNFT` fonksiyonunu çağırabilmemiz için akıllı sözleşmemizin bir örneğini yüklemenin bir yoluna ihtiyacımız olacak. -Daha önce bahsettiğimiz gibi, bu öğreticide [bu mevcut NFT akıllı sözleşmesini](https://ropsten.etherscan.io/address/0x4C4a07F737Bf57F6632B6CAB089B78f62385aCaE) kullanacağız; ancak, bunu nasıl yaptığımızı öğrenmek veya kendiniz yapmak istiyorsanız, diğer ["Bir NFT Nasıl Oluşturulur?"](https://docs.alchemyapi.io/alchemy/tutorials/how-to-create-an-nft) öğreticimize göz atmanızı şiddetle tavsiye ederiz. +Daha önce de belirttiğimiz gibi, bu öğreticide [bu mevcut NFT akıllı sözleşmesini](https://ropsten.etherscan.io/address/0x4C4a07F737Bf57F6632B6CAB089B78f62385aCaE) kullanıyor olacağız; ancak, bunu nasıl yaptığımızı öğrenmek veya kendiniz yapmak isterseniz, diğer öğreticimiz olan ["Bir NFT Nasıl Oluşturulur."](https://www.alchemy.com/docs/how-to-create-an-nft) başlıklı yazımıza göz atmanızı şiddetle tavsiye ederiz. -### Sözleşme ABI'ı {#contract-abi} +### Sözleşme ABI'si {#contract-abi} -Dosyalarımızı yakından incelediyseniz, `src` dizinimizde bir `contract-abi.json` dosyası olduğunu fark etmişsinizdir. 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 ABI gereklidir. +Dosyalarımızı yakından incelediyseniz `src` dizinimizde bir `contract-abi.json` dosyası olduğunu fark etmişsinizdir. 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 ABI gereklidir. Ayrıca Ethereum blok zincirine bağlanmak ve akıllı sözleşmemizi yüklemek için bir Alchemy API anahtarına ve Alchemy Web3 API'sine ihtiyacımız olacak. @@ -591,7 +583,7 @@ Ayrıca Ethereum blok zincirine bağlanmak ve akıllı sözleşmemizi yüklemek Henüz bir Alchemy hesabınız yoksa, [buradan ücretsiz kaydolun.](https://alchemy.com/?a=eth-org-nft-minter) -Bir Alchemy hesabı oluşturduktan sonra, bir uygulama oluşturarak bir API anahtarı oluşturabilirsiniz. Bu, Ropsten test ağına istekte bulunmamıza izin verecektir. +Bir Alchemy hesabı oluşturduktan sonra, bir uygulama yaratarak bir API anahtarı oluşturabilirsiniz. Bu, Ropsten test ağına istekte bulunmamıza izin verecektir. İ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. @@ -601,7 +593,7 @@ Uygulamanıza bir ad verin (biz, "İlk NFT'm!"i seçtik), kısa bir açıklama y Harika, şimdi HTTP Alchemy API URL'mizi oluşturduğumuza göre, onu panonuza kopyalayın... -…ve sonra onu `.env` dosyamıza ekleyelim. Toplamda, .env dosyanız şöyle görünmelidir: +…ve sonra onu .env dosyamıza ekleyelim. Toplamda, .env dosyanız şöyle görünmelidir: ```text REACT_APP_PINATA_KEY = @@ -609,11 +601,11 @@ REACT_APP_PINATA_SECRET = REACT_APP_ALCHEMY_KEY = https://eth-ropsten.alchemyapi.io/v2/ ``` -Artık sözleşme ABI'ımız ve Alchemy API anahtarımız olduğuna göre, [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) kullanarak akıllı sözleşmemizi yüklemeye hazırız. +Artık sözleşme ABI'mız ve Alchemy API anahtarımız olduğuna göre [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) kullanarak akıllı sözleşmemizi yüklemeye hazırız. ### Alchemy Web3 uç noktanızı ve sözleşmenizi ayarlayın {#setup-alchemy-endpoint} -Öncelikle, henüz sahip değilseniz ana dizine giderek [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3)'ü yüklemeniz gerekir: terminalde `nft-minter-tutorial`: +Öncelikle, henüz sahip değilseniz terminalde ana dizine giderek [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3)'ü yüklemeniz gerekir: `nft-minter-tutorial`: ```text cd .. @@ -629,7 +621,7 @@ const { createAlchemyWeb3 } = require("@alch/alchemy-web3") const web3 = createAlchemyWeb3(alchemyKey) ``` -[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 sözleşme ABI'ımızı ve sözleşme adresimizi dosyamıza ekleyelim. @@ -645,72 +637,72 @@ const contractAddress = "0x4C4a07F737Bf57F6632B6CAB089B78f62385aCaE" Her ikisine de sahip olduğumuzda, mint fonksiyonumuzu kodlamaya başlamaya hazırız! -## mintNFT fonksiyonunu uygulayın {#implement-the-mintnft-function} +## `mintNFT` fonksiyonunu uygulayın {#implement-the-mintnft-function} `interact.js` dosyanızın içinde, NFT'mizi aynı adla basacak olan `mintNFT` fonksiyonumuzu tanımlayalım. Çok sayıda eş zamansız çağrı yapacağımız için \(meta verilerimizi IPFS'ye sabitlemek için Pinata'ya, akıllı sözleşmemizi yüklemek için Alchemy Web3'e ve işlemlerimizi imzalamak için MetaMask'e\), fonksiyonumuz da eş zamansız olacaktır. -Fonksiyonumuzun üç girdisi, dijital varlığımızın `url`'si, `name`'i ve `description`'ı olacaktır. `connectWallet` fonksiyonunun altına aşağıdaki fonksiyon imzasını ekleyin: +Fonksiyonumuza üç girdi, dijital varlığımızın `url`'si, `name` ve `description` olacaktır. `connectWallet` fonksiyonunun altına aşağıdaki fonksiyon imzasını ekleyin: ```javascript export const mintNFT = async (url, name, description) => {} ``` -### Girdi hatası işleme {#input-error-handling} +### Giriş hata yönetimi {#input-error-handling} Doğal olarak, girdi parametrelerimiz doğru değilse bu fonksiyondan çıkmak için fonksiyonun başlangıcında bir tür girdi hatası işlemeye sahip olmak mantıklıdır. Fonksiyonumuzun içine aşağıdaki kodu ekleyelim: ```javascript export const mintNFT = async (url, name, description) => { - //error handling + //hata yönetimi if (url.trim() == "" || name.trim() == "" || description.trim() == "") { return { success: false, - status: "❗Please make sure all fields are completed before minting.", + status: "❗Lütfen basım yapmadan önce tüm alanların doldurulduğundan emin olun.", } } } ``` -Girdi parametrelerinden herhangi biri boş bir dizeyse, o zaman `success` boolean'ın false olduğu bir JSON nesnesi döndürürüz ve `status` dizesi, Kullanıcı Arayüzündeki tüm alanların eksiksiz olması gerektiğini aktarır. +Esasen, girdi parametrelerinden herhangi biri boş bir dizeyse, `success` boole değerinin `false` olduğu bir JSON nesnesi döndürürüz ve `status` dizesi, kullanıcı arayüzümüzdeki tüm alanların doldurulması gerektiğini belirtir. -### Meta verileri IPFS'ye yükleyin {#upload-metadata-to-ipfs} +### Meta verileri IPFS'e yükleyin {#upload-metadata-to-ipfs} Meta verilerimizin doğru şekilde biçimlendirildiğini öğrendikten sonraki adım, onu bir JSON nesnesi olarak paketlemek ve yazdığımız `pinJSONToIPFS` aracılığıyla IPFS'ye yüklemektir! -Bunu yapmak için önce `pinJSONToIPFS` fonksiyonunu `interact.js` dosyamıza aktarmamız gerekiyor. `interact.js` dosyasının en üstüne şunu ekleyelim: +Bunu yapmak için önce `pinJSONToIPFS` fonksiyonunu `interact.js` dosyamıza aktarmamız gerekiyor. `interact.js`'nin en üstüne şunu ekleyelim: ```javascript import { pinJSONToIPFS } from "./pinata.js" ``` -`pinJSONToIPFS` öğesinin bir JSON gövdesi aldığını hatırlayın. Bu nedenle onu çağırmadan önce `url`, `name` ve `description` parametrelerimizi bir JSON nesnesi olarak biçimlendirmemiz gerekecek. +`pinJSONToIPFS`'in bir JSON gövdesi aldığını hatırlayın. Bu nedenle onu çağırmadan önce `url`, `name` ve `description` parametrelerimizi bir JSON nesnesi olarak biçimlendirmemiz gerekecek. -`metadata` adında bir JSON nesnesi oluşturmak için kodumuzu güncelleyelim ve ardından bu `metadata` parametresiyle `pinJSONToIPFS`'a bir çağrı yapalım: +Şimdi `metadata` adında bir JSON nesnesi oluşturmak için kodumuzu güncelleyelim ve ardından bu `metadata` parametresiyle `pinJSONToIPFS`'a bir çağrı yapalım: ```javascript export const mintNFT = async (url, name, description) => { - //error handling + //hata yönetimi if (url.trim() == "" || name.trim() == "" || description.trim() == "") { return { success: false, - status: "❗Please make sure all fields are completed before minting.", + status: "❗Lütfen basım yapmadan önce tüm alanların doldurulduğundan emin olun.", } } - //make metadata + //meta veri oluştur const metadata = new Object() metadata.name = name metadata.image = url metadata.description = description - //make pinata call + //pinata çağrısı yap const pinataResponse = await pinJSONToIPFS(metadata) if (!pinataResponse.success) { return { success: false, - status: "😢 Something went wrong while uploading your tokenURI.", + status: "😢 tokenURI'niz yüklenirken bir şeyler ters gitti.", } } const tokenURI = pinataResponse.pinataUrl @@ -719,7 +711,7 @@ export const mintNFT = async (url, name, description) => { Dikkat edin, `pinJSONToIPFS(metadata)` çağrımızın yanıtını `pinataResponse` nesnesinde saklıyoruz. Ardından, bu nesneyi herhangi bir hata için ayrıştırırız. -Bir hata varsa, `success` boolean'ın false olduğu bir JSON nesnesi döndürürüz ve `status` dizemiz çağrımızın başarısız olduğunu aktarır. Aksi takdirde, `pinataURL`'u `pinataResponse`'tan çıkarırız ve onu `tokenURI` değişkenimiz olarak saklarız. +Bir hata varsa, `success` boole değerinin `false` olduğu bir JSON nesnesi döndürürüz ve `status` dizemiz çağrımızın başarısız olduğunu belirtir. Aksi takdirde, `pinataURL`'u `pinataResponse`'tan çıkarır ve onu `tokenURI` değişkenimiz olarak saklarız. Şimdi dosyamızın başında başlattığımız Alchemy Web3 API'sini kullanarak akıllı sözleşmemizi yükleme zamanı. Sözleşmeyi `window.contract` global değişkeninde ayarlamak için `mintNFT` fonksiyonunun altına aşağıdaki kod satırını ekleyin: @@ -730,16 +722,16 @@ window.contract = await new web3.eth.Contract(contractABI, contractAddress) `mintNFT` fonksiyonumuza eklenecek son şey Ethereum işlemimizdir: ```javascript -//set up your Ethereum transaction +//Ethereum işleminizi ayarlayın const transactionParameters = { - to: contractAddress, // Required except during contract publications. - from: window.ethereum.selectedAddress, // must match user's active address. + to: contractAddress, // Sözleşme yayınları dışında gereklidir. + from: window.ethereum.selectedAddress, // kullanıcının aktif adresiyle eşleşmelidir. data: window.contract.methods .mintNFT(window.ethereum.selectedAddress, tokenURI) - .encodeABI(), //make call to NFT smart contract + .encodeABI(), //NFT akıllı sözleşmesine çağrı yapın } -//sign the transaction via MetaMask +//işlemi MetaMask aracılığıyla imzalayın try { const txHash = await window.ethereum.request({ method: "eth_sendTransaction", @@ -748,13 +740,13 @@ try { return { success: true, status: - "✅ Check out your transaction on Etherscan: https://ropsten.etherscan.io/tx/" + + "✅ İşleminizi Etherscan'de kontrol edin: https://ropsten.etherscan.io/tx/" + txHash, } } catch (error) { return { success: false, - status: "😥 Something went wrong: " + error.message, + status: "😥 Bir şeyler ters gitti: " + error.message, } } ``` @@ -762,54 +754,54 @@ try { Ethereum işlemlerine zaten aşinaysanız, yapının gördüklerinize oldukça benzer olduğunu fark edeceksiniz. - İlk olarak işlem parametrelerimizi oluşturuyoruz. - - `to` alıcı adresini belirtir \(akıllı sözleşmemiz\) - - `from`, işlemi imzalayanı belirtir \(kullanıcının MetaMask'a bağlı adresi: `window.ethereum.selectedAddress`\) - - `data`, `tokenURI`'ımızı ve kullanıcının cüzdan adresi olan `window.ethereum.selectedAddress`'i girdi olarak alan akıllı sözleşme `mintNFT` yöntemimize yapılan çağrıyı içerir -- Ardından, MetaMask'ten işlemi imzalamasını istediğimiz `window.ethereum.request` adlı bir bekleme çağrısı yaparız. Dikkat edin, bu istekte eth yöntemimizi \(eth_SentTransaction\) belirtiyoruz ve `transactionParameters`'ımızı aktarıyoruz. 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, `success` boolean'ının true olarak ayarlandığı bir JSON nesnesi döndürür ve `status` dizesi kullanıcıdan işlemleri hakkında daha fazla bilgi için Etherscan'i kontrol etmesini ister. - - İşlem başarısız olursa fonksiyon, `success` boolean'ının false olarak ayarlandığı bir JSON nesnesi döndürür ve `status` dizesi hata mesajını aktarır. + - `to` alıcı adresini belirtir (akıllı sözleşmemiz) + - `from`, işlemi imzalayanı belirtir (kullanıcının MetaMask'a bağlı adresi: `window.ethereum.selectedAddress`) + - `data`, girdi olarak `tokenURI`'ımızı ve kullanıcının cüzdan adresi olan `window.ethereum.selectedAddress`'ı alan akıllı sözleşme `mintNFT` yöntemimize yapılan çağrıyı içerir +- Ardından, MetaMask'ten işlemi imzalamasını istediğimiz bir `window.ethereum.request` bekleme çağrısı yaparız. Dikkat edin, bu istekte eth yöntemimizi (`eth_SentTransaction`) belirtiyor ve `transactionParameters`'ımızı aktarıyoruz. 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, `success` boole değerinin `true` olarak ayarlandığı bir JSON nesnesi döndürür ve `status` dizesi kullanıcıdan işlemleri hakkında daha fazla bilgi için Etherscan'i kontrol etmesini ister. + - İşlem başarısız olursa fonksiyon, `success` boole değerinin `false` olarak ayarlandığı bir JSON nesnesi döndürür ve `status` dizesi hata mesajını aktarır. -Toplamda, `mintNFT` fonksiyonumuz şöyle görünmelidir: +Sonuç olarak, `mintNFT` fonksiyonumuz şöyle görünmelidir: ```javascript export const mintNFT = async (url, name, description) => { - //error handling + //hata yönetimi if (url.trim() == "" || name.trim() == "" || description.trim() == "") { return { success: false, - status: "❗Please make sure all fields are completed before minting.", + status: "❗Lütfen basım yapmadan önce tüm alanların doldurulduğundan emin olun.", } } - //make metadata + //meta veri oluştur const metadata = new Object() metadata.name = name metadata.image = url metadata.description = description - //pinata pin request + //pinata pin isteği const pinataResponse = await pinJSONToIPFS(metadata) if (!pinataResponse.success) { return { success: false, - status: "😢 Something went wrong while uploading your tokenURI.", + status: "😢 tokenURI'niz yüklenirken bir şeyler ters gitti.", } } const tokenURI = pinataResponse.pinataUrl - //load smart contract + //akıllı sözleşmeyi yükle window.contract = await new web3.eth.Contract(contractABI, contractAddress) //loadContract(); - //set up your Ethereum transaction + //Ethereum işleminizi ayarlayın const transactionParameters = { - to: contractAddress, // Required except during contract publications. - from: window.ethereum.selectedAddress, // must match user's active address. + to: contractAddress, // Sözleşme yayınları dışında gereklidir. + from: window.ethereum.selectedAddress, // kullanıcının aktif adresiyle eşleşmelidir. data: window.contract.methods .mintNFT(window.ethereum.selectedAddress, tokenURI) - .encodeABI(), //make call to NFT smart contract + .encodeABI(), //NFT akıllı sözleşmesine çağrı yapın } - //sign transaction via MetaMask + //işlemi MetaMask aracılığıyla imzala try { const txHash = await window.ethereum.request({ method: "eth_sendTransaction", @@ -818,21 +810,21 @@ export const mintNFT = async (url, name, description) => { return { success: true, status: - "✅ Check out your transaction on Etherscan: https://ropsten.etherscan.io/tx/" + + "✅ İşleminizi Etherscan'de kontrol edin: https://ropsten.etherscan.io/tx/" + txHash, } } catch (error) { return { success: false, - status: "😥 Something went wrong: " + error.message, + status: "😥 Bir şeyler ters gitti: " + error.message, } } } ``` -Bu dev bir fonksiyon! Şimdi, `mintNFT` fonksiyonumuzu `Minter.js` bileşenimize bağlamamız gerekiyor... +Bu dev bir fonksiyon! Şimdi, sadece `mintNFT` fonksiyonumuzu `Minter.js` bileşenimize bağlamamız gerekiyor... -## MintNFT'yi Minter.js ön ucumuza bağlayın {#connect-our-frontend} +## `mintNFT`'yi `Minter.js` ön ucumuza bağlayın {#connect-our-frontend} `Minter.js` dosyanızı açın ve en üstteki `import { connectWallet, getCurrentWalletConnected } from "./utils/interact.js";` satırını şu şekilde güncelleyin: @@ -844,7 +836,7 @@ import { } from "./utils/interact.js" ``` -Son olarak, içe aktarılan `mintNFT` fonksiyonunuza bekleme çağrısı yapmak için `onMintPressed` fonksiyonunu uygulayın ve işlemimizin başarılı mı yoksa başarısız mı olduğunu yansıtmak için `status` durum değişkenini güncelleyin: +Son olarak, içe aktarılan `mintNFT`fonksiyonunuza bekleme çağrısı yapmak için `onMintPressed` fonksiyonunu uygulayın ve işlemimizin başarılı mı yoksa başarısız mı olduğunu yansıtmak için `status` durum değişkenini güncelleyin: ```javascript const onMintPressed = async () => { @@ -855,11 +847,11 @@ const onMintPressed = async () => { ## NFT'nizi yayındaki bir web sitesinde yayınlayın {#deploy-your-NFT} -Kullanıcıların etkileşim kurması için projenizi yayınlamaya hazır mısınız? Minter'ınızı canlı bir web sitesine dağıtmak için [bu öğreticiye](https://docs.alchemy.com/alchemy/tutorials/nft-minter/how-do-i-deploy-nfts-online) göz atın. +Kullanıcıların etkileşim kurması için projenizi yayınlamaya hazır mısınız? Minter'ınızı canlı bir web sitesinde dağıtmak için [bu öğreticiye](https://docs.alchemy.com/alchemy/tutorials/nft-minter/how-do-i-deploy-nfts-online) göz atın. Son bir adım... -## Blok zinciri dünyasını kasıp kavurun {#take-the-blockchain-world-by-storm} +## Blokzincir dünyasını kasıp kavurun {#take-the-blockchain-world-by-storm} Şaka yapıyorum, öğreticiyi tamamladınız! @@ -869,6 +861,6 @@ Son bir adım... - Ön ucunuzdan akıllı sözleşme yöntemlerini arama - MetaMask kullanarak işlemleri imzalama -Muhtemelen, cüzdanınızda merkeziyetsiz uygulamanız aracılığıyla basılan NFT'leri gösterebilmek istersiniz. Bu nedenle [NFT'nizi Cüzdanınızda Görüntüleme](https://docs.alchemyapi.io/alchemy/tutorials/how-to-write-and-deploy-a-nft-smart-contract/how-to-view-your-nft-in-your-wallet) adlı hızlı öğreticimize göz atmayı unutmayın! +Muhtemelen, merkeziyetsiz uygulamanız aracılığıyla basılan NFT'leri cüzdanınızda sergilemek istersiniz — bu yüzden hızlı öğreticimiz olan [NFT'nizi Cüzdanınızda Nasıl Görüntülersiniz](https://www.alchemy.com/docs/how-to-view-your-nft-in-your-mobile-wallet) başlıklı yazımıza göz atmayı unutmayın! Ve her zaman olduğu gibi, herhangi bir sorunuz olursa [Alchemy Discord](https://discord.gg/gWuC7zB)'da size yardım etmeye hazırız. Bu öğreticideki kavramları gelecekteki projelerinize nasıl uygulayacağınızı görmek için sabırsızlanıyoruz! diff --git a/public/content/translations/tr/developers/tutorials/optimism-std-bridge-annotated-code/index.md b/public/content/translations/tr/developers/tutorials/optimism-std-bridge-annotated-code/index.md index 9fb38aa2b01..826e53ee6f2 100644 --- a/public/content/translations/tr/developers/tutorials/optimism-std-bridge-annotated-code/index.md +++ b/public/content/translations/tr/developers/tutorials/optimism-std-bridge-annotated-code/index.md @@ -1,21 +1,24 @@ --- title: "Optimism standart köprü sözleşmesine genel bakış" -description: Optimism için standart köprü nasıl çalışır? Neden bu şekilde çalışıyor? +description: "Optimism için standart köprü nasıl çalışır? Neden bu şekilde çalışıyor?" author: Ori Pomerantz -tags: - - "solidity" - - "köprü" - - "katman 2" -skill: advanced +tags: [ "katılık", "köprü", "katman 2" ] +skill: intermediate published: 2022-03-30 lang: tr --- -[Optimism](https://www.optimism.io/), bir [İyimser Toplamadır](/developers/docs/scaling/optimistic-rollups/). İyimser toplamalar, işlemleri Ethereum Mainnet'ten (katman 1 veya K1 olarak da bilinir) çok daha düşük bir fiyata işleyebilir çünkü işlemler ağdaki her düğüm yerine yalnızca birkaç düğüm tarafından işlenir. Aynı zamanda, verilerin tümü K1'e yazılır, böylece her şey kanıtlanabilir ve Mainnet'in tüm bütünlük ve kullanılabilirlik garantileriyle yeniden yapılandırılabilir. +[Optimism](https://www.optimism.io/) bir [İyimser Toplama](/developers/docs/scaling/optimistic-rollups/) türüdür. +İyimser toplamalar, işlemler ağdaki her düğüm yerine yalnızca birkaç düğüm tarafından işlendiği için Ethereum Ana Ağı'ndan (katman 1 veya K1 olarak da bilinir) çok daha düşük bir fiyata işlem yapabilir. +Aynı zamanda, verilerin tümü K1'e yazılır, böylece her şey Ana Ağ'ın tüm bütünlük ve kullanılabilirlik garantileriyle kanıtlanabilir ve yeniden yapılandırılabilir. -Optimism'de (veya başka herhangi bir K2'de) K1 varlıklarını kullanmak için varlıkların [köprülenmesi](/bridges/#prerequisites) gerekir. Kullanıcıların varlıkları (ETH ve [ERC-20 token'ları](/developers/docs/standards/tokens/erc-20/) en yaygın olanlardır) L1'de kilitlemesi ve L2'de eş değer varlıklar alması bunu başarmanın yollarından biridir. Nihayetinde bu varlıkları alan kişiler bunları tekrar K1'e köprülemek isteyebilir. Bunu yaparken, varlıklar K2'de yakılır ve ardından K1'de kullanıcıya geri verilir. +Optimism'de (veya başka herhangi bir K2'de) K1 varlıklarını kullanmak için varlıkların [köprülenmesi](/bridges/#prerequisites) gerekir. +Bunu başarmanın yollarından biri, kullanıcıların K1'de varlıkları (en yaygın olanları ETH ve [ERC-20 token'larıdır](/developers/docs/standards/tokens/erc-20/)) kilitlemesi ve K2'de kullanmak üzere eşdeğer varlıklar almasıdır. +Nihayetinde, bu varlıkları elinde bulunduranlar onları K1'e geri köprülemek isteyebilir. +Bunu yaparken, varlıklar K2'de yakılır ve ardından K1'de kullanıcıya geri verilir. -[Optimism standart köprüsü](https://docs.optimism.io/app-developers/bridging/standard-bridge) bu şekilde çalışır. Bu makalede, nasıl çalıştığını görmek için bu köprünün kaynak kodunu gözden geçireceğiz ve onu iyi yazılmış bir Solidity kodu örneği olarak inceleyeceğiz. +[Optimism standart köprüsü](https://docs.optimism.io/app-developers/bridging/standard-bridge) bu şekilde çalışır. +Bu makalede, nasıl çalıştığını görmek için söz konusu köprünün kaynak kodunu gözden geçirecek ve onu, iyi yazılmış bir Solidity kodu örneği olarak inceleyeceğiz. ## Kontrol akışları {#control-flows} @@ -28,57 +31,59 @@ Köprünün iki ana akışı vardır: #### Katman 1 {#deposit-flow-layer-1} -1. Bir ERC-20 yatırılıyorsa, yatırımcı köprüye yatırılan tutarı harcaması için bir ödenek verir -2. Yatıran, K1 köprüsünü (`depositERC20`, `depositERC20To`, `depositETH` veya `depositETHTo`) çağırır -3. K1 köprüsü, köprülenen varlığın sahibi olur - - ETH: Varlık, çağrının bir parçası olarak yatıran tarafından aktarılır - - ERC-20: Varlık, yatıran tarafından sağlanan ödenek kullanılarak köprü tarafından kendisine devredilir -4. K1 köprüsü, K2 köprüsünde `finalizeDeposit`'i çağırmak için etki alanları arası mesaj mekanizmasını kullanır +1. Bir ERC-20 yatırılırken, yatıran kişi köprüye yatırılan tutarı harcaması için bir izin verir. +2. Yatıran kişi K1 köprüsünü çağırır (`depositERC20`, `depositERC20To`, `depositETH` veya `depositETHTo`) +3. K1 köprüsü köprülenen varlığın mülkiyetini alır. + - ETH: Varlık, çağrının bir parçası olarak yatıran kişi tarafından aktarılır. + - ERC-20: Varlık, yatıran kişi tarafından sağlanan izni kullanarak köprü tarafından kendisine aktarılır. +4. K1 köprüsü, K2 köprüsünde `finalizeDeposit` fonksiyonunu çağırmak için alanlar arası mesaj mekanizmasını kullanır. #### Katman 2 {#deposit-flow-layer-2} -5. Katman 2 köprüsü, `finalizeDeposit` çağrısının meşru olduğunu doğrular: - - Etki alanları arası mesaj sözleşmesinden geldi - - Aslen K1'deki köprüdendi +5. K2 köprüsü, `finalizeDeposit` çağrısının meşru olduğunu doğrular: + - Alanlar arası mesaj sözleşmesinden gelmiştir + - Aslen K1'deki köprüden gelmiştir 6. K2 köprüsü, K2 üzerindeki ERC-20 token sözleşmesinin doğru olup olmadığını kontrol eder: - - K2 sözleşmesi, K1 karşılığının, token'ların K1'den geldiği ile aynı olduğunu bildiriyor - - K2 sözleşmesi, doğru arayüzü ([ERC-165 kullanarak](https://eips.ethereum.org/EIPS/eip-165)) desteklediğini bildirir. -7. K2 sözleşmesi doğruysa, uygun adrese uygun sayıda token basması için onu çağırın. Değilse, kullanıcının K1'deki token'ları talep etmesine izin vermek için bir para çekme işlemi başlatın. + - K2 sözleşmesi, K1'deki karşılığının, token'ların K1'den geldiği sözleşmeyle aynı olduğunu bildirir. + - K2 sözleşmesi, doğru arayüzü desteklediğini bildirir ([ERC-165](https://eips.ethereum.org/EIPS/eip-165) kullanarak). +7. K2 sözleşmesi doğruysa, uygun adrese uygun sayıda token basması için bu sözleşme çağrılır. Değilse, kullanıcının K1'deki token'ları talep etmesine olanak tanıyan bir çekme işlemi başlatılır. ### Çekme akışı {#withdrawal-flow} #### Katman 2 {#withdrawal-flow-layer-2} -1. Çeken kişi K2 köprüsünü çağırır (`draw` veya `withdrawTo`) -2. K2 köprüsü, `msg.sender`'a ait uygun sayıda token'ı yakar -3. K2 köprüsü, K1 köprüsünde `finalizeETHWithdrawal` veya `finalizeERC20Withdrawal`'ı çağırmak için etki alanları arası mesaj mekanizmasını kullanır +1. Çekme işlemini yapan kişi K2 köprüsünü çağırır (`withdraw` veya `withdrawTo`) +2. K2 köprüsü, `msg.sender`'a ait uygun sayıda token'ı yakar. +3. K2 köprüsü, K1 köprüsünde `finalizeETHWithdrawal` veya `finalizeERC20Withdrawal` fonksiyonlarını çağırmak için alanlar arası mesaj mekanizmasını kullanır. #### Katman 1 {#withdrawal-flow-layer-1} 4. K1 köprüsü, `finalizeETHWithdrawal` veya `finalizeERC20Withdrawal` çağrısının meşru olduğunu doğrular: - - Etki alanları arası mesaj mekanizmasından geldi - - Aslen K2'deki köprüdendi -5. K1 köprüsü, uygun varlığı (ETH veya ERC-20) uygun adrese aktarır + - Alanlar arası mesaj mekanizmasından gelmiştir + - Aslen K2'deki köprüden gelmiştir +5. K1 köprüsü, uygun varlığı (ETH veya ERC-20) uygun adrese aktarır. ## Katman 1 kodu {#layer-1-code} -Bu, Ethereum Mainnet K1 üzerinde çalışan koddur. +Bu, K1'de, yani Ethereum Ana Ağı'nda çalışan koddur. ### IL1ERC20Bridge {#IL1ERC20Bridge} -[Bu arayüz burada tanımlanmıştır](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L1/messaging/IL1ERC20Bridge.sol). ERC-20 token'larını köprülemek için gereken fonksiyonları ve tanımları içerir. +[Bu arayüz burada tanımlanmıştır](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L1/messaging/IL1ERC20Bridge.sol). +ERC-20 token'larını köprülemek için gereken fonksiyonları ve tanımları içerir. ```solidity // SPDX-License-Identifier: MIT ``` -[Optimism'in kodunun çoğu MIT lisansı altında yayınlandı](https://help.optimism.io/hc/en-us/articles/4411908707995-What-software-license-does-Optimism-use-). +[Optimism'in kodlarının çoğu MIT lisansı altında yayınlanmıştır](https://help.optimism.io/hc/en-us/articles/4411908707995-What-software-license-does-Optimism-use-). ```solidity pragma solidity >0.5.0 <0.9.0; ``` -Yazım sırasında Solidity'nin en son sürümü 0.8.12'dir. Sürüm 0.9.0 yayınlanana kadar, bu kodun onunla uyumlu olup olmadığını bilemeyiz. +Bu yazı yazıldığı sırada Solidity'nin en son sürümü 0.8.12'dir. +Sürüm 0.9.0 yayınlanana kadar bu kodun onunla uyumlu olup olmadığını bilemeyiz. ```solidity /** @@ -86,20 +91,23 @@ Yazım sırasında Solidity'nin en son sürümü 0.8.12'dir. Sürüm 0.9.0 yayı */ interface IL1ERC20Bridge { /********** - * Events * + * Olaylar * **********/ event ERC20DepositInitiated( ``` -Optimism köprü terminolojisinde _yatırmak_, K1'den K2'ye transfer anlamına, _çekmek_ K2'den K1'e transfer anlamına gelir. +Optimism köprü terminolojisinde _yatırma_ işlemi K1'den K2'ye transfer, _çekme_ işlemi ise K2'den K1'e transfer anlamına gelir. ```solidity address indexed _l1Token, address indexed _l2Token, ``` -Çoğu durumda K1 üzerindeki bir ERC-20 adresi aynı ERC-20'nin K2'deki adresinin aynısı değildir. [Burada token adreslerinin bir listesini görebilirsiniz](https://static.optimism.io/optimism.tokenlist.json). `chainId`'si 1 olan adres K1'de (Mainnet) ve `chainId`'si 10 olan ise K2'de (Optimism). Diğer iki `chainId` değerleri ise Kovan test ağı (42) ve Optimistic Kovan test ağı içindir (69). +Çoğu durumda bir ERC-20'nin K1'deki adresi, K2'deki eşdeğer ERC-20'nin adresiyle aynı değildir. +[Token adreslerinin listesini buradan görebilirsiniz](https://static.optimism.io/optimism.tokenlist.json). +`chainId`'si 1 olan adres K1'de (Ana Ağ), `chainId`'si 10 olan adres ise K2'dedir (Optimism). +Diğer iki `chainId` değeri Kovan test ağı (42) ve Optimistic Kovan test ağı (69) içindir. ```solidity address indexed _from, @@ -109,7 +117,7 @@ Optimism köprü terminolojisinde _yatırmak_, K1'den K2'ye transfer anlamına, ); ``` -Transferlere notlar eklemek mümkündür, bu durumda notlar onları rapor eden olaylara eklenirler. +Transferlere not eklemek mümkündür, bu durumda bu notlar onları bildiren olaylara eklenir. ```solidity event ERC20WithdrawalFinalized( @@ -122,33 +130,35 @@ Transferlere notlar eklemek mümkündür, bu durumda notlar onları rapor eden o ); ``` -Aynı köprü sözleşmesi her yönde transferleri idare eder. K1 köprüsünün durumunda ise bu, yatırımların başlatımı ve çekimlerin sonlandırılması anlamına gelir. +Aynı köprü sözleşmesi her iki yöndeki transferleri de yönetir. +K1 köprüsü söz konusu olduğunda bu, yatırma işlemlerinin başlatılması ve çekme işlemlerinin sonlandırılması anlamına gelir. ```solidity /******************** - * Public Functions * + * Herkese Açık Fonksiyonlar * ********************/ /** - * @dev get the address of the corresponding L2 bridge contract. - * @return Address of the corresponding L2 bridge contract. + * @dev ilgili K2 köprü sözleşmesinin adresini alır. + * @return İlgili K2 köprü sözleşmesinin adresi. */ function l2TokenBridge() external returns (address); ``` -Bu fonksiyona pek gerek duyulmaz, çünkü K2 üzerinde önden dağıtılmış bir sözleşmedir, yani her zaman `0x4200000000000000000000000000000000000010` adresindedir. Burada K2 köprüsüyle simetri için bulunur, çünkü K1 köprüsünün adresinin bilinmesi _önemlidir_. +Bu fonksiyona aslında gerek yoktur çünkü K2'de bu, önceden dağıtılmış bir sözleşmedir ve bu nedenle her zaman `0x4200000000000000000000000000000000000010` adresindedir. +K1 köprüsünün adresini bilmek kolay olmadığından, bu fonksiyon K2 köprüsüyle simetri sağlamak için buradadır. ```solidity /** - * @dev deposit an amount of the ERC20 to the caller's balance on L2. - * @param _l1Token Address of the L1 ERC20 we are depositing - * @param _l2Token Address of the L1 respective L2 ERC20 - * @param _amount Amount of the ERC20 to deposit - * @param _l2Gas Gas limit required to complete the deposit on L2. - * @param _data Optional data to forward to L2. This data is provided - * solely as a convenience for external contracts. Aside from enforcing a maximum - * length, these contracts provide no guarantees about its content. + * @dev bir miktar ERC20'yi K2'deki arayanın bakiyesine yatırır. + * @param _l1Token Yatırmakta olduğumuz K1 ERC20'sinin adresi + * @param _l2Token İlgili K2 ERC20'sinin adresi + * @param _amount Yatırılacak ERC20 miktarı + * @param _l2Gas K2'de yatırma işlemini tamamlamak için gereken gaz limiti. + * @param _data K2'ye iletilecek isteğe bağlı veri. Bu veri yalnızca + * harici sözleşmeler için bir kolaylık olarak sağlanır. Maksimum + * uzunluğu zorunlu kılmanın yanı sıra, bu sözleşmeler içeriği hakkında hiçbir garanti vermez. */ function depositERC20( address _l1Token, @@ -159,19 +169,21 @@ Bu fonksiyona pek gerek duyulmaz, çünkü K2 üzerinde önden dağıtılmış b ) external; ``` -`_l2Gas` parametresi işlemin harcamasına izin verilen K2 gaz miktarıdır. [Belirli (yüksek) bir limite kadar bu ücretsizdir](https://community.optimism.io/docs/developers/bridge/messaging/#for-l1-%E2%87%92-l2-transactions-2), yani basım esnasında ERC-20 sözleşmesi gerçekten garip bir şey yapmazsa bu bir sorun olmamalı. Bu fonksiyon, yaygın bir senaryo olan kullanıcının farklı bir blok zincirindeki aynı adrese varlık köprülemesinin üstesinden gelir. +`_l2Gas` parametresi, işlemin harcamasına izin verilen K2 gazı miktarıdır. +[Belirli bir (yüksek) sınıra kadar bu ücretsizdir](https://community.optimism.io/docs/developers/bridge/messaging/#for-l1-%E2%87%92-l2-transactions-2), bu nedenle ERC-20 sözleşmesi basım sırasında gerçekten garip bir şey yapmadığı sürece bu bir sorun olmamalıdır. +Bu fonksiyon, bir kullanıcının varlıkları farklı bir blokzincirdeki aynı adrese köprülediği yaygın senaryoyu ele alır. ```solidity /** - * @dev deposit an amount of ERC20 to a recipient's balance on L2. - * @param _l1Token Address of the L1 ERC20 we are depositing - * @param _l2Token Address of the L1 respective L2 ERC20 - * @param _to L2 address to credit the withdrawal to. - * @param _amount Amount of the ERC20 to deposit. - * @param _l2Gas Gas limit required to complete the deposit on L2. - * @param _data Optional data to forward to L2. This data is provided - * solely as a convenience for external contracts. Aside from enforcing a maximum - * length, these contracts provide no guarantees about its content. + * @dev bir miktar ERC20'yi K2'deki bir alıcının bakiyesine yatırır. + * @param _l1Token Yatırmakta olduğumuz K1 ERC20'sinin adresi + * @param _l2Token İlgili K2 ERC20'sinin adresi + * @param _to Çekme işleminin yatırılacağı K2 adresi. + * @param _amount Yatırılacak ERC20 miktarı. + * @param _l2Gas K2'de yatırma işlemini tamamlamak için gereken gaz limiti. + * @param _data K2'ye iletilecek isteğe bağlı veri. Bu veri yalnızca + * harici sözleşmeler için bir kolaylık olarak sağlanır. Maksimum + * uzunluğu zorunlu kılmanın yanı sıra, bu sözleşmeler içeriği hakkında hiçbir garanti vermez. */ function depositERC20To( address _l1Token, @@ -183,26 +195,26 @@ Bu fonksiyona pek gerek duyulmaz, çünkü K2 üzerinde önden dağıtılmış b ) external; ``` -Bu fonksiyon neredeyse `depositERC20` ile özdeştir, ama farklı bir adrese ERC-20 yollamanıza izin verir. +Bu fonksiyon `depositERC20` ile neredeyse aynıdır, ancak ERC-20'yi farklı bir adrese göndermenize olanak tanır. ```solidity /************************* - * Cross-chain Functions * + * Zincirler Arası Fonksiyonlar * *************************/ /** - * @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the - * L1 ERC20 token. - * This call will fail if the initialized withdrawal from L2 has not been finalized. + * @dev K2'den K1'e bir çekme işlemini tamamlar ve fonları alıcının + * K1 ERC20 token bakiyesine yatırır. + * K2'den başlatılan çekme işlemi sonlandırılmamışsa bu çağrı başarısız olur. * - * @param _l1Token Address of L1 token to finalizeWithdrawal for. - * @param _l2Token Address of L2 token where withdrawal was initiated. - * @param _from L2 address initiating the transfer. - * @param _to L1 address to credit the withdrawal to. - * @param _amount Amount of the ERC20 to deposit. - * @param _data Data provided by the sender on L2. This data is provided - * solely as a convenience for external contracts. Aside from enforcing a maximum - * length, these contracts provide no guarantees about its content. + * @param _l1Token finalizeWithdrawal işleminin yapılacağı K1 token'ının adresi. + * @param _l2Token Çekme işleminin başlatıldığı K2 token'ının adresi. + * @param _from Transferi başlatan K2 adresi. + * @param _to Çekme işleminin yatırılacağı K1 adresi. + * @param _amount Yatırılacak ERC20 miktarı. + * @param _data K2'deki gönderici tarafından sağlanan veri. Bu veri + * yalnızca harici sözleşmeler için bir kolaylık olarak sağlanır. Maksimum + * uzunluğu zorunlu kılmanın yanı sıra, bu sözleşmeler içeriği hakkında hiçbir garanti vermez. */ function finalizeERC20Withdrawal( address _l1Token, @@ -215,16 +227,20 @@ Bu fonksiyon neredeyse `depositERC20` ile özdeştir, ama farklı bir adrese ERC } ``` -Optimism'de çekme işlemleri (ve K2'den K1'e diğer tüm mesajlar) iki adımlı bir süreçtir: +Optimism'de çekme işlemleri (ve K2'den K1'e diğer mesajlar) iki adımlı bir süreçtir: -1. K2 üzerinde başlatıcı işlem. -2. K1 üzerinde sonlandırıcı veya talep eden bir işlem. Bu işlemin, biten K2 işlemi için olan [hata meydan okuması süresinden](https://community.optimism.io/docs/how-optimism-works/#fault-proofs) sonra gerçekleşmesi gerekir. +1. K2'de bir başlatma işlemi. +2. K1'de bir sonlandırma veya talep etme işlemi. + Bu işlemin, K2 işlemi için [hata itiraz süresi](https://community.optimism.io/docs/how-optimism-works/#fault-proofs) sona erdikten sonra gerçekleşmesi gerekir. ### IL1StandardBridge {#il1standardbridge} -[Bu arayüz burada tanımlanmıştır](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L1/messaging/IL1StandardBridge.sol). Bu dosya ETH için olay ve fonksiyon tanımlamalarını içerir. Bu tanımlamalar ERC-20 için yukarıdaki `IL1ERC20Bridge`'de belirlenenlere gayet benzerler. +[Bu arayüz burada tanımlanmıştır](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L1/messaging/IL1StandardBridge.sol). +Bu dosya, ETH için olay ve fonksiyon tanımlarını içerir. +Bu tanımlar, yukarıda ERC-20 için `IL1ERC20Bridge` içinde tanımlananlara çok benzer. -Bazı ERC-20 token'ları özel işlem gerektirdiği ve standart köprü tarafından idare edilemedikleri için köprü arayüzü iki dosyaya bölünmüştür. Bu yolla bu tarz bir token'ı idare eden özel köprü `IL1ERC20Bridge`'i örnek alabilir ve ETH köprülemek zorunda kalmaz. +Köprü arayüzü iki dosyaya bölünmüştür çünkü bazı ERC-20 token'ları özel işlem gerektirir ve standart köprü tarafından işlenemez. +Bu şekilde, böyle bir token'ı işleyen özel köprü, `IL1ERC20Bridge`'i uygulayabilir ve ayrıca ETH köprülemek zorunda kalmaz. ```solidity // SPDX-License-Identifier: MIT @@ -237,7 +253,7 @@ import "./IL1ERC20Bridge.sol"; */ interface IL1StandardBridge is IL1ERC20Bridge { /********** - * Events * + * Olaylar * **********/ event ETHDepositInitiated( address indexed _from, @@ -247,7 +263,8 @@ interface IL1StandardBridge is IL1ERC20Bridge { ); ``` -Bu olay ERC-20 versiyonunun (`ERC20DepositInitiated`) neredeyse aynısıdır, tek fark K1 ve K2 token adreslerinin olmamasıdır. Aynısı diğer olaylar ve fonksiyonlar için de geçerlidir. +Bu olay, K1 ve K2 token adresleri dışında ERC-20 sürümüyle (`ERC20DepositInitiated`) neredeyse aynıdır. +Aynısı diğer olaylar ve fonksiyonlar için de geçerlidir. ```solidity event ETHWithdrawalFinalized( @@ -257,11 +274,11 @@ Bu olay ERC-20 versiyonunun (`ERC20DepositInitiated`) neredeyse aynısıdır, te ); /******************** - * Public Functions * + * Herkese Açık Fonksiyonlar * ********************/ /** - * @dev Deposit an amount of the ETH to the caller's balance on L2. + * @dev Bir miktar ETH'yi K2'deki çağıranın bakiyesine yatırır. . . . @@ -269,7 +286,7 @@ Bu olay ERC-20 versiyonunun (`ERC20DepositInitiated`) neredeyse aynısıdır, te function depositETH(uint32 _l2Gas, bytes calldata _data) external payable; /** - * @dev Deposit an amount of ETH to a recipient's balance on L2. + * @dev Bir miktar ETH'yi K2'deki bir alıcının bakiyesine yatırır. . . . @@ -281,13 +298,13 @@ Bu olay ERC-20 versiyonunun (`ERC20DepositInitiated`) neredeyse aynısıdır, te ) external payable; /************************* - * Cross-chain Functions * + * Zincirler Arası Fonksiyonlar * *************************/ /** - * @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the - * L1 ETH token. Since only the xDomainMessenger can call this function, it will never be called - * before the withdrawal is finalized. + * @dev K2'den K1'e bir çekme işlemini tamamlar ve fonları alıcının + * K1 ETH token bakiyesine yatırır. Bu fonksiyonu yalnızca xDomainMessenger çağırabildiğinden, çekme işlemi + * sonlandırılmadan asla çağrılmaz. . . . @@ -303,83 +320,87 @@ Bu olay ERC-20 versiyonunun (`ERC20DepositInitiated`) neredeyse aynısıdır, te ### CrossDomainEnabled {#crossdomainenabled} -[Bu sözleşme](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/libraries/bridge/CrossDomainEnabled.sol) iki köprü tarafından da ([K1](#the-l1-bridge-contract) ve [K2](#the-l2-bridge-contract)) diğer katmana mesajlar göndermek için kalıtım ile alınmıştır. +[Bu sözleşme](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/libraries/bridge/CrossDomainEnabled.sol), diğer katmana mesaj göndermek için her iki köprü ([K1](#the-l1-bridge-contract) ve [K2](#the-l2-bridge-contract)) tarafından miras alınır. ```solidity // SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.9.0; -/* Interface Imports */ +/* Arayüz İçe Aktarmaları */ import { ICrossDomainMessenger } from "./ICrossDomainMessenger.sol"; ``` -[Bu arayüz](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/libraries/bridge/ICrossDomainMessenger.sol), sözleşmeye alan adları arası mesajcısını kullanarak nasıl diğer katmana mesaj göndereceğini anlatır. Alan adları arası mesajcısı tamamen başka bir sistemdir ve gelecekte yazmayı umduğum kendine özel bir makaleyi hak ediyor. +[Bu arayüz](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/libraries/bridge/ICrossDomainMessenger.sol), alanlar arası mesajcıyı kullanarak sözleşmeye diğer katmana nasıl mesaj gönderileceğini bildirir. +Bu alanlar arası mesajcı tamamen ayrı bir sistemdir ve gelecekte yazmayı umduğum kendi makalesini hak etmektedir. ```solidity /** * @title CrossDomainEnabled - * @dev Helper contract for contracts performing cross-domain communications + * @dev Alanlar arası iletişim gerçekleştiren sözleşmeler için yardımcı sözleşme * - * Compiler used: defined by inheriting contract + * Kullanılan derleyici: miras alan sözleşme tarafından tanımlanır */ contract CrossDomainEnabled { /************* - * Variables * + * Değişkenler * *************/ - // Diğer etki alanından mesaj göndermek ve almak için kullanılan Messenger sözleşmesi. + // Diğer alandan mesaj göndermek ve almak için kullanılan Mesajcı sözleşmesi. address public messenger; /*************** - * Constructor * + * Yapıcı * ***************/ /** - * @param _messenger Address of the CrossDomainMessenger on the current layer. + * @param _messenger Mevcut katmandaki CrossDomainMessenger'ın adresi. */ constructor(address _messenger) { messenger = _messenger; } ``` -Sözleşmenin bilmesi gereken bir parametre, bu katmandaki alan adları arası mesajcısının adresidir. Bu parametre bir defa yapıcıda belirlenir ve asla değişmez. +Sözleşmenin bilmesi gereken tek parametre, bu katmandaki alanlar arası mesajcının adresidir. +Bu parametre yapılandırıcıda bir kez ayarlanır ve asla değişmez. ```solidity /********************** - * Function Modifiers * + * Fonksiyon Değiştiricileri * **********************/ /** - * Enforces that the modified function is only callable by a specific cross-domain account. - * @param _sourceDomainAccount The only account on the originating domain which is - * authenticated to call this function. + * Değiştirilen fonksiyonun yalnızca belirli bir alanlar arası hesap tarafından çağrılabilir olmasını zorunlu kılar. + * @param _sourceDomainAccount Kaynak alandaki, bu fonksiyonu çağırmak için + * doğrulanmış tek hesap. */ modifier onlyFromCrossDomainAccount(address _sourceDomainAccount) { ``` -Alan adları arası mesajlaşması, çalıştığı blok zincirindeki (ya Ethereum ana ağı ya da Optimism) herhangi bir sözleşmeden erişilebilirdir. Ancak belirli mesajlara _sadece_ öbür taraftaki köprüden gelirse güvenmek için iki tarafta da köprüye ihtiyacımız vardır. +Alanlar arası mesajlaşma, çalıştığı blokzincirdeki (Ethereum Ana Ağı veya Optimism) herhangi bir sözleşme tarafından erişilebilirdir. +Ancak her iki taraftaki köprünün de, belirli mesajlara _yalnızca_ diğer taraftaki köprüden geldiklerinde güvenmesi gerekir. ```solidity require( msg.sender == address(getCrossDomainMessenger()), - "OVM_XCHAIN: messenger contract unauthenticated" + "OVM_XCHAIN: mesajcı sözleşmesi doğrulanmadı" ); ``` -Sadece uygun alan adları arası mesajcısından (`messenger`, aşağıda gördüğünüz üzere) gelen mesajlara güvenilebilir. +Yalnızca uygun alanlar arası mesajcıdan (`messenger`, aşağıda gördüğünüz gibi) gelen mesajlara güvenilebilir. ```solidity require( getCrossDomainMessenger().xDomainMessageSender() == _sourceDomainAccount, - "OVM_XCHAIN: wrong sender of cross-domain message" + "OVM_XCHAIN: alanlar arası mesajın yanlış göndericisi" ); ``` -Alan adları arası mesajcısının diğer katman ile mesaj gönderen adresi sağlama yolu, [`.xDomainMessageSender()` fonksiyonudur](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L1/messaging/L1CrossDomainMessenger.sol#L122-L128). Mesaj tarafından başlatılan işlemde çağrıldığı sürece bu bilgiyi sağlayabilir. +Alanlar arası mesajcının, diğer katmandan bir mesaj gönderen adresi sağlama şekli, [`.xDomainMessageSender()` fonksiyonudur](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L1/messaging/L1CrossDomainMessenger.sol#L122-L128). +Mesaj tarafından başlatılan işlemde çağrıldığı sürece bu bilgiyi sağlayabilir. -Aldığımız mesajın öbür köprüden geldiğinden emin olmalıyız. +Aldığımız mesajın diğer köprüden geldiğinden emin olmalıyız. ```solidity @@ -387,29 +408,30 @@ Aldığımız mesajın öbür köprüden geldiğinden emin olmalıyız. } /********************** - * Internal Functions * + * Dahili Fonksiyonlar * **********************/ /** - * Gets the messenger, usually from storage. This function is exposed in case a child contract - * needs to override. - * @return The address of the cross-domain messenger contract which should be used. + * Genellikle depolamadan mesajcıyı alır. Bu fonksiyon, bir alt sözleşmenin + * geçersiz kılması gerekmesi durumunda kullanıma sunulur. + * @return Kullanılması gereken alanlar arası mesajcı sözleşmesinin adresi. */ function getCrossDomainMessenger() internal virtual returns (ICrossDomainMessenger) { return ICrossDomainMessenger(messenger); } ``` -Bu fonksiyon alan adları arası mesajcısını döndürür. Bundan kalıtım ile alan sözleşmelerin, hangi alan adı arası mesajcının kullanılacağını belirtmeleri için bir algoritma kullanmasına izin vermek için `messenger` değişkeni yerine bir fonksiyon kullanıyoruz. +Bu fonksiyon, alanlar arası mesajcıyı döndürür. +Bundan miras alan sözleşmelerin hangi alanlar arası mesajcıyı kullanacağını belirtmek için bir algoritma kullanmasına izin vermek amacıyla `messenger` değişkeni yerine bir fonksiyon kullanırız. ```solidity /** - * Sends a message to an account on another domain - * @param _crossDomainTarget The intended recipient on the destination domain - * @param _message The data to send to the target (usually calldata to a function with - * `onlyFromCrossDomainAccount()`) - * @param _gasLimit The gasLimit for the receipt of the message on the target domain. + * Başka bir alandaki bir hesaba mesaj gönderir + * @param _crossDomainTarget Hedef alandaki amaçlanan alıcı + * @param _message Hedefe gönderilecek veri (genellikle `onlyFromCrossDomainAccount()` içeren bir fonksiyona + * çağrı verisi) + * @param _gasLimit Hedef alandaki mesajın alınması için gaz limiti. */ function sendCrossDomainMessage( address _crossDomainTarget, @@ -417,17 +439,18 @@ Bu fonksiyon alan adları arası mesajcısını döndürür. Bundan kalıtım il bytes memory _message ``` -Son olarak, fonksiyon diğer katmana bir mesaj gönderir. +Son olarak, diğer katmana mesaj gönderen fonksiyon. ```solidity ) internal { // slither-disable-next-line reentrancy-events, reentrancy-benign ``` -[Slither](https://github.com/crytic/slither) Optimism'in güvenlik açığı ve diğer potansiyel problemleri bulmak için her sözleşmede çalıştırdığı bir statik analizcidir. Bu durumda, sıradaki satır iki açığı tetikler: +[Slither](https://github.com/crytic/slither), Optimism'in güvenlik açıklarını ve diğer potansiyel sorunları aramak için her sözleşmede çalıştırdığı bir statik analizördür. +Bu durumda, aşağıdaki satır iki güvenlik açığını tetikler: 1. [Yeniden giriş olayları](https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-3) -2. [İyi huylu yeniden giriş](https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-2) +2. [Zararsız yeniden giriş](https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-2) ```solidity getCrossDomainMessenger().sendMessage(_crossDomainTarget, _message, _gasLimit); @@ -435,7 +458,7 @@ Son olarak, fonksiyon diğer katmana bir mesaj gönderir. } ``` -Bu durumda yeniden giriş hakkında kaygılı değiliz, Slither'ın bunu bilmesi mümkün olmasa bile `getCrossDomainMessenger()` öğesinin güvenilir bir adres döndürdüğünü biliyoruz. +Bu durumda yeniden giriş konusunda endişelenmiyoruz çünkü Slither'ın bunu bilmesinin bir yolu olmasa bile `getCrossDomainMessenger()`'ın güvenilir bir adres döndürdüğünü biliyoruz. ### K1 köprü sözleşmesi {#the-l1-bridge-contract} @@ -446,10 +469,11 @@ Bu durumda yeniden giriş hakkında kaygılı değiliz, Slither'ın bunu bilmesi pragma solidity ^0.8.9; ``` -Arayüzler diğer sözleşmelerin bir parçası olabilirler, yani geniş aralıkta Solidity sürümlerini desteklemeleri gerekir. Ancak köprü bizim sözleşmemizdir, ve hangi Solidity sürümünü kullandığı hakkında katı davranabiliriz. +Arayüzler diğer sözleşmelerin bir parçası olabilir, bu nedenle çok çeşitli Solidity sürümlerini desteklemeleri gerekir. +Ancak köprünün kendisi bizim sözleşmemizdir ve hangi Solidity sürümünü kullandığı konusunda katı olabiliriz. ```solidity -/* Interface Imports */ +/* Arayüz İçe Aktarmaları */ import { IL1StandardBridge } from "./IL1StandardBridge.sol"; import { IL1ERC20Bridge } from "./IL1ERC20Bridge.sol"; ``` @@ -460,16 +484,17 @@ import { IL1ERC20Bridge } from "./IL1ERC20Bridge.sol"; import { IL2ERC20Bridge } from "../../L2/messaging/IL2ERC20Bridge.sol"; ``` -[Bu arayüz](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/IL2ERC20Bridge.sol) K2 üzerindeki standart köprüyü kontrol etmek için mesajlar oluşturmamızı sağlar. +[Bu arayüz](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/IL2ERC20Bridge.sol) K2'deki standart köprüyü kontrol etmek için mesajlar oluşturmamızı sağlar. ```solidity import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; ``` -[Bu arayüz](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol) ERC-20 sözleşmelerini kontrol etmemizi sağlar. [Onun hakkında dahasını burada okuyabilirsiniz](/developers/tutorials/erc20-annotated-code/#the-interface). +[Bu arayüz](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol) ERC-20 sözleşmelerini kontrol etmemizi sağlar. +[Buradan daha fazlasını okuyabilirsiniz](/developers/tutorials/erc20-annotated-code/#the-interface). ```solidity -/* Library Imports */ +/* Kütüphane İçe Aktarmaları */ import { CrossDomainEnabled } from "../../libraries/bridge/CrossDomainEnabled.sol"; ``` @@ -479,13 +504,13 @@ import { CrossDomainEnabled } from "../../libraries/bridge/CrossDomainEnabled.so import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol"; ``` -[`Lib_PredeployAddresses`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/libraries/constants/Lib_PredeployAddresses.sol) her zaman aynı adrese sahip olan K2 sözleşmelerinin adreslerine sahiptir. Buna K2 üzerindeki standart köprü de dahildir. +[`Lib_PredeployAddresses`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/libraries/constants/Lib_PredeployAddresses.sol) her zaman aynı adrese sahip olan K2 sözleşmelerinin adreslerini içerir. Buna K2'deki standart köprü de dahildir. ```solidity import { Address } from "@openzeppelin/contracts/utils/Address.sol"; ``` -[OpenZeppelin'in Address yardımcı araçları](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol). Sözleşme adresleri ve harici olarak sahiplenilmiş hesapların (EOA) ayrımını yapmak için kullanılır. +[OpenZeppelin'in Adres yardımcı programları](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol). Sözleşme adresleri ile harici olarak sahip olunan hesaplara (EOA) ait olanlar arasında ayrım yapmak için kullanılır. Bunun mükemmel bir çözüm olmadığını unutmayın. Bir sözleşmenin yapıcısı tarafından yapılan çağrılar ve doğrudan çağrıların ayrımını yapmanın bir yolu yoktur ama bu en azından bazı yaygın kullanıcı hatalarını tespit etmemizi ve önlememizi sağlar. @@ -493,31 +518,31 @@ Bunun mükemmel bir çözüm olmadığını unutmayın. Bir sözleşmenin yapıc import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; ``` -[ERC-20 standardı](https://eips.ethereum.org/EIPS/eip-20) biz sözleşmenin hata bildirmesi için iki yolu destekler: +[ERC-20 standardı](https://eips.ethereum.org/EIPS/eip-20) bir sözleşmenin hata bildirmesi için iki yolu destekler: -1. Geri döndür -2. `false` döndürme +1. Geri Al +2. `false` döndür -Her iki durumu da ele almak kodumuzu daha karmaşık hâle getirecektir, bu nedenle [OpenZeppelin'in `SafeERC20`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol)'sini kullanıyoruz, bu da [tüm hataların bir geri dönüşle sonuçlanmasını](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol#L96) sağlar. +Her iki durumu da ele almak kodumuzu daha karmaşık hale getirirdi, bu yüzden bunun yerine [tüm hataların bir geri almaya neden olmasını sağlayan](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol#L96) [OpenZeppelin'in `SafeERC20`'sini](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol) kullanıyoruz. ```solidity /** * @title L1StandardBridge - * @dev The L1 ETH and ERC20 Bridge is a contract which stores deposited L1 funds and standard - * tokens that are in use on L2. It synchronizes a corresponding L2 Bridge, informing it of deposits - * and listening to it for newly finalized withdrawals. + * @dev L1 ETH ve ERC20 Köprüsü, yatırılan L1 fonlarını ve K2'de kullanımda olan standart + * token'ları saklayan bir sözleşmedir. İlgili bir K2 Köprüsü ile senkronize olur, ona yatırma işlemleri hakkında bilgi verir + * ve yeni sonuçlandırılan çekme işlemleri için onu dinler. * */ contract L1StandardBridge is IL1StandardBridge, CrossDomainEnabled { using SafeERC20 for IERC20; ``` -Bu satır `IERC20` arayüzünü her kullandığımızda `SafeERC20` paketleyicisini kullanmasını belirtme yöntemimizdir. +Bu satır, `IERC20` arayüzünü her kullandığımızda `SafeERC20` sarmalayıcısını kullanmayı nasıl belirlediğimizdir. ```solidity /******************************** - * External Contract References * + * Harici Sözleşme Referansları * ********************************/ address public l2TokenBridge; @@ -527,48 +552,63 @@ Bu satır `IERC20` arayüzünü her kullandığımızda `SafeERC20` paketleyicis ```solidity - // Maps L1 token to L2 token to balance of the L1 token deposited + // K1 token'ını K2 token'ına, yatırılan K1 token bakiyesine eşler mapping(address => mapping(address => uint256)) public deposits; ``` -Bunun gibi bir çift [eşleştirme](https://www.tutorialspoint.com/solidity/solidity_mappings.htm), [iki boyutlu bir seyrek diziyi](https://en.wikipedia.org/wiki/Sparse_matrix) tanımlama şeklinizdir. Bu veri yapısındaki değerler `deposit[L1 token addr][L2 token addr]` olarak tanımlanır. Varsayılan değer sıfırdır. Yalnızca farklı bir değere ayarlanmış hücreler depolamaya yazılır. +Bunun gibi çift [eşleme](https://www.tutorialspoint.com/solidity/solidity_mappings.htm), [iki boyutlu seyrek bir dizi](https://en.wikipedia.org/wiki/Sparse_matrix) tanımlama yöntemidir. +Bu veri yapısındaki değerler `deposit[K1 token adresi][K2 token adresi]` olarak tanımlanır. +Varsayılan değer sıfırdır. +Yalnızca farklı bir değere ayarlanmış hücreler depolamaya yazılır. ```solidity /*************** - * Constructor * + * Yapıcı * ***************/ - // This contract lives behind a proxy, so the constructor parameters will go unused. + // Bu sözleşme bir proxy arkasında bulunur, bu nedenle yapıcı parametreleri kullanılmayacaktır. constructor() CrossDomainEnabled(address(0)) {} ``` -Depodaki tüm değişkenleri kopyalamak zorunda kalmadan bu sözleşmeyi yükseltebilmek istiyoruz. Bunu yapmak için bir [`Proxy`](https://docs.openzeppelin.com/contracts/3.x/api/proxy) kullanıyoruz. Bu, çağrıları adresi proxy sözleşmesi tarafından saklanan ayrı bir kişiye aktarmak için [`delegatecall`](https://solidity-by-example.org/delegatecall/) kullanan bir sözleşmedir (yükselttiğinizde proxy'ye bu adresi değiştirmesini söylersiniz). `delegatecall` kullandığınızda, depolama alanı _çağırma_ sözleşmesinin deposu olarak kalır, bu nedenle tüm sözleşme durumu değişkenlerinin değerleri etkilenmez. +Depolamadaki tüm değişkenleri kopyalamak zorunda kalmadan bu sözleşmeyi yükseltebilmek istiyoruz. +Bunu yapmak için bir [`Proxy`](https://docs.openzeppelin.com/contracts/3.x/api/proxy) kullanıyoruz. Bu, çağrıları adresi proxy sözleşmesi tarafından saklanan ayrı bir sözleşmeye aktarmak için [`delegatecall`](https://solidity-by-example.org/delegatecall/) kullanan bir sözleşmedir (yükselttiğinizde proxy'ye bu adresi değiştirmesini söylersiniz). +`delegatecall` kullandığınızda, depolama alanı çağırma sözleşmesinin deposu olarak kalır, bu nedenle tüm sözleşme durumu değişkenlerinin değerleri etkilenmez. -`delegecall`'un _callee_'si olan sözleşmenin depolamasının kullanılmaması ve bu nedenle ona iletilen oluşturucu değerlerinin önemli olmaması, bu modelin etkilerinden birisidir. `CrossDomainEnabled` yapıcısına anlamsız bir değer sağlayabilmemizin nedeni budur. Aşağıdaki başlatmanın yapıcıdan ayrı olmasının nedeni de budur. +`delegatecall`'un çağrılanı olan sözleşmenin depolamasının kullanılmaması ve bu nedenle ona iletilen yapıcı değerlerinin önemli olmaması, bu modelin etkilerinden biridir. +`CrossDomainEnabled` yapıcısına anlamsız bir değer sağlayabilmemizin nedeni budur. +Aşağıdaki başlatmanın yapıcıdan ayrı olmasının nedeni de budur. ```solidity /****************** - * Initialization * + * Başlatma * ******************/ /** - * @param _l1messenger L1 Messenger address being used for cross-chain communications. - * @param _l2TokenBridge L2 standard bridge address. + * @param _l1messenger Zincirler arası iletişim için kullanılan K1 Mesajcı adresi. + * @param _l2TokenBridge K2 standart köprü adresi. */ // slither-disable-next-line external-function ``` -Bu [Slither testi](https://github.com/crytic/slither/wiki/Detector-Documentation#public-function-that-could-be-declared-external), sözleşme kodundan çağrılır ve bu nedenle `public` yerine `external` olarak bildirilebilir. `external` fonksiyonların kullanım maliyeti, çağrı verilerinde parametrelerle sağlanabildikleri için daha düşük olabilir. `public` olarak tanımlanan fonksiyonlara sözleşme içinden erişilebilir olmalıdır. Sözleşmeler kendi çağrı verilerini değiştiremez, bu nedenle parametrelerin bellekte olması gerekir. Böyle bir fonksiyon harici olarak çağrıldığında, çağrı verilerini belleğe kopyalamak gerekir ve bu da gaz maliyetine neden olur. Bu durumda fonksiyon sadece bir kez çağrılır, bu nedenle verimsizlik bizim için önemli değildir. +Bu [Slither testi](https://github.com/crytic/slither/wiki/Detector-Documentation#public-function-that-could-be-declared-external), sözleşme kodundan çağrılmayan ve bu nedenle `public` yerine `external` olarak bildirilebilecek fonksiyonları tanımlar. +`external` fonksiyonların gaz maliyeti, çağrı verilerinde parametrelerle sağlanabildikleri için daha düşük olabilir. +`public` olarak tanımlanan fonksiyonlara sözleşme içinden erişilebilir olmalıdır. +Sözleşmeler kendi çağrı verilerini değiştiremez, bu nedenle parametrelerin bellekte olması gerekir. +Böyle bir fonksiyon harici olarak çağrıldığında, çağrı verilerini belleğe kopyalamak gerekir ve bu da gaz maliyetine neden olur. +Bu durumda fonksiyon sadece bir kez çağrılır, bu nedenle verimsizlik bizim için önemli değildir. ```solidity function initialize(address _l1messenger, address _l2TokenBridge) public { - require(messenger == address(0), "Contract has already been initialized."); + require(messenger == address(0), "Sözleşme zaten başlatıldı."); ``` -`initialize` fonksiyonu yalnızca bir kez çağrılmalıdır. K1 alan adları arası mesajcısının veya K2 token köprüsünün adresi değişirse, yeni bir proxy ve onu çağıran yeni bir köprü oluştururuz. Bunun, çok nadir gerçekleşen tüm sistemin yükseltilmesi dışında gerçekleşmesi pek olası değildir. +`initialize` fonksiyonu yalnızca bir kez çağrılmalıdır. +K1 alanlar arası mesajcısının veya K2 token köprüsünün adresi değişirse, yeni bir proxy ve onu çağıran yeni bir köprü oluştururuz. +Bunun, çok nadir gerçekleşen tüm sistemin yükseltilmesi dışında gerçekleşmesi pek olası değildir. -Bu fonksiyonun, onu _kimin_ arayabileceğini kısıtlayan herhangi bir mekanizmaya sahip olmadığını unutmayın. Bu, teorik olarak bir saldırganın biz proxy'yi ve köprünün ilk sürümünü dağıtana kadar bekleyebileceği ve ardından meşru kullanıcıdan önce `initialize` fonksiyonuna ulaşmak için [front-run](https://solidity-by-example.org/hacks/front-running/) yapabileceği anlamına gelir. Ancak bunu önlemenin iki yöntemi vardır: +Bu fonksiyonun, onu kimin arayabileceğini kısıtlayan herhangi bir mekanizmaya sahip olmadığını unutmayın. +Bu, teorik olarak bir saldırganın biz proxy'yi ve köprünün ilk sürümünü dağıtana kadar bekleyebileceği ve ardından meşru kullanıcıdan önce `initialize` fonksiyonuna ulaşmak için [front-run](https://solidity-by-example.org/hacks/front-running/) yapabileceği anlamına gelir. Ancak bunu önlemenin iki yöntemi vardır: 1. Sözleşmeler doğrudan bir EOA tarafından değil de [onları oluşturan başka bir sözleşmeye sahip olan bir işlemde](https://medium.com/upstate-interactive/creating-a-contract-with-a-smart-contract-bdb67c5c8595) dağıtılırsa tüm süreç atomik olabilir ve başka herhangi bir işlem yürütülmeden önce tamamlanabilir. 2. Geçerli `initialize` çağrısı başarısız olursa, yeni oluşturulan proxy ve köprüyü yok saymak ve yenilerini oluşturmak her zaman mümkündür. @@ -584,34 +624,35 @@ Bunlar, köprünün bilmesi gereken iki parametredir. ```solidity /************** - * Depositing * + * Yatırma * **************/ - /** @dev Modifier requiring sender to be EOA. This check could be bypassed by a malicious - * contract via initcode, but it takes care of the user error we want to avoid. + /** @dev Göndericinin EOA olmasını gerektiren değiştirici. Bu kontrol, kötü niyetli bir + * sözleşme tarafından initcode aracılığıyla atlatılabilir, ancak kaçınmak istediğimiz kullanıcı hatasını önler. */ modifier onlyEOA() { - // Used to stop deposits from contracts (avoid accidentally lost tokens) - require(!Address.isContract(msg.sender), "Account not EOA"); + // Sözleşmelerden yatırma işlemlerini durdurmak için kullanılır (yanlışlıkla kaybedilen token'ları önlemek için) + require(!Address.isContract(msg.sender), "Hesap EOA değil"); _; } ``` -Bu, OpenZeppelin'in `Address` yardımcı araçlarına ihtiyaç duymamızın nedenidir. +OpenZeppelin'in `Address` yardımcı programlarına ihtiyaç duymamızın nedeni budur. ```solidity /** - * @dev This function can be called with no data - * to deposit an amount of ETH to the caller's balance on L2. - * Since the receive function doesn't take data, a conservative - * default amount is forwarded to L2. + * @dev Bu fonksiyon, bir miktar ETH'yi çağıranın K2'deki bakiyesine + * yatırmak için veri olmadan çağrılabilir. + * Alım fonksiyonu veri almadığından, + * K2'ye muhafazakar bir varsayılan miktar iletilir. */ receive() external payable onlyEOA { _initiateETHDeposit(msg.sender, msg.sender, 200_000, bytes("")); } ``` -Bu fonksiyon test amaçlı mevcuttur. Arayüz tanımlarında görünmediğine dikkat edin: Normal kullanım için değildir. +Bu fonksiyon test amaçlı mevcuttur. +Arayüz tanımlarında görünmediğine dikkat edin: Normal kullanım için değildir. ```solidity /** @@ -633,18 +674,18 @@ Bu fonksiyon test amaçlı mevcuttur. Arayüz tanımlarında görünmediğine di } ``` -Bu iki fonksiyon, gerçek ETH yatırma işlemini yöneten fonksiyon olan `_initiateETHDeposit` etrafındaki paketleyicilerdir. +Bu iki fonksiyon, gerçek ETH yatırma işlemini yöneten fonksiyon olan `_initiateETHDeposit` etrafındaki sarmalayıcılardır. ```solidity /** - * @dev Performs the logic for deposits by storing the ETH and informing the L2 ETH Gateway of - * the deposit. - * @param _from Account to pull the deposit from on L1. - * @param _to Account to give the deposit to on L2. - * @param _l2Gas Gas limit required to complete the deposit on L2. - * @param _data Optional data to forward to L2. This data is provided - * solely as a convenience for external contracts. Aside from enforcing a maximum - * length, these contracts provide no guarantees about its content. + * @dev ETH'yi saklayarak ve K2 ETH Ağ Geçidi'ne yatırma hakkında bilgi vererek + * para yatırma mantığını gerçekleştirir. + * @param _from K1'de para yatırma işleminin çekileceği hesap. + * @param _to K2'de para yatırma işleminin verileceği hesap. + * @param _l2Gas K2'de para yatırma işlemini tamamlamak için gereken gaz limiti. + * @param _data K2'ye iletilecek isteğe bağlı veri. Bu veri yalnızca + * harici sözleşmeler için bir kolaylık olarak sağlanır. Maksimum + * uzunluğu zorunlu kılmanın yanı sıra, bu sözleşmeler içeriği hakkında hiçbir garanti vermez. */ function _initiateETHDeposit( address _from, @@ -652,11 +693,14 @@ Bu iki fonksiyon, gerçek ETH yatırma işlemini yöneten fonksiyon olan `_initi uint32 _l2Gas, bytes memory _data ) internal { - // Construct calldata for finalizeDeposit call + // finalizeDeposit çağrısı için çağrı verisi oluştur bytes memory message = abi.encodeWithSelector( ``` -Etki alanları arası mesajların çalışma şekli, hedef sözleşmenin çağrı verileri olarak mesajla birlikte çağrılmasıdır. Solidity sözleşmeleri, çağrı verilerini her zaman aşağıdaki [ABI özelliklerine](https://docs.soliditylang.org/en/v0.8.12/abi-spec.html) uygun olarak yorumlar. [`abi.encodeWithSelector`](https://docs.soliditylang.org/en/v0.8.12/units-and-global-variables.html#abi-encoding-and-decoding-functions) Solidity fonksiyonu, bu çağrı verilerini oluşturur. +Alanlar arası mesajların çalışma şekli, hedef sözleşmenin çağrı verileri olarak mesajla birlikte çağrılmasıdır. +Solidity sözleşmeleri, çağrı verilerini her zaman +[ABI özelliklerine](https://docs.soliditylang.org/en/v0.8.12/abi-spec.html) uygun olarak yorumlar. +Solidity'nin [`abi.encodeWithSelector`](https://docs.soliditylang.org/en/v0.8.12/units-and-global-variables.html#abi-encoding-and-decoding-functions) fonksiyonu bu çağrı verisini oluşturur. ```solidity IL2ERC20Bridge.finalizeDeposit.selector, @@ -669,24 +713,24 @@ Etki alanları arası mesajların çalışma şekli, hedef sözleşmenin çağr ); ``` -Buradaki mesaj, şu parametrelerle [`finalizeDeposit` fonksiyonunu](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/L2StandardBridge.sol#L141-L148) çağırmaktır: +Buradaki mesaj, bu parametrelerle [ `finalizeDeposit` fonksiyonunu](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/L2StandardBridge.sol#L141-L148) çağırmaktır: -| Parametre | Değer | Anlam | -| ----------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -| \_l1Token | address(0) | K1'de ETH'yi (ERC-20 token'ı değildir) temsil eden özel değer | +| Parametre | Değer | Anlamı | +| ------------------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| \_l1Token | address(0) | K1'de ETH'yi (bir ERC-20 token'ı değildir) temsil eden özel değer | | \_l2Token | Lib_PredeployAddresses.OVM_ETH | Optimism'de ETH'yi yöneten K2 sözleşmesi, `0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000` (bu sözleşme yalnızca dahili Optimism kullanımı içindir) | -| \_from | \_from | ETH'yi gönderen K1 üzerindeki adres | -| \_to | \_to | ETH'yi alan K2'deki adres | -| amount | msg.value | Gönderilen wei miktarı (zaten köprüye gönderildi) | -| \_data | \_data | Yatırmaya eklenecek ek tarih | +| \_from | \_from | ETH'yi gönderen K1'deki adres | +| \_to | \_to | ETH'yi alan K2'deki adres | +| miktar | msg.value | Gönderilen wei miktarı (zaten köprüye gönderildi) | +| \_data | \_data | Yatırmaya eklenecek ek veri | ```solidity - // Send calldata into L2 + // Çağrı verisini K2'ye gönder // slither-disable-next-line reentrancy-events sendCrossDomainMessage(l2TokenBridge, _l2Gas, message); ``` -Mesajı, alan adları arası mesajcısı ile gönderin. +Mesajı, alanlar arası mesajcısı ile gönderin. ```solidity // slither-disable-next-line reentrancy-events @@ -701,9 +745,9 @@ Bu transferi dinleyen herhangi bir merkeziyetsiz uygulamayı bilgilendirmek içi * @inheritdoc IL1ERC20Bridge */ function depositERC20( - . - . - . + . + . + . ) external virtual onlyEOA { _initiateERC20Deposit(_l1Token, _l2Token, msg.sender, msg.sender, _amount, _l2Gas, _data); } @@ -712,30 +756,30 @@ Bu transferi dinleyen herhangi bir merkeziyetsiz uygulamayı bilgilendirmek içi * @inheritdoc IL1ERC20Bridge */ function depositERC20To( - . - . - . + . + . + . ) external virtual { _initiateERC20Deposit(_l1Token, _l2Token, msg.sender, _to, _amount, _l2Gas, _data); } ``` -Bu iki fonksiyon, gerçek ERC-20 yatırma işlemini yöneten fonksiyon olan `_initiateERC20Deposit` etrafındaki paketleyicilerdir. +Bu iki fonksiyon, gerçek ERC-20 yatırma işlemini yöneten fonksiyon olan `_initiateERC20Deposit` etrafındaki sarmalayıcılardır. ```solidity /** - * @dev Performs the logic for deposits by informing the L2 Deposited Token - * contract of the deposit and calling a handler to lock the L1 funds. (e.g., transferFrom) + * @dev K2 Yatırılan Token'ı bilgilendirerek yatırma mantığını gerçekleştirir + * sözleşmesi ve K1 fonlarını kilitlemek için bir işleyici çağırır. (örneğin, transferFrom) * - * @param _l1Token Address of the L1 ERC20 we are depositing - * @param _l2Token Address of the L1 respective L2 ERC20 - * @param _from Account to pull the deposit from on L1 - * @param _to Account to give the deposit to on L2 - * @param _amount Amount of the ERC20 to deposit. - * @param _l2Gas Gas limit required to complete the deposit on L2. - * @param _data Optional data to forward to L2. This data is provided - * solely as a convenience for external contracts. Aside from enforcing a maximum - * length, these contracts provide no guarantees about its content. + * @param _l1Token Yatırmakta olduğumuz K1 ERC20'sinin adresi + * @param _l2Token İlgili K2 ERC20'sinin adresi + * @param _from K1'de para yatırma işleminin çekileceği hesap. + * @param _to K2'de para yatırma işleminin verileceği hesap. + * @param _amount Yatırılacak ERC20 miktarı. + * @param _l2Gas K2'de yatırma işlemini tamamlamak için gereken gaz limiti. + * @param _data K2'ye iletilecek isteğe bağlı veri. Bu veri yalnızca + * harici sözleşmeler için bir kolaylık olarak sağlanır. Maksimum + * uzunluğu zorunlu kılmanın yanı sıra, bu sözleşmeler içeriği hakkında hiçbir garanti vermez. */ function _initiateERC20Deposit( address _l1Token, @@ -748,12 +792,14 @@ Bu iki fonksiyon, gerçek ERC-20 yatırma işlemini yöneten fonksiyon olan `_in ) internal { ``` -Bu fonksiyon, birkaç önemli farklılık dışında yukarıdaki `_initiateETHDeposit` fonksiyonuna benzer. İlk fark, bu fonksiyonun token adreslerini ve aktarılacak miktarı parametre olarak almasıdır. ETH söz konusu olduğunda köprüye yapılan çağrı, varlığın köprü hesabına (`msg.value`) transferini zaten içerir. +Bu fonksiyon, birkaç önemli farklılık dışında yukarıdaki `_initiateETHDeposit` fonksiyonuna benzer. +İlk fark, bu fonksiyonun token adreslerini ve aktarılacak miktarı parametre olarak almasıdır. +ETH söz konusu olduğunda köprüye yapılan çağrı, varlığın köprü hesabına (`msg.value`) transferini zaten içerir. ```solidity - // When a deposit is initiated on L1, the L1 Bridge transfers the funds to itself for future - // withdrawals. safeTransferFrom also checks if the contract has code, so this will fail if - // _from is an EOA or address(0). + // K1'de bir yatırma başlatıldığında, K1 Köprüsü gelecekteki + // para çekme işlemleri için fonları kendisine aktarır. safeTransferFrom ayrıca sözleşmede kod olup olmadığını + // kontrol eder, bu nedenle _from bir EOA veya address(0) ise bu işlem başarısız olur. // slither-disable-next-line reentrancy-events, reentrancy-benign IERC20(_l1Token).safeTransferFrom(_from, address(this), _amount); ``` @@ -764,10 +810,11 @@ ERC-20 token transferleri, ETH'den farklı bir süreci takip eder: 2. Kullanıcı, token sözleşmesinin adresi, miktarı vb. ile birlikte köprüyü çağırır. 3. Köprü, token'ları yatırma işleminin bir parçası olarak (kendisine) aktarır. -İlk adım, son ikisinden ayrı bir işlemde gerçekleşebilir. Ancak `_initiateERC20Deposit` çağıran iki fonksiyon, (`depositERC20` ve `DepositERC20To`), bu fonksiyonu `_from` parametresi olarak yalnızca `msg.sender` ile çağırdığından, front-running bir sorun olmaz. +İlk adım, son ikisinden ayrı bir işlemde gerçekleşebilir. +Ancak `_initiateERC20Deposit` çağıran iki fonksiyon (`depositERC20` ve `depositERC20To`), bu fonksiyonu `_from` parametresi olarak yalnızca `msg.sender` ile çağırdığından, front-running bir sorun olmaz. ```solidity - // Construct calldata for _l2Token.finalizeDeposit(_to, _amount) + // _l2Token.finalizeDeposit(_to, _amount) için çağrı verisi oluştur bytes memory message = abi.encodeWithSelector( IL2ERC20Bridge.finalizeDeposit.selector, _l1Token, @@ -778,7 +825,7 @@ ERC-20 token transferleri, ETH'den farklı bir süreci takip eder: _data ); - // Send calldata into L2 + // Çağrı verisini K2'ye gönder // slither-disable-next-line reentrancy-events, reentrancy-benign sendCrossDomainMessage(l2TokenBridge, _l2Gas, message); @@ -786,7 +833,8 @@ ERC-20 token transferleri, ETH'den farklı bir süreci takip eder: deposits[_l1Token][_l2Token] = deposits[_l1Token][_l2Token] + _amount; ``` -Yatırılan token miktarını `deposits` veri yapısına ekleyin. K2'de aynı K1 ERC-20 token'ına karşılık gelen birden fazla adres olabilir, bu nedenle yatırma işlemlerini takip etmek için köprünün K1 ERC-20 token bakiyesini kullanmak yeterli değildir. +Yatırılan token miktarını `deposits` veri yapısına ekleyin. +K2'de aynı K1 ERC-20 token'ına karşılık gelen birden fazla adres olabilir, bu nedenle yatırma işlemlerini takip etmek için köprünün K1 ERC-20 token bakiyesini kullanmak yeterli değildir. ```solidity @@ -795,7 +843,7 @@ Yatırılan token miktarını `deposits` veri yapısına ekleyin. K2'de aynı K1 } /************************* - * Cross-chain Functions * + * Zincirler Arası Fonksiyonlar * *************************/ /** @@ -808,13 +856,14 @@ Yatırılan token miktarını `deposits` veri yapısına ekleyin. K2'de aynı K1 bytes calldata _data ``` -K2 köprüsü, K2 alan adları arası mesajcısına, K1 alan adları arası mesajcısının bu fonksiyonu çağırmasına neden olan bir mesaj gönderir (bir kez [mesajı sonlandıran işlem](https://community.optimism.io/docs/developers/bridge/messaging/#fees-for-l2-%E2%87%92-l1-transactions) elbette K1'de gönderilir). +K2 köprüsü, K2 alanlar arası mesajcısına, K1 alanlar arası mesajcısının bu fonksiyonu çağırmasına neden olan bir mesaj gönderir (tabii ki, [mesajı sonlandıran işlem](https://community.optimism.io/docs/developers/bridge/messaging/#fees-for-l2-%E2%87%92-l1-transactions) K1'de gönderildikten sonra). ```solidity ) external onlyFromCrossDomainAccount(l2TokenBridge) { ``` -Bunun _meşru_ bir mesaj olduğundan, alan adları arası mesajcısından gelen ve K2 token köprüsünden kaynaklanan bir mesaj olduğundan emin olun. Bu fonksiyon, ETH'yi köprüden çekmek için kullanılır, bu nedenle yalnızca yetkili arayan tarafından çağrıldığından emin olmalıyız. +Bunun meşru bir mesaj olduğundan, alanlar arası mesajcısından gelen ve K2 token köprüsünden kaynaklanan bir mesaj olduğundan emin olun. +Bu fonksiyon, ETH'yi köprüden çekmek için kullanılır, bu nedenle yalnızca yetkili arayan tarafından çağrıldığından emin olmalıyız. ```solidity // slither-disable-next-line reentrancy-events @@ -824,7 +873,7 @@ Bunun _meşru_ bir mesaj olduğundan, alan adları arası mesajcısından gelen ETH aktarmanın yolu, alıcıyı `msg.value` içindeki wei miktarıyla aramaktır. ```solidity - require(success, "TransferHelper::safeTransferETH: ETH transfer failed"); + require(success, "TransferHelper::safeTransferETH: ETH transferi başarısız"); // slither-disable-next-line reentrancy-events emit ETHWithdrawalFinalized(_from, _to, _amount, _data); @@ -857,8 +906,7 @@ Bu fonksiyon, ERC-20 token'ları için gerekli değişikliklerle birlikte yukar `deposits` veri yapısını güncelleyin. ```solidity - - // When a withdrawal is finalized on L1, the L1 Bridge transfers the funds to the withdrawer + // K1'de bir çekme sonlandırıldığında, K1 Köprüsü fonları çekene aktarır // slither-disable-next-line reentrancy-events IERC20(_l1Token).safeTransfer(_to, _amount); @@ -868,28 +916,35 @@ Bu fonksiyon, ERC-20 token'ları için gerekli değişikliklerle birlikte yukar /***************************** - * Temporary - Migrating ETH * + * Geçici - ETH Taşıma * *****************************/ /** - * @dev Adds ETH balance to the account. This is meant to allow for ETH - * to be migrated from an old gateway to a new gateway. - * NOTE: This is left for one upgrade only so we are able to receive the migrated ETH from the - * old contract + * @dev ETH bakiyesini hesaba ekler. Bu, ETH'nin + * eski bir ağ geçidinden yeni bir ağ geçidine taşınmasına izin vermek içindir. + * NOT: Bu, yalnızca bir yükseltme için bırakılmıştır, böylece taşınan ETH'yi + * eski sözleşmeden alabiliriz */ function donateETH() external payable {} } ``` -Köprünün daha önce bir uygulaması vardı. Uygulamadan buna geçtiğimizde, tüm varlıkları taşımak zorunda kaldık. ERC-20 token'ları sadece taşınabilir. Ancak, ETH'yi bir sözleşmeye aktarmak için o sözleşmenin onayına ihtiyacınız var ve bu da `donateETH`'in bize sağladığı şeydir. +Köprünün daha önce bir uygulaması vardı. +Uygulamadan buna geçtiğimizde, tüm varlıkları taşımak zorunda kaldık. +ERC-20 token'ları sadece taşınabilir. +Ancak, ETH'yi bir sözleşmeye aktarmak için o sözleşmenin onayına ihtiyacınız var ve bu da `donateETH`'in bize sağladığı şeydir. -## K2 üzerinde ERC-20 Token'ları {#erc-20-tokens-on-l2} +## K2'deki ERC-20 Token'ları {#erc-20-tokens-on-l2} -Bir ERC-20 token'ının standart köprüye sığması için standart köprünün, _sadece ama sadece_ standart köprünün token basmasına izin vermesi gerekir. Bu, köprülerin Optimism üzerinde dolaşan token sayısının K1 köprü sözleşmesi içinde kilitli token sayısına eşit olduğundan emin olması gerektiği için gereklidir. K2'de çok fazla token varsa, bazı kullanıcılar varlıklarını K1'e geri köprüleyemez. Güvenilir bir köprü yerine, esasen [kısmi rezerv bankacılığını](https://www.investopedia.com/terms/f/fractionalreservebanking.asp) yeniden yaratmış olurduk. K1'de çok fazla token varsa, bu token'lardan bazıları köprü sözleşmesinin içinde sonsuza kadar kilitli kalır çünkü K2 token'larını yakmadan onları serbest bırakmanın bir yolu yoktur. +Bir ERC-20 token'ının standart köprüye sığması için standart köprünün ve _sadece_ standart köprünün token basmasına izin vermesi gerekir. +Bu, köprülerin Optimism üzerinde dolaşan token sayısının K1 köprü sözleşmesi içinde kilitli token sayısına eşit olduğundan emin olması gerektiği için gereklidir. +K2'de çok fazla token varsa, bazı kullanıcılar varlıklarını K1'e geri köprüleyemez. +Güvenilir bir köprü yerine, esasen [kısmi rezerv bankacılığını](https://www.investopedia.com/terms/f/fractionalreservebanking.asp) yeniden yaratmış olurduk. +K1'de çok fazla token varsa, bu token'lardan bazıları köprü sözleşmesinin içinde sonsuza kadar kilitli kalır çünkü K2 token'larını yakmadan onları serbest bırakmanın bir yolu yoktur. ### IL2StandardERC20 {#il2standarderc20} -Standart köprüyü kullanan K2 üzerindeki her ERC-20 token'ının, standart köprünün ihtiyaç duyduğu fonksiyonlara ve olaylara sahip olan [bu arayüzü](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/standards/IL2StandardERC20.sol) sağlaması gerekir. +Standart köprüyü kullanan K2'deki her ERC-20 token'ı, standart köprünün ihtiyaç duyduğu fonksiyonları ve olayları içeren [bu arayüzü](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/standards/IL2StandardERC20.sol) sağlamalıdır. ```solidity // SPDX-License-Identifier: MIT @@ -898,20 +953,24 @@ pragma solidity ^0.8.9; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; ``` -[Standart ERC-20 arayüzü](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol), `mint` ve `burn` fonksiyonlarını içermez. Bu yöntemler, token'ları oluşturma ve yok etme mekanizmalarını belirsiz bırakan [ERC-20 standardı](https://eips.ethereum.org/EIPS/eip-20) için gerekli değildir. +[Standart ERC-20 arayüzü](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol), `mint` ve `burn` fonksiyonlarını içermez. +Bu yöntemler, token'ları oluşturma ve yok etme mekanizmalarını belirsiz bırakan [ERC-20 standardı](https://eips.ethereum.org/EIPS/eip-20) için gerekli değildir. ```solidity import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; ``` -[ERC-165 arayüzü](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol), bir sözleşmenin hangi fonksiyonları sağladığını belirtmek için kullanılır. [Standardı buradan okuyabilirsiniz](https://eips.ethereum.org/EIPS/eip-165). +[ERC-165 arayüzü](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol) bir sözleşmenin hangi fonksiyonları sağladığını belirtmek için kullanılır. +[Standardı buradan okuyabilirsiniz](https://eips.ethereum.org/EIPS/eip-165). ```solidity interface IL2StandardERC20 is IERC20, IERC165 { function l1Token() external returns (address); ``` -Bu fonksiyon, bu sözleşmeye köprülenen K1 token'ının adresini sağlar. Ters yönde benzer bir fonksiyonumuz olmadığını unutmayın. Uygulandığında K2 desteğinin planlanıp planlanmadığına bakılmaksızın herhangi bir K1 token'ını köprüleyebilmemiz gerekir. +Bu fonksiyon, bu sözleşmeye köprülenen K1 token'ının adresini sağlar. +Ters yönde benzer bir fonksiyonumuz olmadığını unutmayın. +Uygulandığında K2 desteğinin planlanıp planlanmadığına bakılmaksızın herhangi bir K1 token'ını köprüleyebilmemiz gerekir. ```solidity @@ -924,11 +983,13 @@ Bu fonksiyon, bu sözleşmeye köprülenen K1 token'ının adresini sağlar. Ter } ``` -Token'ları basmak (oluşturmak) ve yakmak (yok etmek) için fonksiyonlar ve olaylar. Köprü, token sayısının doğru (K1'de kilitli token sayısına eşit) olduğundan emin olmak için bu fonksiyonları çalıştırabilen tek varlık olmalıdır. +Token'ları basmak (oluşturmak) ve yakmak (yok etmek) için fonksiyonlar ve olaylar. +Köprü, token sayısının doğru (K1'de kilitli token sayısına eşit) olduğundan emin olmak için bu fonksiyonları çalıştırabilen tek varlık olmalıdır. ### L2StandardERC20 {#L2StandardERC20} -[Bu, `IL2StandardERC20` arayüzü uygulamamızdır](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/standards/L2StandardERC20.sol). Bir tür özel mantığa ihtiyacınız yoksa, bunu kullanmalısınız. +[Bu, `IL2StandardERC20` arayüzünün bizim uygulamamızdır](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/standards/L2StandardERC20.sol). +Bir tür özel mantığa ihtiyacınız yoksa, bunu kullanmalısınız. ```solidity // SPDX-License-Identifier: MIT @@ -937,7 +998,8 @@ pragma solidity ^0.8.9; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; ``` -[OpenZeppelin ERC-20 sözleşmesi](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol). Optimism, mevcut özellikler iyi denetlendiğinde ve varlıkları elinde tutacak kadar güvenilir olması gerektiğinde yeni özellikler icat edilmemesi gerektiğine inanır. +[OpenZeppelin ERC-20 sözleşmesi](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol). +Optimism, mevcut özellikler iyi denetlendiğinde ve varlıkları elinde tutacak kadar güvenilir olması gerektiğinde yeni özellikler icat edilmemesi gerektiğine inanır. ```solidity import "./IL2StandardERC20.sol"; @@ -952,10 +1014,10 @@ Bunlar, bizim ihtiyaç duyduğumuz ve normalde ERC-20'nin gerektirmediği iki ek ```solidity /** - * @param _l2Bridge Address of the L2 standard bridge. - * @param _l1Token Address of the corresponding L1 token. - * @param _name ERC20 name. - * @param _symbol ERC20 symbol. + * @param _l2Bridge K2 standart köprüsünün adresi. + * @param _l1Token İlgili K1 token'ının adresi. + * @param _name ERC20 adı. + * @param _symbol ERC20 sembolü. */ constructor( address _l2Bridge, @@ -973,7 +1035,7 @@ Bunlar, bizim ihtiyaç duyduğumuz ve normalde ERC-20'nin gerektirmediği iki ek ```solidity modifier onlyL2Bridge() { - require(msg.sender == l2Bridge, "Only L2 Bridge can mint and burn"); + require(msg.sender == l2Bridge, "Yalnızca K2 Köprüsü basım ve yakım yapabilir"); _; } @@ -988,11 +1050,12 @@ Bunlar, bizim ihtiyaç duyduğumuz ve normalde ERC-20'nin gerektirmediği iki ek } ``` -[ERC-165](https://eips.ethereum.org/EIPS/eip-165) bu şekilde çalışır. Her arayüz, desteklenen bir dizi fonksiyondur ve [özel](https://en.wikipedia.org/wiki/Exclusive_or) veya bu fonksiyonların [ABI fonksiyon seçicilerine](https://docs.soliditylang.org/en/v0.8.12/abi-spec.html#function-selector) ait olarak tanımlanır. +[ERC-165](https://eips.ethereum.org/EIPS/eip-165) bu şekilde çalışır. +Her arayüz bir dizi desteklenen fonksiyondur ve bu fonksiyonların [ABI fonksiyon seçicilerinin](https://docs.soliditylang.org/en/v0.8.12/abi-spec.html#function-selector) [özel veya](https://en.wikipedia.org/wiki/Exclusive_or) işlemi olarak tanımlanır. K2 köprüsü, varlıkları gönderdiği ERC-20 sözleşmesinin bir `IL2StandardERC20` olduğundan emin olmak için doğruluk kontrolü olarak ERC-165'i kullanır. -**Not:** Hileli sözleşmenin `supportsInterface` için yanlış yanıtlar vermesini önleyecek hiçbir şey yoktur, bu nedenle bu bir güvenlik mekanizması _değil_, doğruluk kontrol mekanizmasıdır. +**Not:** Hileli sözleşmenin `supportsInterface` için yanlış yanıtlar vermesini önleyecek hiçbir şey yoktur, bu nedenle bu bir güvenlik mekanizması değil, doğruluk kontrol mekanizmasıdır. ```solidity // slither-disable-next-line external-function @@ -1013,64 +1076,71 @@ K2 köprüsü, varlıkları gönderdiği ERC-20 sözleşmesinin bir `IL2Standard Yalnızca K2 köprüsünün varlıkları basmasına ve yakmasına izin verilir. -`_mint` ve `_burn` aslında [OpenZeppelin ERC-20 sözleşmesinde](/developers/tutorials/erc20-annotated-code/#the-_mint-and-_burn-functions-_mint-and-_burn) tanımlanmıştır. Bu sözleşme onları harici olarak ifşa etmez, çünkü token'ları basma ve yakma koşulları, ERC-20'yi kullanma yollarının sayısı kadar çeşitlidir. +`_mint` ve `_burn` aslında [OpenZeppelin ERC-20 sözleşmesinde](/developers/tutorials/erc20-annotated-code/#the-_mint-and-_burn-functions-_mint-and-_burn) tanımlanmıştır. +Bu sözleşme onları harici olarak ifşa etmez, çünkü token'ları basma ve yakma koşulları, ERC-20'yi kullanma yollarının sayısı kadar çeşitlidir. ## K2 Köprü Kodu {#l2-bridge-code} -Bu, Optimism üzerindeki köprüyü çalıştıran koddur. [Bu sözleşmenin kaynağı buradadır](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/L2StandardBridge.sol). +Bu, Optimism üzerindeki köprüyü çalıştıran koddur. +[Bu sözleşmenin kaynağı buradadır](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/L2StandardBridge.sol). ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.9; -/* Interface Imports */ +/* Arayüz İçe Aktarmaları */ import { IL1StandardBridge } from "../../L1/messaging/IL1StandardBridge.sol"; import { IL1ERC20Bridge } from "../../L1/messaging/IL1ERC20Bridge.sol"; import { IL2ERC20Bridge } from "./IL2ERC20Bridge.sol"; ``` -[IL2ERC20Bridge](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/IL2ERC20Bridge.sol) arayüzü, yukarıda gördüğümüz [K1 eş değerine](#IL1ERC20Bridge) çok benzer. İki önemli fark vardır: +[IL2ERC20Bridge](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/IL2ERC20Bridge.sol) arayüzü, yukarıda gördüğümüz [K1 eşdeğerine](#IL1ERC20Bridge) çok benzer. +İki önemli fark vardır: -1. K1'de yatırma işlemini başlatır ve çekme işlemlerini sonlandırırsınız. Burada ise çekme işlemlerini başlatır ve yatırma işlemlerini sonlandırırsınız. -2. K1'de ETH ve ERC-20 token'ları arasında ayrım yapmak gerekir. K2'de aynı fonksiyonları her ikisi için de kullanabiliriz çünkü Optimism üzerindeki dahili ETH bakiyeleri, [0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000](https://optimistic.etherscan.io/address/0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000) adresiyle bir ERC-20 token'ı olarak işlenir. +1. K1'de yatırma işlemini başlatır ve çekme işlemlerini sonlandırırsınız. + Burada ise çekme işlemlerini başlatır ve yatırma işlemlerini sonlandırırsınız. +2. K1'de ETH ve ERC-20 token'ları arasında ayrım yapmak gerekir. + K2'de aynı fonksiyonları her ikisi için de kullanabiliriz çünkü Optimism üzerindeki dahili ETH bakiyeleri, [0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000](https://explorer.optimism.io/address/0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000) adresiyle bir ERC-20 token'ı olarak işlenir. ```solidity -/* Library Imports */ +/* Kütüphane İçe Aktarmaları */ import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; import { CrossDomainEnabled } from "../../libraries/bridge/CrossDomainEnabled.sol"; import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol"; -/* Contract Imports */ +/* Sözleşme İçe Aktarmaları */ import { IL2StandardERC20 } from "../../standards/IL2StandardERC20.sol"; /** * @title L2StandardBridge - * @dev The L2 Standard bridge is a contract which works together with the L1 Standard bridge to - * enable ETH and ERC20 transitions between L1 and L2. - * This contract acts as a minter for new tokens when it hears about deposits into the L1 Standard - * bridge. - * This contract also acts as a burner of the tokens intended for withdrawal, informing the L1 - * bridge to release L1 funds. + * @dev L2 Standart köprüsü, K1 ve K2 arasında ETH ve ERC20 geçişlerini sağlamak için + * K1 Standart köprüsü ile birlikte çalışan bir sözleşmedir. + * Bu sözleşme, K1 Standart köprüsüne yapılan yatırmaları duyduğunda yeni token'lar için bir basıcı olarak görev yapar. + * + * Bu sözleşme aynı zamanda çekme amaçlı token'ların yakıcısı olarak da görev yapar ve K1 + * köprüsüne K1 fonlarını serbest bırakması için bilgi verir. */ contract L2StandardBridge is IL2ERC20Bridge, CrossDomainEnabled { /******************************** - * External Contract References * + * Harici Sözleşme Referansları * ********************************/ address public l1TokenBridge; ``` -K1 köprüsünün adresini takip edin. K1 eş değerinin aksine, burada bu değişkene _ihtiyacımız var_. K1 köprüsünün adresi önceden bilinmiyor. +K1 köprüsünün adresini takip edin. +K1 eş değerinin aksine, burada bu değişkene ihtiyacımız _var_. +K1 köprüsünün adresi önceden bilinmiyor. ```solidity /*************** - * Constructor * + * Yapıcı * ***************/ /** - * @param _l2CrossDomainMessenger Cross-domain messenger used by this contract. - * @param _l1TokenBridge Address of the L1 bridge deployed to the main chain. + * @param _l2CrossDomainMessenger Bu sözleşme tarafından kullanılan alanlar arası mesajcı. + * @param _l1TokenBridge Ana zincire dağıtılan K1 köprüsünün adresi. */ constructor(address _l2CrossDomainMessenger, address _l1TokenBridge) CrossDomainEnabled(_l2CrossDomainMessenger) @@ -1079,7 +1149,7 @@ K1 köprüsünün adresini takip edin. K1 eş değerinin aksine, burada bu deği } /*************** - * Withdrawing * + * Çekme * ***************/ /** @@ -1108,21 +1178,23 @@ K1 köprüsünün adresini takip edin. K1 eş değerinin aksine, burada bu deği } ``` -Bu iki fonksiyon çekme işlemlerini başlatır. K1 token adresini belirtmeye gerek olmadığını unutmayın. K2 token'larının bize K1 eş değerinin adresini söylemesi bekleniyor. +Bu iki fonksiyon çekme işlemlerini başlatır. +K1 token adresini belirtmeye gerek olmadığını unutmayın. +K2 token'larının bize K1 eş değerinin adresini söylemesi bekleniyor. ```solidity /** - * @dev Performs the logic for withdrawals by burning the token and informing - * the L1 token Gateway of the withdrawal. - * @param _l2Token Address of L2 token where withdrawal is initiated. - * @param _from Account to pull the withdrawal from on L2. - * @param _to Account to give the withdrawal to on L1. - * @param _amount Amount of the token to withdraw. - * @param _l1Gas Unused, but included for potential forward compatibility considerations. - * @param _data Optional data to forward to L1. This data is provided - * solely as a convenience for external contracts. Aside from enforcing a maximum - * length, these contracts provide no guarantees about its content. + * @dev Token'ı yakarak ve K1 token Ağ Geçidi'ne + * çekme hakkında bilgi vererek çekme mantığını gerçekleştirir. + * @param _l2Token Çekme işleminin başlatıldığı K2 token adresi. + * @param _from K2'de para çekme işleminin çekileceği hesap. + * @param _to K1'de para çekme işleminin verileceği hesap. + * @param _amount Çekilecek token miktarı. + * @param _l1Gas Kullanılmıyor, ancak potansiyel ileriye dönük uyumluluk considerations için dahil edilmiştir. + * @param _data K1'e iletilecek isteğe bağlı veri. Bu veri yalnızca + * harici sözleşmeler için bir kolaylık olarak sağlanır. Maksimum + * uzunluğu zorunlu kılmanın yanı sıra, bu sözleşmeler içeriği hakkında hiçbir garanti vermez. */ function _initiateWithdrawal( address _l2Token, @@ -1132,17 +1204,17 @@ Bu iki fonksiyon çekme işlemlerini başlatır. K1 token adresini belirtmeye ge uint32 _l1Gas, bytes calldata _data ) internal { - // When a withdrawal is initiated, we burn the withdrawer's funds to prevent subsequent L2 - // usage + // Bir çekme başlatıldığında, sonraki K2 kullanımını önlemek için + // çekenin fonlarını yakarız // slither-disable-next-line reentrancy-events IL2StandardERC20(_l2Token).burn(msg.sender, _amount); ``` -`_from` parametresine _değil_, sahte olması çok daha zor olan (bildiğim kadarıyla imkansız) `msg.sender` parametresine güvendiğimize dikkat edin. +`_from` parametresine değil, sahte olması çok daha zor olan (bildiğim kadarıyla imkansız) `msg.sender`'a güvendiğimize dikkat edin. ```solidity - // Construct calldata for l1TokenBridge.finalizeERC20Withdrawal(_to, _amount) + // l1TokenBridge.finalizeERC20Withdrawal(_to, _amount) için çağrı verisi oluştur // slither-disable-next-line reentrancy-events address l1Token = IL2StandardERC20(_l2Token).l1Token(); bytes memory message; @@ -1172,7 +1244,7 @@ K1'de ETH ve ERC-20 arasında ayrım yapmak gerekir. ); } - // Send message up to L1 bridge + // Mesajı K1 köprüsüne gönder // slither-disable-next-line reentrancy-events sendCrossDomainMessage(l1TokenBridge, _l1Gas, message); @@ -1181,7 +1253,7 @@ K1'de ETH ve ERC-20 arasında ayrım yapmak gerekir. } /************************************ - * Cross-chain Function: Depositing * + * Çapraz zincir Fonksiyonu: Yatırma * ************************************/ /** @@ -1202,11 +1274,12 @@ Bu fonksiyon, `L1StandardBridge` tarafından çağrılır. ) external virtual onlyFromCrossDomainAccount(l1TokenBridge) { ``` -Mesajın kaynağının meşru olduğundan emin olun. Bu, fonksiyon `_mint`'i çağırdığı ve köprünün Katman 1'de sahip olduğu token'lar tarafından kapsanmayan token'ları vermek için kullanılabileceği için önemlidir. +Mesajın kaynağının meşru olduğundan emin olun. +Bu, fonksiyon `_mint`'i çağırdığı ve köprünün K1'de sahip olduğu token'lar tarafından kapsanmayan token'ları vermek için kullanılabileceği için önemlidir. ```solidity - // Check the target token is compliant and - // verify the deposited token on L1 matches the L2 deposited token representation here + // Hedef token'ın uyumlu olup olmadığını kontrol edin ve + // K1'de yatırılan token'ın buradaki K2 yatırılan token gösterimiyle eşleştiğini doğrulayın if ( // slither-disable-next-line reentrancy-events ERC165Checker.supportsInterface(_l2Token, 0x1d1d8b63) && @@ -1216,12 +1289,12 @@ Mesajın kaynağının meşru olduğundan emin olun. Bu, fonksiyon `_mint`'i ça Doğruluk testleri: 1. Doğru arayüz destekleniyor -2. L2 ERC-20 sözleşmesinin Katman 1 adresi, token'ların Katman 1 kaynağıyla eşleşiyor +2. K2 ERC-20 sözleşmesinin K1 adresi, token'ların K1 kaynağıyla eşleşiyor ```solidity ) { - // When a deposit is finalized, we credit the account on L2 with the same amount of - // tokens. + // Bir yatırma sonlandırıldığında, K2'deki hesaba aynı miktarda + // token yatırırız. // slither-disable-next-line reentrancy-events IL2StandardERC20(_l2Token).mint(_to, _amount); // slither-disable-next-line reentrancy-events @@ -1235,30 +1308,31 @@ Doğruluk testlerini geçerse yatırmayı tamamlayın: ```solidity } else { - // Either the L2 token which is being deposited-into disagrees about the correct address - // of its L1 token, or does not support the correct interface. - // This should only happen if there is a malicious L2 token, or if a user somehow - // specified the wrong L2 token address to deposit into. - // In either case, we stop the process here and construct a withdrawal - // message so that users can get their funds out in some cases. - // There is no way to prevent malicious token contracts altogether, but this does limit - // user error and mitigate some forms of malicious contract behavior. + // Yatırılan K2 token'ı, K1 token'ının doğru adresi + // konusunda aynı fikirde değil veya doğru arayüzü desteklemiyor. + // Bu yalnızca kötü niyetli bir K2 token'ı olduğunda veya bir kullanıcı bir şekilde + // yatırmak için yanlış K2 token adresi belirttiğinde gerçekleşmelidir. + // Her iki durumda da süreci burada durdurur ve bir çekme + // mesajı oluştururuz, böylece kullanıcılar bazı durumlarda fonlarını geri alabilir. + // Kötü niyetli token sözleşmelerini tamamen önlemenin bir yolu yoktur, ancak bu + // kullanıcı hatasını sınırlar ve bazı kötü niyetli sözleşme davranışlarını azaltır. ``` -Bir kullanıcı yanlış Katman 2 token adresini kullanarak tespit edilebilir bir hata yaptıysa, yatırmayı iptal etmek ve tokenları Katman 1'e iade etmek istiyoruz. Bunu Katman 2'den yapabilmemizin tek yolu, hata meydan okuma süresini beklemek zorunda kalacak bir mesaj göndermektir ancak bu, kullanıcı için token'ları kalıcı olarak kaybetmekten çok daha iyidir. +Bir kullanıcı yanlış K2 token adresini kullanarak tespit edilebilir bir hata yaptıysa, yatırmayı iptal etmek ve token'ları K1'e iade etmek istiyoruz. +Bunu K2'den yapabilmemizin tek yolu, hata meydan okuma süresini beklemek zorunda kalacak bir mesaj göndermektir ancak bu, kullanıcı için token'ları kalıcı olarak kaybetmekten çok daha iyidir. ```solidity bytes memory message = abi.encodeWithSelector( IL1ERC20Bridge.finalizeERC20Withdrawal.selector, _l1Token, _l2Token, - _to, // switched the _to and _from here to bounce back the deposit to the sender + _to, // yatırmayı gönderene geri göndermek için _to ve _from'u burada değiştirdik _from, _amount, _data ); - // Send message up to L1 bridge + // Mesajı K1 köprüsüne gönder // slither-disable-next-line reentrancy-events sendCrossDomainMessage(l1TokenBridge, 0, message); // slither-disable-next-line reentrancy-events @@ -1270,8 +1344,13 @@ Bir kullanıcı yanlış Katman 2 token adresini kullanarak tespit edilebilir bi ## Sonuç {#conclusion} -Standart köprü, varlık aktarımları için en esnek mekanizmadır. Ancak çok genel olduğu için her zaman kullanması en kolay olan mekanizma değildir. Özellikle çekimler için, çoğu kullanıcı meydan okuma süresini beklemeyen ve çekimi sonlandırmak için bir Merkle ispatı gerektirmeyen [üçüncü parti köprüleri](https://optimism.io/apps#bridge) kullanmayı tercih eder. +Standart köprü, varlık aktarımları için en esnek mekanizmadır. +Ancak çok genel olduğu için her zaman kullanması en kolay olan mekanizma değildir. +Özellikle çekimler için, çoğu kullanıcı meydan okuma süresini beklemeyen ve çekimi sonlandırmak için bir Merkle ispatı gerektirmeyen [üçüncü parti köprüleri](https://optimism.io/apps#bridge) kullanmayı tercih eder. -Bu köprüler genellikle Katman 1 üzerinde küçük bir ücret (genelde bir standart köprü çekiminin gaz ücretinden daha azına) için anında sağladıkları varlıklara sahip olarak çalışırlar. Köprü (ya da onu çalıştıran insanlar) Katman 1 varlıklarının azaldığını sezdiğinde Katman 2'den yeteri kadar varlığı aktarır. Bunlar çok büyük çekimler olduğu için, çekim ücreti büyük bir miktar üzerinden amorti edilmiştir ve daha küçük bir yüzdeliktir. +Bu köprüler genellikle K1 üzerinde küçük bir ücret (genelde bir standart köprü çekiminin gaz ücretinden daha azına) için anında sağladıkları varlıklara sahip olarak çalışırlar. +Köprü (ya da onu çalıştıran insanlar) K1 varlıklarının azaldığını sezdiğinde K2'den yeteri kadar varlığı aktarır. Bunlar çok büyük çekimler olduğu için, çekim ücreti büyük bir miktar üzerinden amorti edilmiştir ve daha küçük bir yüzdeliktir. Umarım bu makale katman 2'nin nasıl çalıştığı hakkında dahasını anlamanıza; temiz ve güvenli Solidity kodu yazmanıza yardımcı olmuştur. + +[Çalışmalarımdan daha fazlası için buraya bakın](https://cryptodocguy.pro/). diff --git a/public/content/translations/tr/developers/tutorials/reverse-engineering-a-contract/index.md b/public/content/translations/tr/developers/tutorials/reverse-engineering-a-contract/index.md index 727c73dffea..52fbdd15047 100644 --- a/public/content/translations/tr/developers/tutorials/reverse-engineering-a-contract/index.md +++ b/public/content/translations/tr/developers/tutorials/reverse-engineering-a-contract/index.md @@ -1,102 +1,100 @@ --- -title: "Sözleşmeye Tersine Mühendislik Uygulama" -description: Kaynak koduna sahip olmadığınız bir sözleşmeyi anlama +title: "Reverse Engineering a Contract" +description: How to understand a contract when you don't have the source code author: Ori Pomerantz lang: tr -tags: - - "EVM" - - "işlem kodları" +tags: [ "evm", "opcodes" ] skill: advanced published: 2021-12-30 --- ## Giriş {#introduction} -_Blokzincirde sır yoktur_; her şey tutarlı, doğrulanabilir ve herkes tarafından erişilebilirdir. İdeal olarak [sözleşmelerin kaynak kodları Etherscan'de yayımlanmalı ve doğrulanmalıdır](https://etherscan.io/address/0xb8901acb165ed027e32754e0ffe830802919727f#code). Fakat, [durum her zaman böyle değildir](https://etherscan.io/address/0x2510c039cc3b061d79e564b38836da87e31b342f#code). Bu makalede, kaynak kodu olmayan bir sözleşmeye bakarak sözleşmelerde tersine mühendislik yapmayı öğreneceksiniz, [`0x2510c039cc3b061d79e564b38836da87e31b342f`](https://etherscan.io/address/0x2510c039cc3b061d79e564b38836da87e31b342f). +_There are no secrets on the blockchain_, everything that happens is consistent, verifiable, and publicly available. Ideally, [contracts should have their source code published and verified on Etherscan](https://etherscan.io/address/0xb8901acb165ed027e32754e0ffe830802919727f#code). However, [that is not always the case](https://etherscan.io/address/0x2510c039cc3b061d79e564b38836da87e31b342f#code). In this article you learn how to reverse engineer contracts by looking at a contract without source code, [`0x2510c039cc3b061d79e564b38836da87e31b342f`](https://etherscan.io/address/0x2510c039cc3b061d79e564b38836da87e31b342f). -Ters derleyiciler vardır, fakat her zaman [ kullanılabilir sonuçlar](https://etherscan.io/bytecode-decompiler?a=0x2510c039cc3b061d79e564b38836da87e31b342f) üretmezler. Bu makalede manuel olarak bir sözleşmeye [işlem kodlarından](https://github.com/wolflo/evm-opcodes) nasıl ters mühendislik yapabileceğinizi, sözleşmeyi nasıl anlayacağınızı ve bununla birlikte bir ters derleyicinin sonuçlarını nasıl yorumlayacağınızı öğreneceksiniz. +There are reverse compilers, but they don't always produce [usable results](https://etherscan.io/bytecode-decompiler?a=0x2510c039cc3b061d79e564b38836da87e31b342f). In this article you learn how to manually reverse engineer and understand a contract from [the opcodes](https://github.com/wolflo/evm-opcodes), as well as how to interpret the results of a decompiler. -Bu makaleyi anlayabilmek için Ethereum Sanal Makinesi'nin temellerini çoktan biliyor olmalı ve en azından Ethereum Sanal Makinesi'nin derleyicisine aşina olmalısınız. [Bu konuları buradan okuyabilirsiniz](https://medium.com/mycrypto/the-ethereum-virtual-machine-how-does-it-work-9abac2b7c9e). +To be able to understand this article you should already know the basics of the EVM, and be at least somewhat familiar with EVM assembler. [You can read about these topics here](https://medium.com/mycrypto/the-ethereum-virtual-machine-how-does-it-work-9abac2b7c9e). -## Yürütülebilir Kodu Hazırlama {#prepare-the-executable-code} +## Prepare the Executable Code {#prepare-the-executable-code} -İşlem kodlarını sözleşme için Etherscan'e gidip **Sözleşme** seçeneğine ve sonrasında **İşlem Kodu Görünümüne Geç**'e tıklayarak alabilirsiniz. Bir satıra bir işlem kodunun düştüğü bir görünüm elde edeceksiniz. +You can get the opcodes by going to Etherscan for the contract, clicking the **Contract** tab and then **Switch to Opcodes View**. You get a view that is one opcode per line. -![Etherscan'den İşlem Kodu Görünümü](opcode-view.png) +![Opcode View from Etherscan](opcode-view.png) -Bununla birlikte, sıçramaları anlayabilmek için her kodda işlem kodunun nerede olduğunu bilmeniz gerekir. Bunu yapmanın bir yolu, bir Google Elektronik Tablosu açıp işlem kodlarını C sütununa yapıştırmaktır. [Önceden hazırlanmış bu elektronik tablonun bir kopyasını oluşturarak sonraki adımları atlayabilirsiniz](https://docs.google.com/spreadsheets/d/1tKmTJiNjUwHbW64wCKOSJxHjmh0bAUapt6btUYE7kDA/edit?usp=sharing). +To be able to understand jumps, however, you need to know where in the code each opcode is located. To do that, one way is to open a Google Spreadsheet and paste the opcodes in column C. [You can skip the following steps by making a copy of this already prepared spreadsheet](https://docs.google.com/spreadsheets/d/1tKmTJiNjUwHbW64wCKOSJxHjmh0bAUapt6btUYE7kDA/edit?usp=sharing). -Sonraki adım, sıçramaları anlayabilmemiz için doğru kod konumlarını almaktır. B sütununa işlem kodu boyutunu, A sütünuna da (onaltılık olarak) konumu koyacağız. `B1` hücresine bu fonksiyonu yazın ve kodun sonuna kadar B sütunun geri kalanı için kopyalayıp yapıştırın. Bunu yaptıktan sonra B sütununu gizleyebilirsiniz. +The next step is to get the correct code locations so we'll be able to understand jumps. We'll put the opcode size in column B, and the location (in hexadecimal) in column A. Type this function in cell `B1` and then copy and paste it for the rest of column B, until the end of the code. After you do this you can hide column B. ``` =1+IF(REGEXMATCH(C1,"PUSH"),REGEXEXTRACT(C1,"PUSH(\d+)"),0) ``` -İlk olarak bu fonksiyon işlem kodunun kendisi için bir bayt ekler, sonra da `PUSH` araması yapar. İtme işlem kodları özeldir, çünkü itilen değer için ekstra baytlara sahip olmak zorundadırlar. Eğer işlem kodu bir `PUSH` ise, bayt sayısını çıkarır ve ekleriz. +First this function adds one byte for the opcode itself, and then looks for `PUSH`. Push opcodes are special because they need to have additional bytes for the value being pushed. If the opcode is a `PUSH`, we extract the number of bytes and add that. -`A1`'e ilk kayma olan 0'ı koyun. Ardından `A2`'ye bu fonksiyonu koyun ve yine A sütununun geri kalanı için kopyalayıp yapıştırın: +In `A1` put the first offset, zero. Then, in `A2`, put this function and again copy and paste it for the rest of column A: ``` =dec2hex(hex2dec(A1)+B1) ``` -Bu fonksiyonun bize onaltılık bir değer vermesine ihtiyacımız var çünkü sıçramalardan (`JUMP` and `JUMPI`) önceki itilen değerler de bize onaltılık şekilde verilir. +We need this function to give us the hexadecimal value because the values that are pushed prior to jumps (`JUMP` and `JUMPI`) are given to us in hexadecimal. -## Giriş Noktası (0x00) {#the-entry-point-0x00} +## The Entry Point (0x00) {#the-entry-point-0x00} -Sözleşmeler her zaman ilk bayttan yürütülür. Bu kodun ilk kısmıdır: +Contracts are always executed from the first byte. This is the initial part of the code: -| Offset | İşlem kodları | Yığın (işlem kodundan sonra) | -| -----: | ------------- | ---------------------------- | -| 0 | PUSH1 0x80 | 0x80 | -| 2 | PUSH1 0x40 | 0x40, 0x80 | -| 4 | MSTORE | Boş | -| 5 | PUSH1 0x04 | 0x04 | -| 7 | CALLDATASIZE | CALLDATASIZE 0x04 | -| 8 | LT | CALLDATASIZE\<4 | -| 9 | PUSH2 0x005e | 0x5E CALLDATASIZE\<4 | -| C | JUMPI | Boş | +| Offset | Opcode | Stack (after the opcode) | +| -----: | ------------ | ---------------------------------------------- | +| 0 | PUSH1 0x80 | 0x80 | +| 2 | PUSH1 0x40 | 0x40, 0x80 | +| 4 | MSTORE | Empty | +| 5 | PUSH1 0x04 | 0x04 | +| 7 | CALLDATASIZE | CALLDATASIZE 0x04 | +| 8 | LT | CALLDATASIZE\<4 | +| 9 | PUSH2 0x005e | 0x5E CALLDATASIZE\<4 | +| C | JUMPI | Boş | -Bu kod iki şey yapar: +This code does two things: -1. 0x80'i 0x40-0x5F bellek konumlarına 32 baytlık bir değer olarak (0x80, 0x5F'de depolanır ve 0x40-0x5E tamamen sıfırlardan oluşur) yazın. -2. Çağrı verisini boyutunu okuyun. Ethereum sözleşmesi için olan bir çağrı verisi normalde, fonksiyon seçici için minimum 4 bayta ihtiyaç duyan [ABI'yi (uygulama ikili arayüzü)](https://docs.soliditylang.org/en/v0.8.10/abi-spec.html) takip eder. Eğer çağrı verisi boyutu dörtten azsa, 0x5E'ye sıçrayın. +1. Write 0x80 as a 32 byte value to memory locations 0x40-0x5F (0x80 is stored in 0x5F, and 0x40-0x5E are all zeroes). +2. Read the calldata size. Normally the call data for an Ethereum contract follows [the ABI (application binary interface)](https://docs.soliditylang.org/en/v0.8.10/abi-spec.html), which at a minimum requires four bytes for the function selector. If the call data size is less than four, jump to 0x5E. -![Bu kısım için akış şeması](flowchart-entry.png) +![Flowchart for this portion](flowchart-entry.png) -### 0X5E'deki (ABI olmayan çağrı verisi) İşleyici {#the-handler-at-0x5e-for-non-abi-call-data} +### The Handler at 0x5E (for non-ABI call data) {#the-handler-at-0x5e-for-non-abi-call-data} -| Offset | Opcode | +| Offset | İşlem kodu | | -----: | ------------ | | 5E | JUMPDEST | | 5F | CALLDATASIZE | | 60 | PUSH2 0x007c | | 63 | JUMPI | -Bu kod parçası bir `JUMPDEST` ile başlar. Eğer `JUMPDEST` olmayan bir işlem koduna sıçrama yaparsanız EVM (Ethereum Sanal Makinesi) bir istisna verir. Ardından CALLDATASIZE'a bakar ve eğer "doğru" ise (sıfır değilse) 0x7C'ye sıçrar. Buna aşağıda değineceğiz. +This snippet starts with a `JUMPDEST`. EVM (Ethereum virtual machine) programs throw an exception if you jump to an opcode that isn't `JUMPDEST`. Then it looks at the CALLDATASIZE, and if it is "true" (that is, not zero) jumps to 0x7C. We'll get to that below. -| Offset | Opcode | Stack (opcode'dan sonra) | -| -----: | ---------- | ------------------------------------------------------------------------------ | -| 64 | CALLVALUE | Çağrı tarafından sağlanan [wei](/glossary/#wei). Solidity'de `msg.value` denir | -| 65 | PUSH1 0x06 | 6 CALLVALUE | -| 67 | PUSH1 0x00 | 0 6 CALLVALUE | -| 69 | DUP3 | CALLVALUE 0 6 CALLVALUE | -| 6A | DUP3 | 6 CALLVALUE 0 6 CALLVALUE | -| 6B | SLOAD | Storage[6] CALLVALUE 0 6 CALLVALUE | +| Offset | İşlem kodu | Stack (after opcode) | +| -----: | ---------- | ------------------------------------------------------------------------------------------ | +| 64 | CALLVALUE | [Wei](/glossary/#wei) provided by the call. Called `msg.value` in Solidity | +| 65 | PUSH1 0x06 | 6 CALLVALUE | +| 67 | PUSH1 0x00 | 0 6 CALLVALUE | +| 69 | DUP3 | CALLVALUE 0 6 CALLVALUE | +| 6A | DUP3 | 6 CALLVALUE 0 6 CALLVALUE | +| 6B | SLOAD | Storage[6] CALLVALUE 0 6 CALLVALUE | -Yani hiç çağrı verisi olmadığında Depo[6] değerini okuruz. Bu değerin ne olduğunu henüz bilmiyoruz, fakat sözleşmenin hiç çağrı verisi almadığı işlemleri arayabiliriz. Çağrı verisi olmadan (bu sebeple yöntem da olmadan) ETH transfer eden işlemler için Etherscan'de `Transfer` adında bir yöntem vardır. Aslında, [sözleşmenin aldığı ilk işlem](https://etherscan.io/tx/0xeec75287a583c36bcc7ca87685ab41603494516a0f5986d18de96c8e630762e7) bir transferdir. +So when there is no call data we read the value of Storage[6]. We don't know what this value is yet, but we can look for transactions that the contract received with no call data. Transactions which just transfer ETH without any call data (and therefore no method) have in Etherscan the method `Transfer`. In fact, [the very first transaction the contract received](https://etherscan.io/tx/0xeec75287a583c36bcc7ca87685ab41603494516a0f5986d18de96c8e630762e7) is a transfer. -Eğer işleme bakıp **Daha fazlası için tıklayın** öğesine tıklarsak, girdi verileri de denen çağrı verilerinin aslında boş olduğunu (`0x`) görürüz. Değerin 1,559 ETH olduğuna da dikkat edin, daha sonra işimize yarayacak. +If we look in that transaction and click **Click to see More**, we see that the call data, called input data, is indeed empty (`0x`). Notice also that the value is 1.559 ETH, that will be relevant later. -![Çağrı verisi boş](calldata-empty.png) +![The call data is empty](calldata-empty.png) -Şimdi, **Durum** sekmesine tıklayın ve tersine mühendislik yaptığımız sözleşmeyi (0x2510...) genişletin. İşlem sırasında `Storage[6]`'ın değiştiğini görebilirsiniz, eğer Onaltılığı **Sayı** olarak değiştirirseniz değerin, bir sonraki sözleşme değerine karşılık gelen 1.559.000.000.000.000.000'a dönüştüğünü görebilirsiniz, bu değer wei cinsindendir (noktaları kolay anlaşılması için ekledim). +Next, click the **State** tab and expand the contract we're reverse engineering (0x2510...). You can see that `Storage[6]` did change during the transaction, and if you change Hex to **Number**, you see it became 1,559,000,000,000,000,000, the value transferred in wei (I added the commas for clarity), corresponding to the next contract value. -![Storage[6]'daki değişiklik](storage6.png) +![The change in Storage[6]](storage6.png) -Aynı zaman aralığında [diğer `Transfer` işlemlerinden kaynaklanan durum değişikliklerine baktığımızda](https://etherscan.io/tx/0xf708d306de39c422472f43cb975d97b66fd5d6a6863db627067167cbf93d84d1#statechange) `Storage[6]`'ın, sözleşmenin değerini bir süre takip ettiğiniz görürüz. Şimdilik buna `Value*` adını vereceğiz. Buradaki yıldız işareti (`*`), henüz bu değişkenin ne yaptığını _bilmediğimizi_ hatırlatır, fakat bu sadece sözleşme değerini takip etmeye yönelik olamaz çünkü hesap bakiyenizi `ADDRESS BALANCE`'ı kullanarak görebilirken depolamayı kullanmaya gerek yoktur ve zaten çok pahalıdır. İlk işlem kodu sözleşmenin kendi adresini iter. İkincisi de yığının en üstündeki adresi okur ve bunu hesabın bakiyesiyle değiştirir. +If we look in the state changes caused by [other `Transfer` transactions from the same period](https://etherscan.io/tx/0xf708d306de39c422472f43cb975d97b66fd5d6a6863db627067167cbf93d84d1#statechange) we see that `Storage[6]` tracked the value of the contract for a while. For now we'll call it `Value*`. The asterisk (`*`) reminds us that we don't _know_ what this variable does yet, but it can't be just to track the contract value because there's no need to use storage, which is very expensive, when you can get your accounts balance using `ADDRESS BALANCE`. The first opcode pushes the contract's own address. The second one reads the address at the top of the stack and replaces it with the balance of that address. -| Offset | Opcode | Yığın | +| Offset | İşlem kodu | Yığın | | -----: | ------------ | ------------------------------------------- | | 6C | PUSH2 0x0075 | 0x75 Value\* CALLVALUE 0 6 CALLVALUE | | 6F | SWAP2 | CALLVALUE Value\* 0x75 0 6 CALLVALUE | @@ -104,205 +102,205 @@ Aynı zaman aralığında [diğer `Transfer` işlemlerinden kaynaklanan durum de | 71 | PUSH2 0x01a7 | 0x01A7 Value\* CALLVALUE 0x75 0 6 CALLVALUE | | 74 | JUMP | | -Bu kodu sıçrama hedefinde takip etmeye devam edeceğiz. +We'll continue to trace this code at the jump destination. -| Offset | Opcode | Yığın | +| Offset | İşlem kodu | Yığın | | -----: | ---------- | ----------------------------------------------------------- | | 1A7 | JUMPDEST | Value\* CALLVALUE 0x75 0 6 CALLVALUE | | 1A8 | PUSH1 0x00 | 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | | 1AA | DUP3 | CALLVALUE 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | | 1AB | NOT | 2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | -`NOT` bitseldir, bu yüzden çağrı değerindeki her bitin değerini tersine çevirir. +The `NOT` is bitwise, so it reverses the value of every bit in the call value. -| Offset | Opcode | Yığın | -| -----: | ------------ | --------------------------------------------------------------------------- | -| 1AC | DUP3 | Value\* 2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | -| 1AD | GT | Value\*>2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| Offset | İşlem kodu | Yığın | +| -----: | ------------ | ------------------------------------------------------------------------------------------------------ | +| 1AC | DUP3 | Value\* 2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1AD | GT | Value\*>2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | | 1AE | ISZERO | Value\*\<=2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | | 1AF | PUSH2 0x01df | 0x01DF Value\*\<=2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | -| 1B2 | JUMPI | | +| 1B2 | JUMPI | | -Eğer `Value*`, 2^256-CALLVALUE-1'den küçük ya da ona eşitse sıçrarız. Bu, taşmayı engelleme mantığına benzer. Ve gerçekten de, 0x01DE ofsetinde birkaç anlamsız işlemden sonra (örneğin belleğe yazma silinmek üzere) normal davranış olan taşma algılanırsa sözleşmenin geri döndüğünü görüyoruz. +We jump if `Value*` is smaller than 2^256-CALLVALUE-1 or equal to it. This looks like logic to prevent overflow. And indeed, we see that after a few nonsense operations (writing to memory is about to get deleted, for example) at offset 0x01DE the contract reverts if the overflow is detected, which is normal behavior. -Bunun gibi bir taşmanın oldukça uzak bir ihtimal olduğunu da gözden kaçırmayın. Çünkü böyle bir taşma, çağrı değeri ile `Value*` toplamının 2^256 wei ya da 10^59 ETH gibi bir değer civarında olmasını gerektirir. [Toplam ETH arzı, yazıyla iki yüz milyondan azdır](https://etherscan.io/stat/supply). +Note that such an overflow is extremely unlikely, because it would require the call value plus `Value*` to be comparable to 2^256 wei, about 10^59 ETH. [The total ETH supply, at writing, is less than two hundred million](https://etherscan.io/stat/supply). -| Offset | Opcode | Yığın | -| -----: | -------- | ----------------------------------------- | -| 1DF | JUMPDEST | 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | -| 1E0 | POP | Value\* CALLVALUE 0x75 0 6 CALLVALUE | -| 1E1 | EKLE | Value\*+CALLVALUE 0x75 0 6 CALLVALUE | -| 1E2 | SWAP1 | 0x75 Value\*+CALLVALUE 0 6 CALLVALUE | -| 1E3 | JUMP | | +| Offset | İşlem kodu | Yığın | +| -----: | ---------- | ----------------------------------------- | +| 1DF | JUMPDEST | 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1E0 | POP | Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1E1 | EKLE | Value\*+CALLVALUE 0x75 0 6 CALLVALUE | +| 1E2 | SWAP1 | 0x75 Value\*+CALLVALUE 0 6 CALLVALUE | +| 1E3 | JUMP | | -Eğer buraya geldiysek `Value* + CALLVALUE` değerini alalım ve kayma 0x75 değerine sıçrayalım. +If we got here, get `Value* + CALLVALUE` and jump to offset 0x75. -| Offset | Opcode | Yığın | -| -----: | -------- | ------------------------------- | -| 75 | JUMPDEST | Value\*+CALLVALUE 0 6 CALLVALUE | -| 76 | SWAP1 | 0 Value\*+CALLVALUE 6 CALLVALUE | -| 77 | SWAP2 | 6 Value\*+CALLVALUE 0 CALLVALUE | -| 78 | SSTORE | 0 CALLVALUE | +| Offset | İşlem kodu | Yığın | +| -----: | ---------- | ------------------------------- | +| 75 | JUMPDEST | Value\*+CALLVALUE 0 6 CALLVALUE | +| 76 | SWAP1 | 0 Value\*+CALLVALUE 6 CALLVALUE | +| 77 | SWAP2 | 6 Value\*+CALLVALUE 0 CALLVALUE | +| 78 | SSTORE | 0 CALLVALUE | -Buraya gelince de (bu, çağrı verisinin boş olmasını gerektirir), `Value*`'yu çağrı değerine ekleyelim. Bu `Transfer` işlemlerinin yaptıkları ile tutarlıdır. +If we get here (which requires the call data to be empty) we add to `Value*` the call value. This is consistent with what we say `Transfer` transactions do. -| Offset | Opcode | -| -----: | ------ | -| 79 | POP | -| 7A | POP | -| 7B | STOP | +| Offset | İşlem kodu | +| -----: | ---------- | +| 79 | POP | +| 7A | POP | +| 7B | STOP | -Son olarak, yığını temizleyin (aslında pek de gerekli değildir) ve işlemin başarıyla tamamlandığına dair sinyali verin. +Finally, clear the stack (which isn't necessary) and signal the successful end of the transaction. -Hepsini özetlemek için işte başlangıçtaki kod için bir akış şeması. +To sum it all up, here's a flowchart for the initial code. -![Giriş noktası akış şeması](flowchart-entry.png) +![Entry point flowchart](flowchart-entry.png) -## 0x7C'deki İşleyici {#the-handler-at-0x7c} +## The Handler at 0x7C {#the-handler-at-0x7c} -Bu işleyicinin ne yaptığını bilerek başlığa koymadım. Buradaki amaç, size bu spesifik sözleşmenin nasıl çalıştığını değil, sözleşmelere nasıl tersine mühendislik yapacağınızı öğretmek. Ne yaptığını benimle aynı şekilde öğreneceksiniz, yani kodu takip ederek. +I purposely did not put in the heading what this handler does. The point isn't to teach you how this specific contract works, but how to reverse engineer contracts. You will learn what it does the same way I did, by following the code. -Buraya birkaç farklı yerden geliriz: +We get here from several places: -- Eğer çağrı verisi 1, 2 ya da 3 baytsa (0x63 kaymasından) -- Eğer yöntem imzası bilinmiyorsa (0x42 ve 0x5D kaymalarından) +- If there is call data of 1, 2, or 3 bytes (from offset 0x63) +- If the method signature is unknown (from offsets 0x42 and 0x5D) -| Offset | Opcode | Yığın | -| -----: | ------------ | -------------------- | -| 7C | JUMPDEST | | -| 7D | PUSH1 0x00 | 0x00 | -| 7F | PUSH2 0x009d | 0x9D 0x00 | -| 82 | PUSH1 0x03 | 0x03 0x9D 0x00 | +| Offset | İşlem kodu | Yığın | +| -----: | ------------ | ------------------------------------------------------------------------ | +| 7C | JUMPDEST | | +| 7D | PUSH1 0x00 | 0x00 | +| 7F | PUSH2 0x009d | 0x9D 0x00 | +| 82 | PUSH1 0x03 | 0x03 0x9D 0x00 | | 84 | SLOAD | Storage[3] 0x9D 0x00 | -Bu başka bir depolama hücresidir, herhangi bir işlemde bulamadığım bir hücre. Bu yüzden bunun ne anlama geldiğini bilmek biraz daha zor. Aşağıdaki kod bunu daha açık hale getirecektir. +This is another storage cell, one that I couldn't find in any transactions so it's harder to know what it means. The code below will make it clearer. -| Offset | Opcode | Yığın | -| -----: | ------------------------------------------------- | ------------------------------- | +| Offset | İşlem kodu | Yığın | +| -----: | ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | 85 | PUSH20 0xffffffffffffffffffffffffffffffffffffffff | 0xff....ff Storage[3] 0x9D 0x00 | -| 9A | AND | Storage[3]-as-address 0x9D 0x00 | - -Bu işlem kodları Storage[3]'den okuduğumuz değeri 160 bite kırpar, bu da bir Ethereum adresinin uzunluğudur. - -| Offset | Opcode | Yığın | -| -----: | ------ | ------------------------------- | -| 9B | SWAP1 | 0x9D Storage[3]-as-address 0x00 | -| 9C | JUMP | Storage[3]-as-address 0x00 | - -Bu sıçrama sadece bir sonraki işlem koduna gideceğimiz için gereksizdir. Bu kod, ulaşabileceği gaz verimliliğine yakın bile değildir. - -| Offset | İşlem kodları | Yığın | -| -----: | ------------- | ------------------------------- | -| 9D | JUMPDEST | Storage[3]-as-address 0x00 | -| 9E | SWAP1 | 0x00 Storage[3]-as-address | -| 9F | POP | Storage[3]-as-address | -| A0 | PUSH1 0x40 | 0x40 Storage[3]-as-address | -| A2 | MLOAD | Mem[0x40] Storage[3]-as-address | - -Bu kodun en başında Mem[0x40]'i 0x80 olarak ayarlıyoruz. 0x40'ı aradığımızda, değiştirmediğimizi görüyoruz; yani 0x80 olduğunu varsayabiliriz. - -| Offset | İşlem kodları | Yığın | -| -----: | ------------- | ------------------------------------------------- | -| A3 | CALLDATASIZE | CALLDATASIZE 0x80 Storage[3]-as-address | -| A4 | PUSH1 0x00 | 0x00 CALLDATASIZE 0x80 Storage[3]-as-address | -| A6 | DUP3 | 0x80 0x00 CALLDATASIZE 0x80 Storage[3]-as-address | -| A7 | CALLDATACOPY | 0x80 Storage[3]-as-address | - -0x80'den başlayarak tüm veriyi belleğe kopyalayın. - -| Offset | İşlem kodu | Yığın | -| -----: | ------------- | -------------------------------------------------------------------------------- | -| A8 | PUSH1 0x00 | 0x00 0x80 Storage[3]-as-address | -| AA | DUP1 | 0x00 0x00 0x80 Storage[3]-as-address | -| AB | CALLDATASIZE | CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address | -| AC | DUP4 | 0x80 CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address | -| AD | DUP6 | Storage[3]-as-address 0x80 CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address | -| AE | GAS | GAS Storage[3]-as-address 0x80 CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address | -| AF | DELEGATE_CALL | | - -Şimdi her şey daha açık. Bu sözleşme asıl işi yapması için Storage[3]'teki adresi arayan bir [vekil](https://blog.openzeppelin.com/proxy-patterns/) olarak hareket edebilir. `DELEGATE_CALL` ayrı bir sözleşmeye çağrı yapar, fakat aynı depoda kalır. Bu, vekili olduğumuz yetkili sözleşmenin aynı depolama alanına eriştiği anlamına gelir. Bu çağrı için parametreler şu şekildedir: - -- _Gaz_: Kalan tüm gaz -- _Aranan adres_: Adres-olarak-Storage[3] -- _Çağrı verisi_ Orijinal çağrı verisini koyduğumuz 0x80'den başlayan CALLDATASIZE baytları -- _Dönen veri_: Yok (0x00 - 0x00) Dönen veriyi başka şekillerde alacağız (aşağıya bakın) - -| Offset | İşlem kodları | Yığın | -| -----: | -------------- | --------------------------------------------------------------------------------------------- | +| 9A | AND | Storage[3]-as-address 0x9D 0x00 | + +These opcodes truncate the value we read from Storage[3] to 160 bits, the length of an Ethereum address. + +| Offset | İşlem kodu | Yığın | +| -----: | ---------- | ----------------------------------------------------------------------------------- | +| 9B | SWAP1 | 0x9D Storage[3]-as-address 0x00 | +| 9C | JUMP | Storage[3]-as-address 0x00 | + +This jump is superfluous, since we're going to the next opcode. This code isn't nearly as gas-efficient as it could be. + +| Offset | İşlem kodu | Yığın | +| -----: | ---------- | --------------------------------------------------------------------------------------------------------------------------------------- | +| 9D | JUMPDEST | Depolama[3]-as-address 0x00 | +| 9E | SWAP1 | 0x00 Storage[3]-as-address | +| 9F | POP | Storage[3]-as-address | +| A0 | PUSH1 0x40 | 0x40 Storage[3]-as-address | +| A2 | MLOAD | Mem[0x40] Storage[3]-as-address | + +In the very beginning of the code we set Mem[0x40] to 0x80. If we look for 0x40 later, we see that we don't change it - so we can assume it is 0x80. + +| Offset | İşlem kodu | Yığın | +| -----: | ------------ | ----------------------------------------------------------------------------------------------------- | +| A3 | CALLDATASIZE | CALLDATASIZE 0x80 Storage[3]-as-address | +| A4 | PUSH1 0x00 | 0x00 CALLDATASIZE 0x80 Storage[3]-as-address | +| A6 | DUP3 | 0x80 0x00 CALLDATASIZE 0x80 Storage[3]-as-address | +| A7 | CALLDATACOPY | 0x80 Storage[3]-as-address | + +Copy all the call data to memory, starting at 0x80. + +| Offset | İşlem kodu | Yığın | +| -----: | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| A8 | PUSH1 0x00 | 0x00 0x80 Storage[3]-as-address | +| AA | DUP1 | 0x00 0x00 0x80 Storage[3]-as-address | +| AB | CALLDATASIZE | CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address | +| AC | DUP4 | 0x80 CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address | +| AD | DUP6 | Storage[3]-as-address 0x80 CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address | +| AE | GAS | GAS Storage[3]-as-address 0x80 CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address | +| AF | DELEGATE_CALL | | + +Now things are a lot clearer. This contract can act as a [proxy](https://blog.openzeppelin.com/proxy-patterns/), calling the address in Storage[3] to do the real work. `DELEGATE_CALL` calls a separate contract, but stays in the same storage. This means that the delegated contract, the one we are a proxy for, accesses the same storage space. The parameters for the call are: + +- _Gas_: All the remaining gas +- _Called address_: Storage[3]-as-address +- _Call data_: The CALLDATASIZE bytes starting at 0x80, which is where we put the original call data +- _Return data_: None (0x00 - 0x00) We'll get the return data by other means (see below) + +| Offset | İşlem kodu | Yığın | +| -----: | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | B0 | RETURNDATASIZE | RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | | B1 | DUP1 | RETURNDATASIZE RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | | B2 | PUSH1 0x00 | 0x00 RETURNDATASIZE RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | | B4 | DUP5 | 0x80 0x00 RETURNDATASIZE RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| B5 | RETURNDATACOPY | RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| B5 | RETURNDATACOPY | RETURNDATASIZE (((çağrı başarısı/başarısızlığı))) 0x80 Depolama[3]-as-address | -Burada dönen veriyi 0x80'den başlayan arabellek hafızasına kopyalıyoruz. +Here we copy all the return data to the memory buffer starting at 0x80. -| Offset | İşlem kodları | Yığın | -| -----: | ------------- | ---------------------------------------------------------------------------------------------------------------------------- | -| B6 | DUP2 | (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| B7 | DUP1 | (((call success/failure))) (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| B8 | ISZERO | (((did the call fail))) (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| B9 | PUSH2 0x00c0 | 0xC0 (((did the call fail))) (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| BC | JUMPI | (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| BD | DUP2 | RETURNDATASIZE (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| BE | DUP5 | 0x80 RETURNDATASIZE (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| BF | RETURN | | +| Offset | İşlem kodu | Yığın | +| -----: | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| B6 | DUP2 | (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| B7 | DUP1 | (((call success/failure))) (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| B8 | ISZERO | (((did the call fail))) (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| B9 | PUSH2 0x00c0 | 0xC0 (((did the call fail))) (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| BC | JUMPI | (((çağrı başarısı/başarısızlığı))) RETURNDATASIZE (((çağrı başarısı/başarısızlığı))) 0x80 Depolama[3]-as-address | +| BD | DUP2 | RETURNDATASIZE (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| BE | DUP5 | 0x80 RETURNDATASIZE (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| BF | RETURN | | -Yani çağrının ardından dönen veriyi 0x80 - 0x80+RETURNDATASIZE arabelleğine kopyaladıktan sonra, çağrı başarılı olduysa sonrasında tam olarak o arabellekle `RETURN` yapıyoruz. +So after the call we copy the return data to the buffer 0x80 - 0x80+RETURNDATASIZE, and if the call is successful we then `RETURN` with exactly that buffer. -### DELEGATECALL Başarısız oldu {#delegatecall-failed} +### DELEGATECALL Failed {#delegatecall-failed} -Buraya, yani 0xC0'a geldiysek, çağrı yaptığımız sözleşme geri dönmüştür. Bu sözleşme açısından sadece bir vekil olduğumuz için aynı veriyi döndürmek ve ayrıca geri dönmek istiyoruz. +If we get here, to 0xC0, it means that the contract we called reverted. As we are just a proxy for that contract, we want to return the same data and also revert. -| Offset | Işlem kodları | Yığın | -| -----: | ------------- | ------------------------------------------------------------------------------------------------------------------- | -| C0 | JUMPDEST | (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| C1 | DUP2 | RETURNDATASIZE (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| C2 | DUP5 | 0x80 RETURNDATASIZE (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| C3 | REVERT | | +| Offset | İşlem kodu | Yığın | +| -----: | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| C0 | JUMPDEST | (((çağrı başarısı/başarısızlığı))) RETURNDATASIZE (((çağrı başarısı/başarısızlığı))) 0x80 Depolama[3]-as-address | +| C1 | DUP2 | RETURNDATASIZE (((çağrı başarısı/başarısızlığı))) RETURNDATASIZE (((çağrı başarısı/başarısızlığı))) 0x80 Depolama[3]-as-address | +| C2 | DUP5 | 0x80 RETURNDATASIZE (((çağrı başarısı/başarısızlığı))) RETURNDATASIZE (((çağrı başarısı/başarısızlığı))) 0x80 Depolama[3]-as-address | +| C3 | REVERT | | -Yani daha önce `RETURN`: 0x80 - 0x80+RETURNDATASIZE için kullandığımız arabellekle `REVERT` yapıyoruz +So we `REVERT` with the same buffer we used for `RETURN` earlier: 0x80 - 0x80+RETURNDATASIZE -![Vekil akış şeması çağrısı](flowchart-proxy.png) +![Call to proxy flowchart](flowchart-proxy.png) -## ABI çağrıları {#abi-calls} +## ABI calls {#abi-calls} -Eğer veri boyutu 4 bayt ya da daha fazlaysa bu, geçerli bir ABI çağrısı olabilir. +If the call data size is four bytes or more this might be a valid ABI call. -| Offset | Opcode | Yığın | -| -----: | ------------ | ------------------------------------------------- | -| D | PUSH1 0x00 | 0x00 | +| Offset | İşlem kodu | Yığın | +| -----: | ------------ | ----------------------------------------------------------------------------------------------------------------------------- | +| D | PUSH1 0x00 | 0x00 | | F | CALLDATALOAD | (((First word (256 bits) of the call data))) | | 10 | PUSH1 0xe0 | 0xE0 (((First word (256 bits) of the call data))) | | 12 | SHR | (((first 32 bits (4 bytes) of the call data))) | -Etherscan bize `1C`'nin bilinmeyen bir işlem kodu olduğunu söylüyor, çünkü [bu, Etherscan bu özelliği yazdıktan sonra eklendi](https://eips.ethereum.org/EIPS/eip-145) ve onu henüz güncellemediler. [Güncel bir işlem kodu tablosu](https://github.com/wolflo/evm-opcodes) bize bunun sağa kaydırma olduğunu gösteriyor +Etherscan tells us that `1C` is an unknown opcode, because [it was added after Etherscan wrote this feature](https://eips.ethereum.org/EIPS/eip-145) and they haven't updated it. An [up to date opcode table](https://github.com/wolflo/evm-opcodes) shows us that this is shift right -| Offset | Opcode | Yığın | -| -----: | ---------------- | -------------------------------------------------------------------------------------------------------- | +| Offset | İşlem kodu | Yığın | +| -----: | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 13 | DUP1 | (((first 32 bits (4 bytes) of the call data))) (((first 32 bits (4 bytes) of the call data))) | | 14 | PUSH4 0x3cd8045e | 0x3CD8045E (((first 32 bits (4 bytes) of the call data))) (((first 32 bits (4 bytes) of the call data))) | -| 19 | GT | 0x3CD8045E>first-32-bits-of-the-call-data (((first 32 bits (4 bytes) of the call data))) | -| 1A | PUSH2 0x0043 | 0x43 0x3CD8045E>first-32-bits-of-the-call-data (((first 32 bits (4 bytes) of the call data))) | -| 1D | JUMPI | (((first 32 bits (4 bytes) of the call data))) | +| 19 | GT | 0x3CD8045E>first-32-bits-of-the-call-data (((first 32 bits (4 bytes) of the call data))) | +| 1A | PUSH2 0x0043 | 0x43 0x3CD8045E>first-32-bits-of-the-call-data (((first 32 bits (4 bytes) of the call data))) | +| 1D | JUMPI | (((çağrı verisinin ilk 32 biti (4 baytı))) | -Testleri eşleştiren yöntem imzasını buradaki gibi ikiye bölmek, ortalama olarak testlerin yarısından tasarruf etmemizi sağlar. Bu cümlenin hemen ardından gelen kod ve 0x43'teki kod aynı deseni izler: İlk 32 bitlik çağrı verileri için `DUP1`, ardından `PUSH4 (((method signature>` uygulayın, eşitliği kontrol etmek için `EQ` çalıştırın ve ardından yöntem imzası eşleşirse `JUMPI` komutunu kullanın. Yöntem imzaları, adresleri ve biliniyorsa [karşılık gelen yöntem tanımı](https://www.4byte.directory/) aşağıda verilmiştir: +By dividing the method signature matching tests in two like this saves half the tests on average. The code that immediately follows this and the code in 0x43 follow the same pattern: `DUP1` the first 32 bits of the call data, `PUSH4 (((method signature>`, run `EQ` to check for equality, and then `JUMPI` if the method signature matches. Here are the method signatures, their addresses, and if known [the corresponding method definition](https://www.4byte.directory/): -| Metod | Yöntem imzası | Sıçranacak kayma | -| -------------------------------------------------------------------------------------- | ------------- | ---------------- | -| [splitter()](https://www.4byte.directory/signatures/?bytes4_signature=0x3cd8045e) | 0x3cd8045e | 0x0103 | -| ??? | 0x81e580d3 | 0x0138 | -| [currentWindow()](https://www.4byte.directory/signatures/?bytes4_signature=0xba0bafb4) | 0xba0bafb4 | 0x0158 | -| ??? | 0x1f135823 | 0x00C4 | -| [merkleRoot()](https://www.4byte.directory/signatures/?bytes4_signature=0x2eb4a7ab) | 0x2eb4a7ab | 0x00ED | +| Method | Method signature | Offset to jump into | +| --------------------------------------------------------------------------------------------------------- | ---------------- | ------------------- | +| [splitter()](https://www.4byte.directory/signatures/?bytes4_signature=0x3cd8045e) | 0x3cd8045e | 0x0103 | +| ??? | 0x81e580d3 | 0x0138 | +| [currentWindow()](https://www.4byte.directory/signatures/?bytes4_signature=0xba0bafb4) | 0xba0bafb4 | 0x0158 | +| ??? | 0x1f135823 | 0x00C4 | +| [merkleRoot()](https://www.4byte.directory/signatures/?bytes4_signature=0x2eb4a7ab) | 0x2eb4a7ab | 0x00ED | -Eşleşme bulunamazsa kod, bizim vekili olduğumuz sözleşmenin bir eşleşmesi olmasını umarak [0x7C'deki vekil işlayicisine](#the-handler-at-0x7c) sıçrar. +If no match is found, the code jumps to [the proxy handler at 0x7C](#the-handler-at-0x7c), in the hope that the contract to which we are a proxy has a match. -![ABI çağrıları akış şeması](flowchart-abi.png) +![ABI calls flowchart](flowchart-abi.png) ## splitter() {#splitter} -| Offset | Opcode | Yığın | +| Offset | İşlem kodu | Yığın | | -----: | ------------ | ----------------------------- | | 103 | JUMPDEST | | | 104 | CALLVALUE | CALLVALUE | @@ -314,24 +312,24 @@ Eşleşme bulunamazsa kod, bizim vekili olduğumuz sözleşmenin bir eşleşmesi | 10D | DUP1 | 0x00 0x00 CALLVALUE | | 10E | REVERT | | -Bu fonksiyonun yaptığı ilk şey, çağrının ETH göndermediğini doğrulamaktır. Bu fonksiyon [`payable`](https://solidity-by-example.org/payable/) değildir. Eğer biri bize ETH gönderdiyse bu bir hata olarak gerçekleşmiştir ve o kişiyi ETH'lerini geri alamayacağı bir duruma sokmaktan kaçınmak için `REVERT` yapmamız gerekir. +The first thing this function does is check that the call did not send any ETH. This function is not [`payable`](https://solidity-by-example.org/payable/). If somebody sent us ETH that must be a mistake and we want to `REVERT` to avoid having that ETH where they can't get it back. -| Offset | Opcode | Yığın | -| -----: | ------------------------------------------------- | --------------------------------------------------------------------------- | -| 10F | JUMPDEST | | -| 110 | POP | | -| 111 | PUSH1 0x03 | 0x03 | -| 113 | SLOAD | (((Storage[3] a.k.a the contract for which we are a proxy))) | -| 114 | PUSH1 0x40 | 0x40 (((Storage[3] a.k.a the contract for which we are a proxy))) | -| 116 | MLOAD | 0x80 (((Storage[3] a.k.a the contract for which we are a proxy))) | +| Offset | İşlem kodu | Yığın | +| -----: | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| 10F | JUMPDEST | | +| 110 | POP | | +| 111 | PUSH1 0x03 | 0x03 | +| 113 | SLOAD | (((Storage[3] a.k.a the contract for which we are a proxy))) | +| 114 | PUSH1 0x40 | 0x40 (((Storage[3] a.k.a the contract for which we are a proxy))) | +| 116 | MLOAD | 0x80 (((Storage[3] a.k.a the contract for which we are a proxy))) | | 117 | PUSH20 0xffffffffffffffffffffffffffffffffffffffff | 0xFF...FF 0x80 (((Storage[3] a.k.a the contract for which we are a proxy))) | | 12C | SWAP1 | 0x80 0xFF...FF (((Storage[3] a.k.a the contract for which we are a proxy))) | | 12D | SWAP2 | (((Storage[3] a.k.a the contract for which we are a proxy))) 0xFF...FF 0x80 | -| 12E | VE | ProxyAddr 0x80 | -| 12F | DUP2 | 0x80 ProxyAddr 0x80 | -| 130 | MSTORE | 0x80 | +| 12E | AND | ProxyAddr 0x80 | +| 12F | DUP2 | 0x80 ProxyAddr 0x80 | +| 130 | MSTORE | 0x80 | -Ve 0x80 artık vekil adresini içeriyor +And 0x80 now contains the proxy address | Offset | Opcode | Yığın | | -----: | ------------ | --------- | @@ -340,9 +338,9 @@ Ve 0x80 artık vekil adresini içeriyor | 134 | PUSH2 0x00e4 | 0xE4 0xA0 | | 137 | JUMP | 0xA0 | -### E4 Kodu {#the-e4-code} +### The E4 Code {#the-e4-code} -Bu bu satırları ilk görüşümüz, fakat bunlar diğer yöntemlerle paylaşıldı (aşağı bakın). X yığınındaki değeri arayacağız; `splitter()`'da bu Xin değerinin 0xA0 olduğunu unutmayın. +This is the first time we see these lines, but they are shared with other methods (see below). So we'll call the value in the stack X, and just remember that in `splitter()` the value of this X is 0xA0. | Offset | Opcode | Yığın | | -----: | ---------- | ----------- | @@ -351,31 +349,31 @@ Bu bu satırları ilk görüşümüz, fakat bunlar diğer yöntemlerle paylaşı | E7 | MLOAD | 0x80 X | | E8 | DUP1 | 0x80 0x80 X | | E9 | SWAP2 | X 0x80 0x80 | -| EA | ALT | X-0x80 0x80 | +| EA | SUB | X-0x80 0x80 | | EB | SWAP1 | 0x80 X-0x80 | | EC | RETURN | | -Yani bu kod, yığında (X) bir bellek işaretçisi alır ve sözleşmenin, arabelleği 0x80 - X olan bir `RETURN` durumuna uğramasına sebep olur. +So this code receives a memory pointer in the stack (X), and causes the contract to `RETURN` with a buffer that is 0x80 - X. -`splitter()` durumunda bu, vekili olduğumuz adresi döndürür. `RETURN`, veriyi yazdığımız yerin adresi olan 0x80-0x9F'deki arabelleği verir (0x130un yukarısındaki kayma). +In the case of `splitter()`, this returns the address for which we are a proxy. `RETURN` returns the buffer in 0x80-0x9F, which is where we wrote this data (offset 0x130 above). ## currentWindow() {#currentwindow} -0x158-0x163 kaymalarındaki kod, `splitter()` içindeki 0x103-0x10E'de gördüğümüzle aynıdır (`JUMPI` hedefi dışında), bu nedenle `currentWindow()`'un da `payable` olmadığını biliyoruz. +The code in offsets 0x158-0x163 is identical to what we saw in 0x103-0x10E in `splitter()` (other than the `JUMPI` destination), so we know `currentWindow()` is also not `payable`. -| Offset | Opcode | Yığın | -| -----: | ------------ | -------------------- | -| 164 | JUMPDEST | | -| 165 | POP | | -| 166 | PUSH2 0x00da | 0xDA | -| 169 | PUSH1 0x01 | 0x01 0xDA | +| Offset | Opcode | Yığın | +| -----: | ------------ | ------------------------------------------------------------------------ | +| 164 | JUMPDEST | | +| 165 | POP | | +| 166 | PUSH2 0x00da | 0xDA | +| 169 | PUSH1 0x01 | 0x01 0xDA | | 16B | SLOAD | Storage[1] 0xDA | | 16C | DUP2 | 0xDA Storage[1] 0xDA | | 16D | JUMP | Storage[1] 0xDA | -### DA kodu {#the-da-code} +### The DA code {#the-da-code} -Bu kod da diğer yöntemlerle paylaşılmıştır. Yani Y yığınındaki değeri çağıracağız; `currentWindow()`'da bu Y'nin değerinin Storage[1] olduğunu unutmayın. +This code is also shared with other methods. So we'll call the value in the stack Y, and just remember that in `currentWindow()` the value of this Y is Storage[1]. | Offset | Opcode | Yığın | | -----: | ---------- | ---------------- | @@ -386,57 +384,57 @@ Bu kod da diğer yöntemlerle paylaşılmıştır. Yani Y yığınındaki değer | DF | DUP2 | 0x80 Y 0x80 0xDA | | E0 | MSTORE | 0x80 0xDA | -0x80-0x9F'e Y'yi yazalım. +Write Y to 0x80-0x9F. | Offset | Opcode | Yığın | | -----: | ---------- | -------------- | | E1 | PUSH1 0x20 | 0x20 0x80 0xDA | | E3 | EKLE | 0xA0 0xDA | -Ve geri kalanı da [yukarıda](#the-e4-code) anlatılmıştır. Yani 0xDA'ya yapılan sıçramalar yığının başını (Y), 0x80-0x9F'ye yazar ve bu değeri döndürür. Bir `currentWindow()` durumunda, Storage[1]'ı verir. +And the rest is already explained [above](#the-e4-code). So jumps to 0xDA write the stack top (Y) to 0x80-0x9F, and return that value. In the case of `currentWindow()`, it returns Storage[1]. ## merkleRoot() {#merkleroot} -0x158-0x163 kaymalarındaki kod, `splitter()` içindeki 0x103-0x10E'de gördüğümüzle aynıdır (`JUMPI` hedefi dışında), bu nedenle `merkleRoot()`'un da `payable` olmadığını biliyoruz. +The code in offsets 0xED-0xF8 is identical to what we saw in 0x103-0x10E in `splitter()` (other than the `JUMPI` destination), so we know `merkleRoot()` is also not `payable`. -| Offset | Opcode | Yığın | -| -----: | ------------ | -------------------- | -| F9 | JUMPDEST | | -| FA | POP | | -| FB | PUSH2 0x00da | 0xDA | -| FE | PUSH1 0x00 | 0x00 0xDA | +| Offset | Opcode | Yığın | +| -----: | ------------ | ------------------------------------------------------------------------ | +| F9 | JUMPDEST | | +| FA | POP | | +| FB | PUSH2 0x00da | 0xDA | +| FE | PUSH1 0x00 | 0x00 0xDA | | 100 | SLOAD | Storage[0] 0xDA | | 101 | DUP2 | 0xDA Storage[0] 0xDA | | 102 | JUMP | Storage[0] 0xDA | -Sıçramadan sonra ne olduğunu [çoktan anladık](#the-da-code). Yani `merkleRoot()` Storage[0]'ı döndürür. +What happens after the jump [we already figured out](#the-da-code). So `merkleRoot()` returns Storage[0]. ## 0x81e580d3 {#0x81e580d3} -0xC4-0xCF kaymalarındaki kod, `splitter()` içindeki 0x103-0x10E'de gördüğümüzle aynıdır (`JUMPI` hedefi dışında), dolayısıyla bu fonksiyonun da `payable` olmadığını biliyoruz. - -| Offset | Opcode | Yığın | -| -----: | ------------ | ------------------------------------------------------------ | -| 144 | JUMPDEST | | -| 145 | POP | | -| 146 | PUSH2 0x00da | 0xDA | -| 149 | PUSH2 0x0153 | 0x0153 0xDA | -| 14C | CALLDATASIZE | CALLDATASIZE 0x0153 0xDA | -| 14D | PUSH1 0x04 | 0x04 CALLDATASIZE 0x0153 0xDA | -| 14F | PUSH2 0x018f | 0x018F 0x04 CALLDATASIZE 0x0153 0xDA | -| 152 | JUMP | 0x04 CALLDATASIZE 0x0153 0xDA | -| 18F | JUMPDEST | 0x04 CALLDATASIZE 0x0153 0xDA | -| 190 | PUSH1 0x00 | 0x00 0x04 CALLDATASIZE 0x0153 0xDA | -| 192 | PUSH1 0x20 | 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | -| 194 | DUP3 | 0x04 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | -| 195 | DUP5 | CALLDATASIZE 0x04 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | -| 196 | SUB | CALLDATASIZE-4 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | -| 197 | SLT | CALLDATASIZE-4\<32 0x00 0x04 CALLDATASIZE 0x0153 0xDA | -| 198 | ISZERO | CALLDATASIZE-4>=32 0x00 0x04 CALLDATASIZE 0x0153 0xDA | -| 199 | PUSH2 0x01a0 | 0x01A0 CALLDATASIZE-4>=32 0x00 0x04 CALLDATASIZE 0x0153 0xDA | -| 19C | JUMPI | 0x00 0x04 CALLDATASIZE 0x0153 0xDA | - -Bu fonksiyon en az 32 bayt (1 kelime) çağrı verisi alıyor gibi görünüyor. +The code in offsets 0x138-0x143 is identical to what we saw in 0x103-0x10E in `splitter()` (other than the `JUMPI` destination), so we know this function is also not `payable`. + +| Offset | Opcode | Yığın | +| -----: | ------------ | ------------------------------------------------------------------------------- | +| 144 | JUMPDEST | | +| 145 | POP | | +| 146 | PUSH2 0x00da | 0xDA | +| 149 | PUSH2 0x0153 | 0x0153 0xDA | +| 14C | CALLDATASIZE | CALLDATASIZE 0x0153 0xDA | +| 14D | PUSH1 0x04 | 0x04 CALLDATASIZE 0x0153 0xDA | +| 14F | PUSH2 0x018f | 0x018F 0x04 CALLDATASIZE 0x0153 0xDA | +| 152 | JUMP | 0x04 CALLDATASIZE 0x0153 0xDA | +| 18F | JUMPDEST | 0x04 CALLDATASIZE 0x0153 0xDA | +| 190 | PUSH1 0x00 | 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 192 | PUSH1 0x20 | 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 194 | DUP3 | 0x04 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 195 | DUP5 | CALLDATASIZE 0x04 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 196 | SUB | CALLDATASIZE-4 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 197 | SLT | CALLDATASIZE-4\<32 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 198 | ISZERO | CALLDATASIZE-4>=32 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 199 | PUSH2 0x01a0 | 0x01A0 CALLDATASIZE-4>=32 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 19C | JUMPI | 0x00 0x04 CALLDATASIZE 0x0153 0xDA | + +It looks like this function takes at least 32 bytes (one word) of call data. | Offset | Opcode | Yığın | | -----: | ------ | -------------------------------------------- | @@ -444,80 +442,80 @@ Bu fonksiyon en az 32 bayt (1 kelime) çağrı verisi alıyor gibi görünüyor. | 19E | DUP2 | 0x00 0x00 0x00 0x04 CALLDATASIZE 0x0153 0xDA | | 19F | REVERT | | -Eğer hiçbir çağrı verisi almazsa bu işlem gelen hiçbir veri olmadan geri döndürülür. +If it doesn't get the call data the transaction is reverted without any return data. -Şimdi de _does_ fonksiyonu ihtiyacı olan çağrı verisini aldığında neler olduğunu görelim. +Let's see what happens if the function _does_ get the call data it needs. -| Offset | Opcode | Yığın | -| -----: | ------------ | ---------------------------------------- | -| 1A0 | JUMPDEST | 0x00 0x04 CALLDATASIZE 0x0153 0xDA | -| 1A1 | POP | 0x04 CALLDATASIZE 0x0153 0xDA | +| Offset | Opcode | Yığın | +| -----: | ------------ | ----------------------------------------------------------- | +| 1A0 | JUMPDEST | 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 1A1 | POP | 0x04 CALLDATASIZE 0x0153 0xDA | | 1A2 | CALLDATALOAD | calldataload(4) CALLDATASIZE 0x0153 0xDA | -`calldataload(4)`, çağrı verisinin yöntem imzasından _sonraki_ ilk kelimesidir - -| Offset | Opcode | Yığın | -| -----: | ------------ | ---------------------------------------------------------------------------- | -| 1A3 | SWAP2 | 0x0153 CALLDATASIZE calldataload(4) 0xDA | -| 1A4 | SWAP1 | CALLDATASIZE 0x0153 calldataload(4) 0xDA | -| 1A5 | POP | 0x0153 calldataload(4) 0xDA | -| 1A6 | JUMP | calldataload(4) 0xDA | -| 153 | JUMPDEST | calldataload(4) 0xDA | -| 154 | PUSH2 0x016e | 0x016E calldataload(4) 0xDA | -| 157 | JUMP | calldataload(4) 0xDA | -| 16E | JUMPDEST | calldataload(4) 0xDA | -| 16F | PUSH1 0x04 | 0x04 calldataload(4) 0xDA | -| 171 | DUP2 | calldataload(4) 0x04 calldataload(4) 0xDA | -| 172 | DUP2 | 0x04 calldataload(4) 0x04 calldataload(4) 0xDA | -| 173 | SLOAD | Storage[4] calldataload(4) 0x04 calldataload(4) 0xDA | -| 174 | DUP2 | calldataload(4) Storage[4] calldataload(4) 0x04 calldataload(4) 0xDA | +`calldataload(4)` is the first word of the call data _after_ the method signature + +| Offset | Opcode | Yığın | +| -----: | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 1A3 | SWAP2 | 0x0153 CALLDATASIZE calldataload(4) 0xDA | +| 1A4 | SWAP1 | CALLDATASIZE 0x0153 calldataload(4) 0xDA | +| 1A5 | POP | 0x0153 calldataload(4) 0xDA | +| 1A6 | JUMP | calldataload(4) 0xDA | +| 153 | JUMPDEST | calldataload(4) 0xDA | +| 154 | PUSH2 0x016e | 0x016E calldataload(4) 0xDA | +| 157 | JUMP | calldataload(4) 0xDA | +| 16E | JUMPDEST | calldataload(4) 0xDA | +| 16F | PUSH1 0x04 | 0x04 calldataload(4) 0xDA | +| 171 | DUP2 | calldataload(4) 0x04 calldataload(4) 0xDA | +| 172 | DUP2 | 0x04 calldataload(4) 0x04 calldataload(4) 0xDA | +| 173 | SLOAD | Storage[4] calldataload(4) 0x04 calldataload(4) 0xDA | +| 174 | DUP2 | calldataload(4) Storage[4] calldataload(4) 0x04 calldataload(4) 0xDA | | 175 | LT | calldataload(4)\)`, diğeri de `isClaimed()` şeklindedir, dolayısıyla bir airdrop sözleşmesini andırır. İşlem kodundan işlem koduna geri kalanların üzerinden geçmek yerine, bu sözleşmeden üç fonksiyon için kullanılabilir sonuçlar oluşturan [geri derleyiciyi deneyebiliriz](https://etherscan.io/bytecode-decompiler?a=0x2f81e57ff4f4d83b40a9f719fd892d8e806e0761). Diğerlerine tersine mühendislik yapmak ise alıştırma olarak okuyucuya bırakılmıştır. +One of the remaining methods is `claim()`, and another is `isClaimed()`, so it looks like an airdrop contract. Instead of going through the rest opcode by opcode, we can [try the decompiler](https://etherscan.io/bytecode-decompiler?a=0x2f81e57ff4f4d83b40a9f719fd892d8e806e0761), which produces usable results for three functions from this contract. Reverse engineering the other ones is left as an exercise to the reader. ### scaleAmountByPercentage {#scaleamountbypercentage} -Bu fonksiyon için geri derleyicinin bize verdiği şey şudur: +This is what the decompiler gives us for this function: ```python def unknown8ffb5c97(uint256 _param1, uint256 _param2) payable: @@ -592,15 +590,15 @@ def unknown8ffb5c97(uint256 _param1, uint256 _param2) payable: return (_param1 * _param2 / 100 * 10^6) ``` -İlk `require` çağrı verilerinin, fonksiyon imzasının dört baytına ek olarak iki parametre için yeterli olan en az 64 bayta sahip olup olmadığını test eder. Eğer durum bu değilse, kesinlikle yanlış bir şeyler vardır. +The first `require` tests that the call data has, in addition to the four bytes of the function signature, at least 64 bytes, enough for the two parameters. If not then there is obviously something wrong. -`if` ifadesi, `_param1` değerinin sıfır olmadığını ve `_param1 * _param2` değerinin negatif olmadığını doğrulamaya çalışıyor gibi görünüyor. Muhtemelen paketleme durumlarını önlemek içindir. +The `if` statement seems to check that `_param1` is not zero, and that `_param1 * _param2` is not negative. It is probably to prevent cases of wrap around. -Son olarak, fonksiyon ölçeklendirilmiş bir değer döndürür. +Finally, the function returns a scaled value. -### talep et {#claim} +### claim {#claim} -Geri derleyicinin oluşturduğu kod karmaşık ve bunun haricinde tamamı da bizim açımızdan ilgili değil. Bunların bir kısmını atlayıp bize işe yarar bilgi sağlayacağına inandığım satırlara odaklanacağım +The code the decompiler creates is complex, and not all of it is relevant for us. I am going to skip some of it to focus on the lines that I believe provide useful information ```python def unknown2e7ba6ef(uint256 _param1, uint256 _param2, uint256 _param3, array _param4) payable: @@ -611,10 +609,10 @@ def unknown2e7ba6ef(uint256 _param1, uint256 _param2, uint256 _param3, array _pa revert with 0, 'cannot claim for a future window' ``` -Burada iki önemli şey görüyoruz: +We see here two important things: -- `_param2`, bir `uint256` olarak tanıtılmasına rağmen aslında bir adrestir -- `_param1`, şimdi ya da öncesinde `currentWindow` olması gereken, üstlenilen penceredir. +- `_param2`, while it is declared as a `uint256`, is actually an address +- `_param1` is the window being claimed, which has to be `currentWindow` or earlier. ```python ... @@ -622,7 +620,7 @@ Burada iki önemli şey görüyoruz: revert with 0, 'Account already claimed the given window' ``` -Yani artık Storage[5]'ın pencere ve adreslerden oluşan bir dizi olduğunu ve adresin o pencere için ödülü alıp almadığını biliyoruz. +So now we know that Storage[5] is an array of windows and addresses, and whether the address claimed the reward for that window. ```python ... @@ -642,7 +640,7 @@ Yani artık Storage[5]'ın pencere ve adreslerden oluşan bir dizi olduğunu ve revert with 0, 'Invalid proof' ``` -`unknown2eb4a7ab` değerinin aslında `merkleRoot()` fonksiyonu olduğunu biliyoruz, dolayısıyla bu kod bir [merkle kanıtını](https://medium.com/crypto-0-nite/merkle-proofs-explained-6dd429623dc5) doğruluyor gibi görünüyor. Bu, `_param4` değerinin bir merkle kanıtı olduğu anlamına geliyor. +We know that `unknown2eb4a7ab` is actually the function `merkleRoot()`, so this code looks like it is verifying a [merkle proof](https://medium.com/crypto-0-nite/merkle-proofs-explained-6dd429623dc5). This means that `_param4` is a merkle proof. ```python call addr(_param2) with: @@ -650,7 +648,7 @@ Yani artık Storage[5]'ın pencere ve adreslerden oluşan bir dizi olduğunu ve gas 30000 wei ``` -Bir sözleşme kendi ETH'sini başka bir adrese (sözleşme ya da harici olarak sahip olunan) işte bu şekilde transfer eder. Transfer edilecek miktar olan bir değerle ona çağrı yapar. Yani bu, ETH'nin bir airdrop'u gibi görünüyor. +This is how a contract transfers its own ETH to another address (contract or externally owned). It calls it with a value that is the amount to be transferred. So it looks like this is an airdrop of ETH. ```python if not return_data.size: @@ -660,22 +658,22 @@ Bir sözleşme kendi ETH'sini başka bir adrese (sözleşme ya da harici olarak value unknown81e580d3[_param1] * _param3 / 100 * 10^6 wei ``` -En alttaki iki satır, bize Storage[2]'ın da çağrı yaptığımız bir sözleşme olduğunu söyler. [Oluşturucu işlemine bakarsak](https://etherscan.io/tx/0xa1ea0549fb349eb7d3aff90e1d6ce7469fdfdcd59a2fd9b8d1f5e420c0d05b58#statechange) bu sözleşmenin [0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2](https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2), [kaynak kodu Etherscan'e yüklenmiş bir Paketlenmiş Ether sözleşmesi olduğunu görürüz](https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2#code). +The bottom two lines tell us that Storage[2] is also a contract that we call. If we [look at the constructor transaction](https://etherscan.io/tx/0xa1ea0549fb349eb7d3aff90e1d6ce7469fdfdcd59a2fd9b8d1f5e420c0d05b58#statechange) we see that this contract is [0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2](https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2), a Wrapped Ether contract [whose source code has been uploaded to Etherscan](https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2#code). -Sözleşme, `_param2`'ye ETH göndermeye çalışıyor gibi görünüyor. Eğer yapabilirse, çok iyi. Yapamazsa, [WETH](https://weth.tkn.eth.limo/) göndermeye çalışacak. Eğer `_param2` dışarıdan sahip olunan hesap (EOA) ise, her zaman ETH alabilir, fakat sözleşmeler ETH almayı reddedebilir. Bununla birlikte, WETH bir ERC-20'dir ve sözleşmeler bunu kabul etmeyi reddedemez. +So it looks like the contracts attempts to send ETH to `_param2`. If it can do it, great. If not, it attempts to send [WETH](https://weth.tkn.eth.limo/). If `_param2` is an externally owned account (EOA) then it can always receive ETH, but contracts can refuse to receive ETH. However, WETH is ERC-20 and contracts can't refuse to accept that. ```python ... log 0xdbd5389f: addr(_param2), unknown81e580d3[_param1] * _param3 / 100 * 10^6, bool(ext_call.success) ``` -Fonksiyonun sonunda bir günlük girdisinin oluşturulduğunu görüyoruz. [Oluşturulmuş günlük girdilerine bakın](https://etherscan.io/address/0x2510c039cc3b061d79e564b38836da87e31b342f#events) ve `0xdbd5...` ile başlayan konuyu filtreleyin. Böyle bir girdi oluşturmuş işlemlerden birine [tıklarsak](https://etherscan.io/tx/0xe7d3b7e00f645af17dfbbd010478ef4af235896c65b6548def1fe95b3b7d2274) gerçekten de üstlenme gibi göründüğünü görebiliriz; hesap, tersine mühendislik yaptığımız sözleşmeye bir mesaj göndermiş ve karşılığında ETH almıştır. +At the end of the function we see a log entry being generated. [Look at the generated log entries](https://etherscan.io/address/0x2510c039cc3b061d79e564b38836da87e31b342f#events) and filter on the topic that starts with `0xdbd5...`. If we [click one of the transactions that generated such an entry](https://etherscan.io/tx/0xe7d3b7e00f645af17dfbbd010478ef4af235896c65b6548def1fe95b3b7d2274) we see that indeed it looks like a claim - the account sent a message to the contract we're reverse engineering, and in return got ETH. -![Üstlenme işlemi](claim-tx.png) +![A claim transaction](claim-tx.png) ### 1e7df9d3 {#1e7df9d3} -Bu fonksiyon, yukarıdaki [`claim`](#claim) fonksiyonuna çok benziyor. Ayrıca bir merkle kanıtını kontrol eder, ilkine ETH transfer etmeyi dener ve aynı türde bir günlük girdisi oluşturur. +This function is very similar to [`claim`](#claim) above. It also checks a merkle proof, attempts to transfer ETH to the first, and produces the same type of log entry. ```python def unknown1e7df9d3(uint256 _param1, uint256 _param2, array _param3) payable: @@ -708,7 +706,7 @@ def unknown1e7df9d3(uint256 _param1, uint256 _param2, array _param3) payable: log 0xdbd5389f: addr(_param1), s, bool(ext_call.success) ``` -Asıl fark geri çekilecek olan pencere olan ilk parametrenin orada olmamasıdır. Bunun yerine, her pencerenin üstünde alınabilecek bir döngü vardır. +The main difference is that the first parameter, the window to withdraw, isn't there. Instead, there is a loop over all the windows that could be claimed. ```python idx = 0 @@ -737,8 +735,10 @@ Asıl fark geri çekilecek olan pencere olan ilk parametrenin orada olmamasıdı continue ``` -Yani tüm pencereleri üstlenen bir `claim` varyantı gibi görünüyor. +So it looks like a `claim` variant that claims all the windows. ## Sonuç {#conclusion} -Şu ana kadar kaynak kodu ulaşılabilir olmayan sözleşmeleri, işlem kodlarını ya da geri derleyiciyi kullanarak (eğer çalışırsa) nasıl anlayacağınızı öğrenmiş olmalısınız. Bu makalenin uzunluğundan da anlaşılacağı gibi, bir sözleşmeye tersine mühendislik uygulamak önemsiz değildir, ancak güvenliğin önemli olduğu bir sistemde sözleşmelerin vaat edildiği gibi çalıştığını doğrulayabilmek önemli bir beceridir. +By now you should know how to understand contracts whose source code is not available, using either the opcodes or (when it works) the decompiler. As is evident from the length of this article, reverse engineering a contract is not trivial, but in a system where security is essential it is an important skill to be able to verify contracts work as promised. + +[Çalışmalarımdan daha fazlası için buraya bakın](https://cryptodocguy.pro/). diff --git a/public/content/translations/tr/developers/tutorials/run-node-raspberry-pi/index.md b/public/content/translations/tr/developers/tutorials/run-node-raspberry-pi/index.md index b74b81f3e5a..ab7d8dfdf05 100644 --- a/public/content/translations/tr/developers/tutorials/run-node-raspberry-pi/index.md +++ b/public/content/translations/tr/developers/tutorials/run-node-raspberry-pi/index.md @@ -1,12 +1,14 @@ --- -title: Raspberry Pi 4'ünüzü sadece MicroSD kartı flaşlayarak bir düğüme nasıl dönüştürebilirsiniz -description: Raspberry Pi 4'ünüzü flaşlama, ethernet kablosu takma, SSD diskini bağlama ve Raspberry Pi 4'ünüzü çalıştırarak tam bir Ethereum düğümüne ve doğrulayıcısına dönüştürme +title: "Raspeberry Pi 4 üzerinde bir Ethereum düğümü çalıştırın" +description: "Raspberry Pi 4'ünüzü flash'layın, bir ethernet kablosu takın, SSD diski bağlayın ve cihazı çalıştırarak Raspberry Pi 4'ü tam bir Ethereum düğümü + doğrulayıcısına dönüştürün" author: "EthereumOnArm" tags: - - "istemciler" - - "yürütüm katmanı" - - "mutabakat katmanı" - - "düğümler" + [ + "istemciler", + "yürütme katmanı", + "mutabakat katmanı", + "düğümler" + ] lang: tr skill: intermediate published: 2022-06-10 @@ -14,101 +16,101 @@ source: Ethereum on ARM sourceUrl: https://ethereum-on-arm-documentation.readthedocs.io/en/latest/ --- -**Ethereum on Arm, Raspberry Pi'ı bir Ethereum düğümüne çevirebilecek olan kişiselleştirilmiş bir Linux görüntüsüdür.** +**Ethereum on Arm, bir Raspberry Pi'ı Ethereum düğümüne dönüştürebilen özel bir Linux görüntüsüdür.** -Ethereum on Arm'ı kullanarak Raspberry Pi'ı Ethereum düğümüne çevirmek için aşağıdaki donanım önerilir: +Ethereum on Arm'ı kullanarak bir Raspberry Pi'ı Ethereum düğümüne dönüştürmek için aşağıdaki donanımlar önerilir: -- Raspberry 4 (model B 8GB), Odroid M1 ya da Rock 5B (8GB/16GB RAM) kart -- MicroSD Kartı (minimum 16 GB Sınıf 10) -- Minimum 2 TB SSD'li bir USB 3.0 disk veya USB - SATA kasalı bir SSD. +- Raspberry 4 (model B 8GB), Odroid M1 veya Rock 5B (8GB/16GB RAM) kartı +- MicroSD Kart (minimum 16 GB Sınıf 10) +- Minimum 2 TB SSD USB 3.0 disk veya USB - SATA kasalı bir SSD. - Güç kaynağı - Ethernet kablosu - Bağlantı noktası yönlendirme (daha fazla bilgi için istemcilere bakın) -- Soğutucusu ve fanı olan bir kasa +- Soğutuculu ve fanlı bir kasa - USB klavye, Monitör ve HDMI kablosu (mikro-HDMI) (İsteğe bağlı) -## Neden Ethereum on ARM'ı çalıştıralım? {#why-run-ethereum-on-arm} +## Neden ARM üzerinde Ethereum çalıştırmalısınız? {#why-run-ethereum-on-arm} -ARM kartları çok uygun fiyatlı, esnek ve küçük bilgisayarlardır. Ethereum düğümlerini çalıştırmak için iyi seçimlerdir çünkü ucuza satın alınabilirler, tüm kaynakları yalnızca düğüme odaklanacak şekilde yapılandırılabilirler, bu onları verimli kılar, düşük miktarda güç tüketir ve fiziksel olarak küçüktür, böylece herhangi bir eve dikkat çekmeden sığabilirler. Ayrıca, Raspberry Pi'ın MicroSD'si bir yüklemeye ya da yazılım oluşturmaya gerek olmadan basitçe önceden yüklenmiş bir görüntüyle doldurabildiği için düğümlerin kodlarını yazmak aşırı kolaydır. +ARM kartları çok uygun fiyatlı, esnek, küçük bilgisayarlardır. Ucuz bir şekilde satın alınabildikleri, tüm kaynakları yalnızca düğüme odaklanacak şekilde yapılandırılabildikleri için Ethereum düğümlerini çalıştırmak için iyi seçeneklerdir. Bu onları verimli kılar, düşük miktarda güç tüketirler ve fiziksel olarak küçük olduklarından her eve göze batmayacak şekilde sığabilirler. Ayrıca, Raspberry Pi'nin MicroSD kartına önceden oluşturulmuş bir imaj kolayca yüklenebildiği için düğümleri kurmak da çok kolaydır, yazılım indirme veya derleme gerekmez. ## Nasıl çalışır? {#how-does-it-work} -Raspberry Pi'ın bellek kartı önceden oluşturulmuş bir görüntüyle depolanmıştır. Bu görüntü, bir Ethereum düğümünü çalıştırabilmek için gereken her şeyi içerir. Yüklenmiş bir kartla, kullanıcının yapması gereken tek şey Raspberry Pi'ı açmaktır. Düğümü çalıştırmak için gereken her işlem otomatik olarak başlatılır. Bu, bellek kartı Linux tabanlı bir işletim sistemi (OS) içerdiğinden ve bu sistemde birimi bir Ethereum düğümüne dönüştüren sistem seviyesindeki işlemler otomatik olarak çalıştığından işe yarar. +Raspberry Pi'nin hafıza kartına önceden oluşturulmuş bir imaj yüklenir. Bu imaj, bir Ethereum düğümünü çalıştırmak için gereken her şeyi içerir. İmaj yüklenmiş bir kartla, kullanıcının yapması gereken tek şey Raspberry Pi'ı açmaktır. Düğümü çalıştırmak için gereken tüm işlemler otomatik olarak başlatılır. Bu, bellek kartının Linux tabanlı bir işletim sistemi (OS) içermesi ve bu sistem üzerinde birimi bir Ethereum düğümüne dönüştüren sistem düzeyindeki işlemlerin otomatik olarak çalışması sayesinde mümkündür. -Ethereum, popüler Raspberry Pi Linux OS "Raspbian" kullanılarak çalıştırılamaz, çünkü Raspbian hala 32-bit bir mimari kullanır, bu da Ethereum kullanıcılarının bellek sorunları yaşamasına neden olur ve konsensus istemcileri 32-bit ikili dosyaları desteklemez. Ethereum on Arm ekibi, bunun üstesinden gelmek için yerel bir 64-bit OS olan "Armbian"a geçiş yaptı. +Ethereum, popüler Raspberry Pi Linux işletim sistemi "Raspbian" kullanılarak çalıştırılamaz çünkü Raspbian hâlâ 32-bit bir mimari kullanır, bu da Ethereum kullanıcılarının bellek sorunları yaşamasına neden olur ve mutabakat istemcileri 32-bit ikili dosyaları desteklemez. Bunun üstesinden gelmek için Ethereum on Arm ekibi, "Armbian" adlı yerel bir 64-bit işletim sistemine geçiş yaptı. -**Sürücüler**, ortamın kurulmasından ve SSD diskinin biçimlendirilmesinden, Ethereum yazılımını kurup çalıştırmaya ve ayrıca blokzincir senkronizasyonunu başlatmaya kadar gerekli tüm adımların üstesinden gelir. +**İmajlar, ortamı kurmaktan ve SSD diski biçimlendirmekten, Ethereum yazılımını kurup çalıştırmaya ve blok zinciri senkronizasyonunu başlatmaya kadar gerekli tüm adımları halleder.** -## Yürütüm ve fikir birliği istemcileriyle ilgili not {#note-on-execution-and-consensus-clients} +## Yürütme ve mutabakat istemcileri hakkında not {#note-on-execution-and-consensus-clients} -Ethereum on Arm görüntüsü, hizmet olarak önceden oluşturulmuş yürütüm ve fikir birliği istemcileri içerir. Bir ethereum düğümü senkronize olmak ve çalışmak için iki istemciye de ihtiyaç duyar. Görüntüyü yükleyip depolamanız ve ardından hizmetleri başlatmanız yeterlidir. Bu görüntüye, aşağıdaki yürütüm istemcileri: +Ethereum on Arm imajı, hizmet olarak önceden oluşturulmuş yürütme ve mutabakat istemcileri içerir. Bir Ethereum düğümü, her iki istemcinin de senkronize edilmiş ve çalışır durumda olmasını gerektirir. Yalnızca imajı indirip yüklemeniz ve ardından hizmetleri başlatmanız gerekir. İmaj, aşağıdaki yürütme istemcileriyle önceden yüklenmiştir: - Geth - Nethermind - Besu -ve aşağıdaki fikir birliği istemcileri önceden yüklenmiştir: +ve aşağıdaki mutabakat istemcileri: - Lighthouse - Nimbus - Prysm - Teku -Çalıştırmak için her birinden bir tanesini seçmelisiniz; tüm yürütüm istemcileri tüm fikir birliği istemcileriyle uyumludur. Açık bir şekilde bir istemci seçmezseniz düğüm, varsayılanlarına geri dönecek (Geth ve Lighthouse) ve bunları kart açıldığında otomatik olarak çalıştıracaktır. Geth'in eşleri bulup bağlanabilmesi için yönlendiricinizin 30303 bağlantı noktasını açmalısınız. +Çalıştırmak için her birinden bir tane seçmelisiniz - tüm yürütme istemcileri, tüm mutabakat istemcileriyle uyumludur. Açıkça bir istemci seçmezseniz düğüm varsayılan ayarlarına (Geth ve Lighthouse) geri döner ve kart açıldığında bunları otomatik olarak çalıştırır. Geth'in eşleri bulup onlara bağlanabilmesi için yönlendiricinizde 30303 numaralı bağlantı noktasını açmalısınız. -## Görüntüyü İndirme {#downloading-the-image} +## İmajı İndirme {#downloading-the-image} -Raspberry Pi Ethereum görüntüsü, yürütüm ve fikir birliği istemcilerini otomatik olarak yükleyip ayarlayan ve onları birbiriyle konuşmaları ve Ethereum ağına bağlanmaları için yapılandıran "tak ve çalıştır" tipi bir görüntüdür. Kullanıcının tek yapması gereken basit bir komut kullanarak işlemlerini başlatmaktır. +Raspberry Pi 4 Ethereum imajı, hem yürütme hem de mutabakat istemcilerini otomatik olarak kuran ve ayarlayan, birbirleriyle iletişim kurmaları ve Ethereum ağına bağlanmaları için yapılandıran bir "tak ve çalıştır" imajıdır. Kullanıcının tek yapması gereken, basit bir komut kullanarak işlemlerini başlatmaktır. -[Ethereum on Arm](https://ethereumonarm-my.sharepoint.com/:u:/p/dlosada/Ec_VmUvr80VFjf3RYSU-NzkBmj2JOteDECj8Bibde929Gw?download=1)'dan Raspberry Pi görüntüsünü indirin ve SHA256 karmasını doğrulayın: +Raspberry Pi imajını [Ethereum on Arm](https://ethereumonarm-my.sharepoint.com/:u:/p/dlosada/Ec_VmUvr80VFjf3RYSU-NzkBmj2JOteDECj8Bibde929Gw?download=1) adresinden indirin ve SHA256 karmasını doğrulayın: ```sh -# From directory containing the downloaded image +# İndirilen imajı içeren dizinden shasum -a 256 ethonarm_22.04.00.img.zip -# Hash should output: fb497e8f8a7388b62d6e1efbc406b9558bee7ef46ec7e53083630029c117444f +# Karma çıktısı şu şekilde olmalıdır: fb497e8f8a7388b62d6e1efbc406b9558bee7ef46ec7e53083630029c117444f ``` -Rock 5B ve Odroid M1 kartlarının görüntülerinin Ethereum-on-Arm'ın [indirmeler sayfasında](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/quick-guide/download-and-install.html) mevcut olduğunu unutmayın. +Rock 5B ve Odroid M1 kartları için imajların Ethereum-on-Arm [indirmeler sayfasında](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/quick-guide/download-and-install.html) mevcut olduğunu unutmayın. -## MicroSD'yi yükleme {#flashing-the-microsd} +## MicroSD'ye İmaj Yükleme {#flashing-the-microsd} -Raspberry Pi için kullanılacak MicroSD kartın yüklenebilmesi için öncelikle bir masaüstü veya dizüstü bilgisayara takılması gerekir. Ardından aşağıdaki terminal komutları, indirilen görüntüyü SD karta aktaracaktır: +Raspberry Pi için kullanılacak MicroSD kart, imajın yüklenebilmesi için önce bir masaüstü veya dizüstü bilgisayara takılmalıdır. Ardından, aşağıdaki terminal komutları indirilen imajı SD karta yükleyecektir: ```shell -# check the MicroSD card name +# MicroSD kart adını kontrol edin sudo fdisk -l >> sdxxx ``` -İsmin doğru olması gerçekten önemlidir, çünkü bir sonraki komut, resmi üzerine göndermeden önce kartın mevcut içeriğini tamamen silen `dd`'yi içerir. Devam etmek için sıkıştırılmış resmi içeren dizine gidin: +İsmi doğru yazmanız gerçekten önemlidir, çünkü bir sonraki komut, imajı karta yazmadan önce kartın mevcut içeriğini tamamen silen `dd` komutunu içerir. Devam etmek için sıkıştırılmış imajı içeren dizine gidin: ```shell -# unzip and flash image +# imajı ayıklayın ve yükleyin unzip ethonarm_22.04.00.img.zip sudo dd bs=1M if=ethonarm_22.04.00.img of=/dev/ conv=fdatasync status=progress ``` -Kart şimdi yanıp sönüyor, böylece Raspberry Pi'a takılabilir. +Kartın imajı şimdi yüklendi, artık Raspberry Pi'a takılabilir. ## Düğümü başlatma {#start-the-node} -Raspberry Pi'a takılı SD kart ile ethernet kablosunu ve SSD'yi bağlayın ve ardından gücü açın. İşletim sistemi açılır ve Raspberry Pi'ı bir Ethereum düğümüne dönüştüren, istemci yazılımının yüklenmesi ve oluşturulması da dahil olmak üzere önceden yapılandırılmış görevler otomatik olarak gerçekleştirilir. Bu, muhtemelen 10-15 dakika sürecektir. +SD kart Raspberry Pi'a takılıyken, ethernet kablosunu ve SSD'yi bağlayın, ardından gücü açın. İşletim sistemi açılacak ve istemci yazılımını kurma ve derleme de dahil olmak üzere Raspberry Pi'ı bir Ethereum düğümüne dönüştüren önceden yapılandırılmış görevleri otomatik olarak gerçekleştirmeye başlayacaktır. Bu muhtemelen 10-15 dakika sürecektir. -Her şey kurulduktan ve yapılandırıldıktan sonra, bir ssh bağlantısı aracılığıyla veya panoya bir monitör ve klavye takılıysa doğrudan terminali kullanarak cihazda oturum açın. Düğümü başlatmak için gerekli izinlere sahip olduğundan, oturum açmak için `ethereum` hesabını kullanın. +Her şey kurulup yapılandırıldıktan sonra, bir ssh bağlantısı aracılığıyla veya karta bir monitör ve klavye bağlıysa doğrudan terminali kullanarak cihazda oturum açın. Düğümü başlatmak için gerekli izinlere sahip olduğundan, oturum açmak için `ethereum` hesabını kullanın. ```shell -User: ethereum -Password: ethereum +Kullanıcı: ethereum +Parola: ethereum ``` -Varsayılan yürütüm istemcisi Geth, otomatik olarak başlayacaktır. Bunu, aşağıdaki terminal komutları ile günlükleri kontrol ederek onaylayabilirsiniz: +Varsayılan yürütme istemcisi olan Geth otomatik olarak başlayacaktır. Aşağıdaki terminal komutunu kullanarak günlükleri kontrol ederek bunu doğrulayabilirsiniz: ```sh sudo journalctl -u geth -f ``` -Fikir birliği istemcisi ayrı olarak başlatılmalıdır. Bunu yapmak için yönlendiricinizin 9000 bağlantı noktasını açın ve Ligthouse'un bulup eşlere bağlayabilmesini sağlayın. Sonra da lighthouse hizmetini etkinleştirip başlatın: +Mutabakat istemcisinin açıkça başlatılması gerekir. Bunu yapmak için, Lighthouse'un eşleri bulup onlara bağlanabilmesi için önce yönlendiricinizde 9000 numaralı bağlantı noktasını açın. Ardından lighthouse hizmetini etkinleştirin ve başlatın: ```sh sudo systemctl enable lighthouse-beacon @@ -121,15 +123,15 @@ Günlükleri kullanarak istemciyi kontrol edin: sudo journalctl -u lighthouse-beacon ``` -Kontrol noktası senkronizasyonunu kullandığı için fikir birliği istemcisinin de birkaç dakika içinde senkronize olacağını unutmayın. Yürütüm istemcisi biraz daha fazla, muhtemelen birkaç saat zaman alacak ve fikir birliği istemcisi senkronizasyonunu bitirmediği sürece başlamayacaktır (bunun nedeni, yürütüm istemcisinin senkronize olacağı bir hedefe ihtiyaç duyması ve bunu da fikir birliği istemcisinin sağlıyor olmasıdır). +Mutabakat istemcisinin kontrol noktası senkronizasyonunu kullandığı için birkaç dakika içinde senkronize olacağını unutmayın. Yürütme istemcisi daha uzun sürer (potansiyel olarak birkaç saat) ve mutabakat istemcisi senkronizasyonu bitirene kadar başlamaz (bunun nedeni, yürütme istemcisinin senkronize olmak için bir hedefe ihtiyaç duymasıdır ve bunu da senkronize olmuş mutabakat istemcisi sağlar). -Geth ve Lighthouse hizmetleri senkronize ve çalışır durumdaysa, Raspberry Pi'ınız artık bir Ethereum düğümüdür! En yaygın yöntem, 8545 bağlantı noktasında Geth istemcisine iliştirilebilen Geth Javascript konsolunu kullanarak Ethereum ile etkileşime girmektir. JSON nesneleri şeklinde biçimlendirilmiş komutları Curl gibi bir istek aracı kullanarak göndermek de mümkündür. [Geth dokümanlarında](https://geth.ethereum.org) daha fazla bilgiye ulaşın. +Geth ve Lighthouse hizmetleri çalışır ve senkronize durumdayken, Raspberry Pi'ınız artık bir Ethereum düğümü! Ethereum ağı ile etkileşim kurmanın en yaygın yolu, 8545 numaralı bağlantı noktasındaki Geth istemcisine eklenebilen Geth'in Javascript konsolunu kullanmaktır. Curl gibi bir istek aracı kullanarak JSON nesneleri olarak biçimlendirilmiş komutları göndermek de mümkündür. [Geth dokümantasyonunda](https://geth.ethereum.org/) daha fazlasını görebilirsiniz. -Geth, metrikleri tarayıcıda görüntülenebilen Grafana paneline rapor etmek üzere önceden yapılandırılmıştır. Daha ileri seviye kullanıcılar bu özelliği, `ipaddress:3000` adresine gidip `user: admin` ve `passwd: ethereum` öğelerini geçirmek yoluyla düğümlerinin sağlığını izlemek için kullanmak isteyebilirler. +Geth, metrikleri tarayıcıda görüntülenebilen bir Grafana panosuna bildirecek şekilde önceden yapılandırılmıştır. Daha ileri düzey kullanıcılar, `ipaddress:3000` adresine gidip `user: admin` ve `passwd: ethereum` parametrelerini girerek düğümlerinin sağlığını izlemek için bu özelliği kullanmak isteyebilirler. ## Doğrulayıcılar {#validators} -Fikir birliği istemcisine isteğe bağlı olarak bir doğrulayıcı da eklenebilir. Doğrulayıcı yazılımı, düğümünüzün mutabakata aktif olarak katılmasına olanak tanır ve ağa kriptoekonomik güvenlik sağlar. Bu iş için ETH bazında ödüllendirilirsiniz. Bir doğrulayıcıyı çalıştırmak için öncelikle yatırma sözleşmesine yatırmak üzere 32 ETH'ye sahip olmanız gerekir. **Bu, uzun süreli bir bağlılık gerektirir; bu ETH'yi çekmek henüz mümkün değildir!**. Yatırma işlemi, [Başlama noktası](https://launchpad.ethereum.org/)'ndaki adım-adım rehberi takip edilerek yapılabilir. Bunu bir masaüstü/dizüstü bilgisayarda yapın ancak anahtar oluşturmayın; bu, doğrudan Raspberry Pi üzerinde yapılabilir. +Mutabakat istemcisine isteğe bağlı olarak bir doğrulayıcı da eklenebilir. Doğrulayıcı yazılımı, düğümünüzün mutabakata aktif olarak katılmasına olanak tanır ve ağa kriptoekonomik güvenlik sağlar. Bu çalışma karşılığında ETH olarak ödüllendirilirsiniz. Bir doğrulayıcı çalıştırmak için, önce para yatırma sözleşmesine yatırılması gereken 32 ETH'ye sahip olmanız gerekir. [Launchpad](https://launchpad.ethereum.org/) üzerindeki adım adım kılavuzu izleyerek para yatırma işlemi yapılabilir. Bunu bir masaüstü/dizüstü bilgisayarda yapın, ancak anahtar oluşturmayın — bu işlem doğrudan Raspberry Pi üzerinde yapılabilir. Raspberry Pi'da bir terminal açın ve para yatırma anahtarlarını oluşturmak için aşağıdaki komutu çalıştırın: @@ -139,20 +141,22 @@ sudo apt-get install staking-deposit-cli cd && deposit new-mnemonic --num_validators 1 ``` -Anımsatıcı ifadeyi güvende tutun! Yukarıdaki komut, düğümün anahtar deposunda iki dosya oluşturmuştur: doğrulayıcı anahtarlar ve bir yatırma veri dosyası. Yatırma verilerinin başlatma paneline yüklenmesi gerekir, bu nedenle Raspberry Pi'dan masaüstü/dizüstü bilgisayara kopyalanmalıdır. Bu, bir ssh bağlantısı veya başka bir kopyala/yapıştır yöntemi kullanılarak yapılabilir. +(Veya [staking-deposit-cli](https://github.com/ethereum/staking-deposit-cli) uygulamasını indirip internet bağlantısı olmayan bir makinede çalıştırın ve `deposit new-mnemnonic` komutunu yürütün) -Yatırılan veri dosyası, başlatma panelini çalıştıran bilgisayarda mevcut olduğunda, başlatma paneli ekranındaki `+` üzerine sürüklenip bırakılabilir. Yatırma sözleşmesine işlem göndermek için ekrandaki talimatları izleyin. +Anımsatıcı ifadenizi güvende tutun! Yukarıdaki komut, düğümün anahtar deposunda iki dosya oluşturdu: doğrulayıcı anahtarları ve bir para yatırma veri dosyası. Para yatırma verilerinin Launchpad'e yüklenmesi gerekir, bu nedenle Raspberry Pi'dan masaüstü/dizüstü bilgisayara kopyalanmalıdır. Bu, bir ssh bağlantısı veya başka bir kopyala/yapıştır yöntemi kullanılarak yapılabilir. -Raspberry Pi'a geri dönecek olursak, bir doğrulayıcı başlatılabilir. Bu, doğrulayıcı anahtarlarının içe aktarılmasını, ödülleri toplamak için adresin ayarlanmasını ve ardından önceden yapılandırılmış doğrulama sürecinin başlatılmasını gerektirir. Aşağıdaki örnek Lighthouse içindir; diğer fikir birliği istemcileri için talimatlar [Ethereum on Arm dokümanları](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/)'nda bulunabilir: +Para yatırma veri dosyası, Launchpad'i çalıştıran bilgisayarda mevcut olduğunda, Launchpad ekranındaki `+` üzerine sürüklenip bırakılabilir. Para yatırma sözleşmesine bir işlem göndermek için ekrandaki talimatları izleyin. + +Raspberry Pi'a geri dönersek, bir doğrulayıcı başlatılabilir. Bu, doğrulayıcı anahtarlarını içe aktarmayı, ödülleri toplamak için adresi ayarlamayı ve ardından önceden yapılandırılmış doğrulayıcı sürecini başlatmayı gerektirir. Aşağıdaki örnek Lighthouse içindir—diğer mutabakat istemcileri için talimatlar [Ethereum on Arm belgelerinde](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/) mevcuttur: ```shell -# import the validator keys +# doğrulayıcı anahtarlarını içe aktar lighthouse account validator import --directory=/home/ethereum/validator_keys -# set the reward address +# ödül adresini ayarla sudo sed -i 's/' /etc/ethereum/lighthouse-validator.conf -# start the validator +# doğrulayıcıyı başlat sudo systemctl start lighthouse-validator ``` @@ -160,13 +164,14 @@ Tebrikler, artık Raspberry Pi üzerinde çalışan tam bir Ethereum düğümün ## Daha fazla ayrıntı {#more-details} -Bu sayfa, Raspberry Pi kullanarak Geth-Lighthouse düğümünü ve doğrulayıcısını nasıl kuracağınız hakkında genel bir görünüm sunmuştur. Daha detaylı açıklama [Ethereum-on-Arm web sitesinde](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/index.html) mevcuttur. +Bu sayfa, Raspberry Pi kullanarak bir Geth-Lighthouse düğümü ve doğrulayıcısının nasıl kurulacağına dair genel bir bakış sunmuştur. Daha ayrıntılı talimatlar [Ethereum-on-Arm web sitesinde](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/index.html) mevcuttur. -## Geribildirimleriniz bizi memnun eder {#feedback-appreciated} +## Geri bildirimleriniz bizim için değerli {#feedback-appreciated} -Raspberry Pi'ın, Ethereum ağının sağlığı üzerinde çok olumlu bir etkisi olabilecek büyük bir kullanıcı tabanına sahip olduğunu biliyoruz. Lütfen bu öğreticideki ayrıntıları inceleyin, test ağlarında çalıştırmayı deneyin, Github'da Ethereum on Arm'a göz atın, geribildirimde bulunun, sorunları ve çekme isteklerini dile getirin, teknolojiyi ve dokümanları geliştirmeye yardımcı olun! +Raspberry Pi'ın, Ethereum ağının sağlığı üzerinde çok olumlu bir etkiye sahip olabilecek devasa bir kullanıcı tabanına sahip olduğunu biliyoruz. +Lütfen bu eğiticinin ayrıntılarını inceleyin, test ağlarında çalıştırmayı deneyin, Ethereum on Arm GitHub'ına göz atın, geri bildirimde bulunun, sorunları bildirin, çekme istekleri oluşturun ve teknolojinin ve dokümantasyonun geliştirilmesine yardımcı olun! -## Referanslar {#references} +## Kaynaklar {#references} 1. https://ubuntu.com/download/raspberry-pi 2. https://wikipedia.org/wiki/Port_forwarding diff --git a/public/content/translations/tr/developers/tutorials/scam-token-tricks/index.md b/public/content/translations/tr/developers/tutorials/scam-token-tricks/index.md new file mode 100644 index 00000000000..84ab6dc21bd --- /dev/null +++ b/public/content/translations/tr/developers/tutorials/scam-token-tricks/index.md @@ -0,0 +1,470 @@ +--- +title: "Dolandırıcı jetonlar tarafından kullanılan bazı hileler ve bunların nasıl tespit edileceği" +description: "Bu öğreticide, dolandırıcıların oynadığı bazı hileleri, bunları nasıl uyguladıklarını ve nasıl tespit edebileceğimizi görmek için bir dolandırıcılık jetonunu inceliyoruz." +author: Ori Pomerantz +tags: + [ + "dolandırıcılık", + "solidity", + "erc-20", + "javascript", + "typescript" + ] +skill: intermediate +published: 2023-09-15 +lang: tr +--- + +Bu öğreticide, dolandırıcıların oynadığı bazı hileleri ve bunları nasıl uyguladıklarını görmek için [bir dolandırıcılık jetonunu](https://etherscan.io/token/0xb047c8032b99841713b8e3872f06cf32beb27b82#code) inceliyoruz. Öğreticinin sonunda, ERC-20 jeton sözleşmeleri, yetenekleri ve şüpheciliğin neden gerekli olduğu hakkında daha kapsamlı bir bakış açısına sahip olacaksınız. Ardından, o dolandırıcı jeton tarafından yayılan olaylara bakıyoruz ve yasal olmadığını otomatik olarak nasıl belirleyebileceğimizi görüyoruz. + +## Dolandırıcı jetonlar - nedirler, insanlar neden onları yapar ve onlardan nasıl kaçınılır {#scam-tokens} + +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. Ancak, değer getiren meşru kullanım şekilleri bulunan her yerde, söz konusu değeri kendisi için çalmaya çalışan suçlular bulunur. + +Bu konu hakkında bir kullanıcı perspektifinden [ethereum.org'un başka bir yerinde](/guides/how-to-id-scam-tokens/) daha fazla bilgi edinebilirsiniz. Bu öğretici, nasıl yapıldığını ve nasıl tespit edilebileceğini görmek için bir dolandırıcılık jetonunu incelemeye odaklanmaktadır. + +### wARB'nin bir dolandırıcılık olduğunu nasıl anlarım? {#warb-scam} + +İncelediğimiz jeton, yasal [ARB jetonuna](https://etherscan.io/token/0xb50721bcf8d664c30412cfbc6cf7a15145234ad1) eşdeğermiş gibi davranan [wARB](https://etherscan.io/token/0xb047c8032b99841713b8e3872f06cf32beb27b82#code)'dir. + +Hangisinin yasal jeton olduğunu bilmenin en kolay yolu, kurucu kuruluş olan [Arbitrum](https://arbitrum.foundation/)'a bakmaktır. Yasal adresler [dokümanlarında](https://docs.arbitrum.foundation/deployment-addresses#token) belirtilmiştir. + +### Kaynak kodu neden mevcut? {#why-source} + +Normalde başkalarını dolandırmaya çalışan insanların gizli olmasını bekleriz ve gerçekten de birçok dolandırıcı jetonun kodu mevcut değildir (örneğin, [bu](https://optimistic.etherscan.io/token/0x15992f382d8c46d667b10dc8456dc36651af1452#code) ve [bu](https://optimistic.etherscan.io/token/0x026b623eb4aada7de37ef25256854f9235207178#code)). + +Ancak, yasal jetonlar genellikle kaynak kodlarını yayınlarlar, bu nedenle yasal görünmek için dolandırıcı jetonların yazarları da bazen aynısını yapar. [wARB](https://etherscan.io/token/0xb047c8032b99841713b8e3872f06cf32beb27b82#code), kaynak kodu mevcut olan ve bu sayede anlaşılması daha kolay olan jetonlardan biridir. + +Sözleşme dağıtıcıları kaynak kodunu yayınlayıp yayınlamamayı seçebilse de, yanlış kaynak kodunu yayınlayamazlar. Blok gezgini, sağlanan kaynak kodunu bağımsız olarak derler ve tam olarak aynı bit kodunu elde etmezse, o kaynak kodunu reddeder. [Bu konu hakkında Etherscan sitesinde daha fazla bilgi edinebilirsiniz](https://etherscan.io/verifyContract). + +## Yasal ERC-20 jetonlarıyla karşılaştırma {#compare-legit-erc20} + +Bu jetonu yasal ERC-20 jetonlarıyla karşılaştıracağız. Yasal ERC-20 jetonlarının tipik olarak nasıl yazıldığına aşina değilseniz, [bu öğreticiye bakın](/developers/tutorials/erc20-annotated-code/). + +### Ayrıcalıklı adresler için sabitler {#constants-for-privileged-addresses} + +Sözleşmeler bazen ayrıcalıklı adreslere ihtiyaç duyar. Uzun süreli kullanım için tasarlanan sözleşmeler, örneğin yeni bir çoklu imza sözleşmesinin kullanımını sağlamak için bazı ayrıcalıklı adreslerin bu adresleri değiştirmesine izin verir. Bunu yapmanın birkaç yolu vardır. + +[`HOP` jeton sözleşmesi](https://etherscan.io/address/0xc5102fe9359fd9a28f877a67e36b0f050d81a3cc#code), [`Ownable`](https://docs.openzeppelin.com/contracts/2.x/access-control#ownership-and-ownable) modelini kullanır. Ayrıcalıklı adres, `_owner` adlı bir alanda depolamada tutulur (üçüncü dosyaya bakın, `Ownable.sol`). + +```solidity +abstract contract Ownable is Context { + address private _owner; + . + . + . +} +``` + +[`ARB` jeton sözleşmesi](https://etherscan.io/address/0xad0c361ef902a7d9851ca7dcc85535da2d3c6fc7#code) doğrudan ayrıcalıklı bir adrese sahip değildir. Ancak, bir tanesine ihtiyacı yoktur. [`0xb50721bcf8d664c30412cfbc6cf7a15145234ad1` adresindeki](https://etherscan.io/address/0xb50721bcf8d664c30412cfbc6cf7a15145234ad1#code) bir [`proxy`](https://docs.openzeppelin.com/contracts/5.x/api/proxy)'nin arkasında yer alır. Bu sözleşmenin yükseltmeler için kullanılabilecek ayrıcalıklı bir adresi vardır (dördüncü dosyaya bakın, `ERC1967Upgrade.sol`). + +```solidity + /** + * @dev EIP1967 yönetici yuvasında yeni bir adres saklar. + */ + function _setAdmin(address newAdmin) private { + require(newAdmin != address(0), "ERC1967: yeni yönetici sıfır adresidir"); + StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin; + } +``` + +Buna karşılık, `wARB` sözleşmesi sabit kodlanmış bir `contract_owner`'a sahiptir. + +```solidity +contract WrappedArbitrum is Context, IERC20 { + . + . + . + address deployer = 0xB50721BCf8d664c30412Cfbc6cf7a15145234ad1; + address public contract_owner = 0xb40dE7b1beE84Ff2dc22B70a049A07A13a411A33; + . + . + . +} +``` + +[Bu sözleşme sahibi](https://etherscan.io/address/0xb40dE7b1beE84Ff2dc22B70a049A07A13a411A33), farklı zamanlarda farklı hesaplar tarafından kontrol edilebilecek bir sözleşme değil, [harici olarak sahip olunan bir hesaptır](/developers/docs/accounts/#externally-owned-accounts-and-key-pairs). Bu, muhtemelen değerli kalacak bir ERC-20'yi kontrol etmek için uzun vadeli bir çözümden ziyade, bir birey tarafından kısa süreli kullanım için tasarlandığı anlamına gelir. + +Ve gerçekten de, Etherscan'e baktığımızda, dolandırıcının bu sözleşmeyi 19 Mayıs 2023'te yalnızca 12 saat boyunca kullandığını görüyoruz ([ilk işlem](https://etherscan.io/tx/0xf49136198c3f925fcb401870a669d43cecb537bde36eb8b41df77f06d5f6fbc2)'den [son işleme](https://etherscan.io/tx/0xdfd6e717157354e64bbd5d6adf16761e5a5b3f914b1948d3545d39633244d47b)). + +### Sahte `_transfer` fonksiyonu {#the-fake-transfer-function} + +Gerçek transferlerin [dahili bir `_transfer` fonksiyonu](/developers/tutorials/erc20-annotated-code/#the-_transfer-function-_transfer) kullanılarak yapılması standarttır. + +`wARB`'de bu fonksiyon neredeyse yasal görünüyor: + +```solidity + function _transfer(address sender, address recipient, uint256 amount) internal virtual{ + require(sender != address(0), "ERC20: sıfır adresten transfer"); + require(recipient != address(0), "ERC20: sıfır adrese transfer"); + + _beforeTokenTransfer(sender, recipient, amount); + + _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer tutarı bakiyeyi aşıyor"); + _balances[recipient] = _balances[recipient].add(amount); + if (sender == contract_owner){ + sender = deployer; + } + emit Transfer(sender, recipient, amount); + } +``` + +Şüpheli kısım şudur: + +```solidity + if (sender == contract_owner){ + sender = deployer; + } + emit Transfer(sender, recipient, amount); +``` + +Sözleşme sahibi jeton gönderirse, `Transfer` olayı neden `deployer`'dan geldiklerini gösteriyor? + +Ancak, daha önemli bir sorun var. Bu `_transfer` fonksiyonunu kim çağırıyor? Dışarıdan çağrılamaz, `internal` olarak işaretlenmiştir. Ve elimizdeki kod, `_transfer`'a herhangi bir çağrı içermiyor. Açıkçası, bu bir yem olarak burada. + +```solidity + function transfer(address recipient, uint256 amount) public virtual override returns (bool) { + _f_(_msgSender(), recipient, amount); + return true; + } + + function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { + _f_(sender, recipient, amount); + _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer tutarı yetkiyi aşıyor")); + return true; + } +``` + +Jetonları transfer etmek için çağrılan fonksiyonlara, `transfer` ve `transferFrom`'a baktığımızda, tamamen farklı bir fonksiyon olan `_f_`'yi çağırdıklarını görüyoruz. + +### Gerçek `_f_` fonksiyonu {#the-real-f-function} + +```solidity + function _f_(address sender, address recipient, uint256 amount) internal _mod_(sender,recipient,amount) virtual { + require(sender != address(0), "ERC20: sıfır adresten transfer"); + require(recipient != address(0), "ERC20: sıfır adrese transfer"); + + _beforeTokenTransfer(sender, recipient, amount); + + _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer tutarı bakiyeyi aşıyor"); + _balances[recipient] = _balances[recipient].add(amount); + if (sender == contract_owner){ + + sender = deployer; + } + emit Transfer(sender, recipient, amount); + } +``` + +Bu fonksiyonda iki potansiyel tehlike işareti var. + +- [Fonksiyon değiştirici](https://www.tutorialspoint.com/solidity/solidity_function_modifiers.htm) `_mod_` kullanımı. Ancak, kaynak koduna baktığımızda `_mod_`'un aslında zararsız olduğunu görüyoruz. + + ```solidity + modifier _mod_(address sender, address recipient, uint256 amount){ + _; + } + ``` + +- `_transfer`'de gördüğümüz aynı sorun, yani `contract_owner` jeton gönderdiğinde, jetonların `deployer`'dan geliyormuş gibi görünmesi. + +### Sahte olaylar fonksiyonu `dropNewTokens` {#the-fake-events-function-dropNewTokens} + +Şimdi gerçek bir dolandırıcılığa benzeyen bir şeye geldik. Okunabilirlik için fonksiyonu biraz düzenledim, ancak işlevsel olarak eşdeğerdir. + +```solidity +function dropNewTokens(address uPool, + address[] memory eReceiver, + uint256[] memory eAmounts) public auth() +``` + +Bu fonksiyon, yalnızca sözleşme sahibi tarafından çağrılabileceği anlamına gelen `auth()` değiştiricisine sahiptir. + +```solidity +modifier auth() { + require(msg.sender == contract_owner, "Etkileşime izin verilmiyor"); + _; +} +``` + +Bu kısıtlama son derece mantıklıdır, çünkü rastgele hesapların jeton dağıtmasını istemeyiz. Ancak, fonksiyonun geri kalanı şüphelidir. + +```solidity +{ + for (uint256 i = 0; i < eReceiver.length; i++) { + emit Transfer(uPool, eReceiver[i], eAmounts[i]); + } +} +``` + +Bir havuz hesabından bir alıcı dizisine bir miktar dizisi transfer etmek için bir fonksiyon son derece mantıklıdır. Maaş bordrosu, airdrop'lar vb. gibi tek bir kaynaktan birden çok hedefe jeton dağıtmak isteyeceğiniz birçok kullanım durumu vardır. Birden çok işlem yayınlamak veya hatta aynı işlemin bir parçası olarak farklı bir sözleşmeden ERC-20'yi birden çok kez çağırmak yerine bunu tek bir işlemde yapmak (gaz açısından) daha ucuzdur. + +Ancak, `dropNewTokens` bunu yapmaz. [`Transfer` olayları](https://eips.ethereum.org/EIPS/eip-20#transfer-1) yayar, ancak aslında herhangi bir jeton transfer etmez. Zincir dışı uygulamaların kafasını gerçekten gerçekleşmemiş bir transferden bahsederek karıştırmak için meşru bir neden yoktur. + +### Yakan `Approve` fonksiyonu {#the-burning-approve-function} + +ERC-20 sözleşmelerinin yetkiler için [bir `approve` fonksiyonuna](/developers/tutorials/erc20-annotated-code/#approve) sahip olması gerekir ve gerçekten de dolandırıcı jetonumuzun böyle bir fonksiyonu vardır ve hatta doğrudur. Ancak, Solidity C'den türediği için büyük/küçük harfe duyarlıdır. `Approve` ve `approve` farklı dizelerdir. + +Ayrıca, işlevsellik `approve` ile ilgili değildir. + +```solidity + function Approve( + address[] memory holders) +``` + +Bu fonksiyon, jeton sahiplerinin adreslerinden oluşan bir dizi ile çağrılır. + +```solidity + public approver() { +``` + +`approver()` değiştiricisi, bu fonksiyonu yalnızca `contract_owner`'ın çağırmasına izin verildiğinden emin olur (aşağıya bakın). + +```solidity + for (uint256 i = 0; i < holders.length; i++) { + uint256 amount = _balances[holders[i]]; + _beforeTokenTransfer(holders[i], 0x0000000000000000000000000000000000000001, amount); + _balances[holders[i]] = _balances[holders[i]].sub(amount, + "ERC20: yakma miktarı bakiyeyi aşıyor"); + _balances[0x0000000000000000000000000000000000000001] = + _balances[0x0000000000000000000000000000000000000001].add(amount); + } + } + +``` + +Her sahip adresi için fonksiyon, sahibin tüm bakiyesini `0x00...01` adresine taşır ve etkin bir şekilde yakar (standarttaki gerçek `burn` aynı zamanda toplam arzı da değiştirir ve jetonları `0x00...00`'a transfer eder). Bu, `contract_owner`'ın herhangi bir kullanıcının varlıklarını kaldırabileceği anlamına gelir. Bu, bir yönetişim jetonunda isteyeceğiniz bir özellik gibi görünmüyor. + +### Kod kalitesi sorunları {#code-quality-issues} + +Bu kod kalitesi sorunları, bu kodun bir dolandırıcılık olduğunu _kanıtlamaz_, ancak şüpheli görünmesini sağlar. Arbitrum gibi organize şirketler genellikle bu kadar kötü kod yayınlamazlar. + +#### `mount` fonksiyonu {#the-mount-function} + +[Standartta](https://eips.ethereum.org/EIPS/eip-20) belirtilmemiş olsa da, genel olarak yeni jetonlar oluşturan fonksiyon [`mint`](https://ethereum.org/el/developers/tutorials/erc20-annotated-code/#the-_mint-and-_burn-functions-_mint-and-_burn) olarak adlandırılır. + +`wARB` yapıcısına bakarsak, mint (basma) fonksiyonunun bir nedenle `mount` olarak yeniden adlandırıldığını ve verimlilik için tüm miktar için bir kez yerine, ilk arzın beşte biri ile beş kez çağrıldığını görüyoruz. + +```solidity + constructor () public { + + _name = "Wrapped Arbitrum"; + _symbol = "wARB"; + _decimals = 18; + uint256 initialSupply = 1000000000000; + + mount(deployer, initialSupply*(10**18)/5); + mount(deployer, initialSupply*(10**18)/5); + mount(deployer, initialSupply*(10**18)/5); + mount(deployer, initialSupply*(10**18)/5); + mount(deployer, initialSupply*(10**18)/5); + } +``` + +`mount` fonksiyonunun kendisi de şüphelidir. + +```solidity + function mount(address account, uint256 amount) public { + require(msg.sender == contract_owner, "ERC20: sıfır adrese basım"); +``` + +`require`'a baktığımızda, yalnızca sözleşme sahibinin basım yapmasına izin verildiğini görüyoruz. Bu yasal. Ancak hata mesajı _yalnızca sahip basım yapabilir_ veya buna benzer bir şey olmalıdır. Bunun yerine, alakasız _ERC20: sıfır adrese basım_ şeklindedir. Sıfır adrese basım için doğru test, `require(account != address(0), "")` şeklindedir ki sözleşme bunu kontrol etme zahmetine girmez. + +```solidity + _totalSupply = _totalSupply.add(amount); + _balances[contract_owner] = _balances[contract_owner].add(amount); + emit Transfer(address(0), account, amount); + } +``` + +Basımla doğrudan ilgili iki şüpheli gerçek daha var: + +- Bir `account` parametresi var, ki bu muhtemelen basılan miktarı alması gereken hesaptır. Ancak artan bakiye aslında `contract_owner`'ın. + +- Artan bakiye `contract_owner`'a aitken, yayılan olay `account`'a bir transfer gösterir. + +### Neden hem `auth` hem de `approver`? Neden hiçbir şey yapmayan `mod`? {#why-both-autho-and-approver-why-the-mod-that-does-nothing} + +Bu sözleşme üç değiştirici içerir: `_mod_`, `auth` ve `approver`. + +```solidity + modifier _mod_(address sender, address recipient, uint256 amount){ + _; + } +``` + +`_mod_` üç parametre alır ve onlarla hiçbir şey yapmaz. Neden var? + +```solidity + modifier auth() { + require(msg.sender == contract_owner, "Etkileşime izin verilmiyor"); + _; + } + + modifier approver() { + require(msg.sender == contract_owner, "Etkileşime izin verilmiyor"); + _; + } +``` + +`auth` ve `approver` daha mantıklıdır, çünkü sözleşmenin `contract_owner` tarafından çağrıldığını kontrol ederler. Basım gibi belirli ayrıcalıklı eylemlerin o hesapla sınırlı olmasını bekleriz. Ancak, _tam olarak aynı şeyi yapan_ iki ayrı fonksiyona sahip olmanın ne anlamı var? + +## Otomatik olarak ne tespit edebiliriz? {#what-can-we-detect-automatically} + +Etherscan'e bakarak `wARB`'nin bir dolandırıcılık jetonu olduğunu görebiliriz. Ancak, bu merkezi bir çözümdür. Teorik olarak, Etherscan altüst edilebilir veya hacklenebilir. Bir jetonun yasal olup olmadığını bağımsız olarak anlayabilmek daha iyidir. + +Bir ERC-20 jetonunun şüpheli olduğunu (ya bir dolandırıcılık ya da çok kötü yazılmış) yaydıkları olaylara bakarak belirlemek için kullanabileceğimiz bazı hileler vardır. + +## Şüpheli `Approval` olayları {#suspicious-approval-events} + +[`Approval` olayları](https://eips.ethereum.org/EIPS/eip-20#approval) yalnızca doğrudan bir istekle gerçekleşmelidir ([`Transfer` olaylarının](https://eips.ethereum.org/EIPS/eip-20#transfer-1) aksine, bir yetkinin sonucu olarak gerçekleşebilir). Bu sorunun ayrıntılı bir açıklaması ve isteklerin neden bir sözleşme aracılığıyla değil de doğrudan olması gerektiği için [Solidity belgelerine bakın](https://docs.soliditylang.org/en/v0.8.20/security-considerations.html#tx-origin). + +Bu, [harici olarak sahip olunan bir hesaptan](/developers/docs/accounts/#types-of-account) harcamayı onaylayan `Approval` olaylarının, o hesapta başlayan ve hedefi ERC-20 sözleşmesi olan işlemlerden gelmesi gerektiği anlamına gelir. Harici olarak sahip olunan bir hesaptan gelen diğer her türlü onay şüphelidir. + +İşte tür güvenliğine sahip bir JavaScript çeşidi olan [viem](https://viem.sh/) ve [TypeScript](https://www.typescriptlang.org/docs/) kullanarak [bu tür bir olayı tanımlayan bir program](https://github.com/qbzzt/20230915-scam-token-detection). Çalıştırmak için: + +1. `.env.example` dosyasını `.env` olarak kopyalayın. +2. Bir Ethereum ana ağ düğümünün URL'sini sağlamak için `.env` dosyasını düzenleyin. +3. Gerekli paketleri kurmak için `pnpm install` komutunu çalıştırın. +4. Şüpheli onayları aramak için `pnpm susApproval` komutunu çalıştırın. + +İşte satır satır bir açıklama: + +```typescript +import { + Address, + TransactionReceipt, + createPublicClient, + http, + parseAbiItem, +} from "viem" +import { mainnet } from "viem/chains" +``` + +`viem`'den tür tanımlarını, fonksiyonları ve zincir tanımını içe aktarın. + +```typescript +import { config } from "dotenv" +config() +``` + +URL'yi almak için `.env` dosyasını okuyun. + +```typescript +const client = createPublicClient({ + chain: mainnet, + transport: http(process.env.URL), +}) +``` + +Bir Viem istemcisi oluşturun. Yalnızca blokzincirden okuma yapmamız gerekiyor, bu nedenle bu istemcinin bir özel anahtara ihtiyacı yok. + +```typescript +const testedAddress = "0xb047c8032b99841713b8e3872f06cf32beb27b82" +const fromBlock = 16859812n +const toBlock = 16873372n +``` + +Şüpheli ERC-20 sözleşmesinin adresi ve olayları arayacağımız bloklar. Düğüm sağlayıcıları, bant genişliği pahalı olabileceğinden olayları okuma yeteneğimizi genellikle sınırlar. Neyse ki `wARB` on sekiz saatlik bir süre boyunca kullanılmadı, bu yüzden tüm olaylara bakabiliriz (toplamda sadece 13 tane vardı). + +```typescript +const approvalEvents = await client.getLogs({ + address: testedAddress, + fromBlock, + toBlock, + event: parseAbiItem( + "event Approval(address indexed _owner, address indexed _spender, uint256 _value)" + ), +}) +``` + +Bu, Viem'den olay bilgisi istemenin yoludur. Alan adları da dahil olmak üzere tam olay imzasını sağladığımızda, olayı bizim için ayrıştırır. + +```typescript +const isContract = async (addr: Address): boolean => + await client.getBytecode({ address: addr }) +``` + +Algoritmamız yalnızca harici olarak sahip olunan hesaplar için geçerlidir. `client.getBytecode` tarafından döndürülen herhangi bir bit kodu varsa, bu bir sözleşme olduğu anlamına gelir ve onu atlamalıyız. + +Daha önce TypeScript kullanmadıysanız, fonksiyon tanımı biraz garip görünebilir. Sadece ilk (ve tek) parametrenin `addr` olarak adlandırıldığını değil, aynı zamanda `Address` türünde olduğunu da söylüyoruz. Benzer şekilde, `: boolean` kısmı TypeScript'e fonksiyonun dönüş değerinin bir boole değeri olduğunu söyler. + +```typescript +const getEventTxn = async (ev: Event): TransactionReceipt => + await client.getTransactionReceipt({ hash: ev.transactionHash }) +``` + +Bu fonksiyon, bir olaydan işlem makbuzunu alır. İşlem hedefinin ne olduğunu bildiğimizden emin olmak için makbuza ihtiyacımız var. + +```typescript +const suspiciousApprovalEvent = async (ev : Event) : (Event | null) => { +``` + +Bu, bir olayın şüpheli olup olmadığına gerçekten karar veren en önemli fonksiyondur. Dönüş türü, `(Event | null)`, TypeScript'e bu fonksiyonun bir `Event` veya `null` döndürebileceğini söyler. Olay şüpheli değilse `null` döndürürüz. + +```typescript +const owner = ev.args._owner +``` + +Viem'de alan adları var, bu yüzden olayı bizim için ayrıştırdı. `_owner`, harcanacak jetonların sahibidir. + +```typescript +// Sözleşmeler tarafından yapılan onaylar şüpheli değildir +if (await isContract(owner)) return null +``` + +Sahip bir sözleşme ise, bu onayın şüpheli olmadığını varsayın. Bir sözleşmenin onayının şüpheli olup olmadığını kontrol etmek için, işlemin tam yürütmesini takip ederek sahip sözleşmesine ulaşıp ulaşmadığını ve bu sözleşmenin doğrudan ERC-20 sözleşmesini çağırıp çağırmadığını görmemiz gerekecek. Bu, yapmak istediğimizden çok daha fazla kaynak gerektirir. + +```typescript +const txn = await getEventTxn(ev) +``` + +Onay harici olarak sahip olunan bir hesaptan geliyorsa, buna neden olan işlemi alın. + +```typescript +// Onay, işlemin `from`'u olmayan bir EOA sahibinden geliyorsa şüphelidir +if (owner.toLowerCase() != txn.from.toLowerCase()) return ev +``` + +Sadece dize eşitliğini kontrol edemeyiz çünkü adresler onaltılıktır, bu yüzden harf içerirler. Bazen, örneğin `txn.from`'da, bu harflerin hepsi küçük harftir. Diğer durumlarda, örneğin `ev.args._owner`'da, adres [hata tespiti için karışık büyük/küçük harf](https://eips.ethereum.org/EIPS/eip-55) şeklindedir. + +Ancak işlem sahibinden değilse ve bu sahip harici olarak sahip olunuyorsa, şüpheli bir işlemimiz var demektir. + +```typescript +// İşlem hedefi, araştırdığımız ERC-20 sözleşmesi değilse de şüphelidir +// +if (txn.to.toLowerCase() != testedAddress) return ev +``` + +Benzer şekilde, işlemin `to` adresi, yani çağrılan ilk sözleşme, araştırılan ERC-20 sözleşmesi değilse, şüphelidir. + +```typescript + // Şüphelenmek için bir neden yoksa null döndürün. + return null +} +``` + +Her iki koşul da doğru değilse `Approval` olayı şüpheli değildir. + +```typescript +const testPromises = approvalEvents.map((ev) => suspiciousApprovalEvent(ev)) +const testResults = (await Promise.all(testPromises)).filter((x) => x != null) + +console.log(testResults) +``` + +[Bir `async` fonksiyonu](https://www.w3schools.com/js/js_async.asp) bir `Promise` nesnesi döndürür. Yaygın sözdizimi olan `await x()` ile, işlemeye devam etmeden önce o `Promise`'in yerine getirilmesini bekleriz. Bunu programlamak ve takip etmek basittir, ancak aynı zamanda verimsizdir. Belirli bir olay için `Promise`'in yerine getirilmesini beklerken, bir sonraki olay üzerinde çalışmaya başlayabiliriz. + +Burada bir `Promise` nesneleri dizisi oluşturmak için [`map`](https://www.w3schools.com/jsref/jsref_map.asp) kullanıyoruz. Ardından, tüm bu sözlerin çözülmesini beklemek için [`Promise.all`](https://www.javascripttutorial.net/es6/javascript-promise-all/) kullanırız. Daha sonra şüpheli olmayan olayları kaldırmak için bu sonuçları [`filter`](https://www.w3schools.com/jsref/jsref_filter.asp) ederiz. + +### Şüpheli `Transfer` olayları {#suspicious-transfer-events} + +Dolandırıcı jetonları belirlemenin bir başka olası yolu da şüpheli transferleri olup olmadığına bakmaktır. Örneğin, o kadar çok jetonu olmayan hesaplardan yapılan transferler. [Bu testin nasıl uygulanacağını](https://github.com/qbzzt/20230915-scam-token-detection/blob/main/susTransfer.ts) görebilirsiniz, ancak `wARB`'de bu sorun yoktur. + +## Sonuç {#conclusion} + +ERC-20 dolandırıcılıklarının otomatik olarak tespiti [yanlış negatiflerden](https://en.wikipedia.org/wiki/False_positives_and_false_negatives#False_negative_error) muzdariptir, çünkü bir dolandırıcılık, sadece gerçek bir şeyi temsil etmeyen tamamen normal bir ERC-20 jeton sözleşmesi kullanabilir. Bu yüzden her zaman _jeton adresini güvenilir bir kaynaktan almayı_ denemelisiniz. + +Otomatik algılama, çok sayıda jetonun bulunduğu ve otomatik olarak işlenmesi gereken DeFi parçaları gibi belirli durumlarda yardımcı olabilir. Ancak her zaman olduğu gibi [caveat emptor](https://www.investopedia.com/terms/c/caveatemptor.asp), kendi araştırmanızı yapın ve kullanıcılarınızı da aynısını yapmaya teşvik edin. + +[Çalışmalarımdan daha fazlası için buraya bakın](https://cryptodocguy.pro/). diff --git a/public/content/translations/tr/developers/tutorials/secret-state/index.md b/public/content/translations/tr/developers/tutorials/secret-state/index.md new file mode 100644 index 00000000000..9da538e3fed --- /dev/null +++ b/public/content/translations/tr/developers/tutorials/secret-state/index.md @@ -0,0 +1,597 @@ +--- +title: "Gizli bir durum için sıfır bilgi kullanma" +description: "Zincir üstü oyunlar, herhangi bir gizli bilgi tutamadıkları için sınırlıdır. Bu öğreticiyi okuduktan sonra, bir okuyucu, gizli bir duruma sahip doğrulanabilir oyunlar oluşturmak için sıfır bilgi ispatlarını ve sunucu bileşenlerini bir zincir dışı bileşenle birleştirebilecektir. Bunu yapma tekniği, bir mayın tarlası oyunu oluşturularak gösterilecektir." +author: Ori Pomerantz +tags: + [ + "sunucu", + "zincir dışında", + "merkezi", + "sıfır bilgi", + "zokrates", + "mud" + ] +skill: advanced +lang: tr +published: 2025-03-15 +--- + +_Blokzincirde sır yoktur_. Blokzincire gönderilen her şey herkesin okumasına açıktır. Bu gereklidir çünkü blokzincir, herkesin onu doğrulayabilmesi esasına dayanır. Ancak, oyunlar genellikle gizli duruma dayanır. Örneğin, bir blokzincir gezginine gidip haritayı görebiliyorsanız [mayın tarlası](https://en.wikipedia.org/wiki/Minesweeper_\(video_game\)) oyununun hiçbir anlamı kalmaz. + +En basit çözüm, gizli durumu tutmak için bir [sunucu bileşeni](/developers/tutorials/server-components/) kullanmaktır. Ancak, blokzinciri kullanmamızın nedeni, oyun geliştiricisinin hile yapmasını önlemektir. Sunucu bileşeninin dürüstlüğünden emin olmalıyız. Sunucu, durumun bir karmasını sağlayabilir ve bir hamlenin sonucunu hesaplamak için kullanılan durumun doğru olduğunu kanıtlamak için [sıfır bilgi ispatlarını](/zero-knowledge-proofs/#why-zero-knowledge-proofs-are-important) kullanabilir. + +Bu makaleyi okuduktan sonra, bu türde gizli durum tutan bir sunucuyu, durumu gösteren bir istemciyi ve ikisi arasındaki iletişim için bir zincir üstü bileşeni nasıl oluşturacağınızı bileceksiniz. Kullanacağımız ana araçlar şunlar olacaktır: + +| Araç | Amaç | Doğrulanan sürüm | +| --------------------------------------------- | ----------------------------------------------- | --------------------------------------: | +| [Zokrates](https://zokrates.github.io/) | Sıfır bilgi ispatları ve bunların doğrulanması | 1.1.9 | +| [Typescript](https://www.typescriptlang.org/) | Hem sunucu hem de istemci için programlama dili | 5.4.2 | +| [Node](https://nodejs.org/en) | Sunucuyu çalıştırma | 20.18.2 | +| [Viem](https://viem.sh/) | Blokzincir ile İletişim | 2.9.20 | +| [MUD](https://mud.dev/) | Zincir üstü veri yönetimi | 2.0.12 | +| [React](https://react.dev/) | İstemci kullanıcı arayüzü | 18.2.0 | +| [Vite](https://vitejs.dev/) | İstemci kodunu sunma | 4.2.1 | + +## Mayın Tarlası örneği {#minesweeper} + +[Mayın Tarlası](https://en.wikipedia.org/wiki/Minesweeper_\(video_game\)), mayınlı bir alana sahip gizli bir harita içeren bir oyundur. Oyuncu belirli bir konumda kazı yapmayı seçer. Eğer o konumda bir mayın varsa oyun biter. Aksi takdirde, oyuncu o konumu çevreleyen sekiz karedeki mayın sayısını alır. + +Bu uygulama, verileri [anahtar-değer veritabanı](https://aws.amazon.com/nosql/key-value/) kullanarak zincir üstünde depolamamıza ve bu verileri zincir dışı bileşenlerle otomatik olarak senkronize etmemize olanak tanıyan bir çerçeve olan [MUD](https://mud.dev/) kullanılarak yazılmıştır. Senkronizasyona ek olarak MUD, erişim kontrolü sağlamayı ve diğer kullanıcıların uygulamamızı izinsiz olarak [genişletmesini](https://mud.dev/guides/extending-a-world) kolaylaştırır. + +### Mayın Tarlası örneğini çalıştırma {#running-minesweeper-example} + +Mayın Tarlası örneğini çalıştırmak için: + +1. [Ön koşulları yüklediğinizden](https://mud.dev/quickstart#prerequisites) emin olun: [Node](https://mud.dev/quickstart#prerequisites), [Foundry](https://book.getfoundry.sh/getting-started/installation), [`git`](https://git-scm.com/downloads), [`pnpm`](https://git-scm.com/downloads) ve [`mprocs`](https://github.com/pvolok/mprocs). + +2. Depoyu klonlayın. + + ```sh copy + git clone https://github.com/qbzzt/20240901-secret-state.git + ``` + +3. Paketleri yükleyin. + + ```sh copy + cd 20240901-secret-state/\npnpm install\nnpm install -g mprocs + ``` + + Foundry `pnpm install` komutunun bir parçası olarak yüklendiyse komut satırı kabuğunu yeniden başlatmanız gerekir. + +4. Sözleşmeleri derleyin + + ```sh copy + cd packages/contracts\nforge build\ncd ../.. + ``` + +5. Programı ([anvil](https://book.getfoundry.sh/anvil/) blokzinciri dahil) başlatın ve bekleyin. + + ```sh copy + mprocs + ``` + + Başlatmanın uzun sürdüğünü unutmayın. İlerlemeyi görmek için önce aşağı ok tuşunu kullanarak _contracts_ sekmesine gidin ve MUD sözleşmelerinin dağıtıldığını görün. _Waiting for file changes…_ mesajını aldığınızda, sözleşmeler dağıtılmış demektir ve ilerlemenin devamı _server_ sekmesinde gerçekleşecektir. Orada, _Verifier address: 0x...._ mesajını alana kadar beklersiniz. + + Bu adım başarılı olursa `mprocs` ekranını görürsünüz; solda farklı işlemler ve sağda o anda seçili olan işlemin konsol çıktısı bulunur. + + ![mprocs ekranı](./mprocs.png) + + `mprocs` ile ilgili bir sorun varsa, dört işlemi manuel olarak, her birini kendi komut satırı penceresinde çalıştırabilirsiniz: + + - **Anvil** + + ```sh + cd packages/contracts\nanvil --base-fee 0 --block-time 2 + ``` + + - **Sözleşmeler** + + ```sh + cd packages/contracts\npnpm mud dev-contracts --rpc http://127.0.0.1:8545 + ``` + + - **Sunucu** + + ```sh + cd packages/server\npnpm start + ``` + + - **İstemci** + + ```sh + cd packages/client\npnpm run dev + ``` + +6. Şimdi [istemciye](http://localhost:3000) göz atabilir, **Yeni Oyun**'a tıklayabilir ve oynamaya başlayabilirsiniz. + +### Tablolar {#tables} + +Zincir üstünde [birkaç tabloya](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/mud.config.ts) ihtiyacımız var. + +- `Configuration`: Bu tablo bir tekildir, anahtarı yoktur ve tek bir kaydı vardır. Oyun yapılandırma bilgilerini tutmak için kullanılır: + - `height`: Bir mayın tarlasının yüksekliği + - `width`: Bir mayın tarlasının genişliği + - `numberOfBombs`: Her mayın tarlasındaki bomba sayısı + +- `VerifierAddress`: Bu tablo da bir tekildir. Yapılandırmanın bir parçasını, doğrulayıcı sözleşmenin adresini (`verifier`) tutmak için kullanılır. Bu bilgiyi `Configuration` tablosuna koyabilirdik, ancak sunucu olan farklı bir bileşen tarafından ayarlandığı için ayrı bir tabloya koymak daha kolaydır. + +- `PlayerGame`: Anahtar, oyuncunun adresidir. Veri şudur: + + - `gameId`: Oyuncunun oynadığı haritanın karması olan 32 baytlık değer (oyun tanımlayıcısı). + - `win`: oyuncunun oyunu kazanıp kazanmadığını belirten bir boole değeri. + - `lose`: oyuncunun oyunu kaybedip kaybetmediğini belirten bir boole değeri. + - `digNumber`: oyundaki başarılı kazıların sayısı. + +- `GamePlayer`: Bu tablo, `gameId`'den oyuncu adresine ters eşlemeyi tutar. + +- `Map`: Anahtar, üç değerden oluşan bir demettir: + + - `gameId`: Oyuncunun oynadığı haritanın karması olan 32 baytlık değer (oyun tanımlayıcısı). + - `x` koordinatı + - `y` koordinatı + + Değer tek bir sayıdır. Bir bomba tespit edilirse 255'tir. Aksi takdirde, o konumun etrafındaki bomba sayısının bir fazlasıdır. Sadece bomba sayısını kullanamayız, çünkü varsayılan olarak Ethereum Sanal Makinesi'ndeki tüm depolama ve MUD'daki tüm satır değerleri sıfırdır. "Oyuncu henüz burada kazı yapmadı" ile "oyuncu burada kazı yaptı ve etrafta sıfır bomba buldu" arasında ayrım yapmamız gerekiyor. + +Ek olarak, istemci ve sunucu arasındaki iletişim, zincir üstü bileşen aracılığıyla gerçekleşir. Bu da tablolar kullanılarak uygulanır. + +- `PendingGame`: Yeni bir oyun başlatmak için karşılanmamış istekler. +- `PendingDig`: Belirli bir oyunda belirli bir yerde kazı yapmak için karşılanmamış istekler. Bu bir [zincir dışı tablodur](https://mud.dev/store/tables#types-of-tables), yani EVM depolamasına yazılmaz, yalnızca zincir dışında olaylar kullanılarak okunabilir. + +### Yürütme ve veri akışları {#execution-data-flows} + +Bu akışlar istemci, zincir üstü bileşen ve sunucu arasındaki yürütmeyi koordine eder. + +#### Başlatma {#initialization-flow} + +`mprocs` komutunu çalıştırdığınızda şu adımlar gerçekleşir: + +1. [`mprocs`](https://github.com/pvolok/mprocs) dört bileşen çalıştırır: + + - [Anvil](https://book.getfoundry.sh/anvil/), yerel bir blokzincir çalıştırır + - [Contracts](https://github.com/qbzzt/20240901-secret-state/tree/main/packages/contracts), MUD için sözleşmeleri derler (gerekirse) ve dağıtır + - [Client](https://github.com/qbzzt/20240901-secret-state/tree/main/packages/client), kullanıcı arayüzünü ve istemci kodunu web tarayıcılarına sunmak için [Vite](https://vitejs.dev/) çalıştırır. + - [Server](https://github.com/qbzzt/20240901-secret-state/tree/main/packages/server), sunucu eylemlerini gerçekleştirir + +2. `contracts` paketi, MUD sözleşmelerini dağıtır ve ardından [`PostDeploy.s.sol` betiğini](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/script/PostDeploy.s.sol) çalıştırır. Bu betik yapılandırmayı ayarlar. GitHub'daki kod, [içinde sekiz mayın bulunan 10x5'lik bir mayın tarlası](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/script/PostDeploy.s.sol#L23) belirtir. + +3. [Sunucu](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts), [MUD'u ayarlayarak](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L6) başlar. Diğer şeylerin yanı sıra bu, veri senkronizasyonunu etkinleştirir, böylece ilgili tabloların bir kopyası sunucunun belleğinde bulunur. + +4. Sunucu, [`Configuration` tablosu değiştiğinde](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L23) yürütülecek bir fonksiyona abone olur. [Bu fonksiyon](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L24-L168), `PostDeploy.s.sol` yürütüldükten ve tabloyu değiştirdikten sonra çağrılır. + +5. Sunucu başlatma fonksiyonu yapılandırmaya sahip olduğunda, sunucunun [sıfır bilgi bölümünü](#using-zokrates-from-typescript) başlatmak için [`zkFunctions`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L34-L35) çağrısı yapar. Sıfır bilgi fonksiyonlarının mayın tarlasının genişliğini ve yüksekliğini sabit olarak alması gerektiğinden, yapılandırmayı alana kadar bu gerçekleşemez. + +6. Sunucunun sıfır bilgi bölümü başlatıldıktan sonra, bir sonraki adım [sıfır bilgi doğrulama sözleşmesini blokzincire dağıtmak](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L42-L53) ve MUD'da doğrulayıcı adresini ayarlamaktır. + +7. Son olarak, bir oyuncu [yeni bir oyun başlatmayı](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L55-L71) veya [mevcut bir oyunda kazı yapmayı](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L73-L108) talep ettiğinde görebilmek için güncellemelere abone oluruz. + +#### Yeni oyun {#new-game-flow} + +Oyuncu yeni bir oyun talep ettiğinde bunlar olur. + +1. Bu oyuncu için devam eden bir oyun yoksa veya varsa ama gameId değeri sıfırsa, istemci bir [yeni oyun düğmesi](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/App.tsx#L175) görüntüler. Kullanıcı bu düğmeye bastığında, [React `newGame` fonksiyonunu çalıştırır](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/App.tsx#L96). + +2. [`newGame`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/mud/createSystemCalls.ts#L43-L46) bir `System` çağrısıdır. MUD'da tüm çağrılar `World` sözleşmesi aracılığıyla yönlendirilir ve çoğu durumda `__` çağrısı yaparsınız. Bu durumda, çağrı `app__newGame`'edir, MUD daha sonra bunu [`GameSystem` içindeki `newGame`'e](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/GameSystem.sol#L16-L22) yönlendirir. + +3. Zincir üstü fonksiyon, oyuncunun devam eden bir oyunu olmadığını kontrol eder ve yoksa [isteği `PendingGame` tablosuna ekler](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/GameSystem.sol#L21). + +4. Sunucu, `PendingGame`'deki değişikliği algılar ve [abone olunan fonksiyonu çalıştırır](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L55-L71). Bu fonksiyon [`newGame`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L110-L114)'i çağırır, bu da [`createGame`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L116-L144)'i çağırır. + +5. `createGame`'in yaptığı ilk şey [uygun sayıda mayınla rastgele bir harita oluşturmaktır](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L120-L135). Ardından, Zokrates için gerekli olan boş kenarlıklı bir harita oluşturmak için [`makeMapBorders`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L147-L166) çağrısı yapar. Son olarak, `createGame`, oyun kimliği olarak kullanılan haritanın karmasını almak için [`calculateMapHash`](#calculateMapHash)'i çağırır. + +6. `newGame` fonksiyonu, yeni oyunu `gamesInProgress`'e ekler. + +7. Sunucunun yaptığı son şey, zincir üstü olan [`app__newGameResponse`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol#L38-L43)'u çağırmaktır. Bu fonksiyon, erişim kontrolünü etkinleştirmek için farklı bir `System`, [`ServerSystem`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol) içindedir. Erişim kontrolü, [MUD yapılandırma dosyasında](https://mud.dev/config), [`mud.config.ts`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/mud.config.ts#L67-L72) tanımlanır. + + Erişim listesi, yalnızca tek bir adresin `System`'i çağırmasına izin verir. Bu, sunucu fonksiyonlarına erişimi tek bir adresle sınırlar, böylece kimse sunucuyu taklit edemez. + +8. Zincir üstü bileşen ilgili tabloları günceller: + + - `PlayerGame` içinde oyunu oluşturun. + - `GamePlayer` içinde ters eşlemeyi ayarlayın. + - `PendingGame`'den isteği kaldırın. + +9. Sunucu `PendingGame`'deki değişikliği tanımlar, ancak [`wantsGame`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L58-L60) false olduğu için hiçbir şey yapmaz. + +10. İstemcide [`gameRecord`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/App.tsx#L143-L148), oyuncunun adresi için `PlayerGame` girişine ayarlanır. `PlayerGame` değiştiğinde, `gameRecord` da değişir. + +11. `gameRecord`'da bir değer varsa ve oyun kazanılmadıysa veya kaybedilmediyse, istemci [haritayı görüntüler](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/App.tsx#L175-L190). + +#### Kazı {#dig-flow} + +1. Oyuncu [harita hücresinin düğmesine tıklar](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/App.tsx#L188), bu da [`dig` fonksiyonunu](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/mud/createSystemCalls.ts#L33-L36) çağırır. Bu fonksiyon, [zincir üstündeki `dig`'i](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/GameSystem.sol#L24-L32) çağırır. + +2. Zincir üstü bileşen [bir dizi sağlık kontrolü gerçekleştirir](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/GameSystem.sol#L25-L30) ve başarılı olursa kazı isteğini [`PendingDig`'e ekler](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/GameSystem.sol#L31). + +3. Sunucu [`PendingDig`'deki değişikliği algılar](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L73). [Eğer geçerliyse](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L75-L84), hem sonucu hem de geçerli olduğuna dair bir kanıt oluşturmak için [sıfır bilgi kodunu](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L86-L95) (aşağıda açıklanmıştır) çağırır. + +4. [Sunucu](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L97-L107), zincir üstünde [`digResponse`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol#L45-L64) çağrısı yapar. + +5. `digResponse` iki şey yapar. İlk olarak, [sıfır bilgi ispatını](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol#L47-L61) kontrol eder. Ardından, ispat kontrol edilirse sonucu gerçekten işlemek için [`processDigResult`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol#L67-L86) çağrısı yapar. + +6. `processDigResult`, oyunun [kaybedilip](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol#L76-L78) [kazanılmadığını](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol#L83-L86) kontrol eder ve [zincir üstü harita olan `Map`'i günceller](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol#L80). + +7. İstemci güncellemeleri otomatik olarak alır ve [oyuncuya gösterilen haritayı günceller](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/App.tsx#L175-L190) ve uygunsa oyuncuya kazanıp kaybettiğini söyler. + +## Zokrates Kullanımı {#using-zokrates} + +Yukarıda açıklanan akışlarda, sıfır bilgi kısımlarını bir kara kutu olarak ele alarak atladık. Şimdi onu açalım ve bu kodun nasıl yazıldığını görelim. + +### Haritayı karıştırma {#hashing-map} + +Kullandığımız Zokrates karma fonksiyonu olan [Poseidon](https://www.poseidon-hash.info)'u uygulamak için [bu JavaScript kodunu](https://github.com/ZK-Plus/ICBC24_Tutorial_Compute-Offchain-Verify-onchain/tree/solutions/exercise) kullanabiliriz. Ancak, bu daha hızlı olsa da, bunu yapmak için sadece Zokrates karma fonksiyonunu kullanmaktan daha karmaşık olurdu. Bu bir öğreticidir ve bu nedenle kod performans için değil, basitlik için optimize edilmiştir. Bu nedenle, iki farklı Zokrates programına ihtiyacımız var, biri sadece bir haritanın karmasını hesaplamak için (`hash`) ve diğeri haritadaki bir konumdaki kazının sonucunun sıfır bilgi ispatını oluşturmak için (`dig`). + +### Karma fonksiyonu {#hash-function} + +Bu, bir haritanın karmasını hesaplayan fonksiyondur. Bu kodu satır satır inceleyeceğiz. + +``` +import "hashes/poseidon/poseidon.zok" as poseidon;\nimport "utils/pack/bool/pack128.zok" as pack128; +``` + +Bu iki satır, [Zokrates standart kütüphanesinden](https://zokrates.github.io/toolbox/stdlib.html) iki fonksiyonu içe aktarır. [İlk fonksiyon](https://github.com/Zokrates/ZoKrates/blob/latest/zokrates_stdlib/stdlib/hashes/poseidon/poseidon.zok), bir [Poseidon karmasıdır](https://www.poseidon-hash.info/). Bir [`field` elemanları](https://zokrates.github.io/language/types.html#field) dizisi alır ve bir `field` döndürür. + +Zokrates'teki alan elemanı tipik olarak 256 bitten daha kısadır, ancak çok da değil. Kodu basitleştirmek için, haritayı 512 bite kadar kısıtlıyoruz ve dört alandan oluşan bir diziyi karıştırıyoruz ve her alanda sadece 128 bit kullanıyoruz. [`pack128` fonksiyonu](https://github.com/Zokrates/ZoKrates/blob/latest/zokrates_stdlib/stdlib/utils/pack/bool/pack128.zok), bu amaçla 128 bitlik bir diziyi bir `field`'a dönüştürür. + +``` + def hashMap(bool[${width+2}][${height+2}] map) -> field { +``` + +Bu satır bir fonksiyon tanımı başlatır. `hashMap`, `map` adında tek bir parametre, iki boyutlu bir `bool`(ean) dizisi alır. Haritanın boyutu, [aşağıda açıklanan nedenlerden dolayı](#why-map-border) `width+2`'ye `height+2`'dir. + +Zokrates programları bu uygulamada [şablon dizeleri](https://www.w3schools.com/js/js_string_templates.asp) olarak saklandığı için `${width+2}` ve `${height+2}` kullanabiliriz. `${` ve `}` arasındaki kod JavaScript tarafından değerlendirilir ve bu şekilde program farklı harita boyutları için kullanılabilir. Harita parametresinin etrafında, içinde hiç bomba bulunmayan bir konum genişliğinde bir kenarlık bulunur, bu da genişlik ve yüksekliğe iki eklememizin nedenidir. + +Dönüş değeri, karmayı içeren bir `field`'dır. + +``` + bool[512] mut map1d = [false; 512]; +``` + +Harita iki boyutludur. Ancak, `pack128` fonksiyonu iki boyutlu dizilerle çalışmaz. Bu yüzden önce `map1d` kullanarak haritayı 512 baytlık bir diziye düzleştiririz. Varsayılan olarak Zokrates değişkenleri sabittir, ancak bu diziye bir döngü içinde değerler atamamız gerekir, bu yüzden onu [`mut`](https://zokrates.github.io/language/variables.html#mutability) olarak tanımlarız. + +Zokrates'in `undefined` özelliği olmadığı için diziyi başlatmamız gerekiyor. `[false; 512]` ifadesi [512 `false` değerinden oluşan bir dizi](https://zokrates.github.io/language/types.html#declaration-and-initialization) anlamına gelir. + +``` + u32 mut counter = 0; +``` + +Ayrıca `map1d`'de zaten doldurduğumuz bitlerle doldurmadıklarımızı ayırt etmek için bir sayaca ihtiyacımız var. + +``` + for u32 x in 0..${width+2} { +``` + +Zokrates'te bir [`for` döngüsü](https://zokrates.github.io/language/control_flow.html#for-loops) bu şekilde bildirilir. Bir Zokrates `for` döngüsünün sabit sınırları olmalıdır, çünkü bir döngü gibi görünse de, derleyici aslında onu "açar". `${width+2}` ifadesi, TypeScript kodu derleyiciyi çağırmadan önce `width` ayarlandığı için bir derleme zamanı sabitidir. + +``` + for u32 y in 0..${height+2} {\n map1d[counter] = map[x][y];\n counter = counter+1;\n }\n } +``` + +Haritadaki her konum için bu değeri `map1d` dizisine koyun ve sayacı artırın. + +``` + field[4] hashMe = [\n pack128(map1d[0..128]),\n pack128(map1d[128..256]),\n pack128(map1d[256..384]),\n pack128(map1d[384..512])\n ]; +``` + +`pack128`, `map1d`'den dört `field` değerinden oluşan bir dizi oluşturur. Zokrates'te `array[a..b]` dizinin `a`'da başlayıp `b-1`'de biten dilimi anlamına gelir. + +``` + return poseidon(hashMe);\n} +``` + +Bu diziyi bir karmaya dönüştürmek için `poseidon` kullanın. + +### Karma programı {#hash-program} + +Sunucunun, oyun tanımlayıcıları oluşturmak için doğrudan `hashMap`'i çağırması gerekir. Ancak, Zokrates başlatmak için bir programda yalnızca `main` fonksiyonunu çağırabilir, bu nedenle karma fonksiyonunu çağıran bir `main` içeren bir program oluştururuz. + +``` +${hashFragment}\n\ndef main(bool[${width+2}][${height+2}] map) -> field {\n return hashMap(map);\n} +``` + +### Kazı programı {#dig-program} + +Bu, uygulamanın sıfır bilgi kısmının kalbidir, burada kazı sonuçlarını doğrulamak için kullanılan kanıtları üretiriz. + +``` +${hashFragment}\n\n// (x,y) konumundaki mayın sayısı\ndef map2mineCount(bool[${width+2}][${height+2}] map, u32 x, u32 y) -> u8 {\n return if map[x+1][y+1] { 1 } else { 0 };\n} +``` + +#### Neden harita sınırı {#why-map-border} + +Sıfır bilgi ispatları, bir `if` ifadesinin kolay bir eşdeğerine sahip olmayan [aritmetik devreleri](https://medium.com/web3studio/simple-explanations-of-arithmetic-circuits-and-zero-knowledge-proofs-806e59a79785) kullanır. Bunun yerine, [koşullu operatörün](https://en.wikipedia.org/wiki/Ternary_conditional_operator) eşdeğerini kullanırlar. `a` sıfır veya bir olabiliyorsa, `if a { b } else { c }` ifadesini `ab+(1-a)c` olarak hesaplayabilirsiniz. + +Bu nedenle, bir Zokrates `if` ifadesi her zaman her iki dalı da değerlendirir. Örneğin, bu koda sahipseniz: + +``` +bool[5] arr = [false; 5];\nu32 index=10;\nreturn if index>4 { 0 } else { arr[index] } +``` + +`arr[10]`'u hesaplaması gerektiği için hata verir, bu değer daha sonra sıfırla çarpılacak olsa bile. + +Haritanın etrafında bir konum genişliğinde bir sınıra ihtiyacımız olmasının nedeni budur. Bir konumun etrafındaki toplam mayın sayısını hesaplamamız gerekiyor ve bu, kazı yaptığımız konumun bir satır üstünde ve altında, solunda ve sağındaki konumu görmemiz gerektiği anlamına geliyor. Bu da bu konumların Zokrates'e sağlanan harita dizisinde mevcut olması gerektiği anlamına gelir. + +``` +def main(private bool[${width+2}][${height+2}] map, u32 x, u32 y) -> (field, u8) { +``` + +Varsayılan olarak Zokrates kanıtları girdilerini içerir. Bir noktanın etrafında beş mayın olduğunu bilmek, aslında hangi nokta olduğunu bilmiyorsanız (ve sadece isteğinizle eşleştiremezsiniz, çünkü o zaman kanıtlayıcı farklı değerler kullanabilir ve size bu konuda bilgi vermeyebilir) bir işe yaramaz. Ancak, haritayı Zokrates'e sağlarken gizli tutmamız gerekiyor. Çözüm, kanıt tarafından _açıklanmayan_ bir `private` parametresi kullanmaktır. + +Bu, başka bir kötüye kullanım yolunu açar. Kanıtlayıcı doğru koordinatları kullanabilir, ancak konumun etrafında ve muhtemelen konumun kendisinde herhangi bir sayıda mayın içeren bir harita oluşturabilir. Bu kötüye kullanımı önlemek için, sıfır bilgi ispatının oyun tanımlayıcısı olan haritanın karmasını içermesini sağlıyoruz. + +``` + return (hashMap(map), +``` + +Buradaki dönüş değeri, harita karma dizisini ve kazı sonucunu içeren bir demettir. + +``` + if map2mineCount(map, x, y) > 0 { 0xFF } else { +``` + +Konumun kendisinde bir bomba olması durumunda özel bir değer olarak 255 kullanıyoruz. + +``` + map2mineCount(map, x-1, y-1) + map2mineCount(map, x, y-1) + map2mineCount(map, x+1, y-1) +\n map2mineCount(map, x-1, y) + map2mineCount(map, x+1, y) +\n map2mineCount(map, x-1, y+1) + map2mineCount(map, x, y+1) + map2mineCount(map, x+1, y+1)\n }\n );\n} +``` + +Oyuncu bir mayına çarpmadıysa, konumun etrafındaki alan için mayın sayılarını ekleyin ve bunu döndürün. + +### TypeScript'ten Zokrates Kullanımı {#using-zokrates-from-typescript} + +Zokrates'in bir komut satırı arayüzü vardır, ancak bu programda onu [TypeScript kodunda](https://zokrates.github.io/toolbox/zokrates_js.html) kullanıyoruz. + +Zokrates tanımlarını içeren kütüphaneye [`zero-knowledge.ts`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts) denir. + +```typescript +import { initialize as zokratesInitialize } from "zokrates-js" +``` + +[Zokrates JavaScript bağlamalarını](https://zokrates.github.io/toolbox/zokrates_js.html) içe aktarın. Tüm Zokrates tanımlarına çözümlenen bir söz döndürdüğü için yalnızca [`initialize`](https://zokrates.github.io/toolbox/zokrates_js.html#initialize) fonksiyonuna ihtiyacımız var. + +```typescript +export const zkFunctions = async (width: number, height: number) : Promise => { +``` + +Zokrates'in kendisine benzer şekilde, biz de yalnızca [asenkron](https://www.w3schools.com/js/js_async.asp) olan tek bir fonksiyonu dışa aktarıyoruz. Sonunda döndüğünde, aşağıda göreceğimiz gibi birkaç fonksiyon sağlar. + +```typescript +const zokrates = await zokratesInitialize() +``` + +Zokrates'i başlatın, kütüphaneden ihtiyacımız olan her şeyi alın. + +```typescript +const hashFragment = `\n import "utils/pack/bool/pack128.zok" as pack128;\n import "hashes/poseidon/poseidon.zok" as poseidon;\n .\n .\n .\n }\n `\n\nconst hashProgram = `\n ${hashFragment}\n .\n .\n .\n `\n\nconst digProgram = `\n ${hashFragment}\n .\n .\n .\n ` +``` + +Ardından, yukarıda gördüğümüz karma fonksiyonu ve iki Zokrates programımız var. + +```typescript +const digCompiled = zokrates.compile(digProgram)\nconst hashCompiled = zokrates.compile(hashProgram) +``` + +Burada bu programları derliyoruz. + +```typescript +// Sıfır bilgi doğrulaması için anahtarları oluşturun.\n// Bir üretim sisteminde bir kurulum töreni kullanmak istersiniz.\n// (https://zokrates.github.io/toolbox/trusted_setup.html#initializing-a-phase-2-ceremony).\nconst keySetupResults = zokrates.setup(digCompiled.program, "")\nconst verifierKey = keySetupResults.vk\nconst proverKey = keySetupResults.pk +``` + +Bir üretim sisteminde daha karmaşık bir [kurulum töreni](https://zokrates.github.io/toolbox/trusted_setup.html#initializing-a-phase-2-ceremony) kullanabiliriz, ancak bu bir gösterim için yeterince iyidir. Kullanıcıların kanıtlayıcı anahtarını bilmeleri bir sorun değildir - doğru olmadıkça yine de bir şeyleri kanıtlamak için kullanamazlar. Entropiyi (ikinci parametre, `""`) belirttiğimiz için, sonuçlar her zaman aynı olacaktır. + +**Not:** Zokrates programlarının derlenmesi ve anahtar oluşturulması yavaş süreçlerdir. Bunları her seferinde tekrarlamaya gerek yoktur, sadece harita boyutu değiştiğinde. Bir üretim sisteminde bunları bir kez yaparsınız ve sonra çıktıyı saklarsınız. Bunu burada yapmamamın tek nedeni basitlik uğrunadır. + +#### `calculateMapHash` {#calculateMapHash} + +```typescript +const calculateMapHash = function (hashMe: boolean[][]): string {\n return (\n "0x" +\n BigInt(zokrates.computeWitness(hashCompiled, [hashMe]).output.slice(1, -1))\n .toString(16)\n .padStart(64, "0")\n )\n} +``` + +[`computeWitness`](https://zokrates.github.io/toolbox/zokrates_js.html#computewitnessartifacts-args-options) fonksiyonu aslında Zokrates programını çalıştırır. İki alanlı bir yapı döndürür: `output`, programın çıktısı olan bir JSON dizesi ve `witness`, sonucun sıfır bilgi kanıtını oluşturmak için gereken bilgidir. Burada sadece çıktıya ihtiyacımız var. + +Çıktı, `"31337"` biçiminde, tırnak işaretleri içinde yer alan bir ondalık sayı olan bir dizedir. Ancak `viem` için ihtiyacımız olan çıktı, `0x60A7` biçiminde bir onaltılık sayıdır. Bu yüzden tırnak işaretlerini kaldırmak için `.slice(1,-1)` ve ardından kalan dizeyi, ondalık bir sayı olan, bir [`BigInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt)'e dönüştürmek için `BigInt` kullanırız. `.toString(16)`, bu `BigInt`'i bir onaltılık dizeye dönüştürür ve `"0x"+`, onaltılık sayılar için işaretleyiciyi ekler. + +```typescript +// Kazın ve sonucun sıfır bilgi kanıtını döndürün\n// (sunucu tarafı kodu) +``` + +Sıfır bilgi ispatı, genel girdileri (`x` ve `y`) ve sonuçları (haritanın karması ve bomba sayısı) içerir. + +```typescript + const zkDig = function(map: boolean[][], x: number, y: number) : any {\n if (x<0 || x>=width || y<0 || y>=height)\n throw new Error("Haritanın dışında kazmaya çalışıyorsunuz") +``` + +Zokrates'te bir dizinin sınırları dışında olup olmadığını kontrol etmek bir sorundur, bu yüzden bunu burada yapıyoruz. + +```typescript +const runResults = zokrates.computeWitness(digCompiled, [map, `${x}`, `${y}`]) +``` + +Kazı programını çalıştırın. + +```typescript + const proof = zokrates.generateProof(\n digCompiled.program,\n runResults.witness,\n proverKey)\n\n return proof\n } +``` + +[`generateProof`](https://zokrates.github.io/toolbox/zokrates_js.html#generateproofprogram-witness-provingkey-entropy) kullanın ve ispatı döndürün. + +```typescript +const solidityVerifier = `\n // Harita boyutu: ${width} x ${height}\n \n${zokrates.exportSolidityVerifier(verifierKey)}\n ` +``` + +Bir Solidity doğrulayıcısı, blokzincire dağıtabileceğimiz ve `digCompiled.program` tarafından oluşturulan kanıtları doğrulamak için kullanabileceğimiz bir akıllı sözleşme. + +```typescript + return {\n zkDig,\n calculateMapHash,\n solidityVerifier,\n }\n} +``` + +Son olarak, diğer kodun ihtiyaç duyabileceği her şeyi döndürün. + +## Güvenlik testleri {#security-tests} + +Güvenlik testleri önemlidir çünkü bir işlevsellik hatası eninde sonunda kendini belli edecektir. Ancak uygulama güvensizse, bu durum muhtemelen birinin hile yapıp başkalarına ait kaynaklarla kaçmasıyla ortaya çıkmadan önce uzun süre gizli kalacaktır. + +### İzinler {#permissions} + +Bu oyunda ayrıcalıklı bir varlık var, sunucu. [`ServerSystem`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol) içindeki fonksiyonları çağırmasına izin verilen tek kullanıcı odur. İzinli fonksiyonlara yapılan çağrıların yalnızca sunucu hesabı olarak izin verildiğini doğrulamak için [`cast`](https://book.getfoundry.sh/cast/) kullanabiliriz. + +[Sunucunun özel anahtarı `setupNetwork.ts`'dedir](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/mud/setupNetwork.ts#L52). + +1. `anvil`'i (blokzincir) çalıştıran bilgisayarda bu ortam değişkenlerini ayarlayın. + + ```sh copy + WORLD_ADDRESS=0x8d8b6b8414e1e3dcfd4168561b9be6bd3bf6ec4b\nUNAUTHORIZED_KEY=0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a\nAUTHORIZED_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d + ``` + +2. `cast` kullanarak doğrulayıcı adresini yetkisiz bir adres olarak ayarlamayı deneyin. + + ```sh copy + cast send $WORLD_ADDRESS 'app__setVerifier(address)' `cast address-zero` --private-key $UNAUTHORIZED_KEY + ``` + + `cast` yalnızca bir başarısızlık bildirmekle kalmaz, aynı zamanda tarayıcıdaki oyunda **MUD Geliştirici Araçları**'nı açabilir, **Tablolar**'a tıklayabilir ve **app\_\_VerifierAddress**'i seçebilirsiniz. Adresin sıfır olmadığını görün. + +3. Doğrulayıcı adresini sunucunun adresi olarak ayarlayın. + + ```sh copy + cast send $WORLD_ADDRESS 'app__setVerifier(address)' `cast address-zero` --private-key $AUTHORIZED_KEY + ``` + + **app\_\_VerifiedAddress**'deki adres artık sıfır olmalıdır. + +Aynı `System`'deki tüm MUD fonksiyonları aynı erişim kontrolünden geçer, bu yüzden bu testi yeterli görüyorum. Eğer öyle düşünmüyorsanız, [`ServerSystem`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol) içindeki diğer fonksiyonları kontrol edebilirsiniz. + +### Sıfır bilgi kötüye kullanımları {#zero-knowledge-abuses} + +Zokrates'i doğrulamak için gereken matematik bu öğreticinin (ve benim yeteneklerimin) kapsamı dışındadır. Ancak, sıfır bilgi kodunun doğru yapılmadığında başarısız olduğunu doğrulamak için çeşitli kontroller yapabiliriz. Tüm bu testler, [`zero-knowledge.ts`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts) dosyasını değiştirmemizi ve tüm uygulamayı yeniden başlatmamızı gerektirecektir. Uygulamayı imkansız bir duruma soktuğu için (oyuncunun devam eden bir oyunu var, ancak oyun artık sunucu tarafından kullanılamıyor) sunucu işlemini yeniden başlatmak yeterli değildir. + +#### Yanlış cevap {#wrong-answer} + +En basit olasılık, sıfır bilgi ispatında yanlış cevap vermektir. Bunu yapmak için `zkDig` içine girip [91. satırı değiştiriyoruz](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts#L91): + +```ts +proof.inputs[3] = "0x" + "1".padStart(64, "0") +``` + +Bu, doğru cevaba bakılmaksızın her zaman bir bomba olduğunu iddia edeceğimiz anlamına gelir. Bu sürümle oynamayı deneyin ve `pnpm dev` ekranının **sunucu** sekmesinde şu hatayı göreceksiniz: + +``` + cause: {\n code: 3,\n message: 'yürütme geri alındı: geri al: Sıfır bilgi doğrulaması başarısız',\n data: '0x08c379a00000000000000000000000000000000000000000000000000000000000000002000000000000000\n000000000000000000000000000000000000000000000000205a65726f206b6e6f776c6564676520766572696669636174696f6\ne206661696c'\n }, +``` + +Yani bu tür bir hile başarısız olur. + +#### Yanlış ispat {#wrong-proof} + +Doğru bilgiyi verirsek ama sadece yanlış ispat verimiz varsa ne olur? Şimdi, 91. satırı şununla değiştirin: + +```ts +proof.proof = {\n a: ["0x" + "1".padStart(64, "0"), "0x" + "2".padStart(64, "0")],\n b: [\n ["0x" + "1".padStart(64, "0"), "0x" + "2".padStart(64, "0")],\n ["0x" + "1".padStart(64, "0"), "0x" + "2".padStart(64, "0")],\n ],\n c: ["0x" + "1".padStart(64, "0"), "0x" + "2".padStart(64, "0")],\n} +``` + +Yine de başarısız oluyor, ancak şimdi doğrulayıcı çağrısı sırasında gerçekleştiği için bir neden olmadan başarısız oluyor. + +### Bir kullanıcı sıfır güven kodunu nasıl doğrulayabilir? {#user-verify-zero-trust} + +Akıllı sözleşmeleri doğrulamak nispeten kolaydır. Tipik olarak, geliştirici kaynak kodunu bir blok gezgininde yayınlar ve blok gezgini, kaynak kodunun [sözleşme dağıtım işlemindeki](/developers/docs/smart-contracts/deploying/) koda derlendiğini doğrular. MUD `System`'leri durumunda bu [biraz daha karmaşıktır](https://mud.dev/cli/verify), ancak çok değil. + +Bu, sıfır bilgi ile daha zordur. Doğrulayıcı bazı sabitleri içerir ve onlar üzerinde bazı hesaplamalar yapar. Bu size neyin kanıtlandığını söylemez. + +```solidity + function verifyingKey() pure internal returns (VerifyingKey memory vk) {\n vk.alpha = Pairing.G1Point(uint256(0x0f43f4fe7b5c2326fed4ac6ed2f4003ab9ab4ea6f667c2bdd77afb068617ee16), uint256(0x25a77832283f9726935219b5f4678842cda465631e72dbb24708a97ba5d0ce6f));\n vk.beta = Pairing.G2Point([uint256(0x2cebd0fbd21aca01910581537b21ae4fed46bc0e524c055059aa164ba0a6b62b), uint256(0x18fd4a7bc386cf03a95af7163d5359165acc4e7961cb46519e6d9ee4a1e2b7e9)], [uint256(0x11449dee0199ef6d8eebfe43b548e875c69e7ce37705ee9a00c81fe52f11a009), uint256(0x066d0c83b32800d3f335bb9e8ed5e2924cf00e77e6ec28178592eac9898e1a00)]); +``` + +Çözüm, en azından blok gezginleri kullanıcı arayüzlerine Zokrates doğrulamasını ekleyene kadar, uygulama geliştiricilerinin Zokrates programlarını kullanıma sunması ve en azından bazı kullanıcıların bunları uygun doğrulama anahtarıyla kendilerinin derlemesidir. + +Bunu yapmak için: + +1. [Zokrates'i yükleyin](https://zokrates.github.io/gettingstarted.html). + +2. Zokrates programıyla bir `dig.zok` dosyası oluşturun. Aşağıdaki kod, orijinal harita boyutu olan 10x5'i koruduğunuzu varsayar. + + ```zokrates + import "utils/pack/bool/pack128.zok" as pack128;\n import "hashes/poseidon/poseidon.zok" as poseidon;\n\n def hashMap(bool[12][7] map) -> field {\n bool[512] mut map1d = [false; 512];\n u32 mut counter = 0;\n\n for u32 x in 0..12 {\n for u32 y in 0..7 {\n map1d[counter] = map[x][y];\n counter = counter+1;\n }\n }\n\n field[4] hashMe = [\n pack128(map1d[0..128]),\n pack128(map1d[128..256]),\n pack128(map1d[256..384]),\n pack128(map1d[384..512])\n ];\n\n return poseidon(hashMe);\n }\n\n\n // (x,y) konumundaki mayınların sayısı\n def map2mineCount(bool[12][7] map, u32 x, u32 y) -> u8 {\n return if map[x+1][y+1] { 1 } else { 0 };\n }\n\n def main(private bool[12][7] map, u32 x, u32 y) -> (field, u8) {\n return (hashMap(map) ,\n if map2mineCount(map, x, y) > 0 { 0xFF } else {\n map2mineCount(map, x-1, y-1) + map2mineCount(map, x, y-1) + map2mineCount(map, x+1, y-1) +\n map2mineCount(map, x-1, y) + map2mineCount(map, x+1, y) +\n map2mineCount(map, x-1, y+1) + map2mineCount(map, x, y+1) + map2mineCount(map, x+1, y+1)\n }\n );\n } + ``` + +3. Zokrates kodunu derleyin ve doğrulama anahtarını oluşturun. Doğrulama anahtarı, orijinal sunucuda kullanılan aynı entropi ile oluşturulmalıdır, [bu durumda boş bir dizedir](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts#L67). + + ```sh copy + zokrates compile --input dig.zok\nzokrates setup -e "" + ``` + +4. Solidity doğrulayıcısını kendi başınıza oluşturun ve blokzincirdekiyle işlevsel olarak aynı olduğunu doğrulayın (sunucu bir yorum ekler, ancak bu önemli değildir). + + ```sh copy + zokrates export-verifier\ndiff verifier.sol ~/20240901-secret-state/packages/contracts/src/verifier.sol + ``` + +## Tasarım kararları {#design} + +Yeterince karmaşık herhangi bir uygulamada, ödünler gerektiren rakip tasarım hedefleri vardır. Bazı ödünlere ve mevcut çözümün neden diğer seçeneklere tercih edilebilir olduğuna bakalım. + +### Neden sıfır bilgi {#why-zero-knowledge} + +Mayın tarlası için gerçekten sıfır bilgiye ihtiyacınız yok. Sunucu her zaman haritayı tutabilir ve ardından oyun bittiğinde hepsini ortaya çıkarabilir. Ardından, oyunun sonunda akıllı sözleşme harita karmasını hesaplayabilir, eşleştiğini doğrulayabilir ve eşleşmezse sunucuyu cezalandırabilir veya oyunu tamamen yok sayabilir. + +Bu daha basit çözümü kullanmadım çünkü yalnızca iyi tanımlanmış bir son durumu olan kısa oyunlar için çalışıyor. Bir oyun potansiyel olarak sonsuz olduğunda ([otonom dünyalar](https://0xparc.org/blog/autonomous-worlds) durumunda olduğu gibi), durumu _açığa çıkarmadan_ kanıtlayan bir çözüme ihtiyacınız vardır. + +Bir öğretici olarak bu makale, anlaşılması kolay kısa bir oyuna ihtiyaç duyuyordu, ancak bu teknik daha uzun oyunlar için en kullanışlıdır. + +### Neden Zokrates? {#why-zokrates} + +[Zokrates](https://zokrates.github.io/) mevcut tek sıfır bilgi kütüphanesi değildir, ancak normal, [zorunlu](https://en.wikipedia.org/wiki/Imperative_programming) bir programlama diline benzer ve boole değişkenlerini destekler. + +Uygulamanız için, farklı gereksinimlerle, [Circum](https://docs.circom.io/getting-started/installation/) veya [Cairo](https://www.cairo-lang.org/tutorials/getting-started-with-cairo/)'yu kullanmayı tercih edebilirsiniz. + +### Zokrates ne zaman derlenmeli {#when-compile-zokrates} + +Bu programda, Zokrates programlarını [sunucu her başladığında](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts#L60-L61) derliyoruz. Bu açıkça bir kaynak israfıdır, ancak bu bir öğreticidir, basitlik için optimize edilmiştir. + +Eğer bir üretim seviyesinde uygulama yazıyor olsaydım, bu mayın tarlası boyutunda derlenmiş Zokrates programları içeren bir dosyam olup olmadığını kontrol eder ve varsa onu kullanırdım. Aynı şey, zincir üstünde bir doğrulayıcı sözleşmesi dağıtmak için de geçerlidir. + +### Doğrulayıcı ve kanıtlayıcı anahtarları oluşturma {#key-creation} + +[Anahtar oluşturma](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts#L63-L69), belirli bir mayın tarlası boyutu için bir kereden fazla yapılması gerekmeyen başka bir saf hesaplamadır. Yine, yalnızca basitlik uğruna bir kez yapılır. + +Ek olarak, [bir kurulum töreni](https://zokrates.github.io/toolbox/trusted_setup.html#initializing-a-phase-2-ceremony) kullanabiliriz. Bir kurulum töreninin avantajı, sıfır bilgi ispatında hile yapmak için her katılımcıdan ya entropiye ya da bir ara sonuca ihtiyacınız olmasıdır. En az bir tören katılımcısı dürüstse ve bu bilgiyi silerse, sıfır bilgi ispatları belirli saldırılardan güvende olur. Ancak, bilginin her yerden silindiğini doğrulamak için _hiçbir mekanizma_ yoktur. Sıfır bilgi ispatları kritik derecede önemliyse, kurulum törenine katılmak istersiniz. + +Burada, düzinelerce katılımcısı olan [sürekli tau güçlerine](https://github.com/privacy-scaling-explorations/perpetualpowersoftau) güveniyoruz. Muhtemelen yeterince güvenlidir ve çok daha basittir. Ayrıca, kullanıcıların [sıfır bilgi yapılandırmasını doğrulamalarını](#user-verify-zero-trust) kolaylaştıran anahtar oluşturma sırasında entropi eklemiyoruz. + +### Nerede doğrulanmalı {#where-verification} + +Sıfır bilgi ispatlarını ya zincir üstünde (gaz maliyeti olan) ya da istemcide ([`verify`](https://zokrates.github.io/toolbox/zokrates_js.html#verifyverificationkey-proof) kullanarak) doğrulayabiliriz. İlkini seçtim, çünkü bu, [doğrulayıcıyı bir kez doğrulamanıza](#user-verify-zero-trust) ve sonra sözleşme adresi aynı kaldığı sürece değişmediğine güvenmenize olanak tanır. Doğrulama istemcide yapılsaydı, istemciyi her indirdiğinizde aldığınız kodu doğrulamanız gerekirdi. + +Ayrıca, bu oyun tek oyunculu olsa da, birçok blokzincir oyunu çok oyunculudur. zincir üstü doğrulama, sıfır bilgi ispatını yalnızca bir kez doğrulamanız anlamına gelir. Bunu istemcide yapmak, her istemcinin bağımsız olarak doğrulamasını gerektirirdi. + +### Haritayı TypeScript'te mi yoksa Zokrates'te mi düzleştirmeli? {#where-flatten} + +Genel olarak, işleme TypeScript veya Zokrates'te yapılabildiğinde, çok daha hızlı olan ve sıfır bilgi ispatları gerektirmeyen TypeScript'te yapmak daha iyidir. Örneğin, Zokrates'e karmayı sağlayıp doğru olduğunu doğrulamasını yaptırmamamızın nedeni budur. Karma işlemi Zokrates içinde yapılmalıdır, ancak döndürülen karma ile zincir üstündeki karma arasındaki eşleşme onun dışında gerçekleşebilir. + +Ancak, TypeScript'te yapabilecekken haritayı [Zokrates'te düzleştiriyoruz](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts#L15-L20). Nedeni, diğer seçeneklerin bence daha kötü olmasıdır. + +- Zokrates koduna tek boyutlu bir boole dizisi sağlayın ve iki boyutlu haritayı elde etmek için `x*(height+2)\n+y` gibi bir ifade kullanın. Bu, [kodu](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts#L44-L47) biraz daha karmaşık hale getirirdi, bu yüzden performans kazancının bir öğretici için değmeyeceğine karar verdim. + +- Zokrates'e hem tek boyutlu diziyi hem de iki boyutlu diziyi gönderin. Ancak, bu çözüm bize hiçbir şey kazandırmaz. Zokrates kodu, sağlanan tek boyutlu dizinin gerçekten iki boyutlu dizinin doğru temsili olduğunu doğrulamak zorunda kalırdı. Yani herhangi bir performans kazancı olmazdı. + +- Zokrates'te iki boyutlu diziyi düzleştirin. Bu en basit seçenektir, bu yüzden onu seçtim. + +### Haritalar nerede saklanmalı {#where-store-maps} + +Bu uygulamada [`gamesInProgress`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L20) bellekte basit bir değişkendir. Bu, sunucunuz ölürse ve yeniden başlatılması gerekirse, sakladığı tüm bilgilerin kaybolacağı anlamına gelir. Oyuncular sadece oyunlarına devam edememekle kalmaz, zincir üstü bileşen hala devam eden bir oyunları olduğunu düşündüğü için yeni bir oyun bile başlatamazlar. + +Bu, bu bilgiyi bir veritabanında saklayacağınız bir üretim sistemi için açıkça kötü bir tasarımdır. Burada bir değişken kullanmamın tek nedeni, bunun bir öğretici olması ve basitliğin ana husus olmasıdır. + +## Sonuç: Bu tekniğin uygun olduğu koşullar nelerdir? {#conclusion} + +Artık, zincir üstünde olmaması gereken gizli durumu saklayan bir sunucu ile bir oyun yazmayı biliyorsunuz. Ama hangi durumlarda yapmalısınız? İki ana husus vardır. + +- _Uzun süren oyun_: [Yukarıda belirtildiği gibi](#why-zero-knowledge), kısa bir oyunda oyun bittiğinde durumu yayınlayabilir ve her şeyin o zaman doğrulanmasını sağlayabilirsiniz. Ancak oyun uzun veya belirsiz bir süre aldığında ve durumun gizli kalması gerektiğinde bu bir seçenek değildir. + +- _Bazı merkezileştirme kabul edilebilir_: Sıfır bilgi ispatları, bir varlığın sonuçları taklit etmediği bütünlüğü doğrulayabilir. Yapamadıkları şey, varlığın hala kullanılabilir olacağını ve mesajlara cevap vereceğini sağlamaktır. Kullanılabilirliğin de merkeziyetsiz olması gereken durumlarda, sıfır bilgi ispatları yeterli bir çözüm değildir ve [çok taraflı hesaplamaya](https://en.wikipedia.org/wiki/Secure_multi-party_computation) ihtiyacınız vardır. + +[Çalışmalarımdan daha fazlası için buraya bakın](https://cryptodocguy.pro/). + +### Teşekkürler {#acknowledgements} + +- Alvaro Alonso bu makalenin bir taslağını okudu ve Zokrates hakkındaki bazı yanlış anlamalarımı giderdi. + +Kalan hatalar benim sorumluluğumdadır. diff --git a/public/content/translations/tr/developers/tutorials/secure-development-workflow/index.md b/public/content/translations/tr/developers/tutorials/secure-development-workflow/index.md index 4d6b680f0d8..10da987593d 100644 --- a/public/content/translations/tr/developers/tutorials/secure-development-workflow/index.md +++ b/public/content/translations/tr/developers/tutorials/secure-development-workflow/index.md @@ -1,15 +1,12 @@ --- -title: Akıllı sözleşme güvenlik kontrol listesi -description: Güvenli akıllı sözleşmeler yazmak için önerilen bir iş akışı +title: "Akıllı sözleşme güvenlik kontrol listesi" +description: "Güvenli akıllı sözleşmeler yazmak için önerilen bir iş akışı" author: "Trailofbits" -tags: - - "akıllı sözleşmeler" - - "güvenlik" - - "katılık" +tags: [ "akıllı kontratlar", "güvenlik", "solidity" ] skill: intermediate lang: tr published: 2020-09-07 -source: Güvenli sözleşmeler oluşturmak +source: Building secure contracts sourceUrl: https://github.com/crytic/building-secure-contracts/blob/master/development-guidelines/workflow.md --- @@ -19,14 +16,14 @@ sourceUrl: https://github.com/crytic/building-secure-contracts/blob/master/devel Bilinen güvenlik sorunlarını kontrol edin: -- [Slither](https://github.com/crytic/slither) ile sözleşmelerinizi gözden geçirin. Yaygın güvenlik açıkları için 40'tan fazla yerleşik algılayıcıya sahiptir. Her girişte yeni kodla çalıştırın ve temiz bir rapor aldığından emin olun (veya belirli sorunları susturmak için önceliklendirme modunu kullanın). -- [Crytic](https://crytic.io/) ile sözleşmelerinizi gözden geçirin. Slither'ın kontrol etmediği 50 sorunu kontrol eder. Crytic, GitHub'daki Çekme Taleplerinde güvenlik sorunlarını kolayca ortaya çıkararak ekibinizin de kendi içinde güncel kalmasına yardımcı olabilir. +- Sözleşmelerinizi [Slither](https://github.com/crytic/slither) ile gözden geçirin. Yaygın güvenlik açıkları için 40'tan fazla yerleşik algılayıcıya sahiptir. Her girişte yeni kodla çalıştırın ve temiz bir rapor aldığından emin olun (veya belirli sorunları susturmak için önceliklendirme modunu kullanın). +- Sözleşmelerinizi [Crytic](https://crytic.io/) ile gözden geçirin. Slither'ın kontrol etmediği 50 sorunu kontrol eder. Crytic, GitHub'daki Çekme Taleplerinde güvenlik sorunlarını kolayca ortaya çıkararak ekibinizin de kendi içinde güncel kalmasına yardımcı olabilir. Sözleşmenizin özel özelliklerini göz önünde bulundurun: -- Sözleşmeleriniz yükseltilebilir mi? Açıkları bulunan yükseltilebilirlik kodunuzu [`slither-check-upgradeability`](https://github.com/crytic/slither/wiki/Upgradeability-Checks) veya [Crytic](https://blog.trailofbits.com/2020/06/12/upgradeable-contracts-made-safer-with-crytic/) ile gözden geçirin. Yükseltmenin sıkıntı çıkarabileceği 17 yolu belgeledik. +- Sözleşmeleriniz yükseltilebilir mi? Yükseltilebilirlik kodunuzu kusurlara karşı [`slither-check-upgradeability`](https://github.com/crytic/slither/wiki/Upgradeability-Checks) veya [Crytic](https://blog.trailofbits.com/2020/06/12/upgradeable-contracts-made-safer-with-crytic/) ile gözden geçirin. Yükseltmenin sıkıntı çıkarabileceği 17 yolu belgeledik. - Sözleşmeleriniz ERC'lere uygun olduğunu iddia ediyor mu? Onları [`slither-check-erc`](https://github.com/crytic/slither/wiki/ERC-Conformance) ile kontrol edin. Bu araç, altı ortak özellikten sapmaları anında tanımlar. -- 3. taraf token'ları ile entegre oluyor musunuz? Harici sözleşmelere bağlı kalmadan önce [token entegrasyon kontrol listemizi](/developers/tutorials/token-integration-checklist/) gözden geçirin. +- 3. taraf token'ları ile entegre oluyor musunuz? Harici sözleşmelere güvenmeden önce [jeton entegrasyon kontrol listemizi](/developers/tutorials/token-integration-checklist/) gözden geçirin. Kodunuzun kritik güvenlik özelliklerini görsel olarak inceleyin: @@ -36,10 +33,10 @@ Kodunuzun kritik güvenlik özelliklerini görsel olarak inceleyin: Kritik güvenlik özelliklerini belgeleyin ve bunları değerlendirmek için otomatik test oluşturucuları kullanın: -- [Kodunuz için güvenlik özelliklerini belgelemeyi](/developers/tutorials/guide-to-smart-contract-security-tools/) öğrenin. İlki kadar zordur, ancak iyi bir sonuç elde etmek için en önemli aktivitedir. Ayrıca bu öğreticideki gelişmiş tekniklerden herhangi birini kullanmak için bir ön koşuldur. -- [Echidna](https://github.com/crytic/echidna) ve [Manticore](https://manticore.readthedocs.io/en/latest/verifier.html) ile kullanım için Solidity'de güvenlik özelliklerini tanımlayın. Durum makinenize, erişim kontrollerine, aritmetik işlemlere, harici etkileşimlere ve standart uygunluğuna odaklanın. -- [Slither'ın Python API'sı](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/) ile güvenlik özelliklerini belgeleyin. Kalıtım, değişken bağımlılıklar, erişim kontrolleri ve diğer yapısal konulara odaklanın. -- [Crytic](https://crytic.io) ile her taahhüt için özellik testlerinizi çalıştırın. Crytic, güvenlik özelliği testlerini kullanabilir ve değerlendirebilir, böylece ekibinizdeki herkes GitHub'dan geçtiklerini kolayca görebilir. Başarısız olan testler taahhütleri bloke edebilir. +- Kodunuz için [güvenlik özelliklerini belgelemeyi](/developers/tutorials/guide-to-smart-contract-security-tools/) öğrenin. İlki kadar zordur, ancak iyi bir sonuç elde etmek için en önemli aktivitedir. Ayrıca bu öğreticideki gelişmiş tekniklerden herhangi birini kullanmak için bir ön koşuldur. +- [Echidna](https://github.com/crytic/echidna) ve [Manticore](https://manticore.readthedocs.io/en/latest/verifier.html) ile kullanmak üzere Solidity'de güvenlik özelliklerini tanımlayın. Durum makinenize, erişim kontrollerine, aritmetik işlemlere, harici etkileşimlere ve standart uygunluğuna odaklanın. +- [Slither'ın Python API'si](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/) ile güvenlik özelliklerini tanımlayın. Kalıtım, değişken bağımlılıklar, erişim kontrolleri ve diğer yapısal konulara odaklanın. +- [Crytic](https://crytic.io) ile her commit'te özellik testlerinizi çalıştırın. Crytic, güvenlik özelliği testlerini kullanabilir ve değerlendirebilir, böylece ekibinizdeki herkes GitHub'dan geçtiklerini kolayca görebilir. Başarısız olan testler taahhütleri bloke edebilir. Son olarak, otomatik araçların kolayca bulamayacağı sorunlara dikkat edin: @@ -50,6 +47,6 @@ Son olarak, otomatik araçların kolayca bulamayacağı sorunlara dikkat edin: ## Yardım isteyin {#ask-for-help} -[Ethereum office hours](https://calendly.com/dan-trailofbits/office-hours), (çalışma asatleri) her salı öğleden sonra gerçekleştirilir. Bu 1 saatlik 1'e 1 oturumlar, güvenlikle ilgili tüm sorularınızı bize sorma, araçlarımızı kullanarak sorun giderme ve mevcut yaklaşımınız hakkında uzmanlardan geri bildirim alma fırsatıdır. Bu rehberi tamamlamanıza yardımcı olacağız. +[Ethereum çalışma saatleri](https://calendly.com/dan-trailofbits/office-hours) her Salı öğleden sonra gerçekleştirilir. Bu 1 saatlik 1'e 1 oturumlar, güvenlikle ilgili tüm sorularınızı bize sorma, araçlarımızı kullanarak sorun giderme ve mevcut yaklaşımınız hakkında uzmanlardan geri bildirim alma fırsatıdır. Bu rehberi tamamlamanıza yardımcı olacağız. Slack'imize katılın: [Empire Hacking](https://join.slack.com/t/empirehacking/shared_invite/zt-h97bbrj8-1jwuiU33nnzg67JcvIciUw). Herhangi bir sorunuz olursa #crytic ve #ethereum kanallarında her zaman yanınızdayız. diff --git a/public/content/translations/tr/developers/tutorials/send-token-ethersjs/index.md b/public/content/translations/tr/developers/tutorials/send-token-ethersjs/index.md index e9e45126df1..4cfba8beb8d 100644 --- a/public/content/translations/tr/developers/tutorials/send-token-ethersjs/index.md +++ b/public/content/translations/tr/developers/tutorials/send-token-ethersjs/index.md @@ -1,29 +1,27 @@ --- -title: Ethers.js Kullanarak Token Gönderimi -description: Yeni başlayanlar için Ethers.js kullanarak token gönderme rehberi. +title: "ethers.js Kullanarak Jeton Gönderme" +description: "Yeni başlayanlar için ethers.js kullanarak jeton gönderme rehberi." author: Kim YongJun -tags: - - "ETHERS.JS" - - "ERC-20" - - "TOKEN'LAR" +tags: ["ETHERS.JS", "ERC-20", "TOKENS"] skill: beginner lang: tr published: 2021-04-06 --- -## ethers.js(5.0) Kullanarak Token Gönderin {#send-token} +## ethers.js(5.0) Kullanarak Jeton Gönderin {#send-token} -### Bu Eğitimde Şunların Nasıl Yapılacağını Öğreneceksiniz {#you-learn-about} +### Bu Eğitimde Şunları Öğreneceksiniz {#you-learn-about} -- Ethers.js içe aktarımı -- Token transferi +- ethers.js içe aktarımı +- Jeton transferi - Gaz fiyatını ağ trafiği durumuna göre ayarlama -### Başlamak İçin {#to-get-started} +### Başlarken {#to-get-started} -Başlamak için önce ethers.js kitaplığını javascript'imize aktarmalıyız ethers.js(5.0) dahil +Başlamak için önce ethers.js kütüphanesini javascript'imize aktarmalıyız +ethers.js(5.0) dahil -### Kurulum {#install-ethersjs} +### Yükleme {#install-ethersjs} ```shell /home/ricmoo> npm install --save ethers @@ -34,7 +32,7 @@ Tarayıcıda ES6 ```html ``` @@ -49,23 +47,23 @@ Tarayıcıda ES3(UMD) ### Parametreler {#param} -1. **`contract_address`**: Token sözleşme adresi (aktarmak istediğiniz token, ether olmadığında sözleşme adresi gereklidir) -2. **`send_token_amount`**: Alıcıya göndermek istediğiniz token miktarı +1. **`contract_address`**: Jeton sözleşme adresi (aktarmak istediğiniz jeton, ether olmadığında sözleşme adresi gereklidir) +2. **`send_token_amount`**: Alıcıya göndermek istediğiniz jeton miktarı 3. **`to_address`**: Alıcının adresi 4. **`send_account`**: Göndericinin adresi -5. **`private_key`**: İşlemi imzalamak ve token'ları tam olarak aktarmak için göndericinin özel anahtarı +5. **`private_key`**: İşlemi imzalamak ve jetonları fiilen aktarmak için göndericinin özel anahtarı -## Uyarı {#notice} +## Not {#notice} -`sendTransaction()` onu dahili olarak yaptığı için `signTransaction(tx)` kaldırılmıştır. +`sendTransaction()` bunu dahili olarak yaptığı için `signTransaction(tx)` kaldırılmıştır. -## Gönderim Prosedürleri {#procedure} +## Gönderme Prosedürleri {#procedure} -### 1. Ağa bağlan (test ağı) {#connect-to-network} +### 1. Ağa bağlanma (test ağı) {#connect-to-network} -#### Sağlayıcı Ayarla (Infura) {#set-provider} +#### Sağlayıcıyı Ayarla (Infura) {#set-provider} -Ropsten test ağına bağlan +Ropsten test ağına bağlanma ```javascript window.ethersProvider = new ethers.providers.InfuraProvider("ropsten") @@ -77,7 +75,7 @@ window.ethersProvider = new ethers.providers.InfuraProvider("ropsten") let wallet = new ethers.Wallet(private_key) ``` -### 3. Cüzdanı ağa bağla {#connect-wallet-to-net} +### 3. Cüzdanı Ağa Bağla {#connect-wallet-to-net} ```javascript let walletSigner = wallet.connect(window.ethersProvider) @@ -89,16 +87,16 @@ let walletSigner = wallet.connect(window.ethersProvider) window.ethersProvider.getGasPrice() // gasPrice ``` -### 5. İşlemi tanımla {#define-transaction} +### 5. İşlemi Tanımla {#define-transaction} -Aşağıda tanımlanan bu değişkenler, `send_token()` komutuna bağlıdır +Aşağıda tanımlanan bu değişkenler, send_token() komutuna bağlıdır ### İşlem parametreleri {#transaction-params} -1. **`send_account`**: token göndericisinin adresi -2. **`to_address`**: token alıcısının adresi -3. **`send_token_amount`**: gönderilecek token miktarı -4. **`gas_limit`**: gaz sınırı +1. **`send_account`**: jeton göndericisinin adresi +2. **`to_address`**: jeton alıcısının adresi +3. **`send_token_amount`**: gönderilecek jeton miktarı +4. **`gas_limit`**: gaz limiti 5. **`gas_price`**: gaz ücreti [Nasıl kullanılacağını görmek için aşağıya bakınız](#how-to-use) @@ -119,7 +117,7 @@ const tx = { ```javascript walletSigner.sendTransaction(tx).then((transaction) => { console.dir(transaction) - alert("Send finished!") + alert("Gönderim tamamlandı!") }) ``` @@ -148,7 +146,7 @@ send_token( ### Başarılı! {#success} -![başarılı bir şekilde yapılan işlemin görüntüsü](./successful-transaction.png) +![başarıyla tamamlanmış işlemin görüntüsü](./successful-transaction.png) ## send_token() {#send-token-method} @@ -168,23 +166,23 @@ function send_token( console.log(`gas_price: ${gas_price}`) if (contract_address) { - // general token send + // genel jeton gönderimi let contract = new ethers.Contract( contract_address, send_abi, walletSigner ) - // How many tokens? + // Kaç tane jeton? let numberOfTokens = ethers.utils.parseUnits(send_token_amount, 18) console.log(`numberOfTokens: ${numberOfTokens}`) - // Send tokens + // Jetonları gönder contract.transfer(to_address, numberOfTokens).then((transferResult) => { console.dir(transferResult) - alert("sent token") + alert("jeton gönderildi") }) - } // ether send + } // ether gönderimi else { const tx = { from: send_account, @@ -201,10 +199,10 @@ function send_token( try { walletSigner.sendTransaction(tx).then((transaction) => { console.dir(transaction) - alert("Send finished!") + alert("Gönderim tamamlandı!") }) } catch (error) { - alert("failed to send!!") + alert("gönderim başarısız oldu!!") } } })