mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2025-03-13 11:36:15 +01:00
Merge 3a2a4b655f
into 93519cc65a
This commit is contained in:
commit
13eac0c6d5
2 changed files with 43 additions and 3 deletions
|
@ -34,6 +34,7 @@ import org.bitcoinj.wallet.Wallet;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.nio.BufferOverflowException;
|
||||
import java.nio.BufferUnderflowException;
|
||||
|
@ -41,6 +42,7 @@ import java.nio.ByteBuffer;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.bitcoinj.base.internal.Preconditions.checkArgument;
|
||||
import static org.bitcoinj.base.internal.Preconditions.checkState;
|
||||
|
@ -160,6 +162,25 @@ public class TransactionOutput {
|
|||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can this output be converted to an address (for a given network.)
|
||||
* @return true if this output has an address, false otherwise
|
||||
*/
|
||||
public boolean hasAddress() {
|
||||
Script script = getScriptPubKey();
|
||||
return ScriptPattern.isP2PKH(script) || ScriptPattern.isP2WPKH(script) || ScriptPattern.isP2TR(script) || ScriptPattern.isP2SH(script);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the address for this output.
|
||||
* @param network the network this output exists on
|
||||
* @return The address for this output or empty if an address can't be extracted
|
||||
*/
|
||||
public Optional<Address> getAddress(@Nonnull Network network) {
|
||||
Objects.requireNonNull(network);
|
||||
return Optional.ofNullable(hasAddress() ? getScriptPubKey().getToAddress(network) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this output. This is the amount of currency that the destination address
|
||||
* receives.
|
||||
|
@ -357,11 +378,10 @@ public class TransactionOutput {
|
|||
buf.append(Coin.valueOf(value).toFriendlyString());
|
||||
try {
|
||||
Script script = getScriptPubKey();
|
||||
if (ScriptPattern.isP2PKH(script) || ScriptPattern.isP2WPKH(script) || ScriptPattern.isP2TR(script)
|
||||
|| ScriptPattern.isP2SH(script)) {
|
||||
if (hasAddress()) {
|
||||
buf.append(" to ").append(script.getScriptType().name());
|
||||
if (network != null)
|
||||
buf.append(" ").append(script.getToAddress(network));
|
||||
buf.append(" ").append(getAddress(network).get());
|
||||
} else if (ScriptPattern.isP2PK(script)) {
|
||||
buf.append(" to pubkey ").append(ByteUtils.formatHex(ScriptPattern.extractKeyFromP2PK(script)));
|
||||
} else if (ScriptPattern.isSentToMultisig(script)) {
|
||||
|
|
|
@ -107,6 +107,7 @@ public class WalletTool implements Callable<Integer> {
|
|||
" dump Loads and prints the given wallet in textual form to stdout. Private keys and seed are only printed if --dump-privkeys is specified. If the wallet is encrypted, also specify the --password option to dump the private keys and seed.%n" +
|
||||
" If --dump-lookahead is present, also show pregenerated but not yet issued keys.%n" +
|
||||
" raw-dump Prints the wallet as a raw protobuf with no parsing or sanity checking applied.%n" +
|
||||
" listunspent Prints unspent outputs in a simple format%n" +
|
||||
" create Makes a new wallet in the file specified by --wallet. Will complain and require --force if the wallet already exists.%n" +
|
||||
" If --seed is present, it should specify either a mnemonic code or hex/base58 raw seed bytes.%n" +
|
||||
" If --watchkey is present, it creates a watching wallet using the specified base58 xpub.%n" +
|
||||
|
@ -291,6 +292,7 @@ public class WalletTool implements Callable<Integer> {
|
|||
public enum ActionEnum {
|
||||
DUMP,
|
||||
RAW_DUMP,
|
||||
LISTUNSPENT,
|
||||
CREATE,
|
||||
ADD_KEY,
|
||||
ADD_ADDR,
|
||||
|
@ -391,6 +393,7 @@ public class WalletTool implements Callable<Integer> {
|
|||
// What should we do?
|
||||
switch (action) {
|
||||
case DUMP: dumpWallet(); break;
|
||||
case LISTUNSPENT: listUnspent(); break;
|
||||
case ADD_KEY: addKey(); break;
|
||||
case ADD_ADDR: addAddr(); break;
|
||||
case DELETE_KEY: deleteKey(); break;
|
||||
|
@ -1100,6 +1103,23 @@ public class WalletTool implements Callable<Integer> {
|
|||
}
|
||||
}
|
||||
|
||||
private void listUnspent() throws BlockStoreException {
|
||||
// Setup to get the chain height so we can estimate lock times, but don't wipe the transactions if it's not
|
||||
// there just for the listUnspent case.
|
||||
if (chainFile.exists())
|
||||
setup();
|
||||
|
||||
List<TransactionOutput> unspent = wallet.getUnspents();
|
||||
Coin total = unspent.stream()
|
||||
.map(TransactionOutput::getValue)
|
||||
.reduce(Coin.ZERO, Coin::add);
|
||||
unspent.forEach(output -> {
|
||||
String addressInfo = output.getAddress(net).map(Object::toString).orElse("address unavailable");
|
||||
System.out.printf("%s: %s\n", addressInfo , output.getValue().toPlainString());
|
||||
});
|
||||
System.out.printf("\nTotal: %s\n", total.toPlainString());
|
||||
}
|
||||
|
||||
private void printWallet(@Nullable AesKey aesKey) {
|
||||
System.out.println(wallet.toString(dumpLookAhead, dumpPrivKeys, aesKey, true, true, chain));
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue