SHOW:
|
|
- or go back to the newest paste.
1 | - | // Copyright "Remember remember the 5th of November" 2013 |
1 | + | |
2 | #include <stdio.h> | |
3 | #include <stdbool.h> | |
4 | #include <inttypes.h> | |
5 | #include <ctype.h> | |
6 | #include <string.h> | |
7 | #include <time.h> | |
8 | #include <openssl/sha.h> | |
9 | ||
10 | //Copied from Bitcoin source | |
11 | const uint64_t COIN = 100000000; | |
12 | const uint64_t CENT = 1000000; | |
13 | ||
14 | uint32_t OP_CHECKSIG = 172; // This is expressed as 0xAC | |
15 | bool generateBlock = false; | |
16 | uint32_t startNonce = 0; | |
17 | uint32_t unixtime = 0; | |
18 | ||
19 | typedef struct { | |
20 | /* Hash of Tx */ | |
21 | uint8_t merkleHash[32]; | |
22 | ||
23 | /* Tx serialization before hashing */ | |
24 | uint8_t *serializedData; | |
25 | ||
26 | /* Tx version */ | |
27 | uint32_t version; | |
28 | ||
29 | /* Input */ | |
30 | uint8_t numInputs; // Program assumes one input | |
31 | uint8_t prevOutput[32]; | |
32 | uint32_t prevoutIndex; | |
33 | uint8_t *scriptSig; | |
34 | uint32_t sequence; | |
35 | ||
36 | /* Output */ | |
37 | uint8_t numOutputs; // Program assumes one output | |
38 | uint64_t outValue; | |
39 | uint8_t *pubkeyScript; | |
40 | ||
41 | /* Final */ | |
42 | uint32_t locktime; | |
43 | } Transaction; | |
44 | ||
45 | // Got this off the internet. Am not sure if it can fail in some circumstances | |
46 | void byteswap(uint8_t *buf, int length) | |
47 | { | |
48 | int i; | |
49 | uint8_t temp; | |
50 | ||
51 | for(i = 0; i < length / 2; i++) | |
52 | { | |
53 | temp = buf[i]; | |
54 | buf[i] = buf[length - i - 1]; | |
55 | buf[length - i - 1] = temp; | |
56 | } | |
57 | } | |
58 | ||
59 | // Following two functions are borrowed from cgminer. | |
60 | char *bin2hex(const unsigned char *p, size_t len) | |
61 | { | |
62 | char *s = malloc((len * 2) + 1); | |
63 | unsigned int i; | |
64 | ||
65 | if (!s) | |
66 | return NULL; | |
67 | ||
68 | for (i = 0; i < len; i++) | |
69 | sprintf(s + (i * 2), "%02x", (unsigned int) p[i]); | |
70 | ||
71 | return s; | |
72 | } | |
73 | ||
74 | size_t hex2bin(unsigned char *p, const char *hexstr, size_t len) | |
75 | { | |
76 | int ret = 0; | |
77 | size_t retlen = len; | |
78 | ||
79 | while (*hexstr && len) { | |
80 | char hex_byte[4]; | |
81 | unsigned int v; | |
82 | ||
83 | if (!hexstr[1]) { | |
84 | return ret; | |
85 | } | |
86 | ||
87 | memset(hex_byte, 0, 4); | |
88 | hex_byte[0] = hexstr[0]; | |
89 | hex_byte[1] = hexstr[1]; | |
90 | ||
91 | if (sscanf(hex_byte, "%x", &v) != 1) { | |
92 | return ret; | |
93 | } | |
94 | ||
95 | *p = (unsigned char) v; | |
96 | ||
97 | p++; | |
98 | hexstr += 2; | |
99 | len--; | |
100 | } | |
101 | ||
102 | if (len == 0 && *hexstr == 0) | |
103 | ret = retlen; | |
104 | ||
105 | return ret; | |
106 | } | |
107 | ||
108 | Transaction *InitTransaction() | |
109 | { | |
110 | Transaction *transaction; | |
111 | ||
112 | transaction = calloc(1, sizeof(*transaction)); | |
113 | if(!transaction) | |
114 | { | |
115 | return NULL; | |
116 | } | |
117 | ||
118 | // Set some initial data that will remain constant throughout the program | |
119 | transaction->version = 1; | |
120 | transaction->numInputs = 1; | |
121 | transaction->numOutputs = 1; | |
122 | transaction->locktime = 0; | |
123 | transaction->prevoutIndex = 0xFFFFFFFF; | |
124 | transaction->sequence = 0xFFFFFFFF; | |
125 | transaction->outValue = 50*COIN; | |
126 | ||
127 | // We initialize the previous output to 0 as there is none | |
128 | memset(transaction->prevOutput, 0, 32); | |
129 | ||
130 | return transaction; | |
131 | } | |
132 | ||
133 | int main(int argc, char *argv[]) | |
134 | { | |
135 | Transaction *transaction; | |
136 | unsigned char hash1[32], hash2[32]; | |
137 | char timestamp[255], pubkey[132]; | |
138 | uint32_t timestamp_len = 0, scriptSig_len = 0, pubkey_len = 0, pubkeyScript_len = 0; | |
139 | uint32_t nBits = 0; | |
140 | ||
141 | if((argc-1) < 3) | |
142 | { | |
143 | fprintf(stderr, "Usage: genesisgen [options] <pubkey> \"<timestamp>\" <nBits>\n"); | |
144 | return 0; | |
145 | } | |
146 | ||
147 | pubkey_len = strlen(argv[1]) / 2; // One byte is represented as two hex characters, thus we divide by two to get real length. | |
148 | timestamp_len = strlen(argv[2]); | |
149 | ||
150 | if(pubkey_len != 65) | |
151 | { | |
152 | fprintf(stderr, "Invalid public key length! %s\n", argv[1]); | |
153 | return 0; | |
154 | } | |
155 | ||
156 | if(timestamp_len > 254 || timestamp_len <= 0) | |
157 | { | |
158 | fprintf(stderr, "Size of timestamp is 0 or exceeds maximum length of 254 characters!\n"); | |
159 | return 0; | |
160 | } | |
161 | ||
162 | transaction = InitTransaction(); | |
163 | if(!transaction) | |
164 | { | |
165 | fprintf(stderr, "Could not allocate memory! Exiting...\n"); | |
166 | return 0; | |
167 | } | |
168 | ||
169 | strncpy(pubkey, argv[1], sizeof(pubkey)); | |
170 | strncpy(timestamp, argv[2], sizeof(timestamp)); | |
171 | sscanf(argv[3], "%lu", (long unsigned int *)&nBits); | |
172 | ||
173 | pubkey_len = strlen(pubkey) >> 1; | |
174 | scriptSig_len = timestamp_len; | |
175 | ||
176 | // Encode pubkey to binary and prepend pubkey size, then append the OP_CHECKSIG byte | |
177 | transaction->pubkeyScript = malloc((pubkey_len+2)*sizeof(uint8_t)); | |
178 | pubkeyScript_len = hex2bin(transaction->pubkeyScript+1, pubkey, pubkey_len); // No error checking, yeah. | |
179 | transaction->pubkeyScript[0] = 0x41; // A public key is 32 bytes X coordinate, 32 bytes Y coordinate and one byte 0x04, so 65 bytes i.e 0x41 in Hex. | |
180 | pubkeyScript_len+=1; | |
181 | transaction->pubkeyScript[pubkeyScript_len++] = OP_CHECKSIG; | |
182 | ||
183 | // Encode timestamp to binary | |
184 | transaction->scriptSig = malloc(scriptSig_len*sizeof(uint8_t)); | |
185 | uint32_t scriptSig_pos = 0; | |
186 | ||
187 | ||
188 | // This is basically how I believe the size of the nBits is calculated | |
189 | if(nBits <= 255) | |
190 | { | |
191 | transaction->scriptSig[scriptSig_pos++] = 0x01; | |
192 | transaction->scriptSig[scriptSig_pos++] = (uint8_t)nBits; | |
193 | } | |
194 | else if(nBits <= 65535) | |
195 | { | |
196 | transaction->scriptSig[scriptSig_pos++] = 0x02; | |
197 | memcpy(transaction->scriptSig+scriptSig_pos, &nBits, 2); | |
198 | scriptSig_pos+=2; | |
199 | } | |
200 | else if(nBits <= 16777215) | |
201 | { | |
202 | transaction->scriptSig[scriptSig_pos++] = 0x03; | |
203 | memcpy(transaction->scriptSig+scriptSig_pos, &nBits, 3); | |
204 | scriptSig_pos+=3; | |
205 | } | |
206 | else //else if(nBits <= 4294967296LL) | |
207 | { | |
208 | transaction->scriptSig[scriptSig_pos++] = 0x04; | |
209 | memcpy(transaction->scriptSig+scriptSig_pos, &nBits, 4); | |
210 | scriptSig_pos+=4; | |
211 | } | |
212 | ||
213 | // Important! In the Bitcoin code there is a statement 'CBigNum(4)' | |
214 | // i've been wondering for a while what it is but | |
215 | // seeing as alt-coins keep it the same, we'll do it here as well | |
216 | // It should essentially mean PUSH 1 byte on the stack which in this case is 0x04 or just 4 | |
217 | transaction->scriptSig[scriptSig_pos++] = 0x01; | |
218 | transaction->scriptSig[scriptSig_pos++] = 0x04; | |
219 | ||
220 | transaction->scriptSig[scriptSig_pos++] = (uint8_t)scriptSig_len; | |
221 | ||
222 | scriptSig_len += scriptSig_pos; | |
223 | transaction->scriptSig = realloc(transaction->scriptSig, scriptSig_len*sizeof(uint8_t)); | |
224 | memcpy(transaction->scriptSig+scriptSig_pos, (const unsigned char *)timestamp, timestamp_len); | |
225 | ||
226 | // Here we are asuming some values will have the same size | |
227 | uint32_t serializedLen = | |
228 | 4 // tx version | |
229 | +1 // number of inputs | |
230 | +32 // hash of previous output | |
231 | +4 // previous output's index | |
232 | +1 // 1 byte for the size of scriptSig | |
233 | +scriptSig_len | |
234 | +4 // size of sequence | |
235 | +1 // number of outputs | |
236 | +8 // 8 bytes for coin value | |
237 | +1 // 1 byte to represent size of the pubkey Script | |
238 | +pubkeyScript_len | |
239 | +4; // 4 bytes for lock time | |
240 | ||
241 | // Now let's serialize the data | |
242 | uint32_t serializedData_pos = 0; | |
243 | transaction->serializedData = malloc(serializedLen*sizeof(uint8_t)); | |
244 | memcpy(transaction->serializedData+serializedData_pos, &transaction->version, 4); | |
245 | serializedData_pos += 4; | |
246 | memcpy(transaction->serializedData+serializedData_pos, &transaction->numInputs, 1); | |
247 | serializedData_pos += 1; | |
248 | memcpy(transaction->serializedData+serializedData_pos, transaction->prevOutput, 32); | |
249 | serializedData_pos += 32; | |
250 | memcpy(transaction->serializedData+serializedData_pos, &transaction->prevoutIndex, 4); | |
251 | serializedData_pos += 4; | |
252 | memcpy(transaction->serializedData+serializedData_pos, &scriptSig_len, 1); | |
253 | serializedData_pos += 1; | |
254 | memcpy(transaction->serializedData+serializedData_pos, transaction->scriptSig, scriptSig_len); | |
255 | serializedData_pos += scriptSig_len; | |
256 | memcpy(transaction->serializedData+serializedData_pos, &transaction->sequence, 4); | |
257 | serializedData_pos += 4; | |
258 | memcpy(transaction->serializedData+serializedData_pos, &transaction->numOutputs, 1); | |
259 | serializedData_pos += 1; | |
260 | memcpy(transaction->serializedData+serializedData_pos, &transaction->outValue, 8); | |
261 | serializedData_pos += 8; | |
262 | memcpy(transaction->serializedData+serializedData_pos, &pubkeyScript_len, 1); | |
263 | serializedData_pos += 1; | |
264 | memcpy(transaction->serializedData+serializedData_pos, transaction->pubkeyScript, pubkeyScript_len); | |
265 | serializedData_pos += pubkeyScript_len; | |
266 | memcpy(transaction->serializedData+serializedData_pos, &transaction->locktime, 4); | |
267 | serializedData_pos += 4; | |
268 | ||
269 | // Now that the data is serialized | |
270 | // we hash it with SHA256 and then hash that result to get merkle hash | |
271 | SHA256(transaction->serializedData, serializedLen, hash1); | |
272 | SHA256(hash1, 32, hash2); | |
273 | ||
274 | // This copy isn't necessary imo, but here for clarity | |
275 | memcpy(transaction->merkleHash, hash2, 32); | |
276 | ||
277 | char *merkleHash = bin2hex(transaction->merkleHash, 32); | |
278 | byteswap(transaction->merkleHash, 32); | |
279 | char *merkleHashSwapped = bin2hex(transaction->merkleHash, 32); | |
280 | char *txScriptSig = bin2hex(transaction->scriptSig, scriptSig_len); | |
281 | char *pubScriptSig = bin2hex(transaction->pubkeyScript, pubkeyScript_len); | |
282 | printf("\nCoinbase: %s\n\nPubkeyScript: %s\n\nMerkle Hash: %s\nByteswapped: %s\n",txScriptSig, pubScriptSig, merkleHash, merkleHashSwapped); | |
283 | ||
284 | //if(generateBlock) | |
285 | { | |
286 | printf("Generating block...\n"); | |
287 | if(!unixtime) | |
288 | { | |
289 | unixtime = time(NULL); | |
290 | } | |
291 | ||
292 | unsigned char block_header[80], block_hash1[32], block_hash2[32]; | |
293 | uint32_t blockversion = 1; | |
294 | memcpy(block_header, &blockversion, 4); | |
295 | memset(block_header+4, 0, 32); | |
296 | byteswap(transaction->merkleHash, 32); // We swapped it before, so do it again now. | |
297 | memcpy(block_header+36, transaction->merkleHash, 32); | |
298 | memcpy(block_header+68, &unixtime, 4); | |
299 | memcpy(block_header+72, &nBits, 4); | |
300 | memcpy(block_header+76, &startNonce, 4); | |
301 | ||
302 | uint32_t *pNonce = (uint32_t *)(block_header + 76); | |
303 | uint32_t *pUnixtime = (uint32_t *)(block_header + 68); | |
304 | unsigned int counter, start = time(NULL); | |
305 | while(1) | |
306 | { | |
307 | SHA256(block_header, 80, block_hash1); | |
308 | SHA256(block_hash1, 32, block_hash2); | |
309 | ||
310 | unsigned int check = *((uint32_t *)(block_hash2 + 28)); // The hash is in little-endian, so we check the last 4 bytes. | |
311 | if(check == 0) // \x00\x00\x00\x00 | |
312 | { | |
313 | byteswap(block_hash2, 32); | |
314 | char *blockHash = bin2hex(block_hash2, 32); | |
315 | printf("\nBlock found!\nHash: %s\nNonce: %u\nUnix time: %u", blockHash, startNonce, unixtime); | |
316 | free(blockHash); | |
317 | break; | |
318 | } | |
319 | ||
320 | startNonce++; | |
321 | counter+=1; | |
322 | if(time(NULL)-start >= 1) | |
323 | { | |
324 | printf("\r%d Hashes/s, Nonce %u\r", counter, startNonce); | |
325 | counter = 0; | |
326 | start = time(NULL); | |
327 | } | |
328 | *pNonce = startNonce; | |
329 | if(startNonce > 4294967294LL) | |
330 | { | |
331 | //printf("\nBlock found!\nHash: %s\nNonce: %u\nUnix time: %u", blockHash, startNonce, unixtime); | |
332 | unixtime++; | |
333 | *pUnixtime = unixtime; | |
334 | startNonce = 0; | |
335 | } | |
336 | } | |
337 | } | |
338 | ||
339 | ||
340 | // Lots of cleanup | |
341 | free(merkleHash); | |
342 | free(merkleHashSwapped); | |
343 | free(txScriptSig); | |
344 | free(pubScriptSig); | |
345 | free(transaction->serializedData); | |
346 | free(transaction->scriptSig); | |
347 | free(transaction->pubkeyScript); | |
348 | free(transaction); | |
349 | ||
350 | return 0; | |
351 | } |