
A peek under Bitcoin’s hood: Writing a client that can create a transaction - samlewis
http://www.samlewis.me/2017/06/a-peek-under-bitcoins-hood/
======
mason55
Article says

> _This is also why address reuse in Bitcoin is encouraged as to sign a
> transaction you need to reveal your public key. If you don 't reuse an
> address after sending a transaction from the address, you don't need worry
> about the private key of that address being exposed._

Shouldn't that say "address reuse in Bitcoin is _discouraged_ "? Otherwise I
don't think I understand what he's trying to say.

~~~
narrator
Address reuse only becomes a problem in the theoretical case that someone can
determine the private key from a signature. This would only happen if there
was some sort of breakthrough in cryptoanalysis of elliptic curve
cryptography, which while theoretically possible, is unlikely.

~~~
Obi_Juan_Kenobi
The idea is that you don't want to be secure now, but also in the future. The
ECC Bitcoin uses is vulnerable to Shor's algorithm, and thus quantum
computation. Quantum computing at that scale is a fair ways off, most likely,
but on a timescale of a couple decades or more, a successful attack seems
quite reasonable.

Bitcoin can soft-fork, allowing address generation with a different algorithm.
It's not any sort of existential threat to Bitcoin. But it does require that
you move your coins to a new address if you reuse an address, else you are
vulnerable.

------
hdhzy
Very cool. This could be used to implement offline wallet with minimal amount
of third party code.

One issue I'd like to point is I wish the author used proper random generated
private key. Examples on the internet have a nasty habits of being copy pasted
and reused verbatim :(

~~~
jerguismi
Not using cryptographically safe random key is very stupid, even though it is
only an example. It should be very trivial to fix this example.

I think in python the right way is to use the os.urandom() function.

------
afeezaziz
Hi Sam,

If you're reading the comments, can you do this treatment but for Ethereum and
the smart contracts built on top of it?

I find that your article gives a good explanation especially for beginner to
understand from the code perspective.

~~~
ecesena
FWIW, I was looking at eth code in the weekend and it's pretty accessible (I
was looking at go -- I've read that eth python should be even more readable).

The address part is very similar, even simpler, than bitcoin. It's the same
elliptic curve, same way to build private/public keys.

For the address, it uses a different hash function, Keccak256, and then it's
just serialized in hex. Code here [1]. Pointers to key generation [2, 3].

[1] [https://github.com/ethereum/go-
ethereum/blob/release/1.6/cry...](https://github.com/ethereum/go-
ethereum/blob/release/1.6/crypto/crypto.go#L181)

[2] [https://github.com/ethereum/go-
ethereum/blob/release/1.6/acc...](https://github.com/ethereum/go-
ethereum/blob/release/1.6/accounts/keystore/key.go#L169)

[3] [https://github.com/ethereum/go-
ethereum/blob/release/1.6/acc...](https://github.com/ethereum/go-
ethereum/blob/release/1.6/accounts/keystore/key.go#L138)

~~~
tuxxy
Keccak256? Isn't that just SHA3 with a digest of 256 bits?

~~~
ecesena
I'm unsure. I think this came before sha3 was defined so some parameters may
have changed. But the core is essentially that.

~~~
tylersmith
There are minor padding differences but that's it.

------
ryan-c
Looks like there was bitcoin left in the address he published the private key
for until about 30 minutes ago. I hope that was a deliberate giveaway.

[https://blockchain.info/tx/2685ff794de17cebdf94eb0f111e8b8c0...](https://blockchain.info/tx/2685ff794de17cebdf94eb0f111e8b8c03529a9ae628909cef4090663b54e565)

~~~
samlewis
I did deliberately leave that there in the hope someone might take it using
what they'd learnt from the article. there's a short note about this in the
conclusion to the article. From the "non whole" fee amount it looks as though
someone might have just used some sort of wallet software to take it though,
which is a shame.

------
nurettin
>> 0xFACEBEEF and sent it 0.0005 BTC.. 1 month later and someone had stolen my
0.0005 BTC! I guess people must occasionally trawl through addresses with
simple/common private keys.

This made it worth reading the article. Such cyberpunk!

~~~
thefalcon
For fun[1], you can occasionally trawl through addresses with _any private
key_!

[http://directory.io/](http://directory.io/)

[1] For various definitions of "fun."

~~~
293984j29384
Their FAQ (unlisted on the main page) is interesting as well..

[https://directory.io/faq](https://directory.io/faq)

------
donpdonp
This is an excellent writeup! If any readers are looking for an already-
written and tested bitcoin client library and can use javascript,
[https://bitcoinjs.org/](https://bitcoinjs.org/) is great. I wrapped a simple
cli tool around the library to make the 'coindust' npm package to do simple
operations with bitcoin addresses and public bitcoin APIs.

------
ryan-c
I am actually really surprised it took a month for someone to swipe the BTC he
sent to an address with a private key of 0xfacebeef. That could be found via
an incremental search in under an hour of CPU search time on one computer.

I note that compressed public keys are not being used in these examples - it's
highly recommended to use them, since they reduce transaction size and cost.

Regarding weak keys - there have been a lot of weak key generation techniques
in bitcoin where hiding the public key won't do you any good.

~~~
lordnacho
Just a warning for people, I was playing around with BTC the other day and not
generating random entropy from urandom, just putting in a short string.

I found my BTC was stolen immediately when I did this. It wasn't a lot of
coins, since I was just testing, but it certainly cost me some debugging time
as I wondered how the extra transaction had occurred.

Basically, someone out there has already generated the keys corresponding to
short strings and is keeping an eye on any transactions on them. Maybe more
than one group, who knows?

~~~
tylersmith
There are many of us with bots sweeping weak keys. Some of us give the coins
back to a safe address, some people just keep it. It's like finding money on
the sidewalk.

~~~
null0pointer
A lot of people are equating this to theft. While I can see their point, the
concept of ownership in bitcoin is closely tied to control of the private
keys. In this case many people control certain weak private keys so in a way
you are giving your money away by sending to these addresses.

~~~
ryan-c
Taking money from someone who did not intend to give it to you is a dick move,
regardless of legality or technical difficulty of doing so.

~~~
tylersmith
If it can be taken, somebody is going to take it. It can be people that intend
to keep it, or could be a person to intends to give it back. If you left a
bunch of money unsecured, which would you prefer? Not having it taken isn't an
option if you use a weak key.

------
philfrasty
Can someone explain why bitcoin adresses can be created (offline) without
blockchain-validation for duplicates?

Even if the chances are very small I mean...like....gone is gone...no bank to
call for a false transaction.

~~~
adrianmacneil
Bitcoin addresses are basically a public key, so you can generate them offline
the same way you can generate pgp keys, openssl keys, SSH keys you use to
access GitHub etc.

The chances of a collision are so astronomically low that our sun will
probably run out of fuel and explode before two identical keys are generated.

~~~
philfrasty
With the comfort of a public blockchain at hand why not eliminate this case at
address-creation time?

~~~
KMag
Let's do some back-of-the-envelope calculations.

Let's say the probability of someone cloning a Velociraptor within the next 20
years is 1 in 1 trillion. Let's say that given a Velociraptor has been cloned,
it has a probability of 1 in 1 million of escaping. Let's say that given a
Velociraptor is on the lam, it has a 1 in 100 billion chance of breaking into
your house. Let's say that if there's a Velociraptor in your house, checking
for it increases your chance of survival by 1%.

Let's assume there are 1 quadrillion Bitcoin addresses created.

Under the assumption of correct implementation, checking for velociraptors in
your closet is literally more rational than checking for duplicate addresses.

Now, there is some value in checking for duplicate keys as a safeguard against
implementation bugs, but that's best covered by generating a billion addresses
on your own and checking for duplicates within your personal set.

~~~
293984j29384
From now on, I'm going to start my explanations about how Bitcoin addresses
work with opening a closet to look for velociraptors.

------
sprt
Wrt transactions, I don't understand why you need to send yourself the unspent
BTCs. Why does it make things significantly easier?

~~~
iso-8859-1
Because the miner almost always expects a fee, so why not just infer how high
it is and you don't need to spend block bytes on it?

~~~
sprt
Ok, but the unspent output takes space as well. I think you could just replace
it with the fee. Not sure if I'm missing something or if it was just an
arbitrary design decision.

~~~
samlewis
It has to do with the way transactions and the blockchain ledger works, reread
the transaction part of the article and it might make more sense. Basically,
transaction outputs can either be spent or unspent, you can't half spend an
output (or perhaps more accurately, you can't spend a previous output twice).

~~~
sprt
Yes I understand that's how it works, but I don't get why it's important.
Surely you could double spend an output as long as you don't exceed its value;
and that looks easily verifiable.

~~~
samlewis
Ah, my bad. Sorry if I was being condescending in my previous reply then.

I suspect it was a design decision, yeah. If outputs could be spent multiple
times then you'd need to traverse the chain of outputs backwards to see how
much an output has left in it. Bitcoin's implementation is less complex and
more elegant, imo.

