-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsia_parser.c
More file actions
112 lines (90 loc) · 3.22 KB
/
Copy pathsia_parser.c
File metadata and controls
112 lines (90 loc) · 3.22 KB
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
#include "sia_parser.h"
uint64_t read_le64(const uint8_t* data) {
uint64_t result = 0;
for (int i = 0; i < 8; i++) {
result |= ((uint64_t)data[i]) << (i * 8);
}
return result;
}
void write_le64(uint8_t* buf, uint64_t value) {
for (int i = 0; i < 8; i++) {
buf[i] = (value >> (i * 8)) & 0xFF;
}
}
void print_full_address(const uint8_t address_hash[32]) {
// Calculate checksum
uint8_t checksum[32];
blake2b(address_hash, 32, checksum, 32);
// Print full address: 32-byte hash + 6-byte checksum
for (int i = 0; i < 32; i++) {
printf("%02x", address_hash[i]);
}
for (int i = 0; i < 6; i++) {
printf("%02x", checksum[i]);
}
}
double convert_lohi_to_sc(uint64_t lo, uint64_t hi) {
// Converting SC to hastings and is approximate for display purposes
if (hi == 0) {
return (double)lo / 1e24;
} else {
// For values with hi != 0, this is a rough approximation
double hi_part = (double)hi * (double)(1ULL << 32) * (double)(1ULL << 32);
return (hi_part + (double)lo) / 1e24;
}
}
int parse_transaction_blob(const uint8_t* blob, size_t len, ParsedTxn* txn) {
size_t offset = 0;
// Parse input count
if (len < offset + 8) return -1;
txn->input_count = read_le64(blob + offset);
offset += 8;
printf("Parsing transaction with %llu inputs\n", txn->input_count);
if (txn->input_count > MAX_INPUTS) {
printf("Error: Too many inputs (%llu > %d)\n", txn->input_count, MAX_INPUTS);
return -1;
}
// Parse parent IDs
for (int i = 0; i < txn->input_count; i++) {
if (len < offset + 32) return -1;
memcpy(txn->parent_ids[i], blob + offset, 32);
offset += 32;
printf("Input %d parent ID: ", i);
for (int j = 0; j < 32; j++) {
printf("%02x", txn->parent_ids[i][j]);
}
printf("\n");
}
// Parse output count
if (len < offset + 8) return -1;
txn->output_count = read_le64(blob + offset);
offset += 8;
printf("Transaction has %llu outputs\n", txn->output_count);
if (txn->output_count > MAX_OUTPUTS) {
printf("Error: Too many outputs (%llu > %d)\n", txn->output_count, MAX_OUTPUTS);
return -1;
}
// Parse outputs
for (int i = 0; i < txn->output_count; i++) {
if (len < offset + 48) return -1; // 32 + 8 + 8
memcpy(txn->outputs[i].address_hash, blob + offset, 32);
offset += 32;
txn->outputs[i].value_lo = read_le64(blob + offset);
offset += 8;
txn->outputs[i].value_hi = read_le64(blob + offset);
offset += 8;
printf("Output %d:\n", i);
printf(" To address: ");
print_full_address(txn->outputs[i].address_hash);
printf("\n");
printf(" Amount: %.6f SC\n", convert_lohi_to_sc(txn->outputs[i].value_lo, txn->outputs[i].value_hi));
}
// Parse fee
if (len < offset + 16) return -1;
txn->fee_lo = read_le64(blob + offset);
offset += 8;
txn->fee_hi = read_le64(blob + offset);
offset += 8;
printf("Miner fee: %.6f SC\n", convert_lohi_to_sc(txn->fee_lo, txn->fee_hi));
return 0;
}