0 added
0 removed
Original
2026-01-01
Modified
2026-02-21
1
<p><a>#статьи</a></p>
1
<p><a>#статьи</a></p>
2
<ul><li>17 авг 2022</li>
2
<ul><li>17 авг 2022</li>
3
<li>0</li>
3
<li>0</li>
4
</ul><p>Рассказываем, для чего нужен блокчейн в программировании и как его используют, а также пишем небольшое приложение.</p>
4
</ul><p>Рассказываем, для чего нужен блокчейн в программировании и как его используют, а также пишем небольшое приложение.</p>
5
<p>Иллюстрация: Merry Mary для Skillbox Media</p>
5
<p>Иллюстрация: Merry Mary для Skillbox Media</p>
6
<p>Пишет о программировании, в свободное время создаёт игры. Мечтает открыть свою студию и выпускать ламповые RPG.</p>
6
<p>Пишет о программировании, в свободное время создаёт игры. Мечтает открыть свою студию и выпускать ламповые RPG.</p>
7
<p><strong>Блокчейн</strong> - это последовательная цепочка блоков, которые защищены от подмены. А <strong>блок</strong> - это файл, содержащий информацию о предыдущих действиях, например транзакциях о переводе криптовалют. Но при этом ошибочно считать, что эта технология используется только в криптовалюте, - на самом деле применить блокчейн можно где угодно.</p>
7
<p><strong>Блокчейн</strong> - это последовательная цепочка блоков, которые защищены от подмены. А <strong>блок</strong> - это файл, содержащий информацию о предыдущих действиях, например транзакциях о переводе криптовалют. Но при этом ошибочно считать, что эта технология используется только в криптовалюте, - на самом деле применить блокчейн можно где угодно.</p>
8
<p>Разбираемся, что же такое блокчейн, и пишем приложение с его использованием.</p>
8
<p>Разбираемся, что же такое блокчейн, и пишем приложение с его использованием.</p>
9
<p>Прежде чем говорить про блокчейн, нужно разобраться, что такое хеширование.</p>
9
<p>Прежде чем говорить про блокчейн, нужно разобраться, что такое хеширование.</p>
10
<p><strong>Хеширование</strong> - это преобразование данных произвольной длины в битовую строку фиксированной длины. То есть мы можем взять любой текст, например книгу "451 градус по Фаренгейту", а потом зашифровать его с помощью специального алгоритма.</p>
10
<p><strong>Хеширование</strong> - это преобразование данных произвольной длины в битовую строку фиксированной длины. То есть мы можем взять любой текст, например книгу "451 градус по Фаренгейту", а потом зашифровать его с помощью специального алгоритма.</p>
11
<p>Каждый раз этот алгоритм будет преобразовывать текст в один и тот же хеш. Например, такой:</p>
11
<p>Каждый раз этот алгоритм будет преобразовывать текст в один и тот же хеш. Например, такой:</p>
12
6de4c03655fdc3e982e3bfc4f055dae5064547e8b78ef951b80c94b657a5c684Вряд ли вы узнаете, что здесь зашифровано.<p>Но если будет пропущена хотя бы одна запятая или какая-нибудь буква поменяет регистр, то хеш полностью изменится.</p>
12
6de4c03655fdc3e982e3bfc4f055dae5064547e8b78ef951b80c94b657a5c684Вряд ли вы узнаете, что здесь зашифровано.<p>Но если будет пропущена хотя бы одна запятая или какая-нибудь буква поменяет регистр, то хеш полностью изменится.</p>
13
efdc5e0108e3906fea8c93efb1d9616b7a26aa26549c5d47a1b6c3fda8199ac9И опять вы вряд ли узнаете, что здесь зашифровано.<p>Тут зашифрована та же строка, что и сверху, но в конце я убрал точку. Как видно, результат уже совсем не похож на исходный хеш.</p>
13
efdc5e0108e3906fea8c93efb1d9616b7a26aa26549c5d47a1b6c3fda8199ac9И опять вы вряд ли узнаете, что здесь зашифровано.<p>Тут зашифрована та же строка, что и сверху, но в конце я убрал точку. Как видно, результат уже совсем не похож на исходный хеш.</p>
14
<p>Пока что единственный способ расшифровать хеш - перебор. Теоретически, чтобы найти верный вариант, нужно попробовать бесконечное количество комбинаций. Поэтому хеш применяют, чтобы защитить данные от взлома - даже если они будут утеряны или украдены.</p>
14
<p>Пока что единственный способ расшифровать хеш - перебор. Теоретически, чтобы найти верный вариант, нужно попробовать бесконечное количество комбинаций. Поэтому хеш применяют, чтобы защитить данные от взлома - даже если они будут утеряны или украдены.</p>
15
<p>Один из вариантов использования хешей - хранение паролей. Когда пользователь будет регистрироваться в системе, его данные будут храниться не в чистом виде, а в виде хеша.</p>
15
<p>Один из вариантов использования хешей - хранение паролей. Когда пользователь будет регистрироваться в системе, его данные будут храниться не в чистом виде, а в виде хеша.</p>
16
<p>Каждый раз, когда он будет вводить пароль, тот будет снова хешироваться, а уже потом сравниваться с тем, что записан в базе. Даже если кто-то взломает базу данных, он не узнает, какой пароль использовался. Всё, что он увидит, - это набор непонятных символов.</p>
16
<p>Каждый раз, когда он будет вводить пароль, тот будет снова хешироваться, а уже потом сравниваться с тем, что записан в базе. Даже если кто-то взломает базу данных, он не узнает, какой пароль использовался. Всё, что он увидит, - это набор непонятных символов.</p>
17
<p>Теперь можно вернуться к блокчейну. Особенность каждого его блока - в том, что он не только захеширован, но и хранит информацию о предыдущем блоке.</p>
17
<p>Теперь можно вернуться к блокчейну. Особенность каждого его блока - в том, что он не только захеширован, но и хранит информацию о предыдущем блоке.</p>
18
<p>Рассмотрим это на примере блокнота. Каждая запись в нём будет восприниматься как отдельный блок.</p>
18
<p>Рассмотрим это на примере блокнота. Каждая запись в нём будет восприниматься как отдельный блок.</p>
19
<p>Допустим, есть вот такая первая запись:</p>
19
<p>Допустим, есть вот такая первая запись:</p>
20
Привет, это первая заметка!<p>Её хеш выглядит так:</p>
20
Привет, это первая заметка!<p>Её хеш выглядит так:</p>
21
7cb70ea12f13042dbfbbf492c20e943b2c62a1007a9921e36f5479f6aa748bc9<p>Вторая запись содержит в себе саму запись, а также хеш первой записи. То есть:</p>
21
7cb70ea12f13042dbfbbf492c20e943b2c62a1007a9921e36f5479f6aa748bc9<p>Вторая запись содержит в себе саму запись, а также хеш первой записи. То есть:</p>
22
7cb70ea12f13042dbfbbf492c20e943b2c62a1007a9921e36f5479f6aa748bc9_разделитель_Привет, это вторая запись!<p>В таком виде заметка хешируется:</p>
22
7cb70ea12f13042dbfbbf492c20e943b2c62a1007a9921e36f5479f6aa748bc9_разделитель_Привет, это вторая запись!<p>В таком виде заметка хешируется:</p>
23
8af30f625141cd685dd3ad40f32b0046b562e4efd9746f8225f5a56543a0e50a<p>И этот хеш становится частью третьей записи.</p>
23
8af30f625141cd685dd3ad40f32b0046b562e4efd9746f8225f5a56543a0e50a<p>И этот хеш становится частью третьей записи.</p>
24
<p>Если мы изменим вторую запись, то её хеш станет совсем другим. Следовательно, он не будет совпадать с тем, что был записан в третью запись. То есть блокчейн позволяет нам создавать записи, которые невозможно изменить незаметно.</p>
24
<p>Если мы изменим вторую запись, то её хеш станет совсем другим. Следовательно, он не будет совпадать с тем, что был записан в третью запись. То есть блокчейн позволяет нам создавать записи, которые невозможно изменить незаметно.</p>
25
<p>Теоретически можно подобрать строку, хеш которой будет совпадать с тем, который нужно заменить. Но, как уже говорилось выше, сделать это сложно, особенно если блоков очень много.</p>
25
<p>Теоретически можно подобрать строку, хеш которой будет совпадать с тем, который нужно заменить. Но, как уже говорилось выше, сделать это сложно, особенно если блоков очень много.</p>
26
<p>Чтобы обойти эту проблему, используется децентрализация. То есть блоки хранятся не на едином сервере, а на всех компьютерах, которые используют приложение на блокчейне.</p>
26
<p>Чтобы обойти эту проблему, используется децентрализация. То есть блоки хранятся не на едином сервере, а на всех компьютерах, которые используют приложение на блокчейне.</p>
27
<p>Эта мера используется, например, в криптовалюте<em>BitCoin</em>. И если кто-то захочет её у вас украсть, ему придётся одновременно заменить блоки на всех компьютерах.</p>
27
<p>Эта мера используется, например, в криптовалюте<em>BitCoin</em>. И если кто-то захочет её у вас украсть, ему придётся одновременно заменить блоки на всех компьютерах.</p>
28
<p>Использовать эту технологию можно для чего угодно, а не только для криптовалюты. Например, можно хранить в блокчейне удостоверения личности. Это не позволит мошенникам использовать документы умерших людей, заменив в них фотографию.</p>
28
<p>Использовать эту технологию можно для чего угодно, а не только для криптовалюты. Например, можно хранить в блокчейне удостоверения личности. Это не позволит мошенникам использовать документы умерших людей, заменив в них фотографию.</p>
29
<p>Есть и другие варианты:</p>
29
<p>Есть и другие варианты:</p>
30
<ul><li>В блокчейне можно хранить ставки - тогда ни букмекер, ни игрок не смогут обмануть друг друга.</li>
30
<ul><li>В блокчейне можно хранить ставки - тогда ни букмекер, ни игрок не смогут обмануть друг друга.</li>
31
<li>С помощью блокчейна можно проводить выборы - что исключит возможность фальсификации результатов.</li>
31
<li>С помощью блокчейна можно проводить выборы - что исключит возможность фальсификации результатов.</li>
32
<li>Можно заменить нотариуса блокчейном - и заверять документы без него.</li>
32
<li>Можно заменить нотариуса блокчейном - и заверять документы без него.</li>
33
</ul><p>Это далеко не весь список.</p>
33
</ul><p>Это далеко не весь список.</p>
34
<p>Не стоит думать, что такая система надёжна на 100%. Возможны ошибки в самом программном обеспечении, которые позволят воровать данные до того, как они будут захешированы.</p>
34
<p>Не стоит думать, что такая система надёжна на 100%. Возможны ошибки в самом программном обеспечении, которые позволят воровать данные до того, как они будут захешированы.</p>
35
<p>Чтобы лучше понимать, как работает блокчейн, напишем приложение с использованием этой технологии. Здесь будут приведены только самые важные части кода, поэтому реализация интерфейса останется за кадром. Если же вам интересно увидеть приложение полностью, его можно найти в <a>этом репозитории</a>на GitHub.</p>
35
<p>Чтобы лучше понимать, как работает блокчейн, напишем приложение с использованием этой технологии. Здесь будут приведены только самые важные части кода, поэтому реализация интерфейса останется за кадром. Если же вам интересно увидеть приложение полностью, его можно найти в <a>этом репозитории</a>на GitHub.</p>
36
<p>Начнём с создания класса, который представляет собой блок. Назовём его<em>Note</em>.</p>
36
<p>Начнём с создания класса, который представляет собой блок. Назовём его<em>Note</em>.</p>
37
<p>В своей работе он будет использовать преобразование строки в байты и обратно, а также шифрование, поэтому нужно подключить соответствующие пространства имён:</p>
37
<p>В своей работе он будет использовать преобразование строки в байты и обратно, а также шифрование, поэтому нужно подключить соответствующие пространства имён:</p>
38
using System.Text; using System.Security.Cryptography;<p>Теперь можно приступать к работе над самим классом:</p>
38
using System.Text; using System.Security.Cryptography;<p>Теперь можно приступать к работе над самим классом:</p>
39
///<Summary>Заметка для блокнота, который работает на блокчейне</Summary> class Note { public static string Splitter = "_splitter_"; private string text; private byte[] hash; public Note(string text) { this.text = text; this.hash = ComputeHash(text); } private byte[] ComputeHash(string text) { SHA256 sha = SHA256.Create(); //Создаём объект, который будет вычислять хеш byte[] textBytes = Encoding.Default.GetBytes(text); //Преобразуем текст заметки в байты return sha.ComputeHash(textBytes); //Возвращаем хеш } ///<Summary>Полный текст заметки</Summary> public string Text { get { return this.text; } } ///<Summary>Текст заметки без хеша прошлого блока</Summary> public string ClearText { get { return this.text.Remove(0, this.text.IndexOf(Note.Splitter) + Note.Splitter.Length); } } ///<Summary>Хеш прошлого блока</Summary> public string PreviousHash { get { return this.text.Remove(this.text.IndexOf(Note.Splitter)); } } ///<Summary>Хеш текущего блока в виде строки</Summary> public string HashString { get { //При каждом получении текущего хеша нужно считать его заново //Так мы будем уверены, что он актуален var hash = ComputeHash(this.text); return Encoding.Default.GetString(hash); } } ///<Summary>Хеш в виде байтов</Summary> public byte[] Hash { get { return this.hash; } } }<p>Остаётся только написать программу, которая будет использовать эти блоки. Первым делом нужно создать список блоков:</p>
39
///<Summary>Заметка для блокнота, который работает на блокчейне</Summary> class Note { public static string Splitter = "_splitter_"; private string text; private byte[] hash; public Note(string text) { this.text = text; this.hash = ComputeHash(text); } private byte[] ComputeHash(string text) { SHA256 sha = SHA256.Create(); //Создаём объект, который будет вычислять хеш byte[] textBytes = Encoding.Default.GetBytes(text); //Преобразуем текст заметки в байты return sha.ComputeHash(textBytes); //Возвращаем хеш } ///<Summary>Полный текст заметки</Summary> public string Text { get { return this.text; } } ///<Summary>Текст заметки без хеша прошлого блока</Summary> public string ClearText { get { return this.text.Remove(0, this.text.IndexOf(Note.Splitter) + Note.Splitter.Length); } } ///<Summary>Хеш прошлого блока</Summary> public string PreviousHash { get { return this.text.Remove(this.text.IndexOf(Note.Splitter)); } } ///<Summary>Хеш текущего блока в виде строки</Summary> public string HashString { get { //При каждом получении текущего хеша нужно считать его заново //Так мы будем уверены, что он актуален var hash = ComputeHash(this.text); return Encoding.Default.GetString(hash); } } ///<Summary>Хеш в виде байтов</Summary> public byte[] Hash { get { return this.hash; } } }<p>Остаётся только написать программу, которая будет использовать эти блоки. Первым делом нужно создать список блоков:</p>
40
List<Note> notes = new List<Note>(); //Список блоков notes.Add(new Note "start" + Note.Splitter + "First note")); //Добавляем первую заметку<p>Потом - реализовать метод добавления новых блоков.</p>
40
List<Note> notes = new List<Note>(); //Список блоков notes.Add(new Note "start" + Note.Splitter + "First note")); //Добавляем первую заметку<p>Потом - реализовать метод добавления новых блоков.</p>
41
static void AddNote(string text, List<Note> notes) { notes.Add(new Note(notes[notes.Count - 1].HashString + Note.Splitter + text)); }<p>Когда пользователь вводит текст для новой заметки, он передаётся в метод<em><strong>AddNote()</strong></em>.Там создаётся новый блок, который содержит текст вида</p>
41
static void AddNote(string text, List<Note> notes) { notes.Add(new Note(notes[notes.Count - 1].HashString + Note.Splitter + text)); }<p>Когда пользователь вводит текст для новой заметки, он передаётся в метод<em><strong>AddNote()</strong></em>.Там создаётся новый блок, который содержит текст вида</p>
42
Хеш предыдущего блока_разделитель_текст заметки<p>Созданный блок тут же добавляется в список:</p>
42
Хеш предыдущего блока_разделитель_текст заметки<p>Созданный блок тут же добавляется в список:</p>
43
<em>Скриншот: Skillbox Media</em><p>После того как будет создано несколько заметок, можно проверить список:</p>
43
<em>Скриншот: Skillbox Media</em><p>После того как будет создано несколько заметок, можно проверить список:</p>
44
<em>Скриншот: Skillbox Media</em><p>Здесь отображается только текст заметок, но, если посмотреть на полную информацию о них, можно увидеть, что они содержат в себе хеш прошлого блока:</p>
44
<em>Скриншот: Skillbox Media</em><p>Здесь отображается только текст заметок, но, если посмотреть на полную информацию о них, можно увидеть, что они содержат в себе хеш прошлого блока:</p>
45
Хеш выглядит немного иначе, потому что конвертируется сразу в строку, а не в шестнадцатеричное число<em>Скриншот: Skillbox Media</em><p>Просматривать всё это вручную, чтобы проверить достоверность данных, нет смысла, потому что блоков может быть очень много. Вместо этого напишем метод валидации:</p>
45
Хеш выглядит немного иначе, потому что конвертируется сразу в строку, а не в шестнадцатеричное число<em>Скриншот: Skillbox Media</em><p>Просматривать всё это вручную, чтобы проверить достоверность данных, нет смысла, потому что блоков может быть очень много. Вместо этого напишем метод валидации:</p>
46
///<summary>Проверка подлинности блоков</summary> static void ValidateNotes(List<Note> notes) { for(int i = 0; i < notes.Count; i++) { if(i == 0) //Не проверять первый блок { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("0 - Valid"); } else { Console.ForegroundColor = ConsoleColor.White; //Проверяем, соответствует ли хеш, записанный в текущий блок, хешу прошлого блока if(@notes[i].PreviousHash == @notes[i - 1].HashString) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(i + " - Valid"); } else { Console.WriteLine($"\n\n | {notes[i].PreviousHash} | {notes[i - 1].HashString} | \n\n"); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(i + " - Changed"); } } } Console.WriteLine("\n"); }<p>Теперь можно проверить, всё ли в порядке с заметками, которые мы сохранили:</p>
46
///<summary>Проверка подлинности блоков</summary> static void ValidateNotes(List<Note> notes) { for(int i = 0; i < notes.Count; i++) { if(i == 0) //Не проверять первый блок { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("0 - Valid"); } else { Console.ForegroundColor = ConsoleColor.White; //Проверяем, соответствует ли хеш, записанный в текущий блок, хешу прошлого блока if(@notes[i].PreviousHash == @notes[i - 1].HashString) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(i + " - Valid"); } else { Console.WriteLine($"\n\n | {notes[i].PreviousHash} | {notes[i - 1].HashString} | \n\n"); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(i + " - Changed"); } } } Console.WriteLine("\n"); }<p>Теперь можно проверить, всё ли в порядке с заметками, которые мы сохранили:</p>
47
<em>Скриншот: Skillbox Media</em><p>Если же в каком-нибудь блоке изменится хоть один символ, это сразу станет ясно. Поэтому такой блокнот - идеальный вариант для хранения долговых расписок и другой подобной информации.</p>
47
<em>Скриншот: Skillbox Media</em><p>Если же в каком-нибудь блоке изменится хоть один символ, это сразу станет ясно. Поэтому такой блокнот - идеальный вариант для хранения долговых расписок и другой подобной информации.</p>
48
<p>Это только малая часть того, что можно узнать по этой теме. Мы написали приложение, которое использует блокчейн, и использовали главный принцип блокчейна - последовательность хеширования данных.</p>
48
<p>Это только малая часть того, что можно узнать по этой теме. Мы написали приложение, которое использует блокчейн, и использовали главный принцип блокчейна - последовательность хеширования данных.</p>
49
<p>Если же вы хотите изучить тему глубже, советую почитать<a>статью на Habr</a>. Там же есть ссылка на учебник по защите информации.</p>
49
<p>Если же вы хотите изучить тему глубже, советую почитать<a>статью на Habr</a>. Там же есть ссылка на учебник по защите информации.</p>
50
<a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>
50
<a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>