# Bilgisayarınızda NFT Nasıl Oluşturulur?

Buildspace 'Mint your own NFT collection and ship a Web3 app to show them off' kursunu tamamlarken aldığım notlarla oluşturulmuş bir yazıdır. İsterseniz https://buildspace.so/ adresinden siteye giriş yaparak ücretsiz olarak kursları tamamlayabilirsiniz.

### Lokal Geliştirme Ortamının Kurulması

Öncelikle **Hardhat ** aracına ihtiyacımız olacak. Eğer bilgisayarınızda kurulu değilse gerekli olan programları kurmak için  [buraya tıklayabilirsiniz.](https://hardhat.org/tutorial/setting-up-the-environment.html) 

Yeni bir klasör oluşturup içinde aşağıdaki komutları çalıştıralım.

```
npm init -y
npm install --save-dev hardhat
npx hardhat

``` 
En son komutunu çalıştırdığımızda bir seçim yapmamız istenecektir. Buradan 'Create a basic sample project' seçeneğini seçebilirsiniz. Geri kalan seçenekleri değiştirmeden devam edebiliriz.

```
npm install --save-dev @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers ethers
npm install @openzeppelin/contracts
``` 
Komutlarını çalıştırıp gerekli kütüphaneleri kuralım. Bunlarla beraber geliştirme ortamımız tamamlanmış oluyor.

```
npx hardhat run scripts/sample-script.js
``` 
Komutu ile kurulumu test edebilirsiniz.

### Örnek Contractın Yazılması ve Test Edilmesi

Öncelikle *test/sample-test.js*, *scripts/sample-script.js*, 'contracts/Greeter.sol' dosyalarını projemizden silelim.  Ardından *contracts* klasörü altında istediğimiz isimde uzantısı *sol* ile biten bir dosya oluşturalım. Ben *AllPixelNFT.sol* oluşturdum. Dosyanın içerisini aşağıdaki kodlarla dolduralım.

```
// SPDX-License-Identifier: UNLICENSED

//Solidity versiyonu
pragma solidity ^0.8.0;

//Hardhat console kütüphanesi
import "hardhat/console.sol";

contract AllPixelNFT {
    constructor() {
        //Contact çalıştırıldığında konsole bu metni yazacak.
        console.log("Buralar hep dutluktu.");
    }
}
``` 

Contractı localde çalıştırmak için *scripts* klasörünün içine *run.js* isimli bir dosya oluşturalım.  Aşağıdaki kodları dosyanın içeriğine yazalım.


```
const main = async () => {
 //Contractı derleyen kod
  const nftContractFactory = await hre.ethers.getContractFactory('AllPixelNFT');
  const nftContract = await nftContractFactory.deploy();
  // Deploy tamamlandıktan sonra contract adresini ekrana yazıyoruz
  await nftContract.deployed();
  console.log("Contract Adresi", nftContract.address);
};

const runMain = async () => {
  try {
    await main();
    process.exit(0);
  } catch (error) {
    console.log(error);
    process.exit(1);
  }
};

runMain();
``` 

Konsol penceresine yazacağınız *npx hardhat run scripts/run.js* komutuyla contractınızı çalıştırabilirsiniz. Aşağıdaki gibi bir ekranla karşılaşmanız gerekiyor.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1637595638118/OAyDwYedaf.png)

### Testnette NFT oluşturulması

Öncelikle contract dosyamızın içeriğini aşağıdaki gibi güncelleyelim.


```
pragma solidity ^0.8.0;

// OpenZeppelin Contractlarını ekliyoruz
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "hardhat/console.sol";

// Eklediğimiz contractlardan miras alıyoruz
contract AllPixelNFT is ERC721URIStorage {
  // tokenIdlerini tutmak için miras aldığımız contracları kullanıyoruz
  using Counters for Counters.Counter;
  Counters.Counter private _tokenIds;

  // NFT adı ve sembolünü yazıyoruz
  constructor() ERC721 ("FirstPixelNFT", "FP") {
    console.log("NFT contactim.");
  }

  // Kullanıcıların NFT almak için kullanacakları fonksiyon
  function makeAnAllPixelNFT() public {
     // 0'dan başlayan tokenIdsini alalım
    uint256 newItemId = _tokenIds.current();

     // NFTyi kullanıcıya(msg.sender) gönderelim
    _safeMint(msg.sender, newItemId);

    // NFT'nin verisini ekleyelim
    _setTokenURI(newItemId, "JSON_URL");

    // tokenIdlerini arttıralım
    _tokenIds.increment();
  }
}
``` 

https://jsonkeeper.com/ sitesine aşağıdakine benzer bir JSON yapıştırıp oluşan urli *JSON_URL* alanına yazmanız gerekiyor. 


```
{
    "name": "Dutluk",
    "description": "Buralar hep dutluktu.",
    "image": "https://i.imgur.com/3lGIgPc.jpeg"
}
``` 

*run.js* dosyamızın içeriğinide aşağıdaki gibi güncelleyelim.


```
 const main = async () => {
  //Contractı derleyen kod
  const nftContractFactory = await hre.ethers.getContractFactory('AllPixelNFT');
  const nftContract = await nftContractFactory.deploy();
  // Deploy tamamlandıktan sonra contract adresini ekrana yazıyoruz
  await nftContract.deployed();
  console.log("Contract Adresi", nftContract.address);

  // NFT oluşturan fonksiyonu çağıralım
  let txn = await nftContract.makeAnAllPixelNFT()
  // Kazılmasını(Mining) bekleyelim
  await txn.wait()

  // İkinci NFT'yi oluşturalım
  txn = await nftContract.makeAnAllPixelNFT()
  // Kazılmasını(Mining) bekleyelim
  await txn.wait()

};

const runMain = async () => {
  try {
    await main();
    process.exit(0);
  } catch (error) {
    console.log(error);
    process.exit(1);
  }
};

runMain();
``` 
*npx hardhat run scripts/run.js * komutu ile test edelim. Herhangi bir hata vermeden şu şekilde bir ekran gözükmesi gerekiyor.


![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1637598736115/blvDipx7F.png)

### NFT'nin testnete deploy edilmesi

Testnete deploy edilmesi için  [Alchemy](https://alchemy.com/?r=4c9d95c442b2a5ed)  kullanıyoruz. Üyeliğimizi tamamladıktan sonra API keyi edinmemiz gerekiyor. Giriş yaptıktan sonra gelen sayfada bulunan 'Create App' butonuna tıklayalım.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1637598936059/hSq8nzNK2.png)

Aşağıdaki bilgilere benzer bir şekilde doldurduktan sonra 'Create APP' butonuna tıklayın.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1637599032957/63POMmdLS.png)

Açılan sayfada az önce yazdığımız isimdeki uygulamaya tıklayalım.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1637599094281/By09UKGJZ.png)

View Key butonuna tıklayıp HTTP alanında bulunan keyi not alalım.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1637599121550/YrswtyIKe.png)

Testnette ETH sahibi olabilmek için aşağıdaki siteleri kullanabilirsiniz.

* [MyCrypto](https://app.mycrypto.com/faucet) 
* [Buildspace](https://buildspace-faucet.vercel.app/) 
* [Ethily](https://ethily.io/rinkeby-faucet/) 
*  [Official Rinkeby](https://faucet.rinkeby.io/) 

*scripts* klasörünün altında *deploy.js* dosyasyı oluşturalım. İçeriğini aşağıdaki gibi dolduralım.

```
const main = async () => {
     //Contractı derleyen kod
    const nftContractFactory = await hre.ethers.getContractFactory('AllPixelNFT');
    const nftContract = await nftContractFactory.deploy();
     // Deploy tamamlandıktan sonra contract adresini ekrana yazıyoruz
    await nftContract.deployed();
    console.log("Contract Adresi", nftContract.address);
  
    // NFT oluşturan fonksiyonu çağıralım
    let txn = await nftContract.makeAnAllPixelNFT()
    // Kazılmasını(Mining) bekleyelim
    await txn.wait()
    console.log("Minted NFT #1")

    // İkinci NFT'yi oluşturalım
    txn = await nftContract.makeAnAllPixelNFT()
    // Kazılmasını(Mining) bekleyelim
    await txn.wait()
    console.log("Minted NFT #2")
  };
  
  const runMain = async () => {
    try {
      await main();
      process.exit(0);
    } catch (error) {
      console.log(error);
      process.exit(1);
    }
  };
  
  runMain();
``` 
Ana dizinde bulunan *hardhat.config.js* dosyasını şu şekilde düzenleyelim.

```
require('@nomiclabs/hardhat-waffle');

module.exports = {
  solidity: '0.8.0',
  networks: {
    rinkeby: {
      url: 'ALCHEMY_API_URL',
      accounts: ['PRIVATE_KEY'],
    },
  },
};
``` 
ALCHEMY_API_URL alanına HTTP alanında aldığımız metni yapıştıralım.
PRIVATE_KEY alanına metamasktan alacağımız testnet private keyimizi yapıştıralım.  [Buradan ](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key) nasıl alınacağını öğrenebilirsiniz. *hardhat.config.js* dosyasını asla Git'e commitlemeyin veya kimseye vermeyin.


```
npx hardhat run scripts/deploy.js --network rinkeby
``` 
komutuyla contractımızı deploy edelim. Aşağıdakine benzer bir görüntü oluşması gerekiyor.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1637599706453/C5CfEP2Ph.png)

Contract adresimizi not alalım. Benim adresim 0x471e7Eb5DEEBA4f8509717507De799dAC0480Ecb

Bu adresi https://rinkeby.etherscan.io/ sitesinde aratalım. Çıkan sayfada contractımızı görebiliriz. 

https://rinkeby.etherscan.io/address/0x471e7Eb5DEEBA4f8509717507De799dAC0480Ecb

### NFT'nin OpenSea'de gösterilmesi

https://testnets.opensea.io/ veya https://rinkeby.rarible.com/ adreslerinde contract adresimizi aratalım. Şu şekilde görebiliyor olmamız lazım.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1637600911524/9XZ4EMvxO.png)

Örnek url: 

https://rinkeby.rarible.com/token/0x471e7eb5deeba4f8509717507de799dac0480ecb:1?tab=bids




