bool bp_verify_sig(const struct bp_utxo *txFrom, const struct bp_tx *txTo, unsigned int nIn, unsigned int flags, int nHashType) { if (!txFrom || !txFrom->vout || !txFrom->vout->len || !txTo || !txTo->vin || !txTo->vin->len || (txTo->vin->len <= nIn)) return false; struct bp_txin *txin = parr_idx(txTo->vin, nIn); if (txin->prevout.n >= txFrom->vout->len) return false; struct bp_txout *txout = parr_idx(txFrom->vout, txin->prevout.n); if (!txout) return false; return bp_script_verify(txin->scriptSig, txout->scriptPubKey, txTo, nIn, flags, nHashType); }
static void test_script(bool is_valid,cstring *scriptSig, cstring *scriptPubKey, unsigned int idx, const char *scriptSigEnc, const char *scriptPubKeyEnc) { struct bp_tx tx; static const unsigned int test_flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC; bp_tx_init(&tx); bool rc; rc = bp_script_verify(scriptSig, scriptPubKey, &tx, 0, test_flags, SIGHASH_NONE); if (rc != is_valid) { fprintf(stderr, "script: %sis_valid test %u failed\n" "script: [\"%s\", \"%s\"]\n", is_valid ? "" : "!", idx, scriptSigEnc, scriptPubKeyEnc); assert(rc == is_valid); } bp_tx_free(&tx); }
static void test_tx_valid(bool is_valid, struct bp_hashtab *input_map, cstring *tx_ser, bool enforce_p2sh) { struct bp_tx tx; bp_tx_init(&tx); struct const_buffer buf = { tx_ser->str, tx_ser->len }; assert(deser_bp_tx(&tx, &buf) == true); if (is_valid) { /* checking for valid tx; !bp_tx_valid implies test fail */ assert(bp_tx_valid(&tx) == true); } else { /* checking for invalid tx; bp_tx_valid==false implies test * succeeded; no more work to do; bp_tx_valid==true * implies the test will detect the invalid condition * further down in the code */ if (bp_tx_valid(&tx) == false) goto out; } bp_tx_calc_sha256(&tx); unsigned int i; for (i = 0; i < tx.vin->len; i++) { struct bp_txin *txin; txin = parr_idx(tx.vin, i); assert(txin != NULL); cstring *scriptPubKey = bp_hashtab_get(input_map, &txin->prevout); if (scriptPubKey == NULL) { if (!is_valid) { /* if testing tx_invalid.json, missing input * is invalid, and therefore correct */ continue; } char tx_hexstr[BU256_STRSZ], hexstr[BU256_STRSZ]; bu256_hex(tx_hexstr, &tx.sha256); bu256_hex(hexstr, &txin->prevout.hash); dump_comments(); fprintf(stderr, "tx-valid: TX %s\n" "tx-valid: prevout (%s, %u) not found\n", tx_hexstr, hexstr, txin->prevout.n); assert(scriptPubKey != NULL); } bool rc = bp_script_verify(txin->scriptSig, scriptPubKey, &tx, i, enforce_p2sh ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, 0); if (rc != is_valid) { char tx_hexstr[BU256_STRSZ]; bu256_hex(tx_hexstr, &tx.sha256); dump_comments(); fprintf(stderr, "tx-valid: TX %s\n" "tx-valid: txin %u script verification failed\n", tx_hexstr, i); assert(rc == is_valid); } } out: bp_tx_free(&tx); }