Cara Membuat Ribuan NFT Cryptopunks dengan Nodejs Terbaru
Cara Membuat Ribuan NFT Cryptopunks Nodejs Terbaru - CryptoPunks adalah salah satu proyek NFT paling populer di luar
sana. Dan sekarang, mereka menjual jutaan dolar. Ya aku
tahu! Mengejutkan! Hanya ada 10.000 anak punk yang
unik. Masing-masing dari mereka memiliki seperangkat atribut yang
membuat mereka istimewa dan menonjol dari yang lain.
-
Asing
-
Kera
-
zombie
-
Perempuan
-
Pria
Ada sekitar 89 atribut yang tersedia untuk setiap tipe punk.
Setiap punk tidak boleh memiliki satu pun atau hingga 7 atribut
sekaligus.
Dari materi yang diberikan, kami berpotensi membuat lebih dari 800.000
nfts cryptopunk.
Mari kesampingkan semuanya dan tulis sedikit aplikasi baris perintah
Javascript untuk menghasilkan sekelompok bajingan ini. Selain itu,
kita akan mendapatkan kesempatan untuk menyelesaikan tantangan "produk
kartesius dari beberapa array" dalam Javascript.
Silakan unduh semua lapisan sifat dan gambar punk di sini .
Struktur folder:
Kami akan menggunakan paket node-canvas untuk menggambar gambar dalam proyek ini. Harap pastikan bahwa Anda mengikuti petunjuk penginstalan jika Anda mengalami masalah. Lebih banyak bantuan dapat ditemukan di sini .
npm install canvas
Tambahkan variabel impor dan konfigurasi
const fs = require("fs");
const { createCanvas, loadImage } = require("canvas");
const console = require("console");
const imageFormat = {
width: 24,
height: 24
};
// initialize canvas and context in 2d
const canvas = createCanvas(imageFormat.width, imageFormat.height);
const ctx = canvas.getContext("2d");
// some folder directories that we will use throughout the script
const dir = {
traitTypes : `./layers/trait_types`,
outputs: `./outputs`,
background: `./layers/background`,
}
// we will update this total punks in the following steps.
let totalOutputs = 0;
// set the order of layers that you want to print first
const priorities = ['punks','top','beard'];
- Buat fungsi untuk menghapus data keluaran untuk kita. Kemudian ia membuat ulang folder output bersama dengan metadata baru dan folder punk di dalamnya.
const recreateOutputsDir = () => {
if (fs.existsSync(dir.outputs)) {
fs.rmdirSync(dir.outputs, { recursive: true });
}
fs.mkdirSync(dir.outputs);
fs.mkdirSync(`${dir.outputs}/metadata`);
fs.mkdirSync(`${dir.outputs}/punks`);
};
Hitung semua hasil yang mungkin
Pada langkah ini, kita akan mengetahui cara menghasilkan kombinasi dari
beberapa larik lapisan sifat. Sekarang mari kita turun ke bisnis dan
bersenang-senang. Jangan salin dan tempel kodenya dulu.
Ada banyak cara untuk mengimplementasikan apa yang disebut fungsi
sederhana ini.
-
Pertama adalah menggunakan fungsi Reduce dan FlatMap yang diperkenalkan
di ECMAScript 2019. Ini adalah opsi terpendek dan paling mudah untuk
dipahami.
const cartesian = (...a) => a.reduce((a, b) => a.flatMap(d => b.map(e => [d, e].flat())));
- Opsi umum lainnya adalah menggunakan fungsi Rekursi
const cartesian = (arr) => {
if (arr.length == 1) {
return arr[0];
} else {
var result = [];
var allCasesOfRest = cartesian (arr.slice(1)); // recur with the rest of array
for (var i = 0; i < allCasesOfRest.length; i++) {
for (var j = 0; j < arr[0].length; j++) {
var childArray = [].concat(arr[0][j], allCasesOfRest[i])
result.push(childArray);
}
}
return result;
}
}
Sebagian besar opsi memerlukan jumlah rekursi yang tidak masuk akal, atau
loop yang sangat bersarang atau untuk menyimpan larik permutasi dalam
memori. Ini akan menjadi sangat berantakan ketika kita menjalankannya
terhadap ratusan lapisan sifat yang berbeda. Ini akan menghabiskan
semua memori perangkat Anda dan akhirnya membuat PC/laptop Anda
crash. Saya membuat PC saya digoreng beberapa kali. Jadi jangan
jadi aku.
-
Alih-alih menggunakan fungsi rekursi atau loop bersarang, kita dapat
membuat fungsi untuk menghitung total hasil yang mungkin yang merupakan
produk dari semua panjang array.
var permsCount = arraysToCombine[0].length; for(var i = 1; i < arraysToCombine.length; i++) { permsCount *= arraysToCombine[i].length; }
-
Selanjutnya, kita akan mengatur nilai pembagi untuk menyelesaikan
perbedaan ukuran array
for (var i = arraysToCombine.length - 1; i >= 0; i--) { divisors[i] = divisors[i + 1] ? divisors[i + 1] * arraysToCombine[i + 1].length : 1; }
Tambahkan fungsi lain untuk mengembalikan permutasi unik antara indeks
'0' dan 'numPerms - 1' dengan menghitung indeks yang diperlukan untuk
mengambil karakternya, berdasarkan 'n'
const getPermutation = (n, arraysToCombine) => { var result = [], curArray; for (var i = 0; i < arraysToCombine.length; i++) { curArray = arraysToCombine[i]; result.push(curArray[Math.floor(n / divisors[i]) % curArray.length]); } return result; }
Selanjutnya kita akan memanggil fungsi getPermutation (n) menggunakan for
loop
for(var i = 0; i < numPerms; i++) { combinations.push(getPermutation(i, arraysToCombine)); }
Script lengkap yang kita butuhkan.
const allPossibleCases = (arraysToCombine) => { const divisors = []; let permsCount = 1; for (let i = arraysToCombine.length - 1; i >= 0; i--) { divisors[i] = divisors[i + 1] ? divisors[i + 1] * arraysToCombine[i + 1].length : 1; permsCount *= (arraysToCombine[i].length || 1); } totalOutputs = permsCount; const getCombination = (n, arrays, divisors) => arrays.reduce((acc, arr, i) => { acc.push(arr[Math.floor(n / divisors[i]) % arr.length]); return acc; }, []); const combinations = []; for (let i = 0; i < permsCount; i++) { combinations.push(getCombination(i, arraysToCombine, divisors)); } return combinations; };
Menurut tes kinerja cepat ini, versi terakhir benar-benar mengungguli
yang lain. Tampak menjanjikan bagi saya!
const drawImage= async (traitTypes, background, index) => { // draw background const backgroundIm = await loadImage(`${dir.background}/${background}`); ctx.drawImage(backgroundIm,0,0,imageFormat.width,imageFormat.height); //'N/A': means that this punk doesn't have this trait type const drawableTraits = traitTypes.filter(x=> x.value !== 'N/A') // draw all the trait layers for this one punk for (let index = 0; index < drawableTraits.length; index++) { const val = drawableTraits[index]; const image = await loadImage(`${dir.traitTypes}/${val.trait_type}/${val.value}`); ctx.drawImage(image,0,0,imageFormat.width,imageFormat.height); } console.log(`Progress: ${index}/ ${totalOutputs}`) // save metadata fs.writeFileSync( `${dir.outputs}/metadata/${index}.json`, JSON.stringify({ name: `punk ${index}`, attributes: drawableTraits }), function(err){ if(err) throw err; }) // save image as png file fs.writeFileSync( `${dir.outputs}/punks/${index}.png`, canvas.toBuffer("image/png") ); }
const main = async () => { const traitTypesDir = dir.traitTypes; // register all the traits const types = fs.readdirSync(traitTypesDir); // set all prioritised layers which will be drawn first. for eg: punk type, hair and then hat. You can set these values in the priorities array in line 21 const traitTypes = priorities.concat(types.filter(x=> !priorities.includes(x))) .map(traitType => ( fs.readdirSync(`${traitTypesDir}/${traitType}/`) .map(value=> { return {trait_type: traitType, value: value} }).concat({trait_type: traitType, value: 'N/A'}) )); // register all the backgrounds const backgrounds = fs.readdirSync(dir.background); // trait type avail for each punk const combinations = allPossibleCases(traitTypes) for (var n = 0; n < combinations.length; n++) { const randomBackground = backgrounds[Math.floor(Math.random() * backgrounds.length)] await drawImage(combinations[n] , randomBackground, n); }
Panggil register direktori keluaran dan fungsi utama
(() => {
recreateOutputsDir(); main(); })();
Buka cmd/powershell dan jalankan
node index.js
Atau
npm build
Ta-da. Mari jalankan aplikasi dan buat semua nft untuk kita.
-
Kode sumber: victorquanlam/cryptopunk-nft-generator)
-
Stackoverflow: Produk Cartesian dari nilai array
Silakan tinggalkan suka jika Anda menyukai posting ini.
Post a Comment for "Cara Membuat Ribuan NFT Cryptopunks dengan Nodejs Terbaru"