1
0
Fork 0
cl-sites/w3.cs.jmu.edu/kirkpams/OpenCSF/Books/csf/html/Extended9Blockchain.html
2025-01-28 10:11:14 +01:00

849 lines
No EOL
58 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>9.8. Extended Example: Blockchain Proof-of-Work &mdash; Computer Systems Fundamentals</title>
<link rel="stylesheet" href="_static/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous" />
<link rel="stylesheet" href="_static/css/pygments.css" type="text/css" />
<link rel="stylesheet" href="_static/css/normalize.css" type="text/css" />
<link rel="stylesheet" href="../../../JSAV/css/JSAV.css" type="text/css" />
<link rel="stylesheet" href="../../../lib/odsaMOD-min.css" type="text/css" />
<link rel="stylesheet" href="_static/css/jquery-1.11.4-smoothness-ui.css" type="text/css" />
<link rel="stylesheet" href="../../../lib/odsaStyle-min.css" type="text/css" />
<link rel="stylesheet" href="_static/css/csf.css" type="text/css" />
<style>
.underline { text-decoration: underline; }
</style>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '0.4.1',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {
inlineMath: [['$','$'], ['\\(','\\)']],
displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
processEscapes: true
},
"HTML-CSS": {
scale: "80"
}
});
</script>
<link rel="shortcut icon" href="_static/favicon.ico"/>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="index" title="Computer Systems Fundamentals" href="index.html" />
<link rel="next" title="1. C Language Reintroduction" href="CLangOverview.html" />
<link rel="prev" title="7. Consensus in Distributed Systems" href="DistConsensus.html" />
</head><body>
<nav class="navbar navbar-expand-md navbar-dark navbar-custom fixed-top">
<a class="navbar-brand py-0" href="index.html"><img src="_static/CSF-Logo-Square-Text.png" alt="OpenCSF Logo" height="40em" class="py-1 px-2 mb-0 align-center rounded-lg bg-white" /></a>
<!-- Show a navbar toggler on mobile -->
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#defaultNavbars" aria-controls="defaultNavbars" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="defaultNavbars">
<ul class="navbar-nav mr-auto">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle jmu-gold rounded" href="Extended9Blockchain.html#" id="navbarDropdownChapters" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Contents</a>
<div class="dropdown-menu scrollable-menu" role="menu" aria-labelledby="navbarDropdownChapters">
<a class="dropdown-item" tabindex="-1" href="Extended9Blockchain.html#"><b>Chapter 1</b></a>
<a class="dropdown-item" href="IntroConcSysOverview.html">&nbsp;&nbsp;&nbsp;1.1. Introduction to Concurrent Systems</a>
<a class="dropdown-item" href="SysAndModels.html">&nbsp;&nbsp;&nbsp;1.2. Systems and Models</a>
<a class="dropdown-item" href="Themes.html">&nbsp;&nbsp;&nbsp;1.3. Themes and Guiding Principles</a>
<a class="dropdown-item" href="Architectures.html">&nbsp;&nbsp;&nbsp;1.4. System Architectures</a>
<a class="dropdown-item" href="StateModels.html">&nbsp;&nbsp;&nbsp;1.5. State Models in UML</a>
<a class="dropdown-item" href="SequenceModels.html">&nbsp;&nbsp;&nbsp;1.6. Sequence Models in UML</a>
<a class="dropdown-item" href="StateModelImplementation.html">&nbsp;&nbsp;&nbsp;1.7. Extended Example: State Model Implementation</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 2</b></a>
<a class="dropdown-item" href="ProcessesOverview.html">&nbsp;&nbsp;&nbsp;2.1. Processes and OS Basics</a>
<a class="dropdown-item" href="Multiprogramming.html">&nbsp;&nbsp;&nbsp;2.2. Processes and Multiprogramming</a>
<a class="dropdown-item" href="KernelMechanics.html">&nbsp;&nbsp;&nbsp;2.3. Kernel Mechanics</a>
<a class="dropdown-item" href="Syscall.html">&nbsp;&nbsp;&nbsp;2.4. System Call Interface</a>
<a class="dropdown-item" href="ProcessCycle.html">&nbsp;&nbsp;&nbsp;2.5. Process Life Cycle</a>
<a class="dropdown-item" href="UnixFile.html">&nbsp;&nbsp;&nbsp;2.6. The UNIX File Abstraction</a>
<a class="dropdown-item" href="EventsSignals.html">&nbsp;&nbsp;&nbsp;2.7. Events and Signals</a>
<a class="dropdown-item" href="Extended2Processes.html">&nbsp;&nbsp;&nbsp;2.8. Extended Example: Listing Files with Processes</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 3</b></a>
<a class="dropdown-item" href="IPCOverview.html">&nbsp;&nbsp;&nbsp;3.1. Concurrency with IPC</a>
<a class="dropdown-item" href="IPCModels.html">&nbsp;&nbsp;&nbsp;3.2. IPC Models</a>
<a class="dropdown-item" href="Pipes.html">&nbsp;&nbsp;&nbsp;3.3. Pipes and FIFOs</a>
<a class="dropdown-item" href="MMap.html">&nbsp;&nbsp;&nbsp;3.4. Shared Memory With Memory-mapped Files</a>
<a class="dropdown-item" href="POSIXvSysV.html">&nbsp;&nbsp;&nbsp;3.5. POSIX vs. System V IPC</a>
<a class="dropdown-item" href="MQueues.html">&nbsp;&nbsp;&nbsp;3.6. Message Passing With Message Queues</a>
<a class="dropdown-item" href="ShMem.html">&nbsp;&nbsp;&nbsp;3.7. Shared Memory</a>
<a class="dropdown-item" href="IPCSems.html">&nbsp;&nbsp;&nbsp;3.8. Semaphores</a>
<a class="dropdown-item" href="Extended3Bash.html">&nbsp;&nbsp;&nbsp;3.9. Extended Example: Bash-lite: A Simple Command-line Shell</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 4</b></a>
<a class="dropdown-item" href="SocketsOverview.html">&nbsp;&nbsp;&nbsp;4.1. Networked Concurrency</a>
<a class="dropdown-item" href="FiveLayer.html">&nbsp;&nbsp;&nbsp;4.2. The TCP/IP Internet Model</a>
<a class="dropdown-item" href="NetApps.html">&nbsp;&nbsp;&nbsp;4.3. Network Applications and Protocols</a>
<a class="dropdown-item" href="Sockets.html">&nbsp;&nbsp;&nbsp;4.4. The Socket Interface</a>
<a class="dropdown-item" href="TCPSockets.html">&nbsp;&nbsp;&nbsp;4.5. TCP Socket Programming: HTTP</a>
<a class="dropdown-item" href="UDPSockets.html">&nbsp;&nbsp;&nbsp;4.6. UDP Socket Programming: DNS</a>
<a class="dropdown-item" href="AppBroadcast.html">&nbsp;&nbsp;&nbsp;4.7. Application-Layer Broadcasting: DHCP</a>
<a class="dropdown-item" href="Extended4CGI.html">&nbsp;&nbsp;&nbsp;4.8. Extended Example: CGI Web Server</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 5</b></a>
<a class="dropdown-item" href="InternetOverview.html">&nbsp;&nbsp;&nbsp;5.1. The Internet and Connectivity</a>
<a class="dropdown-item" href="AppLayer.html">&nbsp;&nbsp;&nbsp;5.2. Application Layer: Overlay Networks</a>
<a class="dropdown-item" href="TransLayer.html">&nbsp;&nbsp;&nbsp;5.3. Transport Layer</a>
<a class="dropdown-item" href="NetSec.html">&nbsp;&nbsp;&nbsp;5.4. Network Security Fundamentals</a>
<a class="dropdown-item" href="NetLayer.html">&nbsp;&nbsp;&nbsp;5.5. Network Layer: IP</a>
<a class="dropdown-item" href="LinkLayer.html">&nbsp;&nbsp;&nbsp;5.6. Link Layer</a>
<a class="dropdown-item" href="Wireless.html">&nbsp;&nbsp;&nbsp;5.7. Wireless Connectivity: Wi-Fi, Bluetooth, and Zigbee</a>
<a class="dropdown-item" href="Extended5DNS.html">&nbsp;&nbsp;&nbsp;5.8. Extended Example: DNS client</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 6</b></a>
<a class="dropdown-item" href="ThreadsOverview.html">&nbsp;&nbsp;&nbsp;6.1. Concurrency with Multithreading</a>
<a class="dropdown-item" href="ProcVThreads.html">&nbsp;&nbsp;&nbsp;6.2. Processes vs. Threads</a>
<a class="dropdown-item" href="RaceConditions.html">&nbsp;&nbsp;&nbsp;6.3. Race Conditions and Critical Sections</a>
<a class="dropdown-item" href="POSIXThreads.html">&nbsp;&nbsp;&nbsp;6.4. POSIX Thread Library</a>
<a class="dropdown-item" href="ThreadArgs.html">&nbsp;&nbsp;&nbsp;6.5. Thread Arguments and Return Values</a>
<a class="dropdown-item" href="ImplicitThreads.html">&nbsp;&nbsp;&nbsp;6.6. Implicit Threading and Language-based Threads</a>
<a class="dropdown-item" href="Extended6Input.html">&nbsp;&nbsp;&nbsp;6.7. Extended Example: Keyboard Input Listener</a>
<a class="dropdown-item" href="Extended6Primes.html">&nbsp;&nbsp;&nbsp;6.8. Extended Example: Concurrent Prime Number Search</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 7</b></a>
<a class="dropdown-item" href="SynchOverview.html">&nbsp;&nbsp;&nbsp;7.1. Synchronization Primitives</a>
<a class="dropdown-item" href="CritSect.html">&nbsp;&nbsp;&nbsp;7.2. Critical Sections and Peterson's Solution</a>
<a class="dropdown-item" href="Locks.html">&nbsp;&nbsp;&nbsp;7.3. Locks</a>
<a class="dropdown-item" href="Semaphores.html">&nbsp;&nbsp;&nbsp;7.4. Semaphores</a>
<a class="dropdown-item" href="Barriers.html">&nbsp;&nbsp;&nbsp;7.5. Barriers</a>
<a class="dropdown-item" href="Condvars.html">&nbsp;&nbsp;&nbsp;7.6. Condition Variables</a>
<a class="dropdown-item" href="Deadlock.html">&nbsp;&nbsp;&nbsp;7.7. Deadlock</a>
<a class="dropdown-item" href="Extended7Events.html">&nbsp;&nbsp;&nbsp;7.8. Extended Example: Event Log File</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 8</b></a>
<a class="dropdown-item" href="SynchProblemsOverview.html">&nbsp;&nbsp;&nbsp;8.1. Synchronization Patterns and Problems</a>
<a class="dropdown-item" href="SynchDesign.html">&nbsp;&nbsp;&nbsp;8.2. Basic Synchronization Design Patterns</a>
<a class="dropdown-item" href="ProdCons.html">&nbsp;&nbsp;&nbsp;8.3. Producer-Consumer Problem</a>
<a class="dropdown-item" href="ReadWrite.html">&nbsp;&nbsp;&nbsp;8.4. Readers-Writers Problem</a>
<a class="dropdown-item" href="DiningPhil.html">&nbsp;&nbsp;&nbsp;8.5. Dining Philosophers Problem and Deadlock</a>
<a class="dropdown-item" href="CigSmokers.html">&nbsp;&nbsp;&nbsp;8.6. Cigarette Smokers Problem and the Limits of Semaphores and Locks</a>
<a class="dropdown-item" href="Extended8ModExp.html">&nbsp;&nbsp;&nbsp;8.7. Extended Example: Parallel Modular Exponentiation</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 9</b></a>
<a class="dropdown-item" href="ParallelDistributedOverview.html">&nbsp;&nbsp;&nbsp;9.1. Parallel and Distributed Systems</a>
<a class="dropdown-item" href="ParVConc.html">&nbsp;&nbsp;&nbsp;9.2. Parallelism vs. Concurrency</a>
<a class="dropdown-item" href="ParallelDesign.html">&nbsp;&nbsp;&nbsp;9.3. Parallel Design Patterns</a>
<a class="dropdown-item" href="Scaling.html">&nbsp;&nbsp;&nbsp;9.4. Limits of Parallelism and Scaling</a>
<a class="dropdown-item" href="DistTiming.html">&nbsp;&nbsp;&nbsp;9.5. Timing in Distributed Environments</a>
<a class="dropdown-item" href="DistDataStorage.html">&nbsp;&nbsp;&nbsp;9.6. Reliable Data Storage and Location</a>
<a class="dropdown-item" href="DistConsensus.html">&nbsp;&nbsp;&nbsp;9.7. Consensus in Distributed Systems</a>
<a class="dropdown-item" href="Extended9Blockchain.html">&nbsp;&nbsp;&nbsp;9.8. Extended Example: Blockchain Proof-of-Work</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Appendix A</b></a>
<a class="dropdown-item" href="CLangOverview.html">&nbsp;&nbsp;&nbsp;A.1. C Language Reintroduction</a>
<a class="dropdown-item" href="Debugging.html">&nbsp;&nbsp;&nbsp;A.2. Documentation and Debugging</a>
<a class="dropdown-item" href="BasicTypes.html">&nbsp;&nbsp;&nbsp;A.3. Basic Types and Pointers</a>
<a class="dropdown-item" href="Arrays.html">&nbsp;&nbsp;&nbsp;A.4. Arrays, Structs, Enums, and Type Definitions</a>
<a class="dropdown-item" href="Functions.html">&nbsp;&nbsp;&nbsp;A.5. Functions and Scope</a>
<a class="dropdown-item" href="Pointers.html">&nbsp;&nbsp;&nbsp;A.6. Pointers and Dynamic Allocation</a>
<a class="dropdown-item" href="Strings.html">&nbsp;&nbsp;&nbsp;A.7. Strings</a>
<a class="dropdown-item" href="FunctionPointers.html">&nbsp;&nbsp;&nbsp;A.8. Function Pointers</a>
<a class="dropdown-item" href="Files.html">&nbsp;&nbsp;&nbsp;A.9. Files</a>
</div>
</li>
</ul>
</div>
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
<li class="nav-item"><a class="nav-link jmu-gold" href="https://w3.cs.jmu.edu/kirkpams/OpenCSF/Books/csf/source/Extended9Blockchain.rst"
target="_blank" rel="nofollow">Show Source</a></li>
</ul>
</nav>
<div class="container center">
«&#160;&#160;<a id="prevmod" href="DistConsensus.html">9.7. Consensus in Distributed Systems</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod" href="CLangOverview.html">10.1. C Language Reintroduction</a>&#160;&#160;»
</div>
<br />
<script type="text/javascript" src="_static/js/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/javascript" src="_static/js/jquery-1.11.4-ui.min.js"></script>
<script type="text/javascript" src="_static/js/forge-0.7.0.min.js"></script>
<script type="text/javascript" src="../../../JSAV/lib/jquery.transit.js"></script>
<script type="text/javascript" src="../../../JSAV/lib/raphael.js"></script>
<script type="text/javascript" src="../../../JSAV/build/JSAV-min.js"></script>
<script type="text/javascript" src="_static/js/config.js"></script>
<script type="text/javascript" src="../../../lib/odsaUtils-min.js"></script>
<script type="text/javascript" src="../../../lib/odsaMOD-min.js"></script>
<script type="text/javascript" src="_static/js/d3-4.13.0.min.js"></script>
<script type="text/javascript" src="_static/js/d3-selection-multi.v1.min.js"></script>
<script type="text/javascript" src="../../../lib/dataStructures.js"></script>
<div class="container">
<script>ODSA.SETTINGS.DISP_MOD_COMP = true;ODSA.SETTINGS.MODULE_NAME = "Extended9Blockchain";ODSA.SETTINGS.MODULE_LONG_NAME = "Extended Example: Blockchain Proof-of-Work";ODSA.SETTINGS.MODULE_CHAPTER = "Parallel and Distributed Systems"; ODSA.SETTINGS.BUILD_DATE = "2021-06-01 15:31:51"; ODSA.SETTINGS.BUILD_CMAP = false;JSAV_OPTIONS['lang']='en';JSAV_EXERCISE_OPTIONS['code']='java';</script><div class="section" id="extended-example-blockchain-proof-of-work">
<h1>9.8. Extended Example: Blockchain Proof-of-Work<a class="headerlink" href="Extended9Blockchain.html#extended-example-blockchain-proof-of-work" title="Permalink to this headline"></a></h1>
<p>A blockchain is a sequence of messages that create a verifiable ordering of
events. Blockchains can be used in a variety of applications, such as
cryptocurrency (Bitcoin) or other distributed database ledgers. One key idea
behind a blockchain is that new entries are difficult to generate. A common
technique is to require a proof-of-work calculation, such as finding a string
that produces a cryptographic hash value with several leading 0s.</p>
<p>Consider the example output below. Each line contains a message index (0, 1, 2,
…) followed by the previous lines hash value (<code class="docutils literal notranslate"><span class="pre">0000...</span></code>, <code class="docutils literal notranslate"><span class="pre">f74d...</span></code>, and so on), a
timestamp (omitted for brevity), then a log message (“Genesis Block”). The line
then ends with an integer value (called a <em>nonce</em>), such as <code class="docutils literal notranslate"><span class="pre">0000</span></code>, <code class="docutils literal notranslate"><span class="pre">22d75</span></code>, and
<code class="docutils literal notranslate"><span class="pre">6ea</span></code> as shown. The entire line ending at the nonce is then used as input to a
cryptographic hash function. If the output of the hash does not begin with 0s,
the nonce is increased and the line is re-hashed. For instance, the second line
required 142,709 (<code class="docutils literal notranslate"><span class="pre">0x22d75</span></code>) attempts before the hash output began with 0s. Once
this entry is found, it can be added to the blockchain.</p>
<div class="highlight-none border border-dark rounded-lg bg-light px-0 mb-3 notranslate"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0">1
2
3
4
5
6
7
8</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span>$ ./blockchain
Here is the blockchain:
...0 00000000... [...] Genesis Block ...000000 f74d3a10...
...1 f74d3a10... [...] Data message 1 ...022d75 0000b38b...
...2 0000b38b... [...] Data message 2 ...0006ea 0000e2c4...
...3 0000e2c4... [...] Data message 3 ...00be80 00002c45...
...4 00002c45... [...] Data message 4 ...019e63 0000a65e...
...5 0000a65e... [...] Data message 5 ...0188a8 0000cb6f...
</pre></div>
</td></tr></table></div>
<p>The second field in each line is the previous lines hash output, which serves
the purpose of declaring that the new line is the only legitimate successor of
the previous line. That is, each line explicitly ties itself to the previous
line by including the previous lines hash in the input. Note that the first
line, often called a <em>Genesis block</em>, is special, as it does not follow any
entry. As such, a nonce of 0 is often used for this value and the hash value
does not need to begin with 0s. In this extended example, we use SHA-1 as a
cryptographic hash function simply to make the search more efficient. <strong>In
practice, SHA-1 is considered insecure and should not be use for applications
like this</strong>.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cp">#include</span> <span class="cpf">&lt;assert.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;inttypes.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;openssl/sha.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;pthread.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;stdbool.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;stdint.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;stdlib.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;string.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;time.h&gt;</span><span class="cp"></span>
<span class="cp">#define ASCTIME_LENGTH 24</span>
<span class="cp">#define BLOCKCHAIN_ZEROES 3</span>
<span class="kt">char</span> <span class="o">*</span> <span class="nf">construct_block</span> <span class="p">(</span><span class="kt">uint64_t</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="p">,</span> <span class="k">struct</span> <span class="n">tm</span> <span class="o">*</span><span class="p">,</span>
<span class="kt">char</span> <span class="o">*</span><span class="p">,</span> <span class="kt">size_t</span><span class="p">,</span> <span class="kt">uint64_t</span><span class="p">,</span> <span class="kt">size_t</span> <span class="o">*</span><span class="p">);</span>
<span class="kt">char</span> <span class="o">*</span> <span class="nf">create_genesis_block</span> <span class="p">(</span><span class="kt">void</span><span class="p">);</span>
<span class="kt">char</span> <span class="o">*</span> <span class="nf">hash_to_string</span> <span class="p">(</span><span class="kt">uint8_t</span> <span class="o">*</span><span class="n">hash</span><span class="p">);</span>
<span class="kt">char</span> <span class="o">*</span> <span class="nf">append_block</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="p">,</span> <span class="kt">size_t</span><span class="p">);</span>
<span class="kt">int</span>
<span class="nf">main</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">size_t</span> <span class="n">number_of_threads</span> <span class="o">=</span> <span class="mi">4</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">number_of_blocks</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
<span class="cm">/* Generate the blockchain pointers and create genesis block */</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">blockchain</span><span class="p">[</span><span class="n">number_of_blocks</span><span class="p">];</span>
<span class="n">memset</span> <span class="p">(</span><span class="n">blockchain</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">blockchain</span><span class="p">));</span>
<span class="n">blockchain</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">create_genesis_block</span> <span class="p">();</span>
<span class="cm">/* Use a generic message to append each time */</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">message</span> <span class="o">=</span> <span class="n">calloc</span> <span class="p">(</span><span class="mi">50</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="kt">char</span><span class="p">));</span>
<span class="kt">size_t</span> <span class="n">i</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">number_of_blocks</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">strncpy</span> <span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="s">&quot;Data message &quot;</span><span class="p">,</span> <span class="mi">50</span><span class="p">);</span>
<span class="n">snprintf</span> <span class="p">(</span><span class="n">message</span> <span class="o">+</span> <span class="n">strlen</span> <span class="p">(</span><span class="n">message</span><span class="p">),</span> <span class="mi">50</span> <span class="o">-</span> <span class="n">strlen</span> <span class="p">(</span><span class="n">message</span><span class="p">),</span> <span class="s">&quot;%zd&quot;</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span>
<span class="n">blockchain</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span>
<span class="n">append_block</span> <span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">blockchain</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">number_of_threads</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">free</span> <span class="p">(</span><span class="n">message</span><span class="p">);</span>
<span class="cm">/* Print the results of the computations */</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;Here is the blockchain:</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">number_of_blocks</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot; %s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">blockchain</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="n">free</span> <span class="p">(</span><span class="n">blockchain</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">EXIT_SUCCESS</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/* Parameters for each copy of the mining thread */</span>
<span class="k">struct</span> <span class="n">mining_params</span> <span class="p">{</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">block</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">blocklen</span><span class="p">;</span>
<span class="kt">uint64_t</span> <span class="n">nonce</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">attempts</span><span class="p">;</span>
<span class="kt">bool</span> <span class="n">success</span><span class="p">;</span>
<span class="p">};</span>
<span class="cm">/* Blockchain mining thread. Each instance of this thread starts</span>
<span class="cm"> with a block string to work with. The string contains a nonce</span>
<span class="cm"> that is iteratively incremented until the string hashes to the</span>
<span class="cm"> correct structure (leading zeroes) or the thread runs out of</span>
<span class="cm"> attempts. */</span>
<span class="kt">void</span> <span class="o">*</span>
<span class="nf">mining_thread</span> <span class="p">(</span><span class="kt">void</span> <span class="o">*</span> <span class="n">_params</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">struct</span> <span class="n">mining_params</span> <span class="o">*</span><span class="n">params</span> <span class="o">=</span> <span class="p">(</span><span class="k">struct</span> <span class="n">mining_params</span> <span class="o">*</span><span class="p">)</span> <span class="n">_params</span><span class="p">;</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">block</span> <span class="o">=</span> <span class="n">params</span><span class="o">-&gt;</span><span class="n">block</span><span class="p">;</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">nonce_loc</span> <span class="o">=</span> <span class="n">block</span> <span class="o">+</span> <span class="n">strlen</span> <span class="p">(</span><span class="n">block</span><span class="p">)</span> <span class="o">-</span> <span class="mi">16</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kt">uint8_t</span> <span class="n">hash</span><span class="p">[</span><span class="n">SHA_DIGEST_LENGTH</span><span class="p">];</span>
<span class="k">while</span> <span class="p">(</span><span class="n">count</span> <span class="o">&lt;</span> <span class="n">params</span><span class="o">-&gt;</span><span class="n">attempts</span><span class="p">)</span>
<span class="p">{</span>
<span class="cm">/* Update nonce in the string and re-calculate the hash */</span>
<span class="n">snprintf</span> <span class="p">(</span><span class="n">nonce_loc</span><span class="p">,</span> <span class="mi">17</span><span class="p">,</span> <span class="s">&quot;%016&quot;</span> <span class="n">PRIx64</span><span class="p">,</span> <span class="n">params</span><span class="o">-&gt;</span><span class="n">nonce</span><span class="o">++</span><span class="p">);</span>
<span class="n">memset</span> <span class="p">(</span><span class="n">hash</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">SHA_DIGEST_LENGTH</span><span class="p">);</span>
<span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="n">md</span> <span class="o">=</span>
<span class="n">SHA1</span> <span class="p">((</span><span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">block</span><span class="p">,</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="kt">long</span><span class="p">)</span> <span class="n">params</span><span class="o">-&gt;</span><span class="n">blocklen</span><span class="p">,</span> <span class="n">hash</span><span class="p">);</span>
<span class="cm">/* Check to see if the hash begins with the desired number of</span>
<span class="cm"> leading zeroes */</span>
<span class="kt">bool</span> <span class="n">zeroes</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">BLOCKCHAIN_ZEROES</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">md</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="n">zeroes</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="cm">/* If the leading zeroes match, update the block and exit */</span>
<span class="k">if</span> <span class="p">(</span><span class="n">zeroes</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">hash_str</span> <span class="o">=</span> <span class="n">hash_to_string</span> <span class="p">(</span><span class="n">md</span><span class="p">);</span>
<span class="n">block</span><span class="p">[</span><span class="n">strlen</span> <span class="p">(</span><span class="n">block</span><span class="p">)]</span> <span class="o">=</span> <span class="sc">&#39; &#39;</span><span class="p">;</span>
<span class="n">strncat</span> <span class="p">(</span><span class="n">block</span><span class="p">,</span> <span class="n">hash_str</span><span class="p">,</span> <span class="n">SHA_DIGEST_LENGTH</span> <span class="o">*</span> <span class="mi">2</span><span class="p">);</span>
<span class="n">free</span> <span class="p">(</span><span class="n">hash_str</span><span class="p">);</span>
<span class="n">params</span><span class="o">-&gt;</span><span class="n">success</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="n">pthread_exit</span> <span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">count</span><span class="o">++</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">pthread_exit</span> <span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/* Create a block to append to the end of the chain. Can be</span>
<span class="cm"> parallelized for improved performance, but blockchain</span>
<span class="cm"> calculations are designed to be slow. */</span>
<span class="kt">char</span> <span class="o">*</span>
<span class="nf">append_block</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="n">data</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">previous</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">num_threads</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">uint64_t</span> <span class="n">index</span> <span class="o">=</span> <span class="p">(</span><span class="kt">uint64_t</span><span class="p">)</span> <span class="n">strtoul</span> <span class="p">((</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">previous</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="mi">16</span><span class="p">);</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">prev_hash</span> <span class="o">=</span> <span class="n">calloc</span> <span class="p">(</span><span class="n">SHA_DIGEST_LENGTH</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="kt">char</span><span class="p">));</span>
<span class="n">strncpy</span> <span class="p">(</span><span class="n">prev_hash</span><span class="p">,</span>
<span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="o">&amp;</span><span class="n">previous</span><span class="p">[</span><span class="n">strlen</span> <span class="p">((</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">previous</span><span class="p">)</span> <span class="o">-</span> <span class="n">SHA_DIGEST_LENGTH</span> <span class="o">*</span> <span class="mi">2</span><span class="p">],</span>
<span class="n">SHA_DIGEST_LENGTH</span> <span class="o">*</span> <span class="mi">2</span><span class="p">);</span>
<span class="cm">/* Last block was validated, now construct a new block */</span>
<span class="kt">time_t</span> <span class="n">now</span> <span class="o">=</span> <span class="n">time</span> <span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
<span class="kt">size_t</span> <span class="n">blocklen</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">block</span> <span class="o">=</span>
<span class="n">construct_block</span> <span class="p">(</span><span class="n">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">prev_hash</span><span class="p">,</span> <span class="n">localtime</span> <span class="p">(</span><span class="o">&amp;</span><span class="n">now</span><span class="p">),</span>
<span class="n">data</span><span class="p">,</span> <span class="n">strlen</span> <span class="p">(</span><span class="n">data</span><span class="p">),</span> <span class="mi">0</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">blocklen</span><span class="p">);</span>
<span class="n">free</span> <span class="p">(</span><span class="n">prev_hash</span><span class="p">);</span>
<span class="cm">/* Repeatedly implement a fork/join pattern until the search is</span>
<span class="cm"> successful. Each time through the while-loop, create a fixed</span>
<span class="cm"> number of threads that will perform a maximum number of</span>
<span class="cm"> calculations with different nonces. For instance, using</span>
<span class="cm"> 1,000,000 attempts per thread, the first thread will use nonces</span>
<span class="cm"> 0 through 999,999, the second 1,000,000 through 1,999,999, and</span>
<span class="cm"> so forth. Once all threads have run, check to see if any were</span>
<span class="cm"> successful. If not, create a new set of threads that continue</span>
<span class="cm"> with the next group of possible nonces. */</span>
<span class="kt">size_t</span> <span class="n">attempts_per_thread</span> <span class="o">=</span> <span class="mi">1000000</span><span class="p">;</span>
<span class="kt">uint64_t</span> <span class="n">nonce</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kt">bool</span> <span class="n">success</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="k">while</span> <span class="p">(</span><span class="o">!</span> <span class="n">success</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">struct</span> <span class="n">mining_params</span> <span class="n">params</span><span class="p">[</span><span class="n">num_threads</span><span class="p">];</span>
<span class="n">pthread_t</span> <span class="kr">thread</span><span class="p">[</span><span class="n">num_threads</span><span class="p">];</span>
<span class="kt">int</span> <span class="n">i</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">num_threads</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="cm">/* Each thread needs its own copy of the block, so that</span>
<span class="cm"> it can change the nonce portion of the string. Note</span>
<span class="cm"> that we cannot just use strdup() here, because that</span>
<span class="cm"> would not allocate the additional bytes needed to</span>
<span class="cm"> append the hash for the successul search. */</span>
<span class="n">params</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">block</span> <span class="o">=</span>
<span class="n">calloc</span> <span class="p">(</span><span class="n">blocklen</span> <span class="o">+</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">SHA_DIGEST_LENGTH</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="kt">char</span><span class="p">));</span>
<span class="n">strncpy</span> <span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">block</span><span class="p">,</span> <span class="n">block</span><span class="p">,</span> <span class="n">blocklen</span><span class="p">);</span>
<span class="n">params</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">blocklen</span> <span class="o">=</span> <span class="n">blocklen</span><span class="p">;</span>
<span class="n">params</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">nonce</span> <span class="o">=</span> <span class="n">nonce</span><span class="p">;</span>
<span class="n">params</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">attempts</span> <span class="o">=</span> <span class="n">attempts_per_thread</span><span class="p">;</span>
<span class="n">params</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">success</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="n">pthread_create</span> <span class="p">(</span><span class="o">&amp;</span><span class="kr">thread</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">mining_thread</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">params</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="cm">/* The starting nonce for each thread is repeatedly</span>
<span class="cm"> incremented to ensure no two threads search the same</span>
<span class="cm"> set of values */</span>
<span class="n">nonce</span> <span class="o">+=</span> <span class="n">attempts_per_thread</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/* For this group of threads, check to see if any were</span>
<span class="cm"> successful. If so, replace the generated block string with</span>
<span class="cm"> that thread&#39;s copy. */</span>
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">num_threads</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">pthread_join</span> <span class="p">(</span><span class="kr">thread</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="nb">NULL</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">success</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">success</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">free</span> <span class="p">(</span><span class="n">block</span><span class="p">);</span>
<span class="n">block</span> <span class="o">=</span> <span class="n">params</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">block</span><span class="p">;</span>
<span class="n">success</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span>
<span class="n">free</span> <span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">block</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">block</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/* Create a genesis block to serve as the foundation */</span>
<span class="kt">char</span> <span class="o">*</span>
<span class="nf">create_genesis_block</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
<span class="cm">/* Start off with a bogus 0 hash */</span>
<span class="kt">uint8_t</span> <span class="n">hash</span><span class="p">[</span><span class="n">SHA_DIGEST_LENGTH</span><span class="p">];</span>
<span class="n">memset</span> <span class="p">(</span><span class="n">hash</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">SHA_DIGEST_LENGTH</span><span class="p">);</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">hash_str</span> <span class="o">=</span> <span class="n">hash_to_string</span> <span class="p">(</span><span class="n">hash</span><span class="p">);</span>
<span class="cm">/* Create a genesis block with the current time */</span>
<span class="kt">time_t</span> <span class="n">now</span> <span class="o">=</span> <span class="n">time</span> <span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
<span class="kt">size_t</span> <span class="n">blocklen</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">genesis</span> <span class="o">=</span>
<span class="n">construct_block</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="p">(</span><span class="kt">char</span><span class="o">*</span><span class="p">)</span> <span class="n">hash_str</span><span class="p">,</span> <span class="n">localtime</span> <span class="p">(</span><span class="o">&amp;</span><span class="n">now</span><span class="p">),</span>
<span class="s">&quot;Genesis Block&quot;</span><span class="p">,</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">blocklen</span><span class="p">);</span>
<span class="n">free</span> <span class="p">(</span><span class="n">hash_str</span><span class="p">);</span>
<span class="cm">/* Compute the hash of the genesis block and append it */</span>
<span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="n">md</span> <span class="o">=</span>
<span class="n">SHA1</span> <span class="p">((</span><span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">genesis</span><span class="p">,</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="kt">long</span><span class="p">)</span> <span class="n">blocklen</span><span class="p">,</span> <span class="n">hash</span><span class="p">);</span>
<span class="n">hash_str</span> <span class="o">=</span> <span class="n">hash_to_string</span> <span class="p">(</span><span class="n">md</span><span class="p">);</span>
<span class="n">genesis</span><span class="p">[</span><span class="n">strlen</span> <span class="p">((</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">genesis</span><span class="p">)]</span> <span class="o">=</span> <span class="sc">&#39; &#39;</span><span class="p">;</span>
<span class="n">strncat</span> <span class="p">((</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">genesis</span><span class="p">,</span> <span class="n">hash_str</span><span class="p">,</span> <span class="n">SHA_DIGEST_LENGTH</span> <span class="o">*</span> <span class="mi">2</span><span class="p">);</span>
<span class="n">free</span> <span class="p">(</span><span class="n">hash_str</span><span class="p">);</span>
<span class="k">return</span> <span class="n">genesis</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/* Constrct a block of the following form:</span>
<span class="cm"> index.previous hash.[timestamp].data.nonce</span>
<span class="cm"> (Dots denote spaces for readability of the line.)</span>
<span class="cm"> Note that the dynamic allocation also includes space for this</span>
<span class="cm"> block&#39;s hash at the end, but those bytes are initialized to</span>
<span class="cm"> all 0. */</span>
<span class="kt">char</span> <span class="o">*</span>
<span class="nf">construct_block</span> <span class="p">(</span><span class="kt">uint64_t</span> <span class="n">index</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">previous</span><span class="p">,</span>
<span class="k">struct</span> <span class="n">tm</span> <span class="o">*</span><span class="n">timestamp</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">data</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">length</span><span class="p">,</span>
<span class="kt">uint64_t</span> <span class="n">nonce</span><span class="p">,</span> <span class="kt">size_t</span> <span class="o">*</span><span class="n">block_length</span><span class="p">)</span>
<span class="p">{</span>
<span class="o">*</span><span class="n">block_length</span> <span class="o">=</span>
<span class="mi">16</span> <span class="o">+</span> <span class="mi">16</span> <span class="o">+</span> <span class="n">length</span> <span class="o">+</span> <span class="mi">4</span> <span class="o">+</span> <span class="c1">// index, nonce, length, spaces</span>
<span class="n">SHA_DIGEST_LENGTH</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="c1">// previous hash</span>
<span class="n">ASCTIME_LENGTH</span> <span class="o">+</span> <span class="mi">2</span><span class="p">;</span> <span class="c1">// [ASCII timestamp]</span>
<span class="cm">/* Allocate extra space for the block&#39;s hash, as well */</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">block</span> <span class="o">=</span>
<span class="n">calloc</span> <span class="p">(</span><span class="o">*</span><span class="n">block_length</span> <span class="o">+</span> <span class="mi">2</span> <span class="o">+</span> <span class="n">SHA_DIGEST_LENGTH</span> <span class="o">*</span> <span class="mi">2</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="kt">char</span><span class="p">));</span>
<span class="cm">/* Both the index and the nonce are padded with leading 0s to be</span>
<span class="cm"> fixed width */</span>
<span class="n">snprintf</span> <span class="p">(</span><span class="n">block</span><span class="p">,</span> <span class="mi">17</span><span class="p">,</span> <span class="s">&quot;%016&quot;</span> <span class="n">PRIx64</span><span class="p">,</span> <span class="n">index</span><span class="p">);</span>
<span class="n">block</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span> <span class="sc">&#39; &#39;</span><span class="p">;</span>
<span class="n">strncat</span> <span class="p">(</span><span class="n">block</span><span class="p">,</span> <span class="n">previous</span><span class="p">,</span> <span class="n">SHA_DIGEST_LENGTH</span> <span class="o">*</span> <span class="mi">2</span><span class="p">);</span>
<span class="cm">/* For the [timestamp] the asctime returns a trailing</span>
<span class="cm"> &#39;\n&#39; that must be overwritten with the &#39;]&#39; */</span>
<span class="n">block</span><span class="p">[</span><span class="n">SHA_DIGEST_LENGTH</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">17</span><span class="p">]</span> <span class="o">=</span> <span class="sc">&#39; &#39;</span><span class="p">;</span>
<span class="n">block</span><span class="p">[</span><span class="n">SHA_DIGEST_LENGTH</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">18</span><span class="p">]</span> <span class="o">=</span> <span class="sc">&#39;[&#39;</span><span class="p">;</span>
<span class="n">strncat</span> <span class="p">(</span><span class="n">block</span><span class="p">,</span> <span class="n">asctime</span> <span class="p">(</span><span class="n">timestamp</span><span class="p">),</span> <span class="o">*</span><span class="n">block_length</span> <span class="o">-</span> <span class="n">strlen</span> <span class="p">(</span><span class="n">block</span><span class="p">));</span>
<span class="n">block</span><span class="p">[</span><span class="n">strlen</span> <span class="p">(</span><span class="n">block</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="sc">&#39;]&#39;</span><span class="p">;</span>
<span class="cm">/* For readability of data, add a space before and after */</span>
<span class="n">block</span><span class="p">[</span><span class="n">strlen</span> <span class="p">(</span><span class="n">block</span><span class="p">)]</span> <span class="o">=</span> <span class="sc">&#39; &#39;</span><span class="p">;</span>
<span class="n">strncat</span> <span class="p">(</span><span class="n">block</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">length</span><span class="p">);</span>
<span class="n">block</span><span class="p">[</span><span class="o">*</span><span class="n">block_length</span> <span class="o">-</span> <span class="mi">17</span><span class="p">]</span> <span class="o">=</span> <span class="sc">&#39; &#39;</span><span class="p">;</span>
<span class="n">snprintf</span> <span class="p">(</span><span class="n">block</span> <span class="o">+</span> <span class="o">*</span><span class="n">block_length</span> <span class="o">-</span> <span class="mi">16</span><span class="p">,</span> <span class="mi">17</span><span class="p">,</span> <span class="s">&quot;%016&quot;</span> <span class="n">PRIx64</span><span class="p">,</span> <span class="n">nonce</span><span class="p">);</span>
<span class="k">return</span> <span class="n">block</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/* Convert a SHA hash to a readable hex string */</span>
<span class="kt">char</span> <span class="o">*</span>
<span class="nf">hash_to_string</span> <span class="p">(</span><span class="kt">uint8_t</span> <span class="o">*</span><span class="n">hash</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">size_t</span> <span class="n">j</span><span class="p">;</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">str</span> <span class="o">=</span> <span class="n">calloc</span> <span class="p">(</span><span class="n">SHA_DIGEST_LENGTH</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="kt">char</span><span class="p">));</span>
<span class="cm">/* Each byte gets split into two hex digits */</span>
<span class="k">for</span> <span class="p">(</span><span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">SHA_DIGEST_LENGTH</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span>
<span class="n">sprintf</span> <span class="p">(</span><span class="o">&amp;</span><span class="n">str</span><span class="p">[</span><span class="n">j</span><span class="o">*</span><span class="mi">2</span><span class="p">],</span> <span class="s">&quot;%02x&quot;</span><span class="p">,</span> <span class="n">hash</span><span class="p">[</span><span class="n">j</span><span class="p">]);</span>
<span class="k">return</span> <span class="n">str</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
</div>
<div class="container">
<div class="mt-4 container center">
«&#160;&#160;<a id="prevmod1" href="DistConsensus.html">9.7. Consensus in Distributed Systems</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod1" href="CLangOverview.html">10.1. C Language Reintroduction</a>&#160;&#160;»
</div>
</div>
<br />
<div class="row jmu-dark-purple-bg">
<div class="col-md-12">
<center>
<a id="contact_us" class="btn button-link-no-blue jmu-gold" rel="nofollow" href="mailto:webmaster@opencsf.org" role="button">Contact Us</a>
<a id="license" class="btn button-link-no-blue jmu-gold" rel="nofollow" href="https://w3.cs.jmu.edu/kirkpams/OpenCSF/lib/license.html" target="_blank">License</a>
</center>
</div>
</div>
<script src="_static/js/popper.js-1.14.7-min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="_static/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>