Private Smart Contracts Framework
Private Smart Contracts Framework
Contracts
“v0.9” prerelease
1 Introduction
Distributed ledgers put forth a new paradigm for deploying Internet services that
transcends the classical client-server model. In this new model, it is no longer
the responsibility of a single organization or a small consortium of organizations
to provide the platform for deploying the relevant business logic. Instead, ser-
vice deployments can take advantage of decentralised “trustless” computation to
improve their transparency and security as well as reduce the need for trusted
third parties and intermediaries.
Bitcoin [25], the first successfully deployed distributed ledger protocol, does
not lend itself easily to the implementation of arbitrary protocol logic that can
support the above paradigm. This led to many adaptations of the basic protocol
for specific applications, such as NameCoin [18], a distributed domain regis-
tration protocol, or Bitmessage [29], a ledger-based communications protocol,
and many others. An obvious problem with this approach is that, even though
the Bitcoin source code can be copied arbitrary times, the Bitcoin community
of software developers and miners cannot, and hence such systems are typi-
cally not sustainable. Smart contracts, originally posited as a form of reactive
computation [27], were popularized by Ethereum [31], solving these problems
by providing a uniform and standardized approach for deploying decentralized
computation over the same back-end infrastructure.
Smart contract systems rely on a form of state-machine replication [26] – all
nodes involved in maintaining the smart contract keep a local copy of its state,
and advance this copy with a sequence of requests. This sequence of requests
needs to match for each node in the system – thus the need for consensus over
which requests are made, and their order. In practice, this is achieved through
distributed ledgers.
A seemingly inherent limitation of the decentralised computation paradigm
is the fact that protocol logic deployed as a smart contract has to be completely
non-private. This, naturally, is a major drawback for many of the applications
that can potentially take advantage of smart contracts. Promising cryptographic
techniques for lifting this limitation are zero-knowledge proofs [17], and secure-
computation [16,10]. Motivated by such cryptographic techniques, systems sat-
isfying various definitions of privacy – and requiring various trust assumptions –
have been proposed [4,22,32,19], as we detail in Subsection 1.2. Their reliance on
trust assumptions nevertheless, in one way or another, fundamentally limits the
decentralization features that are afforded by their non-private counterparts. For
instance, a common restriction of such systems is to assume a small, fixed set of
participants at the core of the system. This fundamentally clashes with the basic
principles of a decentralised platform like Bitcoin or Ethereum (collectively clas-
sified as Nakamoto consensus). In these systems, the set of parties maintaining
the system can be arbitrarily large and independent of all platform performance
parameters. This puts forth the following fundamental question that is the main
motivation for our work.
2
to express each of these systems together with a concise description of the pri-
vacy they afford. Thus, Kachina does not supersede these protocols, but rather
gives a common foundation on which one can build further privacy-preserving
systems.
3
some information about the transitions f and g. Being able to achieve this type
of public reconciliation while retaining some privacy requires a mechanism that
enables parties to predict transition conflicts and specify the expected leakage.
We achieve this through the novel concept of state oracle transcripts, which
are records of what operations and assumptions are performed on, and assumed
about, the contract’s state. These allow contract authors to optimise when trans-
actions are in conflict and when not, while also ensuring that the leakage is fixed
once the transaction is created. We further provide a mechanism for analysing
when reordering transactions is safe with respect to a user’s private state, by
specifying a sufficient condition for which transactions must be declared as de-
pendencies when creating a new transaction.
4
specifying the contract (∆r , Λr ) which should be run, a security-conscious con-
tract author may also write a corresponding ideal contract (∆i , Λi ). Our model
gives great flexibility for the author to choose what leakage this contract incurs,
and what influence the adversary has over its behaviour. If the author then en-
sures that the implementation of this ideal contract fits Kachina’s realisation
requirements, then it is sufficient to prove that the real contract UC-emulates
∆r ,Λr ∆i ,Λi
the ideal one – that is, Fsc UC-emulates Fsc . By the fact that the real
contract meets Kachina’s preconditions, it in turn is UC-emulated by Kachina
– and consequently, by the transitivity of UC emulation, the contract author can
securely implement the original, ideal, contract. Te demonstrate this technique
we provide a UC realization of the salient features of Zerocash [3] – implemented
as a Kachina contract – in Section 5, and prove that it UC-emulates a much
simpler ideal payments contract.
There has been an increasing amount of research into smart contracts and their
privacy over the past few years. The results of these often focus on specific use-
cases or trust assumptions. We briefly discuss how the most notable of these
relate to our work in Kachina.
Ethereum. As the first practically deployed smart contract system, Ethereum [31]
is the basis of a lot of our expectations and assumptions about smart contracts.
Ethereum provides no privacy guarantees of any kind, however we refer back to
it during this paper when arguing about modelling choices. We assume that the
reader has some familiarity with the basic flow of Ethereum, such as contract
creation, contract calls, and gas costs.
5
it overcomes the former’s limits of expressiveness. A combination of these proto-
cols would arrive at a similar result as presented in this paper, although with a
more restrictive access to the shared state – due to the reliance on UTXOs, the
shared state of Plutus is a set allowing insertions and deletions, while Kachina
permits arbitrary operations.
Hawk. One of the earliest work on privacy in smart contracts, Hawk [22] is also
one of the most general. It describes how to compile private variants of smart
contracts, given that all participants of the contract trust the same party with its
privacy. This party, the “manager”, can break the contract’s privacy guarantees
if corrupt, however it cannot break the correctness of the contract’s rules. The
construction used in Hawk for the manager party relies of zero-knowledge proofs
of correct contract execution, and is closely related to the proofs parties perform
in Kachina. Kachina’s major difference is a greatly relaxed trust model, which
allows for contracts in settings where there no trusted third party to facilitate
privacy.
Enigma. There are two forms of Enigma: A paper discussing running secure
multi-party computation for smart contracts [32], and a system of the same
name designed to use Intel’s SGX enclave to guarantee privacy [14]. The former
has a lot of potential advantages, but is severely limited by the efficiency of
general-purpose MPC protocols. The latter is a practical construction, and can
claim much better performance than any cryptography-based protocol. The most
obvious drawbacks are the reliance on an external trust assumption, and the poor
track record of secure enclaves against side-channel attacks [5].
State channels. State channels, such as those discussed in [13], occupy a similar
space to Arbitrum, due to their reliance on off-chain computation and on-chain
dispute resolution. The dispute resolution process is different, more aggressively
6
terminating the channel, and typically it considers only participants on the chan-
nel that interact with each other. The privacy given is almost co-incidental, due
to the interaction being local and off-chain in the optimistic case. State channels
are more restrictive in their expressiveness than Arbitrum, in that only few users
can interact with it, a drawback which allows for its main feature however: not
requiring on-chain transactions in the optimistic case.
2 Technical Overview
We first aim to establish informally the goals and core technical ideas of this
paper. These will be fleshed out in the remainder of the paper’s body, with some
of the technical details – primarily in-depth UC constructions and proofs – in
the appendix. We will discuss each of our contributions in turn, and discuss
how combined, they present a powerful tool for constructing privacy-preserving
smart contract systems.
Our model. When a user interacts with a smart contract system, two points
in time are important: The point where the user decides to query the smart
contract, and the point where this query has a lasting effect on the ledger.
Typically, and in our model, defined in Section 3, this takes the form of a user
creating a transaction at one point in time, and this transaction at some point
entering the confirmed ledger state.
At the core, a smart contract is a reactive state-machine, which alters its state
for each user query, according to a transition function ∆. A user can not know
what state the contract will be in, once one of their transactions is confirmed,
and it is quite possible for a transaction to no longer make sense – for instance,
two users cannot both spend the same coin. The adversary may provide its
own input to the transition function, that allows the adversary to influence the
contract’s execution as much – or as little – as the transition function allows.
When a user creates a transaction, in broadcasting it he likely leaks some-
thing about the transaction’s content. The transaction the user creates may also
depend not just in his original input, but the state of the system, as he sees it.
For instance, a user may be able to avoid conflicts with previous transactions
they made – such as in the case of spending UTXO-style coins, not spending
the same coin as a prior transaction. A leakage function Λ is responsible for
both deciding what information is leaked, and deciding which information from
the point of creating a transaction, may later affect its behaviour. This function
also generates a description of the leakage itself, which the user must sign off
on before the transaction is broadcast – this is not a technical requirement, but
an ethical one: As estimating leakage becomes more complex, users can not be
expected to predict the implications of their actions in advance.
The core protocol idea. The kernel of the Kachina protocol, as defined in Sec-
tion 4, is as follows: We restrict ourselves to contracts which divide their state
into a public state σ, and, for each party p, a private state ρp . Roughly these
7
correspond to the shared ledger, and a party’s local storage respectively. We
constrain the transition function to be over pairs (σ, ρp ) instead of over all pri-
vate states – i.e. a party may only change their own private state. Honest users
will maintain their own private state in accordance with the contracts’ rules,
while the contract must anticipate that dishonest parties may set it arbitrar-
ily (this can be circumvented by committing to private states, as descripted in
Appendix G).
In this setting, we can derive a clear image of what leakage is, and a nat-
ural construction based on zero-knowledge proof-systems presents itself: When
creating a transaction, a user may evaluate the transition function against the
current contract state, and prove the corresponding public state update σ 7→ σ 0
in zero-knowledge. Locally, the user updates his own private state, and publishes
a transaction consisting of the transition σ 7→ σ 0 , and a proof of this transitions
correctness.
State oracles. The core ideas as presented above is naïve in its construction,
primarily due to it proving transitions from one public state to another. In
practice, a contract does not exist in a vacuum, and other users will interact with
it. This is especially true for large systems – if I make an Ethereum transaction, it
will almost certainly be applied after many other transactions I do not even know
about. As these different states are not the same as the original, the transition
cannot be applied, as seen in Figure 1. Instead of capturing a transition from
σ 7→ σ 0 , we would rather want to capture a partial function from states to
successor states.
Transaction creation
σ π 7→σ n
σπ σn
σ π 7→σ n
σπ σn
···
Transaction application(s)
···
σ π 7→σ n
∅ ··· σo ··· σ1 7
···
·· σ π 7→σ n
· σ2 7
σ π 7→σ n
σ3 7
Fig. 1. Direct state-transition based transactions can be applied only in the state σ π
they were proven for.
Our approach for modelling this is to have contracts interact with the state
through oracle queries, instead of directly – see Subsection 4.1. A contract sub-
mits a function q to be run against the current state, this returns a result r, and
8
an updated state. Instead of proving the state transition correct, we prove that
the transition function makes a sequence of queries, given their responses match
a corresponding sequence of responses. We refer to this sequence of queries and
responses, ((q1 , r1 ), . . . , (qn , rn )), as an oracle transcript T . Transactions can be
used to determine if a transition makes sense in any given state, and if so, what
the new state should be: If each query, applied in turn, returns the expected
response, then the transition makes sense, and the same mechanism informs
what the resulting state will be. This allows a greater flexibility, sketched in
Figure 2, although it is worth noting that some conflicts are inherent, and can-
not be resolved. We illustrate our solution, and why it is necessary, in detail in
Subsection 4.1.
Transaction creation
T
σπ σn
T
σπ σn
···
Transaction application(s)
···
T
∅ ··· σ o ··· σ1 σ10
···
·· T
· σ2 7
T
σ3 σ30
High-level usage. In practice privacy requirements may not fall within the bound-
aries of any general system, and will require some adjusting or combining with
novel research for their realisation. For instance, building a privacy-preserving
currency system is not possible in Kachina directly – after all, it needs the
balance to be a shared state, which a user cannot overwrite arbitrarily, but this
should also be private – being suitable for neither the shared public state σ, nor
the untrusted local private state ρ. In this case, the design of Zerocash [3] can
easily be adopted to overcome this issue – an example we work out in detail in
Section 5.2. This approach of adding additional layers of privacy is powerful, as
can be seen on this example.
This leaves an uncomfortable situation, however: The Zerocash protocol is a
poor ideal-world specification, but it is this we can realise directly. We propose
using multiple stages of UC-emulation instead: To begin with, we specify as an
ideal smart contract, what leakage and transitions a privacy-preserving payments
system should have. We then specify the core Zerocash design as a Kachina
contract, allowing us to conclude that the ideal Zerocash smart contract is UC-
9
emulated by Kachina, parameterised with the Zerocash definition. To bridge
the gap, we prove a further UC-emulation: the ideal private payments smart
contract is UC-emulated by the ideal Zerocash smart contract.
This allows us to rely solely on the transitivity of UC-emulation to extend
Kachina with additional privacy features – an approach that is made possible by
the design of the ideal smart contract functionality. This functionality provides
the abstraction of the leakage descriptor to ensure that the two worlds can have
the environment sign off on the same leakage, despite underlying differences.
Further, while the ideal smart contract’s adversarial input a is unused through-
out the Kachina protocol, it is crucial for this stage of the UC-emulation – it
affords the simulator a means to influence the ideal private payments contract’s
execution. In Section 5, where this full analysis is performed, this is used to
select party’s public keys in the ideal payments contract, for instance. Finally,
in Appendix J, we show how a system of multiple interacting contracts can be
constructed as an instance of a single, “system” smart-contract.
10
cryptographic simplicity of the construction, and does not necessarily hold for
privacy-preserving systems, although leakage is hard to eliminate completely). 2.
is a consequence of the usage of an underlying ledger, which permits adversarial
influence. Finally, 3. stems from it not always being possible for a transaction to
be applicable in any state. As a result, the state against which a user creates a
new transaction dictates partially when this transaction makes sense.
To represent the contract, we will consider its state σ, and a transition func-
tion ∆. We will adopt the convention that the initial state is denoted by ∅, even
though the contract itself may ascribe a different meaning to this. ∆ should be
a function which takes as inputs the old state, some input w, and the party
identifier of the submitter, p. It should return a new state, σ 0 , and an output y.
While this is sufficient for many things, we will also allow as inputs a context z,
and an adversarial input a. We assume ∆ to be deterministic – nondeterminism
can be simulated by including a randomness source in the context, as seen in
Subsection 4.3. In sum total, a contract is primarily defined by the following
transition function: (σ 0 , y) ← ∆(σ, p, w, z, a).
As mentioned previously, real implementations of smart contracts have some
leakage. Further, due to the ledger-based nature of them, this leakage occurs
separately, before the contract actually evaluates the input. We define a non-
deterministic leakage function Λ, which takes the input w, the party ID p, and
the state of the smart contract in the user’s current view, σp . This function
should return some leakage lkg, which is passed to the adversary.
At the same time, Λ can define what the context z used in the transition
function should be. This value is important for allowing the behaviour of a
contract depend on when a query was submitted, and not just when it is executed
– this will be detailed further in Subsection 4.1. As smart contracts are complex
objects, the user can not be expected to accurately anticipate what leakage a
given query might incur. As a result, we will also return a leakage descriptor
desc, which the user must sign off on before any leakage occurs, or the query is
fully submitted.
A few additional variables may affect what gets leaked. In particular, the
transactions a user previously made, but which are not yet in the confirmed
ledger state may affect the behaviour of new transactions by the same user. For
instance, if the user previously spent a coin, they will not attempt to spend it
again. For this purpose, each such unconfirmed transaction, identified by some
transaction handle τ , is passed to the leakage function, as the list of unconfirmed
transaction Up . Further, a mapping T is supplied, mapping each transaction
handle to the tuple (p, w, z, a, D), dictating the transaction’s owning party, input,
context, adversarial input, and lastly dependencies. These are all as discussed
before, except dependencies, which will be explained shortly. Finally, the leakage
function is given the length of p’s view of the ledger, t – named due to its
approximation of time.
D represents transaction dependencies, which in this work have proven to
be necessary to ensure transactions are executed in the correct order. At a high
level, each transaction has associated dependencies, specified as a list of other
11
transactions, and ideally being . If a new transaction is processed, each of its
dependencies must have previously been successfully processed in the same order,
or the new transaction is rejected. These allow enforcing ordering constraints on
transactions, and constitute a form of leakage. This is also the final purpose of Λ:
to determine which dependencies the new transaction should have. In summary,
a contracts leakage and context are computed as follows: (desc, lkg, D, z) ←
Λ(t, Up , T, σp , p, w).
We consider the pair (∆, Λ) to define a smart contract, and parameterise the
ideal smart contract functionality presented in Subsection 3.2 by both.
The general ideal world usage of this model of smart contracts follows this
pattern:
1. A party submits a contract input w.
2. The corresponding context and leakage are computed.
3. The party signs off on the leakage description desc, or cancels.
4. The adversary is given (lkg, D), and can supply the adversarial input a.
5. At some later point, the submitting party can retrieve the output of ∆ (if
any), while other parties can interact with the modified state.
3.2 UC Specification
∆,Λ
The ideal smart contract functionality Fsc formally captures this notion of
a contract as a leaky state transition function that can be queried by parties
via a ledger. It is parameterised by the transition function ∆ and the leakage
function Λ, and it operates in a hybrid world with a ledger functionality Gledger . A
candidate for such a ledger is GsimpleLedger , as introduced in Appendix B, although
any compatible functionality is sufficient. To avoid confusion with the various
∆,Λ
contract state in Fsc , we refer to both the authoritative ledger state as well as
the party specific prefixes of that state as ledger views.
∆,Λ
Functionality Fsc (sketch)
12
When receiving a message (post-query, w) from an honest party p:
Retrieve p’s current ledger view of length `, and compute the corresponding
smart-contract state using ∆. Feed this, together with p’s unconfirmed transac-
tions and their inputs, the length `, and the input w to Λ.
Ask p if the leakage description returned is acceptable. If so, query the ad-
versary for a unique transaction ID τ , and some adversarial input corresponding
to the leakage, and the transaction’s dependencies. Record the original input, the
adversarial input, the context returned by Λ, and the transaction’s dependencies
as being associated with τ and p. Record the transaction as unconfirmed by p,
and then send (submit, τ ) to Gledger , and return τ .
13
4.1 State Oracles and Transcripts
We introduce the novel tools of state oracles, and state oracle transcripts to
abstract interaction with a contract’s state. When abstracting interaction with
the public and private states, many options are possible – we could constrain the
state to a specific type of data structure, and only support certain operations
over it for instance. This is in fact what the extended UTXO model [11], and
Zexe [4] do. While this has many practical benefits, and is easy to reason about,
it does not, however, enable the action performed on-chain to depend on the
chain’s most current state, which Ethereum permits.
An example. To better motivate the need for some further abstraction over state
interactions (i.e. not proving a state transition directly), we present a represen-
tative example of a smart contract, and discuss how different abstractions of its
state will affect its ability to function.
In particular, we consider a sealed bid auction contract2 . We will assume
that external to this contract exist a notion of time, and two separate privacy-
preserving on-chain assets3 , all within some large system the auction contract
may interact with (such as those presented in Appendix J). The auction is opened
by the seller party, and multiple buyer parties may bid on it. The structure of
this auction allows for the following interactions:
14
and some identification of the current winner. It needs to maintain a set of
the bids themselves – these may just be some kind of reference for the asset
management system to verify, however there is a need to ensure that a buyer
cannot create a new bid after time t1 – something which is not the job of any
asset management system. Finally, we keep a further set: bids which have been
the maximum revealed at some point, but were then succeeded. Privately, the
contract has minimal bookkeeping to do: Parties need to remember which bids
are theirs, and what information is needed to open or withdraw them.
Suppose we adopted a naïve approach to state transitions, and proved the
transitioning from one state to another directly, with no abstraction of any kind.
During the bidding phase it is easily possible for multiple users to attempt to
bid simultaneously (especially considering the delay until transactions become
confirmed by an underlying ledger). In this case, only one of these transactions
will go through – as soon as this transaction changes the state by adding its own
bid, the proof of any other simultaneous transaction becomes invalid.
Often simple abstractions are used instead, such as byte-level access. This
would allow a buyer and the seller to withdraw concurrently – as their withdraws
affect different parts of the state. It does not work as desired in all cases even
in this example – assume a singly-linked list is used to store the set of bids. If
two users attempt to add their own bid to this set simultaneously, they will both
attempt to overwrite the same pointer.
Clearly this is not necessary – a smart abstraction would realise that whichever
user bids first, the resulting set of bids is the same, even if its binary represen-
tation may not be. It is not always the case that the order does not matter – for
instance when claiming the maximum bid later in the auction, if Alice wishes
to claim her bid of 5 is the maximum, she cannot do this after Bob has claimed
his bid of 7. Even here a smart abstraction buys us something however – while
Alice’s transaction may get rejected if placed after Bob’s, the other way around
is fine!
15
The context z encodes additional information a party expects the oracle to
have access to. The need for this context will be detailed later, once the basic
functionality is established. If z = ∅, we may write qi (σ), and omit z. The
oracle may itself abort, in which case we assume any function using it directly
will return ⊥ (in particular Γ, as used in Subsection 4.3). An overview of the
interactions of Γ with public and private state oracles may be found in Figure 3.
z ρ w σ
Private
q1ρ q1σ
r1ρ r1σ
.. ..
U . Γ . U
qnρ qnσ
rnρ rnσ
Trusted
0 y
ρ σ0
Fig. 3. The interaction of Γ (see Subsection 4.3), with Γ having oracle-access to two
separate states: the public state σ, and the private state ρ, together with the context
z.
Crucially, we note that the definition above allows retrieving the queries made
to the oracle, and the responses given by it. We will refer to this sequence of
queries and responses as the oracle transcript T . This transcript is crucial in
the functioning of Kachina, as it provides a means to decouple the part of a
transaction which is proven in zero-knowledge from both the public and private
states entirely. Specifically, we prove that given some input, and a sequence of re-
sponses recorded in a transcript, the smart contract will make the corresponding
queries.
Revisiting our example. To see how this works in practice, we consider what
interactions (besides those verifying time, and the authenticity of the assets
transferred) are made through the public state oracle in our example of a sealed
bid auction. To be more concrete, let us assume that the public state σ consists
of the following elements: 1. A public key of the seller, allowing it to withdraw:
pks , 2. A non-private representation of asset B, the item for auction: b, 3. A
non-private representation of the current maximum bid of asset A: a, 4. The
value of the bid in 3.: v, 5. The public key of the current maximum bidder,
pkb , 6. A set of private representations of asset A of bids: S, and 7. A set of
non-private representations of asset A of previous maximum bids, R. We write
σ = (pks , b, a, v, pkb , S, R), initialised by the seller to (pks , b, ∅, 0, ∅, ∅, ∅).
16
The private state ρ by contrast consists of three variables describing an un-
opened bid: the opening pubBid that is eventually to be made public, a hiding
commitment which it is an opening for, bid, and its value v, all of which may be
set to ⊥: ρ = (pubBid, bid, v)
For each of the (non-initialising) interactions previously listed, we demon-
strate the corresponding oracle queries made:
While this example does not fully handle all corner cases (such as a buyer
bidding multiple times), it is hopefully sufficient to illustrate the core idea: The
query made, and the response to it, will often be the same even if another party
has since interacted. Two bid do not conflict, as the oracle queries each makes
can be run even if the contract’s state has since changed. We also do not need to
17
concern ourselves with the representation: Whether the sets are implemented as
linked lists, arrays, or balanced trees does not matter – the abstract data type
behaves the same, after all.
Transcript oracles. For a given transcript T , we define the transcript oracle O(T )
to act as an oracle with the following behaviour: Internally, it keeps a counter i,
initialised to 1. Let T = (q1 , r1 ) k . . . k (qn , rn ). Then, when receiving a query
q, check if q = qi . If so, increment i, and return ri . If q 6= qi , or i > n, abort.
For transcript oracles, we define the additional function consumed(O), which
returns > if and only if i + 1 = n, i.e. each recorded query has been processed
by the oracle. We refer to a transcript as minimal in some usage context, if once
the usage context, given oracle access to the transcript oracle returns, consumed
holds.
18
order to be able to claim that the transcript doesn’t just start with the queries
an honest execution would make, but matches them exactly.
To tie things together, the basic function is that Alice generates a transcript
for the oracle accesses that her private computation performs. She proves this
transcript correct, and minimal. She sends the transcript and proof to Bob, who
is convinced of the correctness and minimality, and can therefore replicate the
effects of the transcript by applying it to the state directly.
Inherent conflicts. While the approach of abstracting the interaction with the
state away has many benefits, it relies on the contract itself making use of them in
such a way that the original problems of resilience to reorderings are not simply
pushed down the line. For instance, a contract which offers some currency to
the first party to interact with it clearly is not resilient to reordering, by its
very design. Nonetheless, two parties may both see the contract, see the funds it
holds unclaimed, and both decide to claim them. This inherent conflict cannot
be resolved, simply because the parties are acting concurrently.
It is further possible for a contract to be poorly designed, and introduce
conflicts through that. Suppose a contract is auctioning an item, and two parties
wish to bid. A poorly programmed design may have an array of bids in the public
state, and may see both parties attempting to place their bid into the first cell
of the array. A functionally equivalent approach, minimising conflicts, would
instead instruct the public state to insert at the end of the array, regardless of
how many items are occupied.
A note on context. The design of oracles for interacting with the state of the
contract is convenient when this response of the oracles is unlikely to change
over time. In some cases, however this is just not feasible, and the contract may
need advice about highly volatile state. For instance, the Merkle tree roots used
in the Zerocash [3] protocol change with every transaction processed, but need
to have statements proved about them.
To solve this problem, we run the private state oracle in the context of the
view of the submitting party at the point of transaction creation. Specifically,
it can not only read and write the current private state, but can also read the
public and private states at the time when the query was submitted. We also
provide the contract access to “optimistic projections” of the state, which are
the public and private states if all unconfirmed transactions were to appear in
order immediately after the parties current ledger state. This allows the party
to avoid conflicting with their own unconfirmed transactions – for instance in
the Zerocash contract described in Section 5.2.
Finally, we provide a randomness source η as part of the context – this is
chosen as well at the time of query, and ensures that – for honest parties – the
private state oracle may behave nondeterministically. Formally, the context z in
Kachina is a tuple (σ o , ρo , σ π , ρπ , η), where (σ o , ρo ) is the querying parties view
of the contract state at the time of submission, and (σ π , ρπ ) is their projected
view of the contract.
19
4.2 The Challenge of Dependencies
Formal definition. More formally, dep is a pure function, over the following items:
a) a set of unconfirmed transactions, their associated private state transcript,
their associated context, and their respective dependencies. b) the new transac-
tion’s private state transcript, and c) the new transaction’s context (including
the confirmed private state, ρo . It returns a sequence of transactions which must
20
all proceed the new transaction, in the specified order. In mathematical notation,
D ← dep(X, T , z), where ∀x ∈ X : ∃τ, Tτ , zτ , Dτ : x = (τ, Tτ , zτ , Dτ ).
To begin with, we introduce some mathematical notation: First, we write SX
for the set of all permutations of the set X, where each permutation is assumed
to be a list. Second, we write X v Y for the subsequence relation, where one list
is a subsequence of another if and only if the items of the first are found in the
second in the same order:
Finally, we note that the following dependency function will always satisfy
the constraints: dep(X, T , z) = map(proj1 , X). This is as it maximally constrains
the possible permutations which satisfy the dependencies.
21
is given oracle access to the calling user’s private state ρp , and a shared public
state σ, with oracle accesses functioning as described in Subsection 4.1, and
Subsection 4.1. The adversary is permitted to program its own private state
oracle arbitrarily – this corresponds to local computation, after all. In addition to
Γ, the protocol is parameterised by a leakage descriptor desc, which receives the
time t, the sequence of unconfirmed transactions, their private state transcripts
and dependencies, X, both public and private state transcripts Tσ and Tρ , the
original input w, and the context z. Finally, it is parameterised by a dependency
function dep, which is under the constraints noted in Subsection 4.2.
Formally, (∆Kachina , ΛKachina ) ∈ CKachina if and only if there exist corre-
sponding Γ, desc, and dep, such that they are derived approximately as follows:
Some corner cases have been omitted; the full version of these functions may
be found in Appendix C.
22
Protocol Kachina (sketch)
The Kachina protocol realises the ideal smart contract functionality when pa-
rameterised by a transition function Γ, a leakage descriptor desc, and a depen-
dency function dep, such that the corresponding (∆, Λ) pair is in CKachina . It
L
operates in the (Fnizk , GsimpleLedger )-hybrid model, where ((Tσ , ·), (w, Tρ )) ∈ L iff
ΓO(Tσ ),O(Tρ ) (w) does not abort, and exists normally.
∆,Λ
Theorem 1. For any contract (∆, Λ) ∈ CKachina , Kachina UC-emulates Fsc ,
L
in the Fnizk -hybrid world, in the presence of GsimpleLedger .
23
served, and from I holding, we can conclude that the information revealed to it,
or the dummy adversary, is insufficient to distinguish the two worlds.
The simulator for Kachina is quite straight forward; it simply creates simu-
lated NIZK proofs for all honest transactions, and forces the adversary to reveal
witnesses to the simulated NIZK functionality in time for these to be input to
the ideal smart contract. Fundamentally, the security proof relies on state tran-
scripts, as defined in Subsection 4.1, being interchangeable with full state oracles
in the same setting, and this setting being enforced by both the protocol and
functionality.
While a lot of factors must be formally considered, this is derived from re-
ceiving NIZK proofs as part of valid transactions, which prove precisely that if
the preconditions for the transaction are met, then the update performed on the
public state is the same. The private state is a little more tricky, but is guar-
anteed by the dependency invariant J holding for honest parties. This lets us
similarly argue that the private state transcript will have the same effect as the
ideal-world execution.
24
required to make a Zerocash transaction: Merkle-paths to your own commit-
ments, the selection of randomness for new coins, and the encryption of the
secret information of these coins. This information can then be handed to the
central, provable core of the contract, which computes a coin’s serial number,
verifies the Merkle-path, and verifies the integrity of the transaction. Finally, the
serial number and new commitment are sent to the public state oracle, which
ensures the former is new, and adds the latter to the current tree.
A reasonable objection to this design may be that the contract itself is no
longer self-evidently correct – indeed specifying what this Zerocash contract
does, and proving that it achieves this is a separate issue. This is something
that applies in many cases – few problems fall neatly into the state separation
model of Kachina. We can see the Kachina contract here as a middle ground
in the UC emulation proof, and define ideal transition and leakage function for a
∆,Λ
private payments system. We can then show that Fsc parameterised with these
∆,Λ
is UC-emulated by Fsc parameterised with the Zerocash contract. Finally, the
actual realisation is achieved by applying the Kachina protocol itself to this
contract – by the transitivity of UC-emulation.
This has the advantage of having a standardised format and interface for pri-
vacy preserving smart contracts, while acknowledging that often privacy is non-
trivial, and requires substantial additional cryptographic work. Private payments
systems are precisely such a scenario, where fortunately the work has already
been done by Zerocash – which we can precisely capture in our model.
Ideal Private Payments We present first the formal specification of the ideal
private payments smart contract. This consists of the corresponding transition
and leakage functions, ∆pp , and Λpp , and supports the following operations: a)
init, giving a party a unique public key, b) (send, pk), sending one of the parties
own coins to the public key pk, c) mint, creating a new coin for the calling party,
and d) balance, returning the calling party’s balance.
The state transition function for a private payments system. Parties have asso-
ciated public keys, and balances. The payments system allows for parties with-
out a public key to generate one, and for parties to transfer and mint single-
denomination coins, as well as query their own balance.
25
Assert that p’s public key is not set, and ensure the uniqueness of the adver-
sarial input pk (e.g. by incrementing it until it is an unused public key). Record
pk as p’s public key, and return it.
When receiving an input (σ, p, (send, pk) , ·, a):
If p is honest, spend from their associated public key. If not, the adversarial
input is the public key to spend from, asserting it is not associated with any
honest party. Assert the spending public key’s balance is positive, and decrease it
by 1. Increase the receiving public key pk’s balance by 1.
When receiving an input (σ, p, mint, pk, ·):
Increase pk’s balance by 1.
When receiving an input (σ, p, balance, B, ·):
Return the balance B.
Each operation on ∆pp has minimal leakage, revealing only which operation was
performed, and in the case of a transfer, the time and the recipient – if and only
if the recipient is corrupted.
26
Merkle tree root it is contained in, and a path to it. Assert the validity of the
Merkle path, and the correct computation of the coin. Compute it’s serial number,
and instruct the public state oracle to mark this serial number as spent (asserting
its uniqueness), and assert that the provided Merkle tree root exists. Finally,
the private state oracle computes a coin commitment owned by pkz , with the
commitment secrets encrypted with pke . The public state oracle inserts this new
commitment to the set of commitments, and appends the message to the list of
messages, updating the set of past Merkle tree roots.
When receiving an input mint:
Instruct the private state oracle to assert the existence of secret keys. It must
then sample a new coin commitment owned by the recorded private key, and
record the commitment and associated secrets as a held coin. The commitment
is passed to the public state oracle, which is instructed to record it in the set of
commitments, and update the list of past Merkle roots.
When receiving an input balance:
Instruct the private state oracle to process new messages in the public state
context for both the confirmed and projected state. The oracle then returns the
size of the intersection of the sets of held coins in the confirmed and projected
private states. This is returned by this query.
Proof (sketch). desczc is a pure function, and Γzc is a function with oracle access
to public and private state variables. More tricky is showing that depzc satisfies
its requirements. Transcripts generated by run-Γ fall into three categories: They
set a private key (initialisation), they insert a coin (minting), or they remove a
coin, and insert some number of coins (sending).
Consider first a new initialisation transaction. It does not affect the behaviour
of unconfirmed minting and sending transactions, as these do not use the current
private state’s secret key. Further, it cannot co-exist with another unconfirmed
initialisation transaction, as this would initialise the private keys, ensuring an
abort, which violates the preconditions of dependencies.
If the new transaction is a minting or balance transaction, this happily func-
tions independently of other transactions, not having any requirements on the
current private state. Likewise for sending transactions, the state transcript itself
only depends on ρo and ρπ , not the dynamic ρ. Specifically, the only thing vary-
ing there is which coins get added and removed from ρ.C, ~ but this information
is not directly used – its only purpose is to reduce the necessary re-computation
the next time around. u
t
27
UC Emulation
∆ ,Λpp ∆zc ,Λzc
Theorem 2. Fsc pp is UC-emulated by Fsc in presence of GsimpleLedger .
This proof can also be carried out via invariants. Here the invariant tracking
is simple: The real and ideal world have the same coins owned by the same
users at any time. Our simulator, described in Subsection C.3, has a lot of book-
keeping to do, mostly to conjure up fake commitments and encryptions for the
real-world adversary, and replicating them in the real world. We provide a full
proof sketch in Appendix E.
∆ ,Λ
Corollary 1. Fsc pp pp is UC-emulated by Kachina, parameterised by Γzc , depzc ,
L
and desczc , in the Fnizk -hybrid world, in the presence of GsimpleLedger .
6 Conclusion
We have shown in this paper how to build a large class of smart contracts with
only zero-knowledge and distributed ledgers, and outline how this can be used
and extended upon. To do so we have modelled formally what smart contracts
with privacy are, represented as a state transition function that is fed inputs
from a ledger, and a leakage function that decides what parts of the input are
visible on this ledger. We have then defined which class of such contracts we will
consider in this paper, and presented a protocol, Kachina, which utilises non-
interactive zero-knowledge proofs and state oracles to achieve the desired smart
contract behaviour, while leaking only part of the computation performed.
While the designs are largely theoretical and detached from any actual imple-
mentation, we stress that they were designed with real-life constraints in mind:
The use of state oracles allows moving most computationally hard, or storage
intensive operations outside of the NIZK itself, reducing their cost. While the
NIZK must still be universal, zero-knowledge constructions with universal refer-
ence strings exist [24], and are practical to use in this setting, although they are
not directly provable in the UC model.
The concrete semantics of programming a smart contract, as well as the
corresponding oracles, have been deliberately left unspecified, as many candi-
dates are possible, and a well suited language may be domain specific. That
said, most existing (public) smart contracts are small and simple in size, and
would translate and run well even within a zero knowledge proof, if compiled
into appropriate constraints.
In ending this paper, we would like to make clear that this problem space is
by no means solved. We have shown how to realise a specific class of privacy-
preserving smart contracts, however privacy is not such a simple issue to be
addressed by a single paper. In Appendix I, we sketch the relation of trust models
with privacy, and we believe this taxonomy of trust, and how each level can be
addressed, formalised, and brought into a unified model, is a crucial long-term
research question for providing meaningful privacy to users of smart contract
systems.
28
References
1. Christian Badertscher, Peter Gazi, Aggelos Kiayias, Alexander Russell, and Vassilis
Zikas. Ouroboros genesis: Composable proof-of-stake blockchains with dynamic
availability. In David Lie, Mohammad Mannan, Michael Backes, and XiaoFeng
Wang, editors, ACM CCS 2018, pages 913–930. ACM Press, October 2018.
2. Christian Badertscher, Ueli Maurer, Daniel Tschudi, and Vassilis Zikas. Bitcoin
as a transaction ledger: A composable treatment. In Jonathan Katz and Hovav
Shacham, editors, CRYPTO 2017, Part I, volume 10401 of LNCS, pages 324–356.
Springer, Heidelberg, August 2017.
3. Eli Ben-Sasson, Alessandro Chiesa, Christina Garman, Matthew Green, Ian Miers,
Eran Tromer, and Madars Virza. Zerocash: Decentralized anonymous payments
from bitcoin. In 2014 IEEE Symposium on Security and Privacy, pages 459–474.
IEEE Computer Society Press, May 2014.
4. Sean Bowe, Alessandro Chiesa, Matthew Green, Ian Miers, Pratyush Mishra, and
Howard Wu. Zexe: Enabling decentralized private computation. IACR Cryptology
ePrint Archive, 2018:962, 2018.
5. Jo Van Bulck, Marina Minkin, Ofir Weisse, Daniel Genkin, Baris Kasikci, Frank
Piessens, Mark Silberstein, Thomas F. Wenisch, Yuval Yarom, and Raoul Strackx.
Foreshadow: Extracting the keys to the intel SGX kingdom with transient out-of-
order execution. In William Enck and Adrienne Porter Felt, editors, 27th USENIX
Security Symposium, USENIX Security 2018, Baltimore, MD, USA, August 15-17,
2018., pages 991–1008. USENIX Association, 2018.
6. Benedikt Bünz, Shashank Agrawal, Mahdi Zamani, and Dan Boneh. Zether: To-
wards privacy in a smart contract world. Cryptology ePrint Archive, Report
2019/191, 2019. https://eprint.iacr.org/2019/191.
7. Jan Camenisch, Robert R. Enderlein, Stephan Krenn, Ralf Küsters, and Daniel
Rausch. Universal composition with responsive environments. In Jung Hee Cheon
and Tsuyoshi Takagi, editors, ASIACRYPT 2016, Part II, volume 10032 of LNCS,
pages 807–840. Springer, Heidelberg, December 2016.
8. Ran Canetti. Universally composable security: A new paradigm for cryptographic
protocols. In 42nd FOCS, pages 136–145. IEEE Computer Society Press, October
2001.
9. Ran Canetti, Yevgeniy Dodis, Rafael Pass, and Shabsi Walfish. Universally com-
posable security with global setup. In Salil P. Vadhan, editor, TCC 2007, volume
4392 of LNCS, pages 61–85. Springer, Heidelberg, February 2007.
10. Ran Canetti, Yehuda Lindell, Rafail Ostrovsky, and Amit Sahai. Universally com-
posable two-party and multi-party secure computation. In 34th ACM STOC, 2002.
11. Manuel Chakravarty, Roman Kireev, Kenneth MacKenzie, Vanessa McHale, Jann
Müller, Alexander Nemish, Chad Nester, Michael Peyton Jones, Simon Thomp-
sona, Rebecca Valentine, and Philip Wadler. Functional blockchain contracts.
https://iohk.io/research/papers/#functional-blockchain-contracts, 2019.
12. Stefan Dziembowski, Lisa Eckey, Sebastian Faust, and Daniel Malinowski. Perun:
Virtual payment hubs over cryptocurrencies. In 2019 IEEE Symposium on Security
and Privacy, 2019.
13. Stefan Dziembowski, Sebastian Faust, and Kristina Hostáková. General state chan-
nel networks. In David Lie, Mohammad Mannan, Michael Backes, and XiaoFeng
Wang, editors, ACM CCS 2018, pages 949–966. ACM Press, October 2018.
14. The Enigma Project Team. What is Enigma? https://enigma.co/discovery-
documentation/, 2019.
29
15. Etherscan. Ethereum sync (default) chart. https://etherscan.io/chartsync/
chaindefault, 2019.
16. Oded Goldreich, Silvio Micali, and Avi Wigderson. How to play any mental game
or A completeness theorem for protocols with honest majority. In Alfred Aho,
editor, 19th ACM STOC, pages 218–229. ACM Press, May 1987.
17. Shafi Goldwasser, Silvio Micali, and Charles Rackoff. The knowledge complexity of
interactive proof-systems (extended abstract). In 17th ACM STOC, pages 291–304.
ACM Press, May 1985.
18. Harry A. Kalodner, Miles Carlsten, Paul Ellenbogen, Joseph Bonneau, and Arvind
Narayanan. An empirical study of namecoin and lessons for decentralized names-
pace design. In 14th Annual Workshop on the Economics of Information Security,
WEIS 2015, Delft, The Netherlands, 22-23 June, 2015, 2015.
19. Harry A. Kalodner, Steven Goldfeder, Xiaoqi Chen, S. Matthew Weinberg, and Ed-
ward W. Felten. Arbitrum: Scalable, private smart contracts. In William Enck and
Adrienne Porter Felt, editors, USENIX Security 2018, pages 1353–1370. USENIX
Association, August 2018.
20. Thomas Kerber, Markulf Kohlweiss, Aggelos Kiayias, and Vassilis Zikas.
Ouroboros crypsinous: Privacy-preserving proof-of-stake. In 2019 IEEE Sympo-
sium on Security and Privacy, 2019.
21. Aggelos Kiayias, Hong-Sheng Zhou, and Vassilis Zikas. Fair and robust multi-party
computation using a global transaction ledger. In Marc Fischlin and Jean-Sébastien
Coron, editors, EUROCRYPT 2016, Part II, volume 9666 of LNCS, pages 705–734.
Springer, Heidelberg, May 2016.
22. Ahmed E. Kosba, Andrew Miller, Elaine Shi, Zikai Wen, and Charalampos Pa-
pamanthou. Hawk: The blockchain model of cryptography and privacy-preserving
smart contracts. In 2016 IEEE Symposium on Security and Privacy, pages 839–858.
IEEE Computer Society Press, May 2016.
23. Kevin Liao, Matthew A. Hammer, and Andrew Miller. Ilc: A calculus for compos-
able, computational cryptography. Cryptology ePrint Archive, Report 2019/402,
2019. https://eprint.iacr.org/2019/402.
24. Mary Maller, Sean Bowe, Markulf Kohlweiss, and Sarah Meiklejohn. Sonic: Zero-
knowledge snarks from linear-size universal and updateable structured reference
strings. Cryptology ePrint Archive, Report 2019/099, 2019. https://eprint.
iacr.org/2019/099.
25. Satoshi Nakamoto. Bitcoin: A peer-to-peer electronic cash system. 2008.
26. Fred B. Schneider. Implementing fault-tolerant services using the state machine
approach: A tutorial. ACM Comput. Surv., 22(4):299–319, 1990.
27. Nick Szabo. Formalizing and securing relationships on public networks. First
Monday, 2(9), 1997.
28. Fabian Vogelsteller and Vitalik Buterin. ERC-20 token standard. https://github.
com/ethereum/EIPs/blob/master/EIPS/eip-20.md, 2015.
29. Jonathan Warren. Bitmessage: A peer-to-peer message authentication and delivery
system. white paper (27 November 2012), https://bitmessage. org/bitmessage. pdf,
2012.
30. Jeffrey Wilcke. The Ethereum network is currently undergoing a DoS at-
tack. https://blog.ethereum.org/2016/09/22/ethereum-network-currently-
undergoing-dos-attack/, September 2016.
31. Gavin Wood. Ethereum: A secure decentralised generalised transaction ledger.
2014.
32. Guy Zyskind, Oz Nathan, and Alex Pentland. Enigma: Decentralized Computation
Platform with Guaranteed Privacy. arXiv e-prints, June 2015.
30
A UC Conventions
31
This above mechanism is not a great deviation from UC – it can easily be
implemented by having a functionality or protocol record locally the suspension,
and reject new queries from the suspended party until it receives an input of
a specified form. We simply omit this mechanism when writing our protocols.
Something similar is in fact necessary for our security, as parties could otherwise
easily shoot themselves in the foot by concurrently creating conflicting transac-
tions. Responsive environments [7] are a strictly stronger form of this idea.
We assume the existence of a set of all parties P, of which there is a subset of
honest parties H ⊆ P. We assume H 6= ∅. Correspondingly, the set of corrupted
parties is P \H. In this paper, static corruption is assumed, and all functionalities
are assumed to have knowledge of these sets.
As a slight note, we use a somewhat unconventional model of having multiple
functionalities interacting with each other in the ideal world. This is largely to
avoid monolithic functionality design, using composition as a software design
primitive, rather than a security one.
Notation. In terms of notation, we will explicitly declare and initialize all state
variables of functionalities and protocols, to make formal statements about them
more precise. For the same reason, the behaviour of functionalities and proto-
cols is described via detailed pseudocode, instead of text. Most of the notation
is self-explanatory, however adversarial queries are not. As the adversary may
respond arbitrarily to queries, we include with each query a well-formedness
condition, and a fallback distribution. In particular, we write query A with x
and receive the reply y, satisfying P , else sampling from D to mean the
following: Send x to A, then wait for the response y. If P (y) does not hold,
instead randomly sample y from D. This allows us to ensure responses are well-
formed, while avoiding the common technique of aborting in the ideal world on
receiving unexpected input, something we try to avoid, as it effectively permits
denial-of-service in the “ideal” world. Finally, we use the period (“.”) as a mem-
bership access operator, to talk about variables of simulated functionalities, or
in the proof, to talk about state variables of various functionalities and protocol
instances. For instance, we write F.X to mean the state variable X within the
(possibly simulated) functionality F.
32
while the latter represents the empty set, empty map, and in the case of contract
states, the initial state (which the contract itself may ascribe a different format
to). Further, for a map M , we will write k ∈ M to mean that the map contains
the key k. A key is not in the map iff M (k) := ⊥. For lists, we use to denote
the empty list, and k to denote list concatenation. Single non-list items can be
interpreted as a singleton list.
We will use the following functions throughout the paper. prefix(L, x) returns
the longest prefix of L containing x, or L itself, if not such prefix exists. idx(L, x)
returns the index of the first occurrence of x in L, or ⊥ if x ∈ / L.
function prefix(L, x)
let L0 ←
for y ∈ L do
L0 ← L0 k y
if y = x then break
return L0
function idx(L, x)
let i ← 0
for y ∈ L do
if y = x then return i
let i ← i + 1
return ⊥
Finally, we write a ≺ b for the list prefix operation, where we assume reflex-
ivity.
B Ledger Functionalities
As smart contracts utilize an inderection layer of an underlying ledger, for com-
pleteness we will define the behaviour of this underlying ledger. The key char-
acteristics of the ledgers used here are that they maintain a sequence of trans-
actions, which any user may submit new transactions to, which may then even-
tually appear in this sequence. The sequence itself is public, and can be read by
anyone.
We note in particular that for the purposes of this paper, many common
features of ledgers are not required – in particular liveness is optional, although
the ideal-world guarantees for a ledger without liveness are naturally lessened.
Further, we do not specify a validation predicate, instead performing the valida-
tion in our definition of smart contracts. This is solely to have a clean separation
between the consensus system and the semantics of transactions – to prevent
denial-of-service attacks in a real system, this line would need to be blurred, and
transaction validation partially done in the consensus algorithm.
One feature typical ledger functionalities do not have, which we do explicitly
use here, is that of transactional privacy. Typically ledgers leak which party
created a new transaction, something we wish to avoid to strengthen the privacy
of our protocols. It is worth noting that this leakage is entirely network based,
and using a sender-anonymous network is sufficient to adapt “leaky” ledgers to
this more private variant.
33
Finally, readers may be surprised that the “private ledger” of [20] is not used.
This is largely for the same reason that validation predicates are avoided – the
separation of the ledger and transaction semantics is not possible in this private
ledger. While it would be possible to encode ideal smart contracts as specific
ledger blinding functions, this does not accurately model what we intend to
capture, and results in a large, monolithic, and hard-to-understand functionality
– decidedly not ideal.
The perfect ledger is a Platonic ideal form of a distributed ledger – it allows any
party to instantly append to its record, and allows any party to read the current
sequence of recorded transactions. This ledger is very similar to that used in [21],
however it is not realised by existing distributed ledger protocols – not least as
there is by necessity some network delay.
Functionality GperfectLedger
The perfect ledger is strictly more powerful than actual ledger implementations.
Variable Description
Σ := Authoritative ledger state
The simplified ledger captures the essence of the traditional persistence property
of ledgers, although it does not capture liveness. Any user may post transactions,
which are deemed unconfirmed. The adversary may decide when and which
unconfirmed transactions to move to an append-only ledger, and may decide
how long a prefix of this ledger honest parties see – provided it does not remove
anything previously revealed to them.
While the liveness property is not captured by this ledger, due to the large
amount of adversarial control, it is straightforward to see – although we will
not demonstrate it here – that more complex ledgers, such as those defined in
[2,1], UC-emulate GsimpleLedger . In particular, this means that if replaced in the
ideal world with such a ledger, which does have the liveness property, we also in
practice have liveness for our protocol. We discuss the issue of liveness more in
Appendix F.
34
Functionality GsimpleLedger
The simplified interface to Gledger is strictly less powerful than actual ledger im-
plementations, allowing reasoning about a less complex ledger functionality.
Variable Description
Σ := Authoritative ledger state
M := λp. Mapping of parties to ledger states
Variable Description
T := ∅ Mapping from transactions to their executing components.
Up := Sequence of unconfirmed transactions, for all parties p
35
return rejected
send (leak, desc) to p and receive the reply b
if b then
query A with (transaction, lkg, D) and receive the reply (τ, a),
satisfying T (τ ) = ⊥ ∧ τ 6= ⊥, else sampling from ({0, 1}κ , ⊥)
let T (τ ) ← (p, w, z, a, D); Up ← Up k τ
send (submit, τ ) to Gledger on behalf of p
return (posted, τ )
else
return rejected
When receiving a message (check-query, τ ) from an honest party p:
let Σp ← updateState(p)
if τ ∈ Σp then
if T (τ ) = (p, . . .) then return execResult(prefix(Σp , τ ))
else return ⊥
else return not-found
Helper procedures:
procedure updateState(p)
send read to Gledger through p and receive the reply Σp
let C ← execConfirmed(Σp )
let Up0 ← Up
repeat
let Up ← Up0
for τ ∈ Up do
let (. . . , D) ← T (τ )
if D * (C ∪ Up ) ∨ (D ∩ C) 6v Σp then let Up0 ← Up0 \ {τ }
until Up = Up0
return Σp
procedure execState(Σ) = let (σ, ·, ·) ← exec(Σ) in return σ
procedure execResult(Σ) = let (·, y, ·) ← exec(Σ) in return y
procedure execConfirmed(Σ) = let (·, ·, C) ← exec(Σ) in return C
procedure exec(Σ)
let σ ← ∅; y ← ⊥; C ← ∅
for τ ∈ Σ do
if τ ∈ C then continue
if T (τ ) = ⊥ then
query A with (input, τ ) and receive the reply x = (p, w, z, a, D),
satisfying p ∈ / H, else sampling from {none}
if T (τ ) = ⊥ then
let T (τ ) ← x
y←⊥
if T (τ ) = none then continue
let (p, w, z, a, D) ← T (τ )
if D \ C 6= ∅ ∨ D 6v Σ then continue
let (σ 0 , y) ← ∆(σ, p, w, z, a)
36
if σ 0 6= ⊥ then let σ ← σ 0 ; C ← C ∪ {τ }
return (σ, y, C)
C.2 Kachina
Transition Function ∆Kachina
Helper procedures:
function run-Γ(σ, ρ, w, z, h)
Oσ ← U (σ, ∅); Oρ ← U (ρ, z)
if ¬h then let Oρ ← z
y ← ΓOσ ,Oρ (w)
(σ, Tσ ) ← state(Oσ ); (ρ, Tρ ) ← state(Oρ )
return (σ, Tσ , ρ, Tρ , y)
The Kachina leakage function reveals the public state transcript generated by
Γ during the projected transition. This projected transition takes the state of the
contract as the party currently sees it, and first replays all currently unconfirmed
transactions from the same party. Both the initial (latest confirmed) contract
state, as well as the projected state, and a randomness stream are considered the
transaction’s context.
37
let (σ, Tσ , ρ, Tρ , ·) ← run-Γ(σ π , ρπ , w, z, >)
if σ = ⊥ ∨ ρ = ⊥ then
return (⊥, ⊥, ⊥, ⊥, ⊥)
else
let D ← dep(X, Tρ , z)
return (desc(t, X, Tσ , Tρ , w, z), Tσ , D, (Tσ , z))
Protocol Kachina
The Kachina protocol realises the ideal smart contract functionality when pa-
rameterised by a transition function Γ, a leakage descriptor desc, and a depen-
dency function dep, such that the corresponding (∆, Λ) pair is in CKachina . It
L
operates in the (Fnizk , GsimpleLedger )-hybrid model, where L is defined below.
((Tσ , ·), (w, Tρ )) ∈ L if and only if, where Oσ ← O(Tσ ), and Oρ ← O(Tρ ),
ΓOσ ,Oρ (w) 6= ⊥, and after it is run, consumed(Oσ ) ∧ consumed(Oρ ) holds.
Variable Description
T := ∅ Mapping from transactions to their private state transcripts
and contexts.
Y := ∅ Mapping from transactions to their outputs.
U := Sequence of unconfirmed transactions.
38
When receiving a message (check-query, τ ) from a party p:
let Σ ← updateState()
if τ ∈ Σ then return execResult(prefix(Σ, τ ))
else return not-found
Helper procedures:
procedure updateState(p)
send read to GsimpleLedger and receive the reply Σ
let C ← execConfirmed(Σ)
let U 0 ← U
repeat
let U ← U 0
for τ = (·, D, ·) ∈ U do
if D * (C ∪ U ) ∨ (D ∩ C) 6v Σ then let U 0 ← U 0 \ {τ }
until U = U 0
return Σ
procedure execState(Σ) = let (σ, ·, ·) ← exec(Σ) in return σ
procedure execResult(Σ) = let (·, y, ·) ← exec(Σ) in return y
procedure execConfirmed(Σ) = let (·, ·, C) ← exec(Σ) in return C
procedure exec(Σ)
let σ ← ∅; ρ ← ∅; y ← ⊥; C ← ∅
for τ = (Tσ , D, π) ∈ Σ do
if τ ∈ C then continue
let y ← ⊥
L
send (verify, (Tσ , D), π) to Fnizk and receive the reply b
if ¬b then continue
if D \ C 6= ∅ ∨ D 6v Σ then continue
if Tσ (σ) 6= ⊥ then
let σ ← Tσ (σ); C ← C ∪ {τ }
if T (τ ) 6= ⊥ then
let (T , z) ← T (τ )
let ρ ← T (ρ, z)
let y ← Y (τ )
return ((σ, ρ), y, C)
The state transition function for a private payments system. Parties have asso-
ciated public keys, and balances. The payments system allows for parties with-
out a public key to generate one, and for parties to transfer and mint single-
denomination coins, as well as query their own balance.
39
Variable Description
K := ∅ Mapping of parties to public keys
B := λp : 0 Mapping of parties to their spendable coins
Each operation on ∆pp has minimal leakage, revealing only which operation was
performed, and in the case of a transfer, the time and the recipient – if and only
if the recipient is corrupted.
40
else if ∃pk : w = (send, pk) then
R
let c ←− {0, 1}κ
if σ.B(σ.K(p)) − B − > 0 ∧ σ.K(p) = σ π (p) 6= ⊥ then
let lkg ← t
if @p0 ∈ H : pk = σ.K(p0 ) then let lkg ← (t, pk)
return ((send, t, pk) , lkg, , ∅)
else return (⊥, ⊥, ⊥, ⊥)
else if w = mint ∧ σ.K(p) 6= ⊥ then
return (mint, mint, , σ.K(p))
else if w = balance ∧ σ.K(p) 6= ⊥ then
return (balance, balance, , σ.B(σ.K(p)) − B − )
else
return (⊥, ⊥, ⊥, ⊥)
The state transition function for a Zerocash-based token contract. In green are
parts run in the public state oracle, in red are parts run in the private state oracle.
Variable Description
cms := ∅ Public coin commitment set
sns := ∅ Public serial number set
~ :=
R Vector of commitment Merkle tree roots
~
M := Vector of encrypted messages
Variable Description
i := 0 Index of M~ processed.
C~ := Vector of coins available.
Ke := ⊥ Encryption secret key.
Kz := ⊥ Zero-knowledge secret key.
41
send (mint, cm) to Oσ
return >
When receiving an input mint:
send mint to Oρ and receive the reply cm
send (mint, cm) to Oσ
return >
When receiving an input balance:
send balance to Oρ and receive the reply B
return B
42
let σ.M~ ← σ.M~ kM
When receiving an public oracle query (mint, cm):
let σ.cms ← σ.cms ∪ {cm}
~ ← σ.R
let σ.R ~ k merkleroot(σ.cms)
Helper procedures:
function update(ρ, σ)
let N~ ← σ.M ~ [ρ.i:]; ρ.i ← max(ρ.i, |σ.M ~ |)
for M ∈ N ~ do
if ∃r, p : (r, p) = dec(M, ρ.Ke ) then
if commr ((prf pk ρ.Kz (1), p) ∈
/ σ.cms then continue
if prf sn
ρ.Kz (p) ∈ σ.sns then continue
Simulator Szc
Variable Description
B := ∅ Unspent adversarial coins.
K := ∅ Honest public/private key pairs.
T := ∅ Mapping of transactions to created coin commitments.
∆ ,Λ
When receiving a message (transaction, x, D) from Fsc pp pp :
if x = init then
let Tσ ←
query A with (transaction, Tσ , D) and receive the reply (τ, ·),
satisfying T (τ ) = ⊥ ∧ τ 6= ⊥, else sampling from ({0, 1}κ , ⊥)
let (Ke , pke ) ← keyGen(1κ )
R
let Kz ← − {0, 1}κ
let pkz ← prf pk
Kz (1)
let K ← K ∪ {((Kz , Ke ), (pkz , pke ))}
let T (τ ) ← ∅
return (τ, (pkz , pke ))
else if x = (send, t, (pkz , pke )) then
R R
− {0, 1}κ ; r ←
let p ← − {0, 1}κ
R κ κ
let sn ←− prf sn
{0,1}κ ({0, 1} × {0, 1} )
let rt ← root(t)
let cm ← commr (pkz , p)
let B ← B ∪ {(pkz , pke , cm)}
let M ← enc((r, p), pke )
let Tσ ← ((spend, sn, rt) , ∅) k ((msg, M ) , ∅) k ((mint, cm) , ∅)
43
query A with (transaction, Tσ , D) and receive the reply (τ, ·),
satisfying T (τ ) = ⊥ ∧ τ 6= ⊥, else sampling from ({0, 1}κ , ⊥)
let T (τ ) ← {cm}
return (τ, ∅)
else if x = (send, t) then
R
− keyGen(1κ )
let (·, pk) ←
let rt ← root(t)
R κ
− comm{0,1}κ (prf pk
let cm ← {0,1}κ (1), {0, 1} )
R κ κ
− prf sn
let sn ← {0,1}κ ({0, 1} × {0, 1} )
R
let M ← − enc(({0, 1}κ , {0, 1}κ ), pk)
let Tσ ← ((spend, sn, rt) , ∅) k ((msg, M ) , ∅) k ((mint, cm) , ∅)
query A with (transaction, Tσ , D) and receive the reply (τ, ·),
satisfying T (τ ) = ⊥ ∧ τ 6= ⊥, else sampling from ({0, 1}κ , ⊥)
let T (τ ) ← {cm}
return (τ, ∅)
else if x = mint then
R κ
let cm ← − comm{0,1}κ (prf pk
{0,1}κ (1), {0, 1} )
let Tσ ← ((mint, cm) , ∅)
query A with (transaction, Tσ , D) and receive the reply (τ, ·),
satisfying T (τ ) = ⊥ ∧ τ 6= ⊥, else sampling from ({0, 1}κ , ⊥)
let T (τ ) ← {cm}
return (τ, ∅)
else if x = balance then
let Tσ ←
query A with (transaction, Tσ , D) and receive the reply (τ, ·),
satisfying T (τ ) = ⊥ ∧ τ 6= ⊥, else sampling from ({0, 1}κ , ⊥)
return (τ, ∅)
else abort
return (τ, a0 )
∆ ,Λ
When receiving a message (input, τ ) from Fsc pp pp :
send (input, τ ) to A and receive the reply (p, w, (Tσ , Oρ ), ·, D)
if T (τ ) 6= ⊥ then return none
let T (τ ) ← ∅
if w = (send, (pkz , ·)) then
if Tσ = ((spend, sn, rt) , ∅) k ((msg, M ) , ∅) k ((mint, cm0 ) , ∅) then
send (send, pke ) to Oρ and
receive the reply (p, r, Kz , p0 , r0 , rt0 , path, M 0 )
let cm ← commr ((prf pk Kz , p))
let b ← >
send read to Gledger and receive the reply Σ
if @t : 0 ≤ t ≤ |Σ| ∧ rt = root(t) ∧ ∃τ : (T (τ ) = cm ∧ τ ∈ Σ[:t]) then
let b ← ⊥
0 0
if sn 6= prf sn
Kz ((p, r)) ∨ rt 6= rt ∨ M 6= M then let b ← ⊥
if cm0 6= commr0 (pkz , p0 ) then let b ← ⊥
if ¬b then return none
44
// We now know the transaction is valid.
// We must determine if M can be honestly decrypted,
// and which adversarial coin is being spent.
if ∃((·, Ke ), (pkz , pke )) ∈ K then
let d = dec(M, Ke )
if d = (r0 , p0 ) then
let w ← (send, (pkz , pke ))
else
let w ← (send, (simkey, ⊥))
else
let B ← B ∪ {(simkey, ⊥, cm0 )}
let w ← (send, (simkey, ⊥))
if ∃(pk0z , pk0e , cm) ∈ B : pk0z = prf pk
Kz then
let a ← (pk0z , pk0e )
else abort
let T (τ ) ← {cm0 }
let z ← ∅
else return none
else if w = mint ∧ Tσ = ((mint, cm) , ∅) then
let B ← B ∪ {(simkey, ⊥, cm)}
let T (τ ) ← {cm0 }
let z ← (simkey, ⊥); a ← ∅
else return none
return (p, w, z, a, D)
Helper procedures:
procedure root(t)
let cms ← ∅
send read to Gledger and receive the reply Σ
for τ ∈ Σ[:t] do
let cms ← cms ∪ T (τ )
return merkleroot(cms)
D Security Analysis
Proof (of Theorem 1). If an environment can distinguish between the ideal and
real executions in presence of our simulator (see Subsection D.1), then there
must exist some polynomial sequence of interactions permitting it to distinguish
with a non-negligible advantage. Broadly, each of the environment’s actions fall
into one of three categories: a) Honestly interacting with the protocol. b) Hon-
estly interacting with the ledger. c) Commanding the adversary to perform some
action in the real world. We will consider the responses the environment makes
to queries given to the dummy adversary separately, in each case at the point
where the query is made.
We will consider in parallel two random variables of the state of the ideal
world execution, and that of the real world execution at any time. We leave out
45
of our analysis the “stack” of partial executions (as described in Appendix A),
except to show that the flow of each party – i.e. when it is waiting for which
query to be answered – is the same in both worlds. In particular, we note that
the state of the ideal world has the following functionalities’ states as a part of it:
1. the state of the simulator, S, 2. the state of the smart contract functionality,
∆,Λ
Fsc , and finally 4. the state of the ledger GLi . In the real world, for each p ∈ H,
p’s protocol state, which we refer to as φp , is part of the state, along with
L,r
the (shared) NIZK hybrid functionality Fnizk , and the real-world ledger GLr . For
convenience, we will often talk about these states as concrete variables, and not
random variables.
We will prove inductively that any action the environment takes will do two
things: First, it will preserve an invariant I, which holds after the state of both
worlds at any point during the two experiments. Second, if the invariant holds,
the environment gains at most negligible advantage in distinguishing from its
next action. To begin, we will specify the simulator, the invariant I, followed by
a few lemmas helpful in the proof. Finally, we will perform the induction itself.
The simulator for Kachina has fairly little work to do. It creates simulated
transactions by creating a simulated NIZK proof, and attaching it to the leakage
x. Secondly, when presented with an unknown transaction, and asked for the
corresponding input, it attempts to extract the input from the simulated zero-
knowledge functionality.
Simulator SKachina
The simulator SKachina has two main points of interaction in the ideal world:
First, it gets notified of the leakage of honest submissions, in the form of the new
public state σ 0 , and decides their format on the ledger. Second, it gets queried
when an adversarial transaction is seen on the ledger, and must assign meaning
L
to them. Furthermore, it simulates the non-global functionality Fnizk , which the
adversary may interact with.
46
L
simulate sending (verify, (Tσ , D), π) to Fnizk and receive the reply b
L
if b ∧ ∃w, Tρ : Fnizk .W ((Tσ , D), π) = (w, Tρ ) then
return (A, w, (Tσ , O(Tρ )), ∅, D)
else
return none
L
Forward all queries to Fnizk to the simulated instance. Forward all queries, to
global functionalities directly.
We define I as the conjunction of each of the constraints over the state variables
over the two executions listed below.
Fsc∆,Λ
.execConfirmed(Σ 0 k τ )
47
(10) All results and state updates are consistent with the input and transcripts:
∆,Λ
∀p ∈ H, Tσ , τ = (Tσ , ·, ·), w, z : Fsc .T (τ ) = (p, w, z, ∅, ·) =⇒ [∃Tρ :
φp .T (τ ) = (Tρ , z) ∧ φp .Y (τ ) = ΓO(Tσ ),O(Tρ ) (w) ∧ [∀σ, ρ : Tσ (σ) 6= ⊥ ∧
Tρ (ρ, z) 6= ⊥ =⇒ (Tσ (σ), ·, Tρ (ρ, z), ·, φp .Y (τ )) = run-Γ(σ, ρ, w, z, >)]]
(11) Execution results should be equivalent for prefixes and extensions of the
ledger state containing no new adversarial transactions:
∀Σ, p ∈ H : ((Σ ≺ GLr .Σ ∨ GLr .Σ ≺ Σ) ∧ ∀τ ∈ Σ : Fsc ∆,Λ
.T (τ ) 6= ⊥) =⇒
let ((σ , ρ ), y , C ) ← Fsc .exec(Σ); ((σ , ρ ), y , C ) ← φp .exec(Σ) in σ i =
i i i i ∆,Λ r r r r
Often many of these parts of the invariant are trivially preserved due to the
state variables constrained in them being left unchanged. Such trivial cases will
be omitted in our analysis.
Lemma 2 is the kernel of the proof of Kachina, but its formal statement is not
∆,Λ
particularly intuitive. The purpose is quite simple: Both Fsc and Kachina
have exec functions, which executes an entire ledger state given to it. Lemma 2
is a generalisation of invariant (11), and simply states that this execution will
preserve the invariant, and return the same values in the real and ideal world.
48
Proof. First, we consider the extend call. This will only extend if Σ is longer
than GL .Σ – otherwise it extends with , which is a no-op. This call preserves I,
as demonstrated in Subsection D.4.
We prove by induction over Σ. In the base case, Σ = . The invariant is
trivially preserved, and the returned values are equivalent (when ∅ is interpreted
as public/private state pairs). In the induction step, we proceed by case analysis
for the new transaction τ = (T , D, π):
∆,Λ
Case 1. The τ ∈ Fsc .T , and all processed transactions so far have been also
∆,Λ
been recorded (are in Fsc .T ). If so, then by (11), the return values are equiva-
lent. Further, this iteration does not change the state in the ideal world. By (4)
L,r L,r
and (7), we also know that the transaction is either in Fnizk .Π, or Fnizk .Π. As a
result, no state changes will be made in the real-world execution either, trivially
preserving I.
∆,Λ L,r
Case 2. τ ∈ / Fsc .T , but ((T , D), π) ∈ Fnizk .Π. In this case, the real world will
skip this transaction, and set y to ⊥. In the ideal world, the simulator will ensure
∆,Λ
that Fsc .T (τ ) is set to none, and equally this transaction is skipped, with y
set to ⊥. This affects and preserves the following invariants:
∆,Λ L,r
Case 3. τ ∈ / Fsc .T , but ((T , D), π) ∈ Fnizk .Π. In this case, by (15) a witness
must be recorded, and by (3) this witness must be accessible to the simulator. As
a result, the simulator will ensure that T (τ ) is set to (A, w, (Tσ , O(Tρ )), ∅, D). As
this is an adversarial transactions, the ρ-value of the adversary is not constrained,
and neither is the output y-value. As a result, to show the execution equivalence
holds, it suffices to show that both worlds will have the same σ-value after
this new transaction is the same in both worlds. In the real world, Tσ (σ) is
applied, or if this is ⊥, the transaction is skipped. In the ideal world, Tσ (σ)
is first tested to be ⊥, and if it is, the transaction is also skipped. Otherwise,
run-Γ(σ, ·, w, O(Tρ ), ⊥) is run. Since Tσ (σ) 6= ⊥, and ((Tσ , D), (Tρ , w)) ∈ L (by
(15)), we know that the public state oracle used in run-Γ can be replaced with
49
O(Tσ ), and that the call ΓO(Tσ ),O(Tρ ) (w) will terminate successfully. As a result,
the value σ returned in the ideal world is the same as Tσ (σ), that is returned in
∆,Λ
the real world. As Fsc .T is set, the following parts of the invariant are affected
and preserved:
(3) By the left hand side of the disjunction already being satisfied.
(4) By the transaction being recorded in the NIZK, and the simulator knowing
its witness.
∆,Λ
(5) As τ was not in Fsc .T in the induction hypothesis, and is not associated
with an honest party.
(6) By the newly recorded transaction satisfying the postcondition.
(7) By the newly recorded transaction not being recorded as rejected.
(9) By the newly recorded transaction not being honestly owned, not satisfying
the precondition.
∆,Λ
(10) As τ was not in Fsc .T in the induction hypothesis, it cannot be in any
φp .Y , by (5).
(11) By the output equivalence part of the induction step holding.
(12) By τ being previously unrecorded, further restricting the quantification do-
∆,Λ
main, and Fsc .T (τ ) = (A, . . .), not satisfying the precondition.
(16) By the newly recorded transaction being in the ledger state, as this has been
extended if necessary.
∆,Λ
Case 4. The transaction has not been previously seen – that is τ ∈ / Fsc .T ,
L,r L,r
and ((T , D), π) ∈/ Fnizk .Π ∪ Fnizk .Π. In this case, both the real and ideal worlds
will attempt the same NIZK verification (simulated in the ideal world). By (2),
they will both query the adversary for a NIZK witness in the same way, handing
off execution. By the induction hypothesis, I holds as the point of execution
transfer, and as the query made is the same in both worlds, the environment
gains no means to distinguish.
As NIZK verification is the first thing done in both worlds, and NIZK verifi-
cation is agnostic as to which party is verifying, this is equivalent to the environ-
ment first manually verifying the same statement/proof pair. As will be shown in
Subsection D.4, this preserves the invariant, and returns the same result in both
worlds. Therefore, Case 4 is equivalent to either Case 2 (if the NIZK verification
failed), or Case 3 (if the NIZK verification succeeded), as if the NIZK verifica-
tion is done externally beforehand, the statement/proof pair must be either in
L,r L,r
Fnizk .Π, or in Fnizk .Π.
∆,Λ
Case 5. τ ∈ Fsc .T , however (11) cannot be applied, as other transactions have
since been added. By (12), we know that τ belongs to an honest party p0 , and
that τ ∈ φp0 .U . We will use (8) to argue that, where (Tρ , z) = φp0 .T (τ ), either
Tρ (ρi [p0 ], z) 6= ⊥, or the transaction is skipped in both worlds.
First, we consider the possibility that τ ∈ / φp0 .U . By (9) we know that τ can-
not ever be confirmed by a suffix of the ledger state referred to in the invariant.
As this is a prefix of GLr .Σ, such that it contains no unrecorded transactions, the
current induction is necessarily a suffix of it. As a result, we know that the ideal
50
world execution will fail. As transactions are rejected in both worlds under the
same conditions – either dependencies are not satisfied, or Tσ (σ) = ⊥, we can
conclude that these transactions are also skipped in the real world, preserving I
as no state variables are changed, and satisfying all conditions by the induction
hypothesis. We will now focus on the case that τ ∈ φp0 .U
Next, we determine that, given τ ∈ φp0 .U , the longest prefix Σ ∗ referred to
in (8) is a prefix of the ledger state Σ we are currently performing induction
over. We know it to be a prefix of GL .M (p0 ), such that this prefix contains none
of the transactions in φp0 .U . As τ ∈ φp0 .U , and is either a prefix or extension of
GLr .Σ, of which GLr .M (p0 ) is itself a prefix by (13), we can conclude that Σ ∗ ≺ Σ.
As, to apply (8), we are only concerned with the parties private state ρ, we
can observe all transactions in Σ \ Σ ∗ are either not owned by p0 , will not be
accepted in any context, or are in φp0 .U . We can ignore the first possibility, as
the real world execution of them will not affect ρ, regardless. The second can
also be ignored, as these will be skipped by the ideal world execution, and by
induction hypothesis, by the real world execution as well. Next, we consider
which of the transaction in Σ \ Σ ∗ owned by p0 have been successfully processed.
exec provides replay protection, ensuring that each unconfirmed transaction has
been processed at most once. By induction hypothesis, the sequence A of such
transactions that are accepted, and therefore confirmed, is the same in both
worlds. By virtue of exec rejecting transactions which would set the state to
∗
⊥, we know that Tmap(φ (ρ∗ [p0 ]) 6= ⊥, where ρ∗ is taken to be the private
p0 .T,A)
state corresponding to the prefix Σ ∗ in the ideal world. As each transaction in
A got confirmed in order, we know that sat(map(X, A), φp0 .U ) holds, where X
is the function defined in (8), as this performs a more relaxed variant of the
confirmation check.
Now that τ is processed, we know by (8) that its dependencies are either in
confirmed, and in order, in Σ ∗ , or in φp0 .U . In either case, τ is skipped in both
worlds if it is a replayed transaction, or if would set Tσ (σ) = ⊥. In the ideal
world, additionally it gets skipped if it would set the contract state – either σ i
or ρi – to ⊥.
As τ ∈ φp0 .U , and is not a replay, B = A k τ is a permutation of a subset
∗
of φp0 .U . As a result, by (8), we know that Tmap(φ (ρ∗ [p0 ]) 6= ⊥. As we’ve
p0 .T,B)
previously established this holds for A, by definition of T ∗ , this implies that
Tρ (ρ[p0 ]i , z) 6= ⊥, where ρ[p0 ] is the same as the ideal world private state for
the induction hypothesis, by repeated application of (10). Likewise, (10) allows
us to conclude that σ i will also be non-⊥, as the update applied to it will be
equivalent to Tσ (σ i ), which by case analysis is not ⊥.
If the transaction is skipped in both worlds, the induction hypothesis still
applies. Otherwise, both Tσ (σ i ) 6= ⊥ and Tρ (ρi [p0 ], z) 6= ⊥. As previously noted
in Subsection 4.1, we can conclude that the updated states in the ideal world
are equal to σ i ← Tσ (σ i ) and ρi [p0 ] ← Tρ (ρi [p0 ], z). Likewise, (10) applies (as by
(5), φp0 .Y (τ ) is set), and we know the ideal-world result y i = φp0 .Y (τ ).
As in the real world σ r ← Tσ (σ r ), their equality is preserved. If p = p0 ,
by (5), φp .T is defined, and as a result, the same update is carried out to ρ
51
in the real world, as to ρi [p] in the ideal world. Further, it will return the
same result y r as the ideal world, as φp .Y (τ ) = y i . If p 6= p0 , the ideal world
update does not affect ρi [p], and the correctness of the returned private state
is guaranteed by the induction hypothesis. y r = ⊥ is returned, which satisfies
the requirements. Finally, in both cases, as the transaction is not skipped, it is
added to C, ensuring the returned C is the same in both worlds. Neither world
makes any state updates, trivially preserving I. u
t
∆,Λ
Lemma 3. If I holds, then for all p ∈ H, running updateState(p) in Fsc , and
running updateState in φp preserves I.
Proof. To begin with, both worlds retrieve the same value Σ / Σp from GL , due
to (1). As seen in Subsection D.4, this preserves I. Next, by Lemma 2, both
worlds receive the same value C, and the execConfirmed call preserves I. The
∆,Λ
worlds now iterate over φp .U and Fsc .Up respectively, which by (14) are equal
in value. The operations performed are almost identical, with the exception of
the real world deconstructing u = (·, D, ·) for each u ∈ U , while the ideal world
∆,Λ ∆,Λ
extracts (. . . , D) = Fsc .T (u) instead. By (6), if u ∈ Fsc .T , the two are
∆,Λ
equivalent, and by (5), as u ∈ φp .U , it is also in both φp .T , and Fsc .T . We
conclude that both worlds perform the same operations. Updated is only φp .U
∆,Λ
and Fsc .Up respectively. The following parts of the invariant are affected and
preserved:
52
hypothesis is that after k < 2κ interactions with any environment, the state of
both worlds satisfy the invariant I, and the environment has not gained a non-
negligible advantage in distinguishing. We will assume, without loss of generality,
the adversary being a dummy adversary. We provide a concrete list of actions
the environment may take before taking the induction step. We note that as at
any point the environment cannot distinguish, we can assume that it takes the
same action in both worlds without loss of generality.
Base Case.
Proof. Most base cases hold either due to equal initialization of variables con-
strained to be equal, or due to initialization leaving forall quantifiers to quantify
over the empty set. The former is the case for: (1), (2), (5), and (14). The latter
is the case for: (3), (4), (6), (7), (9), (10), (12), and (16). The remaining hold
for the following reasons:
(8) At initialisation, the only prefix of GLr .M (p) is . φp .execState() = (∅, ∅).
The base case therefore holds iff J(∅, ∅) holds. This in turn holds iff T∗ (∅) 6=
⊥, or ∅ 6= ⊥.
(11) At initialisation, the only ledger state Σ which satisfies the condition that
∆,Λ
∀τ ∈ Σ : Fsc .T (τ ) 6= ⊥ is . For this, as both world’s are initialised to
equivalent contract states, the outputs of exec will be equal.
(13) By the reflexivity of ≺. u
t
Induction Step.
∆,Λ
– ∀p ∈ H, w:4 Sending (post-query, w) to Fsc or Kachina.
∆,Λ
– ∀p ∈ H, τ : Sending (check-query, τ ) to Fsc or Kachina.
– ∀p ∈ P, τ : Sending (submit, τ ) to GL .
– ∀p ∈ P: Sending read to GL .
– ∀Σ 0 : Sending (extend, Σ 0 ) to GL .
– ∀p, Σ 0 : Sending (advance, p, Σ 0 ) to GL .
L
– ∀p ∈ P \ H: Sending (prove, x, w) to Fnizk .
5 L
– ∀p ∈ P: Sending (verify, x, π) to Fnizk .
We will prove that I is preserved across any of these queries, and that they
reveal the same information in both worlds.
4
We omit without loss of generality the environments ability to make honest queries
with corrupted parties. The environment may simulate running the honest protocol
to replicate these.
5
Technically, as in prove, the environment can only instruct corrupted parties to
verify. As verification for honest parties preserves the invariant as well, and is a
useful lemma, we prove the more general statement.
53
Case (post-query, w). We proceed by sub-case analysis. We identify the fol-
lowing cases: 1. The transaction is rejected by the contract. 2. The transaction
is rejected by the user. 3. The transaction is posted. In all cases, updateState is
first run. By Lemma 3, this preserves the invariant, and also ensures that the
returned value Σp = GL .M (p) is the value returned in both worlds (by (1)). In
the ideal world, Λ is called. The real world largely emulates the same, computing
most of the same values identically. Of note are the values σ o and ρo /ρo [p], which
are computed in both worlds using execState(Σp ). By Lemma 2, this preserves
the invariant, and returns the same values.
The only place where the two worlds diverge in their computation is in han-
dling the unconfirmed transactions – the ideal world executes run-Γ, and updates
σ π , ρπ , and X accordingly, while the real world applies Tσ and Tρ to the states.
Before we go into the main three cases, we will argue that, if the transaction
is not rejected by the contract, then these two approaches will yield the same
result, and that they will reject equally.
To begin with, the ideal world does also apply the public state transcript,
specifically to check that the result is non-⊥. If this is not satisfied, it immediately
results in the new query being rejected. Correspondingly, the real world will
actually apply this transcript, resulting in σ π = ⊥. As a ⊥ state will remain ⊥,
this will further in the execution result in the final public state σ also being ⊥,
and the real world execution rejecting this query.
Further, we observe that in the real world, the final value of ρπ cannot be
⊥ – to begin with, updateState guarantees that Σp ∩ φp .U = ∅. This in turn,
along with (8) ensures that J(X) holds, as well as that sat(X, U ) holds. It follows
T ∗ (ρo ) 6= ⊥, where T ∗ performs the same repeated applications of Tρ (ρ, z) as
the loop in the main protocol, using the same values. Further, by (3) and (4),
we can conclude that the transcripts Tρ , and contexts z are the same in both
worlds. By (10) , we can conclude that the final ρπ values are also the same in
both worlds. Further, as Tρ and z are equal in both worlds, and by (6) D is also
equal, the sequence X is also equal. Subsequently, σ, ρ, and D are computed
equivalently in both worlds.
We now consider the main case analysis: If the contract rejects the transaction
in the ideal world, the returned description is ⊥. This happens if and only if
σ = ⊥∨ρ = ⊥, the same condition as the real world protocol has for rejecting the
transaction before querying the user. If the transaction is rejected, no variables
are modified, preserving I, and the same value is returned in both worlds, giving
the environment no means to distinguish.
If the contract does not automatically reject the query, the leakage descrip-
tor is computed equally in both worlds, and sent to the party to acknowledge.
The party has the opportunity to accept the described leakage, or cancel the
transaction. At the point of handing over execution to the environment, no state
has been modified, trivially preserving I, and as the same leakage descriptor is
given, it has no means to distinguishing.
54
In the case of the environment subsequently cancelling the transaction, both
worlds immediately return with rejected, again trivially preserving I, and
giving no means to distinguish.
Finally, if the environment accepts the leakage, both worlds obtain the trans-
action identifier τ : The simulator ensures that the real-world adversary is queried
for the same NIZK proof as it is in the real-world, and that the transaction for-
mat matches that of real-world transactions. At the time of the proof query, no
state has been modified, trivially preserving I. As the same statement is queried
for, the environment gains no information to distinguish.
∆,Λ
Subsequently, both worlds record the transaction’s information (in Fsc .T
∆,Λ
and φp .T ), and note is as unconfirmed (in Fsc .U and φp .U ). In the real world,
the result is further recorded in φp .Y . The following parts of I are affected and
preserved (including the prove query):
55
execution equivalences, then induction from Lemma 2 can apply on that as a
base case (in particular, the precondition for Case 5 applies for all subsequent
transactions). The execution equivalence holds for this new base case, as we
know that this new transaction is both honest, and considered unconfirmed
for this party. Therefore, the argument for Case 5 holds for τ itself as well.
As the execution equivalence defined in Lemma 2 is the same as that of (11),
this part of the invariant is preserved.
(12) By the newly added transaction being unconfirmed, it satisfies any quantifi-
cation where τ is set to it. By now being recorded, the range of quantifications
for τ 0 is restricted, relaxing the condition.
(14) By equal update.
(16) By the newly recorded transaction being considered unconfirmed by an hon-
est party.
Finally, both worlds submit to the ledger the same transaction τ , which sim-
ply sent to the adversary. At this point I holds as argued above, and as the same
transaction is sent, the environment cannot distinguish. Finally, (posted, τ ) is
returned, giving the environment no information to distinguish for the same
reasons.
Case read. By (1), both worlds will return the same result; therefore the envi-
ronment cannot distinguish. As no state is changed, I is preserved.
56
(11) Extending GL .Σ further constrains the possible Σ values quantified over.
(12) Without loss of generality, we can assume single-transaction appends to
GLr .Σ. If a new unrecorded transaction is added, it (at first) does not pre-
ceed any transactions, leaving the quantification unchanged, and relaxing
the non-existance quantifier. If a recorded honest transaction is added, then
by (9) and (13), this transaction satisfies the conditions.
(13) By the append-only nature of extend.
(16) By relaxing the constraint.
Case (prove, x, w). In the ideal world, this query is handled by the simulated
L
functionality S.Fnizk . If (x, w) ∈
/ L the call returns immediately with ⊥ in both
worlds, and no variables are modified, giving the environment no information to
distinguish, and preserving I. Otherwise, the adversary is immediately queried
with (prove, x) in both worlds. Again, at this point no variables have been mod-
ified, preserving I, and the information handed to the adversary is the same in
both worlds, giving the environment no information to distinguish. The adver-
sary will eventually respond with a proof π, which is verified against constraints
in both worlds, and randomly sampled if it does not meet them. By (2), the con-
straints are identical in both worlds. Finally Π and W are set, and π returned
in both worlds, giving no distinguishing information to the environment. The
following parts of the invariant are affected and preserved:
57
(12) As in (9).
(15) As only members of L are recorded.
(16) As in (9).
Case (verify, x, π). The flow for verification is only slightly more complex than
that for proving. At a high level, the adversary may be given a chance to produce
a last-moment witness for the statement being verified. If it refuses to do so, the
proof is recorded as definitively invalid. We consider three sub-cases: 1. The
statement/proof pair is recorded as either valid or invalid. 2. The adversary
returns a valid witness. 3. The adversary does not return a valid witness.
In Case 1, verify returns the same value in both worlds by (2), giving
the environment no means to distinguish. Case 2 is equivalent to the adversary
first sending a prove query for the given statement, and supplying it with the
corresponding proof, and then running the verify query. We therefore refer to
Case 1, and the case of prove. In Cases 1 and 2, no state is changed, preserving I.
L,r
Finally, for Case 3, Fnizk .Π is updated equally in both worlds, and ⊥ is returned
in both worlds, giving the environment no information to distinguish. In this
case, the following parts of the invariant are affected and preserved:
Proof (sketch of Theorem 2). To begin with, observe that from the collision resis-
κ
tance of PRFs, commitments, and sampling from {0, 1} , all coin commitments,
serial numbers, and public keys will be unique with overwhelming probability.
The environment can perform the following primary actions: a) For any hon-
est party, run (post-query, w). b) For any honest party, run (check-query, τ ).
c) For any party, run (submit, τ ) against GL . d) For any party, run read against
GL . e) Run (advance, p, Σ 0 ) against GL , and e) for any party, run (extend, Σ 0 )
against GL .
58
All but the first two of these are trivial. The simulator forwards all queries
to GL , and the state of GL depends on no other functionality (transactions “sub-
mitted” in the ideal functionality are only passed to the adversary). As a direct
result, the state and return value of GL follow the same distribution in both
worlds, giving the environment no means to distinguish.
During the running of check-query the environment does have a signifi-
cant additional means of input, in the form of being able to assign meaning to
adversarial transactions as they get executed for the first time. It is sufficient to
show the following: a) From the ideal-world leakage, the simulator can create
indistinguishable real-world leakage. b) Ideal-world transactions have the same
leakage descriptions sent to the environment (and are rejected under the same
conditions). c) An invariant holds between the ideal and real-world contract
state, such that it is preserved across both honest and adversarial transactions’
transition function executions.
We omit the full detail of this invariant. To sketch the idea behind it, we
must prove that the following are preserved: The public keys recorded in the
ideal contract state, and the simulator must correspond directly to secret keys
recorded in the real contract state, and the same public keys returned by the real
contract. Further, the coins held by honest parties in the real contract should be
valid at any time, and correspond directly to the balance of the same party in
the ideal contract. Honest unconfirmed transactions in both the real and ideal
contracts should still be valid when they are finally executed (also implying they
do not conflict with each other).
These are preserved across honest init calls, as the simulator ensures the keys
it stores, and the public keys returned in the ideal contract, are generated in the
same way as in the real contract. They are preserved across honest send calls,
as they remove one commitment from an honest party’s coins, and potentially
add it to the respective recipient party. Further, the leakage functions of honest
sends in the real contract ensures the same coin cannot be spend again. They
are preserved across honest mints, as again the balance is incremented alongside
a new coin being recorded. For adversarial transactions, as the simulator has all
honest private keys, it can, and does, check if an honest party would register
receiving a new coin. If a coin is sent, but no honest party receives it, the simu-
lator records it as adversarial – even if it may not be spendable by the real-world
adversary. Further, the simulator manages which real-world coin commitments
are associated with which adversarial public key in the ideal world. This ensures
it can always spend a corresponding ideal coin to whatever was spent in the real
world (assuming the real world adversary doesn’t spend a coin he doesn’t own,
violating the one-wayness of the PRF).
Transactions remaining valid in the ideal world is guaranteed by ensuring the
balance of a party cannot fall below zero – by assuming the worst case of only
balance removing transactions becoming confirmed. Likewise, in the real world,
the coins eligible for spending are those received in confirmed transactions, but
not spent in unconfirmed ones, ensuring they will not conflict. In both cases, key
59
generation will be refused if one is currently unconfirmed. mint and balance
queries both only require initialisation to have taken place in either world.
To observe that the simulator creates indistinguishable leakage, we first note
that the leakage for real-world init transactions is an empty transcript, which
the simulator indeed recreates. For send transactions, the simulator creates a
public state transcript following the same structure of one in the real contract
execution – spending a coin, creating a new one, and sending a message. Here
there are two cases: either the recipient is adversarial, or it is honest. In the
case of an honest recipient, the simulator does not know the exact public key of
the recipient. Fortunately, however, the environment does not know their secret
keys for the same reason. As a result, it is sufficient to commit to an arbitrary
coin, and encrypt arbitrary secrets. Due to the hiding of the commitments, and
the key-privacy of the encryption scheme, the environment cannot distinguish
this from a real transaction. The simulator creates a random serial number –
revealing nothing due to collision resistance, and from the leakage of the length
of the ledger, can reconstruct the corresponding Merkle tree root, revealing the
same root as the corresponding real-world transaction.
If the adversary is the recipient, the simulator is given the actual public keys
– and can use these directly as in the real protocol, creating a valid spendable
commitment, and a message the adversary can decrypt. Minting is similar to
the case of sending to an honest party – except no message is encrypted. For
the same reason, the leakage is indistinguishable. Finally, honest balance queries
have no leakage in the real world.
For honest parties, the leakage descriptor the environment is asked to sign off
on is identical – for init, mint, and balance consisting of just this string, and
for send, it is (send, t, pk), where pk is the recipient, if it is adversarial, and oth-
erwise is omitted. In each case, assertions made about the current and projected
states are satisfied in either both worlds, or neither, ensuring the transaction is
rejected or posted equally in both worlds. Specifically, all have tests for whether
keys are initialised (asserting negatively in init, and positively everywhere else).
During spending, a positive spendable balance is also asserted in both worlds.
These holding simultaneously is guaranteed by the invariant holding.
Finally, the transaction outputs the environment receives are the same in
both worlds: For init, the simulator ensures it sees equally distributed public
keys. For balance, the equal distribution is guaranteed by the invariant. For
all other messages, it will only see if they are in the ledger state – as the honest
transactions cannot fail, and return nothing. u
t
60
F.1 The δ-delay Ledger
While the simplified ledger GsimpleLedger is nice for the analysis of protocols build-
ing on it as a global functionality, in practice users would like to take advantage
δ
of some liveness guarantees. We present a ledger GdelayLedger , which annotates
transactions with a time at which they were received. This time is never re-
turned to parties, however it asserts that every party can see a transaction, once
it is δ time slots in the past. This ledger operates under the assumption of a
global clock Gclock , which is also presented here. We posit without proof that
δ
GdelayLedger UC-emulates GsimpleLedger , by virtue of the latter having far greater
adversarial power.
δ
Functionality GdelayLedger
The δ-delay ledger adds liveness guarantees to GsimpleLedger , ensuring that suffi-
ciently old transactions are always visible to honest parties.
Variable Description
Σ := Authoritative ledger state
M := λp. Mapping of parties to ledger states
U := ∅ Multiset of unconfirmed transactions
Helper procedures:
procedure liveness
send read to Gclock and receive the reply t
if ∃(τ, t0 ) ∈ U : |t − t0 | > δ then return ⊥
else if ∃(τ, t0 ) ∈ Σ : |t − t0 | > δ ∧ ∃p ∈ H : (τ, t0 ) ∈
/ M (p) then return ⊥
else return >
61
Functionality Gclock
The global clock allows parties to agree on some discrete notion of time.
Variable Description
t := 0 Current time
T := ∅ Timekeepers
A := ∅ Agreements to advance
It is of note that since the ledger exists in both the ideal and real world, we would
ideally wish to be able to utilise the stronger δ-delay ledger (and others) in the
ideal world as well. This is not trivial, however – the UC proof presented in this
paper holds for the simple ledger, and while the transitivity and composability of
UC proofs implies that the simple ledger can be replaced by the stronger ledger
in the real world, this is not the only goal.
In order to enable ideal-world replacement, we consider when UC replace-
ments are commutative. Specifically, consider we have four functionalities, A, B,
C, and D, such that: a) A and B both have C as a global functionality, b) A is
UC-emulated by B with the simulator SB , and c) C is UC-emulated by D with
the simulator SD . Observe that this is a generalisation of our situation, where
∆,Λ
A is Fsc , B is Kachina, C is GsimpleLedger , and D is some other ledger GL .
When can we conclude that A is still UC-emulated by B even if the global
functionality is replaced by D in both worlds? I.e. when can we perform the
inner UC-replacement first, and still be able to perform the outer one?
62
Proof. We will provide this proof largely visually. The environment has a num-
ber of actions it can perform in any given world, in tandem with the dummy
adversary. We will represent these as unconnected wires in a circuit represen-
tation of the different UC functionalities. Each wire is coloured in accordance
with its purpose; these colours serve only to differentiate the wires. We visualise
the preconditions of Theorem 3 in Figure 4 and Figure 5. This crucially includes
the precondition that SB forwards adversarial queries to C, which is represented
equivalently by these queries being made directly instead.
SB A C ≈ B C
SD C ≈ D
SB A D ≈ SB A C SD
63
From here, we can realise both the ideal-world functionalities, provided it is
in the correct order: We must first realise A, as it relies on the presence of C.
We can directly apply the equivalence of Figure 4, as can be seen in Figure 7.
SB A C SD ≈ B C SD
Finally, nothing stands in the way of realising C with D, using the equivalence
of Figure 5 again, this time in the more typical direction. As a result, we get in
Figure 8 the final step, leading us to the intended equivalence, and proving the
related UC-emulation statement.
B C SD ≈ B D
64
H Non-Atomic Executions
Smart contracts are typically closely linked with transactions made on the un-
derlying ledger, and indeed we explicitly make the same link in this paper. That
being said, there are numerous applications which do not rely on a single transac-
tion per interaction with a contract, from Hawk [22], which requires at least two
transactions per round of interaction, to state channels [13], which have many
of the same properties of smart contracts, but may (under optimal conditions)
not require transactions at all.
While the model of smart contracts presented in Section 3 technically ex-
cludes both of these, and a full treatment of both would require further work, it
is nonetheless worth considering how they can be – albeit imperfectly – embed-
ded in this model. First, let us consider contract queries which require multiple
on-chain interactions to “complete”. As an example from Hawk, consider Alice
posts a query to a Hawk-style contract. Naturally, this will not immediately re-
turn – even if Alice’s transaction has made it on-chain. Instead, the transaction
could return a “future object” – a concept often used in concurrent program-
ming design, essentially just being a reference ID, and a promise to associate
some data with it later. Both Alice and the manager party would have to reg-
ularly poll the contract – e.g. send a contract query poll every 10 minutes.
On the manager’s next poll query, he would update the Hawk private state,
and encrypt and post the result for Alice. Finally, when Alice next polls, she
would retrieve the result, and associate it with the previous “future object” as
an output. This sketches a protocol running on top of Kachina, which achieves
this style of interaction. It is worth noting that this requirement for end-users to
interact is also a limitation of the underlying model of universal composability:
The environment must manually instruct parties to resume, or messages to be
forwarded by the adversary.
In a similar vein, we can observe that some transactions need not be placed
on a ledger. In particular, if the shared, public state is not used, the transac-
tion is essentially “offchain”, and there is no need to publicly post it. Further,
if the public state is used for message passing (such as in the construction of
a Zerocash contract above), this part of the transaction need not be on-chain
– sending an out of band message is cheaper. Using the same UC-based ap-
proach described above, it would therefore be possible, for example, to first
define an ideal payment-channel contract, and prove that this is UC-emulated
by a contract implementing, for instance, Perun [12]. Finally, we can argue that
most transactions in this contract can be omitted from the ledger, as they are
just two-party channel interactions. This is a rather roundabout means of con-
structing off-chain communication, however it brings a crucial guarantee with it,
namely that it behaves the same under ledger reorderings as a purely on-chain
contract.
65
I Meta-Parties and Their Relation to Alternative Trust
Models
So far we have presented, and argued for, a model of smart contracts with clear
black-and-white privacy: Users have their own perfectly private local state, and
access to a perfectly public shared state. While we believe this to be the best
starting point for approaching the issue of privacy in smart contracts, reality is
not so simple: Often users have more complex relations with each other.
To consider this more carefully, we can consider that any piece of data in
a smart contract must have a set of owners O, who can interact with it. Fur-
thermore, in any real system, there are parties which can, together, decipher
the actual data itself, and break the privacy of it. Let us refer to the set of all
combinations of parties able to decipher the data as T. While not strictly nec-
essary, in general it is reasonable to assume that the owners are also the users
able to break privacy, that is T ⊆ 2O . While clearly there are many possible
combinations here, a few stand out as interesting, and we observe that they all
relate to some interpretation of privacy-preserving smart contracts:
In particular, this work only directly concerns itself with the first two of
these. It is clear, however that different problems call for different solutions, and
ideally a smart contract system would encode all of these trust systems, not just
one, or a few. Part of the reason for the choice of the first two is that they are
sufficient for constructing the rest, being the exteremes of the spectrum.
The case of Hawk, for instance, was already described above in Appendix H.
We will sketch how state channels might be modelled on top of Kachina, al-
though we stress that a full formal treatment of this, and other settings, will be
left for future work.
A state channel between two users can be interpreted as the two users con-
stituting a “metaparty” – a single entity consisting of multiple parties. This is
subject to some access control for when the constituent parties can act on behalf
of both – commonly requiring agreement from all constituent parties. If Alice
66
and Bob open a new state channel, this can be seen as creating a new combined
party of (Alice, Bob).
In Kachina, this party again has its own private state, and for state chan-
nels, this can track the most recent update of the channel. Updates are now
operations that only affect the private state of this combined party, and as ar-
gued in Appendix H can be left off the ledger entirely. Interestingly, the access
structure for closing channels, and reading the current state is more permissive
in most state or payment channels – requiring only one user to initiate it.
Given a state channel system, most of it can be implemented in a Kachina
smart contract. It is not new for state or payment channels to use smart con-
tracts, however this is typically only for the opening and closing of the channel.
We observe that in Kachina the update of the channel can also be modelled.
This approach of metaparties is useful, but not optimal. For instance, a con-
tract cannot interact with both Alice’s private state, and the state channel be-
tween Alice and Bob at the same time, as presented here. Further, how the
constituents of a metaparty reach consensus on whether an action is permitted
or not is unclear, and varies from case to case. We leave as future work giving
first-class treatment to data owned by multiple parties.
67
address the correct part of the state. To do some, new oracles Oσ0 and Oρ0 are
constructed, which rewrite queries made to them. Then, the requested transition
function is run with these oracles, instead of the original ones.
Variable Description
∀i ∈ Zn : σi := ∅ Public states for each sub-contract
Variable Description
∀i ∈ Zn : ρi := ∅ Private states for each sub-contract
Helper procedures:
function muxPubOracle(i, q, σ, ∅)
let σ 0 ← σ.σi
let (σ 0 , y) ← q(σ 0 , ∅)
if σ 0 = ⊥ then return (⊥, y)
else
let σ.σi ← σ 0
return (σ, y)
function muxPrivOracle(i, q, ρ, (σ o , ρo , σ π , ρπ , η))
let ρ0 ← ρ.ρi
let z 0 ← (σ o .σi , ρo .ρi , σ π .σi , ρπ .ρi , η)
let (ρ0 , y) ← q(ρ0 , z 0 )
if ρ0 = ⊥ then return (⊥, y)
else
let ρ.ρi ← ρ0
return (ρ, y)
68
return (σ o .σi , ρo .ρi , σ π .σi , ρπ .ρi , η)
function unmuxXmux (X, i)
let X 0 ←
for (u, T , z, D) ∈ X do
if ∃T 0 : unmuxPrivOracle(T ) = (i, T 0 ) then
let X 0 ← X 0 k (u, T 0 , unmuxZmux (z, i), D)
return X 0
function descmux (t, X, Tσ , Tρ , (i, w), z)
let (·, Tσ0 ) ← unmuxPubOracle(Tσ ); (·, Tρ0 ) ← unmuxPrivOracle(Tρ )
let X 0 ← unmuxXmux (X, i); z 0 ← unmuxZmux (z, i)
return “Calling sub-contract i: ”+desci (t, X 0 , Tσ0 , Tρ0 , w, z 0 )
function depmux (X, Tρ , z)
if Tρ = then return ∅
else
let (i, Tρ0 ) ← unmuxPrivOracle(Tρ )
let X 0 ← unmuxXmux (X, i); z 0 ← unmuxZmux (z, i)
return depi (X 0 , Tρ0 , z 0 )
Variable Description
Σ := ∅ Mapping from address pairs to public states
69
Variable Description
P := ∅ Mapping from address pairs to private states
Helper procedures:
function muxPubOracle(A, q, σ, ∅)
if A ∈ / σ.Σ then let σ.Σ(A) ← ∅
let σ 0 ← σ.Σ(A)
let (σ 0 , y) ← q(σ 0 , ∅)
if σ 0 = ⊥ then return (⊥, y)
else
let σ.Σ(A) ← σ 0
return (σ, y)
function muxPrivOracle(A, q, ρ, (σ o , ρo , σ π , ρπ , η))
let (ρ.P, σ o .Σ.ρo .P, σ π .Σ, ρπ .P ) ←
forceInitMaps((ρ.P, σ o .Σ, ρo .P, σ π .Σ, ρπ .P ), A, ∅)
let ρ0 ← ρ.P (A)
let z 0 ← (σ o .σi , ρo .ρi , σ π .σi , ρπ .ρi , η)
let (ρ0 , y) ← q(ρ0 , z 0 )
if ρ0 = ⊥ then return (⊥, y)
else
let ρ.P (A) ← ρ0
return (ρ, y)
70
else
let (A = (. . . , dep), Tρ0 ) ← unmuxPrivOracle(Tρ )
let (σ o .Σ.ρo .P, σ π .Σ, ρπ .P ) ←
forceInitMaps((σ o .Σ, ρo .P, σ π .Σ, ρπ .P ), A, ∅)
let z 0 ← (σ o .Σ(A), ρo .P (A), σ π .Σ(A), ρπ .P (A), η)
let X 0 ←
for (u, Tρ , (σ o , ρo , σ π , ρπ , η), D) ∈ X do
if ∃Tρ0 : unmuxPrivOracle(Tρ ) = (A, Tρ0 ) then
let (σ o .Σ.ρo .P, σ π .Σ, ρπ .P ) ←
forceInitMaps((σ o .Σ, ρo .P, σ π .Σ, ρπ .P ), A, ∅)
let X 0 ← X 0 k (u, Tρ0 , (σ o .σi , ρo .ρi , σ π .σi , ρπ .ρi , η), D)
return dep(X 0 , Tρ0 , z 0 )
Smart contract systems truly become interesting when contracts are allowed to
call each other. This is not a technically difficult operation: Contracts simply
need to have an additional exit and entry point to allow new queries to other
contracts to be made, and these queries to be responded to. Specifically, we
require contracts to either return (return, y), or (call, A, M ), with the latter
invoking a separate contract. we associate a special return value structure with
indicating a new contract address and input to call, and require contracts to
process a specific resume message.
As for the first time, it is possible for multiple separate contracts to get called,
we domain-separate the randomness source η.
function unxmuZloopmux ((σ o , ρo , σ π , ρπ , η), A)
let (σ o .Σ, ρo .P, σ π .Σ, ρπ .P ) ← forceInitMaps((σ o .Σ, ρo .P, σ π .Σ, ρπ .P ), A, ∅)
Let η 0 be a randomness source determinstically and collision-resistantally derived
from the pair (η, A).
return (σ o .Σ(A), ρo .P (A), σ π .Σ(A), ρπ .P (A), η 0 )
The multiplexing with registration and loopback transition function Γloopmux al-
lows addressing any pair of address and sub-transition function (A, Γ). These
sub-transition functions may, return values of either (call, A, M ), or (return, y).
In the former case, a different sub-transition function is invoked, and the value
it eventually returns is fed back into the original one, by re-invoking it with
(resume, y).
Variable Description
Σ := ∅ Mapping from address pairs to public states
71
Variable Description
P := ∅ Mapping from address pairs to private states
until ∃y 0 : y = (return, y 0 )
return y 0
Helper procedures:
function muxPubOracle(A, q, σ, ∅)
if A ∈ / σ.Σ then let σ.Σ(A) ← ∅
let σ 0 ← σ.Σ(A)
let (σ 0 , y) ← q(σ 0 , ∅)
if σ 0 = ⊥ then return (⊥, y)
else
let σ.Σ(A) ← σ 0
return (σ, y)
function muxPrivOracle(A, q, ρ, z)
let z 0 ← unmuxZloopmux (z, A)
if A ∈ / ρ.P then let ρ.P (A) ← ∅
let ρ0 ← ρ.P (A)
let (ρ0 , y) ← q(ρ0 , z 0 )
if ρ0 = ⊥ then return (⊥, y)
else
let ρ.P (A) ← ρ0
return (ρ, y)
72
in mind: As this cannot invoke other contracts, their old descriptor function can
be easily lifted to this setting, as seen in Subsection J.2 (a slight caveat is that
either the old descriptor needs to be capable of tolerating unconfirmed transac-
tion transcripts over multiple calls to the underlying function, or there should
exist a function which splits transcripts into these individual calls).
function liftDesc(A, desc)(t, X, Tσ , Tρ , w, z)
let Tσ0 ← map(proj2 ◦ unmuxOracle, Tσ )
let Tρ0 ← map(proj2 ◦ unmuxOracle, Tρ )
let X 0 ← unmuxXregmux (X, A); z 0 ← unmuxZregmux (z, A)
return desc(t, X 0 , Tσ0 , Tρ0 , w, z 0 )
function unmuxT(T , A)
return map(proj2 , filter(λ(A0 , ·) : A = A0 , map(unmuxOracle, T )))
function unmuxXloopmux (X, A)
let X 0 ←
for (u, T , z, D) ∈ X do
let T 0 ← unmuxT(T , A); z 0 ← unmuxZloopmux (z, A)
let X 0 ← X 0 k (u, T 0 , z 0 , D0 )
return X 0
function descloopmux (t, X, Tσ , Tρ , (A = (·, ·, desc, ·), w), z)
return “Calling sub-contract A: ”+desc(t, X, Tσ , Tρ , w, z)
function deploopmux (X, Tρ , z)
let S ← ∅
for (q, r) ∈ Tρ do
let (A, ·) ← unmuxOracle((q, r))
let S ← S ∪ {A}
let D ← ∅
for A = (·, ·, ·, dep) ∈ S do
let Tρ0 ← unmuxT(Tρ , A)
let z 0 ← unmuxZloopmux (z, A)
let X 0 ← unmuxXloopmux (X, A)
let D ← D ∪ dep(X 0 , Tρ0 , z 0 )
return map(proj1 , X) ∩ D
73
Transition Function Γsp
The state transition function for a simple payments system. Parties have associ-
ated public/private keys, and balances. The payments system allows for parties
without a key pair to generate one, and for parties to transfer and mint coins, as
well as query their own balance.
Variable Description
B := λpk : 0 Mapping of public keys to their spendable coins
Variable Description
sk := ∅ The party’s secret key
74
When receiving an public oracle query (send, pk, recv, v):
assert σ.B(pk) ≥ v
let σ.B(pk) ← σ.B(pk) − v
let σ.B(recv) ← σ.B(recv) + v
When receiving an public oracle query (mint, pk, v):
let σ.B(pk) ← σ.B(pk) + v
Variable Description
Σ := ∅ Mapping from address pairs to public states
Variable Description
P := ∅ Mapping from address pairs to private states
75
let pk ← Γpaymux,Oσ ,Oρ (token, (send, A, v))
return callOσ ,Oρ (v, pk, A, w)
Helper procedures:
function subCallOσ ,Oρ (v, A, A0 = (i, Γ, desc, dep), w)
assert A0 6= token
let Oσ0 ← λq : Oσ (muxPubOracle(token, q))
let Oρ0 ← λq : Oρ (muxPrivOracle(token, q))
run Γsp,Oσ0 ,Oρ0 (system-send, A, A0 , v)
return callOσ ,Oρ (v, A, A0 , w)
function callOσ ,Oρ (v, A, A0 = (·, Γ, ·, ·), w)
let Oσ0 ← λq : Oσ (muxPubOracle(A0 , q))
let Oρ0 ← λq : Oρ (muxPrivOracle(A0 , q))
repeat
let y ← ΓOσ0 ,Oρ0 (call, A, v, w)
if ∃v 0 , A00 , w0 : y = (call, v 0 , A00 , w0 ) then
let w ← resume, subCallOσ ,Oρ (v 0 , A0 , A00 , w0 )
until ∃y 0 : y = (return, y 0 )
return y 0
function muxPubOracle(A, q, σ, ∅)
if A ∈ / σ.Σ then let σ.Σ(A) ← ∅
let σ 0 ← σ.Σ(A)
let (σ 0 , y) ← q(σ 0 , ∅)
if σ 0 = ⊥ then return (⊥, y)
else
let σ.Σ(A) ← σ 0
return (σ, y)
function muxPrivOracle(A, q, ρ, (σ o , ρo , σ π , ρπ , η))
let (ρ.P, σ o .Σ.ρo .P, σ π .Σ, ρπ .P ) ←
forceInitMaps((ρ.P, σ o .Σ, ρo .P, σ π .Σ, ρπ .P ), A, ∅)
let ρ0 ← ρ.P (A)
let z 0 ← (σ o .σi , ρo .ρi , σ π .σi , ρπ .ρi , η)
let (ρ0 , y) ← q(ρ0 , z 0 )
if ρ0 = ⊥ then return (⊥, y)
else
let ρ.P (A) ← ρ0
return (ρ, y)
76
J.5 Fees and Cost Models
77
in the ledger iff the gas cost is sufficient, and the latter otherwise. We do not
construct these here, but observe that in a practical system the payment of fees
will require a special status to combat denial of service attacks.
Variable Description
Σ := ∅ Mapping from address pairs to public states
spare := 0 Temporary book-keeping of the value to return
Variable Description
P := ∅ Mapping from address pairs to private states
σ E := ∅ Temporary projected state for estimating gas costs
78
run Γsp (fee-pot, pk, σ.spare × gasPrice)
let σ.spare ← 0
Helper procedures:
function subCallOσ ,Oρ (v, A, A0 = (i, Γ, desc, dep), w)
assert A0 6= token
let Oσ0 ← λq : Oσ (muxPubOracle(token, q))
let Oρ0 ← λq : Oρ (muxPrivOracle(token, q))
run Γsp,Oσ0 ,Oρ0 (system-send, A, A0 , v)
let (c, y) ← callOσ ,Oρ (v, A, A0 , w)
return (c + csend , y)
function callOσ ,Oρ (v, A, A0 = (·, Γ, ·, ·), w)
let Oσ0 ← λq : Oσ (muxPubOracle(A0 , q))
let Oρ0 ← λq : Oρ (muxPrivOracle(A0 , q))
let c ← 0; e ← 0
repeat
let (c0 , y) ← $zk (Oσ0 , Oρ0 , Γ, (call, A, v, w))
let c ← c + c0
if ∃v 0 , A00 , w0 : y = (call, v 0 , A00 , w0 ) then
let (c0 , y) ← subCallOσ ,Oρ (v 0 , A0 , A00 , w0 )
let c ← c + c0 ; w ← (resume, y)
until ∃y 0 : y = (return, y 0 )
return (c, y 0 )
function muxPubOracle(A, q, σ, ∅)
if A ∈ / σ.Σ then let σ.Σ(A) ← ∅
let σ 0 ← σ.Σ(A)
let (σ 0 , y) ← q(σ 0 , ∅)
if σ 0 = ⊥ then return (⊥, y)
else
let σ.Σ(A) ← σ 0
return (σ, y)
function muxPrivOracle(A, q, ρ, (σ o , ρo , σ π , ρπ , η))
let (ρ.P, σ o .Σ.ρo .P, σ π .Σ, ρπ .P ) ←
forceInitMaps((ρ.P, σ o .Σ, ρo .P, σ π .Σ, ρπ .P ), A, ∅)
let ρ0 ← ρ.P (A)
let z 0 ← (σ o .σi , ρo .ρi , σ π .σi , ρπ .ρi , η)
let (ρ0 , y) ← q(ρ0 , z 0 )
if ρ0 = ⊥ then return (⊥, y)
else
let ρ.P (A) ← ρ0
return (ρ, y)
79
descscs = descpaymux
depscs = deppaymux
The chain data transition function Γchaindata allow arbitrary setting and reading
of state. An external assumption is that the setting of state is both enforced and
restricted by the underlying ledger protocol, to give it meaning – for instance
each block may induce a phantom “chain-data” transaction which appears on the
ledger, and sets the most recent block hash in the chain-data contracts state.
The contract we present here does have a further issue: Since the loopback
in our multiplexers occurs only in the main transition function, the transcripts
it generates will commit to specific values for the ledger data upon transaction
creation – something which is likely not reasonable. A more complex loopback
design, which we do not present here, would solve this: If calling into public
or private parts of other contracts were permitted from within the public and
private state oracles respectively.
For both leakage descriptors and dependencies, we make use of our assump-
tion that users cannot directly call set.
function descchaindata (t, X, Tσ , Tρ , w, z)
return “Reading the chain data”
function depchaindata (X, Tρ , (σ o , ρo , σ π , ρπ , η))
return
6
This could be expanded to allow only certain types of setting – such as advancing
the time, but not rewinding it.
80