# Resource Machine V2 Summary ### Introduction At the heart of Anoma sits the Anoma Resource Machine. The Resource Machine is an alternative state architecture, its a way to organize state, which is not the same thing as a virtual machine. So why do we even need a resource machine? In order to realize intents, we need the Resource Machine. If you think of Anoma as a virtual excel spreadsheet in the sky, then the resources are like cells of the spreadsheet. The Resource Machine specifies how those cells should be organized. The Resource logics are the rules for how the cells can be modified. And because the resources are just cells in the Anoma spreadsheet, *intents* can specify how they are created and consumed. ### Affordances The Resource Machine has four key affordances, which we will touch on throughout this post. But for now here is a high level summary: - Atomic state transitions of unspecified complexity - the number of resources created and consumed in every atomic state transition is not bounded by the system. For example think of packing thousands of intents like one big ring trade into one atomic transaction. - Information flow control - allows users to specify with granularity what information they reveal to whom. From the perspective of the Resource Machine both shielded and transparent states are treated equally but the amount of information revealed about the states differs. Information flow control can be achieved at the intent-level, state-level, and network-level. - Account Abstraction - each resource is controlled by a resource logic (an instruction set or predicate that constraints the types of valid state transitions for that particular resource kind) which determines how resources of a particular kind can be created or consumed. - Intent-centric architecture - intents are expressed as partial transactions. The resource machine ensures correct and complete fulfillment and settlement. ### Unbundling VMs The Resource Machine is a new type of VM, its not really a VM in the 1960s Von Neumann sense of a VM. The Resource Machine is an alternative state architecture, its a way to organize state, which is not the same thing as a virtual machine. Traditional Virtual Machines like the EVM bundle three components together: - State architecture - how that state is stored & referenced; permissions. - `SSTORE`, `SLOAD`, ... - Instruction set - (how computation is performed) - `ADD`, `MUL`, ... - Message-passing model (how different programs pass messages to each other) - `(address).call(...)` The Resource Machine only assumes a state architecture. In particular, the resource machine unbundles state architecture, instruction set, and message passing model. In the resource machine state is split into resources, each resource is associated with a resource logic which defines the permissions for that piece of state - you can think of this as a function. Resources are immutable, they can be created and consumed only once. The instruction set is an implementation choice which can be made differently for different resource logics. As opposed to taking a particular instruction set the resource machine just says that your resource logic must define its own method of computation that we can verify and prove. For example if you wanted to you could create a ZK-EVM within a resource by defining this instruction set with the resource logic. This choice is left up to developers, which is a nice feature. The only opinionated choice Anoma makes is to leave this decision up to the developer. The message passing model is determined at runtime, depending how intents flow around the network, that will determine how messages get passed between different solvers computing solutions that satisfy different resource logics. In the end, all you need to produce is state diffs and proofs that state was changed correctly. You could make the resource machine compatible with the message passing model of the EVM as well. ### What exactly are Resources? If our spreadsheet analogy is suitable lets get concrete. Resources are the atomic units of state. They can be created once and consumed once. Resources are immutable. Naturally, as you've probably inferred, created but not yet consumed resources make up the current state of the system. - Resource Logic - a predicate associated with each resource which describes when you can create and consume a resource. The conditions of the resource logic are verified by the resource machine. - Resource Kind - specifies the resources fungibility domain. Resources of the same kind are fungible, resources of different kinds are non-fungible. Resource Kinds are derived from the resource logic and some extra data called a resource label. You might be wondering is this an account model, a UTXO model or some third more interesting thing? While we can't claim resources to be more interesting indeed its a third thing distinct from accounts or UTXO. For example, let's take an account model like Ethereum. You have a state tree that says who (what account) owns what. Transactions specify who to transfer tokens to and how the state tree is updated. In a UTXO model like Bitcoin the state is implicit. Transactions specify the consumption of UTXOs and output of new UTXOs. The new state contains all of the new UTXOs. The resource model is somewhat of a generalization of the UTXO model. Indeed, the state is also implicit, but unlike the UTXO model its not limited to one context or currency case. Resources can be of any kind. Resources can be associated with many types of applications. The general idea is you consume resources and produce new resources and that is your new state. ### Commitments and nullifiers In order to create a resources you publish a resource commitment (not defined by the resource machine). How the commitment is published depends on the concrete instantiation of the RM, but generally it is some piece of data associated with the resource, which is enough to show that this specific resource was created without necessarily showing the resource itself. To publish this commitment you add it to a global commitment accumulator. To consume a resource you publish its nullifier (not fully defined) which again depends on the instantiation of the RM (intentional). You add the nullifier to the global nullifier set to count the resource as consumed. In particular, the Anoma resource machine tracks all of these resources using two merkle trees; the commitment tree and the nullifier set. - The commitment tree tracks all resources which have been created. Every time we create a resource we add a commitment to the commitment trie and we re-calculate the commitment trie root using normal merkle tree methods - Every time we consume a resource, we reveal a nullifier and that goes in the nullifier set. ### Intents as partial transactions So we know what resources are, why they are important, and that they need to be created and consumed in order to update the state of the system. But how do we do this? Recall we mentioned in our analogy that intents let us specify how our Anoma spreadsheet is modified. Intents are credible commitments to preferences and constraints over possible states of the system. For our explanation of the resource machine think of intents as partial transactions. This will make sense shortly. Transactions are a piece of data which contains commitments to the resources you want to create and nullifiers to the resources you want to consume. The TX also contains some proofs that say the logics were satisfied and proofs that the commitments and nullifiers were correctly derived as well as some extra data. How do you know transactions are complete? How do you know this is the state transition you want to execute? We use the notion of balance. Each resource has a numeric value associated with it called quantity. A transaction is balanced if for each resource kind the total quantity of created resources = the total quantity of consumed resources. Inputs = outputs in some form. Only balanced transactions can be executed. Partial transactions can also exist (they are real). Composing transactions means that we output a new transaction that combines commitments and nullifiers from the other transactions (two or more), and the proofs and other data representing the state transition of the union of the first two transactions. #### How does this relate to intents? The resource machine operates on intents! In the context of the resource machine we can think of intents as partial transactions. Note that partial transactions are not necessarily intents, depending on the perspective. When we say intent you can think partial transaction. A user makes a credible commitment to a preferred state change by creating an partial transaction that consumes the resource they want to spend and creates the resource they want in exchange. Its up to the solvers to figure out how to match these commitments. Users will submit intents, and intents being partial transactions can be composed until they balance. Once a solver has a balanced transaction, they can publish the transaction for the state to be updated. One nice feature of this approach is that you can get intent-level composability. Solvers can aggregate partial transactions until they balance and even work together to form the optimal balanced transaction before submitting the transaction to the defined controllers (we'll talk about controllers in a different post). Controllers are the parties that need to provide ordering over transactions as specified by the user's intent. One nice affordance of this approach is that instead of composing transactions, solvers compose intents. This allows you to link the actions in transactions together. You can represent atomic actions with atomic transactions because the transaction size is not limited; e.g. atomic bundles of arbitrary complexity. The complexity of the action does not necessarily require splitting transactions, this decision is up to the user. To recap: - Resource changes are enacted with transactions - Transactions must be balanced - Partial transactions can compose - Intents are represented as preferences and constraints ### Applications with the Resource Machine This sounds really cool in theory, but you might be wondering how does a developer write applications in this model? We talked about resource logics and instruction sets but maybe it was a bit too vague. Fortunately, one of the key additions to the Resource Machine version 2 specification is the section on Applications. From here we'll briefly talk about how applications work in the resource model. Applications are virtual, they don't live anywhere. Applications are not deployed or tracked in any global registry. They are content-addressed by the specific logics involved. The state of applications is sharded across the system. An application exists insofar as there exist resources referencing it. If said resources are consumed then the application no longer exists. This is in contrast to many smart contract based blockchain applications. We define an application as a set of *logics* and an *interface*. Logics specify how to create and consume resources of relevant kinds. Resources can be of different kinds, multiple kinds can be associated with an application. The logics of these resource kinds constitutes the logics of the application. In particular, the resource logics have public inputs, private inputs, and constraints. Note that Resource Logic circuits can be turned into a ZK-SNARK circuit if desired for shielded execution. The application interface specifies what can be done with this application in the form of tx functions. TX functions are functions which outputs transactions. Transaction functions are used to create transactions. They represent the logic that determines how intents are translated into concrete state changes. Transaction functions can read from the content-addressed storage and use index functions to access data. They can be executed in pre-ordering (partial evaluation) or post-ordering (full evaluation) phases. Transaction functions operate within a gas model to compute and bound the total cost of computation. In summary, transaction functions take intents and translate them into transactions that can be ordered and executed by controllers. By now, you might be wondering, are applications composable? Yes! The composition of two or more applications would be the composition of the corresponding logics and interfaces. This unlocks a whole world of possibilities. For example you could compose an encrypted slack like messaging applications, Multichat with an application like Kudos. This would allow a user to send messages with Multichat that contain kudos or that trigger the creation and issuance of kudos. For more details on applications in general and application composition see the new section of the RM v2 report and watch Yulia's talk from ZuBerlin. ### Conclusion In this post we reviewed the Resource Machine at a high level. We talked about how the Resource Machine is a state architecture, not a 1960s style Von Neumann Machine. We compared the RM with existing VM architectures which bundle state architecture, instruction set, and message-passing model together. We then discussed resources as atomic units of state and how they can be created and consumed. Next we talked about how intents can specify the state changes users want over their resources by representing them as partial transactions. Finally we discussed applications in the context of the resource machine composing of resource logics and interfaces. We hoped you enjoyed this succinct explanation of the resource machine and encourage you to dig into the new version of the specification for all of the details. Thanks for reading.