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
Step 2: Fund the contract
Step 3: Verify the Hash
Step 4: Unlock the Box
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