
Low-level Bitcoin - jc123
https://curiosity-driven.org/low-level-bitcoin
======
b1db77d2
A little note about the "make a privkey" section of the signature example; it
can sometimes* make invalid privkeys that are off the end of the EC curve.
Only integers between 0x1 and
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 are valid
in our particular case. Super unlikely to ever get a sha256 hash that matches
the invalid portion, but it's worthwhile to point out.

* probably never, but worth mentioning

~~~
oleganza
This curve order limit actually introduces a small bias. You can choose a
number greater than a curve order, but then it'll be taken modulo the order,
so some incredibly small amount of numbers will be biased closer to zero. In
practice the probability to hit such numbers is less than 2^-128, so you may
easily skip all checks and take the number as is. Of course, nitpickers will
nitpick and that's why in all standards that describe key and nonce generation
(BIP32, RFC 6979 etc), you'll see boilerplate code that checks for such
numbers and does some extra cumbersome computations just to avoid these from
happening.

------
VMG
Possible bug:

The instructions BOOLAND and BOOLOR don't interpret the stack values the same
way IF, VERIFY etc do. They decode the top stack values as integers and
compare against zero, thus they have to fail when the top stack item size is
greater than 4 bytes.

Edit: littleEndian.decode also doesn't seem to respect the size limits

Edit2: .. or signed integers for that matter. So while this is a very cool
basic concept, it's not a complete implementation.

The reference client provides test suites

[https://github.com/bitcoin/bitcoin/blob/master/src/test/data...](https://github.com/bitcoin/bitcoin/blob/master/src/test/data/script_valid.json)

[https://github.com/bitcoin/bitcoin/blob/master/src/test/data...](https://github.com/bitcoin/bitcoin/blob/master/src/test/data/script_invalid.json)

~~~
Theyeard
Yes, you're right, numbers treatment is not exactly the same as in Bitcoin
Core. The script interpreter supports only basics and it was implemented to
show how Bitcoin Script works in general for another article [0].

But it was not clear from this text whether it's a complete implementation or
not so it looks like a bug. I've added the annotation [1] and will update the
interpreter in the future.

Of course if one wanted to use Bitcoin in real projects I'd rather recommend
Bitcoin.js [2] but that's another topic.

Thanks for comment!

[0]: [https://curiosity-driven.org/bitcoin-contracts](https://curiosity-
driven.org/bitcoin-contracts)

[1]: [https://curiosity-driven.org/low-level-
bitcoin#operators](https://curiosity-driven.org/low-level-bitcoin#operators)

[2]: [http://bitcoinjs.org/](http://bitcoinjs.org/)

~~~
VMG
No problem - I wasn't sure if this is something you're currently working on or
just a demonstration. The script interpreter is a tricky beast that looks easy
but has a lot of edge cases. If one client behaves slightly different, a
blockchain fork could happen: [https://bitcoin.org/en/alert/2013-03-11-chain-
fork](https://bitcoin.org/en/alert/2013-03-11-chain-fork)

~~~
Theyeard
Yes, exactly. And there are a lot of tricky corner cases like SIGHASH_SINGLE
when number of inputs != number of outputs with hash 0x01 [0]. Actually the
entire implementation (Bitcoin Core) is the specification :) It's interesting
from the software design point of view - an extreme case of backwards
compatibility. It's hard even within Bitcoin Core as some changes already
caused forks [1].

The article is just a demonstration but it won't hurt if it was as accurate as
possible (while still being readable) :)

[0]
[https://en.bitcoin.it/wiki/OP_CHECKSIG#Procedure_for_Hashtyp...](https://en.bitcoin.it/wiki/OP_CHECKSIG#Procedure_for_Hashtype_SIGHASH_SINGLE)

[1] [http://bitcoinmagazine.com/3668/bitcoin-network-shaken-by-
bl...](http://bitcoinmagazine.com/3668/bitcoin-network-shaken-by-blockchain-
fork/)

------
norswap
This article had me wondering what will happen when people start storing
copyrighted data (or worse, pedopornographic images) inside the blockchain.

~~~
Theyeard
They already do that: [http://www.righto.com/2014/02/ascii-bernanke-wikileaks-
photo...](http://www.righto.com/2014/02/ascii-bernanke-wikileaks-
photographs.html)

Also related:
[http://en.wikipedia.org/wiki/Illegal_number](http://en.wikipedia.org/wiki/Illegal_number)

~~~
the_mitsuhiko
So what happens if someone puts CP into the block chain and publishes the
instructions to retrieve after two months?

~~~
qnr
Nothing. The way arbitrary data is stored in the blockchain is encoding it in
the financial transactional data.

For example, you could use a similar method to "store" data using Paypal: use
the amount of cents in each transaction to encode a byte of data (e.g. $1.17
means 0x75 etc.) and make transfers to random people until enough bytes have
been transferred. That's it, your copyrighted data or CP is now forever
"stored" on Paypal servers.

I don't think this accusation will hold up in any reasonable court. Taking
into account the cost of storing data (20 bytes in a single output of minimum
5400 satoshi + fees) your hypothetical instructions and code to retrieve the
images would be of comparable size to any images you can reasonably store.

~~~
maaku
There is no minimum output size. Outputs can be zero-valued.

~~~
qnr
The standard client and by extension most miners will reject outputs smaller
than a certain value ("dust")

You are correct that the protocol itself doesn't have a minimum output size,
so if you mine a block yourself you can include dust reliably.

