Settling a DAML Payment Obligation on Ethereum

Dimitri Liakakos
Jun 7, 2019 · 6 min read

DAML is a great open source language for modeling rights and obligations between multiple parties.

A DAML agreement between two parties may require the obligor to perform an action such as provide health treatment, paint a fence or transfer an amount of money to the beneficiary. This obligation is conveniently expressed in the agreement field of a DAML smart contract and is settled off-ledger.

Providing health treatment or painting someone’s fence means interacting with the physical world and therefore such obligations must be settled off-ledger. The same though doesn’t hold true when transferring value between parties, especially digital tokens.

Enter Hemera: A DAML library and accompanying app that lets you interact with the Ethereum Network. With Hemera you can build a DAML workflow that deploys and transacts with Ethereum smart contracts but also transfers Ether or any ERC-20 compliant token between addresses.

In this post we will use Hemera to settle a payment obligation created between two parties in a DAML workflow. We will do that by transferring Ether from the payer’s address to the payee’s and evidencing the transaction on the DAML ledger. To accomplish this, will draw inspiration from the example illustrated in DAML’s Ledger Model documentation page. The twist is that instead of transferring IOUs, we will transfer Ether.

Let’s suppose that Alice wants her house painted. She gets an offer from Bob the Painter in exchange for 1 Ether. Alice also happens to be a Hemera user, meaning she has a Hemera user role DAML contract enabling her to interact with the Ethereum Network. Interaction happens when Alice exercises non-consuming choices on her user contract and creates requests which are serviced through an operator party. The operator may be a third party known to Bob, or Bob himself. The operator’s responsibility is to help Alice build her Ethereum transaction and then forward it to the network. In Hemera all transaction signing happens locally for the user, so Alice will never have to share her private key with anyone.

Alice thinks that Bob’s offer is a bargain(!), so let us go ahead kick things off with a DAML scenario we will name paintTheHouse. We will first bootstrap Hemera for Alice and then have Bob create his offer:

In the PaintOffer contract that Bob created, he specified himself as the painter and Alice as the beneficiary. He also added any trusted Hemera operator parties (in our case “Operator”), the amount of Ether he wants for his work and the deposit address for the Ether. The PaintOffer template looks like this:

The PaintOffer contract gives Alice (the beneficiary) a choice to accept Bob’s offer by exercising AcceptOffer and passing in the address for the source of the funds and her Hemera user role Contract Id. Execution of the AcceptOffer choice will result in the creation of a PaintContract instance which is a binding agreement between Alice and Bob that obligates Bob to paint Alice’s house and obligates Alice to remit 1 Ether to Bob.

As a side effect, AcceptOffer will also exercise the User_SendEther choice on Alice’s user contract which in turn will create a Hemera request for the transfer of 1 Ether to Bob’s address. After Alice exercises AcceptOffer, the resulting state of the DAML ledger is the following:

Image for post
Image for post
Active contracts after Alice exercises AcceptOffer

Great! As expected, we have successfully created a PaintContract between Alice and Bob, as well as a TransferRequest contract between Alice and the Operator. While Bob may start painting Alice’s house, the TransferRequest contract will follow the standard Hemera Transfer workflow. Note that Bob will be unaware of the evolution of this transfer request flow (unless of course he acts as the operator), until it is time for Alice to present him evidence that she has made the payment. This is a feature of the privacy model in DAML that you get for free. The process of creating an Ethereum transaction is Alice and the Operator’s business — all Bob cares about is getting paid. After all we want him focussing on his job!

To service the TransferRequest, the Operator will fetch the nonce of the source address (0xC06b51647e3A52d770547B97b1d3c5CDdF264B85) as well as the default values for gas and gas price. the Operator will then archive the TransferRequest and create an UnsignedTransferTransaction with a txToSign field containing the RLP encoded raw transaction that represents the Ether transfer. Below is a visualization of the UnsignedTransferTransaction instance taken from the Navigator:

Image for post
Image for post

As I mentioned before, no one but Alice has access to the private key which unlocks the funds of the from address. Therefore it is Alice’s turn to act. She needs to take the hex-encoded raw transaction in the txToSign field and use her private key to sign it. Since manual transaction signing can be tedious, Hemera optionally provides a tool that Alice can run locally and sign the transaction! Finally, if Alice does not trust the transaction the Operator gave her to sign matches the details of the original request, she can easily verify by using any third party RLP decoder or service that she is comfortable with.

As soon as Alice signs the transaction, she passes the signed payload to the UnsignedTransferTransaction_Sign choice converting it to a SignedTransferTransaction:

Image for post
Image for post

Now when Bob finishes painting her house, Alice can broadcast the signed transaction to the Ethereum Network via the SignedTransferTransaction_Send choice. Once sent, the Operator will update the sendStatus variant of the SignedTransferTransaction contract from New to Sent and will include the time the transaction was sent, the version of the Ethereum node that sent it and last but not least, the transaction hash:

Image for post
Image for post
SignedTransferTransaction’s sendStatus

If you are curious, feel free to take a closer look at this transaction in by following this link.

We are almost done! There is one final step left and that’s settling the PaintContract. Before we do this let’s have a look at it at the Navigator:

Image for post
Image for post
Alice and Bob’s unsettled PaintContract

as well as take a deeper dive at its template:

Alice is given a choice on the PaintContract called SettleTransfer where she can provide the Contract Id of the transfer transaction she signed and sent. The body of the SettleTransfer choice will first assert that the PaintContract has not yet been settled. It will then fetch the transfer transaction and assert that its details match the ones of the specified contract terms. It will then proceed to archive the SignedTransferTransaction contract (so that Alice cannot provide it as proof to another contract). Finally it will update the PaintContract’s settled state to True and populate the txHash field with the Ethereum transaction hash of the transfer.

And that’s it! We have settled the payment obligation on Ethereum and successfully updated the PaintContract agreement:

Image for post
Image for post
The final settled PaintContract!

To recap, here’s a diagram of the entire workflow from start to finish:

Entire workflow for Painting Alice’s House for Ether

If you want to create your own DAML + Ethereum workflow you can fork the Hemera GitHub repo. Also if you have any feedback or want to contribute to the project feel free to comment or submit a PR!

The Startup

Medium's largest active publication, followed by +756K people. Follow to join our community.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store