Blockmunity (3)

이민기·2022년 3월 7일
0

Blockmunity

목록 보기
4/7
post-thumbnail

Blockmunity

5. ✓ NFT 생성

보상으로 받은 토큰을 통해 유저들은 자신만의 NFT를 생성 할 수있도록 했다
이 NFT는 다른 사람에게 판매도 가능하며 다른 사람의 NFT역시도 구매 가능하도록 할 것이다.


Code🖋

Contract.setProvider("HTTP://127.0.0.1:7545");
  const server = process.env.TOKEN_ADDRESS;
  const serverPK = process.env.TOKEN_PRIVATEKEY;
  var erc20contractABI = erc20Abi;
  var erc721contractABI = erc721Abi;
  var erc20contract = await new Contract(erc20contractABI, process.env.ERC20ADDR);
  var erc721contract = await new Contract(erc721contractABI, process.env.ERC721ADDR);
  const imgUri = req.body.imgUri;
  const createrAddress = req.body.address;
  const createrPK = req.body.privateKey;
  const ownerId = req.body.userId;
  const ownerName = req.body.username;
  const title = req.body.title;
  const desc = req.body.desc;
  const txData = erc20contract.methods.transfer(server, 200).encodeABI();
  const rawTransaction = {
    from: createrAddress,
    to: process.env.ERC20ADDR,
    gas: 100000,
    data: txData,
  };
  web3.eth.accounts.signTransaction(rawTransaction, createrPK).then(async (signTx) => {
    web3.eth.sendSignedTransaction(signTx.rawTransaction, async (err, req) => {
      if (!err) {
        db.collection("users").updateOne({ address: createrAddress }, { $inc: { erc20: -200 } }, (err, result) => {
          console.log("토큰 사용 완료");
          if (err) {
            console.log("토큰 감소 오류;;;");
          } else {
            const nftData = erc721contract.methods.mintNFT(createrAddress, imgUri).encodeABI();
            const rawTransaction = {
              from: server,
              to: process.env.ERC721ADDR,
              gas: 5000000,
              data: nftData,
            };
            web3.eth.accounts.signTransaction(rawTransaction, serverPK).then((signTx) => {
              web3.eth.sendSignedTransaction(signTx.rawTransaction, async (err, req) => {
                if (err) {
                  console.log("민팅 실패?;;;");
                } else {
                  db.collection("nftCounter").findOne({ name: "lastNftId" }, (err, result) => {
                    var nftId = result.nftId;
                    var token = {
                      _id: nftId,
                      ownerId: ownerId,
                      ownerName: ownerName,
                      ownerAddress: createrAddress,
                      title: title,
                      desc: desc,
                      img: imgUri,
                      buyable: "No",
                      price: 0,
                      prevOwnerName: "",
                      prevOwnerId: "",
                      createAt: timestamp(),
                    };
                    db.collection("nfts").insertOne(token, (err, result) => {
                      console.log(err);

                      db.collection("nftCounter").updateOne({ name: "lastNftId" }, { $inc: { nftId: 1 } }, (err, result) => {
                        if (err) {
                          console.log(err);
                        } else {
                          res.json({ message: "생성 완료!" });
                        }
                      });
                    });
                  });
                }
              });
            });
          }
        });
      } else {
        console.log(err);
        res.json({ message: "토큰 부족" });
      }
    });
  });
});
  • 먼저 ERC20을 이용해 생성하는 계정의 지갑주소에서 서버에게 토큰을 보내고 MongoDB에서도 최신화를 한다
  • 여기까지 문제 없이 실행된다면 ERC721mintNFT함수를 이용해 NFT를 발급하고, MongoDB에서도 최신화한다 MongoDB에서는 Counter를 이용해서 마지막 NFT의 ID값을 관리하여 최대한 블록에 접근을 덜 할 수 있도록했다.

실제 실행 화면


✍🏻 NFT 전송

자신이 만든 NFT , 자신의 소유라면 다른 사람에게도 보낼 수 있어야 한다.
혼자 꽁꽁 갖고있으면 아무 의미가 없을테니까.... 😢
그런 부분에서 판매와 구매 전 간단하게 전송에 관련된 부분을 짚고 넘어가보려고 한다
코드 자체는 이전에 OpenSea Clone에서 사용한 코드와 크게 다르지는 않다


Code🖋

  const server = process.env.TOKEN_ADDRESS;
  const ownerPK = req.body.ownerPK;
  const ownerAddress = req.body.ownerAddress;
  const reciptUserName = req.body.reciptUserName;
  const tokenId = req.body.tokenId;
  db.collection("users").findOne({ address: ownerAddress }, (err, result) => {
    if (err) {
      console.log("전송하는 유저찾기 실패");
    } else {
      console.log("result1:", result);
      var erc721contractABI = erc721Abi;
      var erc721contract = new Contract(erc721contractABI, process.env.ERC721ADDR);
      db.collection("users").findOne({ username: reciptUserName }, (err, result) => {
        if (err) {
          console.log("수신유저 찾기 실패");
        } else {
          const reciptAddress = result.address;
          const reciptId = result._id;
          console.log(reciptAddress);
          const nftData = erc721contract.methods.transferFrom(ownerAddress, reciptAddress, parseInt(tokenId)).encodeABI();
          const rawTransaction = {
            from: server,
            to: process.env.ERC721ADDR,
            gas: 5000000,
            data: nftData,
          };
          web3.eth.accounts.signTransaction(rawTransaction, ownerPK).then((signTx) => {
            web3.eth.sendSignedTransaction(signTx.rawTransaction, async (err, req) => {
              if (err) {
                console.log("transferFrom에러: ", err);
              } else {
                db.collection("nfts").updateOne(
                  { _id: parseInt(tokenId) },
                  { $set: { ownerId: reciptId, ownerName: reciptUserName, ownerAddress: reciptAddress } },
                  (err, result) => {
                    if (err) {
                      console.log("db수정 실패?");
                    } else {
                      console.log("전송 완료!");
                      res.json({ message: "전송 완료!" });
                    }
                  }
                );
              }
            });
          });
        }
      });
    }
  });
});
  • 먼저 req를 이용해 전송하는 유저의 정블 가져왔고, 전송받는 유저의 이름을 통해 DB에서 정보를 가져와 토큰 넘버와 함께 ERC721transferFrom을 이용해 상대방에게 보내준다

실제 실행 화면



마치며

간단한 NFT 생성과 전송기능이었다 아무래도 이 기능들은 이전 OpenSea를 클론하면서 해봤던 것들이라 조금 더 익숙해진 느낌이었다 😏😉
이제는 정말 중요할 수 있고, 이전 OpenSea 클론에서는 완성하지 못했던 판매와 구매를 구현하러 넘어가보쟈~ 😀😀

profile
블로그를 옮기는 중입니다. https://min71.dev

0개의 댓글