tip: 34
title: Wotsicide (Stardust)
description: Define migration from legacy W-OTS addresses to post-Chrysalis network
author: Luca Moser (@luca-moser) , Wolfgang Welz (@Wollac) 
discussions-to: https://github.com/iotaledger/tips/pull/74
status: Obsolete
type: Standards
layer: Core
created: 2022-04-21
replaces: 17

Abstract

This TIP defines the migration process of funds using the legacy Winternitz one-time signature scheme (W-OTS) to the current network.

Motivation

With Chrysalis, the IOTA protocol moved away from W-OTS as it created a number of security, protocol and UX issues:

  • W-OTS signatures are big and make up a disproportionate amount of data of a transaction.
  • It is only safe to spend from an address once. Spending multiple times from the same address reveals random parts of the private key, making any subsequent transfers (other than the first) susceptible to thefts.
  • As a prevention mechanism to stop users from spending multiple times from the same address, nodes have to keep an ever growing list of those addresses.

As the current protocol no longer supports W-OTS addresses, there needs to be a migration process from W-OTS addresses to Ed25519 addresses. To make this migration as smooth as possible, this TIP proposes a mechanism allowing users to migrate their funds at any time with only a small delay until they are available on the new network.

This TIP outlines the detailed architecture of how users will be able to migrate their funds and specifies the underlying components and their purposes.

Specification

On a high-level the migration process works as follows:

  • Users create migration bundles in the legacy network which target their Ed25519 address in the new network.
  • The Coordinator then mints those migrated funds in so-called Receipt Milestone Option which are placed within milestones on the new network.
  • Nodes in the new network evaluate receipts and book the corresponding funds by creating new UTXOs in the ledger.

Legacy network

Migration bundle

The node software no longer books ledger mutations to non-migration addresses. This means that users are incentivized to migrate their funds as they want to use their tokens. See this document on what migration addresses are.

A migration bundle is defined as follows:

  • It contains exactly one output transaction of which the destination address is a valid migration address and is positioned as the tail transaction within the bundle. The output transaction value is at least 1'000'000 tokens.
  • It does not contain any zero-value transactions which do not hold signature fragments. This means that transactions other than the tail transaction must always be part of an input.
  • Input transactions must not use migration addresses.

The node will only use tail transactions of migration or milestone bundles for the tip-pool. This means that past cones referenced by a milestone will only include such bundles.

The legacy node software is updated with an additional HTTP API command called getWhiteFlagConfirmation which given request data in the following form:

{
    "command": "getWhiteFlagConfirmation",
    "milestoneIndex": 1434593
}

returns data for the given milestone white-flag confirmation:

{
    "milestoneBundle": [
        "SDGKWKJAG...",
        "WNGHJWIFA...",
        "DSIEWSDIG..."
    ],
    "includedBundles": [
        [
            "SKRGI9DFS...",
            "NBJSKRJGW...",
            "ITRUQORTZ..."
        ],
        [
            "OTIDFJKSD...",
            "BNSUGRWER...",
            "OPRGJSDFJ..."
        ],
        ...
    ]
}

where milestoneBundle contains the milestone bundle trytes and includedBundles is an array of tryte arrays of included bundles in the same DFS order as the white-flag confirmation. Trytes within a bundle "array" are sorted from currentIndex = 0 ascending to the lastIndex.

This HTTP API command allows interested parties to verify which migration bundles were confirmed by a given milestone.

Milestone inclusion Merkle proof

The Coordinator will only include migration bundles (respectively the tails of those bundles) in its inclusion Merkle proof. Nodes which do not run with the updated code will crash.

Preventing non-migration bundles

As an additional measure to prevent users from submitting never confirming non-migration bundles (which would lead to key-reuse), nodes will no longer accept non-migration bundles in the HTTP API.

HTTP API level checks:

  • The user must submit an entire migration bundle. No more single zero-value transactions, value-spam bundles etc. are allowed.
  • Input transactions are spending the entirety of the funds residing on the corresponding address. There must be more than 0 tokens on the given address.

Wallet software must be updated to no longer support non-migration bundles.

There are no restrictions put in place on the gossip level, as it is too complex to prevent non-migration transactions to be filtered out, however, these transactions will never become part of a milestone cone.

Current network

Receipt Milestone Option

Each Milestone Essence as specified in TIP-29 can contain a Receipt Milestone Option. Receipts allow for fast migration of funds from the legacy into the new network.

Serialized layout

The following table describes the entirety of a Receipt Milestone Option in its serialized form following the notation from TIP-21:

Name Type Description
Milestone Option Type uint8 Set to value 0 to denote a Receipt Milestone Option.
Migrated At uint32 The index of the legacy milestone in which the listed funds were migrated at.
Final uint8 The value 1 indicates that this receipt is the last receipt for the given Migrated At index.
Funds Count uint16 Denotes how many migrated fund entries are within the receipt.
Funds
Migrated Funds Entry
Name Type Description
Tail Transaction Hash ByteArray[49] The t5b1 encoded tail transaction hash of the migration bundle.
Address oneOf
Ed25519 Address
Name Type Description
Address Type uint8 Set to value 0 to denote an Ed25519 Address.
PubKeyHash ByteArray[32] The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
Amount uint64 The amount which was migrated
Treasury oneOf
Treasury Transaction

Validation

Syntactic validation
  • Final must be either 0 or 1.
  • Funds:
    • Funds Count must be 0 < x ≤ Max Inputs Count.
    • For each fund entry the following must be true:
      • Amount must be at least 1'000'000.
    • The fund entries must be sorted with respect to their Tail Transaction Hash in lexicographical order.
    • Each Tail Transaction Hash must be unique.
  • Treasury must be a syntactically valid Treasury Transaction as described in the Treasury Transaction section.
Semantic validation

Semantic validation is checked with respect to the previous Receipt Milestone Option, i.e. the receipt whose Milestone's Index Number is the largest but still less than the current milestone.

  • Migrated At must not be smaller than in the previous receipt.
  • If the previous receipt has Final set to 1, Migrated At must be larger than the previous.
  • The Amount of the previous Treasury Output plus the sum of all Amount fields of the current Migrated Funds Entries must equal the Amount of the current Treasury Output.
Legitimacy of migrated funds

While the syntactic and semantic validation ensure that the receipt's integrity is correct, it does not actually tell whether the given funds were really migrated in the legacy network.

In order validate this criteria, the node software performs the following operations:

  1. The HTTP API of a legacy node is queried for the Tail Transaction Hash of each Migrated Funds Entry.
  2. The node checks whether the Migrated Funds Entry matches the response from the legacy node.
  3. Additionally, if the receipt's Final flag was set to 1, it is validated whether all funds for the given legacy milestone were migrated, i.e. whether for each Migration Bundle confirmed by that milestone there exists a Migrated Funds Entry in the current or a previous receipt.

If the operation fails, the node software must gracefully terminate with an appropriate error message.

Treasury Transaction

A Treasury Transaction contains a reference to the current Treasury Output (in the form of a Treasury Input object) and a Treasury Output which deposits the remainder.

The Treasury Output cannot be referenced or spent by transactions, it can only be referenced by receipts. It can be queried from the HTTP API and needs to be included within snapshots in order to keep the total supply intact.

The following table describes the entirety of a Treasury Transaction in its serialized form following the notation from TIP-21:

Name Type Description
Input oneOf
Treasury Input
Equivalent to a normal UTXO Input, but instead of a transaction it references a milestone.
Name Type Description
Input Type uint8 Set to value 1 to denote an Treasury Input.
Milestone ID ByteArray[32] The Milestone ID of the milestone that created the referenced Treasury Output.
Output oneOf
Treasury Output
Represents the treasury of the network, i.e. the not yet migrated funds.
Name Type Description
Output Type uint8 Set to value 2 to denote an Treasury Output.
Amount uint64 The amount of funds residing in the treasury.

Booking receipts

After successful receipt validation, the node software generates UTXOs in the following form: For each Migrated Funds Entry a Basic Output (see TIP-18) is created with Amount matching the Amount field of the entry as well as a single Address Unlock Condition for the entry's Address. All other fields of the output are left empty. Normally, the Output ID corresponds to Transaction ID plus Output Index. However, as for those migrated outputs there is no corresponding creating transaction, the Milestone ID of the encapsulating milestone is used as the Transaction ID part. In this case, the Output Index corresponds to the index of the corresponding Migrated Funds Entry.

All the generated Basic Outputs are then booked into the ledger and the new Treasury Output is persisted as an UTXO using the Milestone ID of the receipt which included the Treasury Transaction payload.

Rationale

  • At the current legacy network ledger size of 261446 entries (addresses with ≥ 1'000'000 tokens), it would take at least 2058 receipts to migrate all the funds. While theoretically the Max Message Length allows for more entries to be included in one receipt, the number is limited by the fact that the index of the Migrated Funds Entry is used to generate the Output Index of the generated output. As such, the maximum number of Migrated Funds Entry should also be limited by Max Inputs Count
  • Assuming the best case scenario in which all 261446 entries are sent to migration addresses in the legacy network, these funds could therefore be migrated into the new network within ~5.7h (at a 10 second milestone interval). Of course, in practice users will migrate over time and the receipt mechanism will need to be in place as long as the new network runs.

Copyright

Copyright and related rights waived via CC0.