CINXE.COM
IPLD ♦ CARv1 Specification
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="/css/layout.css?1718759055581"> <link rel="stylesheet" href="/css/nav.css?1718759055581"> <link rel="stylesheet" href="/css/style.css?1718759055581"> <link rel="stylesheet" href="/css/prismjs@1.24-themes-prism.css"> <title>IPLD ♦ CARv1 Specification</title> </head> <body> <header> <div class="sidebar-button" onclick="document.getElementById('sidebar').classList.toggle('sidebar-open')"> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"> <path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path> </svg> </div> <a href="/" class="logo">IPLD</a> <aside id=breadcrumbs> <ul> <li><a href="/specs">specs</a></li> <li><a href="/specs/transport">transport</a></li> <li><a href="/specs/transport/car">car</a></li> <li><a href="/specs/transport/car/carv1/">carv1</a></li> </ul> </aside> </header> <aside id=sidebar> <nav> <ul> <li> <a href="/docs/">Docs</a><ul> <li> <a href="/docs/intro/">Intro</a><ul> <li> <a href="/docs/intro/hello-world/">Hello, World</a></li> <li> <a href="/docs/intro/primer/">The Brief Primer</a></li> <li> <a href="/docs/intro/ecosystem/">InterPlanetary Ecosystem Overview</a></li> <li> <a href="/docs/intro/community/">Finding Community</a></li></ul></li> <li> <a href="/docs/motivation/">Motivation</a><ul> <li> <a href="/docs/motivation/benefits-of-content-addressing/">Benefits of Content Addressing</a></li> <li> <a href="/docs/motivation/data-to-data-structures/">From Data to Data Structures</a></li></ul></li> <li> <a href="/docs/codecs/">Codecs</a><ul> <li> <a href="/docs/codecs/known/">Known Codecs</a><ul> <li> <a href="/docs/codecs/known/dag-cbor/">DAG-CBOR</a></li> <li> <a href="/docs/codecs/known/dag-json/">DAG-JSON</a></li> <li> <a href="/docs/codecs/known/dag-pb/">DAG-PB</a></li></ul></li></ul></li> <li> <a href="/docs/data-model/">Data Model</a><ul> <li> <a href="/docs/data-model/node/">Nodes</a></li> <li> <a href="/docs/data-model/kinds/">Kinds</a></li> <li> <a href="/docs/data-model/pathing/">Pathing</a></li> <li> <a href="/docs/data-model/traversal/">Traversal</a></li></ul></li> <li> <a href="/docs/advanced-data-layouts/">Advanced Data Layouts</a><ul> <li> <a href="/docs/advanced-data-layouts/intro/">Intro to ADLs</a></li> <li> <a href="/docs/advanced-data-layouts/naming/">ADL Naming</a></li> <li> <a href="/docs/advanced-data-layouts/signalling/">Signalling ADLs</a></li> <li> <a href="/docs/advanced-data-layouts/dynamic-loading/">Dynamic Loading</a></li> <li> <a href="/docs/advanced-data-layouts/known/">Known ADLs</a></li></ul></li> <li> <a href="/docs/schemas/">Schemas</a><ul> <li> <a href="/docs/schemas/intro/">Introduction</a><ul> <li> <a href="/docs/schemas/intro/compare/">compare</a></li> <li> <a href="/docs/schemas/intro/goals/">Goals</a></li> <li> <a href="/docs/schemas/intro/feature-summary/">Feature Summary</a></li></ul></li> <li> <a href="/docs/schemas/features/">Features</a><ul> <li> <a href="/docs/schemas/features/typekinds/">Type Kinds</a></li> <li> <a href="/docs/schemas/features/representation-strategies/">Representation Strategies</a></li> <li> <a href="/docs/schemas/features/links/">Links</a></li> <li> <a href="/docs/schemas/features/indicating-adls/">Using ADLs in Schemas</a></li></ul></li> <li> <a href="/docs/schemas/using/">Using Wisely</a><ul> <li> <a href="/docs/schemas/using/authoring-guide/">Authoring Guide</a></li> <li> <a href="/docs/schemas/using/migrations/">Migrations</a></li></ul></li></ul></li> <li> <a href="/docs/synthesis/">Synthesis</a><ul> <li> <a href="/docs/synthesis/gtd/">Getting Things Done</a></li> <li> <a href="/docs/synthesis/building-in-alignment/">Building in Alignment</a></li> <li> <a href="/docs/synthesis/how-ipfs-web-gateways-work/">How IPFS Web Gateways Work</a></li> <li> <a href="/docs/synthesis/encryption/">Working With Encryption</a></li></ul></li></ul></li> <li> <a href="/specs/">Specs</a><ul> <li> <a href="/specs/about/">About the Specifications</a></li> <li> <a href="/specs/codecs/">Codecs</a><ul> <li> <a href="/specs/codecs/dag-cbor/">DAG-CBOR</a><ul> <li> <a href="/specs/codecs/dag-cbor/fixtures/">DAG-CBOR Test Fixtures</a><ul> <li> <a href="/specs/codecs/dag-cbor/fixtures/cross-codec/">cross-codec</a></li></ul></li> <li> <a href="/specs/codecs/dag-cbor/spec/">Spec</a></li></ul></li> <li> <a href="/specs/codecs/dag-cosmos/">DAG-COSMOS</a><ul> <li> <a href="/specs/codecs/dag-cosmos/basic_types/">basic_types</a></li> <li> <a href="/specs/codecs/dag-cosmos/cosmos_state/">cosmos_state</a></li> <li> <a href="/specs/codecs/dag-cosmos/crypto_types/">crypto_types</a></li> <li> <a href="/specs/codecs/dag-cosmos/tendermint_chain/">tendermint_chain</a></li> <li> <a href="/specs/codecs/dag-cosmos/typed_protobuf/">typed_protobuf</a></li></ul></li> <li> <a href="/specs/codecs/dag-eth/">DAG-ETH</a><ul> <li> <a href="/specs/codecs/dag-eth/basic_types/">basic_types</a></li> <li> <a href="/specs/codecs/dag-eth/chain/">chain</a></li> <li> <a href="/specs/codecs/dag-eth/convenience_types/">convenience_types</a></li> <li> <a href="/specs/codecs/dag-eth/state/">state</a></li></ul></li> <li> <a href="/specs/codecs/dag-jose/">DAG-JOSE</a><ul> <li> <a href="/specs/codecs/dag-jose/fixtures/">fixtures</a></li> <li> <a href="/specs/codecs/dag-jose/spec/">Spec</a></li></ul></li> <li> <a href="/specs/codecs/dag-json/">DAG-JSON</a><ul> <li> <a href="/specs/codecs/dag-json/fixtures/">DAG-JSON Test Fixtures</a><ul> <li> <a href="/specs/codecs/dag-json/fixtures/cross-codec/">cross-codec</a></li></ul></li> <li> <a href="/specs/codecs/dag-json/spec/">Spec</a></li></ul></li> <li> <a href="/specs/codecs/dag-pb/">DAG-PB</a><ul> <li> <a href="/specs/codecs/dag-pb/fixtures/">DAG-PB Test Fixtures</a><ul> <li> <a href="/specs/codecs/dag-pb/fixtures/cross-codec/">cross-codec</a></li></ul></li> <li> <a href="/specs/codecs/dag-pb/spec/">Spec</a></li></ul></li></ul></li> <li> <a href="/specs/advanced-data-layouts/">Advanced Data Layouts</a><ul> <li> <a href="/specs/advanced-data-layouts/fbl/">FBL ADL</a><ul> <li> <a href="/specs/advanced-data-layouts/fbl/spec/">spec</a></li></ul></li> <li> <a href="/specs/advanced-data-layouts/hamt/">HAMT ADL</a><ul> <li> <a href="/specs/advanced-data-layouts/hamt/fixture/">HashMap (HAMT) Test Fixtures</a><ul> <li> <a href="/specs/advanced-data-layouts/hamt/fixture/alice-words/">alice-words</a></li></ul></li> <li> <a href="/specs/advanced-data-layouts/hamt/spec/">spec</a></li></ul></li></ul></li> <li> <a href="/specs/schemas/">Schemas</a><ul> <li> <a href="/specs/schemas/prelude/">prelude</a></li></ul></li> <li> <a href="/specs/transport/">Transports</a><ul> <li> <a href="/specs/transport/car/">CAR</a><ul> <li class="active-page"> <a href="/specs/transport/car/carv1/">CARv1 Specification</a></li> <li> <a href="/specs/transport/car/carv2/">CARv2 Specification</a></li> <li> <a href="/specs/transport/car/fixture/">CAR Test Fixtures</a><ul> <li> <a href="/specs/transport/car/fixture/carv1-basic/">carv1-basic</a></li> <li> <a href="/specs/transport/car/fixture/carv2-basic/">carv2-basic</a></li></ul></li></ul></li> <li> <a href="/specs/transport/graphsync/">Graphsync</a><ul> <li> <a href="/specs/transport/graphsync/known_extensions/">known_extensions</a></li></ul></li> <li> <a href="/specs/transport/trustless-pathing/">Trustless Pathing</a><ul> <li> <a href="/specs/transport/trustless-pathing/fixtures/">Trustless Pathing Fixtures</a><ul> <li> <a href="/specs/transport/trustless-pathing/fixtures/unixfs_20m_variety/">unixfs_20m_variety</a></li></ul></li></ul></li></ul></li> <li> <a href="/specs/selectors/">Selectors</a><ul> <li> <a href="/specs/selectors/fixtures/">fixtures</a><ul> <li> <a href="/specs/selectors/fixtures/selector-fixtures-1/">selector-fixtures-1</a></li> <li> <a href="/specs/selectors/fixtures/selector-fixtures-adl/">selector-fixtures-adl</a></li> <li> <a href="/specs/selectors/fixtures/selector-fixtures-recursion/">selector-fixtures-recursion</a></li></ul></li></ul></li> <li> <a href="/specs/patch/">Patch</a><ul> <li> <a href="/specs/patch/fixtures/">IPLD Patch Test Fixtures</a><ul> <li> <a href="/specs/patch/fixtures/fixtures-1/">fixtures-1</a></li></ul></li></ul></li></ul></li> <li> <a href="/libraries/">Libraries</a><ul> <li> <a href="/libraries/golang/">Golang</a></li> <li> <a href="/libraries/javascript/">JavaScript</a></li> <li> <a href="/libraries/python/">Python</a></li> <li> <a href="/libraries/rust/">Rust</a></li></ul></li> <li> <a href="/design/">Design</a><ul> <li> <a href="/design/objectives/">Objectives</a></li> <li> <a href="/design/concepts/">Concepts</a><ul> <li> <a href="/design/concepts/type-theory-glossary/">type-theory-glossary</a></li></ul></li> <li> <a href="/design/libraries/">Libraries</a><ul> <li> <a href="/design/libraries/nodes-and-kinds/">nodes-and-kinds</a></li></ul></li> <li> <a href="/design/tricky-choices/">Tricky Choices</a><ul> <li> <a href="/design/tricky-choices/dag-pb-forms-impl-and-use/">dag-pb-forms-impl-and-use</a></li> <li> <a href="/design/tricky-choices/map-key-domain/">map-key-domain</a></li> <li> <a href="/design/tricky-choices/numeric-domain/">numeric-domain</a></li> <li> <a href="/design/tricky-choices/ordering/">ordering</a></li> <li> <a href="/design/tricky-choices/string-domain/">string-domain</a></li></ul></li> <li> <a href="/design/open-research/">Open Research</a><ul> <li> <a href="/design/open-research/ADL-autoexecution/">ADL autoexecution</a></li></ul></li></ul></li> <li> <a href="/tools/">Tools</a></li> <li> <a href="/glossary/">Glossary</a></li> <li> <a href="/media/">Media</a></li> <li> <a href="/FAQ/">FAQ</a></li></ul> </nav> </aside> <main> <div class=content> <h1>Specification: Content Addressable aRchives (CAR / .car) v1</h1> <p><strong>Status: Final</strong></p> <ul> <li><a href="#summary">Summary</a></li> <li><a href="#format-description">Format Description</a> <ul> <li><a href="#header">Header</a> <ul> <li><a href="#constraints">Constraints</a></li> </ul> </li> <li><a href="#data">Data</a> <ul> <li><a href="#length">Length</a></li> <li><a href="#cid">CID</a></li> <li><a href="#data-1">Data</a></li> </ul> </li> </ul> </li> <li><a href="#additional-considerations">Additional Considerations</a> <ul> <li><a href="#determinism">Determinism</a></li> <li><a href="#performance">Performance</a></li> <li><a href="#security-and-verifiability">Security and Verifiability</a></li> <li><a href="#indexing-and-seeking-reads">Indexing and Seeking Reads</a></li> <li><a href="#padding">Padding</a></li> </ul> </li> <li><a href="#implementations">Implementations</a> <ul> <li><a href="#go">Go</a></li> <li><a href="#javascript">JavaScript</a></li> </ul> </li> <li><a href="#unresolved-items">Unresolved Items</a> <ul> <li><a href="#number-of-roots">Number of roots</a></li> <li><a href="#zero-blocks">Zero blocks</a></li> <li><a href="#root-cid-block-existence">Root CID block existence</a></li> <li><a href="#cid-version">CID version</a></li> <li><a href="#duplicate-blocks">Duplicate Blocks</a></li> </ul> </li> <li><a href="#test-fixtures">Test Fixtures</a></li> </ul> <h2 id="summary" tabindex="-1"><a class="header-anchor" href="#summary">Summary</a></h2> <p>The CAR format (Content Addressable aRchives) can be used to store content addressable objects in the form of IPLD block data as a sequence of bytes; typically in a file with a <code>.car</code> filename extension.</p> <p>The CAR format is intended as a serialized representation of any IPLD DAG (graph) as the concatenation of its blocks, plus a header that describes the graphs in the file (via root CIDs). The requirement for the blocks in a CAR to form coherent DAGs is not strict, so the CAR format may also be used to store arbitrary IPLD blocks.</p> <p>In addition to the binary block data, storage overhead for the CAR format consists of:</p> <ul> <li>A header block encoded as <a href="../../../codecs/dag-cbor/">DAG-CBOR</a> containing the format version and an array of root CIDs</li> <li>A CID for each block preceding its binary data</li> <li>A compressed integer prefixing each block (including the header block) indicating the total length of that block, including the length of the encoded CID</li> </ul> <p>This diagram shows how IPLD blocks, their root CID, and a header combine to form a CAR.</p> <img src="../content-addressable-archives.png" alt="Content Addressable aRchive Diagram" width="100%"> <p>The name <em>Certified ARchive</em> has also <a href="https://github.com/ipfs/archive-format">previously been used</a> to refer to the CAR format.</p> <h2 id="format-description" tabindex="-1"><a class="header-anchor" href="#format-description">Format Description</a></h2> <p>The CAR format comprises a sequence of length-prefixed IPLD block data, where the first block in the CAR is the Header encoded as CBOR, and the remaining blocks form the Data component of the CAR and are each additionally prefixed with their CIDs. The length prefix of each block in a CAR is encoded as a "varint"—an unsigned <a href="https://en.wikipedia.org/wiki/LEB128">LEB128</a> integer. This integer specifies the number of remaining bytes for that block entry—excluding the bytes used to encode the integer, but including the CID for non-header blocks.</p> <pre><code>|--------- Header --------| |---------------------------------- Data -----------------------------------| [ varint | DAG-CBOR block ] [ varint | CID | block ] [ varint | CID | block ] [ varint | CID | block ] … </code></pre> <h3 id="header" tabindex="-1"><a class="header-anchor" href="#header">Header</a></h3> <p>The first bytes of the CAR format hold a varint, this unsigned integer specifies the number of bytes beyond the varint itself that contain the <em>Header</em> block. This Header block is a byte array DAG-CBOR (CBOR with tag 42 for CIDs) encoded object holding the version number and array of roots. As an <a href="../../../../docs/schemas/">IPLD Schema</a>:</p> <pre class="language-ipldsch"><code class="language-ipldsch"><span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">CarHeader</span></span> <span class="token builtin">struct</span> <span class="token punctuation">{</span> version Int roots <span class="token punctuation">[</span><span class="token punctuation">&</span>Any<span class="token punctuation">]</span> <span class="token punctuation">}</span></code></pre> <h4 id="constraints" tabindex="-1"><a class="header-anchor" href="#constraints">Constraints</a></h4> <ul> <li>The <code>version</code> is always a value of <code>1</code>. Future iterations of this specification may make use of <code>version</code> to introduce variations of the format.</li> <li>The <code>roots</code> array must contain <strong>one or more</strong> CIDs, each of which should be present somewhere in the remainder of the CAR.</li> </ul> <p><em>(Caveats: see <a href="#number-of-roots">Number of roots</a> and <a href="#root-cid-block-existence">Root CID block existence</a> under Unresolved Issues.)</em></p> <h3 id="data" tabindex="-1"><a class="header-anchor" href="#data">Data</a></h3> <p>Immediately following the Header block, <strong>one or more</strong> IPLD blocks are concatenated to form the <em>Data</em> section of the CAR format. <em>(Caveat: see <a href="#zero-blocks">Zero blocks</a> under Unresolved Issues.)</em> Each block is encoded into a <em>Section</em> by the concatenation of the following values:</p> <ol> <li>Length in bytes of the combined CID and data in this Section, encoded as a varint</li> <li>CID of the block in this Section, encoded in the raw byte form of the CID</li> <li>Binary data of the block</li> </ol> <h4 id="length" tabindex="-1"><a class="header-anchor" href="#length">Length</a></h4> <p>Each Section begins with a varint representation of an unsigned integer indicating the number of bytes containing the remainder of the section.</p> <h4 id="cid" tabindex="-1"><a class="header-anchor" href="#cid">CID</a></h4> <p>Following the Length, the CID of the block is included in raw byte form. A decoder reading a Section must decode the CID according to CID byte encoding rules, which don't provide a stable length. See <a href="https://github.com/multiformats/cid">https://github.com/multiformats/cid</a> for details on the encoding of a CID. CIDv0 and CIDv1 are currently supported. <em>(Caveat: see <a href="#cid-version">CID version</a> under Unresolved Issues.)</em></p> <p><strong>CID byte decoding summary</strong></p> <p><em>See the <a href="https://github.com/multiformats/cid">CID specification</a> for full details.</em></p> <p>A CIDv0 is indicated by a first byte of <code>0x12</code> followed by <code>0x20</code> which specifies a 32-byte (<code>0x20</code>) length SHA2-256 (<a href="https://github.com/multiformats/multicodec/blob/master/table.csv"><code>0x12</code></a>) digest.</p> <p>Failure to find <code>0x12, 0x20</code> indicates a CIDv1 which is decoded by reading:</p> <ol> <li>Version as an unsigned varint (should be <code>1</code>)</li> <li>Codec as an unsigned varint (valid according to the <a href="https://github.com/multiformats/multicodec/blob/master/table.csv">multicodec table</a>)</li> <li>The raw bytes of a <a href="https://github.com/multiformats/multihash">multihash</a></li> </ol> <p>Reading the multihash requires a partial decode in order to determine the length:</p> <pre><code>| hash function code (varint) | digest size (varint) | digest | </code></pre> <p>The first two bytes of a multihash are varints, where the second varint is an unsigned integer indicating the length of the remaining portion of the multihash. Therefore, a manual decode requires two varint reads and then copying the bytes of those varints in addition to the number of bytes indicated by the second varint into a byte array.</p> <h4 id="data-1" tabindex="-1"><a class="header-anchor" href="#data-1">Data</a></h4> <p>The remainder of a Section, after length-prefix and CID, comprises the raw byte data of the IPLD block. The encoded block may be any IPLD block format as specified by the codec in the CID. Typical codecs will be <a href="../../../codecs/dag-pb/">DAG-PB</a>, <a href="../../../codecs/dag-cbor/">DAG-CBOR</a> or <a href="https://github.com/ipld/specs/issues/223">RAW</a>.</p> <h2 id="additional-considerations" tabindex="-1"><a class="header-anchor" href="#additional-considerations">Additional Considerations</a></h2> <h3 id="determinism" tabindex="-1"><a class="header-anchor" href="#determinism">Determinism</a></h3> <p>Deterministic CAR creation is not covered by this specification. However, deterministic generation of a CAR from a given graph is possible and is relied upon by certain uses of the format, most notably, <a href="https://filecoin-project.github.io/specs">Filecoin</a>. Specifically a <em>filecoin-deterministic car-file</em> is currently implementation-defined as containing all DAG-forming blocks in first-seen order, as a result of a depth-first DAG traversal starting from a single root.</p> <p>Additional rules for the generation of the CAR format may be applied in order to ensure that the same CAR is always generated from the same data. The burden of this determinism is primarily placed on <a href="../../../selectors/">selectors</a> whereby a given selector applied to a given graph will always yield blocks in the same order regardless of implementation.</p> <p>Care regarding the ordering of the <code>roots</code> array in the Header, as well as consideration for CID version <em>(see <a href="#cid-version">below</a>)</em> and avoidance of duplicate blocks <em>(see <a href="#duplicate-blocks">below</a>)</em> may also be required for strict determinism.</p> <p>All such considerations are deferred to the user of the CAR format and should be documented there as this specification does not inherently support determinism.</p> <h3 id="performance" tabindex="-1"><a class="header-anchor" href="#performance">Performance</a></h3> <p>Some considerations regarding performance:</p> <ul> <li><strong>Streaming</strong>: the CAR format is ideal for dumping blocks via streaming reads as the Header can be loaded first and minimal state is required for ongoing parsing.</li> <li><strong>Individual block reads</strong>: as the CAR format contains no index information, reads require either a partial scan to discover the location of a required block or an external index must be maintained and referenced for a seek and partial read of that data. See below regarding indexing.</li> <li><strong>DAG traversal</strong>: without an external index, traversal of a DAG specified by a "root" CID is not possible without dumping all blocks into a more convenient data store or by partial scans to find each block as required, which will likely be too inefficient to be practical.</li> <li><strong>Modification</strong>: CARs may be appended after initial write as there is no constraint in the Header regarding total length. Care must be taken in appending if a CAR is intended to contain coherent DAG data.</li> </ul> <h3 id="security-and-verifiability" tabindex="-1"><a class="header-anchor" href="#security-and-verifiability">Security and Verifiability</a></h3> <p>The roots specified by the Header of a CAR must appear somewhere in its Data section, however there is no requirement that the roots define entire DAGs, nor that all blocks in a CAR must be part of DAGs described by the root CIDs in the Header. Therefore, the roots must not be used alone to determine or differentiate the contents of a CAR.</p> <p>The CAR format contains no internal means, beyond the IPLD block formats and their CIDs, to verify or differentiate contents. Where such a requirement exists, this must be performed externally, such as creating a digest of the entire CAR.</p> <h3 id="indexing-and-seeking-reads" tabindex="-1"><a class="header-anchor" href="#indexing-and-seeking-reads">Indexing and Seeking Reads</a></h3> <p>The CAR format contains no internal indexing, any indexing must be stored externally to a CAR. However, such indexing is possible and makes seeking reads practical. An index storing byte offset (of Section start or block data start) and length (of Section or block data), keyed by CID, will enable a single block read by seeking to the offset and reading the block data. The format of any such index is not specified here and is left up to CAR format parsing implementations.</p> <h3 id="padding" tabindex="-1"><a class="header-anchor" href="#padding">Padding</a></h3> <p>The CAR format contains no specified means of padding to achieve specific total archive sizes or internal byte offset alignment of block data. Because it is not a requirement that each block be part of a coherent DAG under one of the roots of the CAR, dummy block entries may be used to achieve padding. Such padding should also account for the size of the length-prefix varint and the CID for a section. All sections must be valid and dummy entries should still decode to valid IPLD blocks.</p> <h2 id="implementations" tabindex="-1"><a class="header-anchor" href="#implementations">Implementations</a></h2> <h3 id="go" tabindex="-1"><a class="header-anchor" href="#go">Go</a></h3> <p><a href="https://github.com/ipld/go-car">https://github.com/ipld/go-car</a></p> <p>As used in Filecoin for genesis block sharing. Supports creation via a DAG walk from a datastore:</p> <pre class="language-go"><code class="language-go"><span class="token function">WriteCar</span><span class="token punctuation">(</span>ctx context<span class="token punctuation">.</span>Context<span class="token punctuation">,</span> ds format<span class="token punctuation">.</span>DAGService<span class="token punctuation">,</span> roots <span class="token punctuation">[</span><span class="token punctuation">]</span>cid<span class="token punctuation">.</span>Cid<span class="token punctuation">,</span> w io<span class="token punctuation">.</span>Writer<span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token builtin">error</span><span class="token punctuation">)</span></code></pre> <p>And writing to a data store via <code>Put(block)</code> operations:</p> <pre class="language-go"><code class="language-go"><span class="token function">LoadCar</span><span class="token punctuation">(</span>s Store<span class="token punctuation">,</span> r io<span class="token punctuation">.</span>Reader<span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token operator">*</span>CarHeader<span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span></code></pre> <h3 id="javascript" tabindex="-1"><a class="header-anchor" href="#javascript">JavaScript</a></h3> <p><a href="https://github.com/ipld/js-car">https://github.com/ipld/js-car</a></p> <p><code>@ipld/car</code> is consumed through factory methods on its different classes. Each class represents a discrete set of functionality, such as writing or reading .car files:</p> <pre class="language-js"><code class="language-js"><span class="token keyword">import</span> fs <span class="token keyword">from</span> <span class="token string">'fs'</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> Readable <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'stream'</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> CarReader<span class="token punctuation">,</span> CarWriter <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@ipld/car'</span> <span class="token keyword">import</span> <span class="token operator">*</span> <span class="token keyword">as</span> raw <span class="token keyword">from</span> <span class="token string">'multiformats/codecs/raw'</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> <span class="token constant">CID</span> <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'multiformats/cid'</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> sha256 <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'multiformats/hashes/sha2'</span> <span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">example</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> bytes <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">TextEncoder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">encode</span><span class="token punctuation">(</span><span class="token string">'random meaningless bytes'</span><span class="token punctuation">)</span> <span class="token keyword">const</span> hash <span class="token operator">=</span> <span class="token keyword">await</span> sha256<span class="token punctuation">.</span><span class="token function">digest</span><span class="token punctuation">(</span>raw<span class="token punctuation">.</span><span class="token function">encode</span><span class="token punctuation">(</span>bytes<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">const</span> cid <span class="token operator">=</span> <span class="token constant">CID</span><span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> raw<span class="token punctuation">.</span>code<span class="token punctuation">,</span> hash<span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> writer<span class="token punctuation">,</span> out <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">await</span> CarWriter<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">[</span>cid<span class="token punctuation">]</span><span class="token punctuation">)</span> Readable<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span>out<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">pipe</span><span class="token punctuation">(</span>fs<span class="token punctuation">.</span><span class="token function">createWriteStream</span><span class="token punctuation">(</span><span class="token string">'example.car'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">await</span> writer<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token punctuation">{</span> cid<span class="token punctuation">,</span> bytes <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token keyword">await</span> writer<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> inStream <span class="token operator">=</span> fs<span class="token punctuation">.</span><span class="token function">createReadStream</span><span class="token punctuation">(</span><span class="token string">'example.car'</span><span class="token punctuation">)</span> <span class="token keyword">const</span> reader <span class="token operator">=</span> <span class="token keyword">await</span> CarReader<span class="token punctuation">.</span><span class="token function">fromIterable</span><span class="token punctuation">(</span>inStream<span class="token punctuation">)</span> <span class="token keyword">const</span> roots <span class="token operator">=</span> <span class="token keyword">await</span> reader<span class="token punctuation">.</span><span class="token function">getRoots</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> got <span class="token operator">=</span> <span class="token keyword">await</span> reader<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>roots<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Retrieved [%s] from example.car with CID [%s]'</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">TextDecoder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">decode</span><span class="token punctuation">(</span>got<span class="token punctuation">.</span>bytes<span class="token punctuation">)</span><span class="token punctuation">,</span> roots<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span></code></pre> <h2 id="unresolved-items" tabindex="-1"><a class="header-anchor" href="#unresolved-items">Unresolved Items</a></h2> <h3 id="number-of-roots" tabindex="-1"><a class="header-anchor" href="#number-of-roots">Number of roots</a></h3> <p>Regarding the <code>roots</code> property of the Header block:</p> <ul> <li>The current Go implementation assumes at least one CID when creating a CAR</li> <li>The current Go implementation requires at least one CID when reading a CAR</li> <li>The current JavaScript implementation allows for zero or more roots</li> <li>Current usage of the CAR format in Filecoin requires exactly one CID</li> </ul> <p>It is unresolved how the <code>roots</code> array should be constrained. <strong>It is recommended that only a single root CID be used in this version of the CAR format.</strong></p> <p>A work-around for use-cases where the inclusion of a root CID is difficult but needing to be safely within the "at least one" recommendation is to use an empty CID: <code>\x01\x55\x00\x00</code> (zero-length "identity" multihash with "raw" codec). Since current implementations for this version of the CAR specification don't check for the existence of root CIDs <em>(see <a href="#root-cid-block-existence">Root CID block existence</a>)</em>, this will be safe as far as CAR implementations are concerned. However, there is no guarantee that applications that use CAR files will correctly consume (ignore) this empty root CID.</p> <h3 id="zero-blocks" tabindex="-1"><a class="header-anchor" href="#zero-blocks">Zero blocks</a></h3> <p>It is unresolved whether a valid CAR must contain <em>at least one</em> block or whether the empty CAR is a valid format and should be accepted by encoders and decoders.</p> <h3 id="root-cid-block-existence" tabindex="-1"><a class="header-anchor" href="#root-cid-block-existence">Root CID block existence</a></h3> <p>It is unresolved whether an implementation must verify that a CID present in the roots array of the Header also appears as a block in the archive. While it is expected that this would be the case, it is unresolved whether encoders and decoders must validate the existence of root blocks in the archive.</p> <p>Current implementations of this version of the CAR specification <em>do not</em> check for root block existence in the CAR body.</p> <h3 id="cid-version" tabindex="-1"><a class="header-anchor" href="#cid-version">CID version</a></h3> <p>It is unresolved whether both CID versions 0 and 1 format are valid in the roots array and at the start of each block Section. Current implementations do not check CID version in the roots array, and both CID versions are also acceptable in each block Section. Discussions on this specification have suggested limiting CIDs used throughout the format (not within blocks) to CIDv1—requiring conversion if an encoder is provided with a CIDv0 and requiring readers of a CAR to ensure CIDv1 is the only available block key.</p> <h3 id="duplicate-blocks" tabindex="-1"><a class="header-anchor" href="#duplicate-blocks">Duplicate Blocks</a></h3> <p>The possibility of duplicate blocks in a single CAR (such as for padding) is currently not specified.</p> <h2 id="test-fixtures" tabindex="-1"><a class="header-anchor" href="#test-fixtures">Test Fixtures</a></h2> <p>To assist implementations in confirming compliance to this specification, the following test fixtures are available:</p> <ul> <li><a href="../fixture/carv1-basic/">carv1-basic</a> - Basic CAR with linked raw, DAG-PB and DAG-CBOR blocks</li> </ul> </div> </main> </body> </html>