MultiChain is a platform where users can establish and deploy private blockchains within an organization or between organizations. It is an open source platform based on Bitcoin’s Blockchain, except in MultiChain you must configure the multichain at every node as opposed to the Bitcoin Blockchain where anyone can connect and transfer assets on the chain.

MultiChain key features:
- Native multi-currency support
- Expected to be faster than Bitcoin
- Permissioned management
- Quick deployments
- Supported languages – Python, C#, JavaScript, PHP, Ruby
MultiChain forked from the Bitcoin Blockchain allowing users to control whether the chain is private or public, permissions to connect to the network, target time for blocks, and maximum block size and metadata. MultiChain also has a simple API and command line interface that helps to set up the chain.

Below are detailed steps to build and deploy MultiChain private blockchains.
1. Creating a Blockchain
a. Ran this command: multichain-util create chain1

b. View the blockchain’s default settings: %APPDATA%\MultiChain\chain1\params.dat
These are the parameters of the opened file after that command →
c. Initialize the blockchain, including mining the genesis block:
multichaind chain1 –daemon

Now we have the ip address and the port for connecting from the second server:192.168.0.10:9569
2. Connecting to a Blockchain
I installed an Oracle VM VirtualBox and installed windows 10. I had to configure it to make it work.
a. On the second server, ran the following command: multichaind chain1@192.168.0.10:9569 and as expected, I was told that the blockchain was successfully initialized but that I don’t have permissions to connect. I was also given the address in this node wallet: 1SYUeoyrxbjZ3iN65a57f7Dxb7Wrt6onNXmFtM

b. Back to the first server, I had to grant permissions for the node’s wallet address, given by: multichain-cli chain1 grant 1SYUeoyrxbjZ3iN65a57f7Dxb7Wrt6onNXmFtM connect

c. Now, I tried to reconnect again in the second server: multichaind chain1 –daemon (no need to specify the ip address and port again, only to connect to chain1)

3. Using Native Assets
In this section, we would use blockchains for representing asset transactions. If we use blockchains only for data storage and retrieval, we can skip this step.
MultiChain asset features include:
- Smart contracts are not needed
- Flexible asset metadata
- Permissioned follow-on issuance
- Atomic multi-asset payments
- Multi-way atomic asset exchanges
- Multi-signatures for security and escrow
- Subscribe to an asset to query transactions
I created a new asset and sent it between nodes.
a. On the first server, get the address that has the permission to create assets: listpermissions issue

b. Now, we’ll create a new asset on this node with 1000 units, each of which can be subdivided into 100 parts, sending it to itself: issue 1ZKAEF7T6ENtFmePijg92otgHPKDT476tfQ48x asset1 1000 0.01

c. On both servers, I verified that the asset named asset1 is listed:listassets
Server 1:

Server 2:

As we can observe, asset1 is the same for both servers.
c. I also checked the asset balances on each server. The first should show a balance of 1000, and the second should show not show any assets: gettotalbalances
Server 1:

Server 2:

d. I tried to send 100 units of the asset to the second server’s wallet: sendasset 1SYUeoyrxbjZ3iN65a57f7Dxb7Wrt6onNXmFtM asset1 100

e. I granted send and receive permissions to the node’s wallet on server 1: grant 1SYUeoyrxbjZ3iN65a57f7Dxb7Wrt6onNXmFtM receive, send

f. I tried to send 100 units of the asset again to the second server’s wallet: sendasset 1SYUeoyrxbjZ3iN65a57f7Dxb7Wrt6onNXmFtM asset1 100

g. I checked the asset balances again on each server, including transactions with zero confirmations. They should be 900 and 100 respectively: gettotalbalances 0
Server 1:

Server 2:

h. I also viewed the transaction on each node and saw how it affected balances:listwallettransactions 1
Server 1:

Server 2:

4. Transaction Metadata
a. Now, I’ll create a transaction that sends 125 units of asset1 along with some metadata in the first server: sendwithdata 1SYUeoyrxbjZ3iN65a57f7Dxb7Wrt6onNXmFtM ‘{“asset1”:125}’ 48692066726f6d204d756c7469436861696e21 (replacing simple quotation marks by double ones and escaping the double ones with a slash)

b. Using the obtained transaction id, we can examine the transaction on the second server: getwallettransaction a308f740c377e36d388a5deb0732ca09db40e101abfdfbf1c877946430a33c93
In the output from this command, you should see the balance field showing the incoming 125 units of asset1 and the data field containing the hexadecimal metadata that was added.
C:\Multichain>multichain-cli chain1 getwallettransaction a308f740c377e36d388a5deb0732ca09db40e101abfdfbf1c877946430a33c93
{“method”:”getwallettransaction”,”params”:[“a308f740c377e36d388a5deb0732ca09db40e101abfdfbf1c877946430a33c93”],”id”:1,”chain_name”:”chain1"}
{
“balance” : {
“amount” : 0.00000000,
“assets” : [
{
“name” : “asset1”,
“assetref” : “71–266–63605”,
“qty” : 125.00000000
}
]
},
“myaddresses” : [
“1SYUeoyrxbjZ3iN65a57f7Dxb7Wrt6onNXmFtM”
],
“addresses” : [
“1ZKAEF7T6ENtFmePijg92otgHPKDT476tfQ48x”
],
“permissions” : [
],
“items” : [
],
“data” : [
“48692066726f6d204d756c7469436861696e21”
],
“confirmations” : 11,
“blockhash” : “00592688eb4f5a1fd94109dcee3b35a37928730b095b5e11a7014b9924778a19”,
“blockindex” : 1,
“blocktime” : 1503941755,
“txid” : “a308f740c377e36d388a5deb0732ca09db40e101abfdfbf1c877946430a33c93”,
“valid” : true,
“time” : 1503941743,
“timereceived” : 1503941743
}
5. Streams
a. I created a stream, which can be used for general data storage and retrieval. On the first server: create stream stream1 false
The false return means the streams can only be written by those with explicit permissions.

Remember the returned ID as it is the stream1 creation ID and will be used later.
b. I reviewed the stream1 permissions: listpermissions stream1.*
C:\Multichain>multichain-cli chain1 listpermissions stream1.*
{“method”:”listpermissions”,”params”:[“stream1.*”],”id”:1,”chain_name”:”chain1"}
[
{
“address” : “1ZKAEF7T6ENtFmePijg92otgHPKDT476tfQ48x”,
“for” : {
“type” : “stream”,
“name” : “stream1”,
“streamref” : “115–265–30124”
},
“type” : “admin”,
“startblock” : 0,
“endblock” : 4294967295
},
{
“address” : “1ZKAEF7T6ENtFmePijg92otgHPKDT476tfQ48x”,
“for” : {
“type” : “stream”,
“name” : “stream1”,
“streamref” : “115–265–30124”
},
“type” : “activate”,
“startblock” : 0,
“endblock” : 4294967295
},
{
“address” : “1ZKAEF7T6ENtFmePijg92otgHPKDT476tfQ48x”,
“for” : {
“type” : “stream”,
“name” : “stream1”,
“streamref” : “115–265–30124”
},
“type” : “write”,
“startblock” : 0,
“endblock” : 4294967295
}
]
We can see here three types of access that the node address “1ZKAEF7T6ENtFmePijg92otgHPKDT476tfQ48x” has: admin, activate and write. Those are all of the permissions whereby if we trigger the same command on the second server, we obtain the same results. So, the only server that can write and administrate to the stream is the first one.
c. I published something to the stream, using keykey1: publish stream1 key1 73747265616d2064617461

d. Now, I verified that the stream is visible on the other node. On the second server: liststreams
C:\Multichain>multichain-cli chain1 liststreams
{“method”:”liststreams”,”params”:[],”id”:1,”chain_name”:”chain1"}
[
{
“name” : “root”,
“createtxid” : “5fae9236e828ce08d974968747ead7e2b1fe7c14f7d9fbdae1ad5bc07591ab7c”,
“streamref” : “0–0–0”,
“open” : true,
“details” : {
},
“subscribed” : true,
“synchronized” : true,
“items” : 0,
“confirmed” : 0,
“keys” : 0,
“publishers” : 0
},
{
“name” : “stream1”,
“createtxid” : “ac752c059619fcd328979cbaa1c7d67e99bf57c3b52b43559e54bcdcee4eb0bf”,
“streamref” : “115–265–30124”,
“open” : false,
“details” : {
},
“subscribed” : false
}
]
The root stream was in the blockchain by default.
e. I subscribed the second server to the stream and viewed its contents:
subscribe stream1
liststreamitems stream1

f. I allowed the second server to publish to the stream. On the first server:
grant
1SYUeoyrxbjZ3iN65a57f7Dxb7Wrt6onNXmFtM receive,send
grant
1SYUeoyrxbjZ3iN65a57f7Dxb7Wrt6onNXmFtM stream1.write
Both commands were triggered and the txids were returned respectively. Note that the address needs both general send/receive permissions for the blockchain, as well as permission to write to this specific stream.
g. Then, I published a couple of items on the second server:
publish stream1 key1 736f6d65206f746865722064617461
publish stream1 key2 53747265616d732052756c6521
h. I queried the stream’s contents in many different ways. Back on the first server:
subscribe stream1
I. liststreamitems stream1 ← This return 3 items
C:\Multichain>multichain-cli chain1 liststreamitems stream1
{“method”:”liststreamitems”,”params”:[“stream1”],”id”:1,”chain_name”:”chain1"}
[
{
“publishers” : [
“1ZKAEF7T6ENtFmePijg92otgHPKDT476tfQ48x”
],
“key” : “key1”,
“data” : “73747265616d2064617461”,
“confirmations” : 36,
“blocktime” : 1503945656,
“txid” : “0b1203882c45b99b65880a6bb8d8ce378bb549aba5fd956388820b0afa8ca037”
},
{
“publishers” : [
“1SYUeoyrxbjZ3iN65a57f7Dxb7Wrt6onNXmFtM”
],
“key” : “key1”,
“data” : “736f6d65206f746865722064617461”,
“confirmations” : 10,
“blocktime” : 1503947646,
“txid” : “08d431e40cc1aa2c0877ae6f6ae3f4012a1929d1f4735845bdb0b253ba5ac8de”
},
{
“publishers” : [
“1SYUeoyrxbjZ3iN65a57f7Dxb7Wrt6onNXmFtM”
],
“key” : “key2”,
“data” : “53747265616d732052756c6521”,
“confirmations” : 10,
“blocktime” : 1503947646,
“txid” : “35130dfac12dbb2d91810000de88df31054324b763075e850b176a5bf8c6859b”
}
]
First item created by the node on the first server and the other two items created by the second server.
II. liststreamkeys stream1 ← This return 2 items
C:\Multichain>multichain-cli chain1 liststreamkeys stream1
{“method”:”liststreamkeys”,”params”:[“stream1”],”id”:1,”chain_name”:”chain1"}
[
{
“key” : “key1”,
“items” : 2,
“confirmed” : 2
},
{
“key” : “key2”,
“items” : 1,
“confirmed” : 1
}
]
This command returns the 2 keys.
III. liststreamkeyitems stream1 key1 ← this returns the 2 items created using key1
C:\Multichain>multichain-cli chain1 liststreamkeyitems stream1 key1
{“method”:”liststreamkeyitems”,”params”:[“stream1”,”key1"],”id”:1,”chain_name”:”chain1"}
[
{
“publishers” : [
“1ZKAEF7T6ENtFmePijg92otgHPKDT476tfQ48x”
],
“key” : “key1”,
“data” : “73747265616d2064617461”,
“confirmations” : 37,
“blocktime” : 1503945656,
“txid” : “0b1203882c45b99b65880a6bb8d8ce378bb549aba5fd956388820b0afa8ca037”
},
{
“publishers” : [
“1SYUeoyrxbjZ3iN65a57f7Dxb7Wrt6onNXmFtM”
],
“key” : “key1”,
“data” : “736f6d65206f746865722064617461”,
“confirmations” : 11,
“blocktime” : 1503947646,
“txid” : “08d431e40cc1aa2c0877ae6f6ae3f4012a1929d1f4735845bdb0b253ba5ac8de”
}
]
IV. liststreampublishers stream1 ← return the two publishers
C:\Multichain>multichain-cli chain1 liststreampublishers stream1
{“method”:”liststreampublishers”,”params”:[“stream1”],”id”:1,”chain_name”:”chain1"}
[
{
“publisher” : “1ZKAEF7T6ENtFmePijg92otgHPKDT476tfQ48x”,
“items” : 1,
“confirmed” : 1
},
{
“publisher” : “1SYUeoyrxbjZ3iN65a57f7Dxb7Wrt6onNXmFtM”,
“items” : 2,
“confirmed” : 2
}
]
V. liststreampublisheritems stream1
1SYUeoyrxbjZ3iN65a57f7Dxb7Wrt6onNXmFtM ← returns the two items created by this publisher
C:\Multichain>multichain-cli chain1 liststreampublisheritems stream1 1SYUeoyrxbjZ3iN65a57f7Dxb7Wrt6onNXmFtM
{“method”:”liststreampublisheritems”,”params”:[“stream1”,”1SYUeoyrxbjZ3iN65a57f7Dxb7Wrt6onNXmFtM”],”id”:1,”chain_name”:”chain1"}
[
{
“publishers” : [
“1SYUeoyrxbjZ3iN65a57f7Dxb7Wrt6onNXmFtM”
],
“key” : “key1”,
“data” : “736f6d65206f746865722064617461”,
“confirmations” : 11,
“blocktime” : 1503947646,
“txid” : “08d431e40cc1aa2c0877ae6f6ae3f4012a1929d1f4735845bdb0b253ba5ac8de”
},
{
“publishers” : [
“1SYUeoyrxbjZ3iN65a57f7Dxb7Wrt6onNXmFtM”
],
“key” : “key2”,
“data” : “53747265616d732052756c6521”,
“confirmations” : 11,
“blocktime” : 1503947646,
“txid” : “35130dfac12dbb2d91810000de88df31054324b763075e850b176a5bf8c6859b”
}
]
6. Round Robin Mining
In this section we’ll start collaborative mining between the nodes.

a. On the first server, run: grant 1SYUeoyrxbjZ3iN65a57f7Dxb7Wrt6onNXmFtM mine
b. Then, check on second server that two permitted miners are listed: listpermissions mine
C:\Multichain>multichain-cli chain1 listpermissions mine
{“method”:”listpermissions”,”params”:[“mine”],”id”:1,”chain_name”:”chain1"}
[
{
“address” : “1SYUeoyrxbjZ3iN65a57f7Dxb7Wrt6onNXmFtM”,
“for” : null,
“type” : “mine”,
“startblock” : 0,
“endblock” : 4294967295
},
{
“address” : “1ZKAEF7T6ENtFmePijg92otgHPKDT476tfQ48x”,
“for” : null,
“type” : “mine”,
“startblock” : 0,
“endblock” : 4294967295
}
]
c. I ran this command on both server to maximize the degree of miner randomness: setruntimeparam miningturnover 1
d. On either server, checked the current block height: getinfo
C:\Multichain>multichain-cli chain1 getinfo
{“method”:”getinfo”,”params”:[],”id”:1,”chain_name”:”chain1"}
{
“version” : “1.0”,
“nodeversion” : 10000901,
“protocolversion” : 10008,
“chainname” : “chain1”,
“description” : “MultiChain chain1”,
“protocol” : “multichain”,
“port” : 9569,
“setupblocks” : 60,
“nodeaddress” : “chain1@192.168.56.1:9569”,
“burnaddress” : “1XXXXXXWz9XXXXXXmhXXXXXXZfXXXXXXT2BC2F”,
“incomingpaused” : false,
“miningpaused” : false,
“walletversion” : 60000,
“balance” : 0.00000000,
“walletdbversion” : 2,
“reindex” : false,
“blocks” : 173,
“timeoffset” : 0,
“connections” : 1,
“proxy” : “”,
“difficulty” : 0.00000006,
“testnet” : false,
“keypoololdest” : 1503839756,
“keypoolsize” : 2,
“paytxfee” : 0.00000000,
“relayfee” : 0.00000000,
“errors” : “”
}
The block height is in the blocksfield of the response.
e. Then, I got information about the last few blocks, beginning with this one: getblock [block-height](I used “173”)
C:\Multichain>multichain-cli chain1 getblock 173
{“method”:”getblock”,”params”:[“173”],”id”:1,”chain_name”:”chain1"}
{
“hash” : “00aa31ca21318e5010e31c32afd4b598a621a20d105aa09a339822077b5b9cf5”,
“miner” : “1ZKAEF7T6ENtFmePijg92otgHPKDT476tfQ48x”,
“confirmations” : 1,
“size” : 267,
“height” : 173,
“version” : 3,
“merkleroot” : “2e63b11a55eb7d7e59ce9a589fca3e25e699e46557a71dc64fa54f3d8b1588cc”,
“tx” : [
“2e63b11a55eb7d7e59ce9a589fca3e25e699e46557a71dc64fa54f3d8b1588cc”
],
“time” : 1503949956,
“nonce” : 211,
“bits” : “2000ffff”,
“difficulty” : 0.00000006,
“chainwork” : “000000000000000000000000000000000000000000000000000000000000ae00”,
“previousblockhash” : “0063100b17a723cbe8f67c5bc04999c74e7248bd4f61d6b4e0bed33430828b54”
}
The address of the miner of each block is in the minerfield of the response. In different blocks you should see the two different addresses in this field. For example, trying with different block-heights I found that 170 has another miner.
C:\Multichain>multichain-cli chain1 getblock 170
{“method”:”getblock”,”params”:[“170”],”id”:1,”chain_name”:”chain1"}
{
“hash” : “006ec3a18780e3548b653ebb1ead43878a446ac655a7a7a40c4f2cf408a6b3e9”,
“miner” : “1SYUeoyrxbjZ3iN65a57f7Dxb7Wrt6onNXmFtM”,
“confirmations” : 4,
“size” : 266,
“height” : 170,
“version” : 3,
“merkleroot” : “9b4acf7c559597aaa6743ba506d51ee610d89743bbc169d25e2cdc815ce376c2”,
“tx” : [
“9b4acf7c559597aaa6743ba506d51ee610d89743bbc169d25e2cdc815ce376c2”
],
“time” : 1503949930,
“nonce” : 29,
“bits” : “2000ffff”,
“difficulty” : 0.00000006,
“chainwork” : “000000000000000000000000000000000000000000000000000000000000ab00”,
“previousblockhash” : “002387f0d58f5e93581192f3e1ed0a91045abecddaa2225541187572749ea94e”,
“nextblockhash” : “0046a2dceda719642c380b795de12002ba4b8d69621924fa94cf2a3093a31b2b”
}
Collaborative mining validates deployment and setup of the MultiChain. Permissions are granted using transactions with metadata and the miner of the Genesis block is given all of the rights on the network to act as an administrator. The administrator appoints other administrators on the network.
Some MultiChain use cases include:
- Permission blockchain → Validated by consensus, not Proof-of-Work
- Full asset lifecycle → Issuance, transfer, exchange, escrow, re-issuance, redemption, destruction
- General storage and search → 64MB of data per transaction
- Streams → Key-value, identity, time series
“Private blockchains will likely be a more attractive solution for financial institutions wishing to deploy this technology during the next decade,” as described by the MultiChain Whitepaper. MultiChain positions private blockchains as an early version of a more robust, global Bitcoin Blockchain, one that can allow private institutions to begin working with the technology in the way that Intranets exposed entities to the Internet.