Simple Locking Contracts: Part 2

The Ballad of Saint Hodl

Inactivity strikes us as intelligent behavior. Neither we nor most business managers would dream of feverishly trading highly profitable subsidiaries because a small move in the Federal Reserve’s discount rate was predicted or because some Wall Street pundit had reversed his views on the market. Why, then, should we behave differently with our minority positions in wonderful businesses? — Warren Buffet

In part 1 of the series we learned about conditionally locking contracts that allow for two parties to transact value on an ethereum chain using a secret hashed password funds could be kept in public view and then retrieved at a future time. In this article, we will allow a user to send coins to a contract for safe keeping until some point in the future. In crypto trading terms this is know as “Hodling” and is an optimal strategy in investing in general( see: Warren Buffet)

The History of Hodl

In 2013, a user named GameKyuubi posted a now infamous, admittedly drunken, post on his poor luck as a trader.

I AM HODLING

I AM HODLING

I AM HODLINGbitcointalk.org

GameKyuubi understood the importance of holding assets long term as a value investor, however, they lacked the strength of will to do so with the ease of trading options that were available. It is by this example that we will work on a chaincode that will allow the block chain to do the hard work “Hodling” for us.

The Saint Hodl Contracts

Saint Hodl
'-._ ```"""---.._
,-----.:___ `\ ,;;;,
'-.._ ```"""--.._ |,%%%%%% _
, '. `\;;;; -\ _ _.'/\
.' `-.__ \ ,;;;;" .__{=====/_)==:_ ||
,===/ ```";,,,,,,,;;;;;'`-./.____,'/ / '.\/
'---/ ';;;;;;;;' `--.._.' /
,===/ '-. `\/
'---/ ,'`. |
; __.-' \ ,'
jgs \______,,.....------'''`` `---`

TL;DR

Send funds, get later. All of the following contracts will be made available for use on SaintHodl.com for ease of access and are also available as an open source resource on github. You can use your Jaxx.io,MEW, or any Ethereum Classic wallet to interact with them, for free!

The Most Important Part

A time locked contract cannot be opened early. You cannot negotiate with the blockchain, your locked funds are safely tucked away until the predetermined amount of blocks have passed. No backsies.

So in the time locked contract (TLC) this variable is made public and is listed first. Anyone viewing the contract should easily be able to view this number and know what they are getting into ahead of time. In sainthodl’s contract it is written as:

uint public freezeBlocks = 20;

This sets the contract freeze time up for 20 blocks, which is ~280 seconds or 4.67 minutes. Not a long time, but enough for testing. (There is a 2 million block option on site if you are looking for something more 😉 )

Freeze blocks viewed on

Lockers

In part one, hash boxes were publicly view-able. The same will be true with our TLC contracts. Each ‘box’ will consist of 3 details: the owner, how long to hold coins, and how many coins are being held.

struct locker{      
uint freedom;
uint bal;
}
mapping (address => locker) public lockers;

Every address will now be mapped to a unique locker.

Sending funds to a Locker

Whenever anyone sends coins to our TLC contract we want it to add funds to their locker and set the freeze time to some block in the future. To do this we will be using the fall back function in the solidity contract:

function() payable public {        
locker storage l = lockers[msg.sender];
l.freedom = block.number + freezeBlocks;
l.bal = l.bal + msg.value;
}

The locker will be identified by the user sending funds( locker “l” is the locker of the message sender). We then use the latest block.number and add the predetermined number of freeze blocks to get our “freedom block”. The lockers balance will be calculated from its current balance (0 normally) and the value that was sent with the message. If you use the abi from the github with MyEtherWallet.com you will now be able to see everything in the locker (Balance will be in Wei)

Using Mew Contract interface

The Second Most Important Part: Withdrawing

Finally, the urge to panic sell has passed, and you can now safely be trusted to get your funds back. Unlike the hashlocked contract where anyone with the preimage could claim the funds, only the owner of a locker is able to withdraw their funds from the TLC. A word of caution; when allowing strangers to withdraw from a contract it is important to avoid opening up to recursive calls. The Dao contract failed because of this design flaw. This would work by someone calling the withdraw function from a contract that had its fallback function set to also call the withdraw function. To avoid this we will set the lockers balance to zero before we send any funds; this way if a contract calls back it would only be able to withdraw zero.

function withdraw() public { 
locker storage l = lockers[msg.sender];
require (block.number > l.freedom && l.bal > 0);
// avoid recursive call
uint value = l.bal;
l.bal = 0;
msg.sender.transfer(value);
}

Similar to the first function, locker “l” is the locker of the message sender. We then require that both the current block number be greater than the lockers freedom block and that the lockers balance be greater than zero. If either of these conditions are not met, the function will ‘fail’ i.e. not do anything. If both conditions are met; the lockers balance is saved as ‘value’, the original balance is set to zero, and then value is sent to the locker owner.

Withdraw function on Mew

Events

If you read through the contract you will notice two “events” that show up:

event Locked(address indexed locker, uint indexed amount);    
event Released(address indexed locker, uint indexed amount);

These events are displayed in wallets that watch for events and can be used to trigger things like posting to twitter.

Contract as viewed in Parity

Conclusion

With this simple contract anyone is able to commit and retrieve coins on the chain for as short or as long as they like. Part 3 will combine the functions of part 1 & 2 to create a hash-time locked contract to do some really cool things!