Multi-stage asset creation and metadata

When a MultiChain asset is created, it can be open or closed. If an asset is open, then more units of the same asset can be created in future “reissuance” events. By default, only the original issuer can do this, however they can optionally grant this right to other addresses as well.

All units of a particular asset are fungible on the blockchain, no matter who issued them and when. When an asset quantity is sent or exchanged using MultiChain’s API commands, no distinction is made between units created in the original or subsequent issuances. Your application should therefore assume that these units are fully interchangeable, mixed together and equal in value. If you wish to maintain any kind of distinction between the units created by different issuances of the same asset, you should use separate assets instead.

Every issuance event can contain optional metadata, provided in a parameter to the issue(more)(from) APIs. This metadata consists of one of more key-value pairs, and can be retrieved using listassets. In current versions of MultiChain, the total metadata (keys and values) for each issuance transaction is limited to a few kilobytes, making it unsuitable for large pieces of text, images or files. If you wish to embed a large item such as a file, the simplest solution is to publish that file in a stream, and then reference the stream item by transaction ID in the asset’s metadata. (A more advanced approach is to include the file in an extra metadata output within the issuance transaction itself, using raw transactions.)

This tutorial requires MultiChain to be running a blockchain with no native currency or other unusual parameters. Although in reality multiple users would be spread across multiple organizations (and therefore nodes), we can simulate the process by creating multiple addresses on a single node. If you don’t yet have this set up, follow the instructions in sections 1 of the Getting Started guide and then run multichain-cli chain1. The node should also have an address with admin and issue permissions – this will automatically be the case if it started the chain.

Creating the asset

Let’s begin by creating the asset to be used in this tutorial. We start by finding an address that can create assets:

listpermissions issue
listaddresses

An address is suitable if it appears in the output of the first command, and also in the second command together with "ismine" : true.

Enter the address here:

Now let’s issue an open asset named GBP using this address, creating 50000 asset units, each of which can be divided into 100 parts, and include some metadata. The issued units will be sent back to the same address:

issuefrom '{"name":"GBP","open":true}' 50000 0.01 0 '{"origin":"uk", "stage":"01", "purpose":"parts prepayment"}'

A 64-character hexadecimal transaction ID should be shown, for the issuance transaction. Let’s take a look at the new asset:

listassets GBP

Note the issuetxid which matches the transaction ID displayed before, the "open" : true field, meaning that more units of the asset can be created in future, the details field containing the metadata we provided, and the issueqty issuance quantity.

We can also check the balance of this asset for this address, which should be 50000:

getaddressbalances

Issuing more asset units

Now we’ll issue some more units of the same asset. First, let’s create a new address which will receive the new units:

getnewaddress

Enter the address here:

We need to grant this address the permission to receive (and later, send) transactions:

grant receive,send

Now we’re ready to issue 25000 more units of GBP to this new address, with some additional metadata:

issuemorefrom GBP 25000 0 '{"origin":"europe", "stage":"02", "approval":"department"}'

Another transaction ID should be shown for the reissuance event. Now let’s check our asset’s status:

listassets GBP

Note the increased issueqty field, but the metadata shown is still for the original issuance only. For more details:

listassets GBP true

This includes an issues array that provides details of each individual issuance for this asset. For each element in the array, the txid transaction ID is shown, along with the quantity in qty and the metadata details of that issuance.

We can also view the new asset’s balance for both addresses:

getmultibalances * GBP

This should show 50000 units for , 25000 units for , and a total of 75000 units.

Granting issue permissions

In this stage we’ll give other addresses the permission to issue more units of the asset. Let’s begin by seeing the current asset permissions:

listpermissions GBP.*

The issuing address should have two permissions for the asset. The issue permission allows it to issue more units of the asset, and the admin permission allows it to control the permissions of other addresses for this asset.

Now let’s try issuing more units of the asset from the second address (to itself):

issuemorefrom GBP 15000 0

An error should be displayed, indicating that this address does not have permission to issue more units. So let’s use the first address to grant them:

grantfrom GBP.issue

Let’s check that the permission change was applied:

listpermissions GBP.issue

Both addresses should now be displayed, so let’s try the reissuance from the second address again:

issuemorefrom GBP 15000 0

This time a transaction ID should be shown instead of an error. Let’s look at all issuances of the asset so far:

listassets GBP true

Note that three issuances are now shown, with the third showing an empty details field (since no metadata was passed to the issuemorefrom command) and a different address in the issuers field from the first two.

Metadata-only issuance

Finally let’s see an example of a reissuance whose sole purpose is to add some metadata to the asset, and not create any new units. This is achieved simply by passing zero for the quantity parameter:

issuemorefrom GBP 0 0 '{"approval":"head office"}'

The metadata-only issuance event can be viewed here:

listassets GBP true

Where to go from here

Congratulations! You have successfully created a new asset, with multiple issuance events and associated metadata. In a similar way to assets, streams can also be created with custom metadata, but in this case there is no notion of a follow-on event. To explore MultiChain assets in more detail, here are some things to try out:

  • Subscribing to an asset using the subscribe command, then using listassettransactions and getassettransaction to query the full list of that asset’s transactions, whether or not they involve an address in this node’s wallet.
  • Using the chain’s burn address, which has no corresponding private key, to “burn” units of an asset by rendering them unspendable. The address can be obtained using getinfo, and any node can import it using importaddress to track the asset quantities burned.