цифровая электроника
вычислительная техника
встраиваемые системы

 
» » Как создать свой блокчейн: код блокчейна в 100 строк

Как создать свой блокчейн: код блокчейна в 100 строк

Автор: Mike(admin) от 30-10-2017, 19:35

Что такое блокчейн?


Блокчейн сегодня считается перспективной и прорывной технологией, благодаря которой можно организовать не только финансовые операции с участием криптовалют, но и многие другие процессы социальной, экономической и производственной областей человеческой жизнедеятельности. Подробно о том, что такое блокчейн, и каковы его принципы работы можно прочитать здесь.


Как создать свой блокчейн

С технической точки зрения, блокчейн – это распределенная база данных со специальными функциями, такими как проверка, хранение и синхронизация данных. С точки зрения бизнеса, это концепция, которая позволяет проводить эффективные и надежные одноранговые транзакции, не требуя центральной точки контроля. Впрочем, существуют некоторые отличия блокчейна по сравнению с распределенной базой данных. В Blockchain можно только добавить информацию, затем данные проверяются и подписываются. Но как же создать блокчейн? В данном материале мы рассмотрим как запрограммировать свой блокчейн примерно в 100 строках кода, используя язык программирования javascript.


Программная архитектура блокчейна


Blockchain – это цепочка блоков. Чтобы было все как можно проще, но не слишком простым, каждый блок включает в себя наиболее необходимые элементы: индекс, временную метку, данные, хэш и предыдущий хэш. И каждый новый блок, который должен быть добавлен в цепочку, также должен быть проверен.



import CryptoJS from 'crypto-js';

import chain from './chain';

export const calcHash = ({index, prevHash, timestamp, data}) => {
    return CryptoJS.SHA256(index + prevHash + timestamp + data).toString();
}

export const create = (data) => {
    const prev = chain.last();
    const index = prev.index + 1;
    const timestamp = new Date().getTime();
    const prevHash = prev.hash;
    const hash = calcHash({ index, prevHash, timestamp, data });

    return { index, timestamp, data, prevHash, hash };
};

export const isNewBlockValid = (newBlock, prevBlock = chain.last()) => {
    let isValid = true;

    if (prevBlock.index + 1 !== newBlock.index) {
        console.log('New block has invalid index');
        isValid = false;
    } else if (prevBlock.hash !== newBlock.prevHash) {
        console.log('New block has invalid prevHash');
        isValid = false;
    } else if (calcHash(newBlock) !== newBlock.hash) {
        console.log('New block has invalid hash');
        isValid = false;
    }

    return isValid;
};

Цепочка блоков – это одноэлементная реализация, которую вы разрешаете расширять с помощью нового проверенного блока и заменяете цепочку в случае соединения нескольких одноранговых узлов, выбирая ту, которая имеет самое длинное количество блоков в ней.



import { calcHash, isNewBlockValid } from './block';

const Chain = (function () {
    let instance;
    const origin = {
        index: 0,
        timestamp: 0,
        data: 'Hello Blockchain!',
        prevHash: 0,
        hash: calcHash({ index: 0, prevHash: 0, timestamp: 0, data: 'Hello Blockchain!' })
    };
    const chain = [origin];

    function isChainValid(newChain) {
        let isValid = true;

        if (JSON.stringify(newChain[0]) !== JSON.stringify(origin)) {
            console.log('Received chain is invalid. Origin block does not coincide');
            isValid = false;
            return isValid;
        }

        const tempChain = [newChain[0]];
        for (let i = 1; i < newChain.length; i += 1) {
            if (isNewBlockValid(newChain[i], tempChain[i - 1])) {
                tempChain.push(newChain[i]);
            } else {
                isValid = false;
                return isValid;
            }
        }

        return isValid;
    }

    function get() {
        return chain;
    }

    function update(block) {
        if (isNewBlockValid(block)) {
            chain.push(block);
        }
    }

    function last() {
        return chain.slice().pop();
    }

    function replace(newChain) {
        if (isChainValid(newChain) && newChain.length > chain.length) {
            console.log('Received chain is valid. Replacing current chain with received chain');
            chain.length = 0; // clear current chain
            chain.push(...newChain); // fill current already empty chain with the new one if valid
        } else {
            console.log('Received chain is invalid');
        }
    }

    function create() {
        return { get, update, last, replace };
    }

    return {
        init() {
            if (!instance) {
                instance = create();
            }
            return instance;
        }
    };
}());

export default Chain.init();

Существенной особенностью узла является совместное использование и синхронизация цепочки с другими узлами. Когда узел генерирует новый блок, он передает его в сеть. Когда узел подключается к новому одноранговому узлу, он запрашивает последний блок. И когда узел встречает блок с индексом, большим, чем текущий известный блок, он либо добавляет блок своей текущей цепочке, либо запросы для полной цепочки блоков. Нет автоматического обнаружения сверстников. Местоположение (URL-адресов) одноранговых узлов добавляется вручную.



import express from 'express';

import chain from '../chain';
import { create } from '../block';
import sockets from '../p2p/sockets';
import { connectToPeers } from '../p2p/index';
import { broadcast } from '../p2p/handlers';
import { responseLatestMsg } from '../p2p/actions';

const router = express.Router();

router.get('/health-check', (req, res) =>  res.send('OK'));

router.get('/chain', (req, res) => {
    res.setHeader('Content-Type', 'application/json');
    res.send(JSON.stringify(chain.get()))
});

router.post('/mine', (req, res) => {
    const block = create(req.body.data);
    chain.update(block);
    broadcast(responseLatestMsg());
    console.log('New block in chain has been added: ', block);
    res.send(block);
});

router.get('/peers', (req, res) => {
    res.send(sockets.get().map(s => `${s._socket.remoteAddress}:${s._socket.remotePort}`));
});

router.post('/connect', (req, res) => {
    const { peer } = req.body;
    connectToPeers([peer]);
    console.log('New peer in p2p websocket has been added: ', peer);
    res.send(peer);
});

export default router;

Пользователь может управлять узлом с помощью HTTP-сервера, чтобы отображать все блоки в цепочке, создавать новый с содержимым, заданным пользователем, и добавлять одноранговые узлы. Следует отметить, что узел предоставляет два веб-сервера: один для пользователя для qp-управления узлом (HTTP-сервером) и один для одноранговой связи между узлами (сервер Websocket P2P). Дополнительную информацию по реализации такого блокчейна можно найти на github.com/stremann/chainpro.




Теги: блокчейн, криптовалюты



   Благодарим Вас за интерес к информационному проекту digitrode.ru.
   Если Вы хотите, чтобы интересные и полезные материалы выходили чаще, и было меньше рекламы,
   Вы можее поддержать наш проект, пожертвовав любую сумму на его развитие.


Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Комментарии:

Оставить комментарий