Пример #1
0
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;
}
Пример #2
0
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;
}