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 usinglistassettransactions
andgetassettransaction
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 usingimportaddress
to track the asset quantities burned.