Skip to main content
Version: IOTA

Chrysalis Details

Seed and Addresses​

In Chrysalis, all ternary conversions apart from PoW have been removed which results in a better, faster developer experience. Additionally, the WOTS-Signature has been replaced by an Ed25519 signature scheme. This means that you can now use an address multiple times to send and receive coins.

With these changes, and the further adoption of industry standards, both seeds and addresses look completely different in Chrysalis.

IOTA 1.0 address:

UDYXTZBE9GZGPM9SSQV9LTZNDLJIZMPUVVXYXFYVBLIEUHLSEWFTKZZLXYRHHWVQV9MNNX9KZC9D9UZWZRGJMIGPDW

IOTA 1.5 (Chrysalis) address (bech32 standard):

Mainnet with iota.

iota1qpw6k49dedaxrt854rau02talgfshgt0jlm5w8x9nk5ts6f5x5m759nh2ml

Devnet with atoi.

atoi1qpw6k49dedaxrt854rau02talgfshgt0jlm5w8x9nk5ts6f5x5m75zaxtpj

IOTA 1.5 Address Anatomy​

The current IOTA address is based on the Ed25519 signature scheme and it is usually represented by the Bech32 (checksummed base32) format string of 64 characters or hex format:

We can break down the address iota1qpw6k49dedaxrt854rau02talgfshgt0jlm5w8x9nk5ts6f5x5m759nh2ml into three distinguishable parts:

human-readable idseparatordatachecksum
iota | atoi148 bytes [0..9a..z]6 characters [0..9a..z]
iota1qpw6k49dedaxrt854rau02talgfshgt0jlm5w8x9nk5ts6f5x5m759nh2ml

For further reference, please see our Protocol-rfc#0020 - Bech32 Address Format page.

Seed​

With the updated wallet library, developers do not need to use a self-generated seed. By default, the seed is created and stored in Stronghold, our in-house built security enclave. It is not possible to extract the seed from Stronghold for security purposes. Stronghold uses encrypted snapshots that can easily be backed up and securely shared between devices. These snapshots are then further secured with a password.

More information about IOTA Wallet Library is available on the Wallet docs page or in the Exchange guide, which is mainly focuses on value transactions.

note

It is highly recommended you do NOT use online seed generators at all. The seed is the only key to the given funds.

A root of the Ed25519 signature scheme is a 32-byte (256-bit) uniformly randomly generated seed based on which all private keys and corresponding addresses are generated. A seed may be represented by a string of 64 characters using [0-9a-f] alphabet (32 bytes encoded in hexadecimal).

The seed can be, for example, generated using the SHA256 algorithm on some random input generated by cryptographically secure pseudo-random generator, such as os.urandom().

Seed examples (a single seed per line):

4892e2265c45734d07f220294b1697244a8ab5beb38ba9a7d57aeebf36b6e84a
37c4aab22a5883595dbc77907c1626c1be39d104df39c5d5708423c0286aea89
e94346bce41402155ef120e2525fad2d0bf30b10a89e4b93fd8471df1e6a0981
...

In modern wallet implementations, such as our wallet.rs library and firefly wallet, the seed is usually generated from a seed mnemonic (seed phrase), using the BIP39 standard, for better memorization or to be stored by humans. It is based on a randomly generated list of english words and is later used to generate the seed. Either way, the seed is a root for all generated private keys and addresses.

For further reference, please see the Protocol-rfc#0010 - Mnemonic Seed page.

Address/Key Space​

As mentioned above, IOTA 1.5 embraced some existing industry standards, which is apparent during an address generation process. This included the BIP32 standard that describes an approach to Hierarchical Deterministic Wallets which was further improved by BIP44.

These standards define a tree structure as a base for address and key space generation which is represented by a derivation path:

m / purpose / coin_type / account / change / address_index
  • m: a master node (seed).
  • purpose: constant which is {44}.
  • coin_type: a constant set for each crypto currency. IOTA = 4218, for instance.
  • account: account index. Zero-based increasing int. This level splits the address/key space into independent branches (ex. user identities) which each has its own set of addresses/keys.
  • change: change index which is {0, 1}, also known as wallet chain.
    There are two independent chain of addresses/keys. 0 is reserved for public addresses (for coin receival) and 1 is reserved for internal (also known as change) addresses to which a transaction change is returned. In comparison to IOTA 1.0, IOTA 1.5 is fine with address reuse, and so it is, technically speaking, valid to return transaction change to the same originating address. It is up to developers whether to leverage it or not. iota.rs library and its sibling wallet.rs help with either scenario.
  • address_index: address index. Zero-based increasing int that indicates an address index.

As outlined, there is a large address/key space that is secured by a single seed.

And there are a few additional things to note:

  • Each level defines a completely different subtree (subspace) of addresses/keys and those are never mixed up.
  • The hierarchy is ready to "absorb" addresses/keys for different coins at the same time (coin_type) and all those coins are secured by the same seed.
  • There may also be other purposes in the future. However, we should consider it a single purpose as of now. The constant 44 stands for BIP44.
  • The standard was agreed upon by different crypto communities, although not all derivation path components are always in active use. For example, account is not always actively leveraged across crypto space (if this is a case then there is usually account=0 used).
  • Using different accounts may be useful to split addresses/key into some independent spaces and it is up to developers to implement.
note

Having many different accounts may have a negative impact on performance while in the account discovery phase. So, if you are after using multiple, different accounts then you may be interested in our stateful library wallet.rs that incorporates all business logic needed to efficiently manage independent accounts. Additionally, our exchange guide provides some useful tips on how different accounts may be leveraged.

Address Generation

So in case of Chrysalis, the derivation path of address/key space is [seed]/44/4218/{int}/{0,1}/{int}:

  • The levels purpose and coin_type are given.
  • The rest levels are up to developers to integrate, specifically seed, account, wallet_chain, and address_index.

For further reference, please see our Protocol-rfc#0003 - Signature Scheme page.

Messages, Payloads, and Transactions​

In comparison to the original IOTA 1.0, Chrysalis also introduced some fundamental changes to the underlying data structures. The original concept of transactions and bundles is gone and has been replaced by a concept of messages and payloads.

A message is a data structure that is actually being broadcast in the Chrysalis network and represents a node (vertex) in the Tangle graph.

It refers to at least 1 (2 is recommended) and up to 8 previous messages and once a message is attached to the Tangle and approved by a milestone, the Tangle structure ensures the content of the message is unaltered. Every message is referenced by a message_id which is based on a hash algorithm (Blake2b256) of binary content of the message. It also includes previous Tangle messages as its parents which means it is not possible to alter the given message without altering previous messages in the Tangle.

The message is an atomic unit that is confirmed by the network as a whole.

info

IOTA is no longer based on ternary. IOTA 1.5 uses binary to encode and broadcast all underlying data entities.

A message can be up to 32 kb in size and can hold variable sets of information called payloads. The number of payloads a single message can encapsulate is not given. Even a message without a payload is completely valid and can be broadcast. The message itself does not include any timestamp; a message timestamp is derived from an acceptance of the given message by the Tangle network.

For further reference, please see our TIP#0006 - Message page.

A payload represents a layer of concern. Some payloads may change the state of the ledger (ex. SignedTransactions) and some may provide extra features to some specific applications and business use cases (ex. IndexationPayload).

There are already implemented core payloads, such as SignedTransaction, MilestonePayload, and IndexationPayload but the message and payload definition is generic enough to incorporate any future payload(s) the community agrees upon.

For further reference, please see our TIP#0018 - Transaction Payload page.

The IOTA network ensures the outer structure of the message itself is valid and strictly complies with network consensus protocol. However, the inner structure is very flexible, future-proof, and offers network extensibility.

Messages in the Tangle

The current Chrysalis network incorporates the following core payloads:

  • SignedTransaction: a payload that describes UTXO transactions that are the cornerstones of value-based transfers in the IOTA network. Via this payload, a message can also be cryptographically signed.
  • MilestonePayload: a payload that is emitted by the Coordinator.
  • IndexationPayload: a payload that enables the addition of an index to the encapsulating message, as well as some arbitrary data. The given index can be later used to search the message(s).

In comparison to IOTA 1.0, a message itself is not directly related to the IOTA address while broadcasting to the Chrysalis network. Such messages are referenced using the so-called message_id. Messages are indirectly related to IOTA addresses via SignedTransaction payload, specifically the UTXO section.

Unspent Transaction Output (UTXO)​

Originally, IOTA 1.0 used an account-based model for tracking individual iota tokens: each IOTA address held a number of tokens and the aggregated number of tokens from all IOTA addresses was equal to the total supply.

In contrast, Chrysalis uses the unspent transaction output model, or UTXO. It is based on an idea to track unspent amounts of tokens via a data structure called output.

Below is a simplified analogy of how the UTXO works:

  • There are 100 tokens recorded in the ledger as Output A and this output belongs to Alice. So, the initial state of the ledger: Output A = 100 tokens.
  • Alice sends 20 tokens to Paul, 30 tokens to Linda, and keeps 50 tokens at her disposal.
  • Her 100 tokens are recorded as Output A so she has to divide (spent) tokens and create three new outputs:
    Output B with 20 tokens that goes to Paul, Output C with 30 tokens that goes to Linda, and finally Output D with the rest of the 50 tokens that she kept for herself.
  • Original Output A was completely spent and cannot be used any more. It has been spent and so becomes irrelevant to ledger state.
  • New state of ledger:
    • Output B = 20 tokens.
    • Output C = 30 tokens.
    • Output D = 50 tokens.
  • The total supply remains the same, the number of outputs differs, and some outputs were replaced by other outputs in the process.

Unspent Transaction Output

The key takeaway of the outlined process above is the fact that each unique output can be spent only once. Once the given output is spent, it cannot be used any more and is irrelevant in regards to the ledger state.

So even if Alice still wants to keep the remaining tokens at her fingertips, those tokens have to be moved to a completely new output that can be, for instance, still tied to Alice's same IOTA address as before.

Every output also stores information about an IOTA address to which it is coupled with. So addresses and tokens are indirectly coupled via outputs. Basically, the sum of outputs and their amounts under the given address is a balance of the given address, that is, the number of tokens the given address can spend. And the sum of all unspent outputs and their amounts is equal to the total supply.

Outputs are being broadcasted and encapsulated in a message as a part of SignedTransaction payload.

Selected Message Payloads​

Currently, there are two commonly used message payloads, IndexationPayload and SignedTransaction which can be combined as needed.

For further reference, please see our TIP#0007 - Transaction Payload page.

IndexationPayload​

IndexationPayload is a payload type that can be used to attach arbitrary data and key index to a message. When this particular payload is leveraged, then a message and related data entity can be searched via key index in addition to a message_id.

SignedTransaction​

SignedTransaction is a payload type that is used to transfer value-based messages as UTXO. It changes the ledger state as old outputs are being spent (replaced) and new outputs are being created.

Each SignedTransaction includes the following set of information:

  • inputs - a list of valid outputs that should be used to fund the given transaction. Outputs are uniquely referenced via a previous transaction_id and inner index. At least one output has to be given with enough balance to source all outputs of the given message.
  • outputs - a list of IOTA address(es) and related amount(s) the input outputs should be split among. Based on this information, new UTXO outputs are being created.
  • unlock_blocks - it includes a transaction signature(s) (currently based on Ed25519 scheme) that proves token ownership based on a valid seed.

Dust Protection​

Since IOTA is feeless and has the ability to send microtransactions, attackers could use this to spam the network with very low value transactions, which we call dust. To avoid this, we only allow microtransaction below 1Mi (dust) of IOTA tokens to another address if you already have at least 1Mi as a dust allowance output on that address. The number of allowed dust outputs on an address is the amount of the dust allowance outputs divided by 100,000 and rounded down, that is, 10 outputs for each 1 Mi deposited, with a maximum of 100 dust outputs in total.

note

In the UTXO model, each node in the network needs to keep track of all the currently unspent outputs. When the number of outputs becomes too large, it can cause performance and memory issues. The RFC below proposes a new protocol rule regarding the processing of outputs where they transfer a very small amount of IOTA’s so-called dust outputs. Dust outputs are only allowed when they are backed up by a certain deposit on the receiving address. This limits the amount of dust outputs, thus making it expensive to proliferate dust. Since a receiver must make a deposit, the protocol makes receiving dust an opt-in feature.

For further reference, please see our TIP#0015 - Dust Protection page.

Up to 8 Parents​

With IOTA 1.0, you always had to reference 2 parent transactions. With Chrysalis, we introduced a more dynamic number of parent nodes where you can reference up to 8 parents. We recommend you reference at least 2 unique parents at all times for the best possible results.

For further reference, please see our TIP#0008 - Message page.