บันทึกการเรียนรู้ การทำ Generative Art NFT

NFT Nov 27, 2022

สวัสดีครับ บล็อกนี้เป็นบล็อกที่ผมจะเล่าสิ่งที่ได้ทำไป สิ่งที่ได้เรียนรู้ ปัญหา และวิธีแก้ต่างๆ ในการที่ทำ Project NFT ขึ้นมาตัวนึง และ Deploy ลงบน Mainnet (ไม่ใช้ Ethereum Mainnet นะ)

โดยที่ผมจะแบ่งออกเป็น 3 ส่วนคือ

  1. ตัว Generate Art แน่นอนใช้ HashLips น่าจะเป็น Library ที่คนรู้จักมากที่สุด
  2. ตัว Smart Contract ใช้ Openzeppelin เป็นหลัก
  3. ตัว API และ Metadata รวมถึง Images ที่เรา generated ไว้
โจทย์คือ จะทำยังไงก็ได้ ให้ NFT มัน randomโดยที่ไม่มีใครรู้เลย ว่าได้ Rarity อะไรบ้าง แม้แต่ Owner และ Dev เอง หรืออย่างน้อย ก็ขอแค่ให้คนรู้น้อยที่สุดเท่าที่จะทำได้

HashLips

ส่วนนี้ ต้องบอกว่าการ Generate Art จาก Layers ที่มี นั้นง่ายมากๆ ตัว HashLips ทำ Config มาให้เราเรียบร้อยแล้ว แทบไม่มีปัญหาอะไรเลย รวมถึงส่วนนี้ ทีม Designers เค้ามี Artwork มาให้เรียบร้อยแล้ว ผมแค่รัน Script HashLips ก็ได้ผลลัพธ์ JSON และ Images พร้อมใช้งาน

เมื่อได้รูป Images และ JSON ต่อมาก็คือนำรูป และ JSON อัพโหลดไป IPFS หรือใช้ Storage เราเอง (Centralize) ก็ได้ อันนี้ขึ้นอยู่กับว่า เราจะให้เป็นแบบไหนครับ

สิ่งที่มีก็แค่ Rarity ที่เราต้องการ มันไม่ปกติ ก็เลยต้องเขียนการ Random การออก Rarity ขึ้นมาใหม่ (ปรับแต่งเอาจากของเดิม)

แต่ข้อเสียคือ ถ้าเรารัน Script เพื่อ Generate รูป สมมติ 10,000 รูป แสดงว่า เราเห็น Rarity เห็นว่า Item ชิ้นไหนเป็น Rare เป็น Common นะซิ?

คำตอบคือ ใช่ครับ ผมสามารถเห็นรูป เห็น Metadata (JSON) ว่าแต่ละตัวเป็นอะไร ส่วนวิธีแก้คือ

  • เอา Script ไปวางบน Server แล้วก็ตั้งเวลาให้มัน auto gen (แต่แน่นอน คนเข้าถึง Server ได้ก็อาจจะดูได้)
  • Generate on the fly (แปลง Script จากปกติ gen ทีเดียวหมดเลย ก็เปลี่ยนเป็น gen ที่ละตัว แต่ต้องเก็บพวก DNA / logic ต่างๆ ไว้ด้วย)

Smart Contract

ตัว Smart Contract ใช้ OpenZeppelin เป็นหลัก และก็ดู Reference จาก NFT Collection อื่นๆ ประกอบ โดยตัวโปรเจ็ค ผมขึ้นโปรเจ็คด้วย Hardhat เวลาเรา Deploy ก็แค่รัน Script Hardhat ตามที่เรา config task ไว้

โดยข้อแตกต่างของ NFT นี้คือ เป็น Multi-Currency คือสามารถ Mint ได้หลากหลายสกุลเงิน ไม่ใช้ Native Token ปกติ เช่น Ethereum ก็จะใช้ ETH หรือ Polygon ก็จะใช้ MATIC ทำให้เราก็ต้องให้ User ทำการ Approve Contract ก่อน เพื่อจะ Mint

ปัญหาที่เจอคือ

  1. ลืมใส่ function withdraw  เพื่อถอนเงินออกจาก Contract 🤣
  2. ต่อมาใส่ withdraw แล้ว แต่ลืมไป ใน function นี้ มันโอนเฉพาะ Native Token นี่นา อยากให้โอนเงินทุกๆ Token ที่มีเลย (ERC-20)
  3. ต่อมา เกือบดีแล้ว withdraw ลืมให้ Contract Approve เหรียญ ERC-20 ที่เราจะโอนกลับไปที่ owner 🤣
  4. ขั้นตอนการ Verify Contract ก่อนหน้านี้ผมใช้ hardhat มันสามารถ Verify ผ่าน Plugin ได้เลย ที่เป็นพวก Etherscan, BSCScan, PolygonScan อะไรพวกนั้น แต่พอเป็น Blockscout ก็ต้องเอา Bytecode ของ Constructor มาใช้ / ทำ Flatten code อะไรพวกนี้ด้วย ซึ่งมันทำผ่าน Web UI ได้เลย แต่ก็ใช้เวลาเรียนรู้นานเหมือนกัน กว่าจะ Verified ผ่าน
  5. ตอน Flatten ด้วย Hardhat มันจะมีพวก SPDX-License-Identifier ซ้ำๆ จากหลายๆไฟล์ ต้องมาลบมือ และให้เหลือแค่อันเดียว (ตรงนี้ผมไม่แน่ใจเค้าทำกันยังไงนะ)
  6. อีกวิธีในการ Verify คือใช้ sourcify ง่ายกว่ามาก ใช้แค่ JSON (ถ้าใช้ hardhat จะอยู่ใน build-info) และ Contract ลางวางลงไป แล้วใส่ Address ที่เรา Deploy เลือก Network เป็นอันเรียบร้อย

Reveal Metadata

ปัญหาอย่างนึง ที่หลายๆ NFT เจอคือ โดน snip เนื่องจากว่ารู้ว่าข้างใน NFT มี Metadata อะไร หรือรูปอะไร ก็เพราะว่า ดูจาก tokenURI นั่นเอง

ทีนี้พอมาคิดถึงเรื่องนี้ ก็ย้อนกลับไปถึงการ Generate NFT คือการทำ toggle reveal จะไม่มีปัญหาเลย ถ้า Mint หมดเร็วมาก หรือ Sold Out แล้วก็แค่กด Reveal เพื่ออัพเดท baseURI ทุกคนก็จะเห็น metadata / images แต่ปัญหาคือ ถ้า Mint ไม่หมดละ? ยังมีตัวที่ไม่ได้ mint อีกเพียบ ถ้ากด reveal ทุกคนก็จะรู้ว่าตัว rare ออกไปหมดแล้วหรือยัง หรือเหลือตัวไหนบ้างอยู่ดี ก็เลยต้องคิด Solutions ออกมา เช่น

  1. เราจะ gen ทีเดียว 10,000 รูปแล้วอัพลง IPFS ทั้งหมด ทีนี้ คนรู้ CID ก็รู้รูปอื่นๆ ใน folder แม้จะยังไม่ได้ mint
  2. หรือเราจะ gen ทีเดียว 10,000 รูป แล้วอัพลง IPFS เฉพาะ รูปที่ mint (ใช้ Pattern <CID>/tokenID ไม่ได้แล้ว เพราะ CID ต่างกัน
  3. หรือ Host ไว้ที่ Server เราเอง แบบที่ Binance NFT ทำ? เราสามารถจัดการอะไรได้เกือบหมด ข้อเสียคือ Centralized มั้ย?
  4. เลือก setBaseUri โดยยังไม่ต้องอัพโหลดรูปจริงๆ ด้วย ipfs add --only-hash

สรุป

จะเห็นว่าการทำ NFT ออกมานั้น จริงๆ มันมีรายละเอียดหยิบย่อยเหมือนกันแฮะ นี่ขนาดแค่มุม Developer นะ เช่น การทำยังไงเพื่อป้องกันข้อมูลของเรา ให้มีคนรู้น้อยที่สุด เพื่อความโปร่งใส เงื่อนไขต่างๆ ก็มีวิธีทำต่างกันไป บางวิธี ก็มีข้อดี และข้อเสียต่างๆกันไป ขึ้นอยู่กับว่าเราจะเลือกใช้วิธีไหน ก็ต้องรับ trade-off วิธีที่เราเลือกให้ได้ ก็แค่นั้น ไม่มีวิธีไหนดีที่สุด

Happy Coding ❤️

Tags

Chai Phonbopit

Frontend Dev ธรรมดาคนนึง ประสบการณ์ 10 ปีนิดๆ ปัจจุบันกำลังสนใจเรื่องของ Crypto, Web3, Blockchain และ Smart Contract กำลังหัดเรียนรู้ยามว่าง 👻