-
Notifications
You must be signed in to change notification settings - Fork 48
Asset ID
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 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 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
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.
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.
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.
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.
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
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" }