1 Introduction

Smart contracts—computer protocols that regulate the exchange of assets in trustless environments—have become popular with the growth of interest in blockchain technologies. Mainstream blockchain platforms like Ethereum, Libra, and Cardano, feature expressive high-level languages for programming smart contracts. This flexibility has a drawback in that it may open the door to attacks that steal or tamper with the assets controlled by vulnerable contracts [4, 22].

An alternative approach, pursued first by Bitcoin and more recently also by Algorand, is to sacrifice the expressiveness of smart contracts to reduce the attack surface. For instance, Bitcoin has a minimal language for transaction redeem scripts, containing only a limited set of logic, arithmetic, and cryptographic operations. Despite the limited expressiveness of these scripts, it is possible to encode a variety of smart contracts (like gambling games, escrow services, crowdfunding systems, etc.) by suitably chaining transactions [1,2,3, 5, 8, 10, 13, 18,19,20,21, 23]. The common trait of these works is that they render contracts as cryptographic protocols, where participants can exchange/sign messages, read the blockchain, and append transactions. Verifying the correctness of these protocols is hard, since it requires to reason in a computational model, where participants can manipulate arbitrary bitstrings, only being constrained to use PPTIME algorithms.

Departing from this approach, BitML [11] allows to write Bitcoin contracts in a high-level, process-algebraic language. BitML features a compiler that translates contracts into sets of standard Bitcoin transactions, and a sound and complete verification technique of relevant trace properties [12]. The computational soundness of the compiler guarantees that the execution of the compiled contract is coherent with the semantics of the source BitML specification, even in the presence of adversaries. Although BitML can express many of the Bitcoin contracts presented in the literature, it is not “Bitcoin-complete”, i.e. there exist contracts that can be executed on Bitcoin, but are not expressible in BitML [6].

For instance, consider a zero-coupon bond [17], where an investor pays upfront to a bank , and receives back after a maturity date (say, year 2030). We can express this contract in BitML as follows. First, as a precondition to the stipulation of the contract, we require both and to provide a deposit: ’s deposit is , while ’s deposit is . In BitML, we write this precondition as:

where \(x_{1}\) and \(x_{2}\) are the identifiers of transactions containing the required amount of bitcoins (). Under this precondition, we can specify the zero-coupon bond contract as follows:

Upon stipulation, all the deposits required in the preconditions pass under the control of , and can no longer be spent by and . The contract splits these funds in two parts: , that can be withdrawn by at any moment, and , that can be withdrawn by after the maturity date.

Although correctly implements the functionality of zero-coupon bounds, it is quite impractical: for the whole period from the stipulation to the maturity date, are frozen within the contract, and cannot be used by the bank in any way. Although this is a desirable feature for the investor, since it guarantees that he will receive even if the bank fails, it is quite undesirable for the bank. In the real world, the bank would be free to use its own funds, together with those of investors, to make further financial transactions through which to repay the investments. The risk that the bank fails is mitigated by external mechanisms, like insurances or government intervention.

In this paper we propose an extension of BitML that overcomes this issue. The idea is to allow the contract participants to renegotiate it after stipulation, in a controlled way. Renegotiation makes it possible to inject in the contract new funds, that were not specified in the original precondition. We can use this feature to solve the issue with the contract. The new precondition is , i.e. we only require ’s deposit. The revised contract is:

As before, the bank can withdraw at any moment after stipulation. In the second part of the \(\texttt {split} \), the participants renegotiate the contract: if they both agree, pass under the control of the contract \({\texttt {X }_{}}\langle {}\rangle \). The precondition of \({\texttt {X }_{}}\langle {}\rangle \) requires the bank to provide in a fresh deposit; upon renegotiation, can withdraw after the maturity date. The crucial difference with is that the deposit variable \(d_{}\) is instantiated at renegotiation time, unlike \(x_{}\), which must be fixed at stipulation time.

The revised contract solves the problem of , in that it no longer freezes for the whole duration of the bond: the bank could choose to renegotiate the contract, paying , just before the maturity date. This flexibility comes at a cost, since loses the guarantee to eventually receive . To address this issue we need to add, as in the real world, an external mechanism. More specifically, we assume an insurance company that, for an annual premium of paid by the bank, covers a face amount of (with \(2> f > 10 p\)):

We revise the bond contract as follows:

The contract starts by transferring to the bank, and the first year of the premium to the insurer. The remaining are transferred to the renegotiated contract \({\texttt {X }_{}}\langle {1}\rangle \), or, if the renegotiation is not completed by 2021, to the investor.

We remark that the pattern , where requires some authorizations but does not, is rather common in BitML, as it ensures that the contract can proceed even if the authorizations are not provided. Indeed, in such case an honest participant is enough to execute after time t. By suitably exploiting this pattern, it is possible to guarantee that a BitML contract enjoys liveness, by just assuming that at least one participant is honest.

The contracts \({\texttt {X }_{}}\langle {n}\rangle \), for \(n \in 1..9\), allow the insurer to receive the annual premium until 2030: if the bank does not renegotiate the contract for the following year (paying the corresponding premium), then the investor can redeem the face amount of . Finally, the contract \({\texttt {X }_{}}\langle {10}\rangle \) can be triggered if the bank deposits the : when this happens, the face amount is given back to the insurer, and the investor can redeem after the maturity date.

Compared to , the contract offers more protection to the investor. To see why, we must evaluate ’s payoff for all the possible behaviours of the other participants. If and are both honest, then will redeem , as in the ideal contract . Instead, if either or do not accept to renegotiate some \({\texttt {X }_{}}\langle {n}\rangle \), then can redeem as a partial compensation (unlike in , where just loses ). In the real world, could use this compensation to cover the legal fee to sue the bank in court; also, could e.g. increase the premium for future interactions with . By further refining the contract, we could model these real-world mechanisms as oracles, which sanction dishonest participants according to the evidence collected in the blockchain and in messages broadcast by participants. For instance, if and accept the renegotiation \({\texttt {X }_{}}\langle {n}\rangle \) but does not, then the oracle would be able to detect ’s dishonesty by inspecting the authorizations broadcast in year \(2021+n\). The sanction could consist e.g. in blacklisting , so to prevent her from buying other bonds from .

Contributions. We summarise our main contributions as follows:

  • We extend BitML with the renegotiation primitive , suitably adapting the language syntax and semantics. The new primitive increases the expressiveness of BitML: besides allowing participants to provide new deposits and secrets at run-time, it also allows for unbounded recursion.

  • We extend the BitML compiler to the new primitive, making it possible to execute renegotiations on Bitcoin. We accordingly extend the computational soundness result in [11], guaranteeing that the BitML semantics is coherent with the actual Bitcoin executions, also in the presence of adversaries.

  • We exploit renegotiation to design a new gambling game where two players repeatedly flip coins, and whoever wins twice in a row takes the pot (a form of unbounded recursion). We prove the game to be fair.

  • We introduce alternative renegotiation primitives, which allow participants to choose some parameters (e.g. the amounts to be deposited) at renegotiation time, and to change the set of participants involved in the renegotiated contract. We show that both primitives can be executed on Bitcoin as is. We also introduce a primitive that, at the price of minor Bitcoin extensions, supports non-consensual renegotiations, which are automatically triggered by the contract without requiring the participants’ agreement.

Because of space constraints, we relegate part of the technicalities to [9].

2 BitML with Renegotiation and Recursion

We start by formalising contract preconditions. We use to range over participants. We assume a set of deposit names \(x_{}, y_{}, \ldots \), a set of deposit variables \(d_{},e_{},\ldots \), and a set of secret names \(\mathord {{a}_{}}, \mathord {{b}_{}}, \ldots \). We use \(\chi _{},\chi '_{},\ldots \) to range over deposit names and variables, and \(v_{}, v'_{}\) to range over non-negative values.

Definition 1

(Contract precondition). Contract preconditions have the following syntax (the deposits \(\chi _{}\) in a contract precondition must be distinct):

   \(\diamond \)

The precondition requires to own in a deposit \(\chi _{}\), and to spend it for stipulating the contract. The precondition requires to generate a secret \(\mathord {{a}_{}}\), and commit to it before the contract starts. After stipulation, can choose whether to disclose the secret \(\mathord {{a}_{}}\), or not.

To define contracts, we assume a set of recursion variables, ranged over by \(\texttt {X }_{},\texttt {Y }_{},\ldots \), and a language of static expressions \(\mathcal {E}_{},\mathcal {E}'_{},\ldots \), formed by integer constants k, integer variables \(\alpha _{},\beta _{},\ldots \), and the usual arithmetic operators. We omit to define the syntax and semantics of static expressions, since they are standard. We assume that a closed static expression evaluates to a 32-bit value. We use the bold notation for sequences, e.g. \(\mathbf {x_{}}\) denotes a finite sequence of deposit names.

Definition 2

(Contract). Contracts are terms with the syntax in Fig. 1, where: (i) each recursion variable \(\texttt {X }_{}\) has a unique defining equation ; (ii) renegotiations have the correct number of arguments;(iii) the names \(\mathbf {\mathord {{a}_{}}}\) in are distinct, and they include those occurring in p; (iv) in a prefix , the sequences have the same length. We denote with \(0\) the empty sum. We assume that the order of decorations is immaterial, e.g., is equivalent to .    \(\diamond \)

A contract is a choice among guarded contracts . A guarded contract continues as once all the secrets \(\mathbf {\mathord {{a}_{}}}\) have been revealed and satisfy the predicate \(\mathord {p_{}}\). The guarded contract divides the contract into n contracts , each one with balance . The sum of the must coincide with the current balance. The action transfers the whole balance to . When enabled, the above actions can be fired by anyone at anytime. To restrict who can execute a branch and when, one can use the decoration , requiring to wait for ’s authorization, and the decoration , requiring to wait until the time specified by the static expression \(\mathcal {E}_{}\). The action allows the participants involved in the contract to renegotiate it. Intuitively, if , then the contract continues as if all the participants give their authorization, and satisfy the precondition .

Definition 3

(Contract advertisement). A contract advertisement is a term such that: (i) each secret name in occurs in ; (ii) requires a deposit from each in ; (iii) each in refers to a defining equation where the participants in are the same as those in .    \(\diamond \)

The second condition is used to guarantee that the contract is stipulated only if all the involved participants give their authorizations. The last condition is only used to simplify the technical development. We outline in Sect. 5 how to relax it, by allowing renegotiations to exclude some participants, or to include new ones, which were not among those who originally stipulated the contract.

Fig. 1.
figure 1

Syntax of BitML contracts.

We now extend the reduction semantics of BitML [11], by focussing on the new renegotiation primitive. Because of space limitations, here we just provide the underlying intuition, relegating the full formalisation to [9]. We start by defining the configurations of the semantics.

Definition 4

(Configuration). Configurations have the following syntax:

We denote with \({\varGamma _{}} \mid {t_{}}\) a timed configuration, where \(t_{}\in \mathbb {N}\) is a global time.    \(\diamond \)

We illustrate configurations and their semantics through a series of examples.

Deposits. A deposit can be subject to several operations, like e.g. split into two smaller deposits, join with another deposit, transfer to another participant, or destroy. In all cases must authorise the operation. For instance, to authorize the join of two deposits, can perform the following step:

where is the authorization of to spend \(x_{}\). After also provides the dual authorization to spend \(y_{}\), anyone can actually join the deposits:

Advertisement. Any participant can broadcast a new contract advertisement , provided that all the deposits mentioned in exist in the current configuration, and that the names of the secrets declared in are fresh.

Stipulation. To stipulate an advertised contract , all the participants mentioned in it must fulfill the preconditions, and authorise the stipulation. For instance, let , and let be an arbitrary contract involving only and . The stipulation starts from a configuration containing the advertisement and the participants’ deposits:

At this point the participants must commit to their secrets (in this case, only has a secret). This is rendered as a sequence of steps:

where represents the fact that has committed to the secret N, while and represent ending the commitment phase (these steps might seem redundant, but they are useful to obtain a step-by-step correspondence between BitML executions and Bitcoin executions).

After that, and must perform an additional sequence of steps to authorize the transfer of their deposits \(x_{}\), \(y_{}\) to the contract:

where and are the authorizations to spend \(x_{}\) and \(y_{}\).

At this point all the needed authorizations have been given, so the advertisement can be turned into an active contract. This step consumes the deposits and all the authorizations, and creates an active contract, with a fresh name \(z_{}\):

Renegotiation. We illustrate the steps to renegotiate , where , and is an arbitrary contract involving only and , and possibly containing the integer variable \(\alpha _{}\) in static expressions. Here, requires and to spend two deposits, and to commit to a secret. Unlike in the case of contract stipulation above, deposits names are unknown before renegotiation, so we use the deposit variables \(d_{},e_{}\) to refer to them.

Consider a configuration , where contains the branches alternative to the renegotiation. A possible execution of the action starts as follows:

where the advertisement is obtained by transforming as follows: (i) variables \(d_{},e_{}\) are renamed into fresh ones \(d'_{},e'_{}\), and similarly the secret name \(\mathord {{a}_{}}\) into \(\mathord {{a'}_{}}\),(ii) the static expressions in are evaluated, assuming \(\alpha _{}= k_{}\), and replaced with their results.The superscript \(x_{}\) in the advertisement is used to record that, when the renegotiation is concluded, the contract \(x_{}\) must be reduced.

In the subsequent steps participants choose the actual deposit names, and commits to her secret. If owns in \(\varGamma _{}\) a deposit , she can choose \(d'_{}= y_{}\) to satisfy the precondition . Similarly, can choose \(e'_{}= z_{}\) if he owns such a deposit in \(\varGamma _{}\). These choices are performed as follows:

At this point, participants must authorise spending their deposits and the balance of the contract at \(x_{}\). This is done through a series of steps:

Finally, the new contract is stipulated. This closes the old contract, and transfers its balance to the newly generated one, with a fresh name \(x'_{}\):

Note that the branches in are discarded only in the last step above, where we complete the renegotiation. Before this step, it would have been possible to take one of the branches in , aborting the renegotiation.

Withdraw. Executing transfers the whole contract balance to :

After the execution, the alternative branch is discarded, and a fresh deposit of for is created. Note that the active contract \(x_{}\) is terminated.

Split. The \(\texttt {split} \) primitive divides the contract balance in n parts, each one controlled by its own contract. For instance, if \(n=2\):

After this step, the new spawned contracts and are executed concurrently.

Reveal. The prefix can be fired if all the committed secrets \(\mathbf {\mathord {{a}_{}}}\) have been revealed, and satisfy the guard \(\mathord {p_{}}\). For instance, if :

The terms and represent the fact that the secrets \(\mathord {{a}_{}}\) and \(\mathord {{b}_{}}\) have been revealed. Crucially, only the participant who performed the commitment can add the corresponding term to the configuration.

Authorizations. A branch decorated by can be taken only if the participant has provided her authorization. For instance:

The leftmost configuration contains the term , which represents ’s authorization to take the branch . This enables the step to be taken. When multiple authorizations are required, the branch can be taken only after all of them occur in the configuration.

Time Constraints. We represent time in configurations as \({\varGamma _{}} \mid {t_{}}\), where \(\varGamma _{}\) is the untimed part of the configuration and \(t_{}\) is the current time. We always allow the time to advance through the rule \( {\varGamma _{}} \mid {t_{}} \xrightarrow {} {\varGamma _{}} \mid {t_{}+\delta } \), for all \(\delta >0\). A branch decorated with \(\texttt {after}\, d\) can be taken only if time d has passed. For instance:

For the branches not guarded by \(\texttt {after}\), we lift transitions from untimed to timed configurations: namely, for an untimed transition \(\varGamma _{}\xrightarrow {} \varGamma '_{}\), we also have the timed transition \({\varGamma _{}} \mid {t_{}} \xrightarrow {} {\varGamma '_{}} \mid {t_{}}\). This reflects the assumption that participants can always meet deadlines, if they want to.

3 Executing BitML on Bitcoin

To execute a BitML contract, participants first compile it to a set of Bitcoin transactions, and then append these transactions to the blockchain, each following their own strategy. Participants’ strategies can involve other actions besides appending transactions, like e.g. broadcasting signatures on given transactions (which corresponds, in BitML, to add an authorization to the configuration), revealing secrets, and waiting some time (see Definition 16 in [11]). The coherence between the BitML semantics and the execution on Bitcoin is guaranteed by a step-by-step correspondence between the transitions of the BitML semantics and the actions performed by participants on the Bitcoin network.

In this section we illustrate the compiler and the execution protocol through a couple of examples, focussing on the new renegotiation primitive. The needed background on Bitcoin will be introduced along with these examples. We relegate the formal definition of the compilation rules to [9].

Zero-Coupon Bond. Recall the contract from Sect. 1:

The precondition requires to deposit in the contract, and to deposit . In Bitcoin, this precondition corresponds to requiring two unspent transactions redeemable by and , and containing the required amounts. We represent these transactions as follows, using the notation in [7]:

figure a

The transaction is a record with three fields ( is similar). The field points to one or more previous transactions in the blockchain. The field is a pair, whose first element is a boolean predicate (with parameter \(x_{}\)), and the second element, , is the amount that a subsequent transaction satisfying the predicate can redeem from . Here, the predicate is true when \(x_{}\) is a signature of on the redeeming transaction (i.e., one having as ).

Fig. 2.
figure 2

Transactions obtained by compiling the contract.

The contract is compiled into the transactions in Fig. 2. The first one that can be appended to the blockchain is . This requires a few conditions to be met: (i) and are unspent on the blockchain, i.e. no other transactions spend them; (ii) the amount specified in the field of does not exceed the sum of the amounts in and ;(iii) the predicates in the fields of and are true, after replacing the formal parameters with the signatures and , contained in the field of .The contract becomes stipulated once is on the blockchain.

After that, the \(\texttt {split} \) action can be performed by either or , by redeeming with . This transaction uses , a set of two key pairs, each one owned by each participant. These keys are only used in this step, to ensure that no transaction but can redeem .

The transaction creates two unspent outputs (indexed by 0 and 1), corresponding to the two parallel components of the \(\texttt {split} \), each with its own balance. These outputs can be redeemed independently, by different transactions. The output at index 0 can only be redeemed by (note that ’s field refers to the output 0 of ), transferring to . No other redemption is possible, since such output requires a signature with a specific key set, i.e. , which is not used for any other purpose. Further, the output of can be redeemed with ’s key, without ’s one. Similarly, the output 1 of can be redeemed by , which in turns transfers to . The field in ensures that this may only happen after time 2030.

The stipulation protocol followed by participants requires that all the signatures needed to append the transactions in Fig. 2 are exchanged before is appended. This is obtained by exchanging the signatures of after all the other signatures. This ensures that, once the execution of starts, any honest participant can make it proceed, by appending a transaction that correspond to any of the enabled BitML actions.

In general, to guarantee that such liveness property holds, the contract must be suitably crafted, using the pattern discussed in Sect. 1. In Sect. 6 we discuss techniques to statically verify this property.

Zero-Coupon Bond with Renegotiation. Compiling yields the transactions:

figure c

Once these three transactions are on the blockchain, the only enabled action in the corresponding BitML contract is , which asks from as a precondition. At the Bitcoin level, satisfying this precondition requires to broadcast the identifier of a transaction holding and redeemable by himself. In BitML, this corresponds to choosing the deposit name \(y_{}\) for the deposit variable \(d_{}\). Then, participants compile the contract advertisement , where , after replacing \(d_{}\) with \(y_{}\). The compiler produces the following transactions:

figure d

The renegotiation succeeds once is on the blockchain. After that, any participant can perform the , by appending to the blockchain.

As shown by this example, the compiler handles renegotiation as follows:

  • at stipulation time, it does not produce transactions for any ;

  • at renegotiation time, the participants broadcast the identifiers of their new deposits, and the commitments of their new secrets. Static expressions are then evaluated, and replaced by their value. Finally, the new contract is compiled as usual, with the exception that the new initial transaction has an extra input, which transfers the balance of the caller contract to the callee (in the example, this extra input is within ).

Computational Soundness. The main result of [11] is computational soundness, which ensures that each execution trace at the Bitcoin level has a corresponding one in the semantics of BitML. This was achieved by formalizing the semantics of Bitcoin using a computational model, where participants can exchange bitstrings as messages, and append transactions to the blockchain. Then, a coherence relation was defined to relate symbolic runs to computational ones, essentially matching symbolic moves with their implementation in Bitcoin.

Our extension of BitML with renegotiation still enjoys computational soundness. The argument is similar, and requires extending the coherence relation to the new primitive. In particular, the reduction:

corresponds, in Bitcoin, to broadcasting a message which contains the hashes of her secrets and the transaction identifiers that she wishes to use as deposits.

Instead, the reduction:

corresponds to signing all the transactions obtained by compiling the new contract, and broadcasting the signatures. A participant signs only after receiving the signatures of the other transactions from all the other participants.

Computational soundness requires that each contract involves at least one participant, say , who follows the Bitcoin implementation of BitML. In particular, follows the stipulation and renegotiation protocols correctly, i.e. signing nothing but the protocol messages, and signing last. We also make the usual assumptions on computational adversaries: they can only run PPTIME algorithms, and they can break the underlying cryptography with negligible probability, only. Consequently, we only consider computational runs of polynomial length (with respect to the security parameter). This is because in longer runs the adversary would be able to break the cryptography by brute force.

Below, we provide an intuitive statement of computational soundness. The formal statement is in [9].

Theorem 1

(Computational soundness). Under the hypotheses above, each Bitcoin-level computational run has a corresponding coherent BitML run, with overwhelming probability.

4 A Fair Recursive Coin Flipping Game

To illustrate recursion in our extended BitML, we introduce a simple game where two players repeatedly flip coins, and the one who wins two consecutive flips takes the pot. The precondition requires each player to deposit and choose a secret:

Fig. 3.
figure 3

A recursive coin flipping game.

The contract (Fig. 3) asks to reveal his secret first: if waits too much, can withdraw the contract funds after time 1. Then, it is ’s turn to reveal (before time 2, otherwise can withdraw the funds). The current flip winner is if the secrets of and are equal, otherwise it is . At this point, the contract can be renegotiated as , depending on the flip winner (the parameter 1 represents the round). If players do not agree on the renegotiation, then the funds are split fairly, according to the current expected win.

The contract requires and to generate fresh secrets for the n-th turn. If wins again, she can withdraw the pot, otherwise the contract can be renegotiated as . If the players do not agree on the renegotiation, the pot is split fairly between them. The contract is similar.

The following theorem states that our coin flipping game is fair. Fairness ensures that the expected payoff of a rational player is always non-negative, notwithstanding the behaviour of the other player. Rational players must choose random secrets in \(\{0,1\}\). Indeed, non uniformly distributed secrets can make the adversary bias the coin flip in her favour. Further, choosing a secret different from 0 or 1 would decrease the player payoff. Indeed, would be prevented from revealing his secrets (by the predicate in the ), and so could win after the timeout. If chooses a secret different from 0 or 1, she makes win the round (since wins when the secrets are different). Rationality also requires to reveal secrets in time (before the alternative \(\texttt {after}\) branch is enabled), and to take the branch if restipulation does not occur in time. This ensures that, when renegotiation happens, there is still time to reveal the round secrets. Indeed, a late renegotiation could enable the other player to win by timeout.

Theorem 2

The expected payoff of a rational player is always non-negative.

Proof

(Sketch). First, we consider the case where renegotiation always happens. A rational player wins each coin flip with probability 1/2, at least: so, the probability of winning the whole game is also 1/2, at least. In the general case, the renegotiation at the end of each round may fail. When this happens, the rational player takes the branch, distributing the pot according to the expected payoff in the current game state, thus ensuring the fairness of the whole game. The player who won the last coin flip is expected to win , with \(p = \nicefrac {1}{2}\cdot 6 + \nicefrac {1}{2}\cdot (\nicefrac {1}{2}\cdot p + \nicefrac {1}{2}\cdot 0)\), giving \(p=4\). Accordingly, the contracts transfer to the winner of the last flip and to the other player.

5 More Expressive Renegotiation Primitives

The renegotiation primitive we have proposed for BitML is motivated by its simplicity, and by the possibility of compiling into standard Bitcoin transactions. By adding some degree of complexity, we can devise more general primitives, which could be useful in certain scenarios. We discuss below some alternatives.

Renegotiation-Time Parameters. The primitive allows participants to choose at run-time only the deposit variables used in the renegotiated contracts, and to commit to new secrets. A possible extension is to allow participants to choose at run-time arbitrary values for the renegotiation parameters \(\mathbf {\mathcal {E}_{}}\).

For instance, consider a mortgage payment, where a buyer must pay to a bank in 10 installments. After has paid the first five installments (of each), the bank might propose to renegotiate the contract, varying the amount of the installment. Using the BitML renegotiation primitive presented in Sect. 2, we could not model this contract, since the new amount and the number of installments are unknown at the time of the original stipulation. Technically, the issue is that the primitive only involves static expressions \(\mathcal {E}_{}\), the value of which is determined at stipulation time.

To cope with non-statically known values, we could extend guarded contracts with terms of the form , declaring that the value \(v_{}\) is to be chosen by at renegotiation time. For instance, this would allow to model our installments payment plan as \(\texttt {IPP }_{}{\langle {1} \rangle }_{} \), with the following defining equations:

where in \(\texttt {IPP }_{}{\langle {5} \rangle }_{} \), the bank chooses the number of installments k, as well as the amount v of each installment. Note that if does not agree with these values, the renegotiation fails. A more refined version of the contract should take this possibility into account, by adding suitable compensation branches. Although adding the new primitive would moderately increase the complexity of the semantics and of the compiler, this extension can still be implemented on top of standard Bitcoin, preserving our computational soundness result.

Renegotiation with a Given set of Participants. As we have remarked in Sect. 2, a renegotiation can be performed only if all the participants of the contract agree. To generalise, we could require the agreement of a given set of participants (possibly, not among those who originally stipulated the contract).

For instance, consider an escrow service between a buyer and a seller for the purchase of an item worth . The normal case is that the buyer authorizes the transfer of after receiving the item, but it may happen that a dishonest seller never sends the item, or that a dishonest buyer never authorizes the payment. To cope with these cases, the participants can renegotiate the contract, including an escrow service which mediates the dispute, as follows:

where means that only and need to agree in order for the contract to be executed, resolving the dispute. In this case it is crucial that the renegotiation is possible even without the agreement between and . Indeed, if decides to refund (by authorizing ), it is not to be expected that also agrees. Similarly to the one discussed before, also this extension can be implemented on-top of Bitcoin. The computational soundness property is preserved, under the assumption that at least one participant in any renegotiation is honest, i.e. it follows the renegotiation protocol. Crucially, if a renegotiation only involves dishonest participants, the renegotiated contract could be anything, not necessarily that prescribed in the original contract.

Non-consensual Renegotiation. In the variants of discussed before, renegotiation requires one or more participants to agree. Hence, each use of must include suitable alternative branches, to be fired in case the renegotiation fails. In certain scenarios, we may want to renegotiate the contract without the participants having to agree. To this purpose, we can introduce a new primitive , which continues as \({\texttt {X }_{}}\langle {}\rangle \) without requiring anyone to agree. For simplicity, we assume the defining equations of this primitive of the form , where \(v_{}\) represents the amount of added to the contract, by anyone.

We exemplify the new primitive to design a two-players game which starts with a bet of from , and a bet of from . Then, starting from , players take turns adding each to the pot. The first one who is not able to provide the additional within a given time loses the game, allowing the other player to take the whole pot. The contract is as follows:

Unlike , the action can be fired without the authorizations of all the players: it just requires that the authorization to gather is provided, by anyone. Even though the sender of these is not specified in the contract, it is implicit in the game mechanism: for instance, when calls , only is incentivized to add , since not doing so will make win.

Implementing the primitive on top of Bitcoin seems unfeasible: even if it were possible to use complex off-chain multiparty computation protocols [16], doing so might be impractical. Rather, we would like to extend Bitcoin as much as needed for the new primitive. In our implementation of BitML, we compile contracts to sets of transactions and make participants sign them. In standard BitML this is doable since, at stipulation time, we can finitely over-approximate the reducts of the original contract. Recursion can make this set infinite, e.g. , hence impossible to compile and sign statically. A way to cope with this is to extend Bitcoin with malleable signatures which only cover the part of the transaction not affected by the parameter n in . Further, signatures must not cover the fields of transactions, since they change as recursion unfolds. In this way, the same signature can be reused for each call.

Adding malleability provides flexibility, but poses some risks. For instance, instead of redeeming the transaction corresponding to with the transaction of one could instead use the transaction of , since the two transactions have the same signature. To overcome this problem, we could add a new opcode to allow the output script of to access the parameter in the redeeming transaction, so to verify that it is indeed \(n+1\) as intended. Similarly, to check that we have more in the new transaction, an opcode could provide the value of the new output. The same goal could be achieved by adapting the techniques used in [24, 25] to realize covenants.

6 Conclusions

We have investigated linguistic primitives to renegotiate BitML contracts, and their implementation on standard Bitcoin. More expressive primitives could be devised by relaxing this constraint, e.g. assuming the extended UTXO model [14].

The existing verification technique for BitML [12] is based on a sound and complete abstraction of the state space of contracts. Since this abstraction is finite-state, it can be model-checked to verify the required properties. The same technique can be directly applied to BitML contracts featuring renegotiation (but without recursion), since the abstraction would remain finite. Instead, the same abstraction on recursive contracts would lead to infinitely many states. Even if we could exploit the fact that Bitcoin uses 32-bit integers to make the state space finite, it would still be too large for verification to be practical.

If we assume that integers are unbounded, and that participants always accept renegotiations, the extension of BitML presented in Sect. 2 can simulate a counter machine, so making BitML Turing-complete. Hence, verification cannot be sound and complete. Alternative techniques to model checking (e.g., type-based approaches [15]) could be used to analyse relevant contract properties.