- PVSM.RU - https://www.pvsm.ru -
Базовая концепция блокчейна довольно проста: речь идет о распределенной базе данных, поддерживающей постоянно растущий список упорядоченных записей. Запутаться, однако, легко, поскольку всякий раз, когда мы говорим о блокчейнах, мы рассматриваем их с позиции задач, которые пытаемся решить и потому нередко начинаем подмешивать в это определение другие, очень близкие ему понятия. Это справедливо и в случае с популярными блокчейн проектами, такими, как Биткойн и Эфириум. Термин «блокчейн» обычно тесно связан с такими концепциями, как транзакции, умные контракты или криптовалюты.
Все это оправданно, но все же существенно усложняет процесс понимания принципа работы блокчейнов, особенно с точки зрения программного обеспечения с открытым исходным кодом. В этом материале я покажу вам крайне простой блокчейн, написание которого потребовало всего 200 строк Javascript-кода. Я назвал его NaiveChain.
Первым и логичным шагом было бы определиться со структурой блока. Чтобы сохранить максимальную простоту, мы включим в него лишь самое необходимое: индекс, метку времени, данные и хэши текущего и предыдущего блоков.
Хэш предыдущего блока включен в каждый блок для сохранения целостности цепочки
class Block {
constructor(index, previousHash, timestamp, data, hash) {
this.index = index;
this.previousHash = previousHash.toString();
this.timestamp = timestamp;
this.data = data;
this.hash = hash.toString();
}
}
Сохранение целостности данных достигается с помощью хэширования блоков. В данном случае применяется алгоритм SHA-256. Следует также отметить, что получаемый хэш никак не связан с процессом майнинга, поскольку наш блокчейн не требует решения каких-либо «Proof Of Work» задач.
var calculateHash = (index, previousHash, timestamp, data) => {
return CryptoJS.SHA256(index + previousHash + timestamp + data).toString();
};
Для генерации блока мы должны знать хэш предыдущего блока и добавить оставшуюся часть содержимого текущего блока, то есть индекс, хэш, данные и временную метку. Под данными блока понимается какая-либо предоставленная конечными пользователями информация.
var generateNextBlock = (blockData) => {
var previousBlock = getLatestBlock();
var nextIndex = previousBlock.index + 1;
var nextTimestamp = new Date().getTime() / 1000;
var nextHash = calculateHash(nextIndex, previousBlock.hash, nextTimestamp, blockData);
return new Block(nextIndex, previousBlock.hash, nextTimestamp, blockData, nextHash);
};
Блокчейн хранится в оперативной памяти в форме Javascript массива. Первый блок, как это обычно бывает во всех блокчейнах, получил название genesis-block (блок-прародитель). Его содержимое прописано заранее и не подлежит изменению.
var getGenesisBlock = () => {
return new Block(0, "0", 1465154705, "my genesis block!!", "816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7");
};
var blockchain = [getGenesisBlock()];
В любой момент мы должны иметь возможность проверить, действительно ли тот или иной блок или цепочка блоков содержит правильно сформированную и достоверную информацию. Это особенно важно, когда мы получаем новые блоки от других узлов и должны принять решение относительно их подлинности.
var isValidNewBlock = (newBlock, previousBlock) => {
if (previousBlock.index + 1 !== newBlock.index) {
console.log('invalid index');
return false;
} else if (previousBlock.hash !== newBlock.previousHash) {
console.log('invalid previoushash');
return false;
} else if (calculateHashForBlock(newBlock) !== newBlock.hash) {
console.log('invalid hash: ' + calculateHashForBlock(newBlock) + ' ' + newBlock.hash);
return false;
}
return true;
};
В любой момент времени в блокчейне должен существовать только один достоверный набор блоков. В случае конфликта (например, два узла генерируют блок номер 72) мы выбираем цепочку, содержащую наибольшее количество блоков.
var replaceChain = (newBlocks) => {
if (isValidChain(newBlocks) && newBlocks.length > blockchain.length) {
console.log('Received blockchain is valid. Replacing current blockchain with received blockchain');
blockchain = newBlocks;
broadcast(responseLatestMsg());
} else {
console.log('Received blockchain invalid');
}
};
Одна из ключевых составляющих деятельности узла заключается в обмене информации о блокчейне и синхронизации данных с другими узлами.
[1]
Некоторые типичные сценарии обмена сообщениями между узлами, предусмотренные описанным протоколом
Автоматическое обнаружение узлов в нашем блокчейне не используется. Расположения (то есть URL’ы) других узлов прописываются вручную.
Пользователь должен обладать определенными возможности по управлению узлом. Для этого в нашем коде предусмотрена настройка HTTP-сервера.
var initHttpServer = () => {
var app = express();
app.use(bodyParser.json());
app.get('/blocks', (req, res) => res.send(JSON.stringify(blockchain)));
app.post('/mineBlock', (req, res) => {
var newBlock = generateNextBlock(req.body.data);
addBlock(newBlock);
broadcast(responseLatestMsg());
console.log('block added: ' + JSON.stringify(newBlock));
res.send();
});
app.get('/peers', (req, res) => {
res.send(sockets.map(s => s._socket.remoteAddress + ':' + s._socket.remotePort));
});
app.post('/addPeer', (req, res) => {
connectToPeers([req.body.peer]);
res.send();
});
app.listen(http_port, () => console.log('Listening http on port: ' + http_port));
};
Как видно из приведенного выше фрагмента кода, пользователь получает возможность взаимодействовать с узлом следующими способами:
Один из вариантов непосредственного управления узлом — использование Curl:
#получаем все блоки от узла
curl http://localhost:3001/blocks
Следует отметить, что работа каждого узла включает в себя использование двух веб-серверов: управляющего узлом HTTP-сервера и осуществляющего коммуникацию с другими узлами Websocket HTTP-сервера.
Основные компоненты NaiveChain
NaiveChain был создан в демонстрационных и обучающих целях. В силу того, что в нем нет алгоритма майнинга (PoS или PoW), использовать его для публично доступной сети не представляется возможным. Тем не менее проект воплощает на практике всю необходимую базовую функциональность Блокчейн.
Более подробная техническая информация доступна в Github-репозитории [2] проекта.
Автор: Wirex
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/he-shirovanie/250342
Ссылки в тексте:
[1] Image: https://habrastorage.org/files/987/b69/0bd/987b690bd06b40509aa110f8968f2276.png
[2] Github-репозитории: https://github.com/lhartikk/naivechain
[3] Источник: https://geektimes.ru/post/284552/
Нажмите здесь для печати.