bool bp_txout_match(const struct bp_txout *txout, const struct bp_keyset *ks) { if (!txout || !txout->scriptPubKey || !ks) return false; bool rc = false; struct bscript_addr addrs; if (!bsp_addr_parse(&addrs, txout->scriptPubKey->str, txout->scriptPubKey->len)) return false; struct const_buffer *buf; clist *tmp = addrs.pub; while (tmp) { buf = tmp->data; tmp = tmp->next; if (bpks_lookup(ks, buf->p, buf->len, false)) { rc = true; goto out; } } tmp = addrs.pubhash; while (tmp) { buf = tmp->data; tmp = tmp->next; if (bpks_lookup(ks, buf->p, buf->len, true)) { rc = true; goto out; } } out: clist_free_ext(addrs.pub, buffer_free); clist_free_ext(addrs.pubhash, buffer_free); return rc; }
bool bp_script_sign(struct bp_keystore *ks, const cstring *fromPubKey, const struct bp_tx *txTo, unsigned int nIn, int nHashType) { if (!txTo || !txTo->vin || nIn >= txTo->vin->len) return false; struct bp_txin *txin = parr_idx(txTo->vin, nIn); /* get signature hash */ bu256_t hash; bp_tx_sighash(&hash, fromPubKey, txTo, nIn, nHashType); /* match fromPubKey against templates, to find what pubkey[hashes] * are required for signing */ struct bscript_addr addrs; if (!bsp_addr_parse(&addrs, fromPubKey->str, fromPubKey->len)) return false; cstring *scriptSig = cstr_new_sz(64); bool rc = false; bu160_t key_id; struct buffer *kbuf; /* sign, based on script template matched above */ switch (addrs.txtype) { case TX_PUBKEY: kbuf = addrs.pub->data; bu_Hash160((unsigned char *)&key_id, kbuf->p, kbuf->len); if (!sign1(&key_id, ks, &hash, nHashType, scriptSig)) goto out; break; case TX_PUBKEYHASH: kbuf = addrs.pubhash->data; memcpy(&key_id, kbuf->p, kbuf->len); if (!sign1(&key_id, ks, &hash, nHashType, scriptSig)) goto out; if (!bkeys_pubkey_append(ks, &key_id, scriptSig)) goto out; break; case TX_SCRIPTHASH: /* TODO; not supported yet */ case TX_MULTISIG: goto out; case TX_NONSTANDARD: /* unknown script type, cannot sign */ goto out; } if (txin->scriptSig) cstr_free(txin->scriptSig, true); txin->scriptSig = scriptSig; scriptSig = NULL; rc = true; out: if (scriptSig) cstr_free(scriptSig, true); bsp_addr_free(&addrs); return rc; }