NEWS

How to create your own Blockchain?

What is the best way of learning if not creating something on your own? So to learn a blockchain just create one by yourself!

Introduction

Ethereum mainnet is working on the basis of Proof of Work consensus engine. How does it work is a topic for another blog post :). This time we will concentrate on private blockchain working on the basis of Proof of Authority consensus engine.

In Proof of Authority, some nodes act as authorities. Only those entities are able to issue and confirm new blocks – they are trusted by the rest of the network.

Prerequisites

To start your Blockchain network, you need to have Ethereum client. Our choice will be Parity. To download it, when using MacOs, first install homebrew by executing

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

The proceed with Parity installation

brew tap paritytech/paritytech
brew install parity --stable

When using Linux, download Parity from here using the following command

wget wget https://parity-downloads-mirror.parity.io/v1.7.9/x86_64-unknown-linux-gnu/parity_1.7.9_amd64.deb

then execute

sudo dpkg -i parity_1.7.9_amd64.deb

When finished with above commands, type  parity in your terminal. This will start Parity node, connected with main Ethereum blockchain, starting to sync with it.

Private Blockchain

You can start your blockchain in different chains. One of them is Ethereum Foundation blockchain, which is the main one. Another one can be Kovan, which is
the test equivalent of mainnet . You can also choose Ethereum Classic chain. Why Ethereum consist of two chains? This is a question for the separate blog post :).

All above are public chains. To create your first, private node simply execute

parity --chain dev

Voilla, your node is starting, you have just created your first private blockchain!

Ok, now we need to get serious. When you want to start your private Blockchain, different than development node, you need to specify its “chain” specification.

In PoA, some nodes act as authorities. It means that they are some entities who are trusted to issue new blocks and validate the network.

In your chain, you can either list the validators or issue a special smart contract, that contains the list of validators. As the second option adds some flexibility, we will use it. By using validation contract, you can add or remove validators even after the chain is deployed! This is not the case with standard validators list.

What we will do, is use Parity sample AdminList contract. Idea is that one of the authorities is an Admin who is able to add new authorities to the network.

First, before chain deployment, a contract needs to be provided with admin address. To start with, we need some account that will be a validator (authority).

To create admin account, start Parity in development mode with JSON-RPC protocol method calling enabled

parity --chain dev --jsonrpc-apis all

You need to create your admin account that will validate the blocks. Execute following in another terminal window (making sure you have cUrl installed)

curl --data '{"jsonrpc":"2.0","method":"parity_newAccountFromPhrase","params":["this is such a great tutorial", "superSecretPassword"],"id":0}' -H "Content-Type: application/json" -X POST localhost:8545

First parameter is a recovery phrase of the account the second one is your password. Account address is deterministic so the answer you will get is probably

{"jsonrpc":"2.0","result":"0x0013632dfb5759bed171abd94057894b80c07304","id":0}

How our validation Smart Contract code will look like?

pragma solidity ^0.4.8;

// Some addresses are admins.
// Admin can add or remove another admin or a validator.

contract AdminList {
// EVENTS
event ValidatorsChanged(bytes32 indexed parent_hash, uint256 indexed nonce, address[] new_set);
event Report(address indexed reporter, address indexed reported, bool indexed malicious);

/// Admin status.
mapping(address => bool) public isAdmin;
/// Last block at which the validator set was altered.
uint public lastTransitionBlock;
/// Number of blocks at which the validators were changed.
uint256 public transitionNonce;
// Current list of addresses entitled to participate in the consensus.
address[] public validatorsList;
// Tracker validator indices.
mapping(address => uint) validatorIndex;

// Each validator is initially supported by all others.
function AdminList() {
isAdmin[0x0013632dfb5759bed171abd94057894b80c07304] = true;
validatorsList.push(0x0013632dfb5759bed171abd94057894b80c07304);

for (uint i = 0; i < validatorsList.length; i++) {
address validator = validatorsList[i];
validatorIndex[validator] = i;
logTransition();
}
}

// Called on every block to update node validator list.
function getValidators() constant returns (address[]) {
return validatorsList;
}

function logTransition() private {
incrementTransitionNonce();
ValidatorsChanged(block.blockhash(block.number - 1), transitionNonce, validatorsList);
}

function incrementTransitionNonce() private on_new_block {
lastTransitionBlock = block.number;
transitionNonce += 1;
}

// ADMIN FUNCTIONS

// Add a validator.
function addValidator(address validator) only_admin {
validatorIndex[validator] = validatorsList.length;
validatorsList.push(validator);
logTransition();
}

// Remove a validator.
function removeValidator(address validator) only_admin {
uint removedIndex = validatorIndex[validator];
// Can not remove the last validator.
uint lastIndex = validatorsList.length-1;
address lastValidator = validatorsList[lastIndex];
// Override the removed validator with the last one.
validatorsList[removedIndex] = lastValidator;
// Update the index of the last validator.
validatorIndex[lastValidator] = removedIndex;
delete validatorsList[lastIndex];
validatorsList.length--;
// Reset validator status.
validatorIndex[validator] = 0;
logTransition();
}

// Add an admin.
function addAdmin(address admin) only_admin {
isAdmin[admin] = true;
}

// Remove an admin.
function removeAdmin(address admin) only_admin {
isAdmin[admin] = false;
}

// MISBEHAVIOUR HANDLING

// Called when a validator should be removed.
function reportMalicious(address validator) only_admin {
Report(msg.sender, validator, true);
}

// Report that a validator has misbehaved in a benign way.
function reportBenign(address validator) only_admin {
Report(msg.sender, validator, false);
}

// MODIFIERS

modifier only_admin() {
if (!isAdmin[msg.sender]) throw; _;
}

modifier on_new_block() {
if (block.number > lastTransitionBlock) _;
}

// Fallback function throws when called.
function() payable {
throw;
}
}

 

This is nearly the same as the code provided by Parity. Only change can note, that the address we have generated, was placed inside isAdmin mapping and pushed inside validatorsList.

Now, you have to compile your code. You can use truffle framework, solc or one of the online IDE-compilers.

After compilation, bytecode of our validation smart contract looks like this :

c606060405234156200001057600080fd5b60008060016000807213632dfb5759bed171abd94057894b80c0730473ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600380548060010182816200007d9190620002a8565b916000526020600020900160007213632dfb5759bed171abd94057894b80c07304909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050600091505b600380549050821015620001a0576003828154811015156200010257fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555062000192620001a86401000000000262000a82176401000000009004565b8180600101925050620000e4565b5050620002ff565b620001c6620002826401000000000262000b44176401000000009004565b6002546001430340600019167f47e91f47ccfdcb578564e1af55da55c5e5d33403372fe68e4fed3dfd385764a16003604051808060200182810382528381815481526020019150805480156200027257602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001906001019080831162000227575b50509250505060405180910390a3565b600154431115620002a6574360018190555060016002600082825401925050819055505b565b815481835581811511620002d257818360005260206000209182019101620002d19190620002d7565b5b505050565b620002fc91905b80821115620002f8576000816000905550600101620002de565b5090565b90565b610c26806200030f6000396000f3006060604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063170f9291146100b45780631785f53c1461011757806324d7806c14610150578063303e98e5146101a15780633d296efe146101ca57806340a141ff146101f35780634d238c8e1461022c5780637048027514610265578063b7ab4db51461029e578063bfc708a014610308578063fd6e1b5014610341575b600080fd5b34156100bf57600080fd5b6100d5600480803590602001909190505061037a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561012257600080fd5b61014e600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506103b9565b005b341561015b57600080fd5b610187600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061046a565b604051808215151515815260200191505060405180910390f35b34156101ac57600080fd5b6101b461048a565b6040518082815260200191505060405180910390f35b34156101d557600080fd5b6101dd610490565b6040518082815260200191505060405180910390f35b34156101fe57600080fd5b61022a600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610496565b005b341561023757600080fd5b610263600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506106bf565b005b341561027057600080fd5b61029c600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506107cd565b005b34156102a957600080fd5b6102b161087e565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156102f45780820151818401526020810190506102d9565b505050509050019250505060405180910390f35b341561031357600080fd5b61033f600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610912565b005b341561034c57600080fd5b610378600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506109ca565b005b60038181548110151561038957fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561041057600080fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60006020528060005260406000206000915054906101000a900460ff1681565b60025481565b60015481565b60008060008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615156104f257600080fd5b600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549250600160038054905003915060038281548110151561054e57fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060038481548110151561058c57fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060038281548110151561062857fe5b906000526020600020900160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600380548091906001900361066b9190610b69565b506000600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506106b9610a82565b50505050565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561071657600080fd5b600380549050600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600380548060010182816107739190610b95565b9160005260206000209001600083909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506107ca610a82565b50565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561082457600080fd5b60016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b610886610bc1565b600380548060200260200160405190810160405280929190818152602001828054801561090857602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116108be575b5050505050905090565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561096957600080fd5b600115158173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f32c78b6140c46745a46e88cd883707d70dbd2f06d13dd76fe5f499c01290da4f60405160405180910390a450565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610a2157600080fd5b600015158173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f32c78b6140c46745a46e88cd883707d70dbd2f06d13dd76fe5f499c01290da4f60405160405180910390a450565b610a8a610b44565b6002546001430340600019167f47e91f47ccfdcb578564e1af55da55c5e5d33403372fe68e4fed3dfd385764a1600360405180806020018281038252838181548152602001915080548015610b3457602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610aea575b50509250505060405180910390a3565b600154431115610b67574360018190555060016002600082825401925050819055505b565b815481835581811511610b9057818360005260206000209182019101610b8f9190610bd5565b5b505050565b815481835581811511610bbc57818360005260206000209182019101610bbb9190610bd5565b5b505050565b602060405190810160405280600081525090565b610bf791905b80821115610bf3576000816000905550600101610bdb565b5090565b905600a165627a7a72305820a8ebbe55ad842d706116a4bd1720d6184444513036fd36f6278804d5800483af0029

Now, when we have our contract ready, we can move to chain specification.

Chain specification

Our sample chain definition will look like this

{
"name": "myfirstblockchain",
"engine": {
"authorityRound": {
"params": {
"gasLimitBoundDivisor": "0x400",
"stepDuration": "5",
"validators": { "safeContract": "0x0000000000000000000000000000000000000010" }
}
}
},
"params": {
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID" : "0x2222"
},
"genesis": {
"seal": {
"authorityRound": {
"step": "0x0",
"signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
}
},
"difficulty": "0x20000",
"gasLimit": "0x5B8D80"
},
"accounts": {
"0x0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
"0x0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
"0x0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0x0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"0x0013632dfb5759bed171abd94057894b80c07304": { "balance": "1606938044258990275541962092341162602522202993782792835301376" },
"0x0000000000000000000000000000000000000010": { "balance": "1", "constructor" : "606060405234156200001057600080fd5b60008060016000807213632dfb5759bed171abd94057894b80c0730473ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600380548060010182816200007d9190620002a8565b916000526020600020900160007213632dfb5759bed171abd94057894b80c07304909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050600091505b600380549050821015620001a0576003828154811015156200010257fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555062000192620001a86401000000000262000a82176401000000009004565b8180600101925050620000e4565b5050620002ff565b620001c6620002826401000000000262000b44176401000000009004565b6002546001430340600019167f47e91f47ccfdcb578564e1af55da55c5e5d33403372fe68e4fed3dfd385764a16003604051808060200182810382528381815481526020019150805480156200027257602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001906001019080831162000227575b50509250505060405180910390a3565b600154431115620002a6574360018190555060016002600082825401925050819055505b565b815481835581811511620002d257818360005260206000209182019101620002d19190620002d7565b5b505050565b620002fc91905b80821115620002f8576000816000905550600101620002de565b5090565b90565b610c26806200030f6000396000f3006060604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063170f9291146100b45780631785f53c1461011757806324d7806c14610150578063303e98e5146101a15780633d296efe146101ca57806340a141ff146101f35780634d238c8e1461022c5780637048027514610265578063b7ab4db51461029e578063bfc708a014610308578063fd6e1b5014610341575b600080fd5b34156100bf57600080fd5b6100d5600480803590602001909190505061037a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561012257600080fd5b61014e600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506103b9565b005b341561015b57600080fd5b610187600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061046a565b604051808215151515815260200191505060405180910390f35b34156101ac57600080fd5b6101b461048a565b6040518082815260200191505060405180910390f35b34156101d557600080fd5b6101dd610490565b6040518082815260200191505060405180910390f35b34156101fe57600080fd5b61022a600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610496565b005b341561023757600080fd5b610263600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506106bf565b005b341561027057600080fd5b61029c600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506107cd565b005b34156102a957600080fd5b6102b161087e565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156102f45780820151818401526020810190506102d9565b505050509050019250505060405180910390f35b341561031357600080fd5b61033f600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610912565b005b341561034c57600080fd5b610378600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506109ca565b005b60038181548110151561038957fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561041057600080fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60006020528060005260406000206000915054906101000a900460ff1681565b60025481565b60015481565b60008060008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615156104f257600080fd5b600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549250600160038054905003915060038281548110151561054e57fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060038481548110151561058c57fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060038281548110151561062857fe5b906000526020600020900160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600380548091906001900361066b9190610b69565b506000600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506106b9610a82565b50505050565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561071657600080fd5b600380549050600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600380548060010182816107739190610b95565b9160005260206000209001600083909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506107ca610a82565b50565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561082457600080fd5b60016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b610886610bc1565b600380548060200260200160405190810160405280929190818152602001828054801561090857602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116108be575b5050505050905090565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561096957600080fd5b600115158173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f32c78b6140c46745a46e88cd883707d70dbd2f06d13dd76fe5f499c01290da4f60405160405180910390a450565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610a2157600080fd5b600015158173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f32c78b6140c46745a46e88cd883707d70dbd2f06d13dd76fe5f499c01290da4f60405160405180910390a450565b610a8a610b44565b6002546001430340600019167f47e91f47ccfdcb578564e1af55da55c5e5d33403372fe68e4fed3dfd385764a1600360405180806020018281038252838181548152602001915080548015610b3457602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610aea575b50509250505060405180910390a3565b600154431115610b67574360018190555060016002600082825401925050819055505b565b815481835581811511610b9057818360005260206000209182019101610b8f9190610bd5565b5b505050565b815481835581811511610bbc57818360005260206000209182019101610bbb9190610bd5565b5b505050565b602060405190810160405280600081525090565b610bf791905b80821115610bf3576000816000905550600101610bdb565b5090565b905600a165627a7a72305820a8ebbe55ad842d706116a4bd1720d6184444513036fd36f6278804d5800483af0029" }

}
}

 

What parameters are the most important for you to understand?

  • engine – we will use Proof of Authority consensus engine. Each authority will have given time to issue a new block. As per stepDuration, blocks will be issued every 5 seconds. Validators consist are listed in and managed by validation contract, which is located under address `0x0000000000000000000000000000000000000010`. gasLimitBoundDivisor has standard value.
  • params – two first parameters are to be kept default. NetworkID is to be changed when you are creating your own network, to avoid collisions. At this moment, you can leave this parameter as it is.
  •  genesis – this is a description of data that will be put to genesis block. Please note that difficulty is not so important for us, as we are operating on Proof of Authority, not Proof of Work consensus.
  • accounts – accounts that come with genesis block. First four of them are to be able to use Solidity as a programming language, the last one is a compiled validation contract, that we created before (which consist created account admin details). Also, our admin account address is there – we top it up with lots of ether :).
    If you are interested about the rest of parameters, you can read about those here and here

Starting up the nodes

Ok, so we have nearly all that we need to start a private PoA blockchain. Follow to the folder, where you Parity node stores blockchain information. For MacOs it will be

~/Library/Application\ Support/io.parity.ethereum

For Linux

~/.local/share/io.parity.ethereum/

From now on, all commands are to be executed in those folders (to simplify the commands and avoid adding paths to chain spec and password files).

Then, create a file called myfirstblockchain.json
and put our chain spec in it.

Now you can start your network by executing

parity --chain myfirstblockchain.json --jsonrpc-apis all

Congratulations! You just started your node in PoA private blockchain!

Still, it will not work correctly. There is no authority account stored in your chain data. What you need to do, is either move the account details, that you created before in development chain to your “myfirstblockchain” chain key folder or recreate the same account on this particular private blockchain. We will choose option two, to make it simple.

Make sure you are running Parity with your chain spec ( with above command), and in new terminal window, execute

curl --data '{"jsonrpc":"2.0","method":"parity_newAccountFromPhrase","params":["this is such a great tutorial", "superSecretPassword"],"id":0}' -H "Content-Type: application/json" -X POST localhost:8545

This will result in

{"jsonrpc":"2.0","result":"0x0013632dfb5759bed171abd94057894b80c07304","id":0}

That means your account was recreated on your private blockchain. As we said, this command is deterministic so same address is given ( remember, it is already stored in your chain spec and validation contract)

That means your account was recreated on your private blockchain. Now, shut the Parity node down. To allow the authority node to issue new blocks, he needs to be supplied with the password, in order to use authority account private key automatically.

What you need to do, is to in your Parity blockchain data folder, create file “secretPassword.pwds” and put your account password inside it (superSecretPassword). It may seem not really secure, but the idea is that as soon as the authority machine is compromised, it should not be an authority anymore. So more secure password storage does not give us anything more in this particular point.

Ok, so we are nearly at the end. Now we need to start out first Parity node. In your Parity data files folder, execute the following command

parity --chain myfirstblockchain.json --port 30300 --jsonrpc-port 8450 --ui-port 8180 --ws-port 8540 --jsonrpc-apis all --ui-no-validation --gasprice 0 --engine-signer 0x0013632dfb5759bed171abd94057894b80c07304 --password secretPassword.pwds

What it will do, is start your Parity node using provided chain spec. UI, RPC, WebSockets will have ports specified by you (8180,8450,8540), Parity will discover other nodes on port 30300. UI will provide no validation (development mode only!). Gas is for free!

What last two commands do, is provide information for node who is the PoA engine block signer and the path to file with his password.

Ok, we have our node started! Most probably you will encounter “Bad instruction fd” error. This is due to Parity updated their validation contract interface. As it comes to development environment is fine, but for real case we would suggest using
majority list contract which is up to date, not causing any errors. The problem is that it is combined with libraries, so the user needs to know how to add compiled library to validation contract node – this is out of scope for this tutorial.

Ok, now it is time to start the second node. To do this execute following in new terminal window

parity --chain myfirstblockchain.json -d /tmp/parity0 --port 30301 --jsonrpc-port 8451 --ui-port 8181 --ws-port 8541 --jsonrpc-apis all --ui-no-validation

So this Parity node instance will use temporary data folder. Also please note that SAME chain spec needs to be used for all nodes in the network, that are to be connected to the private blockchain! Engine signer data is not needed as this node will not issue new blocks.

You have two Parity nodes running. Your own private blockchain is up :)! Now you need to connect them.

When starting, each Parity node has its enode address listed (as Public node URL).

This is used to discover other nodes on the network. You can use curl and RPC  to connect new nodes by executing

curl --data '{"jsonrpc":"2.0","method":"parity_addReservedPeer","params":["ENODEADDRESS"],"id":0}' -H "Content-Type: application/json" -X POST localhost:8541

By changing the ENODEADDRESS and RPC port accordingly. This has to be done for each node!

For me, two commands are to be executed

curl --data '{"jsonrpc":"2.0","method":"parity_addReservedPeer","params":["enode://6aa5a05298287fd1985df3cdcecb99a28f7b52248ff682ef45b6401574b5c1af8c5a7296c9433af9002a96e9b90c7e0f7d6b48c6002419f30ecbd27c951e49be@192.168.1.155:30301"],"id":0}' -H "Content-Type: application/json" -X POST localhost:8450
curl --data '{"jsonrpc":"2.0","method":"parity_addReservedPeer","params":["enode://21def0a911d822e759285a082e6073afdbac3b9d3b74a08a72f6efd3074ac2e961d3a6c68da9559f6e98c24eb019407a89159ab533763f495d5d66d15c14155f@192.168.1.155:30300"],"id":0}' -H "Content-Type: application/json" -X POST localhost:8451

For both requests, you should see the following response {"jsonrpc":"2.0","result":true,"id":0}.

In logs, you will see 1 node connected.

Now, two local Parity nodes, working in PoA consensus system are connected and ready to work.

Executing the transaction

Now you can proceed to the UIs to execute Ether transfer. We will transfer Ether from one account, located on node 1 to another located on node 2. Note that Parity accounts are stored separately on each node but Blockchain public addresses are available on both. You can, for example, restore an account from the second node on the first one.

UI for the first Parity node is located under http://127.0.0.1:8180/.

UI for the second node can be found underhttp://127.0.0.1:8181/.

It may happen that UI will query you for authorization token. To generate it for first authority node, execute

curl --data '{"method":"signer_generateAuthorizationToken","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8450

Copy the result to the browser.

For the second node, command would be

curl --data '{"method":"signer_generateAuthorizationToken","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8451

When proceeding to status tab, you will see details about other node connected.

Now, what we can do is create an account on node 2 (that is not supposed to issue block as it is not authority), and try to send him some founds from node1.

On node2 UI, follow the tutorial and create your new account.

Grab its address.

Now, follow to UI 1, and enter the authority account.

Transfer money to account from UI 2. Unlock the account with “superSecretPassword”

After a moment, you will get confirmation that was transaction was mined! You can go to Signer tab to see it

 

Now proceed to UI 2 and check out that your account is rich now 🙂

Congratulations! You have just executed your first Ether transfer transaction on your private blockchain! Now you can use it for test development of your application or anything you want. Code created in this post is available here.

Getting started with IOTA

In the previous post we took a first glance at IOTA ledger. Although the plans are great, currently the project is in its incubation phase, with the majority of the most attractive features not yet ready to use. But this shouldn’t stop us from playing with what we already have today.

Before we dig into the code, we need to get connected to one of the two IOTA networks. The “proper” network is called mainnet and there is also a slightly more relaxed one called testnet. As the names suggest, the latter is for test purposes. Each network consists of the multiple nodes that are run by the community. In order to join the network, we either need to run our own node or to connect to the existing node using its public API.

Is node a node?

If we’re tech savvy enough and we have decided to become an active part of the IOTA network, we need to have our node up and running. IOTA’s terminology avoids using “node” name for what they offer now. The only software that is able to run as a part of the network is called “IOTA Reference Implementation” (IRI) – my guess is that it is intended to suggest clearly that the project is still in its infancy and everything might change over time.

IRI is written in Java and is publicly available on GitHub as GPL-licenced open source. Requiring a full Java JRE to run a node is probably one of the reasons IOTA is not yet feasible for real IoT usage. We can choose to run it either from a JAR file provided or – which sounds more appealing to me – using Docker image.

Let’s roll

To build and run the Docker image, type the following:

docker run -d --name iota-node \
  -p 14265:14265 -p 14777:14777/udp -p 15777:15777 \
  -v ~/iota.ini:/iri/iota.ini iotaledger/iri:v1.4.0

We’re creating a container named iota-node for an easy future access. With -p options we’re exposing three custom network ports for external communication. And with -v we’re passing a path to our node’s configuration file that should look as follows:

[IRI]
PORT = 14265
UDP_RECEIVER_PORT = 14777
TCP_RECEIVER_PORT = 15777
NEIGHBORS = [space-separated list of neighbors]
IXI_DIR = ixi
HEADLESS = true
DEBUG = true
DB_PATH = mainnetdb

Here we have the communication ports specified again. They deserve an explanation as its purposes and usage are not obvious and the official docs are not helpful.

The first one – named cryptically PORT – is used to expose our node’s HTTP API. It is useful to configure, orchestrate and monitor our node, but it should not necessarily be exposed to the public internet. We should leave it available from inside the Docker container just for us, but it is not necessary to expose it on our external firewall.

UDP_RECEIVER_PORT and TCP_RECEIVER_PORT are ports that need to be exposed via the firewall – so ensure your router or ISP allows you to configure public traffic over these ports to reach your node. IRI uses UDP by default with TCP fallback – technically, only one of these channels need to be reachable. UDP adds less overhead but TCP in some cases is easier to set up and debug.

Get along with your neighbors

We now have a stranded process running in the void. It’s time to find other nodes we can connect to and sync the state of the Tangle with it. These other nodes are called “neighbors” and we need to maintain a two-way channel between us and our neighbors. As of today, the only way to get some neighbors is to ask the friendly people on #nodesharing IOTA’s Slack channel for a way in. When asked during the European’s daytime, I got some responses in less than an hour.

When you’re already befriended with other nodes owners, you need to give them the publicly available address of your host – most probably looking like udp://12.23.34.45:14777. Note we’re specifying the UDP protocol here and using a corresponding receiver port from our INI file. Our neighbors should give us their addresses, also for UDP protocol (if we decide to use UDP, that is – for TCP, both sides should use TCP protocol and ports, obviously).

To add a neighbor, include its address in your iota.ini file, in NEIGHBORS field, as a space-separated list and restart your node. Alternatively, you can use your node’s HTTP API method to add a neighbor dynamically.

After this is done, try calling getNeighbors to see what’s going on. If everything goes right, the number of all transactions should grow pretty quickly. Now just go for a long lunch (possibly including a dinner) and when you’re back, you’ll be in sync with the network, being a part of IOTA ecosystem. Hooray!

Light Node

There is also the wallet client app (also called “light node”), but its use is restricted to token trading. It requires a connection to the existing node’s HTTP API (this one exposed via port defined in PORT – 14265 in my example). But we’re geeks, we care about tech stuff more than about trading ?.

Speaking of the node’s HTTP API again. If it’s there, we might also use it directly on our own, right? Sure we can. Stay tuned for the next post in the series where we’ll submit a Hello World transaction to IOTA from a Node.JS application.

A post by Adam Bar

IOTA – a new kid in the cryptocurrency town

At Baltic Data Science, we always try to keep focus on the bleeding-edge technologies and innovations. We are especially interested in cryptocurrencies and its prospective wide usage in the industry, not only as a payment method. We already have some experience with Ethereum and Hyperledger as a Blockchain-based app platform, so we were curious what can IOTA offer.

IOTA’s marketing offerings are very prominent. It calls itself “a backbone of IoT” and promises scalability, decentralization, modularity and the lack of transactional fees. Its primary goal is to enable the “Economy of Things” – an environment in which the IoT devices might conduct secure, verifiable and reliable automated transactions for even the smallest amounts. It is not feasible with other cryptocurrency-based technologies because of the transaction fees that would be possibly larger than the amount exchanged.

What IOTA is (or plans to be)?

First of all, technically speaking, contrary to Bitcoin, Ethereum or Hyperledger, it is not a blockchain-basedsolution, because transactions do not require blocks to be formed nor do they create a single chain of blocks. Instead, each transaction is a separate node in the tree-shaped graph of transactions. Every transaction references two earlier transactions that exist in the tree, confirming its validity (by verifying its proof-of-work). This directed tree-shaped graph in IOTA is called the Tangle.

This way, at least theoretically, the whole system is self-validating and the approval process is decoupled from any authority and decentralized. It is also a way to get rid of the transaction fees – all the nodes participating in the network have the incentive to verify proof-of-works of other transactions because it is required in order to submit own transactions to the network.

Scalability, the next major promise of IOTA, is theoretically guaranteed by the fact that it is not required for the node to know the state of the whole Tangle tree – the tree can grow asynchronously in many directions. The assumption is that the separate branches will be eventually “entangled” together and cross-validated by the future transactions. This idea allows nodes to work in a non-fully synced state – this is especially useful in the context of IoT devices that might encounter being offline for a myriad of reasons.

The current state of affairs

Let’s leave the marketing buzz from the landing page and check how all these promises work in today’s reality. The project itself is quite young – the initial commit of the node implementation is not even a year old (Oct 2016). And while the project is really dynamic, it is still in the very early phase. If you count on any detailed reference or deep-dive instructions – you will be disappointed. All you can find is a theoretical academic whitepaper, coarse and partial definitions of terms, API reference and a vibrant Slack community that serves as an announcement board and the only way to have the node connected to the network. For all the rest you need to either dig through the source code or count on the community on Slack to help you.

It turns out that the other theoretical goals are also far from being met in practice.

Decentralization

The pure IOTA Tangle is vulnerable to the attack that enables verification of invalid transactions by generating large enough sub-branch of the tree consisting of fake transactions so that the branch overweights the original, legitimate transactions branch, making it orphaned and leading to the approval of the double-spending transaction.

As of October 2017, there is a single designated node in the IOTA network, called Coordinator, that ensures the consistent state of the ledger, re-validating all the transactions and periodically generating a “Milestone mark” that is intended to indicate the “correct” branch of the Tangle tree. A Milestone is a special transaction, issued by the designated Coordinator node, which marks all the transactions it directly or indirectly approves as trusted.

The existence of Coordinator makes IOTA not fully decentralized by now and prevents from having a private ledger networks, because its address is hardcoded into the IRI (reference node implementation) and its source is not disclosed.

It is said that the existence of the Coordinator is a temporary measure, until the protocol stabilizes and the network gets a certain size making it unfeasible to take over, but no due date is given.

IoT app platform

The idea of the IOTA system is to be possible to run it directly on IoT devices. It is not yet possible to run the full node on Raspberry Pi, though. However, it should be possible to run the thin client that connects to the external node.

What is important, IOTA cannot serve as an app platform as long as there’s no Smart Contract functionality there. It is planned, but it doesn’t seem to be reasonable to expect it soon.

What next?

Even if the number of ToD’s on the IOTA team’s list is long, there are definitely some parts that can be used even today.

In our next post, we’ll look into the ways we can interact with the Tangle, even in its current state of maturity.

A post by Adam Bar.

IOTA – Hello World

Previously in the IOTA series we’ve looked into the assumptions of this promising cryptocurrency system and we’ve connected to the network with our own node. It’s high time to interact with IOTA programatically.

IOTA nodes (or, actually, as the creators of the system prefer to call it – IOTA Reference Implementations) expose an HTTP API that we can interact with and – unlike most of the IOTA’s ecosystem – has an actual documentation available. But while it is indispensable to look into this reference, we’ll rather use the client libraries to talk to our node.

There are three official client libraries out there at the moment and the most mature one is apparently the one we’d like to use – a JavaScript one called iota.lib.js. It is basically a wrapper for the API endpoints.

Talking to node using Node

Let’s start with the empty Node.JS project that we can bootstrap using npm init. Then install IOTA’s library with npm install iota.lib.js --save and jump into the code.

To establish a connection, we need to specify where is our IRI, including the public API port (specified as PORT in the node’s config file or as -p if passed from command line). Note that by default we don’t need any credentials here – that’s why it is important to keep our node’s API port hidden from the external network or configured properly with --remote-auth and --remote-limit-api configuration options to avoid everyone to mess with our beloved node.

const IOTA = require('iota.lib.js')
const iota = new IOTA({
    host: 'http://192.168.1.162',
    port: 14265
})

Now let’s see what our node tells us about itself using getNodeInfo call. All the API calls adhere to the clumsy Node.JS callback passing convention:

iota.api.getNodeInfo((error, nodeInfo) => {
    if (error) {
        console.error('getNodeInfo error', error)
    } else {
        console.log('getNodeInfo result', nodeInfo)
    }
}

What we’ll get in return, apart from the node’s version and footprint information, is the processing state – whether there are any pending transactions to transmit and what is the latest milestone known to our node. This latter value should change every several minutes if our node is in sync with the network.

Where’s my wallet?

Addresses in IOTA can be understood as distinct wallets that can store IOTA tokens. These are long enough strings, so that it’s totally fine to generate it on your own and – in practice – be sure about its uniqueness.

In order to claim the ownership of a given address, we need to have the seed it was generated from – think of the seed as a private key to your box with wallets. The seed needs to be generated securely, probably not using the public websites that does it for you. The easiest would probably be to use macOS/Linux terminal and run:

cat /dev/urandom | LC_ALL=C tr -dc 'A-Z9' | fold -w 81 | head -n 1

Now, the thing we got back, looking similar to FNCWNXJWJIVDGPRWNZYKOMKNIIATPPDKEVCZEWSZTEVIWJFCOUV9PJD9AUCEVQLFEAI9UBUAVQKVEBLKN, is our seed. We’re responsible for storing it securely and privately because it gives a full access to all the addresses (wallets) we’ll create using it.

To actually generate the address we can use to send transactions to, let’s use our API:

const seed = 'FNCWNXJWJIVDGPRWNZYKOMKNIIATPPDKEVCZEWSZTEVIWJFCOUV9PJD9AUCEVQLFEAI9UBUAVQKVEBLKN' // keep it secure!
iota.api.getNewAddress(seed, (error, address) => {
   if (error) {
       console.error('getNewAddress error', error)
   } else {
       console.log('new address generated: ' + address)
   }
})

Spending the tokens

We’re now ready to submit our first transaction, or – how the API calls it – the transfer. Apart from the monetary value (which can be zero), we can attach a message to our transaction. The message needs to be tryte-encoded – we don’t need to care much about it fortunately as we have a helper method for this task: iota.utils.toTrytes.

The code to send our transaction to the IOTA’s tangle is as follows:

const Depth = 3 // constant defined by IOTA - how deep to look for the tips in the Tangle
const MinWeightMagnitude = 16 // constant defined by IOTA - the difficulty of PoW

const transfers = [
    {
        // where are we sending the transaction to?
        address: 'CHNLHJCYBZCYUI9DTHINDDWHNJWFCHQOTGABXFVZQHXF9BROTOIJZJSBXOVKCDGCXZTDDJUVTYBJZYAOH',
        
        // how many tokens are we transferring?
        value: 42,
        
        // do we want to comment on this transaction?
        message: iota.utils.toTrytes('Hello World!')        
    }
]

const options = {
    // addresses of the wallets we're using to fund this transfer
    inputs: ['ZISNLNSKMPDOORSSFRCBGQOPY9BI9SONMTDHJJDWBTTCYLFV9PQ9VSWNI9FHEAEFGROGZ9YHSMZYOGFQG']
}

iota.api.sendTransfer(seed, Depth, MinWeightMagnitude, transfers, options, (error, transactions) => {
  if (error) {
     console.error('sendTransfer error', error)
  } else {
     console.log('transactions sent!', transactions)
  }
})

We need to specify where we send our tokens with message to and which of (our) wallets the tokens come from (if we’re sending non-zero value). In the response, we get a transaction object for each transferobject we’ve submitted.

Attaching to the IOTA's Tangle

If we’re lucky, we should be able to get the transaction’s hash property, paste it at one of the online Tangle viewers and see the details of our transaction. It will be most probably in the “Pending” state. This means the transaction was properly attached to the Tangle, although it wasn’t yet validated by other transactions in the Tangle tree and we need to wait a bit. Normally it gets into “Confirmed” state within a few minutes and we can call it a day.

But we might be not that lucky and our transaction might get attached to the part of the tree that will never be validated, either because there were too many tips in the Tangle tree waiting for validation so that it gets “forgotten” by the tip selection algorithm (the tip selection algorithm is biased towards the transactions from the top of the tree) or it happened to get attached to the subtree that yielded incorrect.

In these cases our transaction never goes away from the “Pending” state and we need to fix the problem by “reattaching” our transfers (called “bundle”) to another part of the Tangle tree. In order to do so, we can periodically run the code that might look like:

iota.api.getLatestInclusion([hash], (error, inclusionStates) => {
  if (error) {
     console.error('getLatestInclusion error', error)
  } else if (inclusionStates[0]) {
     console.log('transaction is included (confirmed)! yay!') 
  } else {
     iota.api.replayBundle(hash, Depth, MinWeightMagnitude, (error, replayTransactions) => {
         // ad infinitum...?
     })
  }
})

This procedure might look strange, as we’re actually adding more and more duplicates to the Tangle – replay transaction is a separate transaction. We now probably need to track the “inclusion state” (status) of both the original and the replay transaction. We also need to replay it once again in case it doesn’t get validated within a few minutes. All this comes with the cost of issuing a new transaction, but this is actually beneficial to the IOTA network as a whole because by doing this we’re confirming another pair of transactions. And there are double-spending validation schemes implemented that ensures only one of the transactions will be finally confirmed.

A post by Adam Bar.

UN’s World Food Programme WFP Appoints Baltic Data Science As Partner In Building Blocks Project

Baltic Data Science has formally been appointed by WFP to support them on the scale-up of the Building Blocks project.

We are very proud to announce that we have been appointed by the World Food Programme to continue our technical support to further roll-out the existing Building Blocks platform. At the beginning of the this year, we together with the Munich-based blockchain solutiins firm Datarella started to transform a proof-of-concept into a fully-functional blockchain-based transaction platform in Jordan. The inhabitants receive food vouchers that can be used in the village’s supermarket.

So what are the benefits compared to traditional transaction payments? Thanks to the blockchain technology, our innovative system provides higher transparency of aid accounts for beneficiaries and easy tracking of transaction which helps to lower the effort of bookkeeping for vendors and WFP. The biggest, however invisible, advantage is a minimized risk of fraud or data mismanagement.

We want to thank WFP for their trust and are looking forward to supporting them on their next phase scaling up and expanding the Building Blocks project further into other countries and markets.

If you want to learn more about our services or specifically this project, please contact us at info (at) balticdatascience.com.

About WFP:
The United Nations World Food Programme “WFP”, with its Headquarters located in Rome, Italy is the world’s largest humanitarian agency fighting hunger worldwide. WFP is mandated to deliver the food necessary to save the lives of victims of natural disasters, wars, and civil unrest. On average, WFP reaches more than 80 million people with food assistance in 75 countries each year. About 11,500 people work for the organization, most of them in remote areas, directly serving the hungry poor. WFP is part of the United Nations (UN) System.

About BDS:
Headquartered in Gdansk, Poland, BDS is an international data science and blockchain development company specializing in business-focused solutions. BDS develops data-driven applications (mobile/desktop frontends and backends) for international customers as well as blockchain-based applications.

About Datarella:
Founded in 2013 and with its headquarter in Munich, Germany, Datarella is an established solutions provider in blockchain and big data delivering a broad range of consulting and development services for corporate clients supporting them on digital business transformation and Big Data. Datarella Blockchain Solutions is a full service consulting and development for business applications of the blockchain. Datarella offers cloud storage and computing, machine learning (AI) and predictive analytics.