28.01.2016 Views

Hacker Bits, February 2016

HACKER BITS is a curated collection of the most popular articles on Hacker News — a social news website widely considered among programmers and entrepreneurs to be the best of its kind. Every month, we select the top voted articles on Hacker News and publish them in magazine format. For more, visit hackerbits.com.

HACKER BITS is a curated collection of the most popular articles on Hacker News — a social news website widely considered among programmers and entrepreneurs to be the best of its kind.

Every month, we select the top voted articles on Hacker News and publish them in magazine format. For more, visit hackerbits.com.

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

hacker bits<br />

<strong>February</strong> <strong>2016</strong>


Curator<br />

Ray Li<br />

Editor<br />

Maureen Ker<br />

Contributors<br />

Geoff Ralston<br />

Miles Shang<br />

Robin Doherty<br />

Mike Hearn<br />

Tanya Khovanova<br />

Todd Hoff<br />

Tom Blomfield<br />

Michael Marner<br />

Ossi Hanhinen<br />

Seth Godin<br />

Martin Matusiak<br />

Support<br />

support@hackerbits.com<br />

new bits<br />

Thank you for making our vision a reality. Yes,<br />

just by reading these words, you, gentle reader,<br />

have made our wildest dreams come true.<br />

You see, we’ve been fans of the now discontinued<br />

<strong>Hacker</strong> Monthly* (RIP), which gathered the biggest<br />

hits of <strong>Hacker</strong> News** into one slick magazine.<br />

When that magazine was shutdown, we were<br />

disheartened. Then we had a crazy idea.<br />

What if we could bring it back to life?<br />

Better yet, what if we could make it free for<br />

everyone?!<br />

Well, thanks to Paul Graham and the contributors<br />

who gave us the go ahead, this pipe dream has<br />

materialized as the inaugural issue of <strong>Hacker</strong> <strong>Bits</strong>.<br />

So sit back and enjoy this curated collection of the<br />

most popular articles on <strong>Hacker</strong> News…and stay<br />

tuned for the next issue!<br />

— Maureen and Ray<br />

*We are not affiliated with <strong>Hacker</strong> Monthly in any way.<br />

**We are not affiliated with <strong>Hacker</strong> News (although we wish we were!)<br />

2 hacker bits


hacker bits<br />

<strong>February</strong> <strong>2016</strong><br />

Geoff Ralston<br />

Miles Shang<br />

Robin Doherty<br />

Tanya Khovanova<br />

Mike Hearn<br />

Todd Hoff<br />

Seth Godin<br />

Tom Blomfield<br />

Michael Marner<br />

Ossi Hanhinen<br />

Martin Matusiak<br />

4<br />

12<br />

20<br />

24<br />

26<br />

37<br />

45<br />

46<br />

50<br />

54<br />

60<br />

A guide to seed fundraising<br />

So you think you can program an<br />

elevator<br />

Why privacy is important, and<br />

having "nothing to hide" is<br />

irrelevant<br />

The dying art of mental math tricks<br />

The resolution of the Bitcoin<br />

experiment<br />

A beginner's guide to scaling to 11<br />

million+ users On Amazon's AWS<br />

Getting ahead vs. doing well<br />

When to join a startup<br />

Sending and receiving SMS on<br />

Linux<br />

How Elm made our work better<br />

Two weeks of rust<br />

hacker bits<br />

3


STARTUP<br />

A guide to<br />

seed fundraising<br />

By GEOFF RALSTON<br />

Startup companies need to purchase<br />

equipment, rent offices,<br />

and hire staff. More importantly,<br />

they need to grow. In almost<br />

every case they will require outside<br />

capital to do these things.<br />

The initial capital raised by a<br />

company is typically called “seed”<br />

capital. This brief guide is a summary<br />

of what startup founders need<br />

to know about raising the seed<br />

funds critical to getting their company<br />

off the ground.<br />

This is not intended to be a<br />

complete guide to fundraising. It<br />

includes only the basic knowledge<br />

most founders will need. The information<br />

comes from my experiences<br />

“<br />

The process of raising that money is often<br />

long, arduous, complex, and ego deflating.<br />

Nevertheless, it is a path almost all<br />

companies and founders must walk...<br />

4 hacker bits


working at startups, investing in<br />

startups, and advising startups at<br />

Y Combinator and Imagine K12.<br />

YC partners naturally gain a lot<br />

of fundraising experience and YC<br />

founder Paul Graham (PG) has<br />

written extensively on the topic.<br />

His essays cover in more detail<br />

much of what is contained in this<br />

guide and are highly recommended<br />

reading.<br />

“<br />

Why raise money?<br />

...work on your product and<br />

talk to your users.<br />

Without startup funding the vast<br />

majority of startups will die. The<br />

amount of money needed to take<br />

a startup to profitability is usually<br />

well beyond the ability of founders<br />

and their friends and family to<br />

finance.<br />

A startup here means a company<br />

that is built to grow fast. High<br />

growth companies almost always<br />

need to burn capital to sustain their<br />

growth prior to achieving profitability.<br />

A few startup companies<br />

do successfully bootstrap (selffund)<br />

themselves, but they are the<br />

exception. Of course, there are<br />

lots of great companies that aren’t<br />

startups. Managing capital needs<br />

for such companies is not covered<br />

herein.<br />

Cash not only allows startups<br />

to live and grow, a war chest is<br />

also almost always a competitive<br />

advantage in all ways that matter:<br />

hiring key staff, public relations,<br />

marketing, and sales. Thus, most<br />

startups will almost certainly want<br />

to raise money.<br />

The good news is that there are<br />

lots of investors hoping to give the<br />

right startup money. The bad news<br />

is, “Fundraising is brutal”. The process<br />

of raising that money is often<br />

long, arduous, complex, and ego<br />

deflating. Nevertheless, it is a path<br />

almost all companies and founders<br />

must walk, but when is the time<br />

right to raise?<br />

When to raise money<br />

Investors write checks when the<br />

idea they hear is compelling, when<br />

they are persuaded that the team<br />

of founders can realize its vision,<br />

and that the opportunity described<br />

is real and sufficiently large. When<br />

founders are ready to tell this story,<br />

they can raise money. And usually<br />

when you can raise money, you<br />

should.<br />

For some founders it is enough<br />

to have a story and a reputation.<br />

However, for most it will require<br />

an idea, a product, and some<br />

amount of customer adoption,<br />

a.k.a. traction. Luckily, the software<br />

development ecosystem today<br />

is such that a sophisticated web or<br />

mobile product can be built and<br />

delivered in a remarkably short period<br />

of time at very low cost. Even<br />

hardware can be rapidly prototyped<br />

and tested.<br />

But investors also need persuading.<br />

Usually a product they<br />

can see, use, or touch will not be<br />

enough. They will want to know<br />

that there is product market fit and<br />

that the product is experiencing<br />

actual growth.<br />

Therefore, founders should<br />

raise money when they have<br />

figured out what the market opportunity<br />

is and who the customer<br />

is, and when they have delivered<br />

a product that matches their needs<br />

and is being adopted at an inter-<br />

hacker bits<br />

5


“<br />

estingly rapid rate. How rapid is<br />

interesting?<br />

This depends, but a rate of<br />

10% per week for several weeks<br />

is impressive. And to raise money<br />

founders need to impress. For<br />

founders who can convince investors<br />

without these things, congratulations.<br />

For everyone else, work on<br />

your product and talk to your users.<br />

Startup founders must understand the<br />

basic concepts behind venture financing.<br />

How much to raise?<br />

Ideally, you should raise as much<br />

money as you need to reach profitability,<br />

so that you’ll never have to<br />

raise money again. If you succeed<br />

in this, not only will you find it<br />

easier to raise money in the future,<br />

you’ll be able to survive without<br />

new funding if the funding environment<br />

gets tight. That said, certain<br />

kinds of startups will need a follow-on<br />

round, such as those building<br />

hardware. Their goal should be<br />

to raise as much money as needed<br />

to get to their next “fundable” milestone,<br />

which will usually be 12 to<br />

18 months later.<br />

In choosing how much to raise<br />

you are trading off several variables,<br />

including how much progress<br />

that amount of money will<br />

purchase, credibility with investors,<br />

and dilution. If you can manage<br />

to give up as little as 10% of your<br />

company in your seed round, that<br />

is wonderful, but most rounds will<br />

require up to 20% dilution and<br />

you should try to avoid more than<br />

25%. In any event, the amount<br />

you are asking for must be tied to<br />

a believable plan. That plan will<br />

buy you the credibility necessary<br />

to persuade investors that their<br />

money will have a chance to grow.<br />

It is usually a good idea to create<br />

multiple plans assuming different<br />

amounts raised and to carefully<br />

articulate your belief that the company<br />

will be successful whether<br />

you raise the full or some lesser<br />

amount. The difference will be how<br />

fast you can grow.<br />

One way to look at the optimal<br />

amount to raise in your first round<br />

is to decide how many months<br />

of operation you want to fund. A<br />

rule of thumb is that an engineer<br />

(the most common early employee<br />

for Silicon Valley startups) costs<br />

all-in about $15k per month. So,<br />

if you would like to be funded for<br />

18 months of operations with an<br />

average of five engineers, then<br />

you will need about 15k x 5 x 18 =<br />

$1.35mm. What if you are planning<br />

to hire for other positions as well?<br />

Don’t worry about it! This is just<br />

an estimate and will be accurate<br />

enough for whatever mix you hire.<br />

And here you have a great answer<br />

to the question: “How much are<br />

you raising?” Simply answer that<br />

you are raising for N months (usually<br />

12-18) and will thus need $X,<br />

where X will usually be between<br />

$500k and $1.5 million. As noted<br />

above, you should give multiple<br />

versions of N and a range for X,<br />

giving different possible growth<br />

scenarios based on how much you<br />

successfully raise.<br />

There is enormous variation<br />

in the amount of money raised<br />

by companies. Here we are concerned<br />

with early raises, which<br />

usually range from a few hundreds<br />

of thousands of dollars up to two<br />

million dollars. Most first rounds<br />

seem to cluster around six hundred<br />

thousand dollars, but largely<br />

thanks to increased interest from<br />

investors in seed, these rounds have<br />

been increasing in size over the last<br />

several years.<br />

Financing options<br />

Startup founders must understand<br />

the basic concepts behind venture<br />

financing. It would be nice if this<br />

was all very simple and could be<br />

explained in a single paragraph.<br />

Unfortunately, as with most legal<br />

matters, that’s not possible. Here<br />

is a very high level summary, but<br />

it is worth your time to read more<br />

about the details and pros and cons<br />

of various types of financing and,<br />

importantly, the key terms of such<br />

deals that you need to be aware of,<br />

from preferences to option pools.<br />

The articles below are a decent<br />

start.<br />

• Venture Hacks / Babk Nivi:<br />

6 hacker bits


Should I Raise Debt or Equity<br />

• Fred Wilson: Financing Options<br />

• Mark Suster on Convertible<br />

Debt, Announcing the Safe<br />

Venture financing usually takes<br />

place in “rounds,” which have traditionally<br />

had names and a specific<br />

order. First comes a seed round,<br />

then a Series A, then a Series<br />

B, then a Series C, and so on to<br />

acquisition or IPO. None of these<br />

rounds are required and, for example,<br />

sometimes companies will start<br />

with a Series A financing (almost<br />

always an “equity round” as defined<br />

below). Recall that we are<br />

focusing here exclusively on seed,<br />

that very first venture round.<br />

Most seed rounds, at least in<br />

Silicon Valley, are now structured<br />

as either convertible debt or simple<br />

agreements for future equity<br />

(safes). Some early rounds are still<br />

done with equity, but in Silicon<br />

Valley they are now the exception.<br />

Convertible debt<br />

Convertible debt is a loan an investor<br />

makes to a company using<br />

an instrument called a convertible<br />

note. That loan will have a principal<br />

amount (the amount of the investment),<br />

an interest rate (usually<br />

a minimum rate of 2% or so), and<br />

“<br />

a maturity date (when the principal<br />

and interest must be repaid).<br />

The intention of this note is that<br />

it converts to equity (thus, “convertible”)<br />

when the company does<br />

an equity financing. These notes<br />

will also usually have a “Cap”<br />

or “Target Valuation” and / or a<br />

discount. A Cap is the maximum<br />

effective valuation that the owner<br />

of the note will pay, regardless of<br />

the valuation of the round in which<br />

the note converts. The effect of the<br />

cap is that convertible note investors<br />

usually pay a lower price per<br />

share compared to other investors<br />

in the equity round.<br />

Similarly, a discount defines<br />

a lower effective valuation via a<br />

percentage off the round valuation.<br />

Investors see these as their seed<br />

“premium” and both of these terms<br />

are negotiable. Convertible debt<br />

may be called at maturity, at which<br />

time it must be repaid with earned<br />

interest, although investors are<br />

often willing to extend the maturity<br />

dates on notes.<br />

Safe<br />

Convertible debt has been almost<br />

completely replaced by the safe at<br />

YC and Imagine K12. A safe acts<br />

like convertible debt without the<br />

interest rate, maturity, and repayment<br />

requirement. The negotiable<br />

terms of a safe will almost always<br />

be simply the amount, the cap, and<br />

the discount, if any. There is a bit<br />

more complexity to any convertible<br />

security, and much of that is driven<br />

by what happens when conversion<br />

occurs. I strongly encourage you to<br />

read the safe primer, which is available<br />

on YC’s site. The primer has<br />

several examples of what happens<br />

when a safe converts, which go a<br />

long way toward explaining how<br />

both convertible debt and safes<br />

work in practice.<br />

Equity<br />

An equity round means setting a<br />

valuation for your company (generally,<br />

the cap on the safes or notes is<br />

considered as a company’s notional<br />

valuation, although notes and safes<br />

can also be uncapped) and thus a<br />

per-share price, and then issuing<br />

and selling new shares of the company<br />

to investors. This is always<br />

more complicated, expensive,<br />

and time consuming than a safe<br />

or convertible note and explains<br />

their popularity for early rounds. It<br />

is also why you will always want<br />

to hire a lawyer when planning to<br />

issue equity.<br />

To understand what happens<br />

when new equity is issued, a<br />

...whatever form of financing you do, it is<br />

always best to use well-known financing<br />

documents.<br />

hacker bits<br />

7


simple example helps. Say you<br />

raise $1,000,000 on a $5,000,000<br />

pre-money valuation. If you also<br />

have 10,000,000 shares outstanding<br />

then you are selling the shares at:<br />

1. $5,000,000 / 10,000,000 = 50<br />

cents per share*<br />

and you will thus sell…<br />

2. 2,000,000 shares<br />

resulting in a new share total<br />

of…<br />

3. 10,000,000 + 2,000,000 =<br />

12,000,000 shares<br />

and a post-money valuation<br />

of…<br />

4. $0.50 * 12,000,000 =<br />

$6,000,000<br />

and dilution of…<br />

5. 2,000,000 / 12,000,000 =<br />

16.7%<br />

Not 20%!<br />

There are several important components<br />

of an equity round with<br />

which you must become familiar<br />

when your company does a priced<br />

round, including equity incentive<br />

plans (option pools), liquidation<br />

preferences, anti-dilution rights,<br />

protective provisions, and more.<br />

These components are all negotiable,<br />

but it is usually the case that if<br />

you have agreed upon a valuation<br />

with your investors (next section),<br />

then you are not too far apart, and<br />

there is a deal to be done. I won’t<br />

say more about equity rounds,<br />

since they are so uncommon for<br />

seed rounds.<br />

One final note: whatever form<br />

of financing you do, it is always<br />

best to use well-known financing<br />

documents like YC’s safe. These<br />

documents are well understood by<br />

the investor community, and have<br />

been drafted to be fair, yet founder<br />

friendly.<br />

Valuation: What is my<br />

company worth?<br />

You are two hackers with an idea,<br />

a few months of hacking’s worth of<br />

software, and several thousand users.<br />

What is your company worth?<br />

It should be obvious that no formula<br />

will give you an answer. There<br />

can only be the most notional sort<br />

of justification for any value at all.<br />

So, how do you set a value when<br />

talking to a potential investor?<br />

Why do some companies seem to<br />

be worth $20mm and some $4mm?<br />

Because investors were convinced<br />

that was what they were (or will<br />

be in the near future) worth. It is<br />

that simple. Therefore, it is best to<br />

let the market set your price and<br />

to find an investor to set the price<br />

or cap. The more investor interest<br />

your company generates, the higher<br />

your value will trend.<br />

Still, it can be difficult in some<br />

circumstances to find an investor to<br />

tell you what you are worth. In this<br />

“<br />

case you can choose a valuation,<br />

usually by looking at comparable<br />

companies who have valuations.<br />

Please remember that the important<br />

thing in choosing your valuation is<br />

not to over-optimize. The objective<br />

is to find a valuation with which<br />

you are comfortable, that will allow<br />

you to raise the amount you need to<br />

achieve your goals with acceptable<br />

dilution, and that investors will find<br />

reasonable and attractive enough to<br />

write you a check. Seed valuations<br />

tend to range from $2mm-$10mm,<br />

but keep in mind that the goal is<br />

not to achieve the best valuation,<br />

nor does a high valuation increase<br />

your likelihood of success.<br />

Investors: Angels & venture<br />

capitalists<br />

The difference between an angel<br />

and a VC is that angels are amateurs<br />

and VCs are pros. VCs invest<br />

other people’s money and angels<br />

invest their own on their own<br />

terms. Although some angels are<br />

quite rigorous and act very much<br />

like the pros, for the most part they<br />

are much more like hobbyists.<br />

Their decision making process is<br />

...by far the best way to<br />

meet a venture capitalist<br />

or an angel is via a warm<br />

introduction.<br />

8 hacker bits


“<br />

usually much faster–they can make<br />

the call all on their own–and there<br />

is almost always a much larger<br />

component of emotion that goes<br />

into that decision.<br />

VCs will usually require more<br />

time, more meetings, and will have<br />

multiple partners involved in the<br />

final decision. And remember, VCs<br />

see LOTS of deals and invest in<br />

very few, so you will have to stand<br />

out from a crowd.<br />

The ecosystem for seed (early)<br />

financing is far more complex now<br />

than it was even five years ago.<br />

There are many new VC firms,<br />

sometimes called “super-angels,”<br />

or “micro-VC’s”, which explicitly<br />

target brand new, very early stage<br />

companies. There are also several<br />

traditional VCs that will invest in<br />

seed rounds. And there are a large<br />

number of independent angels who<br />

will invest anywhere from $25k to<br />

$100k or more in individual companies.<br />

New fundraising options<br />

seem to arrive every year, for<br />

example, AngelList Syndicates in<br />

which angels pool their resources<br />

and follow a single lead angel.<br />

How does one meet and encourage<br />

the interest of investors? If<br />

you are about to present at a demo<br />

day, you are going to meet lots<br />

of investors. There are few such<br />

opportunities to meet a concentrated<br />

and motivated group of seed<br />

Always optimize for getting money<br />

soonest (in other words, be greedy).<br />

investors. Besides a demo day, by<br />

far the best way to meet a venture<br />

capitalist or an angel is via a warm<br />

introduction. Angels will also often<br />

introduce interesting companies<br />

to their own networks. Otherwise,<br />

find someone in your network to<br />

make an introduction to an angel or<br />

VC. If you have no other options,<br />

do research on VCs and angels and<br />

send as many as you can a brief,<br />

but compelling summary of your<br />

business and opportunity (see Documents<br />

You Need below).<br />

Crowdfunding<br />

There are a growing number of<br />

new vehicles to raise money,<br />

such as AngelList, Kickstarter,<br />

FundersClub, and Wefunder. These<br />

crowdfunding sites can be used to<br />

launch a product, run a pre-sales<br />

campaign, or find venture funding.<br />

In exceptional cases, founders have<br />

used these sites as their dominant<br />

fundraising source, or as clear<br />

evidence of demand. They usually<br />

are used to fill in rounds that are<br />

largely complete or, at times, to<br />

reanimate a round that is having<br />

difficulty getting off the ground.<br />

The ecosystem around investing<br />

is changing rapidly, but when and<br />

how to use these new sources of<br />

funds will usually be determined<br />

by your success raising through<br />

more traditional means.<br />

Meeting investors<br />

If you are meeting investors at an<br />

investor day, remember that your<br />

goal is not to close–it is to get the<br />

next meeting. Investors will seldom<br />

choose to commit the first day they<br />

hear your pitch, regardless of how<br />

brilliant it is. So book lots of meetings.<br />

Keep in mind that the hardest<br />

part is to get the first money in the<br />

company. In other words, meet<br />

as many investors as possible but<br />

focus on those most likely to close.<br />

Always optimize for getting money<br />

soonest (in other words, be greedy).<br />

There are a few simple rules<br />

to follow when preparing to meet<br />

with investors. First, make sure you<br />

know your audience–do research<br />

on what they like to invest in and<br />

try to figure out why. Second, simplify<br />

your pitch to the essential–<br />

why this is a great product (demos<br />

are almost a requirement nowadays),<br />

why you are precisely the<br />

right team to build it, and why together<br />

you should all dream about<br />

creating the next gigantic company.<br />

Next make sure you listen carefully<br />

to what the investor has to say.<br />

If you can get the investor to talk<br />

more than you, your probability of<br />

a deal skyrockets. In the same vein,<br />

do what you can to connect with<br />

the investor. This is one of the main<br />

reasons to do research. An investment<br />

in a company is a long term<br />

hacker bits<br />

9


commitment and most investors see<br />

lots of deals. Unless they like you<br />

and feel connected to your outcome,<br />

they will most certainly not<br />

write a check.<br />

Who you are and how well you<br />

tell your story are most important<br />

when trying to convince investors<br />

to write that check. Investors are<br />

looking for compelling founders<br />

who have a believable dream and<br />

as much evidence as possible documenting<br />

the reality of that dream.<br />

Find a style that works for you,<br />

and then work as hard as necessary<br />

to get the pitch perfect. Pitching<br />

is difficult and often unnatural<br />

for founders, especially technical<br />

founders who are more comfortable<br />

in front of a screen than a crowd.<br />

But anyone will improve with<br />

practice, and there is no substitute<br />

for an extraordinary amount of<br />

practice. Incidentally, this is true<br />

whether you are preparing for a<br />

demo day or an investor meeting.<br />

During your meeting, try to<br />

strike a balance between confidence<br />

and humility. Never cross<br />

over into arrogance, avoid defensiveness,<br />

but also don’t be a pushover.<br />

Be open to intelligent counterpoints,<br />

but stand up for what you<br />

believe and whether or not you persuade<br />

the investor just then, you’ll<br />

have made a good impression and<br />

will probably get another shot.<br />

Lastly, make sure you don’t<br />

leave an investor meeting without<br />

...it is almost always better not<br />

“to try to negotiate in real-time.<br />

an attempted close or at very minimum<br />

absolute clarity on next steps.<br />

Do not just walk out leaving things<br />

ambiguous.<br />

Negotiating and closing the<br />

deal<br />

A seed investment can usually be<br />

closed rapidly. As noted above,<br />

it is an advantage to use standard<br />

documents with consistent terms,<br />

such as YC’s safe. Negotiation, and<br />

often there is none at all, can then<br />

proceed on one or two variables,<br />

such as the valuation/cap and possibly<br />

a discount.<br />

Deals have momentum and<br />

there is no recipe towards building<br />

momentum behind your deal<br />

other than by telling a great story,<br />

persistence, and legwork. You may<br />

have to meet with dozens of investors<br />

before you get that close. But<br />

to get started you just need to convince<br />

one of them. Once the first<br />

money is in, each subsequent close<br />

will get faster and easier.<br />

Once an investor says that they<br />

are in, you are almost done. This<br />

is where you should rapidly close<br />

using a handshake protocol. If you<br />

fail at negotiating from this point<br />

on, it is probably your fault.<br />

Negotiations<br />

When you enter into a negotiation<br />

with a VC or an angel, remember<br />

that they are usually more experienced<br />

at it than you are, so it is<br />

almost always better not to try to<br />

negotiate in real-time. Take requests<br />

away with you, and get help<br />

from YC or Imagine K12 partners,<br />

advisors, or legal counsel. But also<br />

remember that although certain<br />

requested terms can be egregious,<br />

the majority of things credible VCs<br />

and angels will ask for tend to be<br />

reasonable. Do not hesitate to ask<br />

them to explain precisely what<br />

they are asking for and why. If the<br />

negotiation is around valuation (or<br />

cap) there are, naturally, plenty of<br />

considerations, e.g. other deals you<br />

have already closed. However, it<br />

is important to remember that the<br />

valuation you choose at this early<br />

round will seldom matter to the<br />

success or failure of the company.<br />

Get the best deal you can get–but<br />

get the deal! Finally, once you get<br />

to yes, don’t wait around. Get the<br />

investor’s signature and cash as<br />

soon as possible. One reason safes<br />

are popular is because the closing<br />

mechanics are as simple as signing<br />

a document and then transferring<br />

funds. Once an investor has decided<br />

to invest, it should take no longer<br />

than a few minutes to exchange<br />

signed documents online (for example<br />

via Clerky or Ironclad) and<br />

execute a wire or send a check.<br />

10 hacker bits


Documents you need<br />

Do not spend too much time developing<br />

diligence documents for a<br />

seed round. If an investor is asking<br />

for too much due diligence or<br />

financials, they are almost certainly<br />

someone to avoid. You will probably<br />

want an executive summary<br />

and a slide deck you can walk<br />

investors through and, potentially,<br />

leave behind so VCs can show to<br />

other partners.<br />

The executive summary should<br />

be one or two pages (one is better)<br />

and should include vision, product,<br />

team (location, contact info),<br />

traction, market size, and minimum<br />

financials (revenue, if any, and<br />

fundraising prior and current).<br />

Generally make sure the slide<br />

deck is a coherent leave-behind.<br />

Graphics, charts, screenshots are<br />

more powerful than lots of words.<br />

Consider it a framework around<br />

which you will hang a more detailed<br />

version of your story. There<br />

is no fixed format or order, but the<br />

following parts are usually present.<br />

Create the pitch that matches you,<br />

how you present, and how you<br />

want to represent your company.<br />

Also note that like the executive<br />

summary, there are lots of similar<br />

templates online if you don’t like<br />

this one.<br />

1. Your company / Logo / Tag<br />

Line<br />

2. Your Vision - Your most<br />

expansive take on why your<br />

Next<br />

new company exists.<br />

3. The Problem - What are you<br />

solving for the customer–<br />

where is their pain?<br />

4. The Customer - Who are they<br />

and perhaps how will you<br />

reach them?<br />

5. The Solution - What you have<br />

created and why now is the<br />

right time.<br />

6. The (huge) Market you are<br />

addressing - Total Available<br />

Market (TAM) >$1B if possible.<br />

Include the most persuasive<br />

evidence you have that<br />

this is real.<br />

7. Market Landscape - including<br />

competition, macro trends,<br />

etc. Is there any insight you<br />

have that others do not?<br />

8. Current Traction - list key<br />

stats / plans for scaling and<br />

future customer acquisition.<br />

9. Business model - how users<br />

translate to revenue. Actuals,<br />

plans, hopes.<br />

10. Team - who you are, where<br />

you come from and why you<br />

have what it takes to succeed.<br />

Pics and bios okay. Specify<br />

roles.<br />

11. Summary - 3-5 key takeaways<br />

(market size, key product<br />

insight, traction)<br />

12. Fundraising - Include what<br />

you have already raised and<br />

what you are planning to raise<br />

now. Any financial projections<br />

may go here as well.<br />

You can optionally include a<br />

summary product roadmap (6<br />

quarters max) indicating what<br />

an investment buys.<br />

It is worth pointing out that startup<br />

investing is rapidly evolving and<br />

it is likely that certain elements<br />

of this guide will at some point<br />

become obsolete, so make sure to<br />

check for updates or future posts.<br />

There is now an extraordinary<br />

amount of information available<br />

on raising venture money. Several<br />

sources are referenced and more<br />

are listed at the end of this document.<br />

Fundraising is a necessary, and<br />

sometimes painful task most startups<br />

must periodically endure. A<br />

founder’s goal should always be to<br />

raise as quickly as possible and this<br />

guide will hopefully help founders<br />

successfully raise their first round<br />

of venture financing. Often that<br />

will seem like a nearly impossible<br />

task and when it is complete, it will<br />

feel as though you have climbed a<br />

very steep mountain. But you have<br />

been distracted by the brutality of<br />

fundraising and once you turn your<br />

attention back to the future you will<br />

realize it was only a small foothill<br />

on the real climb in front of you. It<br />

is time to get back to work building<br />

your company. •<br />

Geoff has been an investor in, board<br />

member of, and advisor to a variety of<br />

start-up companies, mostly in the San<br />

Francisco Bay Area. He is also a partner at<br />

Y Combinator.<br />

Reprinted with permission of the original author. First appeared at themacro.com.<br />

hacker bits<br />

11


PROGRAMMING<br />

So you think you can program<br />

an elevator<br />

By MILES SHANG<br />

Many of us ride elevators every day. We feel<br />

like we understand how they work, how<br />

they decide where to go. If you were asked<br />

to put it into words, you might say that an elevator<br />

goes wherever it's told, and in doing so goes as far in<br />

one direction as it can before turning around. Sounds<br />

simple, right? Can you put it into code?<br />

In this challenge, you are asked to implement the<br />

business logic for a simplified elevator model in Python.<br />

We'll ignore a lot of what goes into a real world<br />

elevator, like physics, maintenance overrides, and<br />

optimizations for traffic patterns. All you are asked to<br />

do is to decide whether the elevator should go up, go<br />

down, or stop.<br />

How does the challenge work? The simulator and<br />

test harness are laid out in this document, followed by<br />

several examples. All of this can be run in an actual<br />

Python interpreter using Python's built-in doctest<br />

12 hacker bits


Open a pull request with your solution. Good<br />

luck! Have fun!<br />

Test harness<br />

Like all elevators, ours can go up and down. We define<br />

constants for these. The elevator also happens to<br />

be in a building with six floors.<br />

>>> UP = 1<br />

>>> DOWN = 2<br />

>>> FLOOR_COUNT = 6<br />

We will make an Elevator class that simulates an elevator.<br />

It will delegate to another class which contains<br />

the elevator business logic, i.e. deciding what the<br />

elevator should do. Your challenge is to implement<br />

this business logic class.<br />

User actions<br />

A user can interact with the elevator in two ways. She<br />

can call the elevator by pressing the up or down button<br />

on any floor, and she can select a destination floor<br />

by pressing the button for that floor on the panel in<br />

the elevator. Both of these actions are passed straight<br />

through to the logic delegate.<br />

>>> class Elevator(object):<br />

... def call(self, floor, direction):<br />

... self._logic_delegate.on_<br />

called(floor, direction)<br />

...<br />

... def select_floor(self, floor):<br />

... self._logic_delegate.on_floor_<br />

selected(floor)<br />

functionality, which extracts the code in this document<br />

and runs it.<br />

A naive implementation of the business logic is<br />

provided in the elevator.py file in this project. If<br />

you run doctest using the provided implementation,<br />

several examples fail to produce the expected output.<br />

Your challenge is to fix that implementation until all of<br />

the examples pass.<br />

Elevator actions<br />

The logic delegate can respond by setting the elevator<br />

to move up, move down, or stop. It can also read the<br />

current floor and movement direction of the elevator.<br />

These actions are accessed through Callbacks, a<br />

mediator provided by the Elevator class to the logic<br />

delegate.<br />

>>> class Elevator(Elevator):<br />

hacker bits<br />

13


... def __init__(self, logic_delegate,<br />

starting_floor=1):<br />

... self._current_floor = starting_<br />

floor<br />

... print "%s..." % starting_floor,<br />

... self._motor_direction = None<br />

... self._logic_delegate = logic_<br />

delegate<br />

... self._logic_delegate.callbacks<br />

= self.Callbacks(self)<br />

...<br />

... class Callbacks(object):<br />

... def __init__(self, outer):<br />

... self._outer = outer<br />

...<br />

... @property<br />

... def current_floor(self):<br />

... return self._outer._<br />

current_floor<br />

...<br />

... @property<br />

... def motor_direction(self):<br />

... return self._outer._motor_<br />

direction<br />

...<br />

... @motor_direction.setter<br />

... def motor_direction(self,<br />

direction):<br />

... self._outer._motor_<br />

direction = direction<br />

That's it for the framework.<br />

Business logic<br />

As for the business logic, an example implementation<br />

is provided in the elevator.py file in this project.<br />

>>> from elevator import ElevatorLogic<br />

As provided, it doesn't pass the tests in this document.<br />

Your challenge is to fix it so that it does. To run the<br />

tests, run this in your shell:<br />

python -m doctest -v README.md<br />

With the correct business logic, here's how the elevator<br />

should behave:<br />

Basic usage<br />

Make an elevator. It starts at the first floor.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

Somebody on the fifth floor wants to go down.<br />

>>> e.call(5, DOWN)<br />

Keep in mind that the simulation won't actually advance<br />

until we call step or one of the run_until_*<br />

methods.<br />

>>> e.run_until_stopped()<br />

2... 3... 4... 5...<br />

The elevator went up to the fifth floor. A passenger<br />

boards and wants to go to the first floor.<br />

>>> e.select_floor(1)<br />

Also, somebody on the third floor wants to go down.<br />

>>> e.call(3, DOWN)<br />

Even though the first floor was selected first, the elevator<br />

services the call at the third floor...<br />

>>> e.run_until_stopped()<br />

4... 3...<br />

...before going to the first floor.<br />

>>> e.run_until_stopped()<br />

2... 1...<br />

Directionality<br />

Elevators want to keep going in the same direction.<br />

An elevator will serve as many requests in one direction<br />

as it can before going the other way. For example,<br />

if an elevator is going up, it won't stop to pick up<br />

passengers who want to go down until it's done with<br />

everything that requires it to go up.<br />

14 hacker bits


e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.call(2, DOWN)<br />

>>> e.select_floor(5)<br />

Even though the elevator was called at the second floor<br />

first, it will service the fifth floor...<br />

>>> e.run_until_stopped()<br />

2... 3... 4... 5...<br />

...before coming back down for the second floor.<br />

>>> e.run_until_stopped()<br />

4... 3... 2...<br />

In fact, if a passenger tries to select a floor that contradicts<br />

the current direction of the elevator, that selection<br />

is ignored entirely. You've probably seen this before.<br />

You call the elevator to go down. The elevator shows<br />

up, and you board, not realizing that it's still going up.<br />

You select a lower floor. The elevator ignores you.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.select_floor(3)<br />

>>> e.select_floor(5)<br />

>>> e.run_until_stopped()<br />

2... 3...<br />

>>> e.select_floor(2)<br />

At this point the elevator is at the third floor. It's not<br />

finished going up because it's wanted at the fifth floor.<br />

Therefore, selecting the second floor goes against the<br />

current direction, so that request is ignored.<br />

>>> e.run_until_stopped()<br />

4... 5...<br />

>>> e.run_until_stopped() # nothing<br />

happens, because e.select_floor(2) was<br />

ignored<br />

Now it's done going up, so you can select the second<br />

floor.<br />

>>> e.select_floor(2)<br />

>>> e.run_until_stopped()<br />

4... 3... 2...<br />

Changing direction<br />

The process of switching directions is a bit tricky.<br />

Normally, if an elevator going up stops at a floor and<br />

there are no more requests at higher floors, the elevator<br />

is free to switch directions right away. However, if<br />

the elevator was called to that floor by a user indicating<br />

that she wants to go up, the elevator is bound to<br />

consider itself going up.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.call(2, DOWN)<br />

>>> e.call(4, UP)<br />

>>> e.run_until_stopped()<br />

2... 3... 4...<br />

>>> e.select_floor(5)<br />

>>> e.run_until_stopped()<br />

5...<br />

>>> e.run_until_stopped()<br />

4... 3... 2...<br />

If nobody wants to go further up though, the elevator<br />

can turn around.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.call(2, DOWN)<br />

>>> e.call(4, UP)<br />

>>> e.run_until_stopped()<br />

2... 3... 4...<br />

>>> e.run_until_stopped()<br />

3... 2...<br />

If the elevator is called in both directions at that floor,<br />

it must wait once for each direction. You may have<br />

seen this too. Some elevators will close their doors<br />

and reopen them to indicate that they have changed<br />

direction.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.select_floor(5)<br />

>>> e.call(5, UP)<br />

>>> e.call(5, DOWN)<br />

>>> e.run_until_stopped()<br />

2... 3... 4... 5...<br />

Here, the elevator considers itself to be going up, as it<br />

hacker bits<br />

15


favors continuing in the direction it came from.<br />

>>> e.select_floor(4) # ignored<br />

>>> e.run_until_stopped()<br />

Since nothing caused the elevator to move further up,<br />

it now waits for requests that cause it to move down.<br />

>>> e.select_floor(6) # ignored<br />

>>> e.run_until_stopped()<br />

Since nothing caused the elevator to move down,<br />

the elevator now considers itself idle. It can move in<br />

either direction.<br />

>>> e.select_floor(6)<br />

>>> e.run_until_stopped()<br />

6...<br />

En passant<br />

Keep in mind that a user could call the elevator or<br />

select a floor at any time. The elevator need not be<br />

stopped. If the elevator is called or a floor is selected<br />

before it has reached the floor in question, then the<br />

request should be serviced.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.select_floor(6)<br />

>>> e.run_until_floor(2) # elevator is not<br />

stopped<br />

2...<br />

>>> e.select_floor(3)<br />

>>> e.run_until_stopped() # stops for<br />

above<br />

3...<br />

>>> e.run_until_floor(4)<br />

4...<br />

>>> e.call(5, UP)<br />

>>> e.run_until_stopped() # stops for<br />

above<br />

5...<br />

On the other hand, if the elevator is already at, or has<br />

passed the floor in question, then the request should<br />

be treated like a request in the wrong direction. That<br />

is to say, a call is serviced later, and a floor selection<br />

is ignored.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.select_floor(5)<br />

>>> e.run_until_floor(2)<br />

2...<br />

>>> e.call(2, UP) # missed the boat, come<br />

back later<br />

>>> e.step() # doesn't stop<br />

3...<br />

>>> e.select_floor(3) # missed the boat,<br />

ignored<br />

>>> e.step() # doesn't stop<br />

4...<br />

>>> e.run_until_stopped() # service<br />

e.select_floor(5)<br />

5...<br />

>>> e.run_until_stopped() # service<br />

e.call(2, UP)<br />

4... 3... 2...<br />

Fuzz testing<br />

No amount of legal moves should compel the elevator<br />

to enter an illegal state. Here, we run a bunch of random<br />

requests against the simulator to make sure that<br />

no asserts are triggered.<br />

>>> import random<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> try: print '-', # doctest:+ELLIPSIS<br />

... finally:<br />

... for i in range(100000):<br />

... r = random.randrange(6)<br />

... if r == 0: e.call(<br />

... random.randrange(FLOOR_<br />

COUNT) + 1,<br />

... random.choice((UP, DOWN)))<br />

... elif r == 1: e.select_<br />

floor(random.randrange(FLOOR_COUNT) + 1)<br />

... else: e.step()<br />

- ...<br />

More examples<br />

The rest of these examples may be useful for catching<br />

bugs. They are meant to be run via doctest, so they<br />

may not be very interesting to read through.<br />

An elevator is called but nobody boards. It goes idle.<br />

16 hacker bits


e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.call(5, UP)<br />

>>> e.run_until_stopped()<br />

2... 3... 4... 5...<br />

>>> e.run_until_stopped()<br />

>>> e.run_until_stopped()<br />

The elevator is called at two different floors.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.call(3, UP)<br />

>>> e.call(5, UP)<br />

>>> e.run_until_stopped()<br />

2... 3...<br />

>>> e.run_until_stopped()<br />

4... 5...<br />

Like above, but called in reverse order.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.call(5, UP)<br />

>>> e.call(3, UP)<br />

>>> e.run_until_stopped()<br />

2... 3...<br />

>>> e.run_until_stopped()<br />

4... 5...<br />

The elevator is called at two different floors, but going<br />

the other direction.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.call(3, DOWN)<br />

>>> e.call(5, DOWN)<br />

>>> e.run_until_stopped()<br />

2... 3... 4... 5...<br />

>>> e.run_until_stopped()<br />

4... 3...<br />

The elevator is called at two different floors, going in<br />

opposite directions.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.call(3, UP)<br />

>>> e.call(5, DOWN)<br />

>>> e.run_until_stopped()<br />

2... 3...<br />

>>> e.run_until_stopped()<br />

4... 5...<br />

Like above, but with directions reversed.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.call(3, DOWN)<br />

>>> e.call(5, UP)<br />

>>> e.run_until_stopped()<br />

2... 3... 4... 5...<br />

>>> e.run_until_stopped()<br />

4... 3...<br />

The elevator is called at two different floors, one<br />

above the current floor and one below. It first goes to<br />

the floor where it was called first.<br />

>>> e = Elevator(ElevatorLogic(), 3)<br />

3...<br />

>>> e.call(2, UP)<br />

>>> e.call(4, UP)<br />

>>> e.run_until_stopped()<br />

2...<br />

>>> e.run_until_stopped()<br />

3... 4...<br />

Like above, but called in reverse order.<br />

>>> e = Elevator(ElevatorLogic(), 3)<br />

3...<br />

>>> e.call(4, UP)<br />

>>> e.call(2, UP)<br />

>>> e.run_until_stopped()<br />

4...<br />

>>> e.run_until_stopped()<br />

3... 2...<br />

The elevator is called while it's already moving.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.call(5, UP)<br />

>>> e.run_until_floor(2)<br />

2...<br />

>>> e.call(3, UP)<br />

>>> e.run_until_stopped()<br />

3...<br />

hacker bits<br />

17


e.run_until_stopped()<br />

4... 5...<br />

If the elevator is already at, or has passed the floor<br />

where it was called, it comes back later.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.call(5, UP)<br />

>>> e.run_until_floor(3)<br />

2... 3...<br />

>>> e.call(3, UP)<br />

>>> e.run_until_stopped()<br />

4... 5...<br />

>>> e.run_until_stopped()<br />

4... 3...<br />

Two floors are selected.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.select_floor(3)<br />

>>> e.select_floor(5)<br />

>>> e.run_until_stopped()<br />

2... 3...<br />

>>> e.run_until_stopped()<br />

4... 5...<br />

Like above, but selected in reverse order.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.select_floor(5)<br />

>>> e.select_floor(3)<br />

>>> e.run_until_stopped()<br />

2... 3...<br />

>>> e.run_until_stopped()<br />

4... 5...<br />

Two floors are selected, one above the current floor<br />

and one below. The first selection sets the direction,<br />

so the second one is completely ignored.<br />

>>> e = Elevator(ElevatorLogic(), 3)<br />

3...<br />

>>> e.select_floor(2)<br />

>>> e.select_floor(4)<br />

>>> e.run_until_stopped()<br />

2...<br />

>>> e.run_until_stopped()<br />

Like above, but selected in reverse order.<br />

>>> e = Elevator(ElevatorLogic(), 3)<br />

3...<br />

>>> e.select_floor(4)<br />

>>> e.select_floor(2)<br />

>>> e.run_until_stopped()<br />

4...<br />

>>> e.run_until_stopped()<br />

If the elevator is called to a floor going up, it should<br />

ignore a request to go down.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.call(5, UP)<br />

>>> e.run_until_stopped()<br />

2... 3... 4... 5...<br />

>>> e.select_floor(6)<br />

>>> e.select_floor(4)<br />

>>> e.run_until_stopped()<br />

6...<br />

>>> e.run_until_stopped()<br />

Like above, but going in other direction.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.call(5, DOWN)<br />

>>> e.run_until_stopped()<br />

2... 3... 4... 5...<br />

>>> e.select_floor(6)<br />

>>> e.select_floor(4)<br />

>>> e.run_until_stopped()<br />

4...<br />

>>> e.run_until_stopped()<br />

Elevator is called to a floor and a passenger also selects<br />

the same floor. The elevator should not go back<br />

to that floor twice.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.call(5, DOWN)<br />

>>> e.select_floor(5)<br />

18 hacker bits


e.run_until_stopped()<br />

2... 3... 4... 5...<br />

>>> e.select_floor(4)<br />

>>> e.run_until_stopped()<br />

4...<br />

>>> e.run_until_stopped()<br />

Similarly, if the elevator is called at a floor where it is<br />

stopped, it should not go back later.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.call(3, UP)<br />

>>> e.run_until_stopped()<br />

2... 3...<br />

>>> e.call(3, UP)<br />

>>> e.call(5, DOWN)<br />

>>> e.run_until_stopped()<br />

4... 5...<br />

>>> e.run_until_stopped()<br />

Elevator is ready to change direction, new call causes<br />

it to keep going in same direction.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.call(2, DOWN)<br />

>>> e.call(4, UP)<br />

>>> e.run_until_stopped()<br />

2... 3... 4...<br />

>>> e.call(5, DOWN) # It's not too late.<br />

>>> e.run_until_stopped()<br />

5...<br />

>>> e.run_until_stopped()<br />

4... 3... 2...<br />

When changing directions, wait one step to clear current<br />

direction.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.select_floor(5)<br />

>>> e.call(5, UP)<br />

>>> e.call(5, DOWN)<br />

>>> e.run_until_stopped()<br />

2... 3... 4... 5...<br />

>>> e.select_floor(4) # ignored<br />

>>> e.run_until_stopped()<br />

>>> e.select_floor(6) # ignored<br />

>>> e.select_floor(4)<br />

>>> e.run_until_stopped()<br />

4...<br />

>>> e.run_until_stopped()<br />

Like above, but going in other direction.<br />

>>> e = Elevator(ElevatorLogic(), 6)<br />

6...<br />

>>> e.select_floor(2)<br />

>>> e.call(2, UP)<br />

>>> e.call(2, DOWN)<br />

>>> e.run_until_stopped()<br />

5... 4... 3... 2...<br />

>>> e.select_floor(3) # ignored<br />

>>> e.run_until_stopped()<br />

>>> e.select_floor(1) # ignored<br />

>>> e.select_floor(3)<br />

>>> e.run_until_stopped()<br />

3...<br />

>>> e.run_until_stopped()<br />

If other direction is not cleared, come back.<br />

>>> e = Elevator(ElevatorLogic())<br />

1...<br />

>>> e.select_floor(5)<br />

>>> e.call(5, UP)<br />

>>> e.call(5, DOWN)<br />

>>> e.run_until_stopped()<br />

2... 3... 4... 5...<br />

>>> e.select_floor(6)<br />

>>> e.run_until_stopped()<br />

6...<br />

>>> e.run_until_stopped()<br />

5...<br />

>>> e.select_floor(6) # ignored<br />

>>> e.select_floor(4)<br />

>>> e.run_until_stopped()<br />

4...<br />

>>> e.run_until_stopped() •<br />

Miles was formerly a software engineer at a tech company in<br />

Silicon Valley. Now, he's a recreational hacker based in Winnipeg,<br />

Manitoba, Canada. He likes hacks that are whimsical,<br />

prosaic, and absurd.<br />

Reprinted with permission of the original author. First appeared at github.com/mshang.<br />

hacker bits<br />

19


OPINION<br />

Why privacy is important,<br />

and having "nothing to hide"<br />

is irrelevant<br />

By ROBIN DOHERTY<br />

The governments of Australia,<br />

Germany, the UK and<br />

the US are destroying your<br />

privacy. Some people don’t see the<br />

problem…<br />

“I have nothing to hide, so<br />

why should I care?”<br />

It doesn’t matter if you have<br />

“nothing to hide”. Privacy is a right<br />

granted to individuals that underpins<br />

the freedoms of expression,<br />

association and assembly; all of<br />

which are essential for a free, democratic<br />

society.<br />

The statement from some politicians<br />

that “if you have nothing to<br />

hide then you have nothing to fear”<br />

purposefully misframes the whole<br />

debate.<br />

This affects all of us. We must<br />

care.<br />

"Arguing that you don’t care<br />

about the right to privacy<br />

because you have nothing<br />

to hide is no different than<br />

saying you don’t care about<br />

free speech because you have<br />

20 hacker bits


nothing to say." – Edward<br />

Snowden<br />

Privacy and freedom<br />

Loss of privacy leads to loss of<br />

freedom.<br />

Your freedom of expression<br />

is threatened by the surveillance<br />

of your internet usage – thought<br />

patterns and intentions can be<br />

extrapolated from your website<br />

visits (rightly or wrongly), and the<br />

knowledge that you are being surveilled<br />

can make you less likely to<br />

research a particular topic. You lose<br />

that perspective, and your thought<br />

can be pushed in one direction as<br />

“<br />

of your communications online<br />

and by phone, and your freedom<br />

of assembly is threatened by the<br />

tracking of your location by your<br />

mobile phone. Can we afford to<br />

risk the benefits of free association,<br />

the social change brought by activists<br />

and campaigners, or the right to<br />

protest?<br />

These freedoms are being<br />

eroded, right now. The effects will<br />

worsen over time, as each failure to<br />

exercise our freedom builds upon<br />

the last, and as more people experience<br />

the chilling effects.<br />

Aggregation<br />

<strong>Bits</strong> of information that you might<br />

• where we go,<br />

• who we contact and when,<br />

• and what we do on the internet.<br />

With just a small portion of this<br />

data, off-the-shelf software and<br />

their own spare time, ABC News<br />

readers found Will Ockenden’s<br />

home, workplace and parents’<br />

home.<br />

The intrusion becomes all<br />

the more spectacular when you<br />

consider the data across a whole<br />

population, the massive budgets of<br />

the Five Eyes intelligence agencies,<br />

and the constant progress of<br />

artificial intelligence and big data<br />

analytics.<br />

Your interactions with the<br />

Ask yourself: at every point in history, who<br />

suffers the most from unjustified surveillance?<br />

It is not the privileged, but the vulnerable.<br />

Surveillance is not about safety, it’s about<br />

power. It’s about control.<br />

Edward Snowden<br />

a result. Similarly, when the things<br />

you write online, or communicate<br />

privately to others, are surveilled,<br />

and you self-censor as a result, the<br />

rest of us lose your perspective,<br />

and the development of further<br />

ideas is stifled.<br />

Your freedom of association<br />

is threatened by the surveillance<br />

not feel the need to hide can be<br />

aggregated into a telling profile,<br />

which might include things that<br />

you actually do want to conceal.<br />

In the case of data retention in<br />

Australia, we have given away our<br />

rights to privacy, and now share a<br />

constant stream of:<br />

world around you can reveal your<br />

political and religious beliefs, your<br />

desires, sympathies and convictions,<br />

and things about yourself that<br />

you aren’t even aware of (and they<br />

might be wrong too).<br />

hacker bits<br />

21


Given enough data and time,<br />

your behaviour might even be<br />

predicted.<br />

Societal chilling effects<br />

The combined result of these<br />

second thoughts across the population<br />

is a chilling effect on many<br />

of the activities that are key to a<br />

well-functioning democracy – activism,<br />

journalism, and political<br />

dissent, among others.<br />

We all benefit from progress<br />

that occurs when activists, journalists<br />

and society as a whole are<br />

able to freely engage in political<br />

discourse and dissent. Many of the<br />

positive changes of the last century<br />

were only possible because of these<br />

freedoms. For example, the 1967<br />

referendum on including indigenous<br />

Australians in the census, and<br />

allowing the federal government to<br />

make laws specifically benefiting<br />

indigenous races, was only made<br />

possible by sustained activism<br />

throughout the 1950s and 60s.<br />

Unfortunately, we are already<br />

self-censoring. A 2013 survey of<br />

US writers found that after the<br />

revelations of the NSA’s mass surveillance<br />

regime, 1 in 6 had avoided<br />

writing on a topic they thought<br />

would subject them to surveillance,<br />

and a further 1 in 6 had seriously<br />

considered doing so.<br />

"Ask yourself: at every point<br />

in history, who suffers the<br />

most from unjustified surveillance?<br />

It is not the privileged,<br />

but the vulnerable. Surveillance<br />

is not about safety,<br />

it’s about power. It’s about<br />

control."<br />

– Edward Snowden<br />

Misuse & misappropriation<br />

By creating databases and systems<br />

of easy access to such a great<br />

volume of personally revealing<br />

information, we increase the scope<br />

of mass surveillance, and therefore<br />

the scope for infringements upon<br />

our human rights.<br />

East Germany is the most<br />

extreme example of a surveillance<br />

state in history. The Stasi – its infamous<br />

security agency – employed<br />

90,000 spies and had a network of<br />

at least 174,000 informants. The<br />

Stasi kept meticulous files on hundreds<br />

of thousands of innocent citizens,<br />

including the “pink files” on<br />

people they believed to be homosexual,<br />

and used this information to<br />

psychologically harrass, blackmail<br />

and discredit people who became<br />

dissenters. But that was before the<br />

internet. Reflecting on the NSA’s<br />

current systems of mass surveillance,<br />

a former Stasi lieutenant<br />

colonel said: “for us, this would<br />

have been a dream come true”.<br />

Even aside from the risk of<br />

systematic state misbehaviour, in<br />

Australia we know that the 2500<br />

snoopers who have unrestricted<br />

Privacy is rarely lost in one fell swoop. It is<br />

usually eroded over time, little bits dissolving<br />

almost imperceptibly until we finally begin to<br />

notice how much is gone. “Why Privacy Matters Even if You Have ‘Nothing to Hide’, Daniel J. Solove<br />

22 hacker bits


access to your data are subject to<br />

“professional curiosity”, fallible<br />

morals, and are only human, so will<br />

make mistakes and become victims<br />

of social engineering, blackmail or<br />

bribery.<br />

This is most dangerous for the<br />

most vulnerable people. For example,<br />

if you have an angry or violent<br />

ex-partner, you could be put in<br />

mortal danger by them getting their<br />

hands on this much detail about<br />

your life.<br />

Risk taking<br />

Our “digital lives” are an accurate<br />

reflection of our actual lives. Our<br />

phone records expose where we go<br />

and who we talk to, and our internet<br />

usage can expose almost everything<br />

about ourselves and what we<br />

care about.<br />

Even if we trust the motives of<br />

our current governments, and every<br />

person with authorised access to<br />

our data, we are taking an incredible<br />

risk. The systems of surveillance<br />

that we entrench now may<br />

be misappropriated and misused at<br />

any time by future governments,<br />

foreign intelligence agencies,<br />

double agents, and opportunistic<br />

hackers.<br />

The more data we have, the<br />

more devastating its potential.<br />

Gradual erosion<br />

Each system of surveillance and<br />

intrusion that we introduce erodes<br />

our privacy and pushes us one step<br />

further away from a free society.<br />

While you may not have noticed<br />

the impact yet, your privacy<br />

has already been eroded. If we continue<br />

along our current path, building<br />

more powers into our systems<br />

of surveillance, what was once<br />

your private life will be whittled<br />

away to nothing, and the freedoms<br />

that we have taken for granted will<br />

cease to exist.<br />

As technology advances, we<br />

are presented with a choice – will it<br />

to continue to offer an overall benefit<br />

to society, or will we allow it to<br />

be used as a tool for total intrusion<br />

into our lives?<br />

"Privacy is rarely lost in<br />

one fell swoop. It is usually<br />

eroded over time, little bits<br />

dissolving almost imperceptibly<br />

until we finally begin to<br />

notice how much is gone."<br />

– Why Privacy Matters Even<br />

if You Have ‘Nothing to<br />

Hide’, Daniel J. Solove<br />

What next?<br />

The governments of Australia,<br />

New Zealand, Canada, the US and<br />

others are poised to take a big step<br />

in the wrong direction with the<br />

Trans-Pacific Partnership (TPP).<br />

The EFF explains why the TPP is<br />

a huge threat to your privacy and<br />

other rights.<br />

• Take action – if you are a technologist,<br />

join the Cryptohack<br />

Network and fight back against<br />

mass surveillance – cryptohack.<br />

net.<br />

• Spread the privacy mindset –<br />

we must foster understanding<br />

of this issue in order to protect<br />

ourselves from harmful laws<br />

and fight against future invasions<br />

of privacy. Please help<br />

spread the knowledge, discuss<br />

this article with a friend, tweet<br />

it, share it, etc.<br />

• Protect yourself – protect your<br />

own data from mass surveillance.<br />

This increases the cost<br />

of mass surveillance and helps<br />

others too. Read my advice<br />

on protecting your data from<br />

retention in Australia, the EFF’s<br />

Surveillance Self-Defense<br />

Guide, and Information Security<br />

for Journalists. •<br />

Robin is a consultant at ThoughtWorks.<br />

He usually plays the role of software<br />

developer or technical lead. He tries<br />

to demystify cryptography and digital<br />

privacy by facilitating cryptoparties in<br />

Melbourne. Follow CryptoPartyAus or<br />

him to hear about the next public cryptoparty.<br />

He also organises cryptohack.<br />

net and Melbourne-based meetups, where<br />

software developers gather to contribute to<br />

open source privacy tools like Pixelated,<br />

helping to make them easier to use.<br />

Reprinted with permission of the original author. First appeared at robindoherty.com.<br />

hacker bits<br />

23


INTERESTING<br />

The dying art of<br />

mental math tricks<br />

By TANYA KHOVANOVA<br />

Without using a calculator,<br />

can you tell how much<br />

752 is? If you are reading<br />

my blog, with high probability you<br />

know that it is 5625. The last two<br />

digits of the square of a number<br />

ending in 5 are always 25. So we<br />

only need to figure out the first two<br />

digits. The first two digits equals<br />

7 times 8, or 56, which is the first<br />

digit of the original number (7)<br />

multiplied by the next number (8).<br />

I was good at mental arithmetic<br />

and saved myself a lot of money<br />

back in the Soviet Union. Every<br />

time I shopped I calculated all the<br />

charges as I stood at the cash register.<br />

I knew exactly how much to<br />

pay, which saved me from cheating<br />

cashiers. To simplify my practice,<br />

the shelves were empty, so I was<br />

never buying too many items.<br />

When I moved to the US, the<br />

situation changed. Salespeople are<br />

not trying to cheat, not to mention<br />

that they use automatic cash registers.<br />

In addition, the US sales taxes<br />

are confusing. I remember how I<br />

bought three identical chocolate<br />

bars and the total was not divisible<br />

by 3. So I completely dropped my<br />

at-the-cash-registers mental training.<br />

Being able to calculate fast was<br />

somewhat useful many years ago.<br />

But now there is a calculator on<br />

every phone.<br />

John H. Conway is a master<br />

of mental calculations. He even<br />

invented an algorithm to calculate<br />

the day of the week for any day. He<br />

taught it to me, and I too can easily<br />

calculate that July 29 of 1926 was<br />

Thursday. This is not useful any<br />

more. If I google “what day of the<br />

week is July 29, 1926,” the first<br />

line in big letters says Thursday.<br />

One day a long time ago I<br />

was watching a TV show of a guy<br />

performing mental tricks: remembering<br />

large numbers, multiplying<br />

large numbers, and so on. At the<br />

end, to a grand fanfare, he showed<br />

his crowned trick. A member from<br />

the audience was to write down a<br />

2-digit number, and to raise it to the<br />

fifth power using a calculator. The<br />

mental guy, once he is told what<br />

the fifth power was, struggled with<br />

great concentration and announced<br />

the original number.<br />

I was so underwhelmed. Any-<br />

24 hacker bits


one knows that the last digit of a<br />

number and its fifth power are the<br />

same. So he only needs to guess<br />

the first digit, which can easily be<br />

estimated by the size of the fifth<br />

power.<br />

I found the description of this<br />

trick online. They recommend<br />

memorizing the fifth powers of the<br />

numbers from 1 to 9. After that,<br />

you do the following. First, listen<br />

to the number. Next, the last digit<br />

of the number you hear is the same<br />

as the last digit of the original<br />

number. To figure out the first digit<br />

of the original number, remove the<br />

last 5 digits of the number you hear.<br />

Finally, determine between which<br />

fifth powers it fits. This makes<br />

sense. Or, you could be lazy and<br />

remember only meaningful digits.<br />

For example, 395=90,224,199, and<br />

405=102,400,000. So if the number<br />

is below 100,000,000, then the first<br />

digit is less than 4.<br />

You do not have to remember<br />

the complete fifth powers of every<br />

digit. You just need to remember<br />

significant ranges. Here they are:<br />

first digit range<br />

1 between 100,000 and<br />

3,000,000<br />

2 between 3,000,000<br />

and 24,000,000<br />

3 between 24,000,000,<br />

100,000,000<br />

4 between 100,000,000<br />

and 300,000,000<br />

first digit range<br />

5 between 300,000,000<br />

and 750,000,000<br />

6 between 750,000,000<br />

and 1,600,000,000<br />

7 between<br />

1,600,000,000 and<br />

3,200,000,000<br />

8 between<br />

3,200,000,000, and<br />

5,900,000,000<br />

9 above 5,900,000,000<br />

Besides, for this trick the guy<br />

needed to guess one out of one<br />

hundred number. He had a phenomenal<br />

memory, so he could easily<br />

have remembered one hundred<br />

fifth powers. Actually he doesn’t<br />

need to remember all the numbers,<br />

only the differentiated features. On<br />

this note, there is a cool thing you<br />

can do. You can guess the number<br />

before the whole fifth power is<br />

announced. One caveat: a 1-digit<br />

number x and 10x when taken to<br />

the fifth power, both begin with the<br />

same long string of digits. So we<br />

can advise the audience not to suggest<br />

a 1-digit number or a number<br />

divisible by 10, as that is too easy<br />

(without telling the real reason).<br />

Now we can match a start of<br />

the fifth power to its fifth root.<br />

Three first digits are almost always<br />

enough. Here is the list of starting<br />

digits and their match: (104,16),<br />

(107,64), (115,41), (116,65),<br />

(118,26), (12,66), (130,42),<br />

(135,67), (141,17), (143,27),<br />

(145,68), (147,43), (156,69),<br />

(161,11), (164,44), (17,28),<br />

(180,71), (184,45), (188,18),<br />

(19,72), (2051,29), (2059,46),<br />

(207,73), (221,74), (229,47),<br />

(23,75), (247,19), (248,12),<br />

(253,76), (254,48), (270,77),<br />

(282,49), (286,31), (288,78),<br />

(30,79), (33,32), (345,51),<br />

(348,81), (370,82), (371,13),<br />

(38,52), (391,33), (393,83),<br />

(40,21), (4181,53), (4182,84),<br />

(44,85), (454,34), (459,54),<br />

(470,86), (498,87), (50,55),<br />

(51,22), (525,35), (527,88),<br />

(53,14), (550,56), (558,89),<br />

(601,57), (604,36), (62,91),<br />

(64,23), (656,58), (659,92),<br />

(693,37), (695,93), (71,59),<br />

(73,94), (75,15), (77,95), (792,38),<br />

(796,24), (81,96), (84,61), (85,97),<br />

(902,39), (903,98), (91,62),<br />

(95,99), (97,25), (99,63).<br />

Or, you can come to the mental<br />

guy’s performance and beat him<br />

by shouting out the correct answer<br />

before he can even finish receiving<br />

the last digit. This would be cool<br />

and cruel at the same time. •<br />

Tanya Khovanova is a Lecturer at MIT<br />

and a freelance mathematician. She<br />

received her Ph.D. in Mathematics from<br />

the Moscow State University in 1988. Her<br />

current research interests lie in recreational<br />

mathematics including puzzles, magic<br />

tricks, combinatorics, number theory,<br />

geometry, and probability theory. Her<br />

website is located at tanyakhovanova.<br />

com, her highly popular math blog at blog.<br />

tanyakhovanova.com and her Number<br />

Gossip website at numbergossip.com.<br />

Reprinted with permission of the original author. First appeared at blog.tanyakhovanova.com.<br />

hacker bits<br />

25


FEATURE<br />

The resolution of the<br />

Bitcoin experiment<br />

By MIKE HEARN<br />

I’ve spent more than 5 years<br />

being a Bitcoin developer. The<br />

software I’ve written has been<br />

used by millions of users, hundreds<br />

of developers, and the talks I’ve<br />

given have led directly to the creation<br />

of several startups. I’ve talked<br />

about Bitcoin on Sky TV and<br />

BBC News. I have been repeatedly<br />

cited by the Economist as a Bitcoin<br />

expert and prominent developer. I<br />

have explained Bitcoin to the SEC,<br />

to bankers and to ordinary people I<br />

met at cafes.<br />

From the start, I’ve always said<br />

the same thing: Bitcoin is an experiment<br />

and like all experiments, it<br />

can fail. So don’t invest what you<br />

can’t afford to lose. I’ve said this in<br />

interviews, on stage at conferences,<br />

and over email. So have other well<br />

known developers like Gavin Andresen<br />

and Jeff Garzik.<br />

But despite knowing that<br />

Bitcoin could fail all along, the<br />

now inescapable conclusion that it<br />

has failed still saddens me greatly.<br />

The fundamentals are broken and<br />

whatever happens to the price in<br />

the short term, the long term trend<br />

should probably be downwards.<br />

I will no longer be taking part in<br />

Bitcoin development and have sold<br />

all my coins.<br />

26 hacker bits


Why has Bitcoin failed?<br />

It has failed because the community<br />

has failed. What was meant to be<br />

a new, decentralised form of money<br />

that lacked “systemically important<br />

institutions” and “too big to fail”<br />

has become something even worse:<br />

a system completely controlled by<br />

just a handful of people.<br />

Worse still, the network is on<br />

the brink of technical collapse. The<br />

mechanisms that should have prevented<br />

this outcome have broken<br />

down, and as a result there’s no<br />

longer much reason to think Bitcoin<br />

can actually be better than the<br />

existing financial system.<br />

Think about it. If you had never<br />

heard about Bitcoin before, would<br />

you care about a payments network<br />

that:<br />

• Couldn’t move your existing<br />

money<br />

• Had wildly unpredictable fees<br />

that were high and rising fast<br />

• Allowed buyers to take back<br />

payments they’d made after<br />

walking out of shops, by simply<br />

pressing a button (if you<br />

aren’t aware of this “feature”<br />

that’s because Bitcoin was only<br />

just changed to allow it)<br />

• Is suffering large backlogs and<br />

flaky payments<br />

• … which is controlled by China<br />

• … and in which the companies<br />

and people building it were in<br />

open civil war?<br />

I’m going to hazard a guess<br />

that the answer is no.<br />

Deadlock on the blocks<br />

In case you haven’t been keeping<br />

up with Bitcoin, here is how the<br />

network looks as of January <strong>2016</strong>.<br />

The block chain is full. You<br />

may wonder how it is possible for<br />

what is essentially a series of files<br />

to be “full”. The answer is that an<br />

entirely artificial capacity cap of<br />

one megabyte per block, put in<br />

place as a temporary kludge a long<br />

time ago, has not been removed<br />

and as a result the network’s capacity<br />

is now almost completely<br />

exhausted.<br />

Figure 1 is a graph of block<br />

sizes.<br />

The peak level in July was<br />

reached during a denial-of-service<br />

attack in which someone flooded<br />

the network with transactions in an<br />

Figure 1: Block sizes<br />

hacker bits<br />

27


Figure 2: Weekly average block sizes<br />

attempt to break things, calling it<br />

a “stress test”. So that level, about<br />

700 kilobytes of transactions (or<br />

less than 3 payments per second),<br />

is probably about the limit of what<br />

Bitcoin can actually achieve in<br />

practice.<br />

NB: You may have read that<br />

the limit is 7 payments per second.<br />

That’s an old figure from 2011 and<br />

Bitcoin transactions got a lot more<br />

complex since then, so the true<br />

“<br />

figure is a lot lower.<br />

The reason the true limit seems<br />

to be 700 kilobytes instead of the<br />

theoretical 1000 is that sometimes<br />

miners produce blocks smaller than<br />

allowed and even empty blocks,<br />

despite that there are lots of transactions<br />

waiting to confirm — this<br />

seems to be most frequently caused<br />

by interference from the Chinese<br />

“Great Firewall” censorship system.<br />

More on that in a second.<br />

If you look closely, you can<br />

see that traffic has been growing<br />

since the end of the 2015 summer<br />

months. This is expected. I wrote<br />

about Bitcoin’s seasonal growth<br />

patterns back in March.<br />

Figure 2 is weekly average<br />

block sizes.<br />

So the average is nearly at the<br />

peak of what can be done. Not surprisingly<br />

then, there are frequent<br />

periods in which Bitcoin can’t<br />

You may have read that the limit is<br />

7 payments per second. That’s an old figure<br />

from 2011 and Bitcoin transactions got a lot<br />

more complex since then, so the true figure<br />

is a lot lower.<br />

28 hacker bits


Figure 3: Recent blocks<br />

keep up with the transaction load<br />

being placed upon it and almost all<br />

blocks are the maximum size, even<br />

when there is a long queue of transactions<br />

waiting. You can see this in<br />

the size column (the 750kb blocks<br />

come from miners that haven’t<br />

properly adjusted their software) in<br />

Figure 3.<br />

When networks run out of<br />

capacity, they get really unreliable.<br />

That’s why so many online attacks<br />

are based around simply flooding<br />

a target computer with traffic. Sure<br />

enough, just before Christmas payments<br />

started to become unreliable<br />

and at peak times backlogs are now<br />

becoming common.<br />

Quoting a news post by Pro-<br />

Hashing, a Bitcoin-using business:<br />

Some customers contacted<br />

Chris earlier today asking<br />

why our bitcoin payouts<br />

didn’t execute …<br />

The issue is that it’s now officially<br />

impossible to depend<br />

upon the bitcoin network<br />

anymore to know when or if<br />

your payment will be transacted,<br />

because the congestion<br />

is so bad that even minor<br />

spikes in volume create<br />

dramatic changes in network<br />

conditions. To whom is it acceptable<br />

that one could wait<br />

either 60 minutes or 14 hours,<br />

chosen at random?<br />

It’s ludicrous that people are<br />

actually writing posts on<br />

reddit claiming that there is<br />

no crisis. People were criticizing<br />

my post yesterday on<br />

the grounds that I somehow<br />

overstated the seriousness of<br />

the situation. Do these people<br />

actually use the bitcoin network<br />

to send money everyday?<br />

ProHashing encountered another<br />

near-miss between Christmas<br />

and New Year, this time because a<br />

payment from an exchange to their<br />

wallet was delayed.<br />

Bitcoin is supposed to respond<br />

to this situation with automatic fee<br />

rises to try and get rid of some users,<br />

and although the mechanisms<br />

hacker bits<br />

29


“<br />

When parts of the community are<br />

viciously turning on the people that<br />

have introduced millions of users to<br />

the currency, you know things have got<br />

really crazy.<br />

behind it are barely functional<br />

that’s still sort of happening: it is<br />

rapidly becoming more and more<br />

expensive to use the Bitcoin network.<br />

Once upon a time, Bitcoin<br />

had the killer advantage of low<br />

and even zero fees, but it’s now<br />

common to be asked to pay more<br />

to miners than a credit card would<br />

charge.<br />

Why has the capacity limit not been<br />

raised?<br />

Because the block chain is controlled<br />

by Chinese miners, just two<br />

of whom control more than 50% of<br />

the hash power. At a recent conference<br />

over 95% of hashing power<br />

was controlled by a handful of<br />

guys sitting on a single stage. The<br />

miners are not allowing the block<br />

chain to grow.<br />

Why are they not allowing it to<br />

grow?<br />

Several reasons. One is that<br />

the developers of the “Bitcoin<br />

Core” software that they run have<br />

refused to implement the necessary<br />

changes. Another is that the miners<br />

refuse to switch to any competing<br />

product, as they perceive doing so<br />

as “disloyalty” —and they’re terrified<br />

of doing anything that might<br />

make the news as a “split” and<br />

cause investor panic. They have<br />

chosen instead to ignore the problem<br />

and hope it goes away.<br />

And the final reason is that the<br />

Chinese internet is so broken by<br />

their government’s firewall that<br />

moving data across the border<br />

barely works at all, with speeds<br />

routinely worse than what mobile<br />

phones provide. Imagine an entire<br />

country connected to the rest<br />

of the world by cheap hotel wifi,<br />

and you’ve got the picture. Right<br />

now, the Chinese miners are able<br />

to — just about — maintain their<br />

connection to the global internet<br />

and claim the 25 BTC reward<br />

($11,000) that each block they create<br />

gives them. But if the Bitcoin<br />

network got more popular, they<br />

fear taking part would get too difficult<br />

and they’d lose their income<br />

stream. This gives them a perverse<br />

financial incentive to actually try<br />

and stop Bitcoin becoming popular.<br />

Many Bitcoin users and observers<br />

have been assuming up until<br />

very recently that somehow these<br />

problems would all sort themselves<br />

out, and of course the block chain<br />

size limit would be raised. After all,<br />

why would the Bitcoin community<br />

… the community that has championed<br />

the block chain as the future<br />

of finance … deliberately kill itself<br />

by strangling the chain in its crib?<br />

But that’s exactly what is happening.<br />

The resulting civil war has<br />

seen Coinbase — the largest and<br />

best known Bitcoin startup in the<br />

USA — be erased from the official<br />

Bitcoin website for picking the<br />

“wrong” side and banned from the<br />

community forums. When parts<br />

of the community are viciously<br />

turning on the people that have<br />

introduced millions of users to the<br />

currency, you know things have got<br />

really crazy.<br />

Nobody knows what’s<br />

going on<br />

If you haven’t heard much<br />

about this, you aren’t alone. One<br />

of the most disturbing things that<br />

took place over the course of 2015<br />

is that the flow of information to<br />

investors and users has dried up.<br />

In the span of only about eight<br />

months, Bitcoin has gone from<br />

being a transparent and open community<br />

to one that is dominated by<br />

rampant censorship and attacks on<br />

30 hacker bits


itcoiners by other bitcoiners. This<br />

transformation is by far the most<br />

appalling thing I have ever seen,<br />

and the result is that I no longer<br />

feel comfortable being associated<br />

with the Bitcoin community.<br />

Bitcoin is not intended to be an<br />

investment and has always been<br />

advertised pretty accurately: as an<br />

experimental currency which you<br />

shouldn’t buy more of than you can<br />

afford to lose. It is complex, but<br />

that never worried me because all<br />

the information an investor might<br />

want was out there, and there’s an<br />

entire cottage industry of books,<br />

conferences, videos and websites<br />

to help people make sense of it all.<br />

That has now changed.<br />

Most people who own Bitcoin<br />

learn about it through<br />

“<br />

the mainstream<br />

media.<br />

Whenever a story<br />

goes mainstream<br />

the Bitcoin price<br />

goes crazy, then<br />

the media report<br />

on the price rises<br />

and a bubble happens.<br />

Stories about<br />

Bitcoin reach newspapers and magazines<br />

through a simple process:<br />

the news starts in a community forum,<br />

then it’s picked up by a more<br />

specialised community/tech news<br />

website, then journalists at general<br />

media outlets see the story on those<br />

sites and write their own versions.<br />

I’ve seen this happen over and over<br />

again, and frequently taken part in<br />

it by discussing stories with journalists.<br />

In August 2015 it became clear<br />

that due to severe mismanagement,<br />

the “Bitcoin Core” project that<br />

maintains the program that runs the<br />

peer-to-peer network wasn’t going<br />

to release a version that raised<br />

the block size limit. The reasons<br />

for this are complicated and discussed<br />

below. But obviously, the<br />

community needed the ability to<br />

keep adding new users. So some<br />

long-term developers (including<br />

me) got together and developed the<br />

necessary code to raise the limit.<br />

That code was called BIP 101 and<br />

we released it in a modified version<br />

of the software that we branded<br />

Bitcoin XT. By running XT, miners<br />

could cast a vote for changing<br />

the limit. Once 75% of blocks<br />

were voting for the change the<br />

rules would be adjusted and bigger<br />

One of the great things<br />

about Bitcoin is its lack of<br />

democracy.<br />

bitcoin.org Admin<br />

blocks would be allowed.<br />

The release of Bitcoin XT<br />

somehow pushed powerful emotional<br />

buttons in a small number<br />

of people. One of them was a guy<br />

who is the admin of the bitcoin.org<br />

website and top discussion forums.<br />

He had frequently allowed discussion<br />

of outright criminal activity<br />

on the forums he controlled, on<br />

the grounds of freedom of speech.<br />

But when XT launched, he made a<br />

surprising decision. XT, he claimed,<br />

did not represent the “developer<br />

consensus” and was therefore<br />

not really Bitcoin. Voting was an<br />

abomination, he said, because:<br />

“One of the great things about<br />

Bitcoin is its lack of democracy”<br />

So he decided to do whatever it<br />

took to kill XT completely, starting<br />

with censorship of Bitcoin’s primary<br />

communication channels: any<br />

post that mentioned the words “Bitcoin<br />

XT” was erased from the discussion<br />

forums he controlled, XT<br />

could not be mentioned or linked<br />

to from anywhere on the official<br />

bitcoin.org website and, of course,<br />

anyone attempting to point users to<br />

other uncensored forums was also<br />

banned. Massive numbers of users<br />

were expelled from the forums and<br />

prevented from expressing their<br />

views.<br />

As you can<br />

imagine, this<br />

enraged people.<br />

Read the comments<br />

on the<br />

announcement to<br />

get a feel for it.<br />

Eventually,<br />

some users found<br />

their way to a new uncensored<br />

forum. Reading it is a sad thing.<br />

Every day for months I have seen<br />

raging, angry posts railing against<br />

the censors, vowing that they will<br />

be defeated.<br />

But the inability to get news<br />

about XT or the censorship itself<br />

through to users has some problematic<br />

effects.<br />

For the first time, investors<br />

have no obvious way to get a<br />

clear picture of what’s going on.<br />

hacker bits<br />

31


“<br />

Dissenting views are being systematically<br />

suppressed. Technical<br />

criticisms of what Bitcoin Core<br />

is doing are being banned, with<br />

misleading nonsense being peddled<br />

in its place. And it’s clear that<br />

many people who casually bought<br />

into Bitcoin during one of its hype<br />

cycles have no idea that the system<br />

is about to hit an artificial limit.<br />

This worries me a great deal.<br />

Over the years governments have<br />

passed a large number of laws<br />

around securities and investments.<br />

Bitcoin is not a security and I do<br />

not believe it falls under those laws,<br />

but their spirit is simple enough:<br />

make sure investors are informed.<br />

When misinformed investors lose<br />

money, government attention frequently<br />

follows.<br />

Why is Bitcoin Core keeping the limit?<br />

People problems.<br />

Why is Bitcoin Core keeping<br />

the limit?<br />

People problems.<br />

When Satoshi left, he handed<br />

over the reins of the program we<br />

now call Bitcoin Core to Gavin<br />

Andresen, an early contributor.<br />

Gavin is a solid and experienced<br />

leader who can see the big picture.<br />

His reliable technical judgement is<br />

one of the reasons I had the confidence<br />

to quit Google (where I had<br />

spent nearly 8 years) and work on<br />

Bitcoin full time. Only one tiny<br />

problem: Satoshi never actually<br />

asked Gavin if he wanted the job,<br />

and in fact he didn’t. So the first<br />

thing Gavin did was grant four<br />

other developers access to the code<br />

as well. These developers were<br />

chosen quickly in order to ensure<br />

the project could easily continue<br />

if anything happened to him. They<br />

were, essentially, whoever was<br />

around and making themselves<br />

useful at the time.<br />

One of them, Gregory Maxwell,<br />

had an unusual set of views: he<br />

once claimed he had mathematically<br />

proven Bitcoin to be impossible.<br />

More problematically, he did not<br />

believe in Satoshi’s original vision.<br />

When the project was first<br />

announced, Satoshi was asked how<br />

a block chain could scale to a large<br />

number of payments. Surely the<br />

amount of data to download would<br />

become overwhelming if the idea<br />

took off? This was a popular criticism<br />

of Bitcoin in the early days<br />

and Satoshi fully expected to be<br />

asked about it. He said:<br />

“The bandwidth might not be<br />

as prohibitive as you think …<br />

if the network were to get [as<br />

big as VISA], it would take<br />

several years, and by then,<br />

sending [the equivalent of] 2<br />

HD movies over the Internet<br />

would probably not seem like<br />

a big deal.”<br />

It’s a simple argument: look at<br />

what existing payment networks<br />

handle, look at what it’d take for<br />

Bitcoin to do the same, and then<br />

point out that growth doesn’t<br />

happen overnight. The networks<br />

and computers of the future will<br />

be better than today. And indeed<br />

back-of-the-envelope calculations<br />

suggested that, as he said to me, “it<br />

never really hits a scale ceiling”<br />

even when looking at more factors<br />

than just bandwidth.<br />

Maxwell did not agree with this<br />

line of thinking. From an interview<br />

in December 2014:<br />

Problems with decentralization<br />

as bitcoin grows are not<br />

going to diminish either, according<br />

to Maxwell: “There’s<br />

an inherent tradeoff between<br />

scale and decentralization<br />

when you talk about transactions<br />

on the network.”<br />

The problem, he said, is that<br />

as bitcoin transaction volume<br />

increases, larger companies<br />

will likely be the only ones<br />

running bitcoin nodes because<br />

of the inherent cost.<br />

The idea that Bitcoin is inherently<br />

doomed because more users means<br />

less decentralisation is a pernicious<br />

one. It ignores the fact that despite<br />

all the hype, real usage is low,<br />

growing slowly and technology<br />

32 hacker bits


gets better over time. It is a belief<br />

Gavin and I have spent much time<br />

debunking. And it leads to an obvious<br />

but crazy conclusion: if decentralisation<br />

is what makes Bitcoin<br />

good, and growth threatens decentralisation,<br />

then Bitcoin should not<br />

be allowed to grow.<br />

Instead, Maxwell concluded,<br />

Bitcoin should become a sort of<br />

settlement layer for some vaguely<br />

defined, as yet un-created<br />

non-blockchain based system.<br />

The death spiral begins<br />

In a company, someone who did<br />

not share the goals of the organisation<br />

would be dealt with in a<br />

simple way: by firing him.<br />

But Bitcoin Core is an open<br />

source project, not a company.<br />

Once the 5 developers with commit<br />

access to the code had been chosen<br />

and Gavin had decided he did not<br />

want to be the leader, there was no<br />

procedure in place to ever remove<br />

one. And there was no interview or<br />

screening process to ensure they<br />

actually agreed with the project’s<br />

goals.<br />

As Bitcoin became more popular<br />

and traffic started approaching<br />

the 1mb limit, the topic of raising<br />

the block size limit was occasionally<br />

brought up between the<br />

developers. But it quickly became<br />

an emotionally charged subject.<br />

Accusations were thrown around<br />

that raising the limit was too risky,<br />

that it was against decentralisation,<br />

and so on. Like many small groups,<br />

people prefer to avoid conflict. The<br />

can was kicked down the road.<br />

Complicating things further,<br />

Maxwell founded a company that<br />

then hired several other developers.<br />

Not surprisingly, their views then<br />

started to change to align with that<br />

of their new boss.<br />

Co-ordinating software upgrades<br />

takes time, and so in May<br />

2015 Gavin decided the subject<br />

must be tackled once and for<br />

all, whilst there was still about 8<br />

months remaining. He began writing<br />

articles that worked through the<br />

arguments against raising the limit,<br />

one at a time.<br />

But it quickly became apparent<br />

that the Bitcoin Core developers<br />

were hopelessly at loggerheads.<br />

Maxwell and the developers he had<br />

hired refused to contemplate any<br />

increase in the limit whatsoever.<br />

They were barely even willing to<br />

talk about the issue. They insisted<br />

that nothing be done without “consensus”.<br />

And the developer who<br />

was responsible for making the<br />

releases was so afraid of conflict<br />

that he decided any controversial<br />

topic in which one side might “win”<br />

simply could not be touched at all,<br />

and refused to get involved.<br />

Thus despite the fact that exchanges,<br />

users, wallet developers,<br />

and miners were all expecting a<br />

rise, and indeed, had been building<br />

entire businesses around the assumption<br />

that it would happen, 3 of<br />

the 5 developers refused to touch<br />

the limit.<br />

Deadlock.<br />

Meanwhile, the clock was<br />

ticking.<br />

Massive DDoS attacks on<br />

XT users<br />

Despite the news blockade, within<br />

a few days of launching Bitcoin XT<br />

around 15% of all network nodes<br />

were running it, and at least one<br />

mining pool had started offering<br />

BIP101 voting to miners.<br />

That’s when the denial of<br />

service attacks started. The attacks<br />

were so large that they disconnected<br />

entire regions from the internet:<br />

“I was DDos’d. It was a massive<br />

DDoS that took down<br />

my entire (rural) ISP. Everyone<br />

in five towns lost their<br />

internet service for several<br />

hours last summer because of<br />

these criminals. It definitely<br />

discouraged me from hosting<br />

nodes.”<br />

In other cases, entire datacenters<br />

were disconnected from the internet<br />

until the single XT node inside<br />

them was stopped. About a third<br />

of the nodes were attacked and<br />

removed from the internet in this<br />

way.<br />

Worse, the mining pool that<br />

had been offering BIP101 was also<br />

attacked and forced to stop. The<br />

message was clear: anyone who<br />

supported bigger blocks, or even<br />

allowed other people to vote for<br />

them, would be assaulted.<br />

The attackers are still out there.<br />

When Coinbase, months after the<br />

launch, announced they had finally<br />

lost patience with Core and would<br />

run XT, they too were forced offline<br />

for a while.<br />

hacker bits<br />

33


Bogus conferences<br />

Despite the DoS attacks and censorship,<br />

XT was gaining momentum.<br />

That posed a threat to Core,<br />

so a few of its developers decided<br />

to organise a series of conferences<br />

named “Scaling Bitcoin”: one in<br />

August and one in December. The<br />

goal, it was claimed, was to reach<br />

“consensus” on what should be<br />

done. Everyone likes a consensus<br />

of experts, don’t they?<br />

It was immediately clear to<br />

me that people who refused to<br />

even talk about raising the limit<br />

would not have a change of heart<br />

because they attended a conference,<br />

and moreover, with the start<br />

of the winter growth season there<br />

remained only a few months to get<br />

the network upgraded. Wasting<br />

those precious months waiting for<br />

conferences would put the stability<br />

of the entire network at risk. The<br />

fact that the first conference actually<br />

banned discussion of concrete<br />

proposals didn’t help.<br />

So I didn’t go.<br />

Unfortunately, this tactic was<br />

devastatingly effective. The community<br />

fell for it completely. When<br />

talking to miners and startups, “we<br />

are waiting for Core to raise the<br />

limit in December” was one of<br />

the most commonly cited reasons<br />

for refusing to run XT. They were<br />

terrified of any media stories about<br />

a community split that might hurt<br />

the Bitcoin price and thus, their<br />

earnings.<br />

Now the last conference has<br />

come and gone with no plan to<br />

raise the limit, some companies<br />

(like Coinbase and BTCC) have<br />

woken up to the fact that they got<br />

played. But too late. Whilst the<br />

community was waiting, organic<br />

growth added another 250,000<br />

transactions per day.<br />

A non-roadmap<br />

Jeff Garzik and Gavin Andresen,<br />

the two of five Bitcoin Core<br />

committers who support a block<br />

size increase (and the two who<br />

have been around the longest), both<br />

have a stellar reputation within the<br />

community. They recently wrote a<br />

joint article titled “Bitcoin is Being<br />

Hot-Wired for Settlement”.<br />

Jeff and Gavin are generally<br />

softer in their approach than I am.<br />

I’m more of a tell-it-like-I-see-it<br />

kinda guy, or as Gavin has delicately<br />

put it, “honest to a fault”. So the<br />

strong language in their joint letter<br />

is unusual. They don’t pull any<br />

punches:<br />

“The proposed roadmap currently<br />

being discussed in the<br />

bitcoin community has some<br />

good points in that it does<br />

have a plan to accommodate<br />

more transactions, but it fails<br />

to speak plainly to bitcoin<br />

users and acknowledge key<br />

downsides.<br />

Core block size does not<br />

change; there has been zero<br />

compromise on that issue.<br />

In an optimal, transparent,<br />

open source environment, a<br />

BIP would be produced …<br />

this has not happened<br />

One of the explicit goals of<br />

the Scaling Bitcoin workshops<br />

was to funnel the chaotic<br />

core block size debate<br />

into an orderly decision<br />

making process. That did not<br />

occur. In hindsight, Scaling<br />

Bitcoin stalled a block size<br />

decision while transaction<br />

fee price and block space<br />

pressure continue to increase.”<br />

Failing to speak plainly, as<br />

they put it, has become more and<br />

more common. As an example, the<br />

plan Gavin and Jeff refer to was<br />

announced at the “Scaling Bitcoin”<br />

conferences but doesn’t involve<br />

making anything more efficient,<br />

and manages an anemic 60%<br />

capacity increase only through<br />

an accounting trick (not counting<br />

some of the bytes in each transaction).<br />

It requires making huge<br />

changes to nearly every piece of<br />

Bitcoin-related software. Instead<br />

of doing a simple thing and raising<br />

the limit, it chooses to do an<br />

incredibly complicated thing that<br />

might buy months at most, assuming<br />

a huge coordinated effort.<br />

Replace by fee<br />

One problem with using fees to<br />

control congestion is that the fee<br />

to get to the front of the queue<br />

might change after you made a<br />

payment. Bitcoin Core has a brilliant<br />

solution to this problem — allow<br />

people to mark their payments<br />

as changeable after they’ve been<br />

sent, up until they appear in the<br />

block chain. The stated intention<br />

is to let people adjust the fee<br />

paid, but in fact their change also<br />

allows people to change the pay-<br />

34 hacker bits


“<br />

ment to point back to themselves,<br />

thus reversing it.<br />

At a stroke, this makes using<br />

Bitcoin useless for actually buying<br />

things, as you’d have to wait for a<br />

buyer’s transaction to appear in the<br />

block chain … which from now on<br />

can take hours rather than minutes,<br />

due to the congestion.<br />

Core’s reasoning for why this<br />

is OK goes like this: it’s no big loss<br />

because if you hadn’t been waiting<br />

for a block before, there was a<br />

theoretical risk of payment fraud,<br />

which means you weren’t using<br />

Bitcoin properly. Thus, making that<br />

risk a 100% certainty doesn’t really<br />

change anything.<br />

In other words, they don’t recognise<br />

that risk management exists<br />

and so perceive this change as zero<br />

cost.<br />

This protocol change will be<br />

released with the next version of<br />

Core (0.12), so will activate when<br />

the miners upgrade. It was massively<br />

condemned by the entire<br />

Bitcoin community but the remaining<br />

Bitcoin Core developers don’t<br />

care what other people think, so the<br />

change will happen.<br />

If that didn’t convince you Bitcoin<br />

has serious problems, nothing<br />

will. How many people would<br />

think bitcoins are worth hundreds<br />

of dollars each when you soon<br />

I woke up this morning to find people<br />

wishing me well in the uncensored forum<br />

and asking me to stay...<br />

won’t be able to use them in actual<br />

shops?<br />

Conclusions<br />

Bitcoin has entered exceptionally<br />

dangerous waters. Previous crises,<br />

like the bankruptcy of Mt Gox,<br />

were all to do with the services and<br />

companies that sprung up around<br />

the ecosystem. But this one is<br />

different: it is a crisis of the core<br />

system, the block chain itself.<br />

More fundamentally, it is a crisis<br />

that reflects deep philosophical<br />

differences in how people view the<br />

world: either as one that should be<br />

ruled by a “consensus of experts”,<br />

or through ordinary people picking<br />

whatever policies make sense to<br />

them.<br />

Even if a new team was built to<br />

replace Bitcoin Core, the problem<br />

of mining power being concentrated<br />

behind the Great Firewall would<br />

remain. Bitcoin has no future<br />

whilst it’s controlled by fewer than<br />

10 people. And there’s no solution<br />

in sight for this problem: nobody<br />

even has any suggestions. For a<br />

community that has always worried<br />

about the block chain being<br />

taken over by an oppressive government,<br />

it is a rich irony.<br />

Still, all is not yet lost. Despite<br />

everything that has happened, in<br />

the past few weeks more members<br />

Reprinted with permission of the original author. First appeared at medium.com/@octskyward.<br />

of the community have started<br />

picking things up from where I am<br />

putting them down. Where making<br />

an alternative to Core was once<br />

seen as renegade, there are now<br />

two more forks vying for attention<br />

(Bitcoin Classic and Bitcoin<br />

Unlimited). So far they’ve hit the<br />

same problems as XT but it’s possible<br />

a fresh set of faces could find<br />

a way to make progress.<br />

There are many talented and<br />

energetic people working in the<br />

Bitcoin space, and in the past five<br />

years I’ve had the pleasure of getting<br />

to know many of them. Their<br />

entrepreneurial spirit and alternative<br />

perspectives on money, economics<br />

and politics were fascinating<br />

to experience, and despite how<br />

it’s all gone down I don’t regret<br />

my time with the project. I woke<br />

up this morning to find people<br />

wishing me well in the uncensored<br />

forum and asking me to stay, but<br />

I’m afraid I’ve moved on to other<br />

things. To those people I say: good<br />

luck, stay strong, and I wish you<br />

the best. •<br />

Mike, one of the developers of the Bitcoin<br />

digital currency system. Previously Mike<br />

was a senior software engineer at Google,<br />

where he worked on Earth, Maps, anti-spam<br />

systems, account signup abuse and<br />

login risk analysis for improved account<br />

security. He is the developer of the widely<br />

used bitcoinj Java API, which has been<br />

used by dozens of complex projects that<br />

work with the Bitcoin protocol.<br />

hacker bits<br />

35


linode bit<br />

HACKERBITS.COM and Ray's blog<br />

are hosted on a Linode since 2010.<br />

Why? Because their customer service<br />

is excellent, and they are a great bargain for a<br />

cloud-hosted virtual private server (VPS).<br />

It's a VPS, so you'll have full root access.<br />

In addition, the daily, weekly and snapshot<br />

backups feature are easy-to-use and saved us<br />

more times than we can remember.<br />

We highly recommend using Linode for your<br />

first VPS and beyond!<br />

Try Linode with our referral link and we will<br />

earn a small commission (at no additional cost<br />

to you) that will help cover <strong>Hacker</strong> <strong>Bits</strong>’ server<br />

hosting costs. You can also use our referral code<br />

below.<br />

Remember, we at <strong>Hacker</strong> <strong>Bits</strong> recommend<br />

Linode because they are helpful and useful, not<br />

because of the small commission we earn if you<br />

decide to buy something.<br />

Referral URL: http://hackerbits.com/linode<br />

Referral Code: 4e56fcfd8e1d9c25df482010fc1566ec8250387e


INTERESTING<br />

A beginner's guide to scaling<br />

to 11 million+ users On<br />

Amazon's AWS<br />

By TODD HOFF<br />

How do you scale a system from one user to<br />

more than 11 million users? Joel Williams,<br />

Amazon Web Services Solutions Architect,<br />

gives an excellent talk on just that subject: AWS<br />

re:Invent 2015 Scaling Up to Your First 10 Million<br />

Users.<br />

If you are an advanced AWS user this talk is not<br />

for you, but it’s a great way to get started if you are<br />

new to AWS, new to the cloud, or if you haven’t kept<br />

up with with constant stream of new features Amazon<br />

keeps pumping out.<br />

As you might expect since this is a talk by Amazon<br />

that Amazon services are always front and center<br />

as the solution to any problem. Their platform play<br />

hacker bits<br />

37


is impressive and instructive. It's obvious by how the<br />

pieces all fit together Amazon has done a great job of<br />

mapping out what users need and then making sure<br />

they have a product in that space.<br />

Some of the interesting takeaways:<br />

• Start with SQL and only move to NoSQL when<br />

necessary.<br />

• A consistent theme is take components and separate<br />

them out. This allows those components to<br />

scale and fail independently. It applies<br />

“<br />

to breaking<br />

up tiers and creating microservices.<br />

• Only invest in tasks that differentiate<br />

you as a business, don't<br />

reinvent the wheel.<br />

• Scalability and redundancy are<br />

not two separate concepts, you<br />

can often do both at the same<br />

time.<br />

• There's no mention of costs.<br />

That would be a good addition<br />

to the talk as that is one of<br />

the major criticisms of AWS<br />

solutions.<br />

The basics<br />

AWS is in 12 regions around the<br />

world.<br />

• A Region is a physical location<br />

in the world where Amazon has<br />

multiple Availability Zones.<br />

There are regions in: North<br />

America; South America; Europe; Middle East;<br />

Africa; Asia Pacific.<br />

• An Availability Zone (AZ) is generally a single<br />

datacenter, though they can be constructed out of<br />

multiple datacenters.<br />

• Each AZ is separate enough that they have separate<br />

power and Internet connectivity.<br />

• The only connection between AZs is a low latency<br />

network. AZs can be 5 or 15 miles apart, for<br />

example. The network is fast enough that your<br />

...Amazon<br />

has done a<br />

great job of<br />

mapping out<br />

what users<br />

need and then<br />

making sure<br />

they have a<br />

product in that<br />

space.<br />

application can act like all AZs are in the same<br />

datacenter.<br />

• Each Region has at least two Availability Zones.<br />

There are 32 AZs total.<br />

• Using AZs it’s possible to create a high availability<br />

architecture for your application.<br />

• At least 9 more Availability Zones and 4 more<br />

Regions are coming in <strong>2016</strong>.<br />

AWS has 53 edge locations around the world.<br />

• Edge locations are used by CloudFront, Amazon’s<br />

Content Distribution Network (CDN) and<br />

Route53, Amazon’s managed<br />

DNS server.<br />

• Edge locations enable users to<br />

access content with a very low<br />

latency no matter where they are<br />

in the world.<br />

Building Block Services.<br />

• AWS has created a number of<br />

services that use multiple AZs<br />

internally to be highly available<br />

and fault tolerant. Here is a list<br />

of what services are available<br />

where.<br />

• You can use these services<br />

in your application, for a fee,<br />

without having to worry about<br />

making them highly available<br />

yourself.<br />

• Some services that exist within<br />

an AZ: CloudFront, Route 53,<br />

S3, DynamoDB, Elastic Load<br />

Balancing, EFS, Lambda, SQS,<br />

SNS, SES, SWF.<br />

• A highly available architecture can be created using<br />

services even though they exist within a single<br />

AZ.<br />

1 User<br />

In this scenario you are the only user and you want to<br />

get a website running.<br />

38 hacker bits


Your architecture will look something like:<br />

• Run on a single instance, maybe a type t2.micro.<br />

Instance types comprise varying combinations of<br />

CPU, memory, storage, and networking capacity<br />

and give you the flexibility to choose the appropriate<br />

mix of resources for your applications.<br />

• The one instance would run the entire web stack,<br />

for example: web app, database, management, etc.<br />

• Use Amazon Route 53 for the DNS.<br />

• Attach a single Elastic IP address to the instance.<br />

• Works great, for a while.<br />

Vertical scaling<br />

• You need a bigger box. Simplest approach to<br />

scaling is choose a larger instance type. Maybe a<br />

c4.8xlarge or m3.2xlarge, for example.<br />

• This approach is called vertical scaling.<br />

• Just stop your instance and choose a new instance<br />

type and you’re running with more power.<br />

• There is a wide mix of different hardware configurations<br />

to choose from. You can have a system<br />

with 244 gigs of RAM (2TB of RAM types are<br />

coming soon). Or one with 40 cores. There are<br />

High I/O instances, High CPU Instances, High<br />

storage instances.<br />

• Some Amazon services come with a Provisioned<br />

IOPS option to guarantee performance. The idea<br />

is you can perhaps use a smaller instance type for<br />

your service and make use of Amazon services<br />

like DynamoDB that can deliver scalable services<br />

so you don’t have to.<br />

• Vertical scaling has a big problem: there’s no<br />

failover, no redundancy. If the instance has a<br />

problem your website will die. All your eggs are<br />

in one basket.<br />

• Eventually a single instances can only get so big.<br />

You need to do something else.<br />

Users > 10<br />

Separate out a single host into multiple hosts.<br />

• One host for the web site.<br />

• One host for the database. Run any database you<br />

want, but you are on the hook for the database<br />

administration.<br />

• Using separate hosts allows the web site and the<br />

database to be scaled independently of each other.<br />

Perhaps your database will need a bigger machine<br />

than your web site, for example.<br />

Or instead of running your own database you could<br />

use a database service.<br />

• Are you a database admin? Do your really want to<br />

worry about backups? High availability? Patches?<br />

Operating systems?<br />

• A big advantage of using a service is you can have<br />

a multi Availability Zone database setup with a<br />

single click. You won’t have to worry about replication<br />

or any of that sort of thing. Your database<br />

will be highly available and reliable.<br />

As you might imagine Amazon has several fully<br />

managed database services to sell you:<br />

• Amazon RDS (Relational Database Service).<br />

There are many options: Microsoft SQL Server,<br />

Oracle, MySQL, PostgreSQL, MariaDB, Amazon<br />

Aurora.<br />

• Amazon DynamoDB. A NoSQL managed database.<br />

• Amazon Redshift. A petabyte scale data warehouse<br />

system.<br />

More Amazon Aurora:<br />

• Automatic storage scaling up to 64TB. You no<br />

longer have to provision the storage for your data.<br />

• Up to 15 read read-replicas.<br />

• Continuous (incremental) backups to S3.<br />

• 6-way replication across 3 AZs. This helps you<br />

handle failure.<br />

• MySQL compatible.<br />

Start with a SQL database instead of a NoSQL database.<br />

• The suggestion is to start with a SQL database.<br />

• The technology is established.<br />

• There’s lots of existing code, communities, support<br />

groups, books, and tools.<br />

hacker bits<br />

39


• You aren’t going to break a SQL database with<br />

your first 10 million users. Not even close. (unless<br />

your data is huge).<br />

• Clear patterns to scalability.<br />

When might you need start with a NoSQL database?<br />

• If you need to store > 5 TB of data in year one or<br />

you have an incredibly data intensive workload.<br />

• Your application has super low-latency requirements.<br />

• You need really high throughput. You need to really<br />

tweak the IOs you are getting both on the reads<br />

and the writes.<br />

• You don’t have any relational data.<br />

Users > 100<br />

• Use a separate host for the web tier.<br />

• Store the database on Amazon RDS. It takes care<br />

of everything.<br />

• That’s all you have to do.<br />

Users > 1000<br />

• As architected your application has availability<br />

issues. If the host for your web service fails then<br />

your web site goes down.<br />

• So you need another web instance in another<br />

Availability Zone. That’s OK because the latency<br />

between the AZs is in the low single digit milliseconds,<br />

almost like they right next to each other.<br />

• You also need to a slave database to RDS that<br />

runs in another AZ. If there’s a problem with the<br />

master your application will automatically switch<br />

over to the slave. There are no application changes<br />

necessary on the failover because your application<br />

always uses the same endpoint.<br />

• An Elastic Load Balancer (ELB) is added to the<br />

configuration to load balance users between your<br />

two web host instances in the two AZs.<br />

Elastic Load Balancer (ELB):<br />

• ELB is a highly available managed load balancer.<br />

The ELB exists in all AZs. It’s a single DNS<br />

endpoint for your application. Just put it in Route<br />

53 and it will load balance across your web host<br />

instances.<br />

• The ELB has Health Checks that make sure traffic<br />

doesn’t flow to failed hosts.<br />

• It scales without your doing anything. If it sees<br />

additional traffic it scales behind the scenes both<br />

horizontally and vertically. You don’t have to<br />

manage it. As your applications scales so is the<br />

ELB.<br />

Users > 10,000s - 100,000s<br />

The previous configuration has 2 instances behind<br />

the ELB, in practice you can have 1000s of instances<br />

behind the ELB. This is horizontal scaling.<br />

You’ll need to add more read replicas to the database,<br />

to RDS. This will take load off the write master.<br />

Consider performance and efficiency by lightening<br />

the load off your web tier servers by moving<br />

some of the traffic elsewhere. Move static content in<br />

your web app to Amazon S3 and Amazon CloudFront.<br />

CloudFront is the Amazon’s CDN that stores your<br />

data in the 53 edge locations across the world.<br />

Amazon S3 is an object base store.<br />

• It’s not like EBS, it’s not storage that’s attached to<br />

an EC2 instance, it’s an object store, not a block<br />

store.<br />

• It’s a great place to store static content, like javascript,<br />

css, images, videos. This sort of content<br />

does not need to sit on an EC2 instance.<br />

• Highly durable, 11 9’s of reliability.<br />

• Infinitely scalable, throw as much data as it as you<br />

want. Customers store multiple petabytes of data<br />

in S3.<br />

• Objects of up to 5TB in size are supported.<br />

• Encryption is supported. You can use Amazon’s<br />

encryption, your encryption, or an encryption<br />

service.<br />

Amazon CloudFront is cache for your content.<br />

• It caches content at the edge locations to provide<br />

your users the lowest latency access possible.<br />

• Without a CDN your users will experience higher<br />

latency access to your content. Your servers will<br />

40 hacker bits


also be under higher load as they are serving the<br />

content as well as handling the web requests.<br />

• One customer needed to serve content at 60 Gbps.<br />

The web tier didn’t even know that was going on,<br />

CloudFront handled it all.<br />

You can also lighten the load by shifting session state<br />

off your web tier.<br />

• Store the session state in ElastiCache or DynamoDB.<br />

• This approach also sets your system up to support<br />

auto scaling in the future.<br />

You can also lighten the load by caching data from<br />

your database into ElastiCache.<br />

are started automatically.<br />

You can also lighten the load by shifting dynamic<br />

content to CloudFront.<br />

• A lot of people know CloudFront can handle static<br />

content, like files, but it can also handle some dynamic<br />

content. This topic is not discussed further<br />

in the talk, but here’s a link.<br />

Auto scaling<br />

If you provision enough capacity to always handle<br />

your peak traffic load, Black Friday, for example,<br />

you are wasting money. It would be better to match<br />

compute power with demand. That’s what Auto Scaling<br />

let’s you do, the automatic resizing of compute<br />

If you provision enough capacity to<br />

always handle your peak traffic load...<br />

“you are wasting money.<br />

• Your database doesn’t need to handle all the gets<br />

for data. A cache can handle a lot of that work<br />

and leaves the database to handle more important<br />

traffic.<br />

Amazon DynamoDB - A managed NoSQL database<br />

• You provision the throughput you want. You dial<br />

up the read and write performance you want to pay<br />

for.<br />

• Supports fast, predictable performance.<br />

• Fully distributed and fault tolerant. It exists in multiple<br />

Availability Zones.<br />

• It’s a key-value store. JSON is supported.<br />

• Documents up to 400KB in size are supported.<br />

Amazon Elasticache - a managed Memcached or Redis<br />

• Managing a memcached cluster isn’t making you<br />

more money so let Amazon do that for you. That’s<br />

the pitch.<br />

• The clusters are automatically scaled for you. It’s a<br />

self-healing infrastructure, if nodes fail new nodes<br />

clusters.<br />

You can define the minimum and maximum size<br />

of your pools. As a user you decide what’s the smallest<br />

number of instances in your cluster and the largest<br />

number of instances.<br />

CloudWatch is a management service that’s embedded<br />

into all applications.<br />

• CloudWatch events drive scaling<br />

• Are you going to scale on CPU utilization? Are<br />

you going to scale on latency? On network traffic?<br />

• You can also push your own custom metrics into<br />

CloudWatch. If you want to scale on something<br />

application specific you can push that metric into<br />

CloudWatch and then tell Auto Scaling you want<br />

to scale on that metric.<br />

Users > 500,000+<br />

• The addition from the previous configuration is<br />

auto scaling groups are added to the web tier. The<br />

hacker bits<br />

41


“<br />

auto scaling group includes the two AZs, but can<br />

expand to 3 AZs, up to as many as are in the same<br />

region. Instances can pop up in multiple AZs not<br />

just for scalability, but for availability.<br />

• The example has 3 web tier instances in each AZ,<br />

but it could be thousands of instances. You could<br />

say you want a minimum of 10 instances and a<br />

maximum of a 1000.<br />

• ElastiCache is used to offload popular reads from<br />

the database.<br />

• DynamoDB is used to offload Session data.<br />

You need to add monitoring, metrics and logging.<br />

• Host level metrics. Look at a single CPU instance<br />

within an autoscaling group and figure out what’s<br />

going wrong.<br />

• Aggregate level metrics. Look at metrics on the<br />

Elastic Load Balancer to get feel for performance<br />

of the entire set of instances.<br />

• Log analysis. Look at what the application is telling<br />

you using CloudWatch logs. CloudTrail helps<br />

you analyze and manage logs.<br />

• External Site Performance. Know what your customers<br />

are seeing as end users. Use a service like<br />

New Relic or Pingdom.<br />

You also need to...<br />

• Know what your customers are saying. Is their<br />

latency bad? Are they getting an error when they<br />

go to your web page?<br />

• Squeeze as much performance as you can from<br />

your configuration. Auto Scaling can help with<br />

that. You don’t want systems that are at 20% CPU<br />

utilization.<br />

Automation<br />

Don’t reinvent the wheel... Only invest in<br />

tasks that differentiate you as a business.<br />

The infrastructure is getting big, it can scale to 1000s<br />

of instances. We have read replicas, we have horizontal<br />

scaling, but we need some automation to help<br />

manage it all, we don’t want to manage each individual<br />

instance.<br />

There’s a hierarchy of automation tools.<br />

• Do it yourself: Amazon EC2, AWS CloudFormation.<br />

• Higher-level services: AWS Elastic Beanstalk,<br />

AWS OpsWorks<br />

AWS Elastic Beanstalk<br />

Manages the infrastructure for your application<br />

automatically. It’s convenient but there’s not a lot of<br />

control.<br />

AWS OpsWorks<br />

An environment where you build your application in<br />

layers, you use Chef recipes to manage the layers of<br />

your application.<br />

Also enables the ability to do Continuous Integration<br />

and deployment.<br />

AWS CloudFormation<br />

• Been around the longest.<br />

• Offers the most flexibility because it offers a templatized<br />

view of your stack. It can be used to build<br />

your entire stack or just components of the stack.<br />

• If you want to update your stack you update the<br />

Cloud Formation template it will update just that<br />

one piece of your application.<br />

• Lots of control, but less convenient.<br />

AWS CodeDeploy<br />

• Deploys your code to a fleet of EC2 instances.<br />

• Can deploy to one or thousands of instances.<br />

• Code Deploy can point to an auto scaling configuration<br />

so code is deployed to a group of instances.<br />

• Can also be used in conjunction with Chef and<br />

Puppet.<br />

42 hacker bits


Decouple infrastructure<br />

• Use SOA/microservices. Take components from<br />

your tiers and separate them out. Create separate<br />

services like when you separated the web tier<br />

from the database tier.<br />

• The individual services can then be scaled independently.<br />

This gives you a lot of flexibility for<br />

scaling and high availability.<br />

• SOA is a key component of the architectures built<br />

by Amazon.<br />

Loose coupling sets you free.<br />

• You can scale and fail components independently.<br />

• If a worker node fails in pulling work from SQS<br />

does it matter? No, just start another one. Things<br />

are going to fail, let’s build an architecture that<br />

handles failure.<br />

• Design everything as a black box.<br />

• Decouple interactions.<br />

• Favor services with built-in redundancy and scalability<br />

rather than building your own.<br />

Don’t reinvent the wheel<br />

• Only invest in tasks that differentiate you as a<br />

business.<br />

• Amazon has a lot of services that are inherently<br />

fault tolerant because they span multiple AZs.<br />

For example: queuing, email, transcoding, search,<br />

databases, monitoring, metrics, logging, compute.<br />

You don’t have to build these yourself.<br />

SQS: queueing service.<br />

• The first Amazon service offered.<br />

• It spans multiple AZs so it’s fault tolerant.<br />

• It’s scalable, secure, and simple.<br />

• Queuing can help your infrastructure by helping<br />

you pass messages between different components<br />

of your infrastructure.<br />

• Take for example a Photo CMS. The systems that<br />

collects the photos and processes them should<br />

be two different systems. They should be able to<br />

scale independently. They should be loosely coupled.<br />

Ingest a photo, put it in queue, and workers<br />

can pull photos off the queue and do something<br />

with them.<br />

AWS Lambda: lets you run code without provisioning<br />

or managing servers.<br />

• Great tool for allowing you to decouple your<br />

application.<br />

• In the Photo CMS example Lambda can respond<br />

to S3 events so when a S3 file is added the Lambda<br />

function to process is automatically triggered.<br />

• We’ve done away with EC2. It scales out for you<br />

and there’s no OS to manage.<br />

Users > 1,000,000+<br />

Reaching a million users and above requires bits of<br />

all the previous points:<br />

• Multi-AZ<br />

• Elastic Load Balancing between tiers. Not just on<br />

the web tier, but also on the application tier, data<br />

tier, and any other tier you have.<br />

• Auto Scaling<br />

• Service Oriented Architecture<br />

• Serve Content Smartly with S3 and CloudFront<br />

• Put caching in front of the DB<br />

• Move state off the web tier.<br />

In addition:<br />

• Use Amazon SES to send email.<br />

• Use CloudWatch for monitoring.<br />

Users > 10,000,000+<br />

As we get bigger we’ll hit issues in the data tier. You<br />

will potentially start to run into issues with your database<br />

around contention with the write master, which<br />

basically means you can only send so much write<br />

traffic to one server.<br />

How do you solve it?<br />

• Federation<br />

• Sharding<br />

• Moving some functionality to other types of DBs<br />

(NoSQL, graph, etc)<br />

hacker bits<br />

43


Federation - splitting into multiple DBs based on<br />

function<br />

• For example, create a Forums Database, a User<br />

Database, a Products Database. You might have<br />

had these in a single database before, now spread<br />

them out.<br />

• The different databases can be scaled independently<br />

of each other.<br />

• The downsides: you can’t do cross database queries;<br />

it delays getting to the next strategy, which is<br />

sharding.<br />

• Start to build custom solutions to solve your particular<br />

problem that nobody has ever done before.<br />

If you need to serve a billion customers you may<br />

need custom solutions.<br />

• Deep analysis of your entire stack.<br />

In review<br />

• Use a multi-AZ infrastructure for reliability.<br />

• Make use of self-scaling services like ELB, S3,<br />

SQS, SNS, DynamoDB, etc.<br />

...use a managed service instead of coding<br />

“your own, unless it’s absolutely necessary.<br />

Sharding - splitting one dataset across multiple hosts<br />

• More complex at the application layer, but there’s<br />

no practical limit on scalability.<br />

• For example, in a Users Database ⅓ of the users<br />

might be sent to one shard, and the last third to<br />

another shard, and another shard to another third.<br />

Moving some functionality to other types of DBs<br />

• Start thinking about a NoSQL database.<br />

• If you have data that doesn’t require complex<br />

joins, like say a leaderboard, rapid ingest of<br />

clickstream/log data, temporary data, hot tables,<br />

metadata/lookup tables, then consider moving it<br />

to a NoSQL database.<br />

• This means they can be scaled independently of<br />

each other.<br />

Users > 11 million<br />

• Scaling is an iterative process. As you get bigger<br />

there's always more you can do.<br />

• Fine tune your application.<br />

• More SOA of features/functionality.<br />

• Go from Multi-AZ to multi-region.<br />

• Build in redundancy at every level. Scalability<br />

and redundancy are not two separate concepts,<br />

you can often do both at the same time.<br />

• Start with a traditional relational SQL database.<br />

• Cache data both inside and outside your infrastructure.<br />

• Use automation tools in your infrastructure.<br />

• Make sure you have good metrics/monitoring/logging<br />

in place. Make sure you are finding out what<br />

your customers experience with your application.<br />

• Split tiers into individual services (SOA) so they<br />

can scale and fail independently of each other.<br />

• Use Auto Scaling once you’re ready for it.<br />

• Don’t reinvent the wheel, use a managed service<br />

instead of coding your own, unless it’s absolutely<br />

necessary.<br />

• Move to NoSQL if and when it makes sense. •<br />

Todd runs highscalability.com.<br />

Reprinted with permission of the original author. First appeared at highscalability.com.<br />

44 hacker bits


OPINION<br />

Getting ahead vs. doing well<br />

By SETH GODIN<br />

Two guys are running away<br />

from an angry grizzly when<br />

one stops to take off his hiking<br />

boots and switches to running<br />

shoes. "What are you doing," the<br />

other guy yells, "those<br />

“<br />

aren't going<br />

to allow you to outrun<br />

the bear..." The<br />

other guy smiles<br />

and points out that<br />

he doesn't have to<br />

outrun the bear, just<br />

his friend.<br />

I was at a fancy<br />

event the other day,<br />

and it was held<br />

in three different<br />

rooms. All of these<br />

fancy folks were<br />

there, in fancy outfits,<br />

etc. More than<br />

once, I heard people<br />

ask, "is this room<br />

the best room?" It<br />

wasn't enough that<br />

the event was fancy. It mattered<br />

that the room assigned was the<br />

fanciest one.<br />

Class rank. The most expensive<br />

car. A 'better' neighborhood. A faster<br />

marathon. More online followers.<br />

A bigger pool...<br />

One unspoken objection to<br />

raising the minimum wage is that<br />

people, other people, those people,<br />

will get paid a<br />

little more. Which<br />

They quit<br />

a good<br />

job, a job<br />

they liked,<br />

because<br />

other<br />

people got<br />

a raise.<br />

might make getting<br />

ahead a little<br />

harder. When we<br />

raise the bottom,<br />

this thinking goes,<br />

it gets harder to<br />

move to the top.<br />

After a company<br />

in Seattle<br />

famously raised<br />

its lowest wage<br />

tier to $70,000,<br />

two people (who<br />

got paid more than<br />

most of the other<br />

workers) quit,<br />

because they felt it<br />

wasn't fair that people who weren't<br />

as productive as they were were<br />

going to get a raise.<br />

They quit a good job, a job they<br />

liked, because other people got a<br />

raise.<br />

This is our culture of 'getting<br />

ahead' talking.<br />

This is the thinking that, "First<br />

class isn't better because of the<br />

seats, it's better because it's not<br />

coach." (Several airlines have tried<br />

to launch all-first-class seating, and<br />

all of them have stumbled.)<br />

There are two challenges here.<br />

The first is that in a connection<br />

economy, the idea that others need<br />

to be in coach for you to be in first<br />

doesn't scale very well. When we<br />

share an idea or an experience, we<br />

both have it, it doesn't diminish the<br />

value, it increases it.<br />

And the second, in the words<br />

of moms everywhere: Life is more<br />

fun when you don't compare. It's<br />

possible to create dignity and be<br />

successful at the same time. (In<br />

fact, that might be the only way to<br />

be truly successful.) •<br />

Seth Godin is the founder of Yoyodyne<br />

and Squidoo, a popular blogger and the<br />

author of 18 bestselling books. His latest<br />

project can be found at www.altmba.com.<br />

Reprinted with permission of the original author. First appeared at sethgodin.typepad.com.<br />

hacker bits<br />

45


STARTUP<br />

When to join a<br />

STARTUP<br />

By TOM BLOMFIELD<br />

Something has changed in<br />

the last few years which has<br />

made an increasing number<br />

of people want to join startups. It<br />

seemed to start around the time<br />

the Social Network movie came<br />

out - perhaps it’s just a<br />

coincidence, but part of me<br />

imagines a group of MBAs<br />

sitting around watching<br />

Justin Timberlake play<br />

Sean Parker, thinking that<br />

actually a billion dollars<br />

would be pretty cool.<br />

When choosing a startup<br />

to work at, people often<br />

overlook one of the most<br />

important factors, which<br />

is the size and stage of the<br />

company. I’d argue this<br />

is sometimes even more<br />

important than the industry or the<br />

idea itself.<br />

Bootstrapping, aka two<br />

people in a bedroom<br />

The startup was recently formed,<br />

and the company might not even<br />

be legally incorporated yet. There’s<br />

“<br />

Anything is<br />

possible. The entire<br />

direction of the<br />

company might<br />

even be changing<br />

from week to week.<br />

no funding and no-one is taking<br />

any salary. You’re two, three or<br />

four people in a bedroom living on<br />

baked beans, working all hours of<br />

the day to get a working prototype<br />

to show to customers or investors.<br />

The only people using your website<br />

or app are a couple of sympathetic<br />

friends and your mum.<br />

Someone else tried to<br />

convince you to join a different<br />

startup a year earlier,<br />

but they had no funding<br />

and zero customers. They<br />

wanted you to work without<br />

a salary in return for 1%<br />

of equity, which sounded<br />

like a scam to you. You’re<br />

glad you picked this startup<br />

instead. You might not<br />

be getting any salary, but<br />

at least you’re joining as<br />

a co-founder with a double-digit<br />

equity stake. You<br />

jokingly talk with your cofounders<br />

about which island you’d each buy<br />

46 hacker bits


when you sell out for billions in a<br />

few years’ time.<br />

The product vision is vague and<br />

broad, but you’re working every<br />

day to try to validate it with customers.<br />

Anything is possible. The<br />

entire direction of the company<br />

might even be changing from week<br />

to week.<br />

Because nothing yet exists,<br />

you need to bring it to life with a<br />

combination of energy and raw<br />

self-belief. There’s little specialisation<br />

and no hierarchy; everyone<br />

does whatever needs to be done. It<br />

can be exhilarating.<br />

It can also be exhausting at<br />

times, lasting months or years before<br />

you find customer traction or<br />

funding.<br />

Seed-funded<br />

Now the company has a working<br />

prototype, a few dozen regular<br />

users and £250k of seed funding.<br />

It’s enough to pay a handful of<br />

people low salaries. Since you’re<br />

too big to fit in a bedroom, you’re<br />

renting desks at a coworking space<br />

or scrounging them off a bigger<br />

startup.<br />

You cut a lot of corners, but<br />

seem to ship an incredible amount<br />

of code. People you don’t know<br />

personally start to use your product<br />

and it feels awesome. You’re<br />

working hard to spread the word,<br />

perhaps even starting to earn a little<br />

revenue from your first paying<br />

users.<br />

You join at this stage for 3%<br />

equity plus whatever basic salary<br />

you need to survive. You talk about<br />

which cities you’d buy houses in<br />

when the company sells.<br />

You might join as the first<br />

professional programmer or designer,<br />

but you’re still more-orless<br />

on your own. When you join,<br />

your first job is to go to the Apple<br />

Store and buy yourself a laptop<br />

because no-one thought to order<br />

any equipment. There’s no “mentorship”<br />

from more experienced<br />

colleagues or even code-review,<br />

simply because the company is still<br />

too small.<br />

“Marketing” consists of one of<br />

the founders emailing your funding<br />

announcement to TechCrunch.<br />

As an employee, you have a<br />

significant say in the direction of<br />

the company, although the business<br />

model might still shift substantially<br />

underneath you. Even if you’re<br />

not making the decisions, you hear<br />

about them immediately.<br />

hacker bits<br />

47


There’s still a good chance that<br />

the company fails to find “product-market<br />

fit” and goes bankrupt<br />

without raising more money. Your<br />

mum tells you that you should have<br />

stuck with your well-paying job at<br />

Oracle.<br />

Series A<br />

The company has raised £3m from<br />

a big-name VC and the team has<br />

grown to 10-15 people. You’ve got<br />

your own office with your logo on<br />

the door, or at least your own area<br />

in the coworking space.<br />

The investor makes you submit<br />

quarterly cashflow reports, so you<br />

start keeping accounts for the first<br />

time. This is done by whoever has<br />

Excel installed on their computer.<br />

The company eventually hires<br />

an office manager to ease the burden<br />

of administration on the founders.<br />

They set up a payroll provider<br />

and start doing peer reviews.<br />

You join the company to do a<br />

specific role, but you spend your<br />

first week or two figuring out what<br />

you should actually be working on.<br />

At least they remembered to buy<br />

you a laptop, a desk and a chair.<br />

There are 3 or 4 engineers<br />

in the team, so you start to do<br />

code-review and set up a continuous<br />

integration server. You lament<br />

all the technical debt that was<br />

accrued by those idiots who arrived<br />

before you, slowing down the pace<br />

of feature development.<br />

A new product direction for the<br />

company is decided in a meeting of<br />

the three founders; this is presented<br />

in an “all-hands” meeting of 12<br />

employees. The company sets out<br />

a quarterly product roadmap, and<br />

you’re asked what you think should<br />

be prioritised. You pick the projects<br />

that most interest you.<br />

You’ll certainly be able to earn<br />

more money at a big company,<br />

but the salaries are enough to live<br />

You join the company<br />

to do a specific role,<br />

but you spend your<br />

first week or two figuring<br />

out what you should<br />

“actually be working on.<br />

comfortably on. You get 0.5% in<br />

stock options with a salary that’s<br />

10-30% below market rate. But you<br />

reckon it’s worth the gamble - if<br />

the company sells, you’ll be able to<br />

buy a really nice house in London.<br />

Still, it feels a long way off.<br />

The marketing function is one<br />

full-time person who does everything<br />

from PR, paid advertising<br />

and social media. The founder no<br />

longer personally runs the company’s<br />

Twitter account. Your company<br />

regularly appears in the “ones to<br />

watch” articles in tech press.<br />

You’ve got thousands of paying<br />

customers, and you occasionally<br />

see people in public using your<br />

app, which feels fantastic. Your<br />

mum isn’t really sure what your<br />

company does, but she’s happy<br />

enough because you’re being paid<br />

a real salary.<br />

Series B<br />

The company is now 2-3 years old<br />

and has just raised £10-20m. It’s<br />

using that money to grow the team,<br />

increasing headcount to 60 people.<br />

The founders got tired of the<br />

dingy office, so they splashed out<br />

on somewhere with lots of exposed<br />

brickwork and glass walls. Everyone<br />

is sitting on Herman Miller<br />

chairs. You find these chairs online<br />

and see they cost £1000 each.<br />

There are 3 or 4 people in<br />

finance and HR roles, and you’re<br />

presented with a company handbook<br />

when you join. You have a<br />

couple of days’ training, but you<br />

mostly figure it out along the way.<br />

Marketing now has three digital<br />

advertising people, and people<br />

specialising in PR, content and<br />

community management. You’ve<br />

got millions of paying customers in<br />

several countries, and your company<br />

is regularly featured in the<br />

business pages of the press.<br />

Engineering has been split into<br />

48 hacker bits


two or three separate teams, and<br />

they’re trying recruit graduating<br />

college students to fill the hiring<br />

pipeline for next year.<br />

You join in a very well-defined<br />

role, after the team manager<br />

recruited you. You meet founders<br />

during your interview, but they<br />

don’t always remember your name<br />

now you work here. The CEO sees<br />

a management coach every fortnight.<br />

A new product direction is<br />

debated at a board meeting, and<br />

senior management is informed<br />

by the CEO. Management let their<br />

teams know that changes are imminent.<br />

Most people are focussed on<br />

“repeatable processes” and scaling<br />

up.<br />

The company doesn’t seem to<br />

release new features very often, but<br />

the app is used by some of of your<br />

mum’s friends, which makes her<br />

very proud.<br />

Your salary is in line with<br />

what other companies are paying,<br />

and you get 0.05% stock options.<br />

You’ve already figured out which<br />

house you’d put a deposit on when<br />

the company sells. A sale seems<br />

inevitable at some stage.<br />

Series C<br />

You’re joining a unicorn! After<br />

5 years, the company has raised<br />

£100m at a £1bn valuation. There<br />

are some strange terms in the deal<br />

structure that you’ve never seen<br />

before, but the company’s HR department<br />

tells you that’s just “legal<br />

stuff”.<br />

“<br />

When you join, you’re granted<br />

£50,000 of options, which you<br />

work out is one two-hundredth of<br />

a percent, or 0.005% of the company.<br />

Friends in other startups tell<br />

you to check what the investor’s<br />

liquidation preference is, but noone<br />

at the company can seem tell<br />

you. They’re all too busy trying<br />

to guess when the IPO is going to<br />

be announced. You figure that any<br />

kind of payout is a nice bonus. The<br />

salary is pretty decent anyway.<br />

You join in the company’s<br />

newly opened Dublin office, part of<br />

a new drive by the company to internationalise.<br />

You’ve joined as one<br />

of 6 new Sales Associates focussing<br />

on European enterprise sales.<br />

There’s 4 week intensive induction<br />

training programme before you’re<br />

allowed to talk to any customers.<br />

The new office feels empty<br />

at first, but you’re surprised how<br />

quickly it fills up with new staff.<br />

You ask where the marketing department<br />

sit, but you’re told they’re<br />

in a different office.<br />

You see the CEO on the cover<br />

of Forbes, but you’ve never actually<br />

met him.<br />

Your mum is already using the<br />

app, although it’s starting to look a<br />

bit dated compared to some of the<br />

newer startups that are in Tech-<br />

Crunch.<br />

Business Insider reports that<br />

the company has fired the new VP<br />

Reprinted with permission of the original author. First appeared at tomblomfield.com.<br />

You see the CEO<br />

on the cover of Forbes, but<br />

you’ve never actually met him.<br />

of Product and is pursuing a new<br />

production direction. She had only<br />

arrived from Twitter 6 months earlier.<br />

An internal memo from HR a<br />

couple of days says that the company’s<br />

doing some minor internal<br />

restructuring.<br />

You see consultants in the<br />

meeting rooms, but you don’t know<br />

what they’re doing.<br />

A month later, you gather for a<br />

televised all-hands meeting, broadcast<br />

from the company’s HQ. The<br />

CEO delivers a short speech announcing<br />

that the company’s been<br />

acquired by Oracle, explaining how<br />

it will accelerate the company’s<br />

ability to deliver on its vision. He<br />

thanks everyone for being part of<br />

the company’s incredible journey.<br />

People in the audience are crying.<br />

HR follows up explaining that<br />

as part of the acquisition, some<br />

departments will be downsized.<br />

You’re told that your stock options<br />

are “underwater”. When you Google<br />

this, you find out that they’re<br />

worthless. You’ve got some friends<br />

in engineering who are being<br />

given Oracle stock as a “retention<br />

package”, but that doesn’t apply to<br />

anyone in sales. You wonder why<br />

you ever joined a startup in the first<br />

place. •<br />

Tom is currently CEO and co-founder of<br />

Mondo - a new smartphone-based bank.<br />

He previously co-founded Boso.com<br />

and GoCardless - both companies were<br />

accepted onto Y Combinator. He blogs<br />

here at tomblomfield.com about software<br />

engineering & startups.<br />

hacker bits<br />

49


PROGRAMMING<br />

Sending &<br />

receiving<br />

SMS on<br />

Linux<br />

By MICHAEL MARNER<br />

A<br />

little while ago I worked on a mixed media<br />

theatre production called If There Was A Colour<br />

Darker Than Black I’d Wear It. As part of<br />

this production I needed to build a system that could<br />

send and receive SMS messages from audience members.<br />

Today we’re looking at the technical aspects of<br />

how to do that using SMS Server Tools.<br />

There are actually a couple of ways to obtain<br />

incoming text messages:<br />

• Using an SMS gateway and software API<br />

• Using a GSM modem plugged into the computer,<br />

and a prepaid SIM<br />

The API route is the easiest way to go from a programming<br />

aspect. It costs money, but most gateways<br />

provide a nice API to interface with, and you’ll be<br />

able to send larger volumes of messages.<br />

50 hacker bits


“<br />

BLACK had a few specific requirements that made<br />

the gateway unsuitable.<br />

Following these steps and you can send<br />

and receive SMS messages on Linux, using<br />

a cheap prepaid SIM and GSM modem.<br />

1. We were projecting out of a van in regional<br />

South Australia. We had terrible phone reception,<br />

and mobile data was really flakey.<br />

2. We were going to be sending text messages to<br />

audience members later, and needed to have<br />

the same phone number.<br />

SMS tools<br />

SMS Tools is an open source software package for<br />

interfacing with GSM modems on Linux. It includes<br />

a daemon, SMSD, which receives messages. SMSD<br />

is configured to run your own scripts when messages<br />

are received, allowing you to do pretty much anything<br />

you want with them.<br />

Installation is straight forward on Ubuntu et al:<br />

So, we got hold of a USB GSM modem and used a<br />

prepaid phone SIM. This allowed us to receive unlimited<br />

messages for free. However, we couldn’t send<br />

messages as quickly as we would have liked.<br />

Modem selection<br />

There are quite a few GSM modems to choose from.<br />

You are looking for one with a USB interface and a<br />

removable SIM. GSM modems that use wifi to connect<br />

to computers won’t work. You need to be able to<br />

remove the SIM because most mobile data SIMs won’t<br />

allow you to send or receive SMS messages. The other<br />

big requirement is Linux drivers, and Google is really<br />

your friend here. The main thing to watch out for is<br />

manufacturers changing the chipsets in minor product<br />

revisions.<br />

We ended up going with an old Vodafone modem<br />

using a Huawei chipset. It shows up in Linux like this:<br />

ID 12d1:1001 Huawei Technologies Co., Ltd.<br />

E169/E620/E800 HSDPA Modem<br />

sudo apt-get install smstools<br />

Next you’ll need to configure the software for your<br />

modem and scripts.<br />

Configuration file<br />

The configuration file is a bit unwieldy, but thankfully<br />

it comes with some sane default settings. Edit the file<br />

in your favourite text editor:<br />

sudo vim /etc/smsd.conf<br />

Modem Configuration<br />

First up you will need to configure your modem. The<br />

modem configuration is at the end of the config file,<br />

and the exact parameters will vary depending on what<br />

modem you have. Let’s have a look at what I needed:<br />

[GSM1]<br />

device = /dev/ttyUSB0<br />

init = AT^CURC=0<br />

incoming = yes<br />

baudrate = 115200<br />

hacker bits<br />

51


“<br />

device is where you specify the file descriptor for<br />

your modem. If you’re using a USB modem, this will<br />

almost allways be /dev/ttyUSB0.<br />

init specifies AT commands needed for your modem.<br />

Some modems require initialisation commands<br />

before they start doing anything. There are two strategies<br />

here, either find the manual for your modem,<br />

or take advantage of the SMSTools Forums to find a<br />

working configuration from someone else.<br />

incoming is there to tell SMSTools you want to<br />

use this device to receive messages.<br />

baudrate is, well, the baud rate needed for<br />

talking to the device.<br />

Like I said, there are many options to pick from,<br />

but this is the bare minimum I needed. Check the<br />

SMSTools website and forum for help!<br />

Event Handler<br />

The other big important part of the config file is the<br />

event handler. Here you can specify a script/program<br />

that is run every time a message is sent or received.<br />

From this script you can do any processing you need,<br />

and could even reply to incoming messages.<br />

eventhandler = /home/michael/smstools/sql_<br />

insert<br />

My script is some simple Bash which inserts a message<br />

into a database, but more on that in a moment.<br />

Sending messages<br />

Sending SMS messages is super easy.<br />

Sending SMS messages is super easy. Smsd looks<br />

in a folder, specified in the config file, for outgoing<br />

messages. Any files that appear in this folder get sent<br />

automatically. By default this folder is /var/spool/sms/<br />

outgoing.<br />

An SMS file contains a phone number to send to<br />

(including country code, but with out the +) and the<br />

body of the message. For example:<br />

To: 61412345678<br />

This is a text message sent by smstools.<br />

Awesome!<br />

Easy! Just put files that look like this into the folder<br />

and you’re sending messages.<br />

Receiving messages<br />

Let’s have a better look at the event handler. Remember,<br />

this script is called every time a message is sent<br />

or received. The information about the message is<br />

given to your program as command line arguments:<br />

1. The event type. This will be either SENT,<br />

RECEIVED, FAILED, REPORT, or CALL.<br />

We’re only interested in RECEIVED here.<br />

2. The path to the SMS file. You read this file to<br />

do whatever you need with the message<br />

You can use any programming language to work with<br />

the message. However, it is very easy to use formail<br />

and Bash. For example:<br />

#!/bin/bash<br />

#run this script only when a message was<br />

received.<br />

if [ "$1" != "RECEIVED" ]; then exit; fi;<br />

#Extract data from the SMS file<br />

SENDER=`formail -zx From: < $2`<br />

TEXT=`formail -I ""


Troubleshooting<br />

That’s all you need to write programs that can send<br />

and receive SMS messages on Linux. Once you have<br />

smsd actually talking to your modem it’s pretty easy.<br />

However, in practice it’s also fragile.<br />

The smsd log file is incredibly useful here. It lives<br />

in /var/log/smstools/smsd.log<br />

Here are some of the errors I encountered and what<br />

to do about them:<br />

Modem Not Registered<br />

You’ll see an error that looks like this:<br />

GSM1: MODEM IS NOT REGISTERED, WAITING 1<br />

SEC. BEFORE RETRYING<br />

This means the modem has lost reception, and is trying<br />

to re-establish a connection. Unfortunately there is<br />

nothing you can do here but wait or, using a USB<br />

extension cable, trying to find a spot with better reception.<br />

Write To Modem Error<br />

An error like this:<br />

GSM1: write_to_modem: error 5: Input/output<br />

error<br />

4. Plug the modem back in<br />

5. Start smsd (sudo service smstools start)<br />

Cannot Open Serial Port<br />

You may see this error:<br />

Couldn’t open serial port /dev/ttyUSB0,<br />

error: No such file or directory<br />

This occurs if you started the computer (and therefore<br />

smsd) before plugging in the modem. Follow the<br />

steps above to fix it.<br />

Conclusion<br />

So there you have it. Follow these steps and you can<br />

send and receive SMS messages on Linux, using a<br />

cheap prepaid SIM and GSM modem.<br />

In the next post we’ll be looking at exactly what I<br />

used this setup for. •<br />

Michael is a freelance developer in South Australia. He obtained<br />

his PhD in 2013 researching novel user interfaces for spatial<br />

augmented reality. He likes working at the intersection of art and<br />

technology on projects that use new ways of interacting with<br />

computers. Michael is Chair of the Board and an announcer at<br />

community radio station Three D Radio in Adelaide, and likes<br />

making music and noise. @MichaelMarner<br />

means the software can no longer communicate with<br />

the modem. This is usually caused by the modem being<br />

accidentally unplugged, the modem being plugged<br />

in after the system has powered up, or by an intermittent<br />

glitch in the USB driver. To fix this, do the following:<br />

1. Stop smsd (sudo service smstools stop)<br />

2. Unplug the modem<br />

3. Wait 10 seconds or so<br />

Reprinted with permission of the original author. First appeared at 20papercups.net.<br />

hacker bits<br />

53


PROGRAMMING<br />

How Elm made<br />

our work better<br />

By OSSI HANHINEN<br />

Elm is a beginner friendly<br />

functional reactive programming<br />

language for building<br />

web frontend. Choosing Elm for<br />

a customer project made my job<br />

nicer than ever and helped maintain<br />

project velocity during months of<br />

development. This boils down to<br />

two things, in my opinion:<br />

1. Elm restricts the way you<br />

program, resulting in maintainable<br />

code no matter what.<br />

2. There are no runtime exceptions<br />

so debugging is way<br />

less of an issue.<br />

At the Reactive 2015 conference,<br />

where I gave a lightning talk on<br />

54 hacker bits


Elm compiler errors can be super helpful<br />

assumption was that we would use<br />

React to build the frontend, but I<br />

wasn't convinced of its merits. We<br />

talked about Cycle.js, ClojureScript<br />

and Reagent, and my recent endeavors<br />

with Elm.<br />

In the end, we decided to just<br />

give Elm a try and quickly fall back<br />

to Reagent or React if it doesn't<br />

work out. We figured we should try<br />

and make the trickiest parts (technology-wise)<br />

first, so we could fail<br />

early.<br />

Here's how I originally put it in<br />

the project README:<br />

stateless web UI rendering, many<br />

people asked me: "How hard is it<br />

to debug compiled Elm code on the<br />

browser?" I was more than a little<br />

confused by these questions, until I<br />

remembered what it's like to write<br />

JavaScript. You make a change,<br />

switch to browser, set up debugging<br />

stops, click on a few things<br />

in the app, check the debugger and<br />

go "Uhhh... How did that happen?<br />

Maybe I should console.log<br />

something?"<br />

Writing Elm, on the other hand,<br />

is like this: you make a change,<br />

check the superb compiler errors,<br />

fix them. Next. Of course, you<br />

should then switch to the browser<br />

and check that it actually does what<br />

you wanted, but the point is: you<br />

don't spend half the time coding<br />

digging through the debugger.<br />

Despite being a whole new<br />

language to learn, I would argue<br />

the gains of the language design<br />

can far outweigh the "loss of time"<br />

while learning. JavaScript is, after<br />

all, a very very convoluted language<br />

with myriads of different<br />

libraries, frameworks, linters et<br />

cetera to try and make dealing with<br />

it less painful.<br />

Based on my experiences, I<br />

wholeheartedly recommend Elm<br />

for all bigger frontend application<br />

projects from now on. There are<br />

parts that are more cumbersome<br />

than in JavaScript, for sure. But<br />

all things considered, I value the<br />

guarantees Elm provides far more<br />

than the ability to do things quick<br />

'n' dirty.<br />

How we chose Elm<br />

In the Summer of 2015 I had a<br />

stroke of luck. I got into a project,<br />

where there were no restrictions on<br />

the frontend technology. We were<br />

tasked with building a web application<br />

for a select few expert users,<br />

from scratch. The browser support<br />

target reflected the fact: Latest<br />

Chrome.<br />

I sat down with Henrik Saksela<br />

to discuss our options. The baseline<br />

Less complexity<br />

The main properties and<br />

benefits of using Elm instead<br />

of plain JavaScript are the<br />

following:<br />

• Strong static types →<br />

finding errors fast with<br />

readable compiler messages<br />

• No null or undefined →<br />

impossible to leave possible<br />

problems unhandled<br />

• Immutability & purity →<br />

readability and maintainability<br />

• No runtime exceptions →<br />

uncomparable reliability<br />

• Reactive by design →<br />

FRP isn't opt-in, it is<br />

baked right in the language<br />

Months later (see next figure)...<br />

hacker bits<br />

55


Tweet of project stats<br />

way and there is no way around it.<br />

Everything in Elm is immutable,<br />

from "variables" to<br />

function definitions to records<br />

(which are a bit like JS objects).<br />

That means rendering a view, for<br />

example, cannot possibly have an<br />

effect on the application state. And<br />

that the dreaded "global state" is<br />

actually a very nice thing - since<br />

we can be sure nothing is changing<br />

it in secret.<br />

The Elm pattern is the following:<br />

The project<br />

The application was a tool for<br />

quickly managing news website<br />

content. In essence, the articles on<br />

the site's main pages are curated<br />

by a handful of experts 24/7, and<br />

our tool was the means for doing<br />

that efficiently. Futurice was also<br />

responsible for the design, both<br />

user interaction and graphics, and<br />

building the backend service, so<br />

we had a great cohesion within the<br />

whole project.<br />

The interaction was heavily<br />

based on drag-and-drop. To place<br />

an article on the page, the user<br />

would drag it from the side panel<br />

into the main panel. Similarly,<br />

“<br />

modules (article groups) could be<br />

dragged up and down on the page<br />

to determine their order.<br />

Architecture<br />

Note: Back when we started the<br />

project, StartApp wasn't as big a<br />

thing as it is now. It might have<br />

guided our approach to a different<br />

direction, but we feel our architectural<br />

choices resulted in a great<br />

solution in this case.<br />

The Elm Architecture outlines<br />

the basic pattern of Model, Update<br />

and View. This is in fact a mandatory<br />

separation in any Elm application.<br />

The language just works that<br />

• Define the shape of the data<br />

(model)<br />

• Define Actions and how to<br />

react to them (update)<br />

• Define how to show the state<br />

(view)<br />

Dissecting the state<br />

Having worked with Virtual DOM<br />

and immutable structures before,<br />

me and Henrik reasoned we could<br />

try and rely on the backend data --<br />

forgoing frontend state completely.<br />

This simple idea worked out really<br />

well for us.<br />

We came to think about "application<br />

state" in this manner:<br />

Go and learn Elm. Seriously. It is the<br />

simplest language I have ever tried...<br />

56 hacker bits


• The UI can be in different<br />

states regarding views, ongoing<br />

drag-and-drop actions and so<br />

on, which should not persist<br />

between sessions. This is our<br />

UiState.<br />

• The backend represents the real<br />

was a bit more involved than the<br />

standard pattern, though:<br />

• Define the shape of the data on<br />

the backend (model)<br />

• Define Actions that get turned<br />

into Tasks<br />

that instead of updating models<br />

immediately based on an Action,<br />

we used the actions to determine<br />

which HTTP calls are necessary to<br />

comply to the user's intent. These<br />

calls then resolve to either a failing<br />

or succeeding scenario. Both of<br />

The Elm pattern<br />

state of the world, or all data<br />

that should persist. This is our<br />

DataState.<br />

UiState was handled like in any<br />

other Elm application, updating the<br />

state based on Actions.<br />

The way we handled DataState<br />

• Define HTTP call tasks that get<br />

turned into succeed/fail Actions<br />

• Define how to react to the succeed/fail<br />

actions (update)<br />

• Define how to show the state<br />

(view)<br />

How our pattern differed from<br />

a standard Elm application was<br />

these are then translated to updates<br />

- be it showing a notification about<br />

the error or changing the data. In<br />

short, we had a fully "pessimistic"<br />

UI that would save the state to the<br />

backend on every change. Pessimistic<br />

means that we never assume<br />

an operation to succeed, but instead<br />

we rely only on facts: what (if at<br />

all) the server responds.<br />

hacker bits<br />

57


The way we update the backend-provided<br />

data in the Elm application<br />

was the main kicker, though.<br />

Once we've POSTed a change to a<br />

list in the backend, we simply GET<br />

the whole list from the backend<br />

one place to another (which would<br />

imply a data change).<br />

There were two main concerns<br />

to this approach: 1) is the UI responsive<br />

enough with backend-only<br />

updates, and 2) is it madness<br />

In our experiments using a wireless<br />

connection (actual users have wired<br />

connections), we found the heaviest<br />

updates took about 600ms on average.<br />

This was before we optimized<br />

the caching, which sped things up<br />

Our model for pessimistic UI updates<br />

and replace the whole thing in our<br />

model. This means the state can<br />

never be inconsistent between the<br />

backend and the frontend. We also<br />

made sure only one of these tasks<br />

could be running at once simply<br />

by deferring data-changing user<br />

interactions until the UI had updated.<br />

The user could still scroll and<br />

click on things while the task was<br />

running, but not drag things from<br />

to discard and replace the whole<br />

model on update. As it turns out,<br />

concern 2 was mostly unfounded.<br />

The Virtual DOM in elm-html does<br />

the heavy lifting, so on the browser<br />

only an updated item gets re-rendered.<br />

Concern 1 was valid though.<br />

As previously stated, our project<br />

was an expert tool. It would only<br />

be used from within the customer<br />

network, using desktop computers.<br />

ten-fold. As a result, pretty much<br />

all updates happen in consistently<br />

under 300ms, which is great!<br />

Strictness - a mixed<br />

blessing?<br />

The strictness of Elm proved invaluable.<br />

Since the compiler won't<br />

let you disregard a potential failure<br />

even when trying out something,<br />

58 hacker bits


there is no way some of them<br />

might end up in production code.<br />

Coupled with total immutability the<br />

language itself enforces good functional<br />

programming practices.<br />

The place where Elm's restrictions<br />

can become hardships<br />

are when dealing with the outside<br />

world. For one, you need to<br />

provide full modeling of the data<br />

structure if you wish to parse a<br />

JSON response from the server.<br />

And you need to take into account<br />

that the parsing may fail at that<br />

point. This all seems obvious once<br />

you get familiar with Elm's type<br />

system, though. If your API is a<br />

little "tricky" - for example the<br />

response JSON can have certain<br />

properties that define which other<br />

properties are available - you may<br />

need to jump through hoops to<br />

make that work.<br />

Another thing is interoperability<br />

with JavaScript libraries. First<br />

off though: Elm has its FRP and<br />

functional utilities built-in, and<br />

the elm-html package comes with<br />

virtual-dom, so there's no need for<br />

stuff like Lodash, React or Redux.<br />

But if you do need to interact<br />

with JavaScript, the mechanism for<br />

that is called Ports. Ports are essentially<br />

strictly typed event streams<br />

to listen to (Elm to JS) or to push<br />

events into (JS to Elm). This means<br />

you will need to write some boilerplate-ish<br />

code, both in Elm and<br />

in JavaScript, in order to pass a<br />

message to the other side. So the<br />

more JavaScript libraries you need,<br />

and the more different kinds of<br />

objects you want to pass through,<br />

the more boilerplate code you will<br />

end up with.<br />

That said, Elm is still fairly<br />

young and seems to be quickly<br />

gaining recognition in the aftermath<br />

of the "functional web frontend<br />

tsunami" React and friends<br />

brought about. The fact some<br />

commonly used library alternatives<br />

are still missing could soon turn.<br />

And while we're on the topic of<br />

dependencies, Elm has one more<br />

ace up its sleeve: the package<br />

system enforces semantic versioning.<br />

Because of the strict typing,<br />

the package manager can infer any<br />

outfacing changes to the package<br />

source code and determine the version<br />

number on its own. No more<br />

sudden breaking because an NPM<br />

package upgraded from 0.14.3 to<br />

0.15.0!<br />

Conclusions<br />

Go and learn Elm. Seriously. It is<br />

the simplest language I have ever<br />

tried, and the team has put a crazy<br />

lot of effort into making the developer<br />

experience as nice as possible.<br />

The syntax may seem daunting<br />

at first, but don't fret. It's like getting<br />

a nice new sweater. A few days<br />

in, you'll be familiar with it and<br />

from then on it's like you've always<br />

known it. In our project, two out of<br />

three developers had never coded<br />

in Elm before. Both of them got up<br />

to speed and were productive in a<br />

couple of weeks. Even the sceptic<br />

told me that once he got over the<br />

initial shock, he found Elm a very<br />

nice language and a good fit for the<br />

project.<br />

A compiled Elm application<br />

has a whole FRP implementation<br />

built in, so it might not make sense<br />

to use it for very small things on a<br />

mostly static web page. For these<br />

kinds of uses, you may be better<br />

off with e.g. PureScript. PureScript<br />

is, however, much harder to learn<br />

without a solid prior understanding<br />

of functional programming concepts.<br />

There are other differences<br />

between the two as well, such as<br />

the way they handle data. Elm uses<br />

persistent data structures under the<br />

hood, which means better performance<br />

in big apps. PureScript<br />

resorts to standard JavaScript data<br />

structures, which results in smaller<br />

compiled files.<br />

To get started with Elm, I<br />

recommend reading through the<br />

official Elm documentation and<br />

checking out the links at Awesome<br />

Elm. When I was first learning the<br />

language, I wrote an introductory<br />

article that describes the basic syntax<br />

and the model-update-view pattern:<br />

Learning FP the hard way. •<br />

Ossi has been writing web stuff since he<br />

was in elementary school. He is always<br />

trying to learn something new and interesting<br />

— nowadays surrounded by the<br />

brilliant people of Futurice.<br />

Reprinted with permission of the original author. First appeared at futurice.com/blog.<br />

hacker bits<br />

59


PROGRAMMING<br />

Two weeks of rust<br />

By MARTIN MATUSIAK<br />

Disclaimer: I'm digging Rust. I lost<br />

my hunger for programming from<br />

doing too many sad commercial<br />

projects. And now it's back. You<br />

rock, Rust!<br />

I<br />

spent about two weeks over<br />

the Christmas/New Year break<br />

hacking on emcache, a memcached<br />

clone in Rust. Why a memcached<br />

clone? Because it's a simple<br />

protocol that I understand and is<br />

not too much work to implement.<br />

It turns out I was<br />

“<br />

in for a really fun<br />

time.<br />

Upsides<br />

The build system<br />

and the package<br />

manager is one of<br />

the best parts of<br />

Rust. How often do you hear that<br />

about a language? In Python I try<br />

to avoid even having dependencies<br />

if I can, and only use the standard<br />

library. I don't want my users to<br />

have to deal with virtualenv and<br />

pip if they don't have to (especially<br />

if they're not pythonistas). In<br />

Rust you "cargo build". One step,<br />

all your dependencies are fetched,<br />

built, and your application with it.<br />

No special cases, no build scripts,<br />

no surprising behavior *whatsoever*.<br />

That's it. You "cargo test". And<br />

you "cargo build --release" which<br />

makes your program 2x faster (did<br />

I mention that llvm is pretty cool?)<br />

Rust *feels* ergonomic. That's<br />

the best word I can think of. With<br />

every other statically compiled<br />

language I've ever used too much<br />

of my focus was being constantly<br />

diverted from what I was trying to<br />

accomplish to annoying little busy<br />

work the compiler kept bugging me<br />

about. For me Rust is the first statically<br />

typed language I enjoy using.<br />

Rust *feels* ergonomic.<br />

That's the best word I<br />

can think of.<br />

Indeed, ergonomics is a feature in<br />

Rust - RFCs talk about it a lot. And<br />

that's important, since no matter<br />

how cool your ideas for language<br />

features are you want to make sure<br />

people can use them without having<br />

to jump through a lot of hoops.<br />

Rust aims to be concise. Function<br />

is fn, public is pub, vector is<br />

vec, you can figure it out. You can<br />

never win a discussion about conciseness<br />

because something will<br />

always be too long for someone<br />

while being too short for someone<br />

else. Do you want u64 or do you<br />

want WholeNumberWithoutPlusOrMinusSignThatFitsIn64<strong>Bits</strong>?<br />

The point is Rust is concise and<br />

typeable, it doesn't require so much<br />

code that you need an IDE to help<br />

you type some of it.<br />

Furthermore, it feels very composable.<br />

As in: the things you make<br />

seem to fit together well. That's<br />

a rare quality in languages, and<br />

almost never happens to me on a<br />

first project in a new language. The<br />

design of emcache is actually<br />

nicely decoupled, and<br />

it just got that way on the<br />

first try. All of the components<br />

are fully unit tested,<br />

even the transport that<br />

reads/writes bytes to/from<br />

a socket. All I had to do<br />

for that is implement a TestStream<br />

that implements the traits Read and<br />

Write (basically one method each)<br />

and swap it in for a TcpStream.<br />

How come? Because the components<br />

provided by the stdlib *do*<br />

compose that well.<br />

But there is no object system!<br />

Well, structs and impls basically<br />

give you something close enough<br />

that you can do OO modeling<br />

anyway. It turns out you can even<br />

do a certain amount of dynamic<br />

60 hacker bits


“<br />

The standard library<br />

is rather small,<br />

and you will need<br />

to go elsewhere<br />

even for certain<br />

pretty simple things<br />

like random numbers<br />

or a buffered stream.<br />

dispatch with trait objects, but<br />

that's something I read up on after<br />

the fact. The one thing that is<br />

incredibly strict in Rust, though,<br />

is ownership, so when you design<br />

your objects (let's just call them<br />

them that, I don't know what else to<br />

call them) you need to decide right<br />

away whether an object that stores<br />

another object will own or borrow<br />

that object. If you borrow you need<br />

to use lifetimes and it gets a bit<br />

complicated.<br />

Parallelism in emcache is<br />

achieved using threads and channels.<br />

Think one very fast storage<br />

and multiple slow transports. Channels<br />

are async, which is exactly<br />

what I want in this scenario. Like<br />

in Scala, when you send a value<br />

over a channel you don't actually<br />

"send" anything, it's one big shared<br />

memory space and you just transfer<br />

ownership of an immutable value<br />

in memory while invalidating<br />

the pointer on the "sending" side<br />

(which probably can be optimized<br />

away completely). In practice,<br />

channels require a little typedefing<br />

overhead so you can keep things<br />

clear, especially when you're<br />

sending channels over channels.<br />

Otherwise I tend to get lost in what<br />

goes where. (If you've done Erlang/<br />

OTP you know that whole dance<br />

of a tuple in a tuple in a tuple, like<br />

that Inception movie.) But this case<br />

stands out as atypical in a language<br />

where boilerplate is rarely needed.<br />

Macros. I bet you expected<br />

these to be on the list. To be honest,<br />

I don't have strong feelings<br />

about Rust's macros. I don't think<br />

of them as a unit of design (Rust<br />

is not a lisp), that's what traits are<br />

for. Macros are more like an escape<br />

hatch for unpleasant situations.<br />

They are powerful and mostly nice,<br />

but they have some weird effects<br />

too in terms of module/crate visibility<br />

and how they make compiler<br />

error messages look (slightly more<br />

confusing I find).<br />

The learning resources have<br />

become very good. The Rust book<br />

is very well written, but I found<br />

it a tough read at first. Start with<br />

Rust by example, it's great. Then<br />

do some hacking and come back to<br />

"the book", it makes total sense to<br />

me now.<br />

No segfaults, no uninitialized<br />

memory, no coercion bugs, no data<br />

races, no null pointers, no header<br />

files, no makefiles, no autoconf,<br />

no cmake, no gdb. What if all the<br />

problems of c/c++ were fixed with<br />

one swing of a magic wand? The<br />

hacker bits<br />

61


future is here, people.<br />

Finally, Rust *feels* productive.<br />

In every statically compiled<br />

language I feel I would go way<br />

faster in Python. In Rust I'm not so<br />

sure. It's concise, it's typeable and<br />

it's composable. It doesn't force me<br />

to make irrelevant nit picky decisions<br />

that I will later have to spend<br />

tons of time refactoring to recover<br />

from. And productivity is a sure<br />

way to happiness.<br />

Downsides<br />

The standard library is rather<br />

small, and you will need to go elsewhere<br />

even for certain pretty simple<br />

things like random numbers or<br />

a buffered stream. The good news<br />

is that Rust's crates ecosystem has<br />

already grown quite large and there<br />

seem to be crates for many of these<br />

things, some even being incubated<br />

to join the standard library later on.<br />

While trying to be concise,<br />

Rust is still a bit wordy and syntax<br />

heavy with all the pointer types and<br />

explicit casts that you see in typical<br />

code. So it's not *that easy* to<br />

read, but I feel once you grasp the<br />

concepts it does begin to feel very<br />

logical. I sure wouldn't mind my<br />

tests looking a bit simpler - maybe<br />

it's just my lack of Rust foo still.<br />

The borrow checker is tough,<br />

everyone's saying this. I keep<br />

“<br />

Language design is really hard,<br />

and sometimes you succeed.<br />

running into cases where I need to<br />

load a value, do a check on it, and<br />

then make a decision to modify or<br />

not. Problem is the load requires a<br />

borrow, and then another borrow is<br />

used in the check, which is enough<br />

to break the rules. So far I haven't<br />

come across a case I absolutely<br />

couldn't work around with scopes<br />

and shuffling code around, but<br />

I wouldn't call it fun - nor is the<br />

resulting code very nice.<br />

Closures are difficult. In your<br />

run-of-the-mill language I would<br />

say "put these lines in a closure, I'll<br />

run them later and don't worry your<br />

pretty little head about it". Not so<br />

in Rust because of move semantics<br />

and borrowing. I was trying to<br />

solve this problem: how do I wrap<br />

(in a minimally intrusive way) an<br />

arbitrary set of statements so that I<br />

can time their execution (in Python<br />

this would be a context manager)?<br />

This would be code that might<br />

mutate self, refers to local vars<br />

(which could be used again after<br />

the closure), returns a value and so<br />

on. It appears tricky to solve in the<br />

general case, still haven't cracked<br />

it.<br />

*mut T is tricky. I was trying to<br />

build my own LRU map (before I<br />

knew there was a crate for it), and<br />

given Rust's lifetime rules you can't<br />

do circular references in normal<br />

safe Rust. One thing *has to*<br />

outlive another in Rust's lifetime<br />

model. So I started hacking together<br />

a linked list using *mut T (as<br />

you would) and I realized things<br />

weren't pointing to where I thought<br />

they were at all. I still don't know<br />

what happened.<br />

The builder pattern. This is an<br />

ugly corner of Rust. Yeah, I get that<br />

things like varargs and keyword arguments<br />

have a runtime overhead.<br />

But the builder pattern, which is to<br />

say writing a completely separate<br />

struct just for the sake of constructing<br />

another struct, is pure boilerplate,<br />

it's so un-Rust. Maybe we<br />

can derive these someday?<br />

Code coverage. There will<br />

probably be a native solution for<br />

this at some point. For now people<br />

use a workaround with kcov, which<br />

just didn't work at all on my code.<br />

Maybe it's because I'm on nightly?<br />

Fixed!<br />

So there you have it. Rust is<br />

a fun language to use, and it feels<br />

like an incredibly well designed<br />

language. Language design is<br />

really hard, and sometimes you<br />

succeed. •<br />

Martin is a software engineer working<br />

mostly in Python on various web stuff.<br />

He's always looking for interesting new<br />

developments in programming languages,<br />

though, and Rust really seems like a<br />

language worth investing in.<br />

Reprinted with permission of the original author. First appeared at matusiak.eu/numerodix.<br />

62 hacker bits


food bit *<br />

The hairy uses of caramel…<br />

Hair is probably the last thing<br />

you’ll want on a piece of caramel,<br />

but amazingly, sticky caramel<br />

has been used to remove unwanted<br />

hair for centuries. It’s a popular form<br />

of hair removal in the Arab world,<br />

where it first originated. Known as<br />

sugaring, the method calls for smearing<br />

liquid caramel onto hairy body<br />

parts, and then sticking a strip of cloth<br />

to the area. The cloth strip is then<br />

violently ripped off, along with most<br />

of the caramel and hair.<br />

* FOOD BIT is where we, enthusiasts of all edibles,<br />

sneak in a fun fact about food.


hacker bits<br />

HACKER BITS is a curated collection of the most popular articles on <strong>Hacker</strong> News — a social news<br />

website widely considered among programmers and entrepreneurs to be the best of its kind.<br />

Every month, we select the top voted articles on <strong>Hacker</strong> News and publish them in magazine format.<br />

For more, visit hackerbits.com.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!