În 1977, sonda Voyager 1 pornea într-o călătorie interstelară purtând cu ea o parte din amintirile, dorințele și aspirațiile noastre, toate criptate pe un disc de aur. Există mari șanse ca informația stocată pe acel disc să persiste în timp, mai mult decât orice alte date păstrate pe Pământ: o formă de aspirație a umanității de a atinge nemurirea. Acest disc poartă și o altă semnificație: ne aparține, este ceva terestru, ne poartă semnătura. Nemurirea și dreptul de proprietate, două forțe puternice ce ne modelează destinul ca societate din vremuri străvechi, au fost acum asimilate de tehnologie.
Acum paisprezece ani, Satoshi Nakamoto a publicat o lucrare celebră despre cum pot fi utilizați arborii Merkle pentru a crea un sistem electronic de plată de tip peer-to-peer și care a devenit primul sistem Blockchain. Cu mult înainte de acest moment, noi, programatorii (recunosc, eu eram departe de a fi programator la acea vreme), vorbeam despre imutabilitate ca fiind Sfântul Graal al designului: nu lăsa pe nimeni să-ți modifice datele, nici chiar pe tine dacă vrei ca datele să fie de încredere, folosește variabile finale, nu exagera cu settere, alege clonarea la limitele sistemului acolo unde nu ai control, ştiţi și voi povestea. Nu ne-am imaginat însă că am putea avea o bază de date imutabilă, distribuită, confidențială și securizată - toate în același timp - așa că e de înțeles că mulți dintre noi am abordat propunerea cu un entuziasm nestăvilit în timp ce o altă parte dintre noi s-a arătat rezervată și sceptică. Folosirea algoritmilor de hashing pentru a garanta imutabilitatea datelor, un algoritm de consens în loc de utilizatorul "admin", un model dinamic care să permită scalarea și un model economic care să susțină adopția, toate venite într-un moment imediat ulterior colapsului financiar din 2007, în care încrederea în sistemele centralizate era la pământ, iar cea în algoritmi era în continuă creștere, a fost fără niciun dubiu o idee genială. Pentru software architects, ea a reprezentat implementarea perfectă a unui design pattern de event sourcing, una din cele mai elegante modalități de a stoca starea unui sistem (tipar ce ne-a oferit GIT-ul), prin faptul că ne permite să recreăm starea aplicației noastre pe baza valorii inițiale (blocul 0) și a evenimentelor ce urmează, fie ele commituri sau tranzacții financiare.
Renunțarea la consistența datelor, compromisul făcut de orice sistem distribuit, a fost rezolvat elegant de algoritmii byzantine fault tolerance, demonstrându-se că o eventuală consistență statistică este fezabilă chiar și în domeniul financiar. Avantajele obținute au fost prea mari pentru a putea trece neobservate. Mai întâi, așa cum știe orice programator (idee cu care orice QA probabil că nu este de acord), poți avea încredere mai mare în cod decât în oameni sau instituții, în special după criza financiară din 2007. În al doilea rând, date fiind o rețea descentralizată destul de mare și un design corect, datele au o viabilitate mai mare decât în orice instituție sau companie ce își poate închide serverele în orice moment sau care poate să nu își mai plătească factura serviciilor de cloud.
Odată cu lansarea Ethereum blockchain în 2015 și introducerea de Smart Contracts, a fost adăugat un nou nivel de abstractizare peste Blockchain: posibilitatea de a rula cod customizat în cadrul unui Blockchain care răspunde cererilor efectuate de utilizatori sau altor evenimente. Astfel s-a deschis posibilitatea stocării oricărui bun ce poate fi reprezentat digital pe un Blockchain bazat pe smart contracts (contracte inteligente): dovada de proprietate asupra cântecelor, artei, meme-urilor, imobilelor și — cine s-ar fi gândit — a linkurilor cu primate plictisite. Cum la nivel de design, în majoritatea blockchainurilor nu există o diferență între o adresă de smart contract și o adresă de portofel digital din perspectiva rețelei, integrarea este una facilă. Când o tranzacție este efectuată către un smart contract, pe lângă un cost minim de "combustibil" plătit de către client care limitează în timp și putere de procesare solicitarea rețelei și a valorii tranzacției, orice alte operațiuni programabile pot avea loc. Acestea sunt de regulă generarea tokenilor digitali (criptomonede), staking, votare participativă, donații de caritate, minare de NFT-uri și orice altceva suportă limbajul de programare acceptat de Blockchain, touring-complet în majoritatea cazurilor.
Le putem considera niște micro-servicii imutabile încărcate pe blockchain ce execută tranzacții în numele utilizatorilor sau al altor contracte. Costul acestei flexibilități sporite este reprezentat de riscurile de securitate și vulnerabilitățile introduse. În privința smart contracturilor încrederea derivă din transparență și din imutabilitate astfel că, de obicei, codul sursă este public. Acest fapt crește riscul găsirii unor vulnerabilități sau defecte în implementarea contractului care nu mai pot fi pe urmă ușor reparate. Asta deoarece a face contractul eligibil pentru un upgrade necesită un grad ridicat de încredere din partea utilizatorilor și un consens al nodurilor rețelei, upgrade-ul putând fi defavorabil unora dintre ei, un caz renumit fiind atacul DAO din 2016.
Aceste riscuri au dus la nevoia de standardizare a smart contracts. Prima propunere de acest fel a fost cea a lui Fabian Vogelsteller în noiembrie 2015, ERC-20 (Ethereum Request for Comments 20), care definește API-ul pe care ar trebui să îl implementeze un smart contract. Puteți consulta specificațiile ERC. Veţi vedea că sunt surprinzător de simple.
Odata cu smart contracts, a fost introdus și conceptul de "tokens" prin care înțelegem orice fel de date digitale gestionate de smart contracts, care transformă criptomonedele, NFT-urile sau alte bunuri stocate pe blockchain în entități programabile. Costurile de tranzacționare sunt exprimate de regulă în criptomonedele care stau la baza blockchainului, folosite pentru plata costului de rulare, validarea sau minarea tranzacțiilor însă sunt separate în mod inteligent de smart contracts și tokenurile pe care acestea le gestionează. Făcând o analogie, Blockchain reprezintă nivelul fizic, smart contracts, nivelul de rețea, iar tokenurile sunt datele utilizatorilor.
Denumirea NFT (Non-Fungible Token) face o distincție clară între NFT-uri și monedele digitale (fungibile). Până în 2017, tokenurile gestionate de smart contracts erau în principal fungibile, ceea ce făcea ca utilizatorul final să nu le poată distinge de criptomonedele Blockchain. În 2017, primul standard pentru tokenuri unice (NFT-uri) a fost lansat de echipa Ethereum, ERC-721, care a definit API-ul contractului menit să gestioneze bunuri unice în blockchain. Acest lucru a permis programatorilor și creatorilor să lanseze și să vândă NFT-uri pe o piață ce a ajuns la o valoare estimată de ~25 miliarde USD în 2021.
Nimic nu i-a împiedicat pe utilizatori să devină proprietarii acestor bunuri în portofelul lor digital, nici măcar faptul că (preluat de pe Wikipedia):
"Registrele NFT pretind să ofere un certificat public de autenticitate sau o dovadă de proprietate, dar drepturile legale ce derivă dintr-un NFT pot fi vagi. NFT-urile nu restricționează partajarea sau copierea fișierelor digitale subiacente, nu transmit în mod obligatoriu dreptul de copyright asupra acelor fișiere digitale și nu opresc crearea de NFT-uri pe baza unor fișiere asociate identice."
Desigur, jucătorii din piața NFT sunt mai optimiști, așa cum ar trebui să fie:
"Acest lucru a declanșat o avalanșă de cazuri de utilizare fără precedent pentru activele digitale, în care proprietatea reală, transferurile de neoprit și proveniența imutabilă sunt esențiale. Deși există un număr mare de domenii și verticale de business în care astfel de proprietăți sunt importante, arta și divertismentul au luat un avans masiv."
Cu alte cuvinte, a avea dovada că deții un link către acel fișier într-un portofel digital este recunoscut de către comunitățile online drept o dovadă de proprietate asupra fișierului respectiv. Este prea devreme pentru a decide dacă vreo valoare legală va fi atribuită acestui tip de proprietate. Momentan, cumpărătorii au încredere în aceste bunuri, deoarece tranzacțiile și proprietatea sunt stocate (se presupune pentru totdeauna) în Blockchain. Dar unde se află fișierul în sine?
Într-adevăr, fișierul nu se află în Blockchain, deoarece ar trebui replicat pe mii de noduri și menținut acolo la nesfârșit, ceea ce va crește dimensiunea Blockchainului dincolo de limitele de fezabilitate. Pentru a oferi un exemplu, stocarea datelor din Blockchain, în special în cazul Ethereum, care încă operează cu algoritmi de consens proof of work, stocarea a 1MB costă cel puțin 4 ETH care, în funcție de momentul la care citiți acest articol, poate avea orice valoare între 0 și infinit raportat la USD. În mod cert, chiar dacă blockchainul este o bază de date (cea mai lentă bază de date din lume), ea nu este gândită pentru a stoca fișiere. Desigur că a descentraliza și a stoca datele în Google Cloud Storage sau în Amazon S3 buckets echivalează cu a-ți trage un glonț în picior. Ai dovada că ești proprietarul acelui fișier, dar el rămâne controlat în totalitate de o companie multinațională în care nu ai încredere, să zicem Facebook.
Aici intervine salvarea: IPFS, acronim pentru InterPlanetary File System, este un omagiu adus visului care a luat naștere în mintea lui J. C. R. Licklide în 1962 când conducea biroul IPTO (Information Processing Techniques Office) al ARPA (Advanced Research Projects Agency), şi anume acela de a implementa o 'rețea intergalactică' peer-to-peer care a dus la internetul așa cum îl știm azi. Însă adevărul este că internetul nu mai este ce a fost. La început era descentralizat. Fiecare calculator din rețea avea un server HTTP care servea conținut unor colegi prin invocări și interogări. Dacă doreai o informație, o cereai direct de la sursă. Nu exista niciun fel de panică că serverele FANG (Facebook, Amazon, Netflix, Google) vor cădea, deoarece nimeni nu era suficient de mare pentru a avea un astfel de impact.
În zilele noastre, nu mai "comunicăm" între noi. Schimbăm informație doar cu giganții care tranzacționează datele noastre pe bani. Probabil aveți impresia că îi trimiteți un mesaj direct pe WhatsApp prietenului vostru. De fapt, trimiteți un mesaj către serverele Facebook care fac o analiză a sentimentelor bazată pe cuvintele voastre. Apoi, organizează o licitație publică a atenției voastre pe piața publicitară, vânzând această atenție celui care licitează mai mult. Doar apoi trimit o notificare prietenului vostru că i-ați scris, iar procesul reîncepe. IPFS își propune să îmbunătățească internetul: să fie relevant și să acționeze la scară inter-planetară, să fie descentralizat, peer-to-peer și să vindece internetul de control.
IPFS este un protocol la nivel de aplicație (hypermedia) asemănător cu HTTP, însă în timp ce mediul WEB se bazează pe URL-uri pentru a identifica resursele (o locație într-un server), IPFS folosește amprentele datelor pentru stabilirea adreselor prin identificatori numiți CIDs (Content Identifiers/Identificatori de conținut). Un CID este un identificator multi-hash al datelor care, pe lângă hashul rădăcinii arborelui Merkel în care sunt stocate datele, mai conține algoritmul de hashing folosit (de obicei SHA2), encodingul și o versiune (momentan 0 sau 1).
Fiind bazat pe hashing, fiecare CID este unic pentru un anumit fișier, ceea ce este extrem de util dacă vrei să te asiguri că nimeni nu a modificat documentul tău. Modificarea unui bit de date va schimba complet adresa lui în rețea, de unde putem deduce avantajul enorm în fața URL-urilor, care azi te-ar putea redirecționa spre poza unei pisici, ca în ziua următoare același URL să te ducă la un meme cu Keanu Reeves, în funcție de starea de spirit a administratorului de servere. Principala diferență dintre adresarea prin URL și cea prin IPFS CID este aceea că URL-ul nu identifică resursa ci o doar locație de pe server. Resursa se poate modifica fără un avertisment în prealabil, în timp ce CID-ul identifică unic resursa.
Prin urmare, URL-urile de tip HTTP nu sunt potrivite ca adrese pentru documentele voastre de valoare, precum mai sus amintitele primate plictisite, dar URL-urile de tip IPFS sunt, folosind așa cum poate ați ghicit deja, aceeași structură de date de tip arbore Merkle. Când solicitați un document prin IPFS, aveți nevoie de CID. Nodul pe care îl invocați caută datele în repo-ul local. Dacă le găsește, veți avea acces instant la fișier. Dacă nu le găsește, își va întreba nodurile vecine dacă au fișierul, operație reluată până la găsirea fișierului. După ce fișierul este găsit, datele sunt stocate în cache, apoi vă sunt deservite. Fișierul este acum stocat pe cel puțin două noduri, fiind accesibil atâta timp cât cel puțin un nod păstrează datele. Dacă nodul ce stochează fișierul se închide sau documentul este șters de către garbage collector, datele se pierd ireversibil. Sau aproape ireversibil deoarece, dacă aveți o copie a fișierului și nimeni nu i-a alterat conținutul, va avea același hash și același CID (având în vedere că folosiți același algoritm hashing, encoding și versiune). IPFS a creat o nouă piață pentru stocarea datelor în mod distribuit. Numeroși provideri oferă garanții că datele voastre vor fi în continuare disponibile pe anumite noduri pentru o anumită perioadă de timp dacă aveți niște criptomonede de cheltuit sau chiar și gratis cu anumite limitări. Câteva exemple de astfel de servicii: filecoin, pinata, eternum, infura și multe altele care vă vor stoca datele în nodurile lor IPFS pentru ca voi să fiți siguri că NFT-ul va rămâne acolo cel puțin până vă decideți să îl vindeți. Aveți și opțiunea de a menține nodul IPFS sau clusterul pe serverul propriu (sau pe cloud companiei, dacă sunteți suficient de norocoși).
Cele mai multe browsere web ignoră protocolul IPFS, cu excepția Opera care oferă suport nativ, ceea ce vă permite să introduceți în bara de adresă ipfs://<CID>
, iar documentul să fie returnat similar cu o pagină servită prin HTTP. Pentru alte browsere, există gateway-uri care traduc IPFS CID într-un URL HTTP standard. Din păcate, timpul de răspuns este deocamdată incomparabil mai mare decât "tradiționalul" world wide web bazat pe HTTP.
De fiecare dată când dezvoltăm o tehnologie nouă merită să ne punem câteva întrebări: Este utilă pentru umanitate? Este utilă măcar pentru noi? Rezolvă mai multe probleme decât creează? Din întreaga piață de 25 de miliarde de dolari, ce valoare aduce pentru artiști, creatori, afaceri și instituții? Cât este doar o bulă speculativă a desenelor jpeg în care smart contracturile joacă rolul unor "slot machines" de dopamină pentru "minat" CID-uri de jpeg-uri stocate pe IPFS, ținute într-un portofel digital pe blockchain cu singurul scop de a le vinde mai târziu la un preț mai mare când nu mai există NFT-uri de minat sau cumpărate doar cu scopul de a dovedi că deținătorul își permite, crescându-și statutul social pe un iaht virtual la o petrecere din Metavers? Nu pot să dau un răspuns acestor întrebări, dar cred că unele lucruri merită stocate în blockchain acum că "zeii" din Silicon Valley ne-au binecuvântat cu o soluție (NFT-urile) pentru care tocmai căutăm problema.
Un lucru important pentru mine îl reprezintă imaginea mea digitală cu care mă întrepătrund suficient, încât să mă întreb cât de mult din mine e în online și cât mai e păstrat doar în propria conștiință și în gândurile celor dragi. Toate gândurile, ideile, fotografiile care îmi amintesc cine eram acum câțiva ani (lucru care mă umple, de obicei, de rușine) și cât de mult m-am schimbat pe parcursul timpului, informație care a devenit proprietatea giganților social media, în principal Facebook. Sunt în continuare responsabil pentru acele date, dar acele date nu îmi aparțin. Haideți să explorăm în continuare cum am putea redeveni proprietarii de drept ai eului nostru digital. Un bun punct de pornire, consider eu, pentru un proiect NFT, este să îți ții "sinele" format din ideile, fotografiile și comentariile puerile cât mai aproape, de ce nu în portofelul tău (digital), stocate pentru totdeauna în IPFS și blockchain. În plan simbolic este o modalitate de a atinge nemurirea sau măcar de a lăsa o urmă, atâta timp cât umanitatea va folosi dispozitive de procesare a informației și atâta timp cât este profitabil să le menținem "on".
Dacă vreți să fiți proprietarul eului vostru digital, primul pas este să obțineți datele. Din fericire, Facebook a adăugat funcționalitatea de a vă putea descărca toate datele. Sper că ați făcut rost de un hard disk suficient de mare pentru acest lucru. Sunt suficient de drăguți să vă ofere datele la calitate înaltă. Găsiți opțiunea navigând la Settings and Privacy > Settings > Your Facebook Information de unde puteți solicita să vă descărcați toate datele pe care vreți să le folosiți în blockchain, în format JSON sau HTML. Am extras datele în ambele formate din curiozitate. Imediat după, acțiunile Facebook au scăzut cu 25% și mai mult, corelația nu este același lucru cu cauzalitatea. Următorul pas este transformarea datelor în NFT-uri™. Am mult text pe wallul de Facebook dar și imagini cu text. Nu vreau să pierd nimic și îmi doresc să păstrez intacte asocierile, deci a trebuit să generez imagini din toate aceste date.
Un programator probabil că se gândeşte acum: hmm, am nevoie de un parser HTML, apoi de o soluție de randare cu dimensiuni customizate pentru imagini pe baza lungimii textului. Având și linkuri cu poze, trebuie să iau URL-urile și să le înlocuiesc cu versiuni codificate base64, și ulterior să capturez conținutul afișat. Când ai intrat suficient de adânc în soluție, experiența intervine și te oprește. Eficiența este cheia succesului, iar ceea ce tu încerci să faci nu pare a fi o problemă care să fi rămas nerezolvată până în 2022. În acel moment îți vine în minte ecranul colegilor QA: nu cel cu reddit, bloguri, chat și social media ci celălalt pe care toolul de automatizare diseacă o aplicație în trei browsere diferite, oferind din când în când capturi de ecran cu flowul, activitate care îți permite să te bucuri de o cafea generoasă până când driverul web întoarce aplicația pe toate părțile. Ați înțeles ideea: permiteți-i lui Selenium să facă munca grea de generare a NFT-urilor în locul vostru. Le cer scuze colegilor din testare dacă acest framework este învechit. Se potrivește obiectivelor noastre și l-am folosit de multe ori în cariera mea, deși niciodată pentru testare.
Am scris așadar, în grabă, 40 de linii de cod java nerefactorizat în 20 de minute, cod care a deschis versiunea descărcată HTML a datelor în Chrome, apoi a folosit Selenium pentru a trece prin toate cele 2343 de postări pe care le-am făcut pe Facebook, luând capturi de ecran, ajustând imaginile și salvându-le într-un folder. Puteți refolosi codul din contul meu de github. În loc să îl fac configurabil și reutilizabil, așa cum ar fi trebuit, am parcurs unsprezece ani de viață digitală sorbind dintr-o cafea și simțindu-mă rușinat. La final am observat că mai mult de 100 de postări la care nu eram dispus să renunț nu încăpeau pe ecran, așa că în loc să combin imaginile cu pachetul grafic din JDK sau cu o bibliotecă specializată, am decis că este mult mai ușor să setez monitorul în mod portret și să rulez scriptul din nou. După încă 30 de minute, aveam deja toate imaginile pe care doream să le convertesc în NFT-uri.
Am ajuns la pasul 2: mutarea datelor pe IPFS. Ca să profit de ocazie, am instalat un nod IPFS pe PC. Există mai multe variante: o opțiune Desktop, un tool slimmed-down în linia de comandă, sau preferata mea - un container docker pentru a-mi menține mediul de lucru mai curat decât codul.
Am efectuat un simplu docker pull al ultimei imagini oficiale urmată de un docker run. Pentru a păstra datele din nod după ce se oprește containerul am montat, de asemenea, două volume pentru staging și date:
>docker pull ipfs/go-ipfs:latest
>docker run -d --name ipfs_host
-v "d:/ipfs/staging":/export
-v "d:/ipfs/data":/data/ipfs
-p 4001:4001 -p 4001:4001/udp -p 127.0.0.1:8080:8080 -p 127.0.0.1:5001:5001 ipfs/go-ipfs:latest
După aceea, verificați log-urile să vedeți dacă nodul pornește corespunzător și dacă se conectează la alte noduri IPFS, la "swarm":
>docker logs -f ipfs_host
>docker exec ipfs_host ipfs swarm peers
Ar trebui să vedeți cum nodul vostru se conectează la peers, ceea ce înseamnă că faceți parte dintr-o rețea distribuită peer-to-peer ce rulează protocolul IPFS. Felicitări!
IPFS care se conectează la colegii săi
După ce se finalizează, puteți adăuga date în nodul IPFS. Am stocat rezultatele comenzii add în fișierul add_output.txt pentru a avea acces la CID-urile imaginilor.
>docker exec -it ipfs_host sh
>ipfs add -r /export/*.png > /export/add_output.txt
Haideți să testăm! Să luăm un CID din listă și să îl verificăm în browserul Opera.
Datele adăugate în IPFS
Imagine încărcată în Opera prin protocolul IPFS
Observați că CID s-a modificat automat. Comanda add generează din oficiu v0 CIDs în timp ce browserul Opera și majoritatea gatewayurilor le convertesc automat în v1 CID. Este o amintire memorabilă, dar nu este încă a mea. Este unică prin CID. Este online, este imutabilă, nu se mai poate șterge (niciodată, așa că aveți grijă ce încărcați), nu este comprimată eficient (aspect mai puțin important în cazul nostru), dar nu îmi aparține. La ce este bună o amintire eternă care nu este deținută de nimeni? Dacă aș putea dovedi lumii (în caz că nu e evident) că această amintire îmi aparține mie, având dovada în portofelul meu, aș avea un argument în favoarea tehnologiei. Ne vom ocupa în continuare de exact de acest lucru.
În afară de a ne menține propriul nod sau cluster IPFS, putem crea un cont pe Pinata, care ne va permite să încărcăm fișiere de până la 1 GB, gratuit, în IPFS. Mai puteți rula clusterul în cloud sau puteți folosi un serviciu plătit de încredere precum Filecoin, dacă vă pasă de datele voastre. Puteți să vă legați nodurile de orice furnizor pentru a duplica datele sau puteți solicita datele din nodurile voastre și să le marcați("tag"). Acest aspect va îmbunătăți disponibilitatea și durata de viață a fișierelor voastre. Deoarece doresc ca fișierele să fie disponibile chiar și când nu îmi folosesc PC-ul, am folosit Pinata pentru a-mi încărca pozele pe IPFS. Observați că mi-am stocat fișierele de două ori. Alții le pot descărca la fel de bine și încărca din nou cu CID-uri diferite (stocându-le cu dimensiuni diferite în bloc, modificând un pixel, rezoluția etc.), ceea ce se întâmplă des în lumea NFT-urilor: cineva fură o colecție NFT și o lansează pe o platformă diferită, monetizând talentul altcuiva. Există puține metode a preveni acest lucru prin natura IPFS-ului. Unele platforme (centralizate) pentru tranzacționat NFT-uri ascund CID-urile sau fac disponibile NFT-urile la o rezoluție mai mică pentru toți utilizatorii care nu dețin NFT-ul în portofelul digital. Acest lucru contravine însă ideii fundamentale de descentralizare și mută controlul datelor în mâinile unei corporații cum este OpenSea. Datele sunt ușor de descărcat, modificat sau duplicat, dar dreptul de proprietate garantat de Blockchain determină oamenii să cumpere NFT-uri care pot apărea identice cu excepția timpului la care s-a executat tranzacția în Blockchain.
Ne aflăm la pasul 3: stocarea adreselor IPFS ale amintirilor noastre în blockchain pentru a avea dovada de proprietate în portofelul nostru digital. Pentru aceasta, avem nevoie de un Blockchain care oferă suport pentru NFT-uri. Cum Ethereum a definit primul protocol NFT în 2017, acesta ar fi prima alegere, deoarece la ora actuală este cel mai descentralizat și sigur Blockchain ce permite rularea smart contracts. Totuși, tranzacțiile pe ETH nu sunt deloc ieftine din cauza algoritmului de consens folosit (proof of work). Dacă considerați că sunt zgârcit, verificați tranzacția ETH de mai jos, de acum câteva zile în care s-a "mintat" un NFT cu un cost de 3.42 ETH și care la momentul la care scriu articolul se apropie de 14.000 USD. Veți înțelege ideea.
Tranzacție de creare de NFT de 10 000 USD
Pentru demonstrația noastră vom folosi una dintre soluțiile cu un cost mai accesibil, care ne permite să salvăm și să vizualizăm NFT-uri direct în portofelul digital. Am ales de această dată soluția vecinilor noștri din Sibiu, Elrond Blockchain, pentru că oferă suport nativ pentru NFT-uri, fiind gestionate ca oricare alt token și au o documentație decentă care detaliază cum să interacționăm cu Blockchain-ul. Ca algoritm de consens folosesc proof of stake, iar o tranzacție costă, în mod tipic, mai puțin de 0.1$ în funcție de prețul criptomonedei Egold subiacente. Dacă am vrea să ne stocăm NFT-urile pe Ethereum, avem posibilitatea să alegem o tehnologie de nivelul doi construită peste Ethereum cum ar fi "Immutable". Un alt Blockchain cu costuri de tranzacționare foarte mici este Solana, care vine, însă cu o serie de compromisuri (precum o descentralizare mai scăzută sau un uptime îndoielnic). Întrucât crearea unei colecții NFT pe Elrond blockchain costă un minim de 0.05 Egold + costuri de transfer și tranzacționare, proiectul ar trebui să se încadreze într-un buget de 30-40$. Asta, pentru că vrem să folosim Blockchainul principal, pentru a le putea arăta prietenilor NFT-urile noastre în aplicația mobilă sau transfera prin aplicația Maiar ori prin portofelul digital web. Dar dacă vreți doar să experimentați, recomand Blockchainurile dev sau test pe care echipa Elrond le pun la dispoziție gratuit.
Dacă doriți să aprofundați diverse aspecte specifice legate de ceea ce vom face în continuare, vă sugerez să le parcurgeți mai întâi documentația. Să începem!
Vom interacționa cu Blockchainul lor folosind SDK-ul lor Python. Oferă mai multe versiuni de SDK pentru limbaje multiple pe contul lor de github. Cum eu sunt un programator Java, m-am gândit că ar fi inspirat să folosesc scripturi bash pentru operațiunile noastre. Puteți consulta documentația pentru Python SDK. Pentru a rula scripturile noastre bash, vom folosi o imagine docker Ubuntu. Puteți găsi majoritatea scripturilor pe care urmează să le folosim pe contul meu de github.
Să instalăm toate toolurile de care avem nevoie într-un container docker pornind de la următorul Dockerfile:
FROM ubuntu:latest
RUN export DEBIAN_FRONTEND=noninteractive
RUN apt update
RUN apt -qy install xxd
RUN apt -qy install python3.9
RUN apt -qy install python3.9-venv
RUN apt -qy install bc
RUN apt -qy install vim
COPY /erdpy-up/erdpy-up.py erdpy-up/erdpy-up.py
RUN useradd --create-home -u 1111 main
USER main
RUN python3.9 erdpy-up/erdpy-up.py
COPY walletKey.pem /home/main/elrondsdk/walletKey.pem
COPY issue_collection.sh /home/main/elrondsdk/is
sue_collection.sh
COPY set_nft_special_role.sh /home/main/elrondsdk/
set_nft_special_role.sh
COPY generate_nft.sh /home/main/elrondsdk
/generate_nft.sh
WORKDIR /home/main/elrondsdk/
Începem cu o imagine Ubuntu și folosim apt pentru a instala toolurile de care avem nevoie, cel mai important fiind Python. Va trebui să folosim parametri codificați în hexazecimal pentru a lucra cu erdpy. Așadar, vom instala xxd, bc în cazul în care avem nevoie de ceva matematică și, desigur, vim, pentru a fixa defectele direct în producție. Restul instrucțiunilor instalează erdpy SDK copiază scripturile bash de care avem nevoie pentru a genera colecția noastră de NFT-uri, apoi pentru a le trimite portofelul nostru digital. Anterior, mi-am generat cheia privată a portofelului digital, fișierul walletKey.pem din fraza parolă pe care am primit-o când am generat portofelul folosind toolul erdpy într-o imagine docker de setup. Vom avea nevoie de cheia privată pentru a semna tranzacția. Păstrați această cheie în siguranță, departe de repositoryurile online.
Următorul pas este generarea unei colecții de NFT-uri. Pentru a lansa o colecție NFT în Elrond, o să urmăm următorii trei pași:
Invocăm un smart contract care creează colecția și îi atribuie un token id.
Asignăm drepturile necesare pentru a gestiona colecția NFT unor adrese de conturi. Pot fi adrese ale unor smart contracts sau adrese de portofel digital.
Pentru pasul 1, am pregătit scriptul bash issue_collection.sh:
#!/usr/bin/bashWALLET_KEY=walletKey.pem
COLLECTION_ID_HEX=
"0x$(echo -n SerbyDId | xxd -p -u | tr -d '\n')"
TICKER_NAME_HEX=
"0x$(echo -n SERBDID | xxd -p -u | tr -d '\n')"
CAN_FREEZE=
"0x$(echo -n canFreeze | xxd -p -u | tr -d '\n')"
CAN_WIPE=
"0x$(echo -n canWipe | xxd -p -u | tr -d '\n')"
CAN_PAUSE=
"0x$(echo -n canPause | xxd -p -u | tr -d '\n')"
CAN_TRANSFER_CREATE_ROLE=
"0x$(echo -n canTransferNFTCreateRole | xxd -p -u |
tr -d '\n')"
CAN_CHANGE_OWNER=
"0x$(echo -n canChangeOwner | xxd -p -u | tr -d
'\n')"
CAN_UPGRADE=
"0x$(echo -n canUpgrade | xxd -p -u | tr -d '\n')"
CAN_ADD_SPECIAL_ROLES=
"0x$(echo -n canAddSpecialRoles | xxd -p -u | tr -d
'\n')"
TRUE="0x$(echo -n true | xxd -p -u | tr -d '\n')"
FALSE=
"0x$(echo -n false | xxd -p -u | tr -d '\n')"
CONTRACT=erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u
GAS_LIMIT=100000000
ELROND_PROXY=https://gateway.elrond.com
ELROND_CHAIN=1./erdpy --verbose contract call
$CONTRACT --recall-nonce \
--pem=${WALLET_KEY} \
--gas-limit=${GAS_LIMIT} \
--value=50000000000000000 \
--proxy=${ELROND_PROXY} \
--chain=${ELROND_CHAIN} \
--function="issueNonFungible" \
--arguments $COLLECTION_ID_HEX $TICKER_NAME_HEX \
$CAN_FREEZE $FALSE \
$CAN_WIPE $TRUE \
$CAN_PAUSE $FALSE \
$CAN_TRANSFER_CREATE_ROLE $TRUE \
$CAN_CHANGE_OWNER $TRUE \
$CAN_UPGRADE $TRUE \
$CAN_ADD_SPECIAL_ROLES $TRUE \
--send
Contractul pe care îl invocăm este un contract particular, special lansat pentru acest scop în Elrond blockchain și este suficient să îl apelăm. Trebuie să atribuim o valoare de 0.05 Egold tranzacției, deoarece acesta este prețul pentru crearea unei colecții NFT. Putem specifica mai multe atribute: dacă colecția se poate actualiza, dacă putem adăuga roluri, dacă putem schimba proprietarul colecției și nu numai. Asta a fost tot! Avem acum o colecție NFT.
Putem verifica rezultatul tranzacției cu ajutorul Elrond blockchain explorerului. Aici veți găsi un link direct către tranzacția tocmai efectuată.
Aceasta este frumusețea tehnologiei blockchain. Totul este transparent dar confidențial. Aș fi putut crea un nou portofel fără a oferi vreo informație personală acestui Blockchain, folosindu-l pentru a genera NFT-uri anonim. Totuși, acele criptomonede 0.05 Egold trebuie să vină de undeva și pot fi urmărite până la ultima zecimală, din portofel în portofel, de la swap contracts până la lichidități. Adresele hașurate cu albastru din tranzacția de mai sus sunt inutile pentru oricine vrea să verifice colecțiile de NFT-uri emise recent (mai ales că data și ora apar în tranzacție). Rezultatul apelului ne va oferi Id-ul colecției de tokenuri pe care îl vom folosi pentru a emite NFT-uri:
NFT-urile sunt lansate sau oferite sub formă de colecție, deoarece execuția unui smart contract care creează și gestionează o colecție este o operație costisitoare. De obicei, mii de NFT-uri sunt generate într-o singură colecție, fiind gestionate de un smart contract care suportă cereri de generare a NFT-urilor ("minting") pentru o sumă de criptomonede preconfigurată în contract. Proprietarul contractului redirecționează apoi suma colectată de smart contract către portofelul lui. Mintingul este doar un cuvânt sofisticat pentru acționarea mânerului de la slot machine care îți returnează aleatoriu unul dintre NFT-uri rămase neasignate în contract, printr-o tranzacție al cărei destinatar este portofelul celui care face apelul sau solicitarea. Majoritatea smart contracts NFT sunt implementate în limbajul Solidity creat special pentru Ethereum blockchain. Un exemplu de smart contract pe modelul jocurilor electronice scris în Rust pentru Elrond blockchain creat de Julian Ćwirko puteți găsi pe github. Scopul nostru este ca NFT-urile ce reprezintă identitatea noastră digitală să ajungă în portofelul nostru digital, nu suntem așadar interesați de minting, iar pentru aceasta e suficient să ne asignăm nouă toate NFT-urile din colecție, fără să le vindem aleatoriu. Pentru etapa 2, ne vom oferi (portofelului nostru digital) rolul de a genera NFT-uri pentru această colecție. În acest scop, vom apela scriptul set_nft_special_role.sh cu parametrul collection ID extras din tranzacția de mai sus. Datele arată astfel:
Acum, putem genera NFT-uri cu adresa portofelului nostru, folosind scriptul generat nft.sh de mai jos:
#!/usr/bin/bashWALLET_KEY=walletKey.pemIPFS_CID=$1
TOKEN_IDENTIFIER=$2
TOKEN_IDENTIFIER_HEX=
"0x$(echo -n ${TOKEN_IDENTIFIER} | xxd -p -u
| tr -d '\n')"function generate_nft(){
NFT_NAME=$1
NFT_NAME_HEX="0x$(echo -n ${NFT_NAME} | xxd -p
-u | tr -d '\n')"
GATEWAY_1_URL=
https://dweb.link/ipfs/${IPFS_CID}/${NFT_NAME}.png
GATEWAY_2_URL=https://ipfs.cf-ipfs.com/ipfs/
${IPFS_CID}/${NFT_NAME}.png
GATEWAY_3_URL=https://cloudflare-ipfs.com/ipfs/
${IPFS_CID}/${NFT_NAME}.pngIPFS_URL_HEX=
"0x$(echo -n ${IPFS_URL} | xxd -p -u | tr -d '\n')"
GATEWAY_1_URL_HEX="0x$(echo -n ${GATEWAY_1_URL} | xxd
-p -u | tr -d '\n')"
GATEWAY_2_URL_HEX="0x$(echo -n ${GATEWAY_2_URL} | xxd
-p -u | tr -d '\n')"
GATEWAY_3_URL_HEX="0x$(echo -n ${GATEWAY_3_URL} | xxd
-p -u | tr -d '\n')"#contract is your address
WALLET_ADDRESS=001863b862703277521ed0cd5f22d5932921905fd6926aac157d08f3618b9c63
GAS_LIMIT=2805501
ELROND_PROXY=https://gateway.elrond.com
ELROND_CHAIN=1./erdpy --verbose contract call
$WALLET_ADDRESS --recall-nonce \
--pem=${WALLET_KEY} \
--gas-limit=${GAS_LIMIT} \
--value=0 \
--proxy=${ELROND_PROXY} \
--chain=${ELROND_CHAIN} \
--function="ESDTNFTCreate" \
--arguments $TOKEN_IDENTIFIER_HEX \
01 \
$NFT_NAME_HEX \
00 \
00 \
00 \
$GATEWAY_2_URL_HEX \
$GATEWAY_3_URL_HEX \
--send
}FILES="/files/*.png"
for f in $FILES
do
echo "Processing $f file..."
NFT_NAME_1="$(echo $f | sed 's/\/files\///' |
sed 's/.png//')"
echo $NFT_NAME_1
generate_nft $NFT_NAME_1
sleep 20
done
Scriptul citește fișierele png unul câte unul și generează un NFT pentru fiecare, asignându-l portofelului meu. Poți seta URL-uri multiple pentru fiecare NFT pentru a-l face accesibil prin intermediul mai multor gatewayuri IPFS, dar fiecare byte de date stocat pe blockchain va crește costul tranzacției. În cele din urmă, am decis să generez NFT-uri unul câte unul, doar cu amintirile pe care doream să le păstrez (unele lucruri sunt mai bune lăsate uitării), așa că am făcut modificări minore la scriptul de mai sus.
Am reușit! Amintirile mele se află acum în portofelul meu digital. În sfârșit sunt ale mele, iar dacă ați reușit să citiți articolul până în acest punct și aveți un portofel Elrond, cereți și vă voi trimite până la 10 de NFT-uri cadou.
NFT-uri în portofelul Web Elrond
Imaginați-vă toate celelalte bunuri pe care ați putea să le aveți în portofelul digital: dovada că sunteți proprietarul casei voastre (un smart contract poate fi executat automat și vă transferă casa băncii dacă nu vă plătiți rata — asta, într-un scenariu de groază), proprietarul tuturor cuvintelor pe care le-ați scris vreodată, a tuturor operelor de artă pe care le-ați creat sau a dovezii că sunteți vaccinați în pandemie. Afirmațiile politicienilor noștri, promisiunile guvernului: imutabile în Blockchain cu consecințe executate automat de smart contracts. Ok, poate că unele scenarii sunt puțin cam orwelliene. Cred însă că identitățile noastre digitale ar trebui să ne aparțină nouă și nu vreunui CEO și că tehnologic a devenit posibil să avem atât control asupra propriei identități, cât și să navigăm pe social media. Înainte să ne ștergem conturile existente, așteptăm să apară un site descentralizat de social media implementat pe smart contracts. Aceasta însă este o discuție despre web3 pentru care avem nevoie de un alt articol și de un alt thread.
Ar trebui să fim deopotrivă speriați și entuziasmați de posibilitățile care ne așteaptă, dar și de presiunea care apasă greu pe umerii noștri pentru a ne asigura că viitorul tehnologic pe care îl construim nu se va întoarce împotriva noastră. Depinde de noi dacă NFT-urile vor fi utilizate ca dovadă de proprietate când vine vorba de artă, imobiliare, identitate digitală sau dacă vor fi folosite în continuare pe post shoturi de dopamină servite de un smart contract pe principiul slot machines sau în speranța de a deveni bogați peste noapte. Cred că problema ownershipului identității digitale este departe de a fi rezolvată legislativ sau se va dovedi a fi chiar imposibil, iar tehnologia Blockchain are potențialul de a ameliora situația actuală. Controlul asupra datelor mele mi-ar aduce un pic de bucurie, un pic de siguranță și m-ar face probabil mai responsabil pentru tot ce fac și ce spun. Chiar dacă noi oamenii uităm, tehnologia acestei ere nu va uita, deoarece toate informațiile vor fi stocate la infinit, în special pe Blockchains, iar IPFS nu are un buton care să spună "șterge-mi profilul".