static void hash_for_segwit(struct sha256_ctx *ctx, const struct bitcoin_tx *tx, unsigned int input_num, const u8 *witness_script) { struct sha256_double h; /* BIP143: * * Double SHA256 of the serialization of: * 1. nVersion of the transaction (4-byte little endian) */ add_le32(tx->version, add_sha, ctx); /* 2. hashPrevouts (32-byte hash) */ hash_prevouts(&h, tx); add_sha(&h, sizeof(h), ctx); /* 3. hashSequence (32-byte hash) */ hash_sequence(&h, tx); add_sha(&h, sizeof(h), ctx); /* 4. outpoint (32-byte hash + 4-byte little endian) */ add_sha(&tx->input[input_num].txid, sizeof(tx->input[input_num].txid), ctx); add_le32(tx->input[input_num].index, add_sha, ctx); /* 5. scriptCode of the input (varInt for the length + script) */ add_varint_blob(witness_script, tal_count(witness_script), add_sha, ctx); /* 6. value of the output spent by this input (8-byte little end) */ add_le64(*tx->input[input_num].amount, add_sha, ctx); /* 7. nSequence of the input (4-byte little endian) */ add_le32(tx->input[input_num].sequence_number, add_sha, ctx); /* 8. hashOutputs (32-byte hash) */ hash_outputs(&h, tx); add_sha(&h, sizeof(h), ctx); /* 9. nLocktime of the transaction (4-byte little endian) */ add_le32(tx->lock_time, add_sha, ctx); }
static void hash_prevouts(struct sha256_double *h, const struct bitcoin_tx *tx) { struct sha256_ctx ctx; size_t i; /* BIP143: If the ANYONECANPAY flag is not set, hashPrevouts is the * double SHA256 of the serialization of all input * outpoints */ sha256_init(&ctx); for (i = 0; i < tx->input_count; i++) { add_sha(&tx->input[i].txid, sizeof(tx->input[i].txid), &ctx); add_le32(tx->input[i].index, add_sha, &ctx); } sha256_double_done(&ctx, h); }
int main() { char buf[BUFSIZ]; int state; char digest[40], *dp; char *b_end = 0; int nbytes; state = NEW_UDIG; while ((nbytes = _read(buf, sizeof buf)) > 0) { char *b; b = buf; b_end = buf + nbytes; while (b < b_end) { char c; c = *b++; switch (state) { /* * New sha udig always starts with character 's' */ case NEW_UDIG: if (c != 's') exit(1); state = SCAN_ALGORITHM_h; break; /* * Scan character 'h'. */ case SCAN_ALGORITHM_h: if (c != 'h') exit(1); state = SCAN_ALGORITHM_a; break; /* * Scan character 'a'. */ case SCAN_ALGORITHM_a: if (c != 'a') exit(1); state = SCAN_ALGORITHM_colon; break; /* * Scan a colon character. */ case SCAN_ALGORITHM_colon: if (c != ':') exit(1); state = SCAN_DIGEST; dp = digest; break; /* * Scan up to 40 hex characters. */ case SCAN_DIGEST: if (!IS_HEX(c)) exit(1); *dp++ = c; if (dp - digest == 40) state = SCAN_NEW_LINE; break; case SCAN_NEW_LINE: if (c != '\n') exit(1); add_sha(digest); state = NEW_UDIG; break; } } } if (state != NEW_UDIG) exit(1); exit(b_end ? 0 : 2); }