Intro to Bitcoin for
Developers
Yuri Pimenov, CTO @ Paybis
y.pimenov@paybis.com
http://coinside.ru
Used resources
● “Bitcoin developer guide” https://bitcoin.org/en/developer-guide
● “Mastering Bitcoin” https://github.com/bitcoinbook/bitcoinbook/
● “Mastering Bitcoin” in Russian and other languages
https://www.transifex.com/bitcoinbook/mastering-bitcoin/
● https://www.coursera.org/learn/cryptocurrency
Bitcoin is P2P
Blockchain is huge
What is Blockchain?
TL;DR: Blockchain is a linked list of blocks containing transactions!
Structure of a Block
Size Field Description
4 bytes Block Size The size of the block, in bytes, following this field
80 bytes Block Header Several fields form the block header
1-9 bytes (VarInt) Transaction Counter How many transactions follow
Variable Transactions The transactions recorded in this block
Block Header
Size Field Description
4 bytes Version A version number to track software/protocol upgrades
32 bytes Previous Block Hash A reference to the hash of the previous (parent) block
32 bytes Merkle Root A hash of the root of the merkle tree of this block’s transactions
4 bytes Timestamp The approximate creation time of this block (Unix Epoch)
4 bytes Difficulty Target The proof-of-work algorithm difficulty target for this block
4 bytes Nonce A counter used for the proof-of-work algorithm
What is Transaction?
TL;DR: Transactions are linked structures!
class COutPoint {
uint256 hash;
uint32_t n;
class CTxIn {
COutPoint prevout;
CScript scriptSig;
class CTxOut {
CAmount nValue;
CScript scriptPubKey;
class CTransaction {
vector<CTxIn> vin;
vector<CTxOut> vout;
Bitcoin transactions: an example
Common transaction forms
Cryptography
● HASH: 𝒇(“The quick brown fox...”) →
0xa3b634ffa1424…
Public key cryptography (Public Key & Private Key):
● SIGN: 𝓕(“The quick brown fox...”, PRIVATE_KEY) →
0xa583fa1dada…
● VERIFY: 𝓕’(0xa583fa1dada…, PUBLIC_KEY) → “The
quick brown fox...”
Elliptic curve
y2 = x3 + 7
Secp256k1
Elliptic curve cryptography
TL;DR: sign with private key, verify with public key
Generating private key
>>> import hashlib
>>> import os
>>> from pycoin import ecdsa, encoding
>>> import binascii
>>> rand = binascii.hexlify(os.urandom(32))
>>> rand
b'19450ccb2fd155fcd5933e1487d6295a7c6d83ce1c198a9b01c178af8
161d592'
>>> secret_exponent = int('0x' + rand.decode(), 0)
>>> secret_exponent
11429821960912496644762147021914232624305188114701093398105
624802483832477074
Generating public key
>>> private_key_wif =
encoding.secret_exponent_to_wif(secret_exponent)
>>> private_key_wif
'Kx4qCrgP6uRVkYrzqpkefPaWMz4JNAKNtB3ofmNjxqTZZQEiKBVs'
>>> public_pair =
ecdsa.public_pair_for_secret_exponent(ecdsa.secp256k1.gener
ator_secp256k1, secret_exponent)
>>> public_pair
(8383574116545539269076290525564606006885119882359933136746
6434419371333356943,
29390949121653277068495088942182866226704757294052224997547
313025682750397184)
Generating Bitcoin address
>>> hash160 =
encoding.public_pair_to_hash160_sec(public_pair)
>>> int('0x' + binascii.hexlify(hash160).decode(), 0)
451995369346927816479889813976421291895952315620
>>> encoding.hash160_sec_to_bitcoin_address(hash160)
'18DdJNbCYjo9nmAZAZZ2X3MYCv7gwoLvQn'
Sizes
len(private key) = 32 bytes (256 bit)
len(public key) = 64 bytes (or 32 bytes + 1 bit)
len(hash) = 20 bytes
1077 < 2256 < 1078
~ Number of atoms in the Universe
Bitcoin address
TL;DR: Address is a Base58 of pubkey hash + checksum
1. Hash = RIPEMD160(SHA256(K))
2. Csum = SHA256(SHA256(Version + Hash))
3. Address = Base58(Version + Hash + Csum[0:4])
Base58 alphabet:
0123456789
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
“Script” is like FORTH
“2 + 7 – 3 == 6” “2 7 OP_ADD 3 OP_SUB 6 OP_EQUAL”
2 [2]
7 [2; 7]
OP_ADD [9]
3 [9; 3]
OP_SUB [6]
6 [6; 6]
OP_EQUAL [TRUE]
Some “Script” operators
● OP_IF
● OP_SWAP
● OP_SUBSTR
● OP_CAT
● OP_ABS
● OP_MOD
● OP_SIZE
● OP_XOR
Transfer of ownership
Pay-to-Public-Key (obsolete)
scriptPubKey: <pubKey> OP_CHECKSIG
scriptSig: <sig>
<sig> <pubKey> OP_CHECKSIG
“OP_CHECKSIG is script opcode used to verify that the signature for a tx input is
valid. OP_CHECKSIG expects two values to be on the stack.”
scriptSig are digitally signed following data:
● ID (hash) of particular input (prev_out)
● double SHA of new transaction data
Pay-to-Public-Key-Hash (P2PKH) transaction
[<sig> <pubKey>]
+
[OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG]
Pay-to-Public-Key-Hash (P2PKH) transaction
<sig> <pubKey> OP_DUP OP_HASH160
<pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
OP_DUP OP_HASH160 <pubKeyHash>
OP_EQUALVERIFY OP_CHECKSIG
<sig> <pubKey>
OP_HASH160 <pubKeyHash> OP_EQUALVERIFY
OP_CHECKSIG
<sig> <pubKey> <pubKey>
<pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG <sig> <pubKey> <pubKeyHashA>
OP_EQUALVERIFY OP_CHECKSIG <sig> <pubKey> <pubKeyHashA>
<pubKeyHash>
OP_CHECKSIG <sig> <pubKey>
True
MultiSig transactions (M-of-N)
scriptPubKey: <M> [pubKey1 … pubKeyN] <N> OP_CHECKMULTISIG
scriptSig: 0 [sig1 … sigM]
Possible use cases:
● 1-of-N: shared account (husband + wife + kid)
● N-of-N: kinda “N”-factor authorization
● M-of-N: escrow services, example 2-of-3
Is that you?
Paybis is looking for a dev:
● Default: PHP, JS, CSS, MySQL, GIT
● Bonus: Symfony2, ReactJS
k.vasilenko@paybis.com
Pay-to-Script-Hash (P2SH, BIP16)
Bitcoin P2SH addresses always start with 3
Example: 3P14159f73E4gFr7JterCCQh9QjiTjiZrG
scriptPubKey: OP_HASH160 <scriptHash> OP_EQUAL
Merkle Tree
Merkle Tree - II
To prove that transaction K is included in the block only nodes HL, HIJ, HMNOP and
HABCDEFGH are required ~ Log2N
Difficulty, Target Difficulty and Nonce
And many many more…
Questions

“Technical Intro to Blockhain” by Yurijs Pimenovs from Paybis at CryptoCurrency focused 54th DevClub.lv

  • 1.
    Intro to Bitcoinfor Developers Yuri Pimenov, CTO @ Paybis y.pimenov@paybis.com http://coinside.ru
  • 2.
    Used resources ● “Bitcoindeveloper guide” https://bitcoin.org/en/developer-guide ● “Mastering Bitcoin” https://github.com/bitcoinbook/bitcoinbook/ ● “Mastering Bitcoin” in Russian and other languages https://www.transifex.com/bitcoinbook/mastering-bitcoin/ ● https://www.coursera.org/learn/cryptocurrency
  • 3.
  • 4.
  • 5.
    What is Blockchain? TL;DR:Blockchain is a linked list of blocks containing transactions!
  • 6.
    Structure of aBlock Size Field Description 4 bytes Block Size The size of the block, in bytes, following this field 80 bytes Block Header Several fields form the block header 1-9 bytes (VarInt) Transaction Counter How many transactions follow Variable Transactions The transactions recorded in this block
  • 7.
    Block Header Size FieldDescription 4 bytes Version A version number to track software/protocol upgrades 32 bytes Previous Block Hash A reference to the hash of the previous (parent) block 32 bytes Merkle Root A hash of the root of the merkle tree of this block’s transactions 4 bytes Timestamp The approximate creation time of this block (Unix Epoch) 4 bytes Difficulty Target The proof-of-work algorithm difficulty target for this block 4 bytes Nonce A counter used for the proof-of-work algorithm
  • 8.
    What is Transaction? TL;DR:Transactions are linked structures! class COutPoint { uint256 hash; uint32_t n; class CTxIn { COutPoint prevout; CScript scriptSig; class CTxOut { CAmount nValue; CScript scriptPubKey; class CTransaction { vector<CTxIn> vin; vector<CTxOut> vout;
  • 9.
  • 10.
  • 11.
    Cryptography ● HASH: 𝒇(“Thequick brown fox...”) → 0xa3b634ffa1424… Public key cryptography (Public Key & Private Key): ● SIGN: 𝓕(“The quick brown fox...”, PRIVATE_KEY) → 0xa583fa1dada… ● VERIFY: 𝓕’(0xa583fa1dada…, PUBLIC_KEY) → “The quick brown fox...”
  • 12.
    Elliptic curve y2 =x3 + 7 Secp256k1
  • 13.
    Elliptic curve cryptography TL;DR:sign with private key, verify with public key
  • 14.
    Generating private key >>>import hashlib >>> import os >>> from pycoin import ecdsa, encoding >>> import binascii >>> rand = binascii.hexlify(os.urandom(32)) >>> rand b'19450ccb2fd155fcd5933e1487d6295a7c6d83ce1c198a9b01c178af8 161d592' >>> secret_exponent = int('0x' + rand.decode(), 0) >>> secret_exponent 11429821960912496644762147021914232624305188114701093398105 624802483832477074
  • 15.
    Generating public key >>>private_key_wif = encoding.secret_exponent_to_wif(secret_exponent) >>> private_key_wif 'Kx4qCrgP6uRVkYrzqpkefPaWMz4JNAKNtB3ofmNjxqTZZQEiKBVs' >>> public_pair = ecdsa.public_pair_for_secret_exponent(ecdsa.secp256k1.gener ator_secp256k1, secret_exponent) >>> public_pair (8383574116545539269076290525564606006885119882359933136746 6434419371333356943, 29390949121653277068495088942182866226704757294052224997547 313025682750397184)
  • 16.
    Generating Bitcoin address >>>hash160 = encoding.public_pair_to_hash160_sec(public_pair) >>> int('0x' + binascii.hexlify(hash160).decode(), 0) 451995369346927816479889813976421291895952315620 >>> encoding.hash160_sec_to_bitcoin_address(hash160) '18DdJNbCYjo9nmAZAZZ2X3MYCv7gwoLvQn'
  • 17.
    Sizes len(private key) =32 bytes (256 bit) len(public key) = 64 bytes (or 32 bytes + 1 bit) len(hash) = 20 bytes 1077 < 2256 < 1078 ~ Number of atoms in the Universe
  • 18.
    Bitcoin address TL;DR: Addressis a Base58 of pubkey hash + checksum 1. Hash = RIPEMD160(SHA256(K)) 2. Csum = SHA256(SHA256(Version + Hash)) 3. Address = Base58(Version + Hash + Csum[0:4]) Base58 alphabet: 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz
  • 19.
    “Script” is likeFORTH “2 + 7 – 3 == 6” “2 7 OP_ADD 3 OP_SUB 6 OP_EQUAL” 2 [2] 7 [2; 7] OP_ADD [9] 3 [9; 3] OP_SUB [6] 6 [6; 6] OP_EQUAL [TRUE]
  • 20.
    Some “Script” operators ●OP_IF ● OP_SWAP ● OP_SUBSTR ● OP_CAT ● OP_ABS ● OP_MOD ● OP_SIZE ● OP_XOR
  • 21.
  • 22.
    Pay-to-Public-Key (obsolete) scriptPubKey: <pubKey>OP_CHECKSIG scriptSig: <sig> <sig> <pubKey> OP_CHECKSIG “OP_CHECKSIG is script opcode used to verify that the signature for a tx input is valid. OP_CHECKSIG expects two values to be on the stack.” scriptSig are digitally signed following data: ● ID (hash) of particular input (prev_out) ● double SHA of new transaction data
  • 23.
    Pay-to-Public-Key-Hash (P2PKH) transaction [<sig><pubKey>] + [OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG]
  • 24.
    Pay-to-Public-Key-Hash (P2PKH) transaction <sig><pubKey> OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG <sig> <pubKey> OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG <sig> <pubKey> <pubKey> <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG <sig> <pubKey> <pubKeyHashA> OP_EQUALVERIFY OP_CHECKSIG <sig> <pubKey> <pubKeyHashA> <pubKeyHash> OP_CHECKSIG <sig> <pubKey> True
  • 25.
    MultiSig transactions (M-of-N) scriptPubKey:<M> [pubKey1 … pubKeyN] <N> OP_CHECKMULTISIG scriptSig: 0 [sig1 … sigM] Possible use cases: ● 1-of-N: shared account (husband + wife + kid) ● N-of-N: kinda “N”-factor authorization ● M-of-N: escrow services, example 2-of-3
  • 26.
    Is that you? Paybisis looking for a dev: ● Default: PHP, JS, CSS, MySQL, GIT ● Bonus: Symfony2, ReactJS k.vasilenko@paybis.com
  • 27.
    Pay-to-Script-Hash (P2SH, BIP16) BitcoinP2SH addresses always start with 3 Example: 3P14159f73E4gFr7JterCCQh9QjiTjiZrG scriptPubKey: OP_HASH160 <scriptHash> OP_EQUAL
  • 28.
  • 29.
    Merkle Tree -II To prove that transaction K is included in the block only nodes HL, HIJ, HMNOP and HABCDEFGH are required ~ Log2N
  • 30.
  • 31.
    And many manymore… Questions