4.4 The Perun Protocol
4.4.1 The Channel Smart Contract C
Let us start by constructing the ledger channel smart contract. In our protocol, this contract is modeled as an ideal functionality that is used by the parties inP.
In the UC framework, this ideal functionality is also called a hybrid functionality.
As discussed in Section 3.2, Ethereum smart contracts always need to be trig- gered by transactions in order to execute a function, receive or payout coins or store data. This means we need to anticipate this contract behavior in our proto- col. As a contract can also not send messages to parties directly to inform them of a particular behavior, we require honest parties to always watch the contract on the blockchain to see if it changed state after some function call.
Whenever we construct timeouts, we assume that an honest party will trigger the smart contract to ensure that the timeout is enforced. If a message is expected from a party, the functionality will inform the other channel participants once the message arrived. If the message did not arrive in time, other honest parties send a timeout message, that wakes up the functionality, which can verify that the timeout for the expected message expired. In most cases, the functionality will then be able to attribute the fault and punish the malicious party by assigning all funds that are concerned with this fault to the other channel party. Fault attribution and timeouts are presented in more detail in Section 3.2. In the functionalityC, we handle fault attribution in virtual channels in the subroutine (C). Otherwise, the contract consists of the following parts: (A) the subroutine used for constructing a given contract instance and (B) the main execution functionality of the contract. Thecontract functionality C maintains the set of activecontract instances. Each
contract instance has a unique identifier. We refer to a contract instance with
identifierid asC(id). In our case, each contract instance corresponds to one ledger
channel, and, for simplicity, has the same identifier. In other words, a contract instance C(β.id) corresponds to a ledger channel β. When a channel is closed,
then the corresponding contract instance terminates (i.e., it is removed from the set of contract instances of C). Contract instances can be easily implemented as a separate contracts or as a singleton contract storing C on the Ethereum ledger. For simplicity we consider a separate contract for each instance. A new contract instance C(β.id) is created when C receives a constructor message. We also say
this specific contract instance. One can also think about it in the following way: every message (other than the constructor message) that is sent to C contains the identifier id that specifies to which particular contract instance it is addressed,
and a similar rule applies to messages sent by C.
The contract C defines a transfer function transfers : β.end-users → R initially equal to 0 on both inputs. This function keeps track of the sum of the transfers between β.Alice and β.Bob that were communicated to the contract. In our case,
these transfers will come only from the closing of virtual channels. The contract also stores information about virtual channels (built on top ofβ) that were closed
via the contract. Technically, we say that some channel γ is marked as closed if it
is added to the list of such closed channels.
When both channel end-users are honest, the contract is executed only for the optimistic closing of the channel through a lc-close message to the contract (cf.
Subroutine (B) Step 4 and 4a). In particular, this means both parties only try to close the ledger channel after all virtual channels are closed. However, if at least one of the channel end parties is dishonest, the other party may initiate the closing of a virtual channel via the contract functionality. In this case, an honest party must be able to prove that the counter party agreed to open a virtual channel. For this purpose both end-users sign opening certificates (γ, σ) every time they open
a new virtual channel. This statement can later be sent to the contract to prove this fact. Similarly, parties exchange signed closing certificates when they agree to close a virtual channel. An opening certificate ocP (resp. closing certificate ccP)
for party P and channel γ look as following:
ocP :=(open γ with initial balance [A 7→xA;B 7→xB] and validity v) ccP :=(close γ with final balance [A 7→xA;B 7→xB] and validity v),
Where each such statement is accompanied by a signatureσP over the respective
statement by party P.
Additionally, the contract must be able to compare channel versions for both ledger and virtual channels. To this end, we use the following terminology to describe channel version tuples: Let w ∈N be a natural number called a version number, and α∈ {0,1}∗ be an update annotation (see Sect. 4.3). Then (
b
δ, w, α) is
calleda version ofδifδbis equal toδ on all attributes except ofδ.cash, and the sum
of the balances (the value) of δb is equal to the value of δ. Moreover, (δ, w, α, σb )
is called a signed version of δ if σ is a valid signature of P on (δ, w, αb ). If w = 0
then we call (δ, w, αb ) the initial version of δ, and we do not require a signature,
We define the winner selection procedure Win to determine which version of a
channel is newer. It was already implicitly defined forV’s and W’s in Section 4.3.
Formally it is defined as follows. Let δ be a ledger or virtual channel. Win takes
as input a pair ((δ0, w0, α0, σ0),(δ1, w1, α1, σ1)) of signed versions ofδ, and returns
as output a cash function θ : δ.end-users → R≥0 defined as follows: let i be such
that wi > w1−i (if no such i exists then choose i:= 0) and then letθ :=δi.cash. We are now ready to define the hybrid contract functionality C formally:
Hybrid Functionality C.
This functionality captures the behavior of a channel contract instance β.
(A) The contract for channel β opening
1) Upon receiving message (lc-open, β) from partyAwhereβ is a ledger
channel s.t. A = β.Alice, remove β.cash(A) coins from A’s account on the ledgerL and send message (lc-opening, β) to β.Bob and go to
step 2)
2) Wait at most ∆ rounds to receive a message (lc-open, β) from party
B =β.Bob.
2a) If this message was received, then remove β.cash(B) coins from B’s account on the ledgerL. Lettransfers:β.end-users →Rbe a transfer function for β which initially outputs 0 on both inputs;
Send a message (lc-opened) to β.end-usersand run subprocedure
(B) below.
2b) Otherwise, if no message from B was recorded addxA coins back
toA’s account in L and send message (lc-not-opened) to A.
(B) The contract C(id) execution
Assumption: for every channel δ ∈ {β, γ} each party P can send at most one message of a given type that concerns δ.
1. Upon receiving (vc-close-init, γ,ocP) from γ.Ingrid∈ β.end-users in
time at leastγ.validity+ 2 (whereocP is an opening certificate ofP :=
β.other-party(γ.Ingrid) on γ) and γ has not been marked as closed:
then send a message (vc-close-init, γ.id) to P and wait for one of the following messages:
a) Upon receiving (vc-already-closed, γ,ccP) from P, where ccP
is a closing certificate of γ.other-party(P) on γ: then mark γ as
b) Upon receiving m := (vc-close, γ, W,SignP(W)) from P (where
W is a version of γ signed by γ.other-party(P)): then send m to γ.Ingrid.
c) Upon receiving (vc-close-timeout, γ) from γ.Ingrid in time at
least ∆ after you sent the message (vc-close-init, γ.id): then go
to subroutine (C) below.
2. Upon receiving messagem := (vc-close-final, γ,ocP,(Vγ.Bob, Sγ.Alice),
(Vγ.Alice, Sγ.Bob)) from γ.Ingrid where ocP is an opening certificate of
P :=β.other-party(γ.Ingrid) on γ, each VP is a version of γ signed by
γ.other-party(P), andSP is a signature of P onW (or is equal to ⊥if
W is the initial version of γ), and γ has not been marked as closed:
then send message mtoP and wait for one of the following messages: a) Upon receiving (vc-already-closed, γ,ccP) fromP, whereccP is
a signed closing certificate onγ from γ.Ingriddo nothing.
b) Else upon receiving (vc-close-timeout, γ) from γ.Ingrid in time
∆ + 1 after you sent m to P: then go to subroutine (C) below. 3. Upon receiving (vc-close-timeout, γ,ccP) from P ∈ γ.end-users in
time at least γ.validity+ 4∆ + 5 where ocP is an opening certificate of
γ.Ingrid on γ and γ has not been marked as closed: send a message
(vc-closing, γ.id) toγ.Ingridand wait for one of the following messages:
a) Upon receiving (vc-already-closed, γ,ccP) from γ.Ingrid, where ccP is a closing certificate ofβ.other-party(P) on γ: then do noth-
ing.
b) (vc-close-timeout, γ) from P in time at least ∆ after you sent
the (vc-closing, γ.id) message to γ.Ingrid: then in this case go to
subroutine (C) below.
4. Upon receiving (lc-close, W) from P, where W = (γP, wP, ε, σ) is
a version of β signed by P0 = β.other-party(P): send a message
(lc-closing) to P0 and wait for one of the following to happen:
a) Upon receiving a rely of P0 with (lc-close, W0) where W0 is
a version of β signed by P0 = β.other-party(P): let balance :=
Win(W, W0) + transfers. For P ∈b β.end-users send balance(Pb)
coins to Pb’s account on the ledger together with a message
(lc-closed), and close the contract.
b) In time τ party P0 replies with a message (vc-active, z), where
z is an opening certificate of P on some channel γ constructed
c) Upon receiving (lc-close-timeout) from P in time ∆ after
you sent the (lc-closing) message to P0: then let balance :=
γP.cash+transfers. For P ∈b β.end-userssend balance(Pb) coins to b
P’s account on the ledger together with a message (lc-closed),
and close this contract instance.
(C) Subroutine for closing a virtual channel when cheating by
party P is detected
Let x:=γ.cash(γ.Alice) +γ.cash(γ.Bob). Remove xcoins from P’s account in transfer and add x coins to β.other-party(P)’s account in transfer. Mark
γ as closed. Send a message (vc-closed) to bothβ.end-users.
The assumption that for every channel δ each party P can send at most one message of a given type that concernsδ(see subroutine (B)), is a technical restric-
tion that simplifies the presentation. By message type, we mean the keyword that starts the message. It essentially means that, e.g., no party can ask to close the same channel twice.