tip: 24
title: Tangle Block
description: Generalization of the Tangle transaction concept
author: Wolfgang Welz (@Wollac) 
discussions-to: https://github.com/iotaledger/tips/pull/55
status: Active
type: Standards
layer: Core
replaces: 6
created: 2022-01-24

Abstract

The Tangle is the graph data structure behind IOTA. In the legacy IOTA protocol, the vertices of the Tangle are represented by transactions. This document proposes an abstraction of this idea where the vertices are generalized blocks, which then contain the transactions or other structures that are processed by the IOTA protocol. Just as before, each block directly approves other blocks, which are known as parents.

The blocks can contain payloads. These are core payloads that will be processed by all nodes as part of the IOTA protocol. Some payloads may have other nested payloads embedded inside. Hence, parsing is done layer by layer.

Motivation

To better understand this layered design, consider the Internet Protocol (IP), for example: There is an Ethernet frame that contains an IP payload. This in turn contains a TCP packet that encapsulates an HTTP payload. Each layer has a certain responsibility and once this responsibility is completed, we move on to the next layer.

The same is true with how blocks are parsed. The outer layer of the block enables the mapping of the block to a vertex in the Tangle and allows us to perform some basic validation. The next layer may be a transaction that mutates the ledger state, and one layer further may provide some extra functionality on the transactions to be used by applications.

By making it possible to add and exchange payloads, an architecture is being created that can easily be extended to accommodate future needs.

Specification

Block ID

The Block ID is the BLAKE2b-256 hash of the entire serialized block.

Serialized Layout

The following table describes the serialization of a Block following the notation from TIP-21:

Name Type Description
Protocol Version uint8 Protocol version number of the block.
Parents Count uint8 The number of blocks that are directly approved.
Parents anyOf
Parent
References another directly approved block.
Name Type Description
Block ID ByteArray[32] The Block ID of the parent.
Payload Length uint32 The length of the following payload in bytes. A length of 0 means no payload will be attached.
Payload optOneOf
Generic Payload
An outline of a generic payload
Name Type Description
Payload Type uint32 The type of the payload. It will instruct the node how to parse the fields that follow.
Data Fields ANY A sequence of fields, where the structure depends on Payload Type.
Nonce uint64 The nonce which lets this block fulfill the PoW requirement.

Syntactic validation

The Tangle can only contain syntactically valid blocks. Invalid blocks must be rejected by the node. The following criteria defines whether the block passes the syntactic validation:

  • The total length of the serialized block must not exceed Max Block Length.
  • Protocol Version must match the Protocol Version config parameter of the node.
  • Parents:
    • Parents Count must be at least 1 and not larger than Max Parents Count.
    • Parents must be sorted in lexicographical order.
    • Each Block ID must be unique.
  • Payload (if present):
    • Payload Type must match one of the values described under Payloads.
    • Data Fields must be correctly parsable in the context of the Payload Type.
    • The payload itself must pass syntactic validation.
  • Nonce must be valid with respect to the PoW condition described under Payloads. The PoW score itself is computed according to TIP-12.
  • There must be no trailing bytes after all block fields have been parsed.

PoW validation

The PoW that needs to be performed for each block protects the network against denial-of-service attacks where in a short time too many blocks are issued for the nodes to process. As the processing time of a block heavily depends on the contained payload, the PoW check can also depend on the Payload Type and is described under Payloads. It is important to note, that the actual parsing and validating of a payload can be computationally expensive. Thus, it is recommended to first parse the block with all its fields including Payload Type (but not parsing or validating the actual payload Data Fields). Now, simple syntactic validation steps – including PoW validation – can be performed and invalid blocks already filtered out before the payload is validated. With this approach, payload-based PoW validation is not significantly more expensive than payload-agnostic validation.

Payloads

While blocks without a payload, i.e. Payload Length set to zero, are valid, such blocks do not contain any information. As such, blocks usually contain a payload. The detailed specification of each payload type is out of scope of this TIP. The following table lists all currently specified payloads that can be part of a block and links to their specification:

Payload NameType ValueTIPPoW Condition
No Payload--PoW score ≥ Min PoW Score
Tagged Data5TIP-23PoW score ≥ Min PoW Score
Transaction6TIP-20PoW score ≥ Min PoW Score
Milestone7TIP-29nonce = 0x0000000000000000

Example

Below is the full serialization of a valid block with a Tagged Data Payload. The tag is the "IOTA" ASCII string and the data is the "hello world" ASCII string. Bytes are expressed as hexadecimal numbers.

  • Protocol Version (1-byte): 02 (2)
  • Parents Count (1-byte): 02 (2)
  • Parents (64-byte):
    • 210fc7bb818639ac48a4c6afa2f1581a8b9525e20fda68927f2b2ff836f73578
    • db0fa54c29f7fd928d92ca43f193dee47f591549f597a811c8fa67ab031ebd9c
  • Payload Length (4-byte): 18000000 (24)
  • Payload (24-byte):
    • Payload Type (4-byte): 05000000 (5)
    • Tag (5-byte):
      • Length (1-byte): 04 (4)
      • Tag (4-byte): 494f5441 ("IOTA")
    • Data (15-byte):
      • Length (4-byte): 0b000000 (11)
      • Data (11-byte): 68656c6c6f20776f726c64 ("hello world")
  • Nonce (8-byte): ce6d000000000000 (28110)

Rationale and alternatives

Instead of creating a layered approach, we could have simply created a flat transaction block that is tailored to mutate the ledger state, and try to fit all the use cases there. For example, with the tagged data use case, we could have filled some section of the transaction with that particular data. Then, this transaction would not correspond to a ledger mutation but instead only carry data.

This approach seems less extensible. It might have made sense if we had wanted to build a protocol that is just for ledger mutating transactions, but we want to be able to extend the protocol to do more than that.

Copyright

Copyright and related rights waived via CC0.