Sharing state among compatible blockchains

in #blockchain6 years ago (edited)

While working on the WoT blockchain I got an interesting idea. It might not be a new one - it seems like Hashgraph is going somewhat in the same direction (though I can't as of yet find any tech docs to confirm or deny this), but anyway, in a nutshell: instead of storing the Merkle root of the entire world-state like Ethereum does in blocks, if we instead only store the state of involved parties and do it per-transaction, we can literally store this state across multiple blockchain, effectively doing a form of sharding.

In Ethereum, each block contains the Merkle root of the complete world-state trie. The reason for this is to ensure and enforce the consensus: as each individual block is processed, i.e. its transactions, as a form of instructions on how to change the state, are applied, every single node in the Ethereum network must come to the same exact conclusion of what the state of every single account in the network / blockchain is.

This effectively enforces serialisation into a single global ledger.

In WoT, I did it in a slightly different way: each block only contains a Merkle root of the new states of the accounts whose state was changed by applying the transactions from within this block. Consensus is achieved in a partial manner: instead of every single block confirming / witnessing the entire state of the world, it only confirms the states of the accounts changed by its transaction. Global consensus, for all involved transactions, is still maintained, though in a bit of a time-diluted manner: even if an "old" address (e.g. one not used in hundreds of thousands of blocks) appears in a new transaction, its old state still exists and must be referenced.

After implementing this system, it occurred to me that it can be scaled to inter-blockchain state-keeping, and even extended to highly-distributed and likely high-throughput networks, though they wouldn't bear much semblance to blockchains.

Basically, if each transaction carries an ID of a blockchain on which it's recorded, and the blockchain ID and hash of the previous transaction it references, along with the signature of the resulting state in which the account is expected to be post-transaction, it doesn't really matter where the transaction is recorded. Sequential nonces can be used to ensure serialisation.

For example, this is how a few transactions starting with a Genesis block might play out:

  • A keypair is generated, the public key will be used in the genesis block transaction. We'll call the public key KpubAlice. Initially, all nonces have a value of 0, so NonceAlice=0 if KpubAlice has never been seen in the blockchain.
  • A unique chain ID is generated, also recorded in the genesis block. We'll call this CHAIN1.
  • The genesis block transaction sends an amount of coins, call it A, to KpubAlice. The nonce associated with KpubAlice increases, so NonceAlice=1. It contains the following data tuple and its signature: (CHAIN1, "coinbase", KpubAlice, A, HASH((KpubAlice, A, NonceAlice=1))). We'll call the signature of this transaction Tsig1 and the hash of this transaction Thash1. The "coinbase" string denotes the type of this transaction.
  • Now there's a new public key, KpubBob, which is to receive an amount of coins named Abob, on the same blockchain, a new transaction will be recorded: (CHAIN1, "local_send", KpubAlice, KpubBob, Abob, HASH((KpubAlice, A-Abob, NonceAlice=1), (KpubBob, Abob, NonceBob=1)). We'll call this transaction's signature Tsig2, and its hash Thash2.
  • Now there's another public key, KpubCharlie, to which KpubBob wants to send Acharlie coins, but this time it wants to record this on a different blockchain, whose ID is CHAIN2. Now the new transaction looks like this: (CHAIN2, "remote_send", CHAIN1, HASH(KpubBob, Abob, NonceBob=1), KpubCharlie, Acharlie, HASH((KpubBob, Abob-Acharlie, NonceBob=2), (KpubCharlie, Acharlie, NonceCharlie=1)).
  • So both KpubBob and KpubCharlie can now continue to issue "local" transactions on CHAIN2, and if one of them ever wants to switch back to CHAIN1, they will just issue such a remote_send transaction, which will itself carry the updated state, as seen on CHAIN2, back to CHAIN1.

I can see this working in practice, with certain practical modifications to address convenience and possible fragilities. Here are a few points that come to my mind:

  • The miners which include remote_send transactions in their blocks need to be full nodes for both chains, to verify the state of the sending account in the old chain, and to record the new state of the account in the new one.
  • It might be a good idea to include plaintext Nonces in the transaction data instead of making them a part of the hashes, to enable re-synchronisation of sorts if something goes wrong. Not sure at this point.
  • The mechanism described here applies to "rich state" applications similar to those used in Ethereum: there can potentially be a lot of data associated with an address. Still, only the instructions how to change the data and the Merkle root of the new state need to be recorded in transactions themselves.

What do you think?

Coin Marketplace

STEEM 0.19
TRX 0.14
JST 0.029
BTC 67044.89
ETH 3251.74
USDT 1.00
SBD 2.64