bool gather_challenges(unsigned_transaction& utx, Watcher& watcher) { utx.challenges.resize(utx.tx.inputs.size()); for (size_t i = 0; i < utx.tx.inputs.size(); ++i) { bc::input_point& point = utx.tx.inputs[i].previous_output; if (!watcher.db().has_tx(point.hash)) return false; bc::transaction_type tx = watcher.find_tx(point.hash); utx.challenges[i] = tx.outputs[point.index].script; } return true; }
Status watcherBridgeRawTx(Wallet &self, const char *szTxID, DataChunk &result) { Watcher *watcher = nullptr; ABC_CHECK(watcherFind(watcher, self)); bc::hash_digest txid; if (!bc::decode_hash(txid, szTxID)) return ABC_ERROR(ABC_CC_ParseError, "Bad txid"); auto tx = watcher->find_tx(txid); result.resize(satoshi_raw_size(tx)); bc::satoshi_save(tx, result.begin()); return Status(); }
Status signTx(bc::transaction_type &result, Watcher &watcher, const KeyTable &keys) { for (size_t i = 0; i < result.inputs.size(); ++i) { // Find the utxo this input refers to: bc::input_point& point = result.inputs[i].previous_output; bc::transaction_type tx = watcher.find_tx(point.hash); // Find the address for that utxo: bc::payment_address pa; bc::script_type& script = tx.outputs[point.index].script; bc::extract(pa, script); if (payment_address::invalid_version == pa.version()) return ABC_ERROR(ABC_CC_Error, "Invalid address"); // Find the elliptic curve key for this input: auto key = keys.find(pa.encoded()); if (key == keys.end()) return ABC_ERROR(ABC_CC_Error, "Missing signing key"); bc::ec_secret secret = libwallet::wif_to_secret(key->second); bc::ec_point pubkey = bc::secret_to_public_key(secret, libwallet::is_wif_compressed(key->second)); // Gererate the previous output's signature: // TODO: We already have this; process it and use it script_type sig_script = outputScriptForPubkey(pa.hash()); // Generate the signature for this input: hash_digest sig_hash = script_type::generate_signature_hash(result, i, sig_script, 1); if (sig_hash == null_hash) return ABC_ERROR(ABC_CC_Error, "Unable to sign"); data_chunk signature = sign(secret, sig_hash, create_nonce(secret, sig_hash)); signature.push_back(0x01); // Create out scriptsig: script_type scriptsig; scriptsig.push_operation(create_data_operation(signature)); scriptsig.push_operation(create_data_operation(pubkey)); result.inputs[i].script = scriptsig; } return Status(); }