...by Daniel Szego
quote
"On a long enough timeline we will all become Satoshi Nakamoto.."
Daniel Szego

Wednesday, August 8, 2018

How to implement a Blockchain from scratch - apply transaction to the state


Mining in an account/balance blockchain system practically means finding a set of consistent valid transactions and applying them to the system state. For this activity we need two sub-functions: on the one hand the, transaction has to be validated against the state, on the other hand the transaction has to be applied to the state. For the sake of simplicity we assume that each block stored the whole state, which is copied one to one at the initializing the block.

For a simple transaction only setting data, the pseudo code is the following:

ValidateTransaction (Transaction t)
if t.signature is not valid
  return error signature not valid
  else
    foreach account a in the state
      if a.address == t.fromAddress
        if a.nonce != t.nonce +1
          return error replay attack
        else
          return transaction is valid
      else
        add new account to accounts with fromAddress 

For a transaction transferring money:

ValidateTransaction (Transaction t)
if t.signature is not valid
  return error signature not valid
  else
    foreach account a in the state
      if a.address == t.fromAddress
        if a.nonce != t.nonce +1
          return error replay attack
        else
          if a.balance < t.amount
            return balance is not enough
         else
          foreach account a in the state
            if a.address == t.toAddress
              return transaction is valid
           add new account to accounts with toAddress
      else
        return error from account must exist at transferring money 

For applying the state we have to iterate on all of the account check them if they are valid and after that apply the state change. It might vary again based on the exact type of the transaction. If it is a simple data transfer transaction:

ApplyState (Transaction t)
  foreach account a in the state 
    if a.address == t.fromAddress
      a.data = t.data

for the money transferring transaction it is a little bit more complicated

ApplyState (Transaction t)
  foreach account a in the state 
    if a.address == t.fromAddress
      a.balance -= t.amount
  foreach account a in the state 
    if a.address == t.toAddress
      a.balance = t.amount