Simple Locking Contracts: Part 1

There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult. — C.A.R Hoare

The Hash Box

This is probably one of the simplest bits of chain code I have written. But as with all things blockchain, I will lead in with an overly complicated story involving fictional characters. I think Bob and Alice get too much attention so I tend to use the lesser known characters in Cryptopia in my stories. They are all fictional so the names really do not matter.

Victor and the Contest

Victor has announced a contest to all of his friends. He will give 5 coins to whichever of his friend’s can comes up with the best song. Some of Victor’s other friends know they are not good song writers but would also like to donate to the contest. Since Victor does not want to hold all the money in his account(and his friends don’t really want him to hold it), Victor decides to build a plexiglass donation box with a lock and place it in the middle of town. Now everyone can see how much money has been donated to the contest and add money if they like. Since everyone is watching the money, the only thing Victor needs to keep safe is his key. Victor has also announced that he will give the key that opens the box to the winner of the contest and they will then get to claim all the money inside.

Building a Lock and a Box

On the blockchain (a digital “middle of town”) we have several tools to create locks. The cheapest secure lock we can use on ethereum chains is the SHA-256 algorithm. SHA-256 algorithm generates an almost-unique, fixed size 256-bit (32-byte) hash. Hash is a one way function — it cannot be decrypted back. It is the building block of most all blockchains in use today. It was included in the original ethereum code as a precompiled contract, meaning that the hash can be used with very little gas in any contract.

Since any data can produce an almost-unique SHA-256,it will work well for our purposes. We start by making a unique phrase that will be used as the key for our box. For the demonstration we will use the secret phrase: `Alice and Bob sitting in a tree.`

You can use any method you like to get the hash of the phrase, and as long as they use SHA-256 it will always return the same 32 bytes. We will set this hash as a public variable our contract so that anyone can read the hash. As the hash is a one-way function there is no danger of allowing others to view and verify it.

bytes32 public hashLock = e839dfa428e99c99630742d1086c99c51e5be27d702c47a786be6f17c8a3a16;

For a contract to receive and store ether we will need to set its fall back function to payable (making it a simple money box).

function () payable public{}

Now we have constructed both a box that anyone can send funds to and a lock/key for our box. Now we will need to add a way that anyone with the key can claim the contents inside.

function claim(string _WhatIsTheMagicKey) public {
require(sha256(_WhatIsTheMagicKey) == hashLock);
selfdestruct(msg.sender);
}

Let’s step through the `claim` function. When someone calls the claim function they will also supple a string that we are calling “_WhatIsTheMagicKey” The first step in the function will test if the SHA-256 hash of the string matches our HashLock. If it doesn’t the function will fail. If the two do match, It will send all of the funds in the box to the person who gave it the magic key. All or nothing (aka atomic). After that the contract self-destructs, cleaning itself up from the public state as it is not needed anymore.

In the Wild

Compiling the byte code can be done any number of ways. I use the built in compiler in Parity, but Remix or truffle will work just as well. I will use MyEtherWallet.com to deploy and interact with the contract.

Step 1: Deploy the contract

Paste the bytecode in the deploy contract section on MEW. This will create a new contract.

Step 2: Fund the contract

At this point the lock box is set up. Add as much money as you like, the only way to get the coins out is with key.

Step 3: Verify the Hash

Since hashLock is constant it is free to view.

Step 4: Unlock the Box

Use the ‘Claim’ function can now be called by anyone with the key to get the funds out of the account

The Complete Contract

pragma solidity ^0.4.18;
contract HashLock {
    bytes32 public hashLock = 0x_007_YourHashGoesHere;
    function () payable public{}
    function claim(string _WhatIsTheMagicKey) public {
        require(sha256(_WhatIsTheMagicKey) == hashLock);
        selfdestruct(msg.sender);
   }
}

Conclusion

The hash box can be used for many things. Bug bounties, contests, simple escrow, you name it. I set the gas price to 10 Gwei so my entire series of tests cost around $.002 USD. This is a simplified version of the hash/time lock contract used in atomic swaps and will be a key building block in a public mixing service coming up.

Part 2: turning a box into a xob….. coming soon

Ethereum Cross Chain Atomic Swaps

In this article, we will create a series of contracts which will allow two people to exchange coins across chains in a trustless atomic manner. An atomic transaction is an indivisible and irreducible series of transactions such that either all occur, or nothing occurs. The contract used is complimentary to BIP-199 so it can be used to transact from ethereum based systems to ethereum based systems or Bitcoin based system(assuming HTLC is allowed).

The difficult problem with cross chain swaps is the off chain coordination required to have the two parties meet and agree on conditions. It is outside the scope of this article, but any communication channel can be used really; email, slack, twitter, reddit, etc….

The background work that makes all of this possible is from BIP-199:

“A Hashed Time-Locked Contract (HTLC) is a script that permits a designated party (the “seller”) to spend funds by disclosing the preimage of a hash. It also permits a second party (the “buyer”) to spend the funds after a timeout is reached, in a refund situation.”

Victor (the “buyer”) and Peggy (the “seller”) exchange public keys and mutually agree upon a timeout threshold.

Peggy provides a hash digest. Both parties can now
 — construct the script and P2SH address for the HTLC.
 — Victor sends funds to the P2SH address or contract.
Either:
 Peggy spends the funds, and in doing so, reveals the preimage to Victor in the transaction; OR Victor recovers the funds after the timeout threshold.

On the Ether chains:

Peggy will be played by account: 0x9552ae966A8cA4E0e2a182a2D9378506eB057580

Victor will be played by account: 0x00D29a21429ad90230aCe2B9a1b25fa35bb288B8

The entire transaction explained:

Peggy will:

  • be locking up funds on etc chain (contract A)
  • that will be sent to Victor
  • when the message that hashes to digest is received

Victor will:

  • be locking up funds on eth chain (contract B)
  • that will be sent to Peggy
  • when the message that hashes to digest is received

Things that need to happen off chain:

  • both parties agree to an exchange rate
  • decide on a reasonable time limit
  • decide on who will lead (generate the preimage)
  • share public addresses

For our test conditions:

  • Peggy is the lead and will generate a sha256 digest off chain
  • Our preimage(“this is a test”) hashes to 2e99758548972a8e8822ad47fa1017ff72f06f3ff6a016851f45c398732bc50c
  • 1 hour timeout
  • 1:50 (1 eth = 50 etc) exchange rate

Everything for the test was deployed to the mainnets of both chains and is there available for review. I have included links where practical. All contracts were deployed with MyEtherWallet using byte code generated from the contract located here. To use this contract as is with out spinning up a node: copy and paste it into remix, fill in the variables for your transaction (hash, time, destination) and copy the byte code to MyEtherWallet to sign and deploy. You will need to create new contracts for your swap .To interact with the contract you can use this abi with the contract address in MyEtherWallet.

Step 1: Contracts are deployed
 Peggy deploys ContractA = 0xa1562aa5ad1e178c56f690c6e776c3c3a2c50193 (etc chain)
 Victor deploys ContractB = 0x7cfc4442dd96d6f85dd41d458a13957ba381e05a (eth chain)

Step 2: Both parties lock funds in their contracts
 Peggy sends .5 etc to 0xa1562aa5ad1e178c56f690c6e776c3c3a2c50193 
 Victor sends .01 eth to 0x7cfc4442dd96d6f85dd41d458a13957ba381e05a

Step 3: claim cross chain funds
 Peggy claims her funds from contract B, reveling the secret 
 Victor read data from contract B , get the key, and claims funds on contract A

That’s it! A little anti-climatic that it only takes 3 steps I guess, but everything on a block chain doesn’t need to be hard. If Peggy never claims her ether, Victor can never claim his. If Peggy does claim her’s she reveals the secret and Victor is free to claim his. The timeout exists so Peggy and Victor can claim their funds if something goes wrong.