mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-11-02 21:47:18 +00:00
Receive to and send from native segwit addresses
- Hierarchical-deterministic derivation of native segwit addresses. - Receive payments to native segwit addresses. - Spend and sign payments from native segwit addresses. - Watch-only wallets with native segwit addresses (zpub/vpub). - WalletAppKit, Wallet-tool and Wallet-template are taught to deal with segwit-enabled wallets. Be aware this adds a new field in the wallet protobuf: output_script_type in Key, which keeps track of the script type of DeterministicKeyChains. Protobufs will be migrated; old DeterministicKeyChains are assumed to be of type P2PKH. Includes some code by Fabrice Drouin.
This commit is contained in:
@@ -24,6 +24,8 @@ import org.bitcoinj.params.TestNet3Params;
|
||||
import org.bitcoinj.protocols.payments.PaymentProtocol;
|
||||
import org.bitcoinj.protocols.payments.PaymentProtocolException;
|
||||
import org.bitcoinj.protocols.payments.PaymentSession;
|
||||
import org.bitcoinj.script.Script;
|
||||
import org.bitcoinj.script.Script.ScriptType;
|
||||
import org.bitcoinj.script.ScriptBuilder;
|
||||
import org.bitcoinj.script.ScriptException;
|
||||
import org.bitcoinj.script.ScriptPattern;
|
||||
@@ -65,6 +67,7 @@ import org.bitcoinj.core.NetworkParameters;
|
||||
import org.bitcoinj.core.Peer;
|
||||
import org.bitcoinj.core.PeerAddress;
|
||||
import org.bitcoinj.core.PeerGroup;
|
||||
import org.bitcoinj.core.SegwitAddress;
|
||||
import org.bitcoinj.core.Sha256Hash;
|
||||
import org.bitcoinj.core.StoredBlock;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
@@ -121,6 +124,7 @@ public class WalletTool {
|
||||
private static OptionSpec<Date> dateFlag;
|
||||
private static OptionSpec<Long> unixtimeFlag;
|
||||
private static OptionSpec<String> seedFlag, watchFlag;
|
||||
private static OptionSpec<Script.ScriptType> outputScriptTypeFlag;
|
||||
private static OptionSpec<String> xpubkeysFlag;
|
||||
|
||||
private static NetworkParameters params;
|
||||
@@ -233,6 +237,7 @@ public class WalletTool {
|
||||
OptionSpec<String> walletFileName = parser.accepts("wallet").withRequiredArg().defaultsTo("wallet");
|
||||
seedFlag = parser.accepts("seed").withRequiredArg();
|
||||
watchFlag = parser.accepts("watchkey").withRequiredArg();
|
||||
outputScriptTypeFlag = parser.accepts("output-script-type").withRequiredArg().ofType(Script.ScriptType.class);
|
||||
OptionSpec<NetworkEnum> netFlag = parser.accepts("net").withRequiredArg().ofType(NetworkEnum.class).defaultsTo(NetworkEnum.MAIN);
|
||||
dateFlag = parser.accepts("date").withRequiredArg().ofType(Date.class)
|
||||
.withValuesConvertedBy(DateConverter.datePattern("yyyy/MM/dd"));
|
||||
@@ -1313,6 +1318,7 @@ public class WalletTool {
|
||||
return;
|
||||
}
|
||||
long creationTimeSecs = getCreationTimeSeconds();
|
||||
ScriptType outputScriptType = options.valueOf(outputScriptTypeFlag);
|
||||
if (creationTimeSecs == 0)
|
||||
creationTimeSecs = MnemonicCode.BIP39_STANDARDISATION_TIME_SECS;
|
||||
if (options.has(seedFlag)) {
|
||||
@@ -1337,11 +1343,11 @@ public class WalletTool {
|
||||
// not reached - all subclasses handled above
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
wallet = Wallet.fromSeed(params, seed);
|
||||
wallet = Wallet.fromSeed(params, seed, outputScriptType);
|
||||
} else if (options.has(watchFlag)) {
|
||||
wallet = Wallet.fromWatchingKeyB58(params, options.valueOf(watchFlag), creationTimeSecs);
|
||||
} else {
|
||||
wallet = new Wallet(params);
|
||||
wallet = Wallet.createDeterministic(params, outputScriptType);
|
||||
}
|
||||
if (password != null)
|
||||
wallet.encrypt(password);
|
||||
@@ -1448,7 +1454,10 @@ public class WalletTool {
|
||||
if (!key.isCompressed())
|
||||
System.out.println("WARNING: Importing an uncompressed key");
|
||||
wallet.importKey(key);
|
||||
System.out.println(LegacyAddress.fromKey(params, key) + " " + key);
|
||||
System.out.print("Addresses: " + LegacyAddress.fromKey(params, key));
|
||||
if (key.isCompressed())
|
||||
System.out.print("," + SegwitAddress.fromKey(params, key));
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1489,7 +1498,7 @@ public class WalletTool {
|
||||
key = wallet.findKeyFromPubKey(HEX.decode(pubKey));
|
||||
} else {
|
||||
try {
|
||||
Address address = LegacyAddress.fromBase58(wallet.getParams(), addr);
|
||||
Address address = Address.fromString(wallet.getParams(), addr);
|
||||
key = wallet.findKeyFromAddress(address);
|
||||
} catch (AddressFormatException e) {
|
||||
System.err.println(addr + " does not parse as a Bitcoin address of the right network parameters.");
|
||||
@@ -1508,8 +1517,8 @@ public class WalletTool {
|
||||
}
|
||||
|
||||
private static void currentReceiveAddr() {
|
||||
ECKey key = wallet.currentReceiveKey();
|
||||
System.out.println(LegacyAddress.fromKey(params, key) + " " + key);
|
||||
Address address = wallet.currentReceiveAddress();
|
||||
System.out.println(address);
|
||||
}
|
||||
|
||||
private static void dumpWallet() throws BlockStoreException {
|
||||
|
||||
@@ -12,7 +12,8 @@ Usage: wallet-tool --flags action-name
|
||||
Will complain and require --force if the wallet already exists.
|
||||
If --seed is present, it should specify either a mnemonic code or hex/base58 raw seed bytes.
|
||||
If --watchkey is present, it creates a watching wallet using the specified base58 xpub.
|
||||
If --seed or --watchkey is combined with either --date or --unixtime, use that as a birthdate for
|
||||
If --seed or --watchkey is combined with either --date or --unixtime, use that as a birthdate for.
|
||||
If --output-script-type, use that for deriving addresses.
|
||||
the wallet. See the set-creation-time action for the meaning of these flags.
|
||||
marry Makes the wallet married with other parties, requiring multisig to spend funds.
|
||||
External public keys for other signing parties must be specified with --xpubkeys (comma separated).
|
||||
|
||||
Reference in New Issue
Block a user