Перейти к содержанию

IPFS: CID, multihash и codec

CID — идентификатор содержимого IPFS. Его часто называют «хешем файла», но такая формулировка теряет сведения о кодеке, структуре и представлении. В уроке разберём составляющие идентификатора и установим, почему обычная контрольная сумма файла не обязана совпадать с корневым CID.

Продолжаем выпуск course-17-edition-1. Реальные CID не вычисляются, поэтому обозначения ROOT_CID и MANIFEST_CID остаются метками. В текущей работе не устанавливается библиотека multiformats и не исполняется декодирование.

Идентификатор блока

Данные IPFS организуются в блоки. CID связывает блок с его содержанием по выбранному алгоритму хеширования и сообщает кодек интерпретации. Дополнительные части позволяют понять версию идентификатора. Текстовая форма также указывает способ кодирования записи.

Различим четыре понятия: байты блока, их криптографический отпечаток, CID с описанием формата и печатную строку CID. Последняя удобна для ссылок, но не является просто шестнадцатеричной записью SHA-256. Поэтому сравнение sha256(file) со всей строкой CID бессмысленно без определения структуры.

В CIDv1 явно присутствует версия и кодек. Multihash сообщает алгоритм и значение отпечатка. Multibase относится к текстовому представлению. Кодек позволяет программе понять, как прочитать блок: например, как сырые байты или как структуру со ссылками.

Один файл может быть деревом

Небольшой файл может храниться одним блоком выбранного типа. Более крупный файл импортируется как множество частей с внутренними связями. Корневой блок описывает структуру, а его CID становится адресом файла в этом представлении.

байты исходного файла
        ↓ импорт
части + структура связей
        ↓
корневой блок → корневой CID

Если вычислить обычную SHA-256 исходного файла, получится отпечаток всей исходной последовательности. Если получить digest из CID корневого структурного блока, он может относиться к другим байтам: описанию ссылок и метаданных. Различие нормально и не означает, что файл испорчен.

В библиотечном манифесте можно хранить оба значения, если у них разные роли. Поле sha256 подтверждает точные байты восстановленного файла. Поле cid описывает его content-addressed-представление. Нельзя обрезать строку CID до 32 байтов и называть результат тем же идентификатором.

Версия и текстовая запись

CIDv0 имеет более ограниченную историческую форму. CIDv1 позволяет явнее выразить кодек и другие параметры. Изменение текстовой базы у одного CIDv1 может изменить печатную строку без изменения логической идентичности блока.

Для приложения сравнение идентификаторов должно опираться на совместимый разбор, когда требуется учитывать такие представления. Простое сравнение строк подходит только при заранее заданной нормальной форме. В нашем проекте договоримся сохранять согласованную текстовую форму для ссылок и полное типизированное значение при проверке.

Переход от CIDv0 к поддерживаемому CIDv1 не всегда означает повторный импорт данных. Но не любой кодек CIDv1 может быть представлен как CIDv0. Поэтому преобразование нельзя реализовать заменой первых символов. Совместимые библиотеки применяют ограничения формата.

Параметры импорта влияют на корень

Два инструмента могут импортировать одинаковый исходный файл с разными размерами частей, формами дерева или настройками листьев. Корневые блоки тогда отличаются и дают разные CID. Содержимое файла после восстановления может при этом быть одинаковым.

Для библиотеки это важный критерий воспроизводимости. Мы должны фиксировать профиль импорта вместе с исходными байтами. Если коллега получил другой корень, сначала сравниваем не только файл, но и настройки. Название «IPFS» не определяет один универсальный способ разбиения всех данных.

Значение Что идентифицирует
SHA-256 файла Одну последовательность исходных байтов
CID блока Блок в указанном формате
CID корня UnixFS Корень конкретного представления файла или каталога
URL шлюза Способ обращения к выбранному серверу

Последняя строка напоминает, что URL с CID содержит дополнительное место выдачи. Хост шлюза можно заменить, сохранив ожидаемый объект. Однако сам ответ требует проверки в выбранной модели.

Проверка неизвестной строки

Сайт сначала ограничивает допустимую длину входа и разбирает CID совместимым инструментом. Затем проверяет поддержку кодека и алгоритма. Корректно сформированная строка может относиться к объекту, который наше приложение не умеет безопасно интерпретировать.

Не используем CID как HTML или команду оболочки. Это данные. При формировании ссылки компоненты проходят соответствующее безопасное кодирование, а доступные шлюзы выбираются из доверенной конфигурации. Пользовательский CID не должен заставлять сервер обратиться к произвольному внутреннему адресу.

Декодирование CID не доказывает доступность объекта или авторство редакции. Оно лишь подтверждает допустимую структуру идентификатора. Для выпуска остаются проверка доверенного объявления и получение достаточных блоков.

Изменить написание или изменить объект

Редактор передаёт техническому сотруднику CID в одной текстовой базе, а тот сохраняет его в другой допустимой форме. Чтобы понять, произошло ли изменение выпуска, сначала разбирают идентификатор библиотекой multiformats и сравнивают его структурное значение. Для допустимых представлений одного CIDv1 изменение текстового кодирования не меняет адресованный блок. Простое сравнение строк может дать ложное различие, если нормальная форма не оговорена.

Совсем другая операция — импортировать прежний HTML как UnixFS с другими параметрами. Здесь меняется не написание готового идентификатора, а создаваемое представление. У нового корня может быть другой digest, хотя восстановленный текст одинаков. Поэтому служебная команда «нормализовать CID» не должна запускать повторный импорт. Её вход — идентификатор; вход импортёра — файлы и профиль. Эти границы записываем в интерфейсах библиотеки отдельно.

Для малого манифеста возможен сырой блок, где блоковые байты совпадают с байтами самого файла. Тогда связь файлового SHA-256 и digest зависит от явно выбранных кодека и хеш-функции. Для другого представления с оболочкой или несколькими частями такой вывод уже не следует из длины значения. Читатель не обязан угадывать, какой импорт использовал издатель: это сообщает профиль и опись.

Полезный результат разбора входной строки — версия CID, кодек, алгоритм multihash и длина digest, а также выбранная нормальная строка для хранения. Приложение дополнительно ограничивает поддерживаемые алгоритмы и структуры. Синтаксически допустимый идентификатор необычного кодека ещё не означает, что наш клиент сможет восстановить из него HTML. Недопустимый ввод отвергается до обращения к сети, а поддерживаемый CID с временно отсутствующими блоками остаётся другим состоянием. Так библиотека не смешивает ошибки адресации с ошибками доступности.

Результат для манифеста

Добавим в досье отдельные поля для корневого CID, CID манифеста и SHA-256 его точных байтов. Реальные значения появятся после будущего импорта и вычисления. До этого метки явно обозначены как незаполненные части проекта.

Структура описана в спецификации CID и документации IPFS. Теперь идентификатор перестаёт быть одной загадочной строкой. Следующий урок покажет, как UnixFS соединяет блоки в файл и каталог, сохраняя возможность проверить каждую часть.

Оглавление серии