Snark: Designing Economic Abstraction

Consensus free finalization allows for state concurrency updates.

A transaction can be described as

transaction {
data //data struct below
sender //who is sending the transaction
}
data {
nonce //incrementing numeric value for transaction ordering
price //price of doing the transaction
gas //upper bound of gas the sender is willing to spend
receiver //receiving entity
value //value being transferred
payload //mutable data
 v        //signatures* (oversimplified)
r //signatures* (oversimplified)
s //signatures* (oversimplified)
}

The life cycle of this transaction can be described as

  • Account creates and signs transaction (creation)
  • Transactions is sent to Node via RPC (transport)
  • Transaction is received and validated by node (queued)
  • Transaction nonce is validated as possible transaction (pending)
  • Transaction is unwound and applied to state (accepted)
  • Transaction has 51% known acceptance (finalized)

Detail interest here is accepted.

State transition in Ethereum can be described as;

func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bool, err error) {
 sender := st.from() // err checked in preCheck
// Pay intrinsic gas
gas, err := IntrinsicGas(st.data)
if err = st.useGas(gas); err != nil {
return nil, 0, false, err
}
var (
evm = st.evm
vmerr error
)
// Increment the nonce for the next transaction
st.state.SetNonce(sender.Address(), st.state.GetNonce(sender.Address())+1)
ret, st.gas, vmerr = evm.Call(sender, st.to().Address(), st.data, st.gas, st.value)
 if vmerr != nil {
if vmerr == vm.ErrInsufficientBalance {
return nil, 0, false, vmerr
}
}
st.refundGas()
st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice))
return ret, st.gasUsed(), vmerr != nil, err
}
  • sender = st.from().Address()
  • nonce = st.state.GetNonce(st.from().Address())
  • to = st.to().Address()
  • value = st.value
  • gas = st.gas
  • data = st.data

EVM transition can be described as;

func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
var (
to = AccountRef(addr)
snapshot = evm.StateDB.Snapshot()
)
evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value)
 if err != nil {
evm.StateDB.RevertToSnapshot(snapshot)
if err != errExecutionReverted {
contract.UseGas(contract.Gas)
}
}
return ret, contract.Gas, err
}
func Transfer(db vm.StateDB, sender, recipient common.Address, amount *big.Int) {
db.SubBalance(sender, amount)
db.AddBalance(recipient, amount)
}

State DB

StateDB {
db Database
trie Trie
// This map holds 'live' objects, which will get modified while processing a state transition.
stateObjects map[common.Address]*stateObject
stateObjectsDirty map[common.Address]struct{}
// DB error.
// State objects are used by the consensus core and VM which are
// unable to deal with database-level errors. Any error that occurs
// during a database read is memoized here and will eventually be returned
// by StateDB.Commit.
dbErr error
// The refund counter, also used by state transitioning.
refund uint64
thash, bhash common.Hash
txIndex int
logs map[common.Hash][]*types.Log
logSize uint
preimages map[common.Hash][]byte
// Journal of state modifications. This is the backbone of
// Snapshot and RevertToSnapshot.
journal journal
validRevisions []revision
nextRevisionId int
lock sync.Mutex
}

Simply put, a transaction informs the state to subtract value from the sender, and add value to the recipient. Fees for this transaction are added to the block creator. Block reward is provided to the block miner.

A state transitions is therefor txn applied to s1 to create s2.

s1 in the current example would be ETH, so we can say s1ETH. Snark allows for s1ETH to co-exist along with s1BTC.

The following changes are implemented

transaction {
state //ID of the state transaction should be applied to

data //data struct below
sender //who is sending the transaction
}
data {
nonce //incrementing numeric value for transaction ordering
price //price of doing the transaction
gas //upper bound of gas the sender is willing to spend
receiver //receiving entity
value //value being transferred
payload //mutable data
 v        //signatures* (oversimplified)
r //signatures* (oversimplified)
s //signatures* (oversimplified)
}
func (env *Work) commitTransaction(tx *types.Transaction) (error, []*types.Log) { 
state := env.GetState(tx.getState())
snap := state.Snapshot()
receipt, _, err := core.ApplyTransaction(state.config, state.gp, state, state.header, tx, &state.header.GasUsed, state.Config{})
if err != nil {
state.RevertToSnapshot(snap)
return err, nil
}
env.txs = append(env.txs, tx)
env.receipts = append(env.receipts, receipt)
env.setState(state, tx.getState())
return nil, receipt.Logs
}

A transaction is applied to a specific state. This allows for the creation of new states, as well as configurable rules per state. (OpCodes remain fixed for now)