# Data Structures

Twine uses [IPLD](https://ipld.io/docs/schemas/) to encode its data. There are two data structures: Pulses, and Chain metadata.

Pulses are logically grouped as chains, which act as proxies for ownership. Generally, a chain is produced for a single purpose or use case by a single process and owner. Every pulse of every chain is also linked (via hash-linking) to pulses of other chains, thus forming the larger Tapestry. Chain metadata stores meta information about the construction of the chain, including the public key for provenance verification.&#x20;

Hash-linking of the data structures is facilitated by the process of [content addressing and CIDs](https://docs.ipfs.tech/concepts/content-addressing). With content addressing, data is referenced by its hash instead of its location using a special identifier called a Content ID (CID). A CID is constructed using the hash of serialized data, meta-information about the serialization method, hash algorithm, format, and version of the CID itself. This self-descriptive CID is used as both an identifier for retrieval of the original data, as well as a checksum to verify its integrity. Since CIDs contain a hash of the data, they can be used for the purposes of hash-linking.&#x20;

{% hint style="info" %}
Content addressing and CIDs were established as part of the distributed peer-to-peer filesystem IPFS, however IPFS is not necessary for Twine data.&#x20;
{% endhint %}

Both Pulses and Chain metadata follow a similar outer structure. What distinguishes them is the type of their \`content\` property.

```
type TwinePulse struct {
    content PulseContent
    signature String
} representation map

type TwineChain struct {
    content ChainContent
    signature String
} representation map
```

### Signatures

Signatures are represented as a string type which encodes a [Compact Javascript Web Signature JWS](https://www.rfc-editor.org/rfc/rfc7515#section-3.1).&#x20;

<pre class="language-json" data-title="Example Compact JWS" data-overflow="wrap"><code class="lang-json"><strong>"eyJhbGciOiJFUzI1NiJ9.FECjYMLfBcaarQShFsVVcV3h12vG9Aw2JN5yNptUodLAQV3mfxSgwqdO-VQStLeTRdZDon4YXVGtcgZ_aLzbEqw1.3xZ-2BxejyxinNugtmmm5bo4LuuymNk0KRILsNMluYXjgKWLJRI9EO_MbUnBGiLjAOg16PV6CGrjYDNwAzzbkQ"
</strong></code></pre>

### Mixins

Twine structures make use of a `Mixin` type which is used to store connections between chains.

```
type Mixin struct {
    chain Link
    value Link
} representation map
```

### Pulses

Pulses are the data structures that chain together to create the tapestry. They are the structures that carry payloads and are used to append updates.

{% tabs %}
{% tab title="Schema" %}

```
type PulseContent struct {
  specification String
  chain Link
  index Integer
  links [Link]
  mixins [Mixin]
  source String
} representation map
```

{% endtab %}

{% tab title="Example JSON" %}

<pre class="language-json"><code class="lang-json"><strong>// Represented as DAG-JSON
</strong><strong>{
</strong>  "content": {
    "chain": {
      "/": "bafyriqeoead7csc563ich2z5r6zk4775kopw6fdi2b4xd2jakect2frugslusvva7boq273kzc5uwgm3gyrtfimonjd5xlv5cjt3vibp36u6m"
    },
    "index": 22217,
    "links": [
      {
        "/": "bafyriqelifnu5iq5pgpzqayswpwlq3n6mbq44jcnnhe7afgyupj5hobuquzsls7n2misixjao6wn24mp2gycnjhgokhznetehc4z76jpxi35u"
      }
    ],
    "mixins": [
      {
        "chain": {
          "/": "bafyriqgpmci2rgrxbirme3rsxwqlfocl6h7hjrcm5qytgiiujr6whp26xi7ofomwldjxsdbv54ahuomvpufgh5gdwi5h3pmeozop6fpnpwfzg"
        },
        "value": {
          "/": "bafyriqamkiqv7rf64ohyb6zhf3y4twnwhgopgh2swyu3ytfnzqjhani5thv4bh2dhaa5yatqr6lubm4adwfw5boieg7jjaz2a7bvwkpmxvvcg"
        }
      }
    ],
    "payload": {
      "timestamp": "2022-03-25T20:11:44.207Z"
    },
    "source": "random.colorado.edu"
  },
  "signature": "eyJhbGciOiJSUzI1NiJ9.FEDk6G9L64PqhDw5OE3o5AWwpGptF_t9_myMew2W9_ZBc5YEWZ0KVKE0xmAVb-vgQnJqV1W7iZVzxWzE6RaW0tdR.dpCCKYWMjo0iy_zJyb8ZSuqP-ShWJdJJHWGky4WblAYfpMMudyPD7ZOIvJY8ysGIt0_wSFjxZnlA62yL_sz0sCLC2xj93GrCwuBDafikbyzHf2zzOxYpqkXLGorq_02DHg_RrySU1CQqNrKMwTHbsOTz0VyoXii2H8wTRZyYeCoJ5Ju0W6cSDJJcoxm6ozhZnqcjjkohBUAbu0wX4nj_rdWPwmIFzYAnPXdN9id_Eo3s5PIO4jO5NzQQ3VzkFx1N9W3NbMeEuqkz-nwe4DGmgSr-EqFmhvLjPVmB1kYQ4bYovMykdQJyKETQ6r0XXKgjJ8KegDrSGU1o2N2dkpYdBQ"
}
</code></pre>

{% endtab %}
{% endtabs %}

### Chain Metadata

Chain Metadata structures store information about the chain as a whole. They must be retrieved in order to verify the signatures of Twine data structures.

{% tabs %}
{% tab title="Schema" %}

```
type ChainContent struct {
  specification String
  key JWK # https://www.rfc-editor.org/rfc/rfc7517
  links_radix Integer
  meta Map
  mixins [Mixin]
  source String
} representation map
```

{% endtab %}

{% tab title="Example JSON" %}

<pre class="language-json"><code class="lang-json"><strong>// Represented as DAG-JSON
</strong>{
  "content": {
    "key": {
      "alg": "ES256",
      "crv": "P-256",
      "kty": "EC",
      "x": "yiQcZrPJGV11Z6o0r4Oj-iKrGbYYqSp7vLgUDUtQDUA",
      "y": "gUyDV_gyzU2SMfPmIB2uyOtclxR6v6Ic-JTmJDq4Tq0"
    },
    "links_radix": 32,
    "meta": {
      "description": "Weather chain showing boulder weather every 5 minutes."
    },
    "mixins": [
      
    ],
    "source": "entwine.me",
    "specification": "twine/1.0.x"
  },
  "signature": "eyJhbGciOiJFUzI1NiJ9.FECjYMLfBcaarQShFsVVcV3h12vG9Aw2JN5yNptUodLAQV3mfxSgwqdO-VQStLeTRdZDon4YXVGtcgZ_aLzbEqw1.3xZ-2BxejyxinNugtmmm5bo4LuuymNk0KRILsNMluYXjgKWLJRI9EO_MbUnBGiLjAOg16PV6CGrjYDNwAzzbkQ"
}
</code></pre>

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.twine.world/twine-protocol-documentation/concepts/data-structures.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
