If you’re not familiar with theory of Atomic Swaps, we suggest you take a look at Part 1, before reading this article. In this part we’ll focus more on the technical details of Zano’s implementation.
Compared to Bitcoin, Zano has a completely different code base, and even a different elliptical curve, but fortunately HTLCs allow us to organize atomic swaps between completely different projects. The only thing that they need to have in common is the hash function used in the HTLC. In the vast majority of cases, the hash is a classic SHA-256, so we implemented HTLC based on SHA-256 in Zano.
Unlike Bitcoin, where the semantics of the transaction output is formed through a special script, in Zano (as well as in all CryptoNote coins) there are predefined types of outputs (and accordingly inputs), the interpretation of which is defined in the core code as protocol rules. These outputs are a standard output (public key outputs) and a multisig output. To support atomic swaps, a new type of output (and, accordingly, type of input) was introduced — output to HTLC. This is a special output type, that specifies all the necessary data — refund address, redeem address, time lock, hash — which is handled accordingly by the core and wallet.
One noticeable difference with Bitcoin is that if the redeem transaction did not take place during the specified period of time, then you do not need to make a separate transaction to get the refund: the coins are automatically considered returned, and the corresponding logic is implemented both in the core and in the wallet code.
Unlike standard Zano transactions, redeem transactions cannot have mixins. Or, more precisely, it would be pointless to include mixins in a redeem transaction, since an HTLC output and a redeem transaction can easily be connected by the hash of the secret (which they both contain). In addition, it is easy to match a pair of HTLC-Redeem transactions in the Bitcoin network associated with a particular atomic swap operation in the Zano network, since the HTLC hash will obviously be the same on both networks.
However, Zano is a private blockchain with single-use addresses and unlinkable transactions. Even if it was possible to establish that a pair of transactions (HTLC-Redeem) was associated with an atomic swap on another blockchain, it would still likely be impossible to establish an association between these transactions and a particular wallet, or to determine where and when these coins were subsequently transferred.
In order to better illustrate how atomics work in Zano, as well as to show how to work with the atomic swap API in Zano, we have implemented a small example under nodejs. A more detailed description of this example with an explanation of the API can be found in our documentation. As a basis for our demo we used this article and this repository, which perfectly illustrate an example of atomic swaps between Bitcoin and BitcoinCash with full clarifications and great guidance. We have simplified the code significantly in order to illustrate the basic principles, however, we recommend you read the article if you want to have a better understanding of how HTLC works in Bitcoin and its forks. Also, keep in mind that this code is provided as a simplified example and is not intended to be used in production “as is”.
In the example that we wrote, it is important to understand the P2SH (Pay-To-Script-Hash) concept that is used in Bitcoin for creating HTLC transactions. As mentioned above, to define the specific way in which the output of a transaction can be used, Bitcoin uses a “script”, a special stack-based programming language. To be more specific, the script that is defined for a specific output will actually be the end of the script, and the beginning of this script will have to be provided by the party which spends this output (for more details, see the article).
However, in addition to explicitly including the “half” of the script in the output, there is also a way to send the output script’s hash (P2SH), which means that the content of the output script itself is not disclosed until the moment the output is actually spent. This way, the transaction only contains an indication that both halves of the script must be provided when spending this output — the half from which the hash in the P2SH output was derived, and the half which unlocks the script.
In the example given, this type of output is used to create an HTLC for Bitcoin transactions. Since both parties have agreed on the terms of the deal, and they know their public keys and each other’s public keys (namely public keys and not addresses, because, unlike Zano, in Bitcoin an address is a hash of a public key), then both sides will be able to generate the same HTLC output script, and as a result, both will get the same “script hash address” (P2SH). For one side it will be a “script hash address” (P2SH) to which it will send BTC, and for the other side it will be a “script hash address” (P2SH) that it will monitor (as a watch-only wallet), in order to detect that the HTLC for them is created and confirmed by the network.
We will not consider in detail the scenarios with a refund, since information about the refund procedure for Bitcoin is described in detail in that article and in Zano no additional actions need to be performed — if the HTLC has not been redeemed within the specified period of time, then the money is automatically considered returned to the address of the sender wallet.
In the described scenario, the process of the atomic swap starts on the BTC side, but in the repository with the example one can also find an example in which the process starts on the Zano side. In fact, it is simpler this way, because the Zano wallet is able to come up with a secret in a deterministic way, thus the user does not need to create and store the secret himself, and share its hash with the second party. All this happens automatically, and even if the wallet file got damaged during the swap process, and the secret got lost, after restoring the wallet from the seed phrase, the secret could be derived from the transaction and private data, thus allowing the swap process to continue.
New Release and Network Hard Fork (#3)
With this article we are announcing a new release, which will deploy a hard fork to activate Atomic Swaps at block 1082577 (estimated date June 1st). We kindly ask everyone to update your Zano client to the latest version, to avoid future network issues. All non-upgraded clients will be unable to work with the network after the hard fork occurs.