Привет Хабр.  История началась пол года назад, когда ко мне пришел мой старый знакомый художник и предложил создать NFT коллекцию на блокчейне Ethereum. Скажу сразу, я никогда не интересовался криптой и на тот момент понятие не имел, что такое NFT и как они устроены.  В этой статья я не буду рассказывать, что такое NFT и для чего они нужны, вместо этого я сосредоточусь на технической части, т.к. когда я начинал материала было крайне мало и приходилось додумывать некоторые решения самому. После проведенного небольшого исследования, мне удалось разбить изначальную задачу из абстрактного “создать NFT коллекцию” на более мелкие и конкретные, а именно: с генерировать 10 000 уникальных изображений  с генерировать 10 000 метаданных к каждому изображению загрузить 10 000 изображений вместе с метеданными в децентрализованное хранилище создать смарт-контракт для NFT токенов загрузить созданный смарт-контракт в mainnet Ethereum создать сайт, который будет взаимодействовать с нашим смарт-контрактом с помощью web3, где собственно пользователи и смогут менять свои эфиры на наши NFT токены Казалось бы пустяки, а нет, на каждом этапе меня поджидали непредвиденные моменты, о которых мы сейчас и поговорим. Как с генерировать 10 000 уникальных изображений? Почему именно 10 000? Ответ достаточно прост, большинство популярных NFT проектов, предлагают коллекции именно из 10 000 NFT токенов. Каждый создатель, сам волен решать сколько NFT токенов он хочет выпустить, но мы решили не отходить от канона и тоже сделали 10 000 токенов. Итак, как же все таки с генерировать 10 000 уникальных изображений? Конечно же с помощью автоматического наложения слоев друг на друга. Немного поразмыслив, мы с художником пришли к выводу, что для нашего проекта нам нужны следующие слои: фон - 20 шт туловище персонажа - 25 шт голова - 15 шт эмоции - 20 шт одежда - 30 шт обувь - 25 шт аксессуары - 40 шт В общем количестве, у нас получилось приблизительно 175 уникальных слоев в формате png, что более чем достаточно, чтобы получить 10 000 уникальных персонажей. Теперь осталось совсем ничего, а именно написать утилиту, которая на входе будет принимать заготовки в виде слоев, а на выходе будет отдавать готовых персонажей.  Писать я буду на Golang, итак поехали. Для начала, нам нужно описать 2 структуры в пакете domain, одна для слоев, а другая для холста. Давайте более подробно рассмотрим обе структуры. ImageLayer: Image - изображение слоя Priority - приоритет слоя, т.к. слои нужно накладывать в определенном порядке, сначала фон, потом туловище, потом голова, итд … XPos, YPos - позиция слоя на холсте BgProperty: Width - ширина холста Length - длина холста Итак, когда базовые структуры описаны, мы можем перейти к написанию сервиса, который собственно и будет комбинировать наши слои в определенном порядке.  Код сервиса достаточно простой, на входе сервис принимает список слоев и параметры холста, а на выходе возвращает байты сгенерированного изображения. Хочется отметить, что  Go обладает достаточно хорошей библиотекой для работы с изображениями и именно с ней мы будем работать, собственно код: Отлично, когда код для генерации изображений готов, мы можем переходить к генерации метаданных.  Для начала, стоит отметить, что именно в метаданных хранятся все свойства и ссылки на картинки для NFT токенов, а также именно по метаданным, большинство торговых площадок выполняют поиск NFT токенов. Поэтому очень важно выбрать правильный формат для метаданных. В каком формате должны быть метаданные для NFT токенов? Т.к. NFT токены основаны на ERC-721 стандарте, а сам стандарт никак не описывает в каком формате должны быть метаданные, мы вольны использовать любой формат какой только захотим. Но если мы хотим, чтобы наши NFT токены могли полноценно торговаться на таких пощадках как opensea, мы должны следовать следующему JSON формату:  Отлично, когда мы разобрались с форматом, давайте опишем структуру для хранения метаданных на Go: Перед тем как приступать к генерации метаданных, нам нужны готовые ссылки на загруженные в децентрализованное хранилище изображения. В следующей статье, я расскажу как загружать изображения в децентрализованное хранилище, а также продолжим работать с метаданными. P.S.Весь исходный код можно посмотреть на github. Golang & Blockchain Enthusiast