Skip to content

Asset ID

Oded Leiba edited this page Mar 28, 2016 · 38 revisions

The asset ID is an immutable identifier of an asset that is created at issuance and is derived from the issuance transaction and the asset's divisibility.

There are two types of Asset IDs corresponding to the two types of assets supported by the new colored coins protocol: locked and unlocked.

Unlocked Asset IDs

Unlocked asset IDs look similar to Bitcoin addresses, except instead of starting with the number 1 start with the capital letter U.

An unlocked Asset ID is derived from the pubkey script of the UTXO referenced in the first input of the issuance transaction similar to the way that a Bitcoin address is derived from a public key. The difference is that instead of padding the network version 0x00 which gives the prefix 1 to standard Bitcoin addresses, we pad with a pre-defined 2 bytes sequence which ensures the asset ID has the prefix U, followed by one of the characters a, h or d, depending on the asset aggregation policy:

Aggregation policy Padding
aggregatable 0x2e37
hybrid 0x2e6b
dispersed 0x2e4e

In detail, the process is

script = pubkey script of the output referenced in first input of issuance transaction
padding = 2 bytes according to the asset aggregation policy
extended_ripemd = padding+RIPEMD-160(SHA-256(pk))
checksum = first 4 bytes of SHA-256(SHA-256(extended_ripemd))
divisibility = asset divisibility extended to 2 bytes
Unlocked Asset ID = Base58(extended_ripemd+checksum+divisibility)

where + means concatenation.

An example of such an asset ID is

Ua9kP82bbaxtYodahVBY8zs6cZ78Xua4X97Nu8

Locked Asset IDs

Locked asset IDs look similar to Bitcoin addresses, except instead of starting with the number 1 start with the capital letter L.

A Locked Asset ID is derived in a similar way, except instead of using the script of the referenced output, we use the transaction ID + index of the UTXO referenced in the first input of the issuance transaction. For padding, we use a different table of 2 byte sequences, which ensures the asset ID has the prefix L, followed by one of the characters a, h or d, depending on the asset aggregation policy:

Aggregation policy Padding
aggregatable 0x20ce
hybrid 0x2102
dispersed 0x20e4

In detail, the process is

txid = Transaction ID of first UTXO in the issuance transaction 
idx = Index of first UTXO in the issuance transaction 
padding = 2 bytes according to the asset aggregation policy
extended_ripemd = padding+RIPEMD-160(SHA-256(txid+':'+idx))
checksum = first 4 bytes of SHA-256(SHA-256(extended_ripemd))
divisibility = asset divisibility extended to 2 bytes
Locked Asset ID = Base58(extended_ripemd+checksum+divisibility)

where as before + means concatenation.

An example of such an asset ID is

Ld9ohgk6wruYptPeoDQRHRif8fG2vJe1uN4ryz

Comments

Asset IDs are divisibility dependent

The reason the asset divisibility is included in the asset ID is to prevent the edge case of issuing the same asset twice, each time with a different divisibility. For technical reasons (basically in order to get the correct L,U prefixes) we had to extend the 3 bits defining the divisibility to 2 full bytes by padding them with zeros.

Asset IDs and Bitcoin Confirmations

Note that both asset ID types make no reference to a Bitcoin block and hence are meaningful even at zero confirmations. Thanks to that, and to our [coloring scheme](Coloring Scheme) we can perform [issuance and transfer](Coloring Scheme#issuance-transaction-encoding) of an asset in the same transaction.

Unlocked

Since an unlocked asset ID uses a transaction output pubkey script, all assets that originate from an output carrying the exact same pubkey script, are considered the same. For example, when the issuance transaction's first input points to a standard pay-to-public-key-hash output, we can perform more than one issuance transactions (provided we own the corresponding private key) and issue more units of that asset by using outputs payed to the same address, since they carry the exact same pubkey script, which is why it is unlocked.

Locked

Since locked asset IDs reference a transaction id, any attempt to issue more of that asset will necessarily generate a new asset ID, so this specific asset can only be issued once, which is why it is locked.

Lock status and the [Rules Engine](Rules Engine)

Since the new colored coins protocol supports an extra layers of rules it is possible to override the locked status by declaring Minters in the Metadata

Example

The data fields relevant for the construction of an asset id are the transaction ID and index of the UTXO in case of a locked asset or the pubkey script of the UTXO in case of a unlocked asset.

As an example, look at the following transaction. If we were to build a locked asset id we would be interested in the transaction ID and index corresponding to the fields previous_transaction_hash and output_index below. If on the other hand we were to build an unlocked asset id, we would need the pubkey script of that UTXO. In most cases, including the most common type of a payment as in this example, pay-to-public-key-hash, we can construct that pubkey script by using data from the issuance transaction itself without needing to fetch the referenced UTXO. Specifically, we would locate the public key of the credited address ('16yVP3cQ74DWpHj2CWfTHRbzaU8c5ymo1J' in this case) in the second part of the script. Then, we can construct and encode the predicted pubkey script.

{
  "hash":"84c8cd6d13414210f69201d6df78bd12b5ade17091d1fa0cfcd53fc2938ef252",
  "version":1,
  "lock_time":0,
  "size":225,
  "inputs":[
    {
      "previous_transaction_hash":"15b4b52fdb0b7fd0fd005bf8fa887985635dbec3ee2aad336a22d24eb887e55f",
      "output_index":1,
      "amount":26245000,
      "script":"304402203fea7908daa6c65e08394d9172e1983fc5e70471d50e8d7f0c6536a072e884fa0220271a9610d6d59f2be2b3d98583e77b69efa3ba60473a808b48d961113e34174401 02062c6865ca9aec945eb9bf2856d73d5d3f7899bf5b0a5b8def6d90732a7831fe",
      "addresses":[
        "16yVP3cQ74DWpHj2CWfTHRbzaU8c5ymo1J"
      ]
    }
  ],
  "outputs":[
    {
      "amount":14985000,
      "spent":false,
      "script":"OP_DUP OP_HASH160 4c51251aa9fc9c55dd594b03b7645e347c55c247 OP_EQUALVERIFY OP_CHECKSIG",
      "script_hex":"76a9144c51251aa9fc9c55dd594b03b7645e347c55c24788ac",
      "script_type":"hash160",
      "addresses":[
        "17xXZdSSngEpe9CkdwotigRsr3uY7vWZuu"
      ]
    },
    {
      "amount":11250000,
      "spent":false,
      "script":"OP_DUP OP_HASH160 d6cdda1c12e42b356d87419304445b45a0894f72 OP_EQUALVERIFY OP_CHECKSIG",
      "script_hex":"76a914d6cdda1c12e42b356d87419304445b45a0894f7288ac",
      "script_type":"hash160",
      "addresses":[
        "1LanCu8W2Xz5Wo1b1qrhFRAzUmtwSMUcDJ"
      ]
    }
  ],
  "amount":26235000,
  "fees":10000,
  "confirmations":0,
  "pool":"memory"
}
Clone this wiki locally