เรียนรู้วิธีใช้ Solidity เพื่อสร้าง NFT บนเครือข่ายในห้านาที

NFT แบบออฟไลน์
สิ่งนี้ทำให้เกิดคำถาม ไม่ใช่ NFT ทั้งหมดบนเครือข่ายใช่หรือไม่ ใครก็ตามที่เคยทำงานกับ NFT บน Ethereum blockchain สามารถบอกคุณได้ว่าการจัดเก็บข้อมูลแบบ on-chain มีข้อจำกัด เนื่องจากมีราคาแพงมากและโครงการ NFT ส่วนใหญ่จัดเก็บไฟล์รูปภาพและข้อมูลเมตาแบบ off-chain บ่อยครั้งที่ข้อมูลเดียวที่เราเห็นว่าจัดเก็บ "ในเครือข่าย" คือแฮชของข้อมูลเมตาที่ไม่เปลี่ยนรูปแบบ (โทเค็นURI ของเรา) - วิธีที่ง่ายที่สุดในการอธิบายแฮชนี้คือลิงก์ไปยัง NFT จริงของเรา ความแตกต่างในที่นี้คือ แฮชจะขึ้นอยู่กับข้อมูลที่ สร้างมัน เปลี่ยนแหล่งที่มา และแฮชใช้ไม่ได้อีกต่อไป ดังนั้นมันจึงเปลี่ยนรูปไม่ได้ ทุกคนสามารถเรียกใช้โหนด IPFS ได้เช่นเดียวกับที่ทุกคนสามารถเรียกใช้ตัวขุดโหนดบล็อกเชนหรือฉันทามติ
ตอนนี้เราอาจคุ้นเคยกับโครงการ "บนเครือข่าย" อย่าง Loot แล้ว ทำอย่างไร เราสามารถจัดเก็บสื่อภาพที่เหมาะสมบนเครือข่ายได้จริงหรือ
คำตอบคือใช่ แต่ต้องใช้บางสิ่ง ได้แก่ การเข้ารหัส Base64 และประเภทภาพ SVG ทั้งสองอย่างนี้ช่วยให้เราสามารถทำงานกับข้อมูลข้อความ แทนที่จะเป็นข้อมูลภาพ "หนัก" ของหน่วยความจำทั่วไป เช่น PNG หรือ JPEG หมายความว่าเราต้องทำสองสิ่ง:
Base64 เข้ารหัสข้อมูลเมตา json ของเรา
เข้ารหัส "คำแนะนำ" ในการเรนเดอร์รูปภาพในรูปแบบ SVG
โชคดีที่เบราว์เซอร์เข้าใจทั้งสองรูปแบบ และตลาดบนเบราว์เซอร์เช่น OpenSea สามารถแสดง NFT ของเราในลักษณะเดียวกับลิงก์ไปยังแฮชของร้านค้า IPFS อย่างไรก็ตาม เบราว์เซอร์ไม่ใช่ "การดึงและแคช" รูปภาพ แต่แสดงรูปภาพแทนเรา
การเข้ารหัส Base64
วิธีหนึ่งในการบรรลุการจัดเก็บข้อมูลเมตาแบบ on-chain และหลีกเลี่ยงความต้องการเครื่องมือใดๆ เช่น IPFS คือการเข้ารหัส base64 และจัดเก็บโดยตรงในข้อมูลโทเค็น NFT ของเรา ในกรณีของเรา tokenURI จะส่งคืนข้อมูลเมตาจริงในรูปแบบที่เข้ารหัส ซึ่งไม่ใช่ "ลิงก์" อีกต่อไป แต่เป็นข้อมูลเมตาเอง
อย่างที่ฉันพูด เราจะใช้ประโยชน์จากไลบรารี Base64.sol ที่มีอยู่จาก GitHub คุณสามารถนำเข้าจาก GitHub หรือเพียงแค่โคลน/คัดลอกโค้ดแล้วนำเข้าไฟล์นี้จากไดเร็กทอรีเดียวกับที่คุณวาง
สิ่งที่ควรทราบเกี่ยวกับการเข้ารหัสเป็น Base64 คือการเข้ารหัสไม่ใช่รูปแบบหนึ่งของการบีบอัดข้อมูล ดังนั้นเราจึงไม่ลดขนาดของข้อมูล เราเพียงแค่จัดเก็บในรูปแบบที่เบราว์เซอร์สามารถถอดรหัสได้ ข้อมูลเมตาของเรามีขนาดไม่ใหญ่มาก ซึ่งเป็นกรณีของอิมเมจ NFT ของเรา ด้านล่างนี้คือตัวอย่าง:

ในโค้ดตัวอย่างของเรา เราใช้ฟังก์ชัน 'BuildMetaData' ซึ่งรับ tokenId (ID ของ NFT ของเรา) และส่งกลับสตริงข้อความ json ที่เข้ารหัส base64 ที่มี OpenSea โดยใช้ชื่อ คำอธิบาย คุณสมบัติเพื่อแสดงทุกสิ่งที่คุณต้องการสำหรับ NFT ของคุณ และที่สำคัญที่สุดคือภาพลักษณ์ของเรา นอกจากนี้ยังใช้ฟังก์ชัน BuildImage ซึ่งฉันจะอธิบายด้านล่าง
นี่คือตัวอย่างข้อมูลเมตาของเรา:
{
"name":"NFT1",
"description":"This is our on-chain NFT",
"image": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAwIiBoZWlnaHQ9IjUwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCBpZD0ic3ZnXzExIiBoZWlnaHQ9IjYwMCIgd2lkdGg9IjUwMyIgeT0iMCIgeD0iMCIgZmlsbD0iaHNsKDI5Myw1MCUsMjUlKSIvPjx0ZXh0IGZvbnQtc2l6ZT0iMTgiIHk9IjEwJSIgeD0iNSUiIGZpbGw9ImhzbCg5MCwxMDAlLDgwJSkiPlNvbWUgVGV4dDwvdGV4dD48dGV4dCBmb250LXNpemU9IjE4IiB5PSIxNSUiIHg9IjUlIiBmaWxsPSJoc2woOTAsMTAwJSw4MCUpIj5Tb21lIFRleHQ8L3RleHQ+PHRleHQgZm9udC1zaXplPSIxOCIgeT0iMjAlIiB4PSI1JSIgZmlsbD0iaHNsKDkwLDEwMCUsODAlKSI+U29tZSBUZXh0PC90ZXh0Pjx0ZXh0IGZvbnQtc2l6ZT0iMTgiIHk9IjEwJSIgeD0iODAlIiBmaWxsPSJoc2woOTAsMTAwJSw4MCUpIj5Ub2tlbjogMTwvdGV4dD48dGV4dCBmb250LXNpemU9IjE4IiB5PSI1MCUiIHg9IjUwJSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZmlsbD0iaHNsKDkwLDEwMCUsODAlKSI+dXNlclRleHQ8L3RleHQ+PC9zdmc+",
"attributes": [
{
"trait_type": "TextColor",
"value":"328"
}
]
}
โดยทั่วไป ค่า "รูปภาพ" ของเราจะมีลักษณะดังนี้:
{
"image": "ipfs://QmWwMDLz6hQKCqjYba5cSHdrNUvPvAdndtaWjdFpm52GYm/1.gif"
}
เกิดอะไรขึ้นกับค่ารูปภาพของเรา ค่ารูปภาพของเราคือ 1 - SVG และ 2 - SVG เข้ารหัส Base64 ด้วย ซึ่งหมายความว่าข้อความ SVG ของเราได้รับการเข้ารหัสเหมือนข้อมูล json (ข้อความ)
สังเกตได้ว่าเราได้เพิ่มเนื้อหาบางส่วนลงใน json ที่เข้ารหัสแล้ว ดังนี้:
"ข้อมูลแอปพลิเคชัน/json:; base64"
นี่เป็นเพียงการอธิบายว่าข้อมูลคืออะไรและวิธีที่เครื่องรับหรือเบราว์เซอร์ของผู้รับสามารถถอดรหัสตามนั้นได้อย่างไร
การเข้ารหัส ABI
เรายังดำเนินการเข้ารหัส ABI ตลอดทั้งรหัสโครงการ ในกรณีของเรา การเข้ารหัส ABI หรือ Application Binary Interface อนุญาตให้เราเชื่อมข้อความหลายบรรทัดเข้าด้วยกันเท่านั้น "นี่", "คือ", "ของฉัน", "รหัส" จะทำให้เกิดข้อผิดพลาดหากไม่ได้เข้ารหัสเป็นสตริงเดียว
ไฟล์เอสวีจี
SVG คืออะไร และเหตุใดจึงสำคัญสำหรับเรา
โดยพื้นฐานแล้ว SVG หรือกราฟิกแบบเวกเตอร์ที่ปรับขนาดได้ช่วยให้เราจัดเก็บรูปภาพในรูปแบบประเภท xml หรือเป็นข้อความ ข้อความที่สามารถจัดเก็บแบบออนไลน์ได้ แทนที่จะเก็บข้อมูลรูปภาพขนาดใหญ่ เราอธิบายรูปภาพที่เราต้องการเป็นข้อความและเข้ารหัสด้วยวิธีที่เบราว์เซอร์ของเราและ OpenSea สามารถแสดงผลให้เราได้ เราสามารถกำหนดลักษณะต่างๆ ของภาพได้ ทั้งขนาด สี หรือแม้แต่ข้อความที่จะแสดงผลให้เราได้
ลองคิดแบบนี้ ถ้าฉันต้องการส่งภาพธรรมดาๆ ให้คุณ ฉันสามารถส่งภาพ PNG ความละเอียดสูงทางอีเมลหรือข้อความ หรือคุณสามารถอธิบายง่ายๆ ด้วยคำไม่กี่คำ แล้วให้ใบเสร็จของคุณ ผู้ส่งแสดงหรือสร้างขึ้นมาให้คุณ . หากการถ่ายโอนข้อมูลมีราคาแพง เราสามารถสร้าง "การแลกเปลี่ยน" ที่ลดต้นทุนโดยการเพิ่มต้นทุนของผู้รับ (ตามความพยายาม)
คำอธิบายข้อความด้านล่างมีแนวโน้มที่จะถ่ายโอนข้อมูลมากน้อยกว่า HD PNG ตราบใดที่ผู้รับมีเครื่องมือในการนำเสนอสิ่งนี้ เราจะลดค่าใช้จ่ายลงอย่างมากในแง่ของการจัดเก็บหรือถ่ายโอนข้อมูล:
"พื้นหลังสีน้ำเงินขนาด 500x500 พร้อมข้อความสีขาวว่า 'Hello World'"
โค้ดตัวอย่างของเราอธิบายพารามิเตอร์ของ SVG ในฟังก์ชัน BuildImage
มีเครื่องมือและเทมเพลตออนไลน์ที่ยอดเยี่ยมมากมายสำหรับสร้าง SVG และฉันขอแนะนำให้คุณหาเครื่องมือบางอย่างที่จะช่วยคุณเปลี่ยนไอเดียของคุณให้เป็น SVG
ตรวจสอบให้แน่ใจว่าใช้เปอร์เซ็นต์สำหรับเค้าโครง เนื่องจากค่า "ฮาร์ดโค้ด" ในการพัฒนาแอปอาจทำให้เกิดปัญหาเมื่อเราเพิ่มหรือลดขนาดหน้าจอที่แสดงผล 1,000px เป็นจุดเริ่มต้นสำหรับข้อความนั้นใช้ได้จนกว่าเราจะลดขนาดหน้าจอของอุปกรณ์ให้ต่ำกว่า 1,000x1000 ซึ่งในกรณีนี้เราควรตั้งค่าเป็น 80%
SVG ของเรา ก่อนการเข้ารหัส ABI และ Base64:
'
""
เราจะแจ้งให้ทราบอีกครั้งว่าเราได้แนบรายละเอียดเกี่ยวกับข้อมูล:
“data:image/svg+xml;base64”
การป้อนข้อมูลของผู้ใช้
คุณสมบัติที่น่าสนใจอย่างหนึ่งของสัญญาอัจฉริยะของเราคือความสามารถสำหรับผู้ใช้ในการมีส่วนร่วมกับ NFT ขั้นสุดท้ายโดยการป้อนข้อมูลที่เป็นข้อความลงในฟังก์ชัน mint การป้อนข้อมูลของผู้ใช้นี้จะถูกบันทึกเป็น "สตริงในหน่วยความจำ" จากนั้นจึงเพิ่มลงในข้อมูล SVG ของเราแบบไดนามิกผ่านฟังก์ชัน BuildImage
ฉันจำกัดขนาดของการป้อนข้อความและเพิ่มข้อผิดพลาดสำหรับขีดจำกัดนี้ แต่ผู้ใช้ทราบดีถึงสิ่งที่พวกเขาอาจเพิ่ม สิ่งนี้ไม่เปลี่ยนรูปและมีอยู่บนบล็อกเชนตลอดไป
ฟังก์ชัน mint ของเราทำได้โดยการเพิ่มความคาดหวังของสตริงในฟังก์ชัน:
function mint(string memory _userText) public payable {
uint256 supply = totalSupply();
bytes memory strBytes = bytes(_userText);
require(strBytes.length <= stringLimit, "String input exceeds limit.");
require(exists(_userText) != true, "String already exists!");
Word memory newWord = Word(
string(
abi.encodePacked(
"NFT",
uint256(supply + 1).toString()
)
),
"This is our on-chain NFT",
randomNum(361, block.difficulty, supply).toString(),
randomNum(361, block.timestamp, supply).toString(),
_userText
);
if (msg.sender != owner()) {
require(msg.value >= 0.005 ether);
}
wordsToTokenId[supply + 1] = newWord; //Add word to mapping @tokenId
_safeMint(msg.sender, supply + 1);
NFT และการโต้ตอบสัญญาอัจฉริยะ
หากคุณใช้เครื่องมือเช่น Remix คุณสามารถแก้ไขโค้ดที่ให้มา อัปโหลดไปยัง Remix คอมไพล์และปรับใช้สำหรับการทดสอบ
เนื่องจากฟังก์ชัน mint ของเราต้องการให้ผู้ใช้ป้อนข้อมูลสตริง สามารถเพิ่มข้อความได้ จากนั้นใช้ฟังก์ชัน tokenURI ของเราเพื่อดูว่าอะไรถูกสร้างขึ้น นี่คือฟังก์ชัน tokenURI แบบเดียวกับที่ตลาดอย่าง OpenSea ใช้ในการดึงหรือแยกวิเคราะห์ข้อมูล NFT ของเราและ ภาพ

แล้วเราจะทำอย่างไร หากต้องการแสดงผลในเบราว์เซอร์ของคุณ เราต้องคัดลอกทุกอย่างที่อยู่หลัง "string" (เราไม่ต้องการสิ่งนี้) และวางลงในเบราว์เซอร์ของเรา ผลลัพธ์ของการวางสิ่งนี้ในเบราว์เซอร์ของเราจะมีลักษณะดังนี้:

นอกจากนี้ เราสามารถดูรูปภาพของเราได้โดยการคัดลอกค่า "รูปภาพ" ส่วนที่เราต้องการคัดลอกจะถูกเน้นที่นี่:

ผลลัพธ์มีลักษณะดังนี้:

ข้อมูลภาพจะถูกวางลงในเบราว์เซอร์ในพื้นที่ของเรา
NFT ของเรา
ลิงค์ต้นฉบับ



