Browsed by
Category: blockchain compatible

Get your Bitcoin address using Ethereum smart contract

Get your Bitcoin address using Ethereum smart contract

Ethereum and Bitcoin are both using the same type of encryption, the ECC (Elliptic Curve Cryptography) over the same graph (256k1). While it’s not really recommended, the same key pair can be used both for Bitcoin and Ethereum.

A simple Solidity code can be used to get the Bitcoin address of a public key. Such a code can run locally (as a constant function) on the Ethereum Virtual Machine to save gas, or as a regular Ethereum transaction.

The code in this example requires the user to insert their public key in its uncompressed format as an input; then it produces the binary address that matches that uncompressed public key for the main Bitcoin network. The code can be easily modified to work with compressed public keys as well (just remove the yPoint and add the side of the ECC graph). The code can also be amended to give the binary address of other testnet/namecoin.

 

How to create a Bitcoin address

The most basic process of deriving Bitcoin address from a public key is set in the following technical documentation.

 As you can clearly see, there’s very little to it than just hashing and appending.

Recreating the process in Solidity

First, let’s generate a random keypair using bitaddress.org. Under the tab “wallet details” we can see the uncompressed public key.

The public key
xPoint = C4BB8E42F7DA5504A456C16BE533549DA4FE580279382478F3365FF7CCBF032D
yPoint = 68A73547E809F1ABFAA51D10019E8AC682D1205448042326E9E3B91841CB9FA7

Now let’s create our smart contract in Solidity:

pragma solidity ^0.4.11;

contract BitValid{
	
	bytes32 constant mask4 = 0xffffffff00000000000000000000000000000000000000000000000000000000;
	bytes1 constant network = 0x00;


	function getBitcoinAddress(
			bytes32 _xPoint,
			bytes32 _yPoint)
			constant
			returns(
				bytes20 hashedPubKey,
				bytes4 checkSum,
				bytes1 network)
	{
		hashedPubKey 	= getHashedPublicKey(_xPoint, _yPoint);
 		checkSum 	= getCheckSum(hashedPubKey);
 		network 	= network;
	}

	function getHashedPublicKey(
			bytes32 _xPoint,
			bytes32 _yPoint)
			constant
			returns(
				bytes20 hashedPubKey)
	{
		var startingByte = 0x04;
 		return ripemd160(sha256(startingByte, _xPoint, _yPoint));
	}

	function getCheckSum(
			bytes20 _hashedPubKey)
			constant
			returns(
				bytes4 checkSum)
	{
		var full = sha256((sha256(network, _hashedPubKey)));
		return bytes4(full&mask4);
	}
}

The function getBitocinAddress() takes the x and y coordinate of the public key from the user, both are 32 bytes long (the uncompressed public key) and will return 3 variables, the hashed public key (bytes20), the checksum (bytes4) and the network starting byte (bytes1).

The network starting byte is currently hard codded to 0x00 (the main starting code). You can change this code to work with any other test network.

The hashed public key is obtained by hashing the public key (both x and y coordinates) with the starting byte 0x04 twice (as described in the technical documentation). Once with sha256 and then again with ripemd160. The finale result is 20 bytes long.
function getHashedPublicKey(
		bytes32 _xPoint,
		bytes32 _yPoint)
		constant
		returns(
			bytes20 hashedPubKey)
{
	var startingByte = 0x04;
	return ripemd160(sha256(startingByte, _xPoint, _yPoint));
}
After we got the hashed public key, we’ll prepend the network byte to it and hash it again twice using the sha256 function. The result of 32 bytes long is used to construct the checksum, a special 4 bytes that are used to allow another user to verify that the Bitcoin address they’re sending to is indeed a valid address.
bytes32 constant mask4 = 0xffffffff00000000000000000000000000000000000000000000000000000000;

function getCheckSum(
		bytes20 _hashedPubKey)
		constant
		returns(
			bytes4 checkSum)
{
	var full = sha256((sha256(network, _hashedPubKey)));
	return bytes4(full&mask4);
}
We don’t need all of the 32 bytes, only the first 4 bytes, but slicing variables is a hard thing to do in Solidity. Luckily, Solidity does allow for easy bit manipulation and masking. You’ll need to create a mask of 32 bytes to match the 32 bytes of the sha256 output. This mask should take only the first 4 bytes, as they’re the real checksum.
The full result (32 bytes) = 0x4c30ed507a508af52063560ff8f1c09e66be0587868a0b8ca21ab337440e4e8e
Mask for the first 4 bytes = 0xffffffff00000000000000000000000000000000000000000000000000000000
checksum = 0x4c30ed50

The results

At the end of the day, we have the following three components to return to the user, the network byte (currently hard coded), the hashed public key and the checksum. These are the three components that make up a Bitcoin address.

However, this isn’t the last step. In Bitcoin, a special type of encoding is used called base58. The current code doesn’t convert the result into base58 (I’ll leave it for another day), so we’ll be forced to do this step manually.

The following website provides some tools to convert our bytecode into base58. This is basically the final Bitcoin address.

At the end of the day

Using Solidity to retrieve the Bitcoin address that matches a specific public key (and therefore, a private key as well) might be useful when you’re trying to create a smart contract that maps some events between entities on both blockchains and I suspect might have some value when dealing with identities. The procedure isn’t cheap on gas but can be done locally using the EVM. It’s a shame that there’s no access to the bytecode of the transactions in Solidity since it could have made the process of finding the Bitcoin address of the message sender automated.

Proof of data integrity – Solidity code

Proof of data integrity – Solidity code

Update:

I’ve simplified to code to take more advantage of the boolean data type Ethereum offers.

Now the mapping is (bytes32=>bool) instead of (bytes32=>bytes32).

The boolean array is used to prove the existence of a single document. The root of the tree is stored once and is hashed again with the new input.

The complete code can be found on Github. The old test files can be used on this code as well

struct tree{
    bytes32 root;
    mapping(bytes32=>bool) dataExist;
}

bytes32 public empty;

mapping (address=>tree) public users;    
****

function addData(
			uint256 _input,
			address _user)
			returns (bool success)
{
	var data   = keccak256(_input);        
	var oldRoot = getUserRoot(_user);
    var newRoot = hashTheTwo(data, oldRoot);

    users[_user].dataExist[data] = true;

    users[_user].root = newRoot;

    return true;
}
****

function checkDataIntegrity
        (uint256[] _data, 
        address _user)
        constant         
        returns (bool complete){ 

	var oldRoot = empty;                         
    
    for (uint i = 0; i < _data.length; i++) {     
        var data = keccak256(_data[i]);
        if(users[_user].dataExist[data]){
            var root = hashTheTwo(data, oldRoot);
            oldRoot = root;
            continue;             
        }else{
            return false;
        }
    }

    if(root == getUserRoot(_user)){
    	return true;
    }else{
    	return false;
    }
}
Contract: test 01
    The first stage is Deploying Data
      ✓ Deploys the Data contract
      ✓ Register account 0 user (69ms)
    Adds three datas to account 0 user tree
      ✓ get account 0 user root - should be undefined (79ms)
      ✓ Adds the first data 1 (108ms)
      ✓ Adds the second data 2 (86ms)
      ✓ Adds the third data 5 (79ms)
    Check data integrity
      ✓ Pass the complete array [1, 2, 5] - expect true (122ms)
      ✓ Pass the  array [1, 2] - expect false (93ms)
      ✓ Pass the  array [1, 5, 2] - expect false (83ms)


  9 passing (818ms)
    

Storing data on the blockchain

Current blockchain architecture allows us to decentralized valuable information. The most obvious example is the blockchain itself, which is nothing more than just a database that each user can interact with. The users can download a copy of the blockchain, parse it and extract any information that is meaningful to them, to add information to that database, to check its integrity and so on.

But adding information directly to the blockchain is a problematic process. For one, it’s highly expensive. Whether you’re using Bitcoin or Ethereum as the blockchain on which to store your data, you’ll soon find out that any attempt to save more than a few bytes of data at a time can get ridiculously expensive. For that reason, many have started to use the blockchain as a method to “proof existence” of said document. In this process, instead of publishing the full document on the blockchain, the document is hashed using a prespecified hashing algorithm. This practice means that the owner of the document uses the blockchain not as a mean to store his or hers document, but to prove:

  1. Ownership over the said document (As long as he keep the private key from which the transaction was deployed)
  2. The existence of the said document at a specific point in time (by looking at the block header timestamp)
  3. The integrity of that specific document, as each minor change to the original file, will result in an entirely different hash.

By keeping the document yourself, you’re also able to better handle your privacy, as now instead of publishing your own private documents on a public blockchain for all to see, you’re only posting the result of a hash function, which is extremely difficult to Didact the contains of the original document from.

Such a system might be sufficient for sporadic use. But what happens if we want to create a system that new documents are continuously added to it. And we want to be able to prove the integrity of each individual document, both by itself and in conjunction to those preceding it?

 

Binary trees.

Binary trees are not a new thing in blockchains. Merkle trees and roots are used in Bitcoin and Ethereum to store and organize transactions and to allow for merged mining. In Ethereum the trees are also used to access the storage (variables) and states of the blockchain.

One of the great characteristics of binary trees is the ability to use them, plus some hashing algorithm to prove the integrity of the data stored in it.

Let’s have a look at the most common example, the Bitcoin Merkle tree. In this tree, each leaf represents one transaction. These transactions are hashed together again and again until finally, the final hash (the root) is produced. Storing the root require much less space than when storing all of the transactions data. But if I want to check that a specific transaction is indeed a part of a specific block, I can reconstruct that said block Merkle root by myself. In this case, that means that instead of storing all of the transactions that took place in the blockchain, I maintain only copies of the transaction that is relevant to me (and usually it requires less than a half of the transactions in a block).

In Bitcoin this tree is used both to proof the integrity of the block and to make it easier to validate transaction without having a full copy of the blockchain

 

My proposal 

Knowing the advantages of binary trees, hashing, key encryptions, and filled with the motivation to create a user specific database that will allow him/her to maintain control over his/hers private information, while still being able to prove their ownership over the information and the integrity of that information, I decided to play a little with different Solidity codes. The idea was to use mapping as the mean of creating pairs of leaves and root.

 

Each leaf is hashed with the previous root to produce the new root of the tree

Each root is the hashed of all of the chain that lies bellow its level, plus the new leaf added. This way, each attached leaf if linked and chained with the rest.

pragma solidity ^0.4.6;

contract Data{
    
    struct tree{
        bytes32 root;
        mapping(bytes32=>bytes32) leafAndRoot;
    }

    bytes32 public empty;                                           // Hard codded         
    
    mapping (address=>tree) public users;
    
    function newUser(){                                             // To do - Modifer "onlyNewUser" 
        users[msg.sender];
    }
    
    function addData(
            uint256 _data,              // To do - serialize data/non empty
            address _user)
            returns (bool success){  
        
        var leaf    = keccak256(_data);   // Hashing the input
        var oldRoot = getUserRoot(_user);
        var newRoot = hashTheTwo(leaf, oldRoot);
        
        users[_user].leafAndRoot[leaf] = newRoot;
        users[_user].root = newRoot;

        return true;
    }
    
    function getRoot(
            uint256 _leafData,      // The input is in plain uint256 and hashed format to allow for future UI to be devloped
            address _user)
            constant 
            returns (bytes32 root){ // The root of specific leaf
        
        var leaf = keccak256(_leafData);                                            // Hashing the input
        return users[_user].leafAndRoot[leaf];
    }
    
    function getUserRoot(
                address _user)
                constant
                returns (bytes32 root){ // The higest (last) root      
        return users[_user].root;
    }

    function hashTheTwo
                (bytes32 _a, // To do - serialize data/non empty
                bytes32 _b)  // To do - serialize data/non empty
                constant
                returns (bytes32 hashed){         
        return keccak256(_a, _b);
    }
    
    function checkDataIntegrity
            (uint256[] _data, // To do - serialize data/non empty
            address _user)
            constant         // Run localy
            returns (bool complete){ 
         
         

        var oldRoot = empty;                         // Hard codded                        
        for (uint i = 0; i < _data.length; i++) {    // Reconstructing the tree     
            var data = keccak256(_data[i]);          // Hashing the input
            var root = hashTheTwo(data, oldRoot);
            
            if(root == getRoot(_data[i], _user)){         
                oldRoot = root;
                continue;
            }else{
                return false;
            }
        }        

        if (oldRoot == getUserRoot(_user)){
            return true;
        }else{
            return false;
        }
    }
}

For each new user, a new struct object is created containing two parts, The latest root in the tree, and the tree itself. The tree maps from bytes32 (the data/leaf) to the bytes32 of the root. That way a user can look up for a specific information and, if the root is valid, attest that the said information is indeed present in the database, while others cannot tell what the real information is just by looking at the blockchain.

Currently, due to input limitations in solidity, the easiest way to input and parse and the array is by using u/int array. Future implementation might include bytes32[] array or even direct string array as input.

All the input values are hashed to get a uniform 32 bytes result and to increase privacy.

function hashTheTwo(
        bytes32 _a,
        bytes32 _b)
        constant
        returns (bytes32){         // To do - serialize data/non empty
    return keccak256(_a, _b);
}

The data is then hashed together with the highest existing root to receive the new root of the tree (If the tree is empty, meaning no root exist yet, the first leaf is hashed with empty bytes32 variable).

The new root is then stored in a dedicated variable to allow adding extra information without manually looking for the latest existing root.

function addData
        (uint256 _data,
        address _user)
        returns (bool){                 // To do - serialize data/non empty
    
    var leaf    = keccak256(_data);     // Hashing the input
    var oldRoot = getUserRoot(_user);
    var newRoot = hashTheTwo(leaf, oldRoot);

    users[_user].leafAndRoot[leaf] = newRoot;
    users[_user].root = newRoot;

    return true;
}

When trying to prove the authenticity of a single entry, it’s enough to just check for the existence of a (none empty) root that corresponds to that specific piece of information.

function getRoot(
            uint256 _leafData,
            address _user)
            constant
            returns (bytes32){ // The root of specific leaf

    var leaf = keccak256(_leafData);                                            // Hashing the input
    return users[_user].leafAndRoot[leaf];
}

// Can also be rewtiren to give bool result

function isExist(
            uint256 _leafData,
            address _user)
            constant
            returns (bool exist){
            
    var leaf = keccak256(_leafData);                                            // Hashing the input
    if(getRoot(_leafData, _user) != 0x00){
        return true;
    }else{
        return false;
    }            
}

Proving the existence of the entire database is done by providing all the pieces in their proper order and reconstructing the finale root. If the results match the one stored on the blockchain, that means that the owner of that data array has a complete copy of that array.

function checkDataIntegrity(
            uint256[] _data,
            address _user)
            constant
            returns (bool){ 
     
     // To do - serialize data/non empty
     // Run localy

    var oldRoot = empty;    // Hard codded                        
    for (uint i = 0; i < _data.length; i++) {

        var data = keccak256(_data[i]);         // Hashing the input
        var root = hashTheTwo(data, oldRoot);

        if(root == getRoot(_data[i], _user)){   // Reconstructing the tree 
            oldRoot = root;
            continue;
        }else{
            return false;
        }
    }        

    if (oldRoot == getUserRoot(_user)){
        return true;
    }else{
        return false;
    }
}

The complete code plus test file can be found on my github page

Contract: test 01
    The first stage is Deploying Data
      ✓ Deploys the Data contract
      ✓ Register account 0 user (69ms)
    Adds three datas to account 0 user tree
      ✓ get account 0 user root - should be undefined (79ms)
      ✓ Adds the first data 1 (108ms)
      ✓ Adds the second data 2 (86ms)
      ✓ Adds the third data 5 (79ms)
    Check data integrity
      ✓ Pass the complete array [1, 2, 5] - expect true (122ms)
      ✓ Pass the  array [1, 2] - expect false (93ms)
      ✓ Pass the  array [1, 5, 2] - expect false (83ms)


  9 passing (818ms)
    

What can I do with it?

I can use the above system to prove that I’m in control over my own data, that I have the original data and that I maintain a complete copy of my database. Such a system can be combined with other types of encryptions to prove that the data is both belongs to me, complete, and recognized by other authorities.

I prove that I have a my complete medical file, I prove that the said message belongs to me and that it was signed by myself and by the doctor
How to be blockchain compatible. part one

How to be blockchain compatible. part one

Tl;dr: Don’t try to move your existing organization to be a “decentralized/ blockchain based” look at the cases in which your organization might implement some blockchain based solutions and start making the necessary changes in-house to allow future integration.

Seeing how new technologies are changing our world, and change it fast, makes many entrepreneurs twist and itch. It’s in the blood of most of them to try and incorporate this new technology as soon as possible. However, most are failing to properly understand what the blockchain (it’s more than just a chain of blocks) is and how it can affect their organization. Many want to completely redesign their business model and organization architecture to migrate entirely to the blockchain.
I find this approach to be counterproductive (and in most cases, outright ludicrous). Instead, I’m trying to help them to consider the need of their business, to map their current application and its architecture and to educate themselves on what the blockchain really is, and what it isn’t. Then we can look at ways in which existing organizations might make their systems more compatible with current blockchains. That way these organizations are both going through and internal (and valuable!) process of learning how to work with the blockchain, create a list of cases in which the blockchain might be beneficial to them.

In the next few posts, I’ll expand on it and try to give a general review of how a business owner might start remodeling their systems to be blockchain compatible.

The Database. Part one.

Many considering the blockchain storage features to be similar to those of a legacy database systems. However, the blockchain differs from such architectures in many aspects. In this article, I’ll try to give a general review of the things legacy databases and blockchain have in common, and of course, of the things that separate them from each other.

  1. Writing and reading is extremely more expensive than in legacy systems
  2. The array is an append only array. That means that data cannot be delete or update
  3. Most current languages cannot work with blockchain
  4. A substantial amount of the information stored on the blockchain is irrelevant for most users

Study case

Let’s consider the following case. A social network app wants to migrate its database onto the blockchain. That social app probably contains a multitude of data entries. Our social network app might be using a rational database (must commonly SQL), or non-rational database (NoSQL).

If our app uses a rational database, it might look something like this:

Table – users:

User id User name User email Number of articles published by user
1 Shlomi Zeltsinger Shlomi.zeltsinger@gmail.com [1, 5]
2 John Doe NoOne@gmail.com [2,3,4,6]

Table – articles:

Article id Created by user id body title
1 1 Story number one Good title
2 2 Story number two Better title
3 2 Story number three Best title
4 2 Story number four Excellent title
5 1 Story number five Stolen title
6 2 Story number six Bad title

In the case of NoSQL database, we will have the following structure:

Whenever our social app wants to update its legacy database, it uses the TRANSACTION.

START TRANSACTION
      INSERT INTO articles VALUES (
                  7, # Article id 
                  1, # User id
                  "story number seven", # Body
                  "title number seven" # Title )
COMMIT

Transactions in this sense have the following four characteristics:

Atomicity − ensures that all operations within the work unit are completed successfully. Otherwise, the transaction is aborted at the point of failure and all the previous operations are rolled back to their former state.

Consistency − ensures that the database properly changes states upon a successfully committed transaction.

Isolation − enables transactions to operate independently of and transparent to each other.

Durability − ensures that the result or effect of a committed transaction persists in case of a system failure.

(from https://www.tutorialspoint.com/sql/sql-transactions.htm)

Now let’s see what a transaction in the meaning of the blockchain is. First of all, it does possess some of the characteristics described above. Each transaction is atomic – either it was valid and accepted into a block, or it’s not. There’s no gray area. Each transaction is also isolated from the other, at least when looking at systems like the current Bitcoin and Ethereum blockchains (Some advance research is done on a new architecture that might change this propriety a little). Also, once a transaction was accepted to the blockchain, its effect is durable, and even if my own personal server falls, the result of that action is still available.  When it comes to consistency, transactions that are transmitted to the Bitcoin/Ethereum network will be verified and examined using various tools (scripting language, cryptography, EVM) that force consists result across the network.

So, if all four characteristics are the same, then what’s the difference?

Expensive

Some of you might have looked at the above example, the one in which we’re adding article number seven, and asked yourselves “what is going to happen to the user’s table”? We specifically asked to update the article table, but now – the user table should also reflect the changes made (now user id 1 have 3 articles [1,5,7] ). To update this field, we’ll either add the command UPDATE to our TRANSACTION code:

START TRANSACTION
      UPDATE users
      SET articles = [1, 5, 7]
      WHERE user id = 1;
COMMIT

Or transmit this UPDATE command as a second transaction. In both cases, we’re adding extra work to our database both in computational cycles or in physical storage place (now we need to store the number Three in out database). But in the case of Bitcoin and Ethereum, we’re using the blockchain to store the information, and we’re asking the other nodes on the network to validate our transactions constantly. And this has a much higher price than doing so locally.

How high? Well, in the case of Ethereum, every 256 bit that is stored, requires 20K of gas unit (that’s the minimum storage space for words). At a current gas price of 0. 00000005 Ethers per 1 gas unit that amounts to: 20,000 * 0.00000005  = 0.001 ethers per 1 Byte.

Therefore storing one kilobyte will cost you: 0.001 Ether * 31 = 0.031 Ethers.

At current market price of 350 USD per ethers, that means that one kilobyte of data should cost 10.85 USD. That’s 10,850,000 USD for one Gigabyte.

Bitcoin prices aren’t much more competitive. And what is worse, currently each transaction cannot contain more than 40 bytes of added information – our articles will be very short.

This raises the questions:

  • What type of information should be stored on the blockchain? Will it be more cost effective to reconstruct some of it on demand? (For example, whenever someone looks for the number of articles that were published by user number 1, the server will consult its own local copy of the blockchain, and count only the articles that were written by that user)
  • Can we index our array in such a way that two modification be efficiently made at the same time?

Variables state

The truth is that the information that is stored on the blockchain doesn’t look at all like the table shown above. The blockchain maintains a list of its valid transactions (in the case of both Bitcoin and Ethereum) and in the case of Ethereum only, a tree of states in which indexed variables are stored.

TX 1 Add user (1, “Shlomi Zeltsinger”, Shlomi.zeltsinger@gmail.com)
TX 2 Add article (1, 1, “story number one”, “Good title”)
TX 3 Add user (1, “John Doe”, NoOne@gmail.com)
TX 4 Add article (2, 2, “story number two”, “Better title”)
TX 5 Add article (3, 2, “story number three”, “Best title”)

The fact that the blockchain is a list of transactions and not a real scheme (table/objects) based database have some interesting implications. First, to interpret this list of the transactions to something of value to use, we’ll need to parse the blockchain and reconstruct our database from scratch.

Someone would need to sit with a pen and paper, read through the list of the transactions and write down the desired information.

For example, if we’re looking for all the articles that were created by John Doe, that someone will first have to look for a transaction that begins with “add users” and contains the name “John Doe” (tx3). When the right transaction was found, that someone will write down the user id of John Doe (2) and then he’ll need to look for all the transactions that begin with “Add article” and count only the ones that have that number that matches John Doe user id (2). Tedious work, no doubt.

In the case of Ethereum we’re giving an extra tool to help us a little. That is that instead of looking at one transaction after the other, we can look at the “state tree” (sometimes “state trie”) of each block. In Ethereum, once we paid the high fee of storage, each variable is indexed. Whenever a change is made to that variable, a new state will be added to the “state tree”. That means that by knowing the index of the said variable, I can find the said indexed variable.

This raises the questions:

  • Can we construct our transactions in a manner that will make it easier to read through?
  • Is it possible to “point” from one transaction to the other?
User id User name User email Number of articles published by user
TX 1 Shlomi Zeltsinger Shlomi.zeltsinger@gmail.com [TX 2, TX 7]
TX 3 John Doe NoOne@gmail.com [TX 4,TX 5,TX 6, TX 8]

Table – articles:

Article id Created by user id body title
TX 2 TX 1 Story number one Good title
TX 4 TX 3 Story number two Better title
TX 5 TX 3 Story number three Best title
TX 6 TX 3 Story number four Excellent title
TX 7 TX 1 Story number five Stolen title
TX 8 TX 3 Story number six Bad title

(Maybe instead of “User Id” field to identify user we’ll do better to point to the transaction at which the user was created?)

  • If were storing the information on the Ethereum network, perhaps it will be easier to treat it as objects (NoSQL) rather then as information that should be stored in rational tables?

Append only

We just saw that both Ethereum and Bitcoin, maintains a list of ALL of their transactions and that we can reconstruct our database by following each transaction. One after the other. As we know, once transactions make it to the blockchain, they stay there. That means that I have no way to change (UPDATE) the information that was already stored. However, by properly constructing my transaction, I can add a comment for future users noting a distinct change. For example, I can create a transaction for changing the user email address

TX 1 Add user (“Shlomi Zeltsinger”, Shlomi.zeltsinger@gmail.com)
TX 2 Add article ( TX 1, “story number one”, “Good title”)
TX 3 Add user (“John Doe”, NoOne@gmail.com)
TX 4 Add article (TX 3, “story number two”, “Better title”)
TX 5 Add article (TX 3, “story number three”, “Best title”)

.

.

.

 .

.

.

TX 500 Update user (TX 1, email: newMail@gmail.com )

Pay attention that now, if I want to find all the articles that were created by the user with the email newMail@gmail.com just iterating through the “add users” transactions will simply won’t do. I will also be required to look for the UPDATE transaction.

This is a great example of a case in which the Ethereum state tree is far superior because once the user is indexed, I can check his or hers email by checking the state of that proper variables.

This raises the questions:

  • What can we do when a node isn’t fully synced. There might be some changes to the data that we have that we’re not yet aware of?
  • If John Dow will add a new article, should this article point to TX 3 or the newer TX 500?
  • Is all the data that is stored on the blockchain is relevant for us? How can we quickly identify the pieces of information that are relevant?

The blockchain probably isn’t the place to store your data. Yet.

As you can see, there are some major issues that need to be solved and considered before you could move your data to the blockchain. It is my recommendation for those who wish to arrnest its power to first try and mimic some of its working architecture principals in-house. Prepare your database both regarding design and structure and make sure that the architectural differences (and the reasonings behind them) clear to you and your team. That way you’ll in a much better position that will allow you to start and slowly integrate some of your business with either Bitcoin or Ethereum (or both) in a way that is truly advantages.

In the next parts, I’ll be talking about some specific codes and architectural tricks that will help us to implement some of the principles mentioned above.