本文整理汇总了Java中org.bitcoinj.wallet.SendRequest.forTx方法的典型用法代码示例。如果您正苦于以下问题:Java SendRequest.forTx方法的具体用法?Java SendRequest.forTx怎么用?Java SendRequest.forTx使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类org.bitcoinj.wallet.SendRequest
的用法示例。
在下文中一共展示了SendRequest.forTx方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Java代码示例。
示例1: testMultiSigOutputToString
import org.bitcoinj.wallet.SendRequest; //导入方法依赖的package包/类
@Test
public void testMultiSigOutputToString() throws Exception {
sendMoneyToWallet(AbstractBlockChain.NewBlockType.BEST_CHAIN, Coin.COIN);
ECKey myKey = new ECKey();
this.wallet.importKey(myKey);
// Simulate another signatory
ECKey otherKey = new ECKey();
// Create multi-sig transaction
Transaction multiSigTransaction = new Transaction(PARAMS);
ImmutableList<ECKey> keys = ImmutableList.of(myKey, otherKey);
Script scriptPubKey = ScriptBuilder.createMultiSigOutputScript(2, keys);
multiSigTransaction.addOutput(Coin.COIN, scriptPubKey);
SendRequest req = SendRequest.forTx(multiSigTransaction);
this.wallet.completeTx(req);
TransactionOutput multiSigTransactionOutput = multiSigTransaction.getOutput(0);
assertThat(multiSigTransactionOutput.toString(), CoreMatchers.containsString("CHECKMULTISIG"));
}
示例2: _generateCoupons
import org.bitcoinj.wallet.SendRequest; //导入方法依赖的package包/类
private ArrayList<ECKey> _generateCoupons(int number, Coin value) throws InsufficientMoneyException {
SendRequest sr;
Transaction tx = new Transaction(params);
ArrayList<ECKey> coupons = new ArrayList<>();
for (int i = 0; i < number; i++) {
ECKey ek = couponWallet.freshReceiveKey();
coupons.add(ek);
tx.addOutput(value, ek.toAddress(params));
System.out.printf("Address / Key: %s / %s\n", ek.toAddress(params), ek.getPrivateKeyAsWiF(params));
}
sr = SendRequest.forTx(tx);
sr.feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
feedWallet.completeTx(sr);
try {
feedWallet.commitTx(sr.tx);
peerGroup.broadcastTransaction(sr.tx).broadcast().get();
} catch (Exception e) {
e.printStackTrace();
}
return coupons;
}
示例3: getPreparedSendTx
import org.bitcoinj.wallet.SendRequest; //导入方法依赖的package包/类
public Transaction getPreparedSendTx(String receiverAddress,
Coin receiverAmount) throws AddressFormatException,
InsufficientMoneyException, WalletException, TransactionVerificationException {
Transaction tx = new Transaction(params);
checkArgument(Restrictions.isAboveDust(receiverAmount),
"The amount is too low (dust limit).");
tx.addOutput(receiverAmount, Address.fromBase58(params, receiverAddress));
SendRequest sendRequest = SendRequest.forTx(tx);
sendRequest.fee = Coin.ZERO;
sendRequest.feePerKb = Coin.ZERO;
sendRequest.ensureMinRequiredFee = false;
sendRequest.aesKey = aesKey;
sendRequest.shuffleOutputs = false;
sendRequest.signInputs = false;
sendRequest.ensureMinRequiredFee = false;
sendRequest.changeAddress = getUnusedAddress();
wallet.completeTx(sendRequest);
checkWalletConsistency(wallet);
verifyTransaction(tx);
// printTx("prepareSendTx", tx);
return tx;
}
示例4: makeUnsignedChannelContract
import org.bitcoinj.wallet.SendRequest; //导入方法依赖的package包/类
protected synchronized SendRequest makeUnsignedChannelContract(Coin valueToMe) {
Transaction tx = new Transaction(wallet.getParams());
if (!getTotalValue().subtract(valueToMe).equals(Coin.ZERO)) {
tx.addOutput(getTotalValue().subtract(valueToMe), getClientKey().toAddress(wallet.getParams()));
}
tx.addInput(contract.getOutput(0));
return SendRequest.forTx(tx);
}
示例5: doRaiseFee
import org.bitcoinj.wallet.SendRequest; //导入方法依赖的package包/类
private void doRaiseFee(final KeyParameter encryptionKey) {
// construct child-pays-for-parent
final TransactionOutput outputToSpend = checkNotNull(findSpendableOutput(wallet, transaction, feeRaise));
final Transaction transactionToSend = new Transaction(Constants.NETWORK_PARAMETERS);
transactionToSend.addInput(outputToSpend);
transactionToSend.addOutput(outputToSpend.getValue().subtract(feeRaise),
wallet.freshAddress(KeyPurpose.CHANGE));
transactionToSend.setPurpose(Transaction.Purpose.RAISE_FEE);
final SendRequest sendRequest = SendRequest.forTx(transactionToSend);
sendRequest.aesKey = encryptionKey;
try {
wallet.signTransaction(sendRequest);
log.info("raise fee: cpfp {}", transactionToSend);
wallet.commitTx(transactionToSend);
application.broadcastTransaction(transactionToSend);
state = State.DONE;
updateView();
dismiss();
} catch (final KeyCrypterException x) {
badPasswordView.setVisibility(View.VISIBLE);
state = State.INPUT;
updateView();
passwordView.requestFocus();
log.info("raise fee: bad spending password");
}
}
示例6: getSendRequest
import org.bitcoinj.wallet.SendRequest; //导入方法依赖的package包/类
private SendRequest getSendRequest(String fromAddress,
String toAddress,
Coin amount,
Coin fee,
@Nullable KeyParameter aesKey,
AddressEntry.Context context) throws AddressFormatException,
AddressEntryException {
Transaction tx = new Transaction(params);
Preconditions.checkArgument(Restrictions.isAboveDust(amount, fee),
"The amount is too low (dust limit).");
tx.addOutput(amount.subtract(fee), Address.fromBase58(params, toAddress));
SendRequest sendRequest = SendRequest.forTx(tx);
sendRequest.fee = fee;
sendRequest.feePerKb = Coin.ZERO;
sendRequest.ensureMinRequiredFee = false;
sendRequest.aesKey = aesKey;
sendRequest.shuffleOutputs = false;
Optional<AddressEntry> addressEntry = findAddressEntry(fromAddress, context);
if (!addressEntry.isPresent())
throw new AddressEntryException("WithdrawFromAddress is not found in our wallet.");
checkNotNull(addressEntry.get(), "addressEntry.get() must not be null");
checkNotNull(addressEntry.get().getAddress(), "addressEntry.get().getAddress() must not be null");
sendRequest.coinSelector = new BtcCoinSelector(addressEntry.get().getAddress());
sendRequest.changeAddress = addressEntry.get().getAddress();
return sendRequest;
}
示例7: estimateBtcTradingFeeTxSize
import org.bitcoinj.wallet.SendRequest; //导入方法依赖的package包/类
public Transaction estimateBtcTradingFeeTxSize(Address fundingAddress,
Address reservedForTradeAddress,
Address changeAddress,
Coin reservedFundsForOffer,
boolean useSavingsWallet,
Coin tradingFee,
Coin txFee,
String feeReceiverAddresses)
throws InsufficientMoneyException, AddressFormatException {
Transaction tradingFeeTx = new Transaction(params);
tradingFeeTx.addOutput(tradingFee, Address.fromBase58(params, feeReceiverAddresses));
tradingFeeTx.addOutput(reservedFundsForOffer, reservedForTradeAddress);
SendRequest sendRequest = SendRequest.forTx(tradingFeeTx);
sendRequest.shuffleOutputs = false;
sendRequest.aesKey = aesKey;
if (useSavingsWallet)
sendRequest.coinSelector = new BtcCoinSelector(walletsSetup.getAddressesByContext(AddressEntry.Context.AVAILABLE));
else
sendRequest.coinSelector = new BtcCoinSelector(fundingAddress);
sendRequest.fee = txFee;
sendRequest.feePerKb = Coin.ZERO;
sendRequest.ensureMinRequiredFee = false;
sendRequest.changeAddress = changeAddress;
checkNotNull(wallet, "Wallet must not be null");
log.info("estimateBtcTradingFeeTxSize");
wallet.completeTx(sendRequest);
return tradingFeeTx;
}
示例8: addAvailableInputsAndChangeOutputs
import org.bitcoinj.wallet.SendRequest; //导入方法依赖的package包/类
private void addAvailableInputsAndChangeOutputs(Transaction transaction, Address address, Address changeAddress, Coin txFee) throws WalletException {
SendRequest sendRequest = null;
try {
// Lets let the framework do the work to find the right inputs
sendRequest = SendRequest.forTx(transaction);
sendRequest.shuffleOutputs = false;
sendRequest.aesKey = aesKey;
// We use a fixed fee
sendRequest.fee = txFee;
sendRequest.feePerKb = Coin.ZERO;
sendRequest.ensureMinRequiredFee = false;
// we allow spending of unconfirmed tx (double spend risk is low and usability would suffer if we need to wait for 1 confirmation)
sendRequest.coinSelector = new BtcCoinSelector(address);
// We use always the same address in a trade for all transactions
sendRequest.changeAddress = changeAddress;
// With the usage of completeTx() we get all the work done with fee calculation, validation and coin selection.
// We don't commit that tx to the wallet as it will be changed later and it's not signed yet.
// So it will not change the wallet balance.
checkNotNull(wallet, "wallet must not be null");
wallet.completeTx(sendRequest);
} catch (Throwable t) {
if (sendRequest != null && sendRequest.tx != null)
log.warn("addAvailableInputsAndChangeOutputs: sendRequest.tx={}, sendRequest.tx.getOutputs()={}", sendRequest.tx, sendRequest.tx.getOutputs());
throw new WalletException(t);
}
}
示例9: broadCastTransaction
import org.bitcoinj.wallet.SendRequest; //导入方法依赖的package包/类
@Override
public String broadCastTransaction(String serializedTx) throws NodeException {
LOGGER.info("Broadcasting TX");
try {
Transaction originalTransaction = uniquidNodeConfiguration.getNetworkParameters().getDefaultSerializer()
.makeTransaction(Hex.decode(serializedTx));
SendRequest send = SendRequest.forTx(originalTransaction);
return NodeUtils.sendTransaction(uniquidNodeConfiguration.getNetworkParameters(), send);
} catch (Throwable t) {
throw new NodeException("Exception while broadcasting transaction", t);
}
}
示例10: initiate
import org.bitcoinj.wallet.SendRequest; //导入方法依赖的package包/类
@Override
public synchronized void initiate(@Nullable KeyParameter userKey, ClientChannelProperties clientChannelProperties) throws ValueOutOfRangeException, InsufficientMoneyException {
final NetworkParameters params = wallet.getParams();
Transaction template = new Transaction(params);
// There is also probably a change output, but we don't bother shuffling them as it's obvious from the
// format which one is the change. If we start obfuscating the change output better in future this may
// be worth revisiting.
Script redeemScript =
ScriptBuilder.createCLTVPaymentChannelOutput(BigInteger.valueOf(expiryTime), myKey, serverKey);
TransactionOutput transactionOutput = template.addOutput(totalValue,
ScriptBuilder.createP2SHOutputScript(redeemScript));
if (transactionOutput.isDust())
throw new ValueOutOfRangeException("totalValue too small to use");
SendRequest req = SendRequest.forTx(template);
req.coinSelector = AllowUnconfirmedCoinSelector.get();
req.shuffleOutputs = false; // TODO: Fix things so shuffling is usable.
req = clientChannelProperties.modifyContractSendRequest(req);
if (userKey != null) req.aesKey = userKey;
wallet.completeTx(req);
Coin multisigFee = req.tx.getFee();
contract = req.tx;
// Build a refund transaction that protects us in the case of a bad server that's just trying to cause havoc
// by locking up peoples money (perhaps as a precursor to a ransom attempt). We time lock it because the
// CheckLockTimeVerify opcode requires a lock time to be specified and the input to have a non-final sequence
// number (so that the lock time is not disabled).
refundTx = new Transaction(params);
// by using this sequence value, we avoid extra full replace-by-fee and relative lock time processing.
refundTx.addInput(contract.getOutput(0)).setSequenceNumber(TransactionInput.NO_SEQUENCE - 1L);
refundTx.setLockTime(expiryTime);
if (Context.get().isEnsureMinRequiredFee()) {
// Must pay min fee.
final Coin valueAfterFee = totalValue.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
if (Transaction.MIN_NONDUST_OUTPUT.compareTo(valueAfterFee) > 0)
throw new ValueOutOfRangeException("totalValue too small to use");
refundTx.addOutput(valueAfterFee, myKey.toAddress(params));
refundFees = multisigFee.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
} else {
refundTx.addOutput(totalValue, myKey.toAddress(params));
refundFees = multisigFee;
}
TransactionSignature refundSignature =
refundTx.calculateSignature(0, myKey.maybeDecrypt(userKey),
getSignedScript(), Transaction.SigHash.ALL, false);
refundTx.getInput(0).setScriptSig(ScriptBuilder.createCLTVPaymentChannelP2SHRefund(refundSignature, redeemScript));
refundTx.getConfidence().setSource(TransactionConfidence.Source.SELF);
log.info("initiated channel with contract {}", contract.getHashAsString());
stateMachine.transition(State.SAVE_STATE_IN_WALLET);
// Client should now call getIncompleteRefundTransaction() and send it to the server.
}
示例11: initiate
import org.bitcoinj.wallet.SendRequest; //导入方法依赖的package包/类
/**
* Creates the initial multisig contract and incomplete refund transaction which can be requested at the appropriate
* time using {@link PaymentChannelV1ClientState#getIncompleteRefundTransaction} and
* {@link PaymentChannelV1ClientState#getContract()}.
* By default unconfirmed coins are allowed to be used, as for micropayments the risk should be relatively low.
* @param userKey Key derived from a user password, needed for any signing when the wallet is encrypted.
* The wallet KeyCrypter is assumed.
* @param clientChannelProperties Modify the channel's configuration.
*
* @throws ValueOutOfRangeException if the value being used is too small to be accepted by the network
* @throws InsufficientMoneyException if the wallet doesn't contain enough balance to initiate
*/
@Override
public synchronized void initiate(@Nullable KeyParameter userKey, ClientChannelProperties clientChannelProperties) throws ValueOutOfRangeException, InsufficientMoneyException {
final NetworkParameters params = wallet.getParams();
Transaction template = new Transaction(params);
// We always place the client key before the server key because, if either side wants some privacy, they can
// use a fresh key for the the multisig contract and nowhere else
List<ECKey> keys = Lists.newArrayList(myKey, serverKey);
// There is also probably a change output, but we don't bother shuffling them as it's obvious from the
// format which one is the change. If we start obfuscating the change output better in future this may
// be worth revisiting.
TransactionOutput multisigOutput = template.addOutput(totalValue, ScriptBuilder.createMultiSigOutputScript(2, keys));
if (multisigOutput.isDust())
throw new ValueOutOfRangeException("totalValue too small to use");
SendRequest req = SendRequest.forTx(template);
req.coinSelector = AllowUnconfirmedCoinSelector.get();
req.shuffleOutputs = false; // TODO: Fix things so shuffling is usable.
req = clientChannelProperties.modifyContractSendRequest(req);
if (userKey != null) req.aesKey = userKey;
wallet.completeTx(req);
Coin multisigFee = req.tx.getFee();
multisigContract = req.tx;
// Build a refund transaction that protects us in the case of a bad server that's just trying to cause havoc
// by locking up peoples money (perhaps as a precursor to a ransom attempt). We time lock it so the server
// has an assurance that we cannot take back our money by claiming a refund before the channel closes - this
// relies on the fact that since Bitcoin 0.8 time locked transactions are non-final. This will need to change
// in future as it breaks the intended design of timelocking/tx replacement, but for now it simplifies this
// specific protocol somewhat.
refundTx = new Transaction(params);
// don't disable lock time. the sequence will be included in the server's signature and thus won't be changeable.
// by using this sequence value, we avoid extra full replace-by-fee and relative lock time processing.
refundTx.addInput(multisigOutput).setSequenceNumber(TransactionInput.NO_SEQUENCE - 1L);
refundTx.setLockTime(expiryTime);
if (Context.get().isEnsureMinRequiredFee()) {
// Must pay min fee.
final Coin valueAfterFee = totalValue.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
if (Transaction.MIN_NONDUST_OUTPUT.compareTo(valueAfterFee) > 0)
throw new ValueOutOfRangeException("totalValue too small to use");
refundTx.addOutput(valueAfterFee, myKey.toAddress(params));
refundFees = multisigFee.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
} else {
refundTx.addOutput(totalValue, myKey.toAddress(params));
refundFees = multisigFee;
}
refundTx.getConfidence().setSource(TransactionConfidence.Source.SELF);
log.info("initiated channel with multi-sig contract {}, refund {}", multisigContract.getHashAsString(),
refundTx.getHashAsString());
stateMachine.transition(State.INITIATED);
// Client should now call getIncompleteRefundTransaction() and send it to the server.
}
示例12: toSendRequest
import org.bitcoinj.wallet.SendRequest; //导入方法依赖的package包/类
public SendRequest toSendRequest() {
final Transaction transaction = new Transaction(Constants.NETWORK_PARAMETERS);
for (final PaymentIntent.Output output : outputs)
transaction.addOutput(output.amount, output.script);
return SendRequest.forTx(transaction);
}
示例13: createBtcTradingFeeTx
import org.bitcoinj.wallet.SendRequest; //导入方法依赖的package包/类
/**
* @param reservedForTradeAddress From where we want to spend the transaction fee. Used also as change reservedForTradeAddress.
* @param useSavingsWallet
* @param tradingFee The amount of the trading fee.
* @param feeReceiverAddresses The reservedForTradeAddress of the receiver of the trading fee (arbitrator). @return The broadcasted transaction
* @throws InsufficientMoneyException
* @throws AddressFormatException
*/
public Transaction createBtcTradingFeeTx(Address fundingAddress,
Address reservedForTradeAddress,
Address changeAddress,
Coin reservedFundsForOffer,
boolean useSavingsWallet,
Coin tradingFee,
Coin txFee,
String feeReceiverAddresses,
FutureCallback<Transaction> callback)
throws InsufficientMoneyException, AddressFormatException {
log.debug("fundingAddress " + fundingAddress.toString());
log.debug("reservedForTradeAddress " + reservedForTradeAddress.toString());
log.debug("changeAddress " + changeAddress.toString());
log.info("reservedFundsForOffer " + reservedFundsForOffer.toPlainString());
log.debug("useSavingsWallet " + useSavingsWallet);
log.info("tradingFee " + tradingFee.toPlainString());
log.info("txFee " + txFee.toPlainString());
log.debug("feeReceiverAddresses " + feeReceiverAddresses);
Transaction tradingFeeTx = new Transaction(params);
SendRequest sendRequest = null;
try {
tradingFeeTx.addOutput(tradingFee, Address.fromBase58(params, feeReceiverAddresses));
// the reserved amount we need for the trade we send to our trade reservedForTradeAddress
tradingFeeTx.addOutput(reservedFundsForOffer, reservedForTradeAddress);
// we allow spending of unconfirmed tx (double spend risk is low and usability would suffer if we need to
// wait for 1 confirmation)
// In case of double spend we will detect later in the trade process and use a ban score to penalize bad behaviour (not impl. yet)
sendRequest = SendRequest.forTx(tradingFeeTx);
sendRequest.shuffleOutputs = false;
sendRequest.aesKey = aesKey;
if (useSavingsWallet)
sendRequest.coinSelector = new BtcCoinSelector(walletsSetup.getAddressesByContext(AddressEntry.Context.AVAILABLE));
else
sendRequest.coinSelector = new BtcCoinSelector(fundingAddress);
// We use a fixed fee
sendRequest.fee = txFee;
sendRequest.feePerKb = Coin.ZERO;
sendRequest.ensureMinRequiredFee = false;
// Change is optional in case of overpay or use of funds from savings wallet
sendRequest.changeAddress = changeAddress;
checkNotNull(wallet, "Wallet must not be null");
wallet.completeTx(sendRequest);
WalletService.printTx("tradingFeeTx", tradingFeeTx);
broadcastTx(tradingFeeTx, callback);
return tradingFeeTx;
} catch (Throwable t) {
if (wallet != null && sendRequest != null && sendRequest.coinSelector != null)
log.warn("Balance = {}; CoinSelector = {}",
wallet.getBalance(sendRequest.coinSelector),
sendRequest.coinSelector);
log.warn("createBtcTradingFeeTx failed: tradingFeeTx={}, txOutputs={}", tradingFeeTx.toString(), tradingFeeTx.getOutputs());
throw t;
}
}
示例14: completeBsqTradingFeeTx
import org.bitcoinj.wallet.SendRequest; //导入方法依赖的package包/类
public Transaction completeBsqTradingFeeTx(Transaction preparedBsqTx,
Address fundingAddress,
Address reservedForTradeAddress,
Address changeAddress,
Coin reservedFundsForOffer,
boolean useSavingsWallet,
Coin txFee) throws
TransactionVerificationException, WalletException,
InsufficientMoneyException, AddressFormatException {
log.debug("preparedBsqTx " + preparedBsqTx.toString());
log.debug("fundingAddress " + fundingAddress.toString());
log.debug("changeAddress " + changeAddress.toString());
log.debug("reservedFundsForOffer " + reservedFundsForOffer.toPlainString());
log.debug("useSavingsWallet " + useSavingsWallet);
log.debug("txFee " + txFee.toPlainString());
// preparedBsqTx has following structure:
// inputs [1-n] BSQ inputs
// outputs [0-1] BSQ change output
// mining fee: burned BSQ fee
// We add BTC mining fee. Result tx looks like:
// inputs [1-n] BSQ inputs
// inputs [1-n] BTC inputs
// outputs [0-1] BSQ change output
// outputs [1] BTC reservedForTrade output
// outputs [0-1] BTC change output
// mining fee: BTC mining fee + burned BSQ fee
// In case of txs for burned BSQ fees we have no receiver output and it might be that there is no change outputs
// We need to guarantee that min. 1 valid output is added (OP_RETURN does not count). So we use a higher input
// for BTC to force an additional change output.
final int preparedBsqTxInputsSize = preparedBsqTx.getInputs().size();
// the reserved amount we need for the trade we send to our trade reservedForTradeAddress
preparedBsqTx.addOutput(reservedFundsForOffer, reservedForTradeAddress);
// we allow spending of unconfirmed tx (double spend risk is low and usability would suffer if we need to
// wait for 1 confirmation)
// In case of double spend we will detect later in the trade process and use a ban score to penalize bad behaviour (not impl. yet)
// WalletService.printTx("preparedBsqTx", preparedBsqTx);
SendRequest sendRequest = SendRequest.forTx(preparedBsqTx);
sendRequest.shuffleOutputs = false;
sendRequest.aesKey = aesKey;
if (useSavingsWallet)
sendRequest.coinSelector = new BtcCoinSelector(walletsSetup.getAddressesByContext(AddressEntry.Context.AVAILABLE));
else
sendRequest.coinSelector = new BtcCoinSelector(fundingAddress);
// We use a fixed fee
sendRequest.fee = txFee;
sendRequest.feePerKb = Coin.ZERO;
sendRequest.ensureMinRequiredFee = false;
sendRequest.signInputs = false;
// Change is optional in case of overpay or use of funds from savings wallet
sendRequest.changeAddress = changeAddress;
checkNotNull(wallet, "Wallet must not be null");
wallet.completeTx(sendRequest);
Transaction resultTx = sendRequest.tx;
// Sign all BTC inputs
for (int i = preparedBsqTxInputsSize; i < resultTx.getInputs().size(); i++) {
TransactionInput txIn = resultTx.getInputs().get(i);
checkArgument(txIn.getConnectedOutput() != null && txIn.getConnectedOutput().isMine(wallet),
"txIn.getConnectedOutput() is not in our wallet. That must not happen.");
WalletService.signTransactionInput(wallet, aesKey, resultTx, txIn, i);
WalletService.checkScriptSig(resultTx, txIn, i);
}
WalletService.checkWalletConsistency(wallet);
WalletService.verifyTransaction(resultTx);
WalletService.printTx(Res.getBaseCurrencyCode() + " wallet: Signed tx", resultTx);
return resultTx;
}
示例15: initiate
import org.bitcoinj.wallet.SendRequest; //导入方法依赖的package包/类
@Override
public synchronized void initiate(@Nullable KeyParameter userKey) throws ValueOutOfRangeException, InsufficientMoneyException {
final NetworkParameters params = wallet.getParams();
Transaction template = new Transaction(params);
// There is also probably a change output, but we don't bother shuffling them as it's obvious from the
// format which one is the change. If we start obfuscating the change output better in future this may
// be worth revisiting.
Script redeemScript =
ScriptBuilder.createCLTVPaymentChannelOutput(BigInteger.valueOf(expiryTime), myKey, serverKey);
TransactionOutput transactionOutput = template.addOutput(totalValue,
ScriptBuilder.createP2SHOutputScript(redeemScript));
if (transactionOutput.isDust())
throw new ValueOutOfRangeException("totalValue too small to use");
SendRequest req = SendRequest.forTx(template);
req.coinSelector = AllowUnconfirmedCoinSelector.get();
editContractSendRequest(req);
req.shuffleOutputs = false; // TODO: Fix things so shuffling is usable.
req.aesKey = userKey;
wallet.completeTx(req);
Coin multisigFee = req.tx.getFee();
contract = req.tx;
// Build a refund transaction that protects us in the case of a bad server that's just trying to cause havoc
// by locking up peoples money (perhaps as a precursor to a ransom attempt). We time lock it because the
// CheckLockTimeVerify opcode requires a lock time to be specified and the input to have a non-final sequence
// number (so that the lock time is not disabled).
refundTx = new Transaction(params);
// by using this sequence value, we avoid extra full replace-by-fee and relative lock time processing.
refundTx.addInput(contract.getOutput(0)).setSequenceNumber(TransactionInput.NO_SEQUENCE - 1L);
refundTx.setLockTime(expiryTime);
if (Context.get().isEnsureMinRequiredFee()) {
// Must pay min fee.
final Coin valueAfterFee = totalValue.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
if (Transaction.MIN_NONDUST_OUTPUT.compareTo(valueAfterFee) > 0)
throw new ValueOutOfRangeException("totalValue too small to use");
refundTx.addOutput(valueAfterFee, myKey.toAddress(params));
refundFees = multisigFee.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
} else {
refundTx.addOutput(totalValue, myKey.toAddress(params));
refundFees = multisigFee;
}
TransactionSignature refundSignature =
refundTx.calculateSignature(0, myKey.maybeDecrypt(userKey),
getSignedScript(), Transaction.SigHash.ALL, false);
refundTx.getInput(0).setScriptSig(ScriptBuilder.createCLTVPaymentChannelP2SHRefund(refundSignature, redeemScript));
refundTx.getConfidence().setSource(TransactionConfidence.Source.SELF);
log.info("initiated channel with contract {}", contract.getHashAsString());
stateMachine.transition(State.SAVE_STATE_IN_WALLET);
// Client should now call getIncompleteRefundTransaction() and send it to the server.
}