MultiChain Explorer

Follow the steps listed down in the Github repository for the same.

Setting up in Local:

Accessing Explorer from localhost


Accessing Explorer installed on the remote server:
Make sure that you update the network and security settings in the aws.
Also take a note of the change in the host accessible in the chain1.conf file here.

 

Github Repo: https://github.com/MultiChain/multichain-explorer

 

MultiChain Mining

In MultiChain, block creators must prove their identity by signing blocks

Block signatures

Block signatures are embedded inside the OP_RETURN metadata of the coinbase transaction, using a regular bitcoin-style signature format. The payload signed by the block creator is the full block header, with the following modifications:

  • The merkle_root is recalculated based on the txid of the coinbase transaction with the OP_RETURN removed. This prevents a dependency loop from block signature → coinbase txid → merkle root → block header → block signature.
  • The nonce field is set to 0. This avoids having to recalculate the signature for every attempt at finding a block hash to match the target difficulty. However it does lead to some malleability in that a user without mine permissions could generate a block with the same content as a valid block, but with a different nonce. Seeing as the nonce serves no purpose other than to randomize the block’s content for its hash, this should not be a source of concern.

In the case of a permissioned MultiChain blockchain, consensus is based on block signatures and a customizable round-robin consensus scheme, rather than proof-of-work as in bitcoin.

On the first server, run:

grant 15ZLxwAQU4XFrLVs2hwQz1NXW9DmudRMcyx2ZV mine

(Even though the permission is called mine note that there is no real “mining” taking place, in the sense of proof-of-work.) On the second server, check that two permitted block validators are listed:

listpermissions mine

Run this on both servers to maximize the degree of validator randomness:

setruntimeparam miningturnover 1

Now wait for a couple of minutes, so that a few blocks are added. (This assumes you left the block time on the default of 15 seconds.) On either server, check the creators of the last few blocks:

listblocks -10

The address of the validator of each block is in the miner field of each element of the response.

Snippet:
RR Mining

Node-1 Terminal | Node-2 Terminal

 

Reference: https://www.multichain.com/developers/mining-block-signatures/
https://www.multichain.com/getting-started/

MultiChain Streams

MultiChain streams enable a blockchain to be used as a general purpose append-only database, with the blockchain providing timestamping, notarization and immutability. A MultiChain blockchain can contain any number of streams, where the data published in every stream is stored by every node. If a node chooses to subscribe to a stream, it will index that stream’s contents to enable efficient retrieval in various ways.

Each stream is an ordered list of items, in which each item has the following characteristics:

  • One or more publishers who have digitally signed that item.
  • A key between 0 and 256 bytes in length.
  • Some data, which can reach many megabytes in size.
  • Information about the item’s transaction and block, including its txid, blockhash, blocktime, and so on.

Like native assets, MultiChain streams can be referred to in any of three ways:

  • An optional stream name, chosen at the time of stream creation. If used, the name must be unique on a blockchain, between both assets and streams. Stream names are stored as UTF-8 encoded strings up to 32 bytes in size and are case insensitive.
  • A createtxid, containing the txid of the transaction in which the stream was created.
  • A streamref which encodes the block number and byte offset of the stream creation transaction, along with the first two bytes of its txid.

If root-stream-name in the blockchain parameters is a non-empty string, it defines a stream which is created with the blockchain and can be written to immediately. The root stream’s createtxid is the txid of the coinbase of the genesis block, and its streamref is 0-0-0.

Create a stream, which can be used for general data storage and retrieval. On the first server:

create stream stream1 false

The false means the stream can only be written to by those with explicit permissions. Let’s see its permissions:

listpermissions stream1.*

So for now, only the first server has the ability to write to the stream, as well as administrate it. Let’s publish something to it, with key key1:

publish stream1 key1 73747265616d2064617461

The txid of the stream item is returned. Now let’s see that the stream is visible on another node. On the second server:

liststreams

(The root stream was in the blockchain by default.) Now we want the second server to subscribe to the stream, then view its contents:

subscribe stream1
liststreamitems stream1

Now we want the second server to be allowed to publish to the stream. On the first server:

grant 15ZLxwAQU4XFrLVs2hwQz1NXW9DmudRMcyx2ZV send
grant 15ZLxwAQU4XFrLVs2hwQz1NXW9DmudRMcyx2ZV stream1.write

Note that the address needs both general send permissions for the blockchain, as well as permission to write to this specific stream. Now let’s publish a couple of items on the second server:

publish stream1 key1 736f6d65206f746865722064617461
publish stream1 key2 53747265616d732052756c6521

Now let’s query the stream’s contents in many different ways. Back on the first server:

subscribe stream1
liststreamitems stream1 (should show 3 items)
liststreamkeys stream1 (2 keys)
liststreamkeyitems stream1 key1 (2 items with this key)
liststreampublishers stream1 (2 publishers)
liststreampublisheritems stream1 15ZLxwAQU4XFrLVs2hwQz1NXW9DmudRMcyx2ZV

Snippets:

Streams -1 (node 1 and node 2)

Streams – 2

Reference: https://www.multichain.com/developers/data-streams/
https://www.multichain.com/getting-started/

 

MultiChain Native Assets

MultiChain allows the creation & tracking of assets at the network level.

A use of  Blockchain to have defined limited native assets & let peers or nodes transact them among each other in an atomic or non-atomic manner. Anything can be defined as an asset.

Using native assets:

MultiChain allows the creation and tracking of assets at the network level

Assets in MultiChain

MultiChain supports assets natively at the blockchain level. The identifiers and quantities of assets are encoded within each transaction output, alongside the quantity of the blockchain’s native currency (which may be zero if it is not being used). Every MultiChain node tracks and verifies the quantity of assets in transactions, just as it is does with the native currency. Specifically, it checks that the total quantities of all assets in a transaction’s outputs are exactly matched by the total in its inputs. MultiChain allows each transaction output can contain any number of different assets.

In MultiChain, assets can be referred to in any of three ways:

  • An optional asset name, chosen at the time of issuance. If used, the name must be unique on a blockchain, between both assets and streams. Asset names are stored as UTF-8 encoded strings up to 32 bytes in size and are case insensitive.
  • An issuetxid, containing the txid of the transaction in which the asset was issued.
  • An assetref which encodes the block number and byte offset of the issuance transaction, along with the first two bytes of its txid.Common Commands:
    
    listpermissions issue (Check whether you have the permission to issue or not)
    issue 16bNJqp4d8JX3uL7UYr5hACWLnK2LU4f2Ep9FD aj007 100000 0.000001 (Address which has the permission to issue. Here aj007 is the asset issued. This has precison till 6 as specified in the last param)
    listassets (list the assets on the chain)
    gettotalbalances (get the total balance on the server)
    send 15ZLxwAQU4XFrLVs2hwQz1NXW9DmudRMcyx2ZV aj007 5000 (send the assets to the given address on node - 2)
    listwallettransactions (get the total transactions which have occured in the given wallet)
    
    sendwithdata 15ZLxwAQU4XFrLVs2hwQz1NXW9DmudRMcyx2ZV '{"aj007":500}' data (Sending metadata in transaction)


    Reference: https://www.multichain.com/developers/native-assets/

MultiChain

Installing MultiChain on Linux

su (enter root password)
cd /tmp
wget https://www.multichain.com/download/multichain-1.0.5.tar.gz
tar -xvzf multichain-1.0.5.tar.gz
cd multichain-1.0.5
mv multichaind multichain-cli multichain-util /usr/local/bin (to make easily accessible on the command line) exit (to return to your regular user)

We need two servers with multichain installed on them.
Try Amazon EC2.
After installing multichain and initializing the blockchain, make sure you modify the Network and security settings port numbers to allow the two nodes to communicate with each other.

1. Creating a blockchain

First we will create a new blockchain named chain1. On the first server, run this command:

multichain-util create chain1

View the blockchain’s default settings:

cat ~/.multichain/chain1/params.dat

Initialize the blockchain, including creating the genesis block:

multichaind chain1 -daemon

2. Connecting to a blockchain

Now we’ll connect to this blockchain from elsewhere. On the second server, run the following:

multichaind multichaind chain1@172.31.29.15:6461

You should be told that the blockchain was successfully initialized, but you do not have permission to connect. You should also be shown a message containing an address in this node’s wallet.

Back on the first server, add connection permissions for this address:

multichain-cli chain1 grant 15ZLxwAQU4XFrLVs2hwQz1NXW9DmudRMcyx2ZV connect,send,receive

Now try reconnecting again from the second server:

multichaind chain1 -daemon

3. Some commands in interactive mode

Before we proceed, let’s enter interactive mode so we can issue commands without typing multichain-cli chain1 every time. On both servers:

multichain-cli chain1

If you are using Windows, interactive mode is not yet available, so all commands in this guide should be preceded by multichain-cli chain1. You will also need to open another DOS command line in the directory where you installed the MultiChain executables.

Now that the blockchain is working on two nodes, you can run the commands in this section on either or both. To get general information:

getinfo

See a list of all available commands:

help

Show all permissions currently assigned:

listpermissions

Create a new address in the wallet:

getnewaddress

List all addresses in the wallet:

getaddresses

Get the parameters of this blockchain (based on params.dat file):

getblockchainparams

For each node, get a list of connected peers:

getpeerinfo

4. Streams

Now let’s create a stream, which can be used for general data storage and retrieval. On the first server:

create stream stream1 false

The false means the stream can only be written to by those with explicit permissions. Let’s see its permissions:

listpermissions stream1.*

So for now, only the first server has the ability to write to the stream, as well as administrate it. Let’s publish something to it, with key key1:

publish stream1 key1 73747265616d20646174358

The txid of the stream item is returned. Now let’s see that the stream is visible on another node. On the second server:

liststreams

(The root stream was in the blockchain by default.) Now we want the second server to subscribe to the stream, then view its contents:

subscribe stream1
liststreamitems stream1

Now we want the second server to be allowed to publish to the stream. On the first server:

grant 15ZLxwAQU4XFrLVs2hwQz1NXW9DmudRMcyx2ZV send
grant 15ZLxwAQU4XFrLVs2hwQz1NXW9DmudRMcyx2ZV stream1.write

Note that the address needs both general send permissions for the blockchain, as well as permission to write to this specific stream. Now let’s publish a couple of items on the second server:

publish stream1 key1 736f6d65206f746865722064617461
publish stream1 key2 53747265616d732052756c6521

Now let’s query the stream’s contents in many different ways. Back on the first server:

subscribe stream1
liststreamitems stream1 (should show 3 items)
liststreamkeys stream1 (2 keys)
liststreamkeyitems stream1 key1 (2 items with this key)
liststreampublishers stream1 (2 publishers)
liststreampublisheritems stream1 1... (2 items by this publisher)

Reference: https://www.multichain.com/getting-started/

Aj007 SmartContract (Aj007 coin)

Ethereum based Aj007 Smart Contract


pragma solidity 0.4.24;

contract admined{
	address public admin;

	constructor() public {
		admin = msg.sender;
	}
	
	modifier onlyAdmin() { 
		if(msg.sender != admin) revert();
		_;
	}

	function transferAdminship (address newAdmin) onlyAdmin public{
		admin = newAdmin;
	}
}

contract Aj007Base{

	mapping (address => uint256) public balanceOf;
	// allowing others to execute transactions on your behalf
	mapping (address => mapping ( address => uint256)) public allowance;
	
	// balanceOf[address] = 5;
	string public standard = "Aj007 v1.0";
	string public name;
	string public symbol;
	uint8 public decimal; // 1.23 Number of decimal
	uint256 public totalSupply;
	//indexed address passsed will be stored in log memory and not contract data
	event Transfer(address indexed from, address indexed to, uint256 _value);

	constructor (uint256 initialSupply, string tokenName, string tokenSymbol, uint8 decimalUnits) public{
		balanceOf[msg.sender] = initialSupply;
		totalSupply = initialSupply;
		decimal = decimalUnits;
		name = tokenName;
		symbol = tokenSymbol;

	} 

	function transfer (address _to,uint256 _value) public{
		if(balanceOf[msg.sender] < _value) revert();
		//0-255 8 bit
		// 250,10 = 4 Buffer overflow
		if(balanceOf[_to] + _value < balanceOf [_to]) revert();
		// Any number of conditions can be added here
		balanceOf[msg.sender] -= _value;
		balanceOf[_to] += _value;
		// Can be used for debugging values of smart contract and also act as an event for other clients
		// Technically a logging method
		emit Transfer(msg.sender,_to,_value);
	}

	function approve (address _spender, uint256 _value) public returns(bool res){
		allowance[msg.sender][_spender] = _value;
		return true;
	}
	
	function transferFrom (address _from, address _to, uint256 _value) public returns(bool res){
		if(balanceOf[_from] < _value) revert();
		if(balanceOf[_to] + _value < balanceOf[_to]) revert();
		if(_value > allowance[_from][msg.sender]) revert();

		balanceOf[_from] -= _value;
		balanceOf[_to] += _value;

		allowance[_from][msg.sender] -= _value;

		emit Transfer(_from,_to, _value);
		return true;
	}
	
}

contract Aj007 is admined, Aj007Base{

	uint256 public minimumBalanceForAccounts = 5 finney;
	uint256 public sellPrice;
	uint256 public buyPrice;
	mapping (address => bool) public frozenAccount;

	event FrozenFund(address target, bool frozenStatus);
	

	constructor (uint256 initialSupply, string tokenName, string tokenSymbol, uint8 decimalUnits, address centralAdmin) Aj007Base(0,tokenName,tokenSymbol,decimalUnits) public{
		totalSupply = initialSupply;
		if(centralAdmin != 0)
			admin = centralAdmin;
		else
			admin = msg.sender;
		balanceOf[admin]=initialSupply;
		totalSupply = initialSupply;	
	}

	function mintToken (address target, uint256 mintedAmount) onlyAdmin public returns(bool res) {
		balanceOf[target]+= mintedAmount;
		totalSupply += mintedAmount;
		// Notify the total amount is increased
		emit Transfer(0, this, mintedAmount);
		// Notify that the token is added to the given account
		emit Transfer(this, target, mintedAmount);
		return true;
	}

	function freezeAccount (address target, bool freeze) onlyAdmin public{
		frozenAccount[target] = freeze;
		emit FrozenFund(target, freeze);
	}
	
	function transfer (address _to,uint256 _value) public{
		if(msg.sender.balance < minimumBalanceForAccounts){
			//Ensures minimum balance is maintained in account. 
			//If ether amount goes to 0 the transaction cannot be processed further.
			sell((minimumBalanceForAccounts - msg.sender.balance)/sellPrice);
		}
		if(frozenAccount[msg.sender]) revert();
		if(balanceOf[msg.sender] < _value) revert();
		//0-255 8 bit
		// 250,10 = 4 Buffer overflow
		if(balanceOf[_to] + _value < balanceOf [_to]) revert();
		// Any number of conditions can be added here
		balanceOf[msg.sender] -= _value;
		balanceOf[_to] += _value;
		// Can be used for debugging values of smart contract and also act as an event for other clients
		// Technically a logging method
		emit Transfer(msg.sender,_to,_value);
	}

	// Ensure admin frozen accounts wont be able to transfer any coins anywhere
	function transferFrom (address _from, address _to, uint256 _value) public returns(bool res){
		if(frozenAccount[_from]) revert();
		if(balanceOf[_from] < _value) revert();
		if(balanceOf[_to] + _value < balanceOf[_to]) revert();
		if(_value > allowance[_from][msg.sender]) revert();

		balanceOf[_from] -= _value;
		balanceOf[_to] += _value;

		allowance[_from][msg.sender] -= _value;

		emit Transfer(_from,_to, _value);
		return true;
	}

	function setPrices (uint256 newSellPrice, uint256 newBuyPrice) onlyAdmin public returns(bool res){
		sellPrice = newSellPrice;
		buyPrice = newBuyPrice;
		return true;
	}
	
	//Sent Ether's contract gives the buyer tokens (For messageSender who wants to get the token)
	function buy () public payable{
		// convert to wei
		uint256 amount = (msg.value/(1 ether)) / buyPrice;
		// check if smart contract itself has those any coins to transfer
		if(balanceOf[this] < amount) revert();
		balanceOf[msg.sender] += amount;
		balanceOf[this] -= amount;
		emit Transfer(this, msg.sender, amount);
	}
	
	function sell (uint256 amount) public{
		
		// Check if the sender himself has those many tokens
		if (balanceOf[msg.sender] < amount) revert();
		balanceOf[this] += amount;
		// change coin balance of sender
		balanceOf[msg.sender] -= amount;
		if(!msg.sender.send(amount * sellPrice * 1 ether)){
			// revert() will revert all the changes which have been done above
			revert();
		}
		else{
			// Aj007 coin function to receive the coins back to the contract
			emit Transfer(msg.sender, this, amount);			
		}
	}
	
	// Function to have block rewards for mining
	function giveBlockreward () private {
		balanceOf[block.coinbase] += 1;
	}

	// Add the currentChallenge and set difficulty for the blockChain
	bytes32 public currentChallenge;
	uint public timeOfLastProof;
	uint public difficulty = 10**32;

	function proofOfWork (uint nonce) public{
		bytes32 n = keccak256(abi.encodePacked(nonce, currentChallenge));

		// revert() Exception as difficulty alsways has to be greater than the previous 
		if(n < bytes8(difficulty)) revert();

		uint timeSinceLastBlock = (now - timeOfLastProof);
		if(timeSinceLastBlock < 5 seconds) revert();

		// Reward given for every 1 minute here
		balanceOf[msg.sender] += timeSinceLastBlock / 60 seconds;

		//Ensures average mining time is 10 minutes
		difficulty = difficulty * 10 minutes / timeOfLastProof * 1;
		timeOfLastProof = now;

		currentChallenge = keccak256(abi.encodePacked(nonce, currentChallenge,blockhash(block.number-1)));
	}	
}

Ethereum Token/Coin (Aj007)

Ethereum Coin Aj007

Solidity Smart Contract


pragma solidity 0.4.8;
contract Aj007{

	mapping (address => uint256) public balanceOf;
	// allowing others to execute transactions on your behalf
	mapping (address => mapping (address => uint256)) public allowance;
	
	// balanceOf[address] = 5;
	string public standard = "Aj007 v1.0";
	string public name;
	string public symbol;
	uint8 public decimal; // 1.23 Number of decimal
	uint256 public totalSupply;
	//indexed address passsed will be stored in log memory and not contract data
	event Transfer(address indexed from, address indexed to, uint256 _value);

	function  Aj007 (uint256 initialSupply, string tokenName, string tokenSymbol, uint8 decimalUnits){
		balanceOf[msg.sender] = initialSupply;
		totalSupply = initialSupply;
		decimal = decimalUnits;
		name = tokenName;
		symbol = tokenSymbol;

	} 

	function transfer (address _to,uint256 _value){
		if(balanceOf[msg.sender] < _value) throw;
		//0-255 8 bit
		// 250,10 = 4 Buffer overflow
		if(balanceOf[_to] + _value < balanceOf [_to]) throw;
		// Any number of conditions can be added here
		balanceOf[msg.sender] -= _value;
		balanceOf[_to] += _value;
		// Can be used for debugging values of smart contract and also act as an event for other clients
		// Technically a logging method
		Transfer(msg.sender,_to,_value);
	}

	function approve (address _spender, uint256 _value) returns(bool res){
		allowance[msg.sender][_spender] = _value;
		return true;
	}
	
	function transferFrom (address _from, address _to, uint256 _value) returns(bool res){
		if(balanceOf[_from] < _value) throw;
		if(balanceOf[_to] + _value < balanceOf[_to]) throw; if(_value > allowance[_from][msg.sender]) throw;

		balanceOf[_from] -= _value;
		balanceOf[_to] += _value;

		allowance[_from][msg.sender] -= _value;

		Transfer(_from,_to, _value);
		return true;
	}
	
}

Minimum Viable Token (MVT)

Creation of Smart Contract Token on Ethereum Network.

Minimum Viable Token


pragma solidity 0.4.8;
contract Aj007{

mapping (address => uint256) public balanceOf;
// balanceOf[address] = 5;
string public standard = "Aj007 v1.0";
string public name;
string public symbol;
uint8 public decimal;

function Aj007 (uint256 initialSupply){
balanceOf[msg.sender] = initialSupply;
}

function transfer (address _to,uint256 _value){
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;
}

}

Deploy Smart Contract in Ethereum Consortium

This can be done in many ways.

One of the ways is to use the Ethereum Remix IDE

Ethereum Remix IDE: https://remix.ethereum.org/

Remix will auto compile the code if you have selected “Auto Compile” else click on  to compile you code. Now we will deploy this smart contract in Ethereum Consortium Blockchain, which we had created.

Deploy smart contracts on azure ethereum consortium blockchain

To deploy smart contract, we will use Remix only. In remix browser click on “Run” tab, which is located on top right side of screen

From “Environment” drop down select “Web3 Provider”. It will show a pop up like shown below.

Click on OK. Now you need to provide “Web3 Provider Endpoint” for you Ethereum blockchain network. It is the “ethereum-rpc-endpoint”  value which we had saved from Azure portal as part of step1. Paste this value in popup window and click on “OK”.

Now It will show you some values in “Account” dropdown, which was earlier blank. Now we have connected remix IDE with in Ethereum Consortium Blockchain. Lets deploy smart contract. Click on “Create”


Ethereum or Mist Wallet

You can also make use of the Ethereum or mist wallet from your local system and connect to the transactionn node on the remote azure consortium deployment.

Command:

./ethereumwallet --rpc --rpcapi="db,eth,net,web3,personal,web3" ethereum admin side from Consortium deployment

./mist --rpc --rpcapi="db,eth,net,web3,personal,web3" ethereum admin side from Consortium deployment

Eg:./ethereumwallet --rpc --rpcapi="db,eth,net,web3,personal,web3" http://a3uc7l-dns-reg1.eastus.cloudapp.azure.com:8545

The Ethereum/Mist wallet would provide with more convinient UI and access to the remote Transaction node and would facilitate easy deployment of the Smart Contract.

Reference: https://blogs.msdn.microsoft.com/reenusaluja/2018/03/12/deploy-your-first-smart-contract-on-azure-ethereum-consortium-blockchain/

Ethereum Consortium

Proceed with the deployment as stated in the official reference document.

Reference Docs : https://docs.microsoft.com/en-us/azure/blockchain-workbench/ethereum-deployment-guide

#Some usefull commands to access the rpc from remote terminals:

geth --dev --rpc --rpcaddr "0.0.0.0"
geth -rpc --rpcapi="db,eth,net,web3,personal,web3"
geth --dev --rpc --rpcaddr "0.0.0.0" --rpcapi "eth,net,web3,admin,personal" [...]

#You can multiple instance of the Geth on different ports using --port flag and just run all Geth instance with --ipcdisable flag


geth [...] --rpc --rpcport 8546 --rpcaddr "0.0.0.0" --rpcapi "eth,net,web3,admin,personal" [...] --dev

./ethereumwallet --rpc --rpcapi="db,eth,net,web3,personal,web3" http://a3uc7l-dns-reg1.eastus.cloudapp.azure.com:8545

Wallets

Ethereum Wallet: https://github.com/ethereum/mist/releases

Mist: https://github.com/ethereum/mist/releases

MetaMask: https://metamask.io/