A theory of transaction parallelism in blockchains

Decentralized blockchain platforms have enabled the secure exchange of crypto-assets without the intermediation of trusted authorities. To this purpose, these platforms rely on a peer-to-peer network of byzantine nodes, which collaboratively maintain an append-only ledger of transactions, called blockchain. Transactions represent the actions required by users, e.g. the transfer of some units of crypto-currency to another user, or the execution of a smart contract which distributes crypto-assets according to its internal logic. Part of the nodes of the peer-to-peer network compete to append transactions to the blockchain. To do so, they group the transactions sent by users into blocks, and update their view of the blockchain state by executing these transactions in the chosen order. Once a block of transactions is appended to the blockchain, the other nodes validate it, re-executing the transactions in the same order. The serial execution of transactions does not take advantage of the multi-core architecture of modern processors, so contributing to limit the throughput. In this paper we develop a theory of transaction parallelism for blockchains, which is based on static analysis of transactions and smart contracts. We illustrate how blockchain nodes can use our theory to parallelize the execution of transactions. Initial experiments on Ethereum show that our technique can improve the performance of nodes.


Introduction
Decentralized blockchain platforms like Bitcoin and Ethereum allow mutually untrusted users to create and exchange crypto-assets, without resorting to trusted intermediaries. These exchanges can be either simple transfers of an asset from one user to another one, or they can be the result of executing complex protocols, called smart contracts. All the actions performed by users are recorded on a public data structure, called blockchain, from which everyone can infer the amount of crypto-assets owned by each user. The disintermediation stems from the fact that maintaining the blockchain does not depend on trusted authorities: rather, this task is collaboratively performed by a peer-to-peer network, following a complex consensus protocol which guarantees the consistency of the blockchain also in the presence of (a minority of) adversaries in the network.
Users interact with the blockchain by sending transactions, which may request direct transfers of crypto-assets, or invoke smart contracts which in turn trigger transfers according to the programmed logic. The sequence of transactions on the blockchain determines, besides the balance of each user, the state of each smart contract. The nodes of the peer-to-peer network process the transactions sent by users, playing either the role of miner or that of validator. Miners group transactions into blocks, execute them serially to determine the new blockchain state, and append blocks to the blockchain. Validators read blocks, and re-execute their transactions to update their local view of the blockchain state. To do this, validators process transactions exactly in the same order in which they occur in the block, since choosing a different order could potentially result in inconsistencies between the nodes.
Executing transactions in a purely sequential fashion is quite effective to ensure the consistency of the blockchain state, but in the age of multi-core processors it fails to properly exploit the computational capabilities of nodes. By enabling miners and validators to concurrently execute transactions, it would be possible to improve the efficiency and the throughput of the blockchain. Although there exist a few works that address this problem (we discuss them in Section 1.3 below), their approach is eminently empirical, and they are focussed only on Ethereum. A comprehensive study of the theoretical foundations of transaction parallelism in blockchains would improve the understanding of these optimizations, and it would allow to extend them to other blockchains beyond Ethereum. 1.1. Contributions. This paper exploits techniques from concurrency theory to provide a formal backbone for parallel execution of transactions in blockchains. More specifically, our main contributions can be summarised as follows: • We introduce a general model of blockchain platforms, parameterized over the observables and the semantics of transactions (Section 2). Building upon it, we define the semantics of a blockchain by iterating the semantics of its transactions: this reflects the standard implementation of nodes, where transactions are evaluated in sequence, without any concurrency. We show that the two most widespread blockchain platforms, i.e. Bitcoin and Ethereum, can be expressed as an instance of this general model. • We introduce two notions of swappability of transactions (Section 3). The first one is extensional: two adjacent transactions can be swapped if this preserves the blockchain state. The second notion -strong swappability -is intensional: two adjacent transactions can be swapped is the static approximations of their read/written observables satisfy a simple condition, inspired by Bernstein's conditions for the parallel execution of processes. Basically, these conditions require that the observables written by a transaction are not read or written by the other transaction. Theorem 3.12 shows that the strong swappability relation is included in the extensional relation. Theorem 3.17 shows that, if we repeatedly exchange adjacent strongly swappable transactions, the resulting blockchain is observationally equivalent to the original one. • For Bitcoin, we show that the static approximations checked by the strong swappability condition can be easily inferred by transactions: the least approximations of the written observables are the transaction inputs and outputs, while those of the read observables are the transaction inputs (Lemma 3.18). For Ethereum obtaining precise approximations is more complex, because of its Turing-complete contract language. We discuss in Section 3.2 a few tricky cases, and we report in Section 5 our experience with a novel tool to statically Vol. 17:4 A theory of transaction parallelism in blockchains 10:3 detect swappable Ethereum transactions. We further show that, for both Bitcoin and Ethereum, strong swappability is stricter then swappability (Examples 3.21 and 3.25). • Building upon strong swappability, we devise a true concurrent model of transaction execution (Section 4). To this purpose, we transform a block of transactions into an occurrence net, describing exactly the partial order induced by the swappability relation. We model the concurrent executions of a blockchain in terms of the step firing sequences (i.e. finite sequences of sets of transitions) of the associated occurrence net. In Theorem 4.6 we establish that the concurrent executions are semantically equivalent to the serial one. • Finally, we describe how miners and validators can use our results to parallelize transactions, exploiting their multi-core architecture (Section 5). An initial experimental validation of our technique on Ethereum, which exploits a novel static analyser of Ethereum bytecode, shows that there are margins to make it applicable in practice.

1.2.
Overview of the approach: ERC-721 tokens. We illustrate the main elements of our theory by considering an archetypal Ethereum smart contract, which implements a "non-fungible token". A non-fungible token represents a digital version of real-world assets, e.g. access keys, pieces of arts, and serves as verifiable proof of authenticity and ownership within a blockchain network. This kind of contracts are quite relevant: currently, token transfers involve ∼ 50% of the transactions on the Ethereum blockchain [tok], with larger peaks due to popular contracts like Cryptokitties [You17].
We sketch the implementation of the Token contract (the full code is in the Appendix), using Solidity, the main high-level smart contract language in Ethereum. This contract follows the standard ERC-721 interface [ESES,FFB19] and defines functions to transfer tokens between users, and to delegate their trade to other users.
In Ethereum, a smart contract is similar to an object in an object-oriented language: it has an internal state, and a set of functions to manipulate it. Users and contracts are identified by their addresses.
The state of the contract Token is defined by the following mappings: mapping ( uint256 = > address ) owner ; mapping ( uint256 = > bool ) exists ; mapping ( address = > uint256 ) balance ; mapping ( address = > mapping ( address = > bool ) ) operatorApprovals ; Tokens are uniquely identified by an integer value (of type uint256), while users are identified by an address (the address 0 denotes a dummy owner). The mapping owner associates tokens to their owners' addresses, exists tells whether a token has been created or not, and balance gives the number of tokens owned by each user. The mapping operatorApprovals allows users to delegate the transfer of their tokens to third parties.
The following function transferFrom transfers a token from the owner to another user: The require assertion at line 2 rules out some undesirable cases, e.g., if the token does not exist, or it is not owned by the from user, or the user attempts to transfer the token to himself. Once all these checks are passed, the transfer succeeds if the sender of the transaction owns the token, or if he has been delegated by the owner (line 3). The mappings owner and balance are updated as expected (lines 4-6).
The function setApprovalForAll delegates the transfers of all the tokens of the sender to the operator when the boolean isApproved is true, otherwise it revokes the delegation: Users interact with contracts by sending transactions to the blockchain. Transactions involve the execution of smart contract functions that may trigger contracts updates and transfer of crypto-currency from the caller to the callee. For example, consider a user (with address) A, which owns two tokens identified by the integers 1 and 2, and consider the following transactions: Intuitively, transaction T 1 means that A (the sender) calls the function transferFrom of the Token contract to transfer the ownership of token 1 to user P. Transaction T 2 delegates user P to manage A's tokens. Transaction T 3 says that B transfers token 2 from A to Q; T 4 means that user P transfers token 1 to B.
Since each transaction modifies the internal state of the contract Token, the order in which a miner executes them is relevant. For example, executing the sequence of transactions B = T 1 T 2 T 3 T 4 results in a state where B owns token 1, and Q owns token 2. It is easy to see that T 3 can only succeed if executed after T 2 , because it depends on the fact that B is delegated by A, i.e. operatorApprovals[A][B] is true. Therefore, to run in parallel the transactions of B, a miner would need to find an execution schedule that does not affect the resulting state. Our notion of swappability formalizes this intuition: two transactions T and T are swappable if they result in the same state, independently of their order (Definition 3.4). For example, consider the transactions T 1 and T 2 above: regardless of whether T 1 is executed before or after T 2 , after their execution we obtain a state where token 1 is owned by P, and B can act as delegate of A.
Clearly, the notion of swappability outlined above is undecidable whenever the contract language is Turing-equivalent, like in the case of Ethereum. Therefore, swappability cannot be directly used by a miner to determine a parallel execution schedule. We overcome this issue by resorting to a static analysis of the smart contract. The underlying idea is to derive a syntactic approximation of swappability, called strong swappability (Definition 3.11). This captures the fact that two transactions T and T depend and affect different portions of a contract state. Thus, such transactions can be run in any order. For example, the transactions T 1 and T 2 above depend on and modify different parts of the state of the Token contract: therefore, they are strongly swappable.
To detect if two transactions T and T are strongly swappable (in symbols T#T ), one needs to statically over-approximate the state variables that may be read and written during Vol. 17 . Using the same reasoning for T 3 and T 4 , we obtain the following over-approximations of the state variables written/read by T 1 -T 4 (we denote with W i and R i the variables written and read by T i , respectively): Similarly, it is straightforward to see that T 2 #T 4 and T 3 #T 4 , while the other combinations are not strongly swappable.
The strong swappability relation induces a partial order between transactions: this can be exploited by a blockchain node to choose a parallel execution schedule. To do that, from a given sequence of transactions, we build an occurrence net [BD87], a special kind of Petri net with no cycles and where places can hold at most 1 mark. This net encodes the partial order induced by the swappability relation and formalizes the concurrent semantics of transactions. One of our main results is that any concurrent execution in the occurrence net is equivalent to the serial one (see item (c) of Theorem 4.6).
Consider again the the sequence of transactions B = T 1 T 2 T 3 T 4 above. The associated occurrence net is displayed in Figure 1. Intuitively, each transaction in B corresponds, in the net, to a transition (rendered as a box), linked to two places (rendered as circles). A transition can fire when all its incoming places contain the mark. If two transactions are not strongly swappable, the corresponding transitions are linked through a place. In Figure 1, since T 1 and T 3 are not strongly swappable, the place between t 1 and t 3 ensures that t 3 can be executed only after t 1 , so rendering the dependency implicitly defined in B. The same holds for T 2 and T 3 , and for T 1 and T 4 . Instead, transitions corresponding to strongly swappable transactions can be fired concurrently. In our example, this is the case for t 1 and t 2 (since T 1 #T 2 ), as well as for t 3 and t 4 (since T 3 #T 4 ).
Although in our example we have considered the tricky case where the sender and the receiver of tokens overlap, in practice this is a marginal case: in Ethereum, the large majority of transactions in a block either involve distinct users, or invoke distinct ERC-721 interfaces. 1 Therefore, we expect that in practice the degree of concurrency of transferFrom transactions is higher than shown above. 1 Although we are not aware of any work to support this claim, some empirical evidence can be obtained by inspecting the token-related transactions in https://etherscan.io/tokentxns, which shows that this overlapping is a rare event in practice.
Occurrence net for B = T 1 T 2 T 3 T 4 of the ERC-721 token.

Related work.
A few works study how to optimize the execution of transactions on Ethereum, using dynamic techniques adopted from software transactional memory.
In [DGHK17,DGHK18], miners execute a set of transactions speculatively in parallel, using abstract locks and inverse logs to dynamically discover conflicts and to recover from inconsistent states. The obtained execution is guaranteed to be equivalent to a serial execution of the same set of transactions. The work [AKP + 19] proposes a conceptually similar technique, but based on optimistic software transactional memory. The work [SH20] studies the effectiveness of speculatively executing smart contracts in Ethereum. After sampling past blocks of transactions (from July 2016 to December 2017), the authors replay them by using a speculative execution engine, and measure the speedup obtained by parallel execution. The results show that simple speculative strategies are enough to obtain nonnegligible speed-ups. Another observation of [SH20] is that many of the data conflicts (i.e. concurrent read/write accesses to the same state location) arise in periods of high traffic, and they are caused by a small number of popular contracts, like e.g. ERC-20 and ERC-721 tokens. The experiments in [DGHK17] suggest that parallelizing transaction execution may lead to a significant improvement of the performance of nodes: the benchmarks on a selection of representative contracts show an overall speedup of 1.33x for miners and 1.69x for validators, using only three cores. A main difference between these works and ours is that they study empirical aspects of transaction parallelism (e.g., the speedup obtained on a given benchmark), while ours is more focussed on the theoretical counterpart. Still, our theory is not intended to serve as a justification of the correctness of the above-mentioned approaches. Actually, we follow a different path to transaction parallelism, based on static analysis of transactions, rather than on speculative execution. The reason for this divergence lies in the fact that optimizations based on speculative execution of transactions are not fully compatible with current blockchain platforms. Indeed, since speculative execution is non-deterministic, miners need to communicate the chosen schedule of transactions to validators, which otherwise cannot correctly validate the block. This schedule must be embedded in the mined block: since current blockchains do not support this kind of block metadata, implementing in practice these approaches would require a "soft-fork" of the blockchain. Instead of performing dynamic checks, our approach relies on a static analysis to detect potential conflicts. Miners can use any static analysis to execute transactions in parallel; once they have appended a block, validators just need to execute its transactions, possibly exploiting another static analysis to parallelize execution while preserving the semantics of the block. In this way, our approach is compatible with any blockchain platform, without requiring a soft-fork. Vol. 17:4 A theory of transaction parallelism in blockchains 10:7 Our approach is based on static analyses of the variables read and written by transactions. Although the literature describes various static analyses of smart contracts, most of them are focussed on finding security vulnerabilities [MCJ18], and they do not produce the approximations needed for our purposes. A few papers propose static analyses of read/written variables, but they are not specifically targeted to Ethereum bytecode contracts. The recent work [PKS21] implements a static analysis that approximates the portion of a contract state affected by the execution of a transaction. This analysis is then exploited to evaluate the parallel execution of transactions over multiple shards [LNZ + 16]. Although the commutativity relation inferred by the analysis of [PKS21] is similar of our swappability relation, it is not directly usable on arbitrary Ethereum contracts, since the analysis of [PKS21] is targeted to contracts written in the functional contract language Scilla [SNJ + 19]. Actually, the vast majority of transactions in Ethereum are sent to contracts written in Solidity (see footnote 7 in Section 5), hence this assumption could undermine the applicability of the analysis of [PKS21] in the wild. The work [DLP11] describes an analysis based on separation logic, and applies it to resolve conflicts in the setting of snapshot isolation for transactional memory in Java. When a conflict is detected, the read/write sets are used to determine how the code can be modified to resolve it. The work [CCG08] presents a static analysis of read and written locations in a C-like language with atomic sections, and uses it to translate atomic sections into standard lock operations. Designing precise static analyses for Solidity could perhaps take inspiration from these works.
In the permissioned setting, Hyperledger Fabric [ABB + 18] natively supports transaction parallelism. It follows the "execute first and then order" paradigm: transactions are executed speculatively, and then their ordering is checked for correctness [Fab]. In this paradigm, appending a transaction requires a few steps. First, a client proposes a transaction to a set of "endorsing" peers, which simulate the transaction without updating the blockchain. The output of the simulation includes the state updates of the transaction execution, and the sets of read/written keys. These sets are then signed by the endorsing peers, and returned to the client, which submits them to the "ordering" peers. Ordering peers group transactions into blocks, and send them to the "committing" peers, which validate them. A block T 1 · · · T n is valid when the keys read by transaction T i are not written by a transaction T j with j < i. Finally, validated blocks are appended to the blockchain.
A preliminary version of this work was presented at COORDINATION 2020 [BGM20]. The current version substantially extends it, generalising the theory to arbitrary blockchain platforms (while [BGM20] is focussed only on Ethereum). Besides making it possible to extend our results to blockchains beyond Ethereum, this generalization has allowed us to refine some of our results to UTXO-based blockchains like Bitcoin. The current work also contains the complete technical machinery, including proofs, of our theory, and the experimental validation of our optimization technique on Ethereum. 2. An abstract model of blockchains In this section we introduce a general model of blockchain platforms, abstracting from the actual form of transactions, from the language to write smart contracts, and from the fact that transactions are grouped into blocks. We then show how to instantiate this model to the two most widespread blockchain platforms, i.e. Bitcoin and Ethereum. V is a set of valid blockchain states (ranged over by σ, σ , . . .); • σ 0 ∈ Σ is the initial state; • · ∈ Σ × T → Σ is the state transition function (we write T σ for (σ, T) ).
The set of all finite sequences of transactions is denoted by T * , and the empty sequence is denoted by ε. The set T * with the concatenation operator and the neutral element ε is a monoid, referred to as the free monoid over T. A blockchain B is an element of T * . The semantics of a blockchain B starting from a state σ, denoted as B σ , is obtained by iterating the semantics of its transactions: We write B for B σ 0 , where σ 0 is the initial state. We say that a blockchain state σ is reachable if σ = B for some B.
A state update π : O V is a function which defines how values associated with observables are modified. We denote with { v /p} the state update which maps the observable p to the value v. Given a blockchain state σ and a state update π, applying π to σ results in a blockchain state σπ such that, for all observables p: We use P, Q, . . . to range over sets of observables. . We now formalise the basic functionality of Bitcoin within our general blockchain model, simplifying or omitting the parts that are irrelevant for our subsequent technical development.

Transactions. Bitcoin transactions are records with the following fields:
• out is the list of outputs. Each output is a record of the form {scr : e , val : v}, where e is a script, and v ≥ 0 is the amount of bitcoins stored in the output. Intuitively, a later transaction can spend the bitcoins stored in a transaction output by providing a witness which satisfies its script. • in is the list of inputs. Each input is a pair (T, i), meaning that the transaction wants to spend the i-th output of the transaction T; Vol. 17:4 A theory of transaction parallelism in blockchains 10:9 • wit is the list of witnesses, of the same length as in. Intuitively, if the j-th input is (T, i), then the j-th witness must make the i-th script of T evaluate to true. 2 We let f range over transaction fields, and we denote with T.f the content of field f of transaction T. We write T.f(i) for the i-th element of the sequence T.f, when in range. We interchangeably use the notation (T, i) and T.out(i) for transaction outputs. We use A, B, . . . to range over users, and, we just write the name A of a user in place of her public/private keys, e.g. we write versig(A, e) for versig(pk A , e), and sig A (T) for sig sk A (T).
Bitcoin scripts are small programs written in a non-Turing equivalent language. Following [ABLZ18], we model them as terms with the following syntax: Besides constants v, basic arithmetic/logical operators, and conditionals, scripts can access the elements of a sequence (e.n), and the sequence of witnesses of the redeeming transaction (rtx.wit); further, they can compute the size |e| of a bitstring and its hash H(e). The script versig(e, e ) evaluates to 1 if the signature resulting from the evaluation of e is verified against the public key resulting from the evaluation of e, and 0 otherwise. For all signatures, the signed message is the redeeming transaction (except its witnesses).
The evaluation of scripts is defined as a function · T,i , which takes two additional parameters (used for signature verification): the redeeming transaction T, and the index i of the redeeming input/witness. The result of the semantics can be an integer or a bitstring. The rules of the semantics are standard: we refer to [ABLZ18] for a formalization. The in and wit fields are empty, making T 0 a coinbase transaction (i.e., the first transaction in the blockchain). This transaction has two outputs: (T 0 , 1) allows A to redeem 80B, while (T 0 , 2) allows B to redeem 20B. Assume that (T 0 , 1) is unspent, and that A wants to transfer 10B to B, and keep the remaining 70B. To do this, A can append to the blockchain a new transaction, e.g.: The in field points to the first output of T 0 , and the wit field contains A's signature on T 1 (but for the wit field itself). This witness makes the script (T 0 , 1).scr evaluate to true, hence the redemption succeeds, and the output (T 0 , 1) is spent.
Assume now that the outputs (T 0 , 2) and (T 1 , 2) are unspent. Participant B can spend both of them by appending a new transaction T 2 to the blockchain: In this case, the recipient of the 30B is not explicitly specified by the script (T 2 , 1).scr: actually, any transaction which provides as witness a preimage of 51 can spend that output.
Blockchain states. We define observables as transaction outputs (T, i), and the set of values as V = {0, 1}. In this way, blockchain states are partial functions σ ∈ O {0, 1}, modelling the set of unspent transaction outputs (UTXO ). We denote with U σ the set whose characteristic function is σ, i.e. U σ = σ −1 {1}. Hereafter, when not ambiguous we treat T.in as a set, rather than as a sequence, and we write T.out for the set of pairs {(T, 1), . . . , (T, n)}, where n = |T.out|. The initial blockchain state is the UTXO {T 0 .out}, where T 0 is a coinbase transaction (i.e., T 0 .in = ε).
State transitions. We start by defining when a transaction is valid in a blockchain state.

Definition 2.3 (Valid Bitcoin transactions).
We say that a transaction T is valid in a blockchain state σ (in symbols, σ T) when the following conditions hold: val We say that T is consistent when there exists some σ such that σ T.

Condition
(1) requires that all the inputs of T are unspent in σ; condition (2) asks that all the scripts referred to by T.in evaluate to true, using the witnesses in T.wit; condition (3) asks that the value of the inputs of T is greater or equal to the value of its outputs.
We now define the state transition function of Bitcoin as T σ = σ , where: A theory of transaction parallelism in blockchains 10:11 We extend validity to blockchains by passing through their semantics, i.e. we write B T when B is one of the most used platforms for smart contracts: it actually implements a decentralized virtual machine that runs contracts written in a Turing-complete bytecode language, called EVM [Eth21]. Abstractly, an Ethereum contract is similar to an object in an object-oriented language: it has an internal state, and a set of functions to manipulate it. Each contract controls an amount of crypto-currency (the ether ), that it can exchange with other users and contracts. Transactions trigger contracts updates, which may possibly involve a transfer of crypto-currency from the caller to the callee. Users and contracts are identified by their addresses. We use C, D, . . . to range over contract addresses, and f, g, . . . for contract functions. We denote with Addr the set of all addresses X, Y, . . ., including both user and contract addresses.

Transactions. Ethereum transactions are terms of the form:
where A is the address of the caller, X is the address of the called contract or user, f is the called function, n is the amount of ether transferred from A to X, and v is the sequence of actual parameters. A contract has a finite set of functions, i.e. terms of the form f(x){S }, where f is a function name, x is the sequence of formal parameters (omitted when empty), and S is the function body. The functions in a contract have distinct names. We denote with Γ(X) the contract at address X. We abstract from the actual syntax of S , and we just assume that the semantics of function bodies is defined (see e.g. [BGM19, CPZ19, JKL + 20] for concrete instances of syntax and semantics of function bodies). For uniformity, we assume that user addresses are associated with a contract having exactly one function, which just skips. In this way, the statement A.transfer(n), which transfers n currency units to user A, can be rendered as a call to this function.
Blockchain states. Each Ethereum contract has a key-value store, rendered as a partial function V V from values to values. The elements in the domain of this function are also called keys. The set of values V includes basic types, e.g. integers and strings. An observable is a term of the form X.k, i.e. a key in the key-value store at a given address. The possible blockchain states are the partial functions σ ∈ O V such that: • for all addresses X, σ X.balance is defined; • for all user addresses A, σ A.k is defined iff k = balance. The second constraint allows for a uniform treatment of users and contracts. The initial state σ 0 maps each address X to a balance n 0 X ≥ 0, while all the other keys are unbound. State transitions. Let Const be a set of constant names x, y, . . .. We denote with S X σ,ρ the semantics of the statement S . This semantics is either a blockchain state σ , or it is undefined (denoted by ⊥). The semantics is parameterised over a state σ, an address X (the contract wherein S is evaluated), and an environment ρ : Const V, used to evaluate the formal parameters and the special names sender and value. These names represent, respectively, the caller of the function, and the amount of ether transferred along with the call. We postulate that sender and value are not used as formal parameters.
We define the auxiliary operators + and − on blockchain states as follows: i.e., σ + X : n updates σ by increasing the balance of X of n currency units.
is valid in a blockchain state σ (in symbols, σ T) when the following conditions hold: Condition (1) requires that A's balance is sufficient to transfer n ether to X; condition (2) asks that the function call terminates in a non-error state.
We define the semantics of a transaction in a blockchain state σ as follows: If the transaction is valid, the updated state is the one resulting from the execution of the function call. Note that n units of currency are transferred to X before starting to execute f, and that the names sender and value are bound, respectively, to A and n. If the transaction is not valid, i.e. A's balance is not enough or the execution of f fails, then the transaction does not alter the blockchain state. Invalid transactions can actually occur in the Ethereum blockchain, but they have no effect on the state of contracts: so, our semantics makes them identities w.r.t. the append operation.
Example 2.6. Consider a contract at address C which includes the following functions: The first function only sets the value of the key x to 1; the second one transfers a unit of ether to address B when x is 0; the last one always sends a unit of ether to y. Consider a blockchain B = T 0 T 1 T 2 where: Let σ 0 be a state such that σ 0 A.balance ≥ 2. The semantics of B in σ 0 is: where the semantics of the single transactions is: A theory of transaction parallelism in blockchains 10:13

Swapping transactions
We define two blockchain states to be observationally equivalent when they agree on the values associated to all observables. The actual definition of equivalence is a bit more general, allowing us to restrict the set P of observables over which we require the agreement.
The following lemma ensures that our notion of observational equivalence is an equivalence relation, and that it is preserved when we restrict the set of observables: We extend the relations above to blockchains, by passing through their semantics. For all P, we define B ∼ P B iff B σ ∼ P B σ holds for all reachable σ (note that all the definitions and results in this paper apply to reachable states, since the unreachable ones do not represent actual blockchain executions). We write B ∼ B when B ∼ P B holds for all P.
A relation R ⊆ T * × T * is a is a congruence (with respect to concatenation) if: The following lemma states that ∼ is a congruence: therefore, if B and B are observationally equivalent, then we can replace B with B in a larger blockchain, preserving its semantics.
We say that two transactions are swappable when exchanging their order preserves observational equivalence.
Definition 3.4 (Swappability). We say that two transactions T = T are swappable, in symbols T T , when TT ∼ T T.
The theory of trace languages originated from Mazurkiewicz's works [Maz88] allows us to study observational equivalence under various swappability relations. In general, given an alphabet Σ and a symmetric and irreflexive relation I ⊆ Σ × Σ (which models independence between two elements in Σ), the Mazurkiewicz's trace equivalence I is a congruence between words on Σ. Intuitively, all the words in the same equivalence class of I represent equivalent concurrent executions. In our setting, Σ is the set of transactions, and I will be instantiated with various swappability relations. The fact that I is a congruence will allow us to replace a sequence of transactions with an equivalent one within a blockchain. To exemplify Definition 3.5, let I = {(T 1 , T 2 ), (T 2 , T 1 )}. The equivalence class of the word Note that, starting from the word T 0 T 1 T 1 T 2 T 0 , the other words in its equivalence class can be obtained by swapping adjacent occurrences of T 1 and T 2 . This reflects the fact that T 1 and T 2 are assumed to be concurrent, as they are related by I. Intuitively, all the words in the same equivalence class (with respect to I ) represent equivalent executions. This is made formal by Theorem 3.6 below, which ensures that the Mazurkiewicz equivalence constructed on the swappability relation is an observational equivalence. Hence, we can transform a blockchain into an observationally equivalent one by a finite number of swaps of adjacent swappable transactions.
Note that the converse of Theorem 3.6 does not hold: indeed, B B requires that B and B have the same length, while B ∼ B may also hold for blockchains of different lengths (e.g., B = BT where T is a transaction which does not alter the state).
Safe approximations of read/written observables. The relation is undecidable whenever the contract language is Turing-equivalent, e.g., in the case of Ethereum. When is undecidable, to detect swappable transactions we can follow a static approach. First, we over-approximate the set of observables read and written by transactions (Definition 3.7). We then check a simple condition on these approximations (Definition 3.14) to detect if two transactions can be swapped. Of course, the quality of the approximation is crucial to the effectiveness of the approach. In general, the coarser the approximation, the stricter the induced swappability relation: therefore, an overly coarse approximation would undermine the parallelization of transactions.
In Definition 3.7 we state that P safely approximates the observables written by T (in symbols, P |= w T) when executing T does not alter the state of the observables not in P.
Defining the set of read observables is a bit trickier: we require that executing T in two states that agree on the values of the observables in the read set results in two states that differ at most on the observables where they did not agree before the execution of T.
Definition 3.7 (Safe approximation of read/written observables). Given a set of observables P and a transaction T, we define: Example 3.8. Recall from Example 2.6 the Ethereum transaction: Therefore, in both cases BT 2 ∼ Q B T 2 , and so we have proved that {A.balance} |= r T 2 .
Widening a safe approximation (either of read or written observables) preserves its safety; further, the intersection of two write approximations is still safe. From this, it follows that there exists a least safe approximation of the observables written by a transaction.
Lemma 3.9. Let • ∈ {r, w}. Then: (a) if P |= • T and P ⊆ P , then P |= • T; The following example shows that, in general, part (b) of Lemma 3.9 does not hold for read approximations. Note that, in any reachable state σ, it must be σ C.k = σ C.k . Let Q be such that B ∼ Q B , and let σ = B , σ = B , let n = σ C.balance, and let n = σ C.balance. Appending T to B and B will result in: Strong swappability. We use safe approximations of read/written observables to detect when two transactions are swappable, recasting in our setting Bernstein's conditions [Ber66] for the parallel execution of processes. More specifically, we require that the set of observables written by T is disjoint from those written or read by T , and vice versa. When this happens, we say that the two transactions are strongly swappable.
Definition 3.11 (Strong swappability). We say that two transactions T = T are strongly swappable, in symbols T#T , when there exist W, W , R, R ⊆ O such that W |= w T, W |= w T , R |= r T, R |= r T , and: The following theorem ensures the soundness of our approximation: if two transactions are strongly swappable, then they are also swappable. Since its proof depends on notions that have yet to be defined, we postpone it at the end of the section. The converse implication does not hold neither in Bitcoin nor in Ethereum, as shown by Examples 3.21 and 3.25. Theorem 3.13 states that the Mazurkiewicz equivalence # is stricter than . Together with Theorem 3.6, if B is transformed into B by exchanging adjacent strongly swappable transactions, then B and B are observationally equivalent.
Parameterised strong swappability. Note that if the contract language is Turingequivalent, then finding approximations which satisfy the disjointness condition in Definition 3.11 is not computable, and so the relation # is undecidable. This is because strong swappability abstracts from the actual static analysis used to compute the safe approximations: it just assumes that these approximations exist. Definition 3.14 below parameterises strong swappability over a static analysis, which we render as a function from transactions to sets of observables. Formally, W is a static analysis of written observables when W(T) |= w T, for all T; similarly, R is a static analysis of read observables when R(T) |= r T, for all T.
Definition 3.14 (Parameterised strong swappability). Let W and R be static analyses of written/read observables. We say that two transactions T = T are strongly swappable w.r.t. W and R, in symbols T# W R T , if:  The following lemma states that the relation # W R is a sound approximation of swappability. Note that if T#T , then there exist W and R such that T# W R T . Then, from Lemma 3.16 it follows that T and T are swappable. This proves Theorem 3.12, from which in turns we obtain Theorem 3. 13. Putting it all together, we have proved the inclusions:

Vol. 17:4
A theory of transaction parallelism in blockchains 10:17 3.1. Swapping transactions in Bitcoin. By instantiating our general blockchain model to Bitcoin, we can refine some of the swappability results presented before. In particular, in Bitcoin we can easily construct safe approximations of the observables read/written by a transaction, by just considering their inputs and outputs (Lemma 3.18). Further, while strong swappability is stricter than swappability (Example 3.21), strong and parameterized strong swappability coincide in Bitcoin (Theorem 3.22).
The following lemma provides the least safe approximations of the observables read and written by consistent transactions. For inconsistent transactions, these approximations are just the empty set (Lemma 3.19). Intuitively, the observables written by T can be approximated as T.in ∪ T.out, because T spends all the transaction outputs in T.in, and creates the transaction outputs in T.out. Instead, the read observables can be approximated as T.in, since by Definition 2.3, executing T from two states which agree on T.in leads to two states which only differ on the observables for which they differed before.
Lemma 3. 18. Let T be a consistent Bitcoin transaction, and let: Then, W (resp. R) is the least safe approximation of written (resp. read) observables.
Proof. We first show that W and R are safe approximations of written / read observables, and then that they are the least ones.
• W is a safe approximation of written observables. Let Q be such that Q∩(T.in∪T.out) = ∅. For all blockchain states σ, we have that ε σ = σ, and: Since Q and T.in ∪ T.out are disjoint, we have that σ ∼ Q σ . Therefore, T ∼ Q ε. By Definition 3.7, it follows that T.in ∪ T.out |= w T. • R is a safe approximation of read observables. Assume that B 0 ∼ T.in B 1 . Then, T is valid in B 0 iff it is valid in B 1 . Let Q be such that B 0 ∼ Q B 1 , let σ 0 = B 0 and σ 1 = B 1 . For i ∈ {0, 1}, we have that: Since σ 0 ∼ Q σ 1 , it follows that σ 0 ∼ Q σ 1 , and therefore B 0 T ∼ Q B 1 T. By Definition 3.7, it follows that T.in |= r T. • W is the least safe approximation of written observables. By contradiction, let W W be such that W |= w T, and let R R be such that R |= r T. Let p ∈ W \ W . Since {p} ∩ W = ∅ and W |= w T, then T ∼ {p} ε. Since T is consistent, there exists σ such that σ T. Then, T σ = σ , where U σ = (U σ \ T.in) ∪ T.out. Since p ∈ T.in ∪ T.out, it follows that σ p = σp, and so T ∼ {p} ε -contradiction. Therefore, W is the least approximation of the observables written by T. to B T but not to BT , it follows that BT ∼ Q B T -contradiction. Therefore, R is the least approximation of the observables read by T.
Lemma 3. 19. T is inconsistent if and only if ∅ |= w T and ∅ |= r T.

Proof.
For the "only if" part, assume that T is inconsistent. For |= w , for all σ we have that T σ = σ = ε σ . Therefore, for all Q e have T ∼ Q ε, from which it follow that ∅ |= w T. For all |= r , for all B, B and Q we have that if B ∼ Q B then BT ∼ Q B T. Therefore, ∅ |= r T. For the "if" part, assume that ∅ |= w T. Then, for all Q it must be T ∼ Q ε, i.e. T ∼ ε. By definition of ∼ this implies that, for all σ, T σ = ε σ = σ. Therefore, T is not valid in any blockchain state σ, and so T is inconsistent.
By exploiting the results above, we can provide an alternative sufficient condition for (strong) swappability. If T is valid in some state where it is also possible to append another transaction T before T (i.e., T T is valid in that state), then T and T are strongly swappable. This is a peculiar property of UTXO-based blockchains like Bitcoin: in Example 3.26 we show that this is not the case for Ethereum. Lemma 3. 20. In Bitcoin, if there exists σ such that σ T and σ T T, then T#T .

Proof.
Let σ be such that σ T and σ T T. Then, by condition (1) of Definition 2.3: By Lemma 3.18, T.in ∪ T.out and T.in are safe approximations of written/read observables. By (3.1), these approximations satisfy the condition of Definition 3.11, and so T#T .
The following example shows that the converse of Theorem 3.12 does not hold in Bitcoin, i.e. there exist transactions which are swappable but not strongly swappable.
Example 3.21 (Swappable transactions, but not strongly). Consider the transactions in Figure 2, where the scripts and currency values are immaterial (we just assume that condition (2) of Definition 2.3 is satisfied for each matching input/output pair). We show that T 1 and T 3 are swappable. Let σ be a blockchain state. If T 1 is not valid in σ, then T 1 T 3 σ = T 1 T 3 σ holds trivially, since also T 3 is not valid. Otherwise, if σ T 1 : Therefore, T 1 and T 3 are swappable. We now show that they are not strongly swappable. Assume that T 1 is consistent. Then, by Lemma 3.18 it follows that W 1 = T 1 .in ∪ T 1 .out is the least safe approximation of the observables written by T 1 . Let σ be such that T 1 is valid in σ. Then, T 3 is valid in T 1 T 2 σ , and so by Lemma 3.18 is also follows that W 3 = T 3 .in ∪ T 3 .out is the least safe approximation of the observables written by T 3 . Since (T 1 , 1) ∈ W 1 ∩ W 3 , then T 1 and T 3 are not strongly swappable.
Finally, we prove that strong and parameterized strong swappability coincide in Bitcoin.

Swapping transactions in Ethereum.
We now illustrate our notions of swappability in Ethereum through a series of examples. We postpone to Section 5 a discussion on how to approximate the observables read/written by Ethereum contracts, so to compute the parameterized strong swappability relation.
Example 3.23 (Swappability). Recall the contract C and the blockchain B = T 0 T 1 T 2 from Example 2.6. By Definition 3.4, we have that: • T 0 T 2 (see Figure 3, top left). Indeed, regardless of whether T 0 is appended to the blockchain before or after T 2 , after their execution we obtain the same state: σ { 1 /C.x}, when σA.balance ≥ 1, and σ{ 1 /C.x} otherwise.
• T 1 T 2 (see Figure 3, top right). Let σ be such that σC.x = 0 and σA.balance = 1. If we append T 1 before T 2 we obtain the state σ = σ − A : 1 + C : 1 and in this state T 2 is idempotent. Instead, the result of executing T 2 before T 1 is the state σ = σ − A : 1 + B : 1 and in this state T 1 is idempotent. Therefore, T 1 T 2 . • T 0 T 1 (see Figure 3, bottom). Depending on how we append T 0 and T 1 we obtain two different states. Let σ be such that σC.x = 0 and σA.balance ≥ 1. If we append T 1 before T 0 we obtain the state σ { 1 /C.x}. Instead, if we append T 0 and then T 1 we obtain the state σ{ 1 /C.x} − A : 1 + C : 1.
Example 3.24 (Strong swappability). Let C be the contract of Example 2.6, and let f 3 (){skip} be a function of a contract D. Then, consider the following transactions: where A, B, and F are account addresses. Intuitively, T 3 #T 4 because they are operating on observables of different addresses. Formally, consider the following safe approximations of the written/read observables of T 3 and T 4 :  Since (W 3 ∪ R 3 ) ∩ W 4 = ∅ = (W 4 ∪ R 4 ) ∩ W 3 , the two transactions are strongly swappable. Now, consider the following transaction that calls the function f 2 with the address A: This transaction transfers 1 currency unit from B to A. Intuitively, since T 5 touches A.balance, then it should not be swappable with T 3 and T 4 . Formally, consider the following safe approximations W 5 and R 5 : Since W 3 ∩ W 5 = ∅ = W 4 ∩ W 5 , then ¬(T 3 #T 5 ) and ¬(T 4 #T 5 ).
The following example shows that the converse of Theorem 3.12 does not hold, i.e. there may exist transactions that are swappable but not strongly swappable. This is because of static analyses could produce false negatives.
Since it is not possible that the guards of h 1 and h 2 are both true, one of T 1 or T 2 raises an exception, leaving the state unaffected. Then, also in this case we have that However, T 1 and T 2 are not strongly swappable. Intuitively, this is because there exist reachable states σ, σ such that σC 1 k 1 = 0 = σ C 1 k 2 . Formally, consider the following sets which are the least safe over-approximations of the written observables by T 1 and by T 2 , respectively. This means that every safe approximation of T 1 must include the observables of W 1 , and similarly for the set W 2 . Since W 1 ∩ W 2 = ∅, then T 1 #T 2 does not hold.

True concurrency for blockchains
Given a swappability relation R, we transform a sequence of transactions B into an occurrence net N R (B), which describes the partial order induced by R. Our main result is that any concurrent execution of the transactions in B which respects this partial order is equivalent to the serial execution of B (Theorem 4.6).
Occurrence nets. We start by recapping the notion of Petri net [Rei85]. A Petri net is a tuple N = (P, Tr, F, m 0 ), where P is a set of places, Tr is a set of transitions (with P ∩ Tr = ∅), and F : (P × Tr) ∪ (Tr × P) → N is a weight function. The state of a net is a marking, i.e. a multiset m : P → N defining how many tokens are contained in each place; we denote with m 0 the initial marking. The behaviour of a Petri net is specified as a transition relation between markings: intuitively, a transition t is enabled at m when each place p has at least F(p, t) tokens in m. When an enabled transition t is fired, it consumes F(p, t) tokens from each p, and produces F(t, p ) tokens in each p . Formally, given x ∈ P ∪ Tr, we define the preset • x and the postset x • as multisets: • x(y) = F(y, x), and x • (y) = F(x, y). A transition t is enabled at m when • t ⊆ m. The transition relation between markings is defined as m where t is enabled. We say that t 1 · · · t n is a firing sequence from m to m when m t 1 − → · · · tn − → m , and in this case we say that m is reachable from m. We say that m is reachable when it is reachable from m 0 .
From blockchains to occurrence nets. We describe in Figure 4 how to transform a blockchain B = T 1 · · · T n into a Petri net N R (B), where R is an arbitrary relation between transactions. Although any relation R ensures that N R (B) is an occurrence net (Lemma 4.1), our main results hold when R is a strong swappability relation. The transformation works as follows: the i-th transaction in B is rendered as a transition (T i , i) in N R (B), and transactions related by R are transformed into concurrent transitions. Technically, this concurrency is specified as a relation < between transitions, such that (T i , i) < (T j , j) whenever i < j, but T i and T j are not related by R. The places, the weight function, and the initial marking of N R (B) are chosen to ensure that the firing ot transitions respects the relation <. Step firing sequences. Theorem 4.6 establishes a correspondence between concurrent and serial execution of transactions. Since the semantics of serial executions is given in terms of blockchain states σ, to formalise this correspondence we use the same semantics domain also for concurrent executions. This is obtained in two steps. First, we define concurrent executions of B as the step firing sequences (i.e. finite sequences of sets of transitions) of N # (B). Then, we give a semantics to step firing sequences, in terms of blockchain states. We denote finite sets of transitions, called steps, as U, U , . . .. Their preset and postset are defined as • U = p∈U • p and U • = p∈U p • , respectively. We say that U is enabled at m when • U ≤ m, and in this case firing U results in the move m be a finite sequence of steps. We say that U is a step firing sequence from m to m if m Concurrent execution of transactions. To execute transactions in parallel, the idea is to execute them in isolation, and then merge their changes, whenever they are disjoint. The state updates π resulting from the execution of a transaction are formalised as in Section 2.
An update collector is a function Π that, given a state σ and a transaction T, gives a state update π = Π(σ, T) which maps (at least) the updated observables to their new values. In practice, update collectors can be obtained by instrumenting the run-time environment of blockchains, to record the state updates resulting from the execution of transactions. We Definition 4.2 (Update collector). We say that a function Π is an update collector when T σ = σ (Π(σ, T)), for all σ and T.
There exists a natural ordering of update collectors, which extends the ordering between state updates (i.e., set inclusion, when interpreting them as sets of substitutions): namely, Π Π holds when ∀σ, T : Π(σ, T) ⊆ Π (σ, T). The following lemma characterizes the least update collector w.r.t. this ordering. The merge of two state updates is the union of the corresponding substitutions; to avoid collisions, we make the merge undefined when the domains of the two updates overlap.
Definition 4.4 (Merge of state updates). Let π 0 , π 1 be state updates. When dom π 0 ∩ dom π 1 = ∅, we define π 0 ⊕ π 1 as follows: The merge operator enjoys the commutative monoidal laws, and can therefore be extended to (finite) sets of state updates.
We now associate step firing sequences with state updates. The semantics of a step U = {(T 1 , 1), . . . , (T n , n)} in σ is obtained by applying to σ the merge of the updates Π(σ, T i ), for all i ∈ 1..n -whenever the merge is defined. The semantics of a step firing sequence is then obtained by folding the semantics of its steps.
Definition 4.5 (Semantics of step firing sequences). We define the semantics of step firing sequences, given Π and σ, as: Concurrent execution of blockchains. Theorem 4.6 below relates serial executions of transactions to concurrent ones (which are rendered as step firing sequences). Item (a) establishes a confluence property: if two step firing sequences lead to the same marking, then they also lead to the same blockchain state. Item (b) ensures that the blockchain, interpreted as a sequence of transitions, is a step firing sequence, and it is maximal (i.e., there is a bijection between the transactions in the blockchain and the transitions of the corresponding net). Finally, item (c) ensures that executing maximal step firing sequences is equivalent to executing serially the entire blockchain.
Let the following sets be safe approximations of the corresponding transactions where the subscript denotes the transaction and the superscript denotes if the set approximates the read or written keys, e.g., P w f safely approximates the keys written by T f , whereas P r g safely approximates the keys read by T g . By Definition 3.11 we have that T f #T h and T g #T h , but ¬(T f #T g ). By instantiating the construction of Figure 4 using the relation #, we obtain the occurrence net N # (T f T h T g ) of Figure 5, where t f = (T f , 1), t h = (T h , 2), and t g = (T g , 3). From this occurrence net is easy to see that transition t g can only be fired after t f , while t h can be fired independently from t f and t g . This is coherent with the fact that T h is swappable with both T f and T g , while T f and T g are not swappable.
Recall that Π is the least update collector, i.e. a function that given a state σ returns the minimal update π mapping qualified keys to their new values. To run in parallel the transactions, we execute them in isolation and then we merge their effect, by merging their state updates. For example, given a state σ such that σC.x = σC.y = 0 the minimal updates for t f , t g , and t h are: By Definition 4.5 the parallel execution of t f , t g , and t h in σ results in the following states σ{ 1 /C.y, 1 /C.x} Note that, for all σ the serial execution of T f and T h (in both orders) is equal to their concurrent execution (similarly for T g and T h ): Instead, for all σ such that σCx = σCy = 0 the concurrent executions of T f and T g may differ from serial ones: This is due the fact that t f and t g are not concurrent in the occurrence net of Figure 5. Now let U = {t f , t h }{t g } be a maximal step firing sequence of N # (B). Since t f and t h are concurrent by item (c) of Theorem 4.6 we can conclude that the semantics of U in the state σ is equivalent to the serial one of B = T f T h T g : It is worth noticing that any other maximal step firing sequence of N # (B) results in the same state. For example, consider U = {t f }{t g , t h }, where the places (t f , * ), (t g , * ) and (t h , * ) contain one token each, while the other places have no tokens. Since U and U lead to the same marking, by item (a) of Theorem 4.6 we conclude that Although U is maximal, it is not a step firing sequence, since the second step is not enabled, therefore, no items of Theorem 4.6 apply to U . This is coherent with the fact that U does not represent any sequential execution of B.

Experimental validation
In this section we discuss how to exploit our theoretical results in practice to improve the performance of blockchain nodes. We start by sketching the algorithm used by miners and validators to construct blocks. Miners should perform the following steps: (1) gather from the network a set of transactions, and put them in an arbitrary linear order B, which is the mined block; (2) compute the relation # W R on B, using a static analysis of read/written observables; (3) construct the occurrence net N # W R (B); (4) execute the transactions in B concurrently according to the occurrence net, exploiting the available parallelism. The protocol followed by validators is almost identical to that of miners: the main difference is that step 1 is skipped, and at step 2, the relation # W R is computed starting from the block B to be validated. Note that the static analysis used by a validator could be different from the analysis used by the node which mined B, and therefore the occurrence net could be different from that used by the miner. However, this is not a problem: from item (c) of Theorem 4.6 it follows that executing B on any occurrence nets built on any static analysis of read/written variables leads to the same state. In this way, blocks do not need to carry the occurrence net as metadata: this makes our approach is compatible with any blockchain platform, without requiring a soft-fork.
For the case of Bitcoin, we argue that implementing this algorithm is straightforward: indeed, Lemma 3.18 allows to compute the strong swappability relation directly from the transactions inputs and outputs. For Ethereum the problem is more complex, since the algorithm relies on a static analysis of the observables read/written by transactions. Therefore, in the rest of this section we evaluate the feasibility of our approach on Ethereum. To this purpose, we implement a prototype analyser of Ethereum bytecode, and we evaluate its precision on a relevant contract. We then compare the time of sequential executions of blocks against their parallel executions (which includes the time for the static analysis). Despite the limitations of the static analysis tool (that we discuss at the end of the section), we find that our technique improves the execution time in our experiment. The total time is the sum of times for analyzing the contract bytecode, computing the occurrence net, and of running the transactions in parallel.

Analysing Ethereum bytecode.
In general, precise static analyses at the level of the Ethereum bytecode are difficult to achieve, since the language has features like dynamic dispatching and pointer aliasing which are notoriously a source of imprecision for static analysis. As far as we know, none of the analysis tools for Ethereum contracts exports an over-approximation of read/written keys which is usable to the purpose of this paper. The only tool we know of that outputs such an over-approximation is ES-ETH [Mar19], but it has several limitations which make its output too coarse to be usable in practice. So, to perform an empirical validation of our approach we develop a new prototypical tool [Tos20a]. Our tool takes as input the EVM bytecode of a contract and a sequence of transactions, and gives as output the occurrence net, using the construction in Section 4. The tool implements as a standalone library [Tos20b] a static analysis that over-approximates the read and written keys for each function of a given smart contract.
Before presenting the design underlying our static analyzer, we briefly recall the EVM memory model and how the bytecode generated by Solidity compiler is organized (see [Eth21,Woo14] for further details). The execution of a smart contract involves three kinds of memory: (i) the world state, i.e. a mapping from addresses to account information (e.g., balances, functions, etc.); (ii) the contract storage, mapping keys to values; (iii) the working memory, i.e. a stack which stores function parameters, local variables and temporary values created during the function execution. The EVM machine features instructions to load and store values from these memories, e.g., SSTORE and SLOAD operate on the world state.
The Solidity compiler splits the generated bytecode in two sections: the constructor code and the runtime code. The constructor code is executed upon contract creation, and typically returns the runtime code to be deployed on the blockchain. The runtime code is executed upon a function call. This code first initializes the contract storage and the stack, and then transfers the control to the body of the function called in the transaction.
Our static analysis symbolically executes both the constructor and runtime code. Since EVM bytecode has no explicit notion of function declaration, we analyze the constructor code and the first part of the runtime code to detect which functions are declared in the contract and where their code is located. Once we identify the functions, we analyze their code separately. For each function we compute three sets: the sets of keys that are read/written by the function, and the set of calls made to external contracts. To construct these sets we exploit a symbolic semantics of EVM instructions, that operates on abstract versions of the stack and memory storage. Intuitively, the analysis of each instruction results in an abstract value, specifying the operation performed and the affected keys.

Experiments.
We experimentally validate our approach by estimating the potential speed up achieved by running transactions in parallel. To this purpose we consider a contract which implements a two-players lottery (see Listing 2 in the Appendix for its Solidity code). Intuitively, a user who wants to participate in the lottery performs the following steps: (1) join the game by sending a certain amount of cryptocurrency, representing the bid; (2) commit to a secret string by sending its hash, which is stored on the contract state; (3) once both players have completed the commit phase, they can reveal their secrets, independently from each other; (4) once both players have revealed, anyone can call the win function to transfer the bets to the winner, who is determined according to the parity of the length of players' secrets.
Once the contract has been initialized (with transaction t n ), a complete execution of the lottery then requires 7 transactions: t j 0 , t c 0 , t r 0 , representing the join, commit and reveal of the first player, t j 1 , t c 1 , t r 1 for the second player, and t w for invoking the win function. Figure 6 displays the occurrence net computed by our tool from a single complete execution of the lottery. The occurrence net shows that players can join, commit and reveal independently from each other. However, the commit transactions can be fired only after both join have been fired, while the reveal transactions can be fired only after both commit. Further, the win transaction can be fired only after both players have revealed their secrets.
To estimate the possible speed up obtained by running the transactions in parallel, we play the whole lottery 10 times, generating a total amount of 70 transactions (besides the contract creation). We first run these transactions sequentially, and measure the execution time of each transaction. Then, we use our tool to find a parallel schedule, and compute the time spent if the transactions were run in parallel.
We carry out our experiments on a laptop machine with Intel Core i5-3320M CPU @ 2.60GHz and 4Gb of RAM. 4 We use geth 5 to setup a development chain, and Truffle 6 to deploy a local instance of the Lottery contract on this chain.
We first compute the sequential execution time by summing up the time spent for running each transaction, as reported by the logs of geth. The first column of Table 1 displays the time of sequential execution, averaged over 10 measurements.
Then, we analyze the sequence of transactions using our tool, obtaining the occurrence net. The second column of Table 1 displays the average time spent by the tool to analyze the transactions and to build the occurrence net (again, the measurements are repeated for 10 times). From the occurrence net, we estimate the average time required by the most expensive parallel schedule. This schedule is computed as the longest and most expensive path (in terms of time) of the occurrence net. The time required to execute this schedule is in the third column of Table 1. Note that estimating the cost of the parallel execution in this way implies that we are assuming to have a sufficient number of threads to execute the transactions (in the Lottery experiment, two threads are enough), and that once a transaction is assigned to a thread it is executed with no latency or queuing time. Finally, the fourth column of Table 1 displays the total time required to analyze the transactions and to run them in parallel.
Although the experiment is carried with simplifying assumptions and on a single contract, the results of Table 1 are a first empirical evidence of the practical applicability of our approach, and that parallelizing the execution of transaction may lead to performance improvements in Ethereum nodes. We discuss below some current limitations and possible improvements of our experimental validation.
Limitations and possible improvements. The current version of our static analysis tool of Ethereum bytecode has been developed under some simplifying assumptions. First, the tool can only analyse contracts whose bytecode respects the following conditions, which are always satisfied for bytecode obtained by the Solidity compiler: (i) the constructor code always returns the runtime code; (ii) the runtime code does not access the world state in response to a call with an invalid function signature; (iii) when a transaction calls a valid function, the runtime code always transfers the control to the body of the function. While the tool could be adapted to updates of the Solidy compiler, pieces of bytecode not generated by the compiler may easily violate these conditions, and it seems implausible to obtain a precise analysis without making any assumption on the structure of bytecode. However, this should not be an issue in practice, since the vast majority of transaction currently occurring in Ethereum blocks looks like to call contracts with a verified Solidity source 7 .
A second simplification used in our tool is that the over-approximation of the keys read/written by a transaction does not exploit the transaction fields (besides the called contract and function). Thus, different calls to the same function but with different actual parameters result in the same over-approximation. Although this simplifies the implementation, it may decrease the precision of the analysis, because the values of the function parameters are left abstract. Consequently, the occurrence net constructed by the tool contains more dependencies than strictly needed. For instance, the tool would not detect the swappable transactions in the ERC-721 example described in Section 1.2, since there the transaction fields are essential to obtain a precise over-approximation. A possible improvement could be to refine the analysis tool using all the transaction fields.
Finally, the measurements we performed in our experiment are too coarse-grained to allow a precise estimation of the speed up achieved by running the transactions in parallel. For example, we did not consider the overhead required to maintain the threads and to dispatch the transactions when executing the schedule given by the occurrence net. To precisely measure this overhead, one would need to integrate our approach with an Ethereum node, and use it to compute the achieved speed up. Although preliminary, the results of our experiment shown in Table 1 are positive enough to make us believe that a speed up will be confirmed also when taking into account these overheads.

Conclusions
We have proposed a theory of transaction parallelism for blockchains, aimed at improving the performance of blockchain nodes. We have started by introducing a general model of blockchain platforms, and we have shown how to instantiate it to Bitcoin and Ethereum, the two most widespread blockchains. We have defined two transactions to be swappable when inverting their order does not affect the blockchain state. Since swappability is undecidable in general, we have introduced a static approximation, called strong swappability, based on a static analysis of the observables read/written by transactions. We have rendered concurrent executions of a sequence of transactions as step firing sequences in the associated occurrence net. Our main technical result, Theorem 4.6, shows that these concurrent executions are semantically equivalent to the sequential one. An initial experimental assessment of our approach in Ethereum shows that there are margins to make it applicable in practice.
We remark that our work does not address the problem of selecting and ordering transactions to maximize the gain of the miner, i.e. it does not proposes strategies to construct blocks of transactions (step 1 in the miner algorithm described in Section 5). Rather, our theory studies how to exploit the available parallelism to execute a block of transactions, assuming that the block is given (which is always the case for validators). Miners can follow different strategies to construct blocks, driven by the economic incentives provided by the blockchain platform. In Bitcoin, miner incentives are given by block rewards and by the fees paid by users for each transaction included in a block. In Ethereum, besides these incentives, miners can extract value directly from smart contracts by suitably ordering users' transactions and inserting their own. This form of miner extractable value has become prominent with the emergence of DeFi contracts like decentralized exchanges [DGK + 20, QZG21, ZQC + 21]. Once a miner has formed a block of transaction according to its strategy, our theory tells how to speed up its execution by parallelizing transactions.
In Ethereum, malevolent users could attempt a denial-of-service attack by bloating the blockchain with transactions directed to contracts which are hard to statically analyse. This would make a naïve miner spend a lot of time executing the static analysis on these adversarial transactions. This kind of attacks can be mitigated by miner strategies which put a strict upper bound to the execution time of the analysis. Note that, since most transactions in Ethereum are directed to a small number of well-known contracts, like e.g. ERC tokens, DeFi contracts, etc. [OHJ20], to achieve an effective speed up it would be enough to parallelize the transactions sent to these contracts, and execute the transactions sent to unknown contracts without any concurrency.
Aiming at minimality, our model does not include the gas mechanism, which is used in Ethereum to pay miners for executing contracts. The sender of a transaction deposits into it some crypto-currency, to be paid to the miner which appends the transaction to the blockchain. Each instruction executed by the miner consumes part of this deposit; when the deposit reaches zero, the miner stops executing the transaction. At this point, all the effects of the transaction (except the payment to the miner) are rolled back. Our transaction model could be easily extended with a gas mechanism, by associating a cost to statements and recording the gas consumption in the environment. Remarkably, adding gas does not invalidate approximations of read/written keys which are correct while neglecting gas. However, a gas-aware analysis may be more precise of a gas-oblivious one: for instance, in the statement if k then f long (); x:=1 else y:=1 (where f long is a function which exceeds the available gas) a gas-aware analysis would be able to detect that x is not written.
Let B B . We have to show B ∼ B . We proceed by induction on the rules above. For rules [ 0] and [ 1], the thesis follows by reflexivity, since ∼ is an equivalence relation (Lemma 3.2). For rule [ 2], the thesis follows immediately by Definition 3.4. For rule [ 3], first note that B = B 0 B 1 and B = B 0 B 1 . By the induction hypothesis it follows that: Therefore, by two applications of Lemma 3.3: Proof of Lemma 3. 9. Item (a). For the case • = w, let P |= w T and P ⊆ P . Let Q be such that Q ∩ P = ∅. We have to show that T ∼ Q ε. Since P ⊆ P , it must be Q ∩ P = ∅. Then, since P |= w T, it must be T ∼ Q ε, as required. For the case • = r, let P |= r T and P ⊆ P . We have to show that, for all B 1 , B 2 , if B 1 ∼ P B 2 and B 1 ∼ Q B 2 , then B 1 T ∼ Q B 2 T. But this follows immediately by the fact that P ⊆ P and P |= r T.
Proof. By induction on |B 2 |. For the base case, it must be B 2 = ε and hence T 2 = ∅. Then, B 1 B 2 = B 1 and T 1 ∪ T 2 = T 1 . Therefore, the thesis coincides with the first hypothesis. For the induction case, it must be B 2 = B 2 T, with |B 2 | = n. Furthermore, it must be T 2 = {T} ∪ T 2 , for some T 2 such that B 2 T 2 . By the induction hypothesis: We now formalize when a blockchain B is a serialization of a multiset of transactions T.
Definition B.5 (Serialization of multisets of transactions). We define the relation between blockchains and multisets of transactions as follows: ε []

B T BT ([T] + T)
Lemma B.6. If T# W R T for all T ∈ T and B T then, B = B 1 T B 2 =⇒ T# W R T . Proof. By a simple induction on |T| we can conclude that, whenever B is of the form B 1 T B 2 for some B 1 , B 2 and T , we have that T ∈ T. The thesis then follows immediately.
B 1 π 2 p = B 1 p = B 2 p = B 2 π 2 p = B 1 T p Definition B.8. Let Π be a state updater, and let W be such that ∀T : W(T) |= w T. We say that Π and W are compatible when ∀σ, T : dom Π(σ, T) ⊆ W(T).

Vol. 17:4
A theory of transaction parallelism in blockchains 10:35 We extend the semantics of transactions to finite multisets of transactions. Hereafter, we denote with [] the empty multiset, with [T 1 , . . . , T n ] the multiset containing T 1 , . . . , T n , and with A + B the sum between multisets, i.e. (A + B)(x) = A(x) + B(x) for all x.
Definition B.9 (Semantics of multisets of transactions). We denote the semantics of a multiset of transactions T, in a state σ and an update collector Π, as T Π σ , where the partial function · Π σ is defined as: T Π σ = σ T∈T Π(σ, T). Hereafter, we say that a multiset T is strongly swappable w.r.t. a relation R ⊆ # when: Clearly, T = [T] + T for some T such that B T . Let Π( B 0 , T) = π T . By the induction hypothesis: Notice that: where π T ∈T Π( B 0 , T )). Let Π( B 0 , T) = π T . Since T is strongly swappable w.r.t. # W R and Π is compatible with W, it must be dom π ∩ dom π T = ∅, and hence (π ⊕ π T ) is defined. Then, it must be: = B 0 π π T By Lemma B.  The following theorem ensures that the parallel execution of strongly swappable transactions is equivalent to any sequential execution of them.
Theorem B.11. Let T be strongly swappable w.r.t. # W R , and let B T. Then, for all σ: Proof. Direct by Lemma B.10 and by the fact that every W is compatible with Π .
A parellelized blockchain B is a finite sequence of multisets of transactions; we denote with ε the empty sequence. We extend the semantics of multisets (Theorem B.9) to parallelized blockchains as follows.
Definition B.12 (Semantics of parallelized blockchains). The semantics of parallelized blockchains is defined as follows: We write B Π for B Π σ 0 , where σ 0 is the initial state. We also extend the serialization relation (Definition B.5) to parallelized blockchains.
Proof. Transitivity and reflexivity hold by definition. For antisymmetricity, assume that (T i , i) < * (T j , j) and (T j , j) < * (T i , i). Then, it is easy to verify that i ≤ j and j ≤ i, and so i = j. Since T i and T j are uniquely determined by i and j, we have that T i = T j . Therefore, (T i , i) = (T j , j), as required.
Lemma B. 16. N R (B) is an occurrence net, for all R and B.