Обзор блокчейн технологии


Владимир Боков

vlad@neonix.pro / @razum2um

Проблемы
Double spend (двойная трата)
Blockchain != Bitcoin

Internet != Facebook

Blockchain - последовательный набор блоков (ориентированный граф), каждый следующий блок в котором включает в качестве хэшируемой информации значение хэш-функции от предыдущего блока.
Как сделать работающую демократию?
POW, proof of work, доказательство работы
POS, proof of stake, доказательство доли
POA, proof of authority, доказательство влияния (dPOS, делегированные доли)
вероятность генерации блока пропорциональна распределена согласно голосам или по времени
Как что-то менять в мере где все неизменно?
Что такое время

деньги

блоки

Как хранить стейт?

Дерево хешей (Merkle tree)

Как решать проблема остановки?
Инструкции контракта

              PUSH1 0x60
              PUSH1 0x40
              MSTORE
              PUSH1 0x04
              CALLDATASIZE
              LT
              PUSH2 0x00cf
              JUMPI
              PUSH4 0xffffffff
              PUSH29 0x0100000000000000000000000000000000000000000000000000000000
              PUSH1 0x00
              CALLDATALOAD
            
Кишочки
Пример взаимодействия

              // Request
              curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"],"id":1}'

              // Result
              {
                "id":1,
                "jsonrpc": "2.0",
                "result": "0x0234c8a3397aab58" // 158972490234375000
              }
            
Блок

              > eth.getBlock('latest')
              {
                difficulty: 639976204,
                ...
                gasLimit: 4700036,
                gasUsed: 79376,
                hash: "0xd5b3fc641f7eeacaff29d71399213db6ad2688d6944ba0d56565e82d14ad3654",
                ...
                miner: "0x00d8ae40d9a06d0e7a2877b62e32eb959afbe16d",
                ...
                number: 2751636,
                parentHash: "0xf261529f5014340fe9b78eacc770e93ed0bc5e7cd139ac2e6b1db58c5f28789e",
                ...
                timestamp: 1519951218,
                ...
                transactions: ["0xd94dfde6f6da011d65fb1d10604cc14d8ed57d6b628cd8212d68fdb0c25ee7b6"]
              }
            
Транзакция

              > eth.getTransaction('0xd94dfde6f6da011d65fb1d10604cc14d8ed57d6b628cd8212d68fdb0c25ee7b6')
              {
                blockHash: "0xd5b3fc641f7eeacaff29d71399213db6ad2688d6944ba0d56565e82d14ad3654",
                blockNumber: 2751636,
                from: "0xd89d82c04d66d1df48c246c4bb807334a3bff743",
                to: "0x1f072e78ae13fceaa085b75a723fbd0c31373055",
                transactionIndex: 0,
                gas: 4700000,
                gasPrice: 50000000000,
                hash: "0xd94dfde6f6da011d65fb1d10604cc14d8ed57d6b628cd8212d68fdb0c25ee7b6",
                input: "0x82ab890a00000000000000000000000000000000000000000000000000000000000b0b40",
                nonce: 9882,
                r: "0x15d42f80400eb4a574ceb2b6d1782744c247cfb94b5a848f67d4eb47f10adac2",
                s: "0x55f32de228e5f27baa956155fe0a902a1fab34db2c4e8e138d552427c2ab0d99",
                v: "0x2a",
                value: 0
              }
            

              const InputDataDecoder = require('ethereum-input-data-decoder');
              const decoder = new InputDataDecoder(`abi.json`);
              const data = '0x82ab890a00000000000000000000000000000000000000000000000000000000000b0b40'
              decoder.decodeData(data);
              
              { name: 'update', types: [ 'uint256' ], inputs: [ BN: b0b40> ] }
            

Etherscan.io FTW

Ассоциативный массив

              contract Hashes {
                mapping(address => string) public mails;

                function sendMail(address a, string s) public {
                  mails[a] = s;
                }

                function getMail() public view returns(string) {
                  return mails[msg.sender];
                }
              }
            
(Not)Private

              contract Hashes {
                mapping(address => string) public mails;

                function sendMail(address a, string s) public {
                  mails[a] = s;
                }

                function getMail() public view returns(string) {
                  return mails[msg.sender];
                }
              }
            
Паттерн для динамических структур

              contract DynArray {
                string[] public texts;
                uint public counter;

                function addText(string text) public {
                    texts.push(text);
                    counter = counter + 1;
                }
              }
            

Итерироваться дорого