> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ton.org/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.ton.org/feedback

```json
{
  "path": "/languages/tl-b/complex-and-non-trivial-examples",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# Complex and non-trivial TL-B examples

export const Image = ({src, darkSrc, alt = '', darkAlt, href, target, height = 342, width = 608, noZoom = false, center = false}) => {
  const isSVG = src.match(/\.svg(?:[#?].*?)?$/i) !== null;
  const shouldInvert = isSVG && !darkSrc;
  const shouldCreateLink = href !== undefined;
  const minPx = 9;
  const maxPx = 608;
  const expectedPx = `a number or a string with a number that is greater than ${minPx - 1} and less than or equal to ${maxPx}`;
  const createInvalidPropCallout = (title, received, expected) => {
    return <Danger>
        <span className="font-bold">
          Invalid <code>{title.toString()}</code> passed!
        </span>
        <br />
        <span className="font-bold">Received: </span>
        {received.toString()}
        <br />
        <span className="font-bold">Expected: </span>
        {expected.toString()}
        {}
      </Danger>;
  };
  const checkValidDimensionValue = value => {
    switch (typeof value) {
      case "string":
      case "number":
        const num = Number(value);
        return Number.isSafeInteger(num) && num >= minPx && num <= maxPx;
      default:
        return false;
    }
  };
  let callouts = [];
  if (height && !checkValidDimensionValue(height)) {
    callouts.push(createInvalidPropCallout("height", height, expectedPx));
  }
  if (width && !checkValidDimensionValue(width)) {
    callouts.push(createInvalidPropCallout("width", width, expectedPx));
  }
  if (callouts.length !== 0) {
    return callouts;
  }
  const heightPx = Number(height);
  const widthPx = Number(width);
  const shouldCenter = center === "true" || center === true ? true : false;
  const shouldNotZoom = noZoom === "true" || noZoom === true ? true : false;
  const images = <>
      <img className="block dark:hidden" src={src} alt={alt} {...height && ({
    height: heightPx
  })} {...width && ({
    width: widthPx
  })} {...(shouldCreateLink || shouldInvert || shouldNotZoom) && ({
    noZoom: "true"
  })} />
      <img className={`hidden dark:block ${shouldInvert ? "invert" : ""}`} src={darkSrc ?? src} alt={darkAlt ?? alt} {...height && ({
    height: heightPx
  })} {...width && ({
    width: widthPx
  })} {...(shouldCreateLink || shouldInvert || shouldNotZoom) && ({
    noZoom: "true"
  })} />
    </>;
  if (shouldCreateLink) {
    if (shouldCenter) {
      return <div style={{
        display: "flex",
        justifyContent: "center"
      }}>
          <a href={href} target={target ?? "_self"}>
            {images}
          </a>
        </div>;
    }
    return <a href={href} target={target ?? "_self"}>
        {images}
      </a>;
  }
  if (shouldCenter) {
    return <div style={{
      display: "flex",
      justifyContent: "center"
    }}>{images}</div>;
  }
  return images;
};

export const Aside = ({type = "note", title = "", icon = "", iconType = "regular", children}) => {
  const asideVariants = ["note", "tip", "caution", "danger"];
  const asideComponents = {
    note: {
      outerStyle: "border-sky-500/20 bg-sky-50/50 dark:border-sky-500/30 dark:bg-sky-500/10",
      innerStyle: "text-sky-900 dark:text-sky-200",
      calloutType: "note",
      icon: <svg width="14" height="14" viewBox="0 0 14 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="w-4 h-4 text-sky-500" aria-label="Note">
          <path fill-rule="evenodd" clip-rule="evenodd" d="M7 1.3C10.14 1.3 12.7 3.86 12.7 7C12.7 10.14 10.14 12.7 7 12.7C5.48908 12.6974 4.0408 12.096 2.97241 11.0276C1.90403 9.9592 1.30264 8.51092 1.3 7C1.3 3.86 3.86 1.3 7 1.3ZM7 0C3.14 0 0 3.14 0 7C0 10.86 3.14 14 7 14C10.86 14 14 10.86 14 7C14 3.14 10.86 0 7 0ZM8 3H6V8H8V3ZM8 9H6V11H8V9Z"></path>
        </svg>
    },
    tip: {
      outerStyle: "border-emerald-500/20 bg-emerald-50/50 dark:border-emerald-500/30 dark:bg-emerald-500/10",
      innerStyle: "text-emerald-900 dark:text-emerald-200",
      calloutType: "tip",
      icon: <svg width="11" height="14" viewBox="0 0 11 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="text-emerald-600 dark:text-emerald-400/80 w-3.5 h-auto" aria-label="Tip">
          <path d="M3.12794 12.4232C3.12794 12.5954 3.1776 12.7634 3.27244 12.907L3.74114 13.6095C3.88471 13.8248 4.21067 14 4.46964 14H6.15606C6.41415 14 6.74017 13.825 6.88373 13.6095L7.3508 12.9073C7.43114 12.7859 7.49705 12.569 7.49705 12.4232L7.50055 11.3513H3.12521L3.12794 12.4232ZM5.31288 0C2.52414 0.00875889 0.5 2.26889 0.5 4.78826C0.5 6.00188 0.949566 7.10829 1.69119 7.95492C2.14321 8.47011 2.84901 9.54727 3.11919 10.4557C3.12005 10.4625 3.12175 10.4698 3.12261 10.4771H7.50342C7.50427 10.4698 7.50598 10.463 7.50684 10.4557C7.77688 9.54727 8.48281 8.47011 8.93484 7.95492C9.67728 7.13181 10.1258 6.02703 10.1258 4.78826C10.1258 2.15486 7.9709 0.000106649 5.31288 0ZM7.94902 7.11267C7.52078 7.60079 6.99082 8.37878 6.6077 9.18794H4.02051C3.63739 8.37878 3.10743 7.60079 2.67947 7.11294C2.11997 6.47551 1.8126 5.63599 1.8126 4.78826C1.8126 3.09829 3.12794 1.31944 5.28827 1.3126C7.2435 1.3126 8.81315 2.88226 8.81315 4.78826C8.81315 5.63599 8.50688 6.47551 7.94902 7.11267ZM4.87534 2.18767C3.66939 2.18767 2.68767 3.16939 2.68767 4.37534C2.68767 4.61719 2.88336 4.81288 3.12521 4.81288C3.36705 4.81288 3.56274 4.61599 3.56274 4.37534C3.56274 3.6515 4.1515 3.06274 4.87534 3.06274C5.11719 3.06274 5.31288 2.86727 5.31288 2.62548C5.31288 2.38369 5.11599 2.18767 4.87534 2.18767Z"></path>
        </svg>
    },
    caution: {
      outerStyle: "border-amber-500/20 bg-amber-50/50 dark:border-amber-500/30 dark:bg-amber-500/10",
      innerStyle: "text-amber-900 dark:text-amber-200",
      calloutType: "warning",
      icon: <svg className="flex-none w-5 h-5 text-amber-400 dark:text-amber-300/80" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" aria-label="Warning">
          <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
        </svg>
    },
    danger: {
      outerStyle: "border-red-500/20 bg-red-50/50 dark:border-red-500/30 dark:bg-red-500/10",
      innerStyle: "text-red-900 dark:text-red-200",
      calloutType: "danger",
      icon: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor" className="text-red-600 dark:text-red-400/80 w-4 h-4" aria-label="Danger">
          <path d="M17.1 292c-12.9-22.3-12.9-49.7 0-72L105.4 67.1c12.9-22.3 36.6-36 62.4-36l176.6 0c25.7 0 49.5 13.7 62.4 36L494.9 220c12.9 22.3 12.9 49.7 0 72L406.6 444.9c-12.9 22.3-36.6 36-62.4 36l-176.6 0c-25.7 0-49.5-13.7-62.4-36L17.1 292zm41.6-48c-4.3 7.4-4.3 16.6 0 24l88.3 152.9c4.3 7.4 12.2 12 20.8 12l176.6 0c8.6 0 16.5-4.6 20.8-12L453.4 268c4.3-7.4 4.3-16.6 0-24L365.1 91.1c-4.3-7.4-12.2-12-20.8-12l-176.6 0c-8.6 0-16.5 4.6-20.8 12L58.6 244zM256 128c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"></path>
        </svg>
    }
  };
  let variant = type;
  let gotInvalidVariant = false;
  if (!asideVariants.includes(type)) {
    gotInvalidVariant = true;
    variant = "danger";
  }
  const iconVariants = ["regular", "solid", "light", "thin", "sharp-solid", "duotone", "brands"];
  if (!iconVariants.includes(iconType)) {
    iconType = "regular";
  }
  return <>
      <div className={`callout my-4 px-5 py-4 overflow-hidden rounded-2xl flex gap-3 border ${asideComponents[variant].outerStyle}`} data-callout-type={asideComponents[variant].calloutType}>
        <div className="mt-0.5 w-4" data-component-part="callout-icon">
          {}
          {icon === "" ? asideComponents[variant].icon : <Icon icon={icon} iconType={iconType} size={14} />}
        </div>
        <div className={`text-sm prose min-w-0 w-full ${asideComponents[variant].innerStyle}`} data-component-part="callout-content">
          {gotInvalidVariant ? <p>
              <span className="font-bold">
                Invalid <code>type</code> passed!
              </span>
              <br />
              <span className="font-bold">Received: </span>
              {type}
              <br />
              <span className="font-bold">Expected one of: </span>
              {asideVariants.join(", ")}
            </p> : <>
              {title && <p className="font-bold">{title}</p>}
              {children}
            </>}
        </div>
      </div>
    </>;
};

<Aside type="note">
  TL-B pages will be moved down in the sidebar in mid-April 2026. Here is the preview of a possible future placement within the "Blockchain foundations" section:

  <Image src="/resources/images/tmp-tlb-light.png" darkSrc="/resources/images/tmp-tlb-dark.png" alt="Preview of a possible future placement of the TL-B language in the sidebar." width={294} height={156} noZoom={true} />
</Aside>

## Unary

The **unary** functional type is commonly used for dynamic sizing in structures such as [`hml_short`](https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L29).

Unary supports two main options:

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
unary_zero$0 = Unary ~0;
unary_succ$1 {n:#} x:(Unary ~n) = Unary ~(n + 1);
```

The `unary_zero` variation is straightforward: if the first bit is `0`, the result of the entire unary deserialization is `0`.

The `unary_succ` variation, however, is more complex: it is loaded recursively and represents a value of `~(n + 1)`. This means it repeatedly calls itself until it reaches `unary_zero`. In other words, the desired value will equal the number of units in a row.

For example, consider the serialization of the bitstring `110`.
The deserialization call chain is as follows:

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
unary_succ$1 -> unary_succ$1 -> unary_zero$0
```

Once `unary_zero` is reached, the value is returned up the call stack, similar to how values are returned in a recursive function.

To better visualize the result, let's trace the return path:

`0 -> ~(0 + 1) -> ~(1 + 1) -> 2`

This shows that the bitstring `110` corresponds to `Unary 2`.

## Hashmap

The Hashmap complex type is used to store dictionaries from FunC smart contract code, i.e., `dict`.

We need a support structure:

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
bit$_ (## 1) = Bit;
```

The following TL-B structures are used to serialize a Hashmap with a fixed key length:

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
hm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n)
          {n = (~m) + l} node:(HashmapNode m X) = Hashmap n X;

hmn_leaf#_ {X:Type} value:X = HashmapNode 0 X;
hmn_fork#_ {n:#} {X:Type} left:^(Hashmap n X)
           right:^(Hashmap n X) = HashmapNode (n + 1) X;

hml_short$0 {m:#} {n:#} len:(Unary ~n) {n <= m} s:(n * Bit) = HmLabel ~n m;
hml_long$10 {m:#} n:(#<= m) s:(n * Bit) = HmLabel ~n m;
hml_same$11 {m:#} v:Bit n:(#<= m) = HmLabel ~n m;

unary_zero$0 = Unary ~0;
unary_succ$1 {n:#} x:(Unary ~n) = Unary ~(n + 1);

hme_empty$0 {n:#} {X:Type} = HashmapE n X;
hme_root$1 {n:#} {X:Type} root:^(Hashmap n X) = HashmapE n X;
```

This root structure is `HashmapE n X` that can be in one of the two possible states: either `hme_empty` or `hme_root`.

### Hashmap parsing example

As an example, consider the following cell, represented in binary form:

```
[1] -> {
  [00] -> {
    [1001000] -> {
      [1010000010000001100001001],
      [1010000010000000001101111]
    },
    [1011100000000000001100001001]
  }
}
```

This cell uses the `HashmapE` structure with an 8-bit key size, and its values are represented using the `uint16` type—that is, `HashmapE 8 uint16`.

The `HashmapE` structure utilizes three distinct key types:

```
1 = 777
17 = 111
128 = 777
```

To parse this Hashmap, we must first determine which structure type to use: either `hme_empty` or `hme_root`. This is decided by identifying the `correct prefix`. The `hme_empty` variation is indicated by a single bit `0` (`hme_empty$0`), while the `hme_root` variation is indicated by a single bit `1` (`hme_root$1`). After reading the first bit, if it is `1` (`1[1]`), we know it is the `hme_root` variation.

Next, we can populate the structure variables with known values. The initial result is:

`hme_root$1 {n:#} {X:Type} root:^(Hashmap 8 uint16) = HashmapE 8 uint16;`

Here, the one-bit prefix is already read. The curly braces `{}` indicate conditions that need not be read. Specifically:

* `{n:#}` indicates that `n` is any `uint32` number.
* `{X:Type}` means that `X` can be any type.

The next portion to read is `root:^(Hashmap 8 uint16)`, where the `^` symbol denotes a link that must be loaded.

```
[00] -> {
    [1001000] -> {
      [1010000010000001100001001],
      [1010000010000000001101111]
    },
    [1011100000000000001100001001]
  }
```

#### Initiating branch parsing

According to our schema, this is the correct `Hashmap 8 uint16` structure. Next, we populate it with known values, resulting in the following:

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
hm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l 8)
          {8 = (~m) + l} node:(HashmapNode m uint16) = Hashmap 8 uint16;
```

As shown above, conditional variables `{l:#}` and `{m:#}` have appeared, but both values are unknown at this stage. After reading the corresponding `label`, we can deduce that `n` is part of the equation `{n = (~m) + l}`. This means we must calculate both `l` and `m`, where the sign indicates the resulting value of `~`.

To determine the value of `l`, we need to load the `label:(HmLabel ~l uint16)` sequence. Below, we outline the 3 basic structural options for `HmLabel`:

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
hml_short$0 {m:#} {n:#} len:(Unary ~n) {n <= m} s:(n * Bit) = HmLabel ~n m;
hml_long$10 {m:#} n:(#<= m) s:(n * Bit) = HmLabel ~n m;
hml_same$11 {m:#} v:Bit n:(#<= m) = HmLabel ~n m;
```

Each option is determined by its corresponding prefix. Our root cell comprises 2 zero bits, displayed as (`2[00]`). Therefore, the only logical option is `hml_short$0`, which starts with a prefix of `0`.

Next, let's fill in the `hml_short` structure with known values:

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
hml_short$0 {m:#} {n:#} len:(Unary ~n) {n <= 8} s:(n * Bit) = HmLabel ~n 8
```

At this point, we don't know the value of `n`. However, since it includes a `~` character, we can calculate it. To do so, we load `len:(Unary ~n)`;  [more about unary here](#unary).

Starting with `2[00]`, only one bit remains after defining the `HmLabel` type.

We load this final bit and observe that its value is `0`, which indicates that the `unary_zero$0` variation is used. This means that the `n` value for the `HmLabel` variation is zero.

Now, we can complete the `hml_short` structure by using the calculated `n` value:

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
hml_short$0 {m:#} {n:#} len:0 {n <= 8} s:(0 * Bit) = HmLabel 0 8
```

We have an empty `HmLabel`, denoted by `s = 0`, which means there is nothing to load.

Next, we complete our structure by incorporating the calculated value of `l`, as follows:

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
hm_edge#_ {n:#} {X:Type} {l:0} {m:#} label:(HmLabel 0 8)
          {8 = (~m) + 0} node:(HashmapNode m uint16) = Hashmap 8 uint16;
```

Now that we have calculated the value of `l`, we can also calculate `m` using the equation `n = (~m) + 0`, which simplifies to `m = n - 0`. Therefore, `m = n = 8`.

With all unknown values determined, we can load the `node:(HashmapNode 8 uint16)`.

Regarding the HashmapNode, we have several options:

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
hmn_leaf#_ {X:Type} value:X = HashmapNode 0 X;
hmn_fork#_ {n:#} {X:Type} left:^(Hashmap n X)
           right:^(Hashmap n X) = HashmapNode (n + 1) X;
```

In this case, we determine the option not by using the prefix but by examining the parameter. Specifically, if `n = 0`, the correct result will be either `hmn_leaf` or `hmn_fork`.
Since, in this example, `n = 8`, we use the `hmn_fork` variation. Now, we can fill in the known values as follows:

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
hmn_fork#_ {n:#} {X:uint16} left:^(Hashmap n uint16)
           right:^(Hashmap n uint16) = HashmapNode (n + 1) uint16;
```

After entering the known values, we must calculate the `HashmapNode (n + 1) uint16`. This means that the resulting value of `n` must be equal to our parameter, i.e., 8. To calculate the local value of `n`, we use the following formula:

`n = (n_local + 1)` -> `n_local = (n - 1)` -> `n_local = (8 - 1)` -> `n_local = 7`.

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
hmn_fork#_ {n:#} {X:uint16} left:^(Hashmap 7 uint16)
           right:^(Hashmap 7 uint16) = HashmapNode (7 + 1) uint16;
```

Now that we know the formula, obtaining the final result is straightforward.
Next, we load the left and right branches, and for each subsequent branch, [the process is repeated](#initiating-branch-parsing).

#### Analyzing loaded hashmap values

Continuing the previous example, let's examine how loading branches work for dictionary values. For instance, given the bitstring: `28[1011100000000000001100001001]`.

The result is once again `hm_edge`, and the next step is to fill in the sequence with the correct known values as follows:

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
hm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l 7)
          {7 = (~m) + l} node:(HashmapNode m uint16) = Hashmap 7 uint16;
```

Next, the `HmLabel` response is loaded using the `HmLabel` variation, as the prefix is `10`.

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
hml_long$10 {m:#} n:(#<= m) s:(n * Bit) = HmLabel ~n m;
```

Now, let's fill in the sequence:

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
hml_long$10 {m:#} n:(#<= 7) s:(n * Bit) = HmLabel ~n 7;
```

The new construction, `n:(#<= 7)`, clearly denotes a sizing value that corresponds to the number 7, which is, in fact, the `log2` of the number `+ 1`. For simplicity, however, we can count the number of bits required to represent the number 7.
In binary, the number 7 is written as `111`, which means 3 bits are needed. Therefore, the value for `n = 3`.

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
hml_long$10 {m:#} n:(## 3) s:(n * Bit) = HmLabel ~n 7;
```

Next, we load `n` into the sequence, which results in `111`. As noted earlier, this coincidentally equals 7. Then, we load `s` into the sequence, which consists of 7 bits: `0000000`. Remember, `s` is part of the key.

Afterward, we return to the top of the sequence and fill in the resulting `l`:

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
hm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel 7 7)
          {7 = (~m) + 7} node:(HashmapNode m uint16) = Hashmap 7 uint16;
```

Then we calculate the value of `m`: `m = 7 - 7`, which gives us `m = 0`.
Since `m = 0`, the structure is ideally suited for use with a `HashmapNode`:

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
hmn_leaf#_ {X:Type} value:X = HashmapNode 0 X;
```

Next, we substitute our `uint16` type and load the value. When converted to decimal, the remaining 16 bits, `0000001100001001`, give us the value `777`.

Now, let's restore the key. We need to combine all the parts of the key that were computed previously. Each related key part is combined with one bit, depending on the branch type used. A `1` bit is added for the right branch, and a `0` bit is added for the left branch. If a full `HmLabel` exists above, its bits are added to the key.

In this specific case, 7 bits are taken from the `HmLabel 0000000`, and a `1` bit is added before the sequence of zeros because the value was obtained from the right branch. The final result is 8 bits, or `10000000`, which means the key value equals `128`.

## Other hashmap types

Now that we have discussed hashmaps and how to load the standardized Hashmap type, let's explain how the additional hashmap types function.

### HashmapAugE

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
ahm_edge#_ {n:#} {X:Type} {Y:Type} {l:#} {m:#}
  label:(HmLabel ~l n) {n = (~m) + l}
  node:(HashmapAugNode m X Y) = HashmapAug n X Y;

ahmn_leaf#_ {X:Type} {Y:Type} extra:Y value:X = HashmapAugNode 0 X Y;

ahmn_fork#_ {n:#} {X:Type} {Y:Type} left:^(HashmapAug n X Y)
  right:^(HashmapAug n X Y) extra:Y = HashmapAugNode (n + 1) X Y;

ahme_empty$0 {n:#} {X:Type} {Y:Type} extra:Y
          = HashmapAugE n X Y;

ahme_root$1 {n:#} {X:Type} {Y:Type} root:^(HashmapAug n X Y)
  extra:Y = HashmapAugE n X Y;
```

The primary distinction between the `HashmapAugE` and the regular `Hashmap` is the presence of an `extra:Y` field in each node (not just in leaf nodes containing values).

### PfxHashmap

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
phm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n)
           {n = (~m) + l} node:(PfxHashmapNode m X)
           = PfxHashmap n X;

phmn_leaf$0 {n:#} {X:Type} value:X = PfxHashmapNode n X;
phmn_fork$1 {n:#} {X:Type} left:^(PfxHashmap n X)
            right:^(PfxHashmap n X) = PfxHashmapNode (n + 1) X;

phme_empty$0 {n:#} {X:Type} = PfxHashmapE n X;
phme_root$1 {n:#} {X:Type} root:^(PfxHashmap n X)
            = PfxHashmapE n X;
```

The key difference between the `PfxHashmap` and the regular `Hashmap` lies in its ability to store keys of varying lengths due to the inclusion of the `phmn_leaf$0` and `phmn_fork$1` nodes.

### VarHashmap

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
vhm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n)
           {n = (~m) + l} node:(VarHashmapNode m X)
           = VarHashmap n X;
vhmn_leaf$00 {n:#} {X:Type} value:X = VarHashmapNode n X;
vhmn_fork$01 {n:#} {X:Type} left:^(VarHashmap n X)
             right:^(VarHashmap n X) value:(Maybe X)
             = VarHashmapNode (n + 1) X;
vhmn_cont$1 {n:#} {X:Type} branch:Bit child:^(VarHashmap n X)
            value:X = VarHashmapNode (n + 1) X;

// nothing$0 {X:Type} = Maybe X;
// just$1 {X:Type} value:X = Maybe X;

vhme_empty$0 {n:#} {X:Type} = VarHashmapE n X;
vhme_root$1 {n:#} {X:Type} root:^(VarHashmap n X)
            = VarHashmapE n X;
```

Similarly, the main difference between the `VarHashmap` and the regular `Hashmap` is its ability to accommodate different key lengths, attributed to the presence of the `vhmn_leaf$00` and `vhmn_fork$01` nodes. Additionally, the `VarHashmap` can form a common value prefix (child map) by utilizing the `vhmn_cont$1` node.

## BinTree

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
bta_leaf$0 {X:Type} {Y:Type} extra:Y leaf:X = BinTreeAug X Y;
bta_fork$1 {X:Type} {Y:Type} left:^(BinTreeAug X Y)
           right:^(BinTreeAug X Y) extra:Y = BinTreeAug X Y;
```

The binary tree key generation mechanism operates similarly to the standardized Hashmap framework but without using labels; instead, it relies on branch prefixes.

## VmTuple

```tlb theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
vm_tupref_nil$_ = VmTupleRef 0;
vm_tupref_single$_ entry:^VmStackValue = VmTupleRef 1;
vm_tupref_any$_ {n:#} ref:^(VmTuple (n + 2)) = VmTupleRef (n + 2);
vm_tuple_nil$_ = VmTuple 0;
vm_tuple_tcons$_ {n:#} head:(VmTupleRef n) tail:^VmStackValue = VmTuple (n + 1);
vm_stk_tuple#07 len:(## 16) data:(VmTuple len) = VmStackValue;
```

Tuple is an *actual* tuple of elements that is written in FunC as `[a, b, c]`. VmTuple is used internally in [VmStack](https://github.com/ton-blockchain/ton/blob/05bea13375448a401d8e07c6132b7f709f5e3a32/crypto/block/block.tlb#L862)
for tuple serialization, which is outputted from a contract's methods.

Let's consider a serialization of the following tuple: \[44, `Cell{00B5BD3EB0}`, -1].
When disassembled, it looks as follows:

```
[070003] -> {
   [] -> {
      [01000000000000002C],
      [03] -> {
         [00B5BD3EB0]
      }
   },
   [01FFFFFFFFFFFFFFFF]
}
```

The root cell will be parsed using the constructor `vm_stk_tuple`, since its prefix is `0x07`. The next 2 bytes are `len:(## 16)` that equals `0003 == 3`.

Next comes `data:(VmTuple 3)`. There are two variants of parsing of `VmTuple`: `VmTuple (n + 1)` and  `VmTuple 0`. Since `n > 0`, `VmTuple (n + 1)` is used.

The first field is `head:(VmTupleRef 2=(3-1))`. There are three variants of parsing: `0`, `1`, and `n+2`. Our `n` equals `2`, so the third variant is used.

The only field is `ref:^(VmTuple (n + 2))`, i.e. `ref:^(VmTuple 2)`.

Our `n` equals `2`, so the variant `(n + 1)` is chosen. Next read `head:(VmTupleRef n)` -> `head:(VmTupleRef 1=(2-1))`. In `VmTupleRef 1`, there is only one field: `entry:^VmStackValue`.
Essentially, this field is the value,`01 000000000000002C`.

We read the `head` and reached the end, now we go in the opposite direction and read the `tail:^VmStackValue`. Going up, the first tail is `03` with a link to the cell.
`0x03` on the stack means a cell; we just read this link and save it as the value,`00B5BD3EB0`. Then go up a level and read another `tail`, this is `01 FFFFFFFFFFFFFFFF`, i.e., int equal to `-1`.

After we have reached the end, the parsing is completed, and we add all the received elements into the array in the order in which we received them.

## References

[Link to the original article](https://github.com/xssnick/ton-deep-doc/blob/master/TL-B.md) - *Oleg Baranov.*
