# Blockchain Applications

We've now covered the fundamental elements of Nakamoto consensus. In this section, we'll examine some of the ways in which digital currency systems can be constructed on top of blockchain protocols. Specifically, we take a look at the two most popular designs introduced widely by Bitcoin and Ethereum, respectively. As in our previous section regarding applications on BFT systems, we'll define some state, transactions, and state transition functions. From these three basic elements we can develop complete value-transfer mechanisms.

When designing any transaction-based application, one must first take care to fully specify a list of end goals. A currency system, at its core, should assign ownership to units of currency. "Ownership" can take many forms, but for the moment it's simpler to assume that an "owner" refers to an individual user. We'll later briefly examine how to extend this definition to include, for instance, joint ownership between multiple users. Other than simply assigning ownership, our system should also allow users to transfer ownership of units of currency. Of course, this should be subject to reasonable restrictions along the lines of preventing a user from spending money they don't actually have.

We have several options for the structure of such a system. Bitcoin popularized a potential model that came to be known as the "unspent transaction output", or "UTXO," representation of digital currency. This model in many ways resembles physical cash translated into a digital form. Currency is represented as unique bundles that each have an owner, similar to the manner in which one might own and carry currency notes. These bundles, called "outputs" for reasons that will soon become clear, differ from physical notes in that they can be arbitrarily divided or combined with other outputs to generate new ones of any desired value.

Let's construct a simple UTXO system somewhat similar to that of Bitcoin. As ever, we begin with the definition of our state:

{
    "outputs": {
        "<string>": {
            "value": <number>,
            "owner": "<string>",
            "spent": <true | false>
        }
    }
}

Our state consists only of a mapping between the unique identifier for each output and data about the output. This data includes the value of the output, the output's owner, and a flag telling us whether or not the output is "spent." The "spent" flag highlights another difference between the UTXO model and physical cash. Whereas cash notes can be reused over many different transactions, outputs may only be used in a single transaction, after which it is "spent." Once spent, an output may no longer be used in any future transaction.

We can now design the structure of our transaction. In a UTXO system, transactions "consume" existing outputs and generate new ones of value equal to the total value of those consumed. We refer to the consumed outputs as "transaction inputs," and the generated outputs simply as "transaction outputs," hence the name of the mechanism. For each input to the transaction, we additionally want to include a digital signature over the transaction generated by the owner of that input. This serves as our verification that the owner does indeed wish to spend the referenced output. When combined, these elements produce the following transaction structure:

{
    "inputs": [
        "<number>"
    ],
    "outputs": [
        {
            "id": <number>,
            "value": <number>,
            "owner": "<string>",
            "spent": <true | false>
        }
    ],
    "signatures": [
        "<string>"
    ]
}

At last, we can construct our state transition function. This function must carry out a few key tasks before it can return a new state. First, it should do some basic verification on the transaction. Each transaction input should be "unspent" and correspond to a valid signature from the input's owner. Furthermore, the sum of all input values should be equivalent to the sum of the values for each newly generated output. These checks ensure that funds can't be stolen or created out of thin air. Finally, the function can mark the inputs as "spent" and add the outputs to the state.

def state_transition_function(old_state, transaction):
    # Basic input validation
    for x in range (0, len(transaction["inputs"])):
        tx_input_id = transaction["inputs"][x]
        tx_input = old_state.outputs[tx_input_id]

        # Make sure the input isn't spent
        assert tx_input.spent == False
        # Make sure the input corresponds to a valid signature
        assert is_valid_signature(signatures[x], tx_input["owner"], transaction)

    # Find the sum of all input values
    tx_input_sum = 0
    for x in range(0, len(transaction["inputs"])):
        tx_input_id = transaction["inputs"][x]
        tx_input = old_state["outputs"][tx_input_id]
        tx_input_sum = tx_input_sum + tx_input.value

    # Find the sum of all output values
    tx_output_sum = 0
    for x in range(0, len(transaction["outputs"])):
        tx_output = transaction["outputs"][x]
        tx_output_sum = tx_output_sum + tx_output.value

    # Check that input sum and output sum are equal
    assert tx_input_sum == tx_output_sum

    new_state = old_state

    # Mark all inputs as "spent"
    for x in range(0, len(transaction["inputs"])):
        tx_input_id = transaction["inputs"][x]
        new_state["outputs"][tx_input_id]["spent"] = True

    # Add new outputs to our state
    for x in range(0, len(transaction["outputs"])):
        tx_output = transaction["outputs"][x]
        new_state["outputs"][tx_output["id"]] = tx_output

    return new_state

Let's run through this system with an example. Suppose that our initial state is as follows:

{
    "outputs": {
        1: {
            "value": 500,
            "owner": "User A",
            "spent": false
        }
    }
}

We've only included a single output with a value of 500 units owned by User A. Next, we'd like to introduce a transaction in which User A transfers 100 units to User B and 200 units to User C. User A creates the following transaction:

{
    "inputs": [
        1
    ],
    "outputs": [
        {
            "id": 2,
            "value": 200,
            "owner": "User B",
            "spent": false
        },
        {
            "id": 3,
            "value": 100,
            "owner": "User C",
            "spent": false
        },
        {
            "id": 4,
            "value": 200,
            "owner": "User A",
            "spent": false
        }
    ],
    "signatures": [
        "This is User A's signature!"
    ]
}

This transaction consumes Output #1 as an input and simultaneously generates three new outputs. Note that User A has included an output that transfers the remaining 500 - 200 - 100 units back to themselves. We refer to this as a "return" output, a necessary addition as the original output can no longer be used after this transaction is executed. Once we run this transaction through our state transition function, we find the following final state:

{
    "outputs": {
        1: {
            "value": 500,
            "owner": "User A",
            "spent": true
        },
        2: {
            "value": 200,
            "owner": "User B",
            "spent": false
        },
        3: {
            "value": 100,
            "owner": "User C",
            "spent": false
        },
        4: {
            "value": 200,
            "owner": "User A",
            "spent": false
        }
    }
}

We now see one "spent" output and three "unspent" outputs, as expected. If one attempts to run the same transaction through the state transition function against this new state, the function will throw an error as Output #1 is now marked as "spent." We've successfully managed to design a basic UTXO currency system in only a few lines of code. In practice, we may wish to support more complex behavior within our application. Bitcoin, for instance, replaces the "owner" of each output with a "verification script," essentially a small piece of code that defines the conditions under which an output may be spent. This allows users to attach elaborate ownership models to an output that go beyond simple ownership managed by a digital keypair.

The early ubiquity of the UTXO model was challenged by the introduction of the "account model," popularized by Ethereum. This alternative representation of value exchange more closely resembles digital banking than physical bank notes. In essence, the state of an account-based system consists of a mapping between unique user accounts and information about those accounts. Part of this information typically includes the "balance" of each account in the unit of the system. Once again examining a simple state of such a model:

{
    "accounts": {
        "<string>": {
            "balance": <number>
        }
    }
}

Immediately, we can observe that this feels similar to what one might expect to see on a bank's website. We've entirely removed the concept of unique "bundles" of currency. Instead, we've introduced a balance field that keeps track of the amount of currency owned by each account. Transactions are equally simplified:

{
    "sender": "<string>",
    "recipient": "<string>",
    "amount": <number>,
    "signature": "<string>"
}

This likely appears familiar to anyone who has read a monthly bank account statement. As with UTXO transactions, we've included a "signature" field that ensures only the owner of an account may spend from it. Next, the state transition function:

def state_transition_function(old_state, transaction):
    sender = transaction["sender"]
    recipient = transaction["recipient"]

    # Make sure the transaction has a valid signature
    assert is_valid_signature(transaction["signature"], sender)
    # Make sure the owner's balance is greater than the transaction amount
    assert old_state["accounts"][sender]["balance"] >= transaction["amount"]

    new_state = old_state

    # Reduce the sender's balance by the transaction amount
    new_state["accounts"][sender]["balance"] = old_state["accounts"][sender]["balance"] - transaction["amount"]
    # Increase the recipient's balance by the transaction amount
    new_state["accounts"][recipient]["balance"] = old_state["accounts"][recipient]["balance"] + transaction.amount

    return new_state

The state transition function too has been vastly simplified. It must only verify the sender's signature and account balance before executing the balance change. Updating account balances is as easy as reducing the balance of one account and increasing the balance of the other.

Given the following initial state:

{
    "accounts": {
        "User A": {
            "balance": 500
        },
        "User B": {
            "balance": 0
        }
    }
}

And a single transaction:

{
    "sender": "User A",
    "recipient": "User B",
    "amount": 200,
    "signature": "This is User A's signature!"
}

We find a reasonable final state:

{
    "accounts": {
        "User A": {
            "balance": 300
        },
        "User B": {
            "balance": 200
        }
    }
}

As has been repeatedly highlighted, the account model is in many ways both simpler and more intuitive than its UTXO counterpart. This simplicity is likely responsible for much of its popularity in recent years. Further popularity may be attributed to the relative "permanence" of the account in comparison to the single-use transaction output. The following chapter explores, in part, the power of this permanence when made accessible to application developers on Ethereum. No matter their differences, both the account-model and UTXO-model still see wide-spread use within blockchain systems today.

This variety in application design calls attention to the importance of a sense of separation between the "consensus" and "execution" layers of any blockchain system. Consensus protocols aim to come to agreement about some set and ordering of transactions. Well designed protocols should, ideally, be completely agnostic to the actual content or structure of the transactions they process. A single consensus protocol can be used to run many different types of applications, just as a single application can be executed on many different consensus protocols. This separation has only become more pronounced within modern blockchain systems like Eth2.

We've attempted to provide readers with a feel for this distinction throughout both this chapter and the previous one. We continue this practice going forward into our explorations of Eth1 and Eth2. Consensus protocols are defined first, without any explicit reference to the interior of a transaction. State, transactions, and state transition functions are then described for the particular applications we wish to analyze. We hope that this method of teaching proves useful to anyone who seeks to apply the knowledge in this text to domains outside of Ethereum.