> ## 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/tep-examples",
  "feedback": "Description of the issue"
}
```

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

</AgentInstructions>

# TEP 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>

The purpose of this article is to explain common TL-B examples that you encounter when reading our standards.

## NFT

The [NFT collection and each NFT item](/standard/tokens/nft/overview) are separate smart contracts in TON Blockchain. Each specific implementation must
comply with the [TEP 0062](https://github.com/ton-blockchain/TEPs/blob/master/text/0062-nft-standard.md) standard.

When reading this TEP, you encounter a TL-B schema that describes the serialization of a
message that transfers the rights of a given NFT item to another user.

```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"]}}
transfer#5fcc3d14 query_id:uint64 new_owner:MsgAddress
response_destination:MsgAddress custom_payload:(Maybe ^Cell)
forward_amount:(VarUInteger 16) forward_payload:(Either Cell ^Cell)
= InternalMsgBody;
```

Thus, a cell corresponds to this TL-B scheme if it sequentially contains:

* 32-bits that represents the hexadecimal number `0x5fcc3d14`.
* An arbitrary request number that is an unsigned 64-bit integer in binary form.
* An address of the new owner of the NFT item that is a sequence of bits corresponding to the
  `MsgAddress` TL-B scheme (see the [address](/foundations/addresses/overview) page for details).
* An address where to send a response with confirmation of a successful transfer and the rest of the incoming message coins. It is
  serialized as the previous field.
* Optional custom data. For the description of how the `Maybe` type works,
  see [simple examples page](/languages/tl-b/simple-examples).
* The amount of nanotons to be sent to the new owner. For the explanation of how `VarUInteger n` works, see
  [simple examples page](/languages/tl-b/simple-examples).
* The optional custom data that should be sent to the new owner. For the description of how the `Either` type works,
  see [simple examples page](/languages/tl-b/simple-examples).

The knowledge gained from analyzing the TL-B schemes above is sufficient to understand all the schemes that
you will encounter when analyzing the [Jetton](https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md#summary),
[NFT Royalty](https://github.com/ton-blockchain/TEPs/blob/master/text/0066-nft-royalty-standard.md),
[SBT](https://github.com/ton-blockchain/TEPs/blob/master/text/0085-sbt-standard.md),
[Jetton wallet](https://github.com/ton-blockchain/TEPs/blob/master/text/0089-jetton-wallet-discovery.md) standards.

## Jetton

It was mentioned above that an example of the TL-B scheme related to NFTs is sufficient to understand all schemes related to Jettons.
However, as Jetton transactions are among the most common on the TON blockchain, we will analyze relevant schemes separately.

A standard interface for *Jettons (TON fungible tokens)* is specified in [TEP 0074](https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md).

To transfer tokens from one wallet to another, it is required to send a message to the sender's
jetton-wallet corresponding to the following TL-B scheme. For the description of how data types `VarUInteger n`, `Maybe`, and `Either` work, see
[simple examples page](/languages/tl-b/simple-examples).

```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"]}}
transfer#0f8a7ea5 query_id:uint64 amount:(VarUInteger 16) destination:MsgAddress
                 response_destination:MsgAddress custom_payload:(Maybe ^Cell)
                 forward_ton_amount:(VarUInteger 16) forward_payload:(Either Cell ^Cell)
                 = InternalMsgBody;
```

Thus, a cell corresponds to this TL-B scheme if it sequentially contains:

* 32-bits that represents the hexadecimal number `0x0f8a7ea5`.
* An arbitrary request number that is an unsigned 64-bit integer in binary form.
* An amount of transferred jettons in elementary units.
* An address of the new owner of jettons, which is a sequence of bits corresponding to the
  `MsgAddress` TL-B scheme (see the [address](/foundations/addresses/overview) page for details).
* An address to which to send a response with confirmation of a successful transfer and the rest of the incoming message coins. It is
  serialized as the previous field.
* Optional custom data.
* The amount of nanotons to be sent to the new owner.
* Optional custom data that should be sent to the `destination` address.

If `forward_amount > 0`, the receiver's jetton-wallet should send a message to the `destination` address with
`forward_amount` nanotons attached and with the following TL-B schema.

```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"]}}
transfer_notification#7362d09c query_id:uint64 amount:(VarUInteger 16)
                              sender:MsgAddress forward_payload:(Either Cell ^Cell)
                              = InternalMsgBody;
```

Thus, a cell corresponds to this TL-B scheme if it sequentially contains:

* 32 bits that represent the hexadecimal number `0x7362d09c`.
* An arbitrary request number that is an unsigned 64-bit integer in binary form.
* An amount of transferred jettons in elementary units.
* An address of the previous owner of transferred jettons.
* Optional custom data that should be sent to the destination address.

The rest of the TL-B schemes corresponding to the Jettons can be examined in a similar way.

## DNS

*TON DNS* is a service for translating human-readable domain names (such as test.ton or mysite.temp.ton) into TON smart contract addresses.
It is specified in [TEP 0081](https://github.com/ton-blockchain/TEPs/blob/master/text/0081-dns-standard.md).

Let's consider TL-B schemes of *DNS Records* 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"]}}
proto_http#4854 = Protocol;

proto_list_nil$0 = ProtoList;
proto_list_next$1 head:Protocol tail:ProtoList = ProtoList;


cap_is_wallet#2177 = SmcCapability;

cap_list_nil$0 = SmcCapList;
cap_list_next$1 head:SmcCapability tail:SmcCapList = SmcCapList;

dns_smc_address#9fd3 smc_addr:MsgAddressInt flags:(## 8) { flags <= 1 }
  cap_list:flags . 0?SmcCapList = DNSRecord;
dns_next_resolver#ba93 resolver:MsgAddressInt = DNSRecord;
dns_adnl_address#ad01 adnl_addr:bits256 flags:(## 8) { flags <= 1 }
  proto_list:flags . 0?ProtoList = DNSRecord;
dns_storage_address#7473 bag_id:bits256 = DNSRecord;

_ (HashmapE 256 ^DNSRecord) = DNS_RecordSet;
```

The first thing you need to pay attention to: how lists of arbitrary length are formed.
For instance, `ProtoList` combinator consists of two constructors: `proto_list_nil` that indicates the end of a list and
`proto_list_next` that indicates that there is a record of protocol followed by the next record or the end of a list.

When deserializing data of the `ProtoList` type, the prefix `1` or `0` is read first. If the prefix is `0`, then we have reached the end
of the list and there is nothing more to read. Otherwise, the protocol entry is read, followed by a prefix
indicating whether the next protocol entry will be followed or the end of the list. The same applies to the `SmcCapList` type.

Next, pay attention to the `DNSRecord` type. The constructors `dns_next_resolver` and `dns_storage_address` are simple.
Let's deal with the `dns_adnl_address`constructor:

* first comes the `0xad01` prefix;
* then 256 bits representing ADNL address;
* next, the 8-bit flag, which is currently bounded by `1`;
* finally, if the first bit of the flag is `1`, the serialization continued with `ProtoList` type;
* if the first bit of the flag is `0`, then serialization is completed.

The serialization of `dns_smc_address` follows the same logic.
