add Network enum, make addresses use the network type

This commit is contained in:
Daniel Newton 2020-09-25 19:26:23 +12:00
parent e8d8fa6126
commit 6833096c58
26 changed files with 332 additions and 238 deletions

1
.gitignore vendored
View file

@ -6,3 +6,4 @@ build
out
*.log
.DS_Store
bin/

View file

@ -1,5 +1,6 @@
package com.sparrowwallet.drongo;
import com.sparrowwallet.drongo.protocol.Network;
import com.sparrowwallet.drongo.rpc.BitcoinJSONRPCClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -15,12 +16,14 @@ import java.util.concurrent.Executors;
public class Drongo {
private static final Logger log = LoggerFactory.getLogger(Drongo.class);
private Network network;
private String nodeZmqAddress;
private BitcoinJSONRPCClient bitcoinJSONRPCClient;
private List<WatchWallet> watchWallets;
private String[] notifyRecipients;
public Drongo(String nodeZmqAddress, Map<String, String> nodeRpc, List<WatchWallet> watchWallets, String[] notifyRecipients) {
public Drongo(Network network, String nodeZmqAddress, Map<String, String> nodeRpc, List<WatchWallet> watchWallets, String[] notifyRecipients) {
this.network = network;
this.nodeZmqAddress = nodeZmqAddress;
this.bitcoinJSONRPCClient = new BitcoinJSONRPCClient(nodeRpc.get("host"), nodeRpc.get("port"), nodeRpc.get("user"), nodeRpc.get("password"));
this.watchWallets = watchWallets;
@ -67,6 +70,10 @@ public class Drongo {
}
}
public Network getNetwork() {
return network;
}
public BitcoinJSONRPCClient getBitcoinJSONRPCClient() {
return bitcoinJSONRPCClient;
}

View file

@ -8,6 +8,8 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;
import com.sparrowwallet.drongo.protocol.Network;
public class Main {
private static final Logger log = LoggerFactory.getLogger(Main.class);
@ -28,6 +30,8 @@ public class Main {
log.error("Could not load properties from provided path " + propertiesFile);
}
Network network = Network.valueOf(properties.getProperty("network", Network.BITCOIN.name()));
String nodeZmqAddress = properties.getProperty("node.zmqpubrawtx");
if(nodeZmqAddress == null) {
log.error("Property node.zmqpubrawtx not set, provide the zmqpubrawtx setting of the local node");
@ -61,15 +65,16 @@ public class Main {
System.exit(1);
}
Drongo drongo = new Drongo(nodeZmqAddress, rpcConnection, watchWallets, notifyRecipients.split(","));
Drongo drongo = new Drongo(network, nodeZmqAddress, rpcConnection, watchWallets, notifyRecipients.split(","));
drongo.start();
}
private static WatchWallet getWalletFromProperties(Properties properties, int walletNumber) {
Network network = Network.valueOf(properties.getProperty("network", Network.BITCOIN.name()));
String walletName = properties.getProperty("wallet.name." + walletNumber);
String walletDescriptor = properties.getProperty("wallet.descriptor." + walletNumber);
if(walletName != null && walletDescriptor != null) {
return new WatchWallet(walletName, walletDescriptor);
return new WatchWallet(network, walletName, walletDescriptor);
}
return null;

View file

@ -6,6 +6,7 @@ import com.sparrowwallet.drongo.crypto.DeterministicKey;
import com.sparrowwallet.drongo.crypto.ECKey;
import com.sparrowwallet.drongo.policy.Policy;
import com.sparrowwallet.drongo.policy.PolicyType;
import com.sparrowwallet.drongo.protocol.Network;
import com.sparrowwallet.drongo.protocol.ProtocolException;
import com.sparrowwallet.drongo.protocol.Script;
import com.sparrowwallet.drongo.protocol.ScriptType;
@ -30,24 +31,26 @@ public class OutputDescriptor {
private static final Pattern KEY_ORIGIN_PATTERN = Pattern.compile("\\[([A-Fa-f0-9]{8})([/\\d'hH]+)\\]");
private static final Pattern CHECKSUM_PATTERN = Pattern.compile("#([" + CHECKSUM_CHARSET + "]{8})$");
private final Network network;
private final ScriptType scriptType;
private final int multisigThreshold;
private final Map<ExtendedKey, KeyDerivation> extendedPublicKeys;
private final Map<ExtendedKey, String> mapChildrenDerivations;
public OutputDescriptor(ScriptType scriptType, ExtendedKey extendedPublicKey, KeyDerivation keyDerivation) {
this(scriptType, Collections.singletonMap(extendedPublicKey, keyDerivation));
public OutputDescriptor(Network network, ScriptType scriptType, ExtendedKey extendedPublicKey, KeyDerivation keyDerivation) {
this(network, scriptType, Collections.singletonMap(extendedPublicKey, keyDerivation));
}
public OutputDescriptor(ScriptType scriptType, Map<ExtendedKey, KeyDerivation> extendedPublicKeys) {
this(scriptType, 0, extendedPublicKeys);
public OutputDescriptor(Network network, ScriptType scriptType, Map<ExtendedKey, KeyDerivation> extendedPublicKeys) {
this(network, scriptType, 0, extendedPublicKeys);
}
public OutputDescriptor(ScriptType scriptType, int multisigThreshold, Map<ExtendedKey, KeyDerivation> extendedPublicKeys) {
this(scriptType, multisigThreshold, extendedPublicKeys, new LinkedHashMap<>());
public OutputDescriptor(Network network, ScriptType scriptType, int multisigThreshold, Map<ExtendedKey, KeyDerivation> extendedPublicKeys) {
this(network, scriptType, multisigThreshold, extendedPublicKeys, new LinkedHashMap<>());
}
public OutputDescriptor(ScriptType scriptType, int multisigThreshold, Map<ExtendedKey, KeyDerivation> extendedPublicKeys, Map<ExtendedKey, String> mapChildrenDerivations) {
public OutputDescriptor(Network network, ScriptType scriptType, int multisigThreshold, Map<ExtendedKey, KeyDerivation> extendedPublicKeys, Map<ExtendedKey, String> mapChildrenDerivations) {
this.network = network;
this.scriptType = scriptType;
this.multisigThreshold = multisigThreshold;
this.extendedPublicKeys = extendedPublicKeys;
@ -201,11 +204,11 @@ public class OutputDescriptor {
}
public Address getAddress(DeterministicKey childKey) {
return scriptType.getAddress(childKey);
return scriptType.getAddress(network, childKey);
}
private Address getAddress(Script multisigScript) {
return scriptType.getAddress(multisigScript);
return scriptType.getAddress(network, multisigScript);
}
private Script getMultisigScript(List<ChildNumber> childPath) {
@ -233,7 +236,7 @@ public class OutputDescriptor {
}
public Wallet toWallet() {
Wallet wallet = new Wallet();
Wallet wallet = new Wallet(network);
wallet.setPolicyType(isMultisig() ? PolicyType.MULTI : PolicyType.SINGLE);
wallet.setScriptType(scriptType);
@ -257,11 +260,11 @@ public class OutputDescriptor {
extendedKeyDerivationMap.put(keystore.getExtendedPublicKey(), keystore.getKeyDerivation());
}
return new OutputDescriptor(wallet.getScriptType(), wallet.getDefaultPolicy().getNumSignaturesRequired(), extendedKeyDerivationMap);
return new OutputDescriptor(wallet.getNetwork(), wallet.getScriptType(), wallet.getDefaultPolicy().getNumSignaturesRequired(), extendedKeyDerivationMap);
}
// See https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md
public static OutputDescriptor getOutputDescriptor(String descriptor) {
public static OutputDescriptor getOutputDescriptor(Network network, String descriptor) {
ScriptType scriptType = ScriptType.fromDescriptor(descriptor);
if(scriptType == null) {
ExtendedKey.Header header = ExtendedKey.Header.fromExtendedKey(descriptor);
@ -273,7 +276,7 @@ public class OutputDescriptor {
}
int threshold = getMultisigThreshold(descriptor);
return getOutputDescriptorImpl(scriptType, threshold, descriptor);
return getOutputDescriptorImpl(network, scriptType, threshold, descriptor);
}
private static int getMultisigThreshold(String descriptor) {
@ -286,7 +289,7 @@ public class OutputDescriptor {
}
}
private static OutputDescriptor getOutputDescriptorImpl(ScriptType scriptType, int multisigThreshold, String descriptor) {
private static OutputDescriptor getOutputDescriptorImpl(Network network, ScriptType scriptType, int multisigThreshold, String descriptor) {
Matcher checksumMatcher = CHECKSUM_PATTERN.matcher(descriptor);
if(checksumMatcher.find()) {
String checksum = checksumMatcher.group(1);
@ -333,7 +336,7 @@ public class OutputDescriptor {
}
}
return new OutputDescriptor(scriptType, multisigThreshold, keyDerivationMap, keyChildDerivationMap);
return new OutputDescriptor(network, scriptType, multisigThreshold, keyDerivationMap, keyChildDerivationMap);
}
private static String getChecksum(String descriptor) {

View file

@ -45,7 +45,7 @@ public class TransactionTask implements Runnable {
TransactionOutput referencedOutput = referencedTransaction.getOutputs().get((int)referencedVout);
if(referencedOutput.getScript().containsToAddress()) {
try {
Address[] inputAddresses = referencedOutput.getScript().getToAddresses();
Address[] inputAddresses = referencedOutput.getScript().getToAddresses(drongo.getNetwork());
input.getOutpoint().setAddresses(inputAddresses);
inputJoiner.add((inputAddresses.length == 1 ? inputAddresses[0] : Arrays.asList(inputAddresses)) + ":" + vin);
} catch(NonStandardScriptException e) {
@ -67,7 +67,7 @@ public class TransactionTask implements Runnable {
try {
if(output.getScript().containsToAddress()) {
try {
Address[] outputAddresses = output.getScript().getToAddresses();
Address[] outputAddresses = output.getScript().getToAddresses(drongo.getNetwork());
output.setAddresses(outputAddresses);
outputJoiner.add((outputAddresses.length == 1 ? outputAddresses[0] : Arrays.asList(outputAddresses)) + ":" + vout + " (" + output.getValue() + ")");
} catch(NonStandardScriptException e) {

View file

@ -2,6 +2,7 @@ package com.sparrowwallet.drongo;
import com.sparrowwallet.drongo.address.Address;
import com.sparrowwallet.drongo.crypto.*;
import com.sparrowwallet.drongo.protocol.Network;
import java.util.HashMap;
import java.util.List;
@ -14,9 +15,9 @@ public class WatchWallet {
private HashMap<Address,List<ChildNumber>> addresses = new HashMap<>(LOOK_AHEAD_LIMIT*2);
public WatchWallet(String name, String descriptor) {
public WatchWallet(Network network, String name, String descriptor) {
this.name = name;
this.outputDescriptor = OutputDescriptor.getOutputDescriptor(descriptor);
this.outputDescriptor = OutputDescriptor.getOutputDescriptor(network, descriptor);
}
public void initialiseAddresses() {

View file

@ -2,20 +2,26 @@ package com.sparrowwallet.drongo.address;
import com.sparrowwallet.drongo.protocol.Base58;
import com.sparrowwallet.drongo.protocol.Bech32;
import com.sparrowwallet.drongo.protocol.Network;
import com.sparrowwallet.drongo.protocol.Script;
import com.sparrowwallet.drongo.protocol.ScriptType;
import java.io.Console;
import java.util.Arrays;
import static com.sparrowwallet.drongo.address.P2WPKHAddress.HRP;
public abstract class Address {
protected final Network network;
protected final byte[] hash;
public Address(byte[] hash) {
public Address(Network network, byte[] hash) {
this.network = network;
this.hash = hash;
}
public Network getNetwork() {
return network;
}
public byte[] getHash() {
return hash;
}
@ -51,20 +57,20 @@ public abstract class Address {
return getAddress().hashCode();
}
public static Address fromString(String address) throws InvalidAddressException {
public static Address fromString(Network network, String address) throws InvalidAddressException {
Exception nested = null;
if(address != null && (address.startsWith("1") || address.startsWith("3"))) {
if(address != null && address.length() > 0 && network.legacyPrefixes.contains(String.valueOf(address.charAt(0)))) {
try {
byte[] decodedBytes = Base58.decodeChecked(address);
if(decodedBytes.length == 21) {
int version = decodedBytes[0];
int version = Byte.toUnsignedInt(decodedBytes[0]);
byte[] hash = Arrays.copyOfRange(decodedBytes, 1, 21);
if(version == 0) {
return new P2PKHAddress(hash);
if(version == network.pkhVersion) {
return new P2PKHAddress(network, hash);
}
if(version == 5) {
return new P2SHAddress(hash);
if(version == network.shVersion) {
return new P2SHAddress(network, hash);
}
}
} catch (Exception e) {
@ -72,19 +78,19 @@ public abstract class Address {
}
}
if(address != null && address.startsWith(HRP)) {
if(address != null && address.startsWith(network.hrp)) {
try {
Bech32.Bech32Data data = Bech32.decode(address);
if (data.hrp.equals(HRP)) {
if (data.hrp.equals(network.hrp)) {
int witnessVersion = data.data[0];
if (witnessVersion == 0) {
byte[] convertedProgram = Arrays.copyOfRange(data.data, 1, data.data.length);
byte[] witnessProgram = Bech32.convertBits(convertedProgram, 0, convertedProgram.length, 5, 8, false);
if (witnessProgram.length == 20) {
return new P2WPKHAddress(witnessProgram);
return new P2WPKHAddress(network, witnessProgram);
}
if (witnessProgram.length == 32) {
return new P2WSHAddress(witnessProgram);
return new P2WSHAddress(network, witnessProgram);
}
}
}

View file

@ -1,19 +1,20 @@
package com.sparrowwallet.drongo.address;
import com.sparrowwallet.drongo.Utils;
import com.sparrowwallet.drongo.protocol.Network;
import com.sparrowwallet.drongo.protocol.Script;
import com.sparrowwallet.drongo.protocol.ScriptType;
public class P2PKAddress extends Address {
private byte[] pubKey;
public P2PKAddress(byte[] pubKey) {
super(Utils.sha256hash160(pubKey));
public P2PKAddress(Network network, byte[] pubKey) {
super(network, Utils.sha256hash160(pubKey));
this.pubKey = pubKey;
}
public int getVersion() {
return 0;
return network.pkhVersion;
}
public ScriptType getScriptType() {

View file

@ -1,15 +1,16 @@
package com.sparrowwallet.drongo.address;
import com.sparrowwallet.drongo.protocol.Network;
import com.sparrowwallet.drongo.protocol.Script;
import com.sparrowwallet.drongo.protocol.ScriptType;
public class P2PKHAddress extends Address {
public P2PKHAddress(byte[] pubKeyHash) {
super(pubKeyHash);
public P2PKHAddress(Network network, byte[] pubKeyHash) {
super(network, pubKeyHash);
}
public int getVersion() {
return 0;
return network.pkhVersion;
}
public ScriptType getScriptType() {

View file

@ -1,16 +1,17 @@
package com.sparrowwallet.drongo.address;
import com.sparrowwallet.drongo.Utils;
import com.sparrowwallet.drongo.protocol.Network;
import com.sparrowwallet.drongo.protocol.Script;
import com.sparrowwallet.drongo.protocol.ScriptType;
public class P2SHAddress extends Address {
public P2SHAddress(byte[] scriptHash) {
super(scriptHash);
public P2SHAddress(Network network, byte[] scriptHash) {
super(network, scriptHash);
}
public int getVersion() {
return 5;
return network.shVersion;
}
@Override
@ -33,7 +34,7 @@ public class P2SHAddress extends Address {
return "Script Hash";
}
public static P2SHAddress fromProgram(byte[] program) {
return new P2SHAddress(Utils.sha256hash160(program));
public static P2SHAddress fromProgram(Network network, byte[] program) {
return new P2SHAddress(network, Utils.sha256hash160(program));
}
}

View file

@ -1,14 +1,14 @@
package com.sparrowwallet.drongo.address;
import com.sparrowwallet.drongo.protocol.Bech32;
import com.sparrowwallet.drongo.protocol.Network;
import com.sparrowwallet.drongo.protocol.Script;
import com.sparrowwallet.drongo.protocol.ScriptType;
public class P2WPKHAddress extends Address {
public static final String HRP = "bc";
public P2WPKHAddress(byte[] pubKeyHash) {
super(pubKeyHash);
public P2WPKHAddress(Network network, byte[] pubKeyHash) {
super(network, pubKeyHash);
}
public int getVersion() {
@ -16,7 +16,7 @@ public class P2WPKHAddress extends Address {
}
public String getAddress() {
return Bech32.encode(HRP, getVersion(), hash);
return Bech32.encode(network.hrp, getVersion(), hash);
}
public ScriptType getScriptType() {

View file

@ -2,11 +2,11 @@ package com.sparrowwallet.drongo.address;
import com.sparrowwallet.drongo.protocol.*;
import static com.sparrowwallet.drongo.address.P2WPKHAddress.HRP;
import com.sparrowwallet.drongo.protocol.Network;
public class P2WSHAddress extends Address {
public P2WSHAddress(byte[] scriptHash) {
super(scriptHash);
public P2WSHAddress(Network network, byte[] scriptHash) {
super(network, scriptHash);
}
public int getVersion() {
@ -14,7 +14,7 @@ public class P2WSHAddress extends Address {
}
public String getAddress() {
return Bech32.encode(HRP, getVersion(), hash);
return Bech32.encode(network.hrp, getVersion(), hash);
}
public ScriptType getScriptType() {
@ -36,7 +36,7 @@ public class P2WSHAddress extends Address {
return "Witness Script Hash";
}
public static P2WSHAddress fromProgram(byte[] program) {
return new P2WSHAddress(Sha256Hash.hash(program));
public static P2WSHAddress fromProgram(Network network, byte[] program) {
return new P2WSHAddress(network, Sha256Hash.hash(program));
}
}

View file

@ -0,0 +1,18 @@
package com.sparrowwallet.drongo.protocol;
public enum Network {
TESTNET("tb", "mn2", 111, 196),
BITCOIN("bc", "13", 0, 5);
public final String hrp;
public final String legacyPrefixes;
public final int pkhVersion;
public final int shVersion;
private Network(String hrp, String legacyPrefixes, int pkhVersion, int shVersion) {
this.hrp = hrp;
this.legacyPrefixes = legacyPrefixes;
this.pkhVersion = pkhVersion;
this.shVersion = shVersion;
}
}

View file

@ -3,6 +3,7 @@ package com.sparrowwallet.drongo.protocol;
import com.sparrowwallet.drongo.Utils;
import com.sparrowwallet.drongo.address.*;
import com.sparrowwallet.drongo.crypto.ECKey;
import com.sparrowwallet.drongo.protocol.Network;
import org.bouncycastle.util.encoders.Hex;
import java.io.ByteArrayInputStream;
@ -153,22 +154,22 @@ public class Script {
/**
* Gets the destination address from this script, if it's in the required form.
*/
public Address[] getToAddresses() throws NonStandardScriptException {
public Address[] getToAddresses(Network network) throws NonStandardScriptException {
for(ScriptType scriptType : SINGLE_HASH_TYPES) {
if(scriptType.isScriptType(this)) {
return new Address[] { scriptType.getAddress(scriptType.getHashFromScript(this)) };
return new Address[] { scriptType.getAddress(network, scriptType.getHashFromScript(this)) };
}
}
if(P2PK.isScriptType(this)) {
return new Address[] { P2PK.getAddress(P2PK.getPublicKeyFromScript(this).getPubKey()) };
return new Address[] { P2PK.getAddress(network, P2PK.getPublicKeyFromScript(this).getPubKey()) };
}
if(MULTISIG.isScriptType(this)) {
List<Address> addresses = new ArrayList<>();
ECKey[] pubKeys = MULTISIG.getPublicKeysFromScript(this);
for(ECKey pubKey : pubKeys) {
addresses.add(new P2PKAddress(pubKey.getPubKey()));
addresses.add(new P2PKAddress(network, pubKey.getPubKey()));
}
return addresses.toArray(new Address[addresses.size()]);

View file

@ -6,6 +6,7 @@ import com.sparrowwallet.drongo.address.*;
import com.sparrowwallet.drongo.crypto.ChildNumber;
import com.sparrowwallet.drongo.crypto.ECKey;
import com.sparrowwallet.drongo.policy.PolicyType;
import com.sparrowwallet.drongo.protocol.Network;
import java.util.*;
import java.util.stream.Collectors;
@ -18,23 +19,23 @@ import static com.sparrowwallet.drongo.protocol.Transaction.WITNESS_SCALE_FACTOR
public enum ScriptType {
P2PK("P2PK", "m/44'/0'/0'") {
@Override
public Address getAddress(byte[] pubKey) {
return new P2PKAddress(pubKey);
public Address getAddress(Network network, byte[] pubKey) {
return new P2PKAddress(network, pubKey);
}
@Override
public Address getAddress(ECKey key) {
return getAddress(key.getPubKey());
public Address getAddress(Network network, ECKey key) {
return getAddress(network, key.getPubKey());
}
@Override
public Address getAddress(Script script) {
public Address getAddress(Network network, Script script) {
throw new ProtocolException("No script derived address for non pay to script type");
}
@Override
public Address[] getAddresses(Script script) {
return new Address[] { getAddress(getPublicKeyFromScript(script).getPubKey()) };
public Address[] getAddresses(Network network, Script script) {
return new Address[] { getAddress(network, getPublicKeyFromScript(script).getPubKey()) };
}
@Override
@ -132,17 +133,17 @@ public enum ScriptType {
},
P2PKH("P2PKH", "m/44'/0'/0'") {
@Override
public Address getAddress(byte[] pubKeyHash) {
return new P2PKHAddress(pubKeyHash);
public Address getAddress(Network network, byte[] pubKeyHash) {
return new P2PKHAddress(network, pubKeyHash);
}
@Override
public Address getAddress(ECKey key) {
return getAddress(key.getPubKeyHash());
public Address getAddress(Network network, ECKey key) {
return getAddress(network, key.getPubKeyHash());
}
@Override
public Address getAddress(Script script) {
public Address getAddress(Network network, Script script) {
throw new ProtocolException("No script derived address for non pay to script type");
}
@ -245,23 +246,23 @@ public enum ScriptType {
},
MULTISIG("Bare Multisig", "m/44'/0'/0'") {
@Override
public Address getAddress(byte[] bytes) {
public Address getAddress(Network network, byte[] bytes) {
throw new ProtocolException("No single address for multisig script type");
}
@Override
public Address getAddress(Script script) {
public Address getAddress(Network network, Script script) {
throw new ProtocolException("No single address for multisig script type");
}
@Override
public Address getAddress(ECKey key) {
public Address getAddress(Network network, ECKey key) {
throw new ProtocolException("No single key address for multisig script type");
}
@Override
public Address[] getAddresses(Script script) {
return Arrays.stream(getPublicKeysFromScript(script)).map(pubKey -> new P2PKAddress(pubKey.getPubKey())).toArray(Address[]::new);
public Address[] getAddresses(Network network, Script script) {
return Arrays.stream(getPublicKeysFromScript(script)).map(pubKey -> new P2PKAddress(network, pubKey.getPubKey())).toArray(Address[]::new);
}
@Override
@ -431,18 +432,18 @@ public enum ScriptType {
},
P2SH("P2SH", "m/45'/0'/0'") {
@Override
public Address getAddress(byte[] scriptHash) {
return new P2SHAddress(scriptHash);
public Address getAddress(Network network, byte[] scriptHash) {
return new P2SHAddress(network, scriptHash);
}
@Override
public Address getAddress(ECKey key) {
public Address getAddress(Network network, ECKey key) {
throw new ProtocolException("No single key address for script hash type");
}
@Override
public Address getAddress(Script script) {
return getAddress(Utils.sha256hash160(script.getProgram()));
public Address getAddress(Network network, Script script) {
return getAddress(network, Utils.sha256hash160(script.getProgram()));
}
@Override
@ -556,20 +557,20 @@ public enum ScriptType {
},
P2SH_P2WPKH("P2SH-P2WPKH", "m/49'/0'/0'") {
@Override
public Address getAddress(byte[] scriptHash) {
return P2SH.getAddress(scriptHash);
public Address getAddress(Network network, byte[] scriptHash) {
return P2SH.getAddress(network, scriptHash);
}
@Override
public Address getAddress(ECKey key) {
public Address getAddress(Network network, ECKey key) {
Script p2wpkhScript = P2WPKH.getOutputScript(key.getPubKeyHash());
return P2SH.getAddress(p2wpkhScript);
return P2SH.getAddress(network, p2wpkhScript);
}
@Override
public Address getAddress(Script script) {
public Address getAddress(Network network, Script script) {
if(P2WPKH.isScriptType(script)) {
return P2SH.getAddress(script);
return P2SH.getAddress(network, script);
}
throw new ProtocolException("Provided script is not a P2WPKH script");
@ -659,19 +660,19 @@ public enum ScriptType {
},
P2SH_P2WSH("P2SH-P2WSH", "m/48'/0'/0'/1'") {
@Override
public Address getAddress(byte[] scriptHash) {
return P2SH.getAddress(scriptHash);
public Address getAddress(Network network, byte[] scriptHash) {
return P2SH.getAddress(network, scriptHash);
}
@Override
public Address getAddress(ECKey key) {
public Address getAddress(Network network, ECKey key) {
throw new ProtocolException("No single key address for wrapped witness script hash type");
}
@Override
public Address getAddress(Script script) {
public Address getAddress(Network network, Script script) {
Script p2wshScript = P2WSH.getOutputScript(script);
return P2SH.getAddress(p2wshScript);
return P2SH.getAddress(network, p2wshScript);
}
@Override
@ -760,17 +761,17 @@ public enum ScriptType {
},
P2WPKH("P2WPKH", "m/84'/0'/0'") {
@Override
public Address getAddress(byte[] pubKeyHash) {
return new P2WPKHAddress(pubKeyHash);
public Address getAddress(Network network, byte[] pubKeyHash) {
return new P2WPKHAddress(network, pubKeyHash);
}
@Override
public Address getAddress(ECKey key) {
return getAddress(key.getPubKeyHash());
public Address getAddress(Network network, ECKey key) {
return getAddress(network, key.getPubKeyHash());
}
@Override
public Address getAddress(Script script) {
public Address getAddress(Network network, Script script) {
throw new ProtocolException("No script derived address for non pay to script type");
}
@ -865,18 +866,18 @@ public enum ScriptType {
},
P2WSH("P2WSH", "m/48'/0'/0'/2'") {
@Override
public Address getAddress(byte[] scriptHash) {
return new P2WSHAddress(scriptHash);
public Address getAddress(Network network, byte[] scriptHash) {
return new P2WSHAddress(network, scriptHash);
}
@Override
public Address getAddress(ECKey key) {
public Address getAddress(Network network, ECKey key) {
throw new ProtocolException("No single key address for witness script hash type");
}
@Override
public Address getAddress(Script script) {
return getAddress(Sha256Hash.hash(script.getProgram()));
public Address getAddress(Network network, Script script) {
return getAddress(network, Sha256Hash.hash(script.getProgram()));
}
@Override
@ -1023,11 +1024,11 @@ public enum ScriptType {
return getAllowedPolicyTypes().contains(policyType);
}
public abstract Address getAddress(byte[] bytes);
public abstract Address getAddress(Network network, byte[] bytes);
public abstract Address getAddress(ECKey key);
public abstract Address getAddress(Network network, ECKey key);
public abstract Address getAddress(Script script);
public abstract Address getAddress(Network network, Script script);
public abstract Script getOutputScript(byte[] bytes);
@ -1053,8 +1054,8 @@ public enum ScriptType {
public abstract byte[] getHashFromScript(Script script);
public Address[] getAddresses(Script script) {
return new Address[] { getAddress(getHashFromScript(script)) };
public Address[] getAddresses(Network network, Script script) {
return new Address[] { getAddress(network, getHashFromScript(script)) };
}
public ECKey getPublicKeyFromScript(Script script) {

View file

@ -31,6 +31,8 @@ public class PSBT {
private static final int STATE_OUTPUTS = 3;
private static final int STATE_END = 4;
private Network network;
private int inputs = 0;
private int outputs = 0;
@ -46,7 +48,8 @@ public class PSBT {
private static final Logger log = LoggerFactory.getLogger(PSBT.class);
public PSBT(Transaction transaction) {
public PSBT(Network network, Transaction transaction) {
this.network = network;
this.transaction = transaction;
for(int i = 0; i < transaction.getInputs().size(); i++) {
@ -64,6 +67,7 @@ public class PSBT {
public PSBT(WalletTransaction walletTransaction, Integer version, boolean includeGlobalXpubs) {
Wallet wallet = walletTransaction.getWallet();
this.network = wallet.getNetwork();
transaction = new Transaction(walletTransaction.getTransaction().bitcoinSerialize());
@ -119,7 +123,7 @@ public class PSBT {
List<WalletNode> outputNodes = new ArrayList<>();
for(TransactionOutput txOutput : transaction.getOutputs()) {
try {
Address address = txOutput.getScript().getToAddresses()[0];
Address address = txOutput.getScript().getToAddresses(network)[0];
if(address.equals(walletTransaction.getRecipientAddress())) {
outputNodes.add(wallet.getWalletAddresses().getOrDefault(walletTransaction.getRecipientAddress(), null));
} else if(address.equals(wallet.getAddress(walletTransaction.getChangeNode()))) {
@ -164,7 +168,8 @@ public class PSBT {
}
}
public PSBT(byte[] psbt) throws PSBTParseException {
public PSBT(Network network, byte[] psbt) throws PSBTParseException {
this.network = network;
this.psbtBytes = psbt;
parse();
}
@ -279,7 +284,7 @@ public class PSBT {
}
for(TransactionOutput output: transaction.getOutputs()) {
try {
log.debug(" Transaction output value: " + output.getValue() + " to addresses " + Arrays.asList(output.getScript().getToAddresses()) + " with script hex " + Utils.bytesToHex(output.getScript().getProgram()) + " to script " + output.getScript());
log.debug(" Transaction output value: " + output.getValue() + " to addresses " + Arrays.asList(output.getScript().getToAddresses(network)) + " with script hex " + Utils.bytesToHex(output.getScript().getProgram()) + " to script " + output.getScript());
} catch(NonStandardScriptException e) {
log.debug(" Transaction output value: " + output.getValue() + " with script hex " + Utils.bytesToHex(output.getScript().getProgram()) + " to script " + output.getScript());
}
@ -317,7 +322,7 @@ public class PSBT {
}
int inputIndex = this.psbtInputs.size();
PSBTInput input = new PSBTInput(inputEntries, transaction, inputIndex);
PSBTInput input = new PSBTInput(network, inputEntries, transaction, inputIndex);
boolean verified = input.verifySignatures();
if(!verified && input.getPartialSignatures().size() > 0) {
@ -586,7 +591,7 @@ public class PSBT {
}
}
public static PSBT fromString(String strPSBT) throws PSBTParseException {
public static PSBT fromString(Network network, String strPSBT) throws PSBTParseException {
if (!isPSBT(strPSBT)) {
throw new PSBTParseException("Provided string is not a PSBT");
}
@ -596,6 +601,6 @@ public class PSBT {
}
byte[] psbtBytes = Utils.hexToBytes(strPSBT);
return new PSBT(psbtBytes);
return new PSBT(network, psbtBytes);
}
}

View file

@ -66,7 +66,7 @@ public class PSBTInput {
this.proprietary.putAll(proprietary);
}
PSBTInput(List<PSBTEntry> inputEntries, Transaction transaction, int index) throws PSBTParseException {
PSBTInput(Network network, List<PSBTEntry> inputEntries, Transaction transaction, int index) throws PSBTParseException {
for(PSBTEntry entry : inputEntries) {
switch(entry.getKeyType()) {
case PSBT_IN_NON_WITNESS_UTXO:
@ -86,7 +86,7 @@ public class PSBTInput {
}
for(TransactionOutput output: nonWitnessTx.getOutputs()) {
try {
log.debug(" Transaction output value: " + output.getValue() + " to addresses " + Arrays.asList(output.getScript().getToAddresses()) + " with script hex " + Utils.bytesToHex(output.getScript().getProgram()) + " to script " + output.getScript());
log.debug(" Transaction output value: " + output.getValue() + " to addresses " + Arrays.asList(output.getScript().getToAddresses(network)) + " with script hex " + Utils.bytesToHex(output.getScript().getProgram()) + " to script " + output.getScript());
} catch(NonStandardScriptException e) {
log.error("Unknown script type", e);
}
@ -100,7 +100,7 @@ public class PSBTInput {
}
this.witnessUtxo = witnessTxOutput;
try {
log.debug("Found input witness utxo amount " + witnessTxOutput.getValue() + " script hex " + Utils.bytesToHex(witnessTxOutput.getScript().getProgram()) + " script " + witnessTxOutput.getScript() + " addresses " + Arrays.asList(witnessTxOutput.getScript().getToAddresses()));
log.debug("Found input witness utxo amount " + witnessTxOutput.getValue() + " script hex " + Utils.bytesToHex(witnessTxOutput.getScript().getProgram()) + " script " + witnessTxOutput.getScript() + " addresses " + Arrays.asList(witnessTxOutput.getScript().getToAddresses(network)));
} catch(NonStandardScriptException e) {
log.error("Unknown script type", e);
}

View file

@ -2,6 +2,7 @@ package com.sparrowwallet.drongo.uri;
import com.sparrowwallet.drongo.address.Address;
import com.sparrowwallet.drongo.address.InvalidAddressException;
import com.sparrowwallet.drongo.protocol.Network;
import java.math.BigDecimal;
import java.net.URI;
@ -79,7 +80,7 @@ public class BitcoinURI {
* @param input The raw URI data to be parsed (see class comments for accepted formats)
* @throws BitcoinURIParseException if the URI is not syntactically or semantically valid.
*/
public BitcoinURI(String input) throws BitcoinURIParseException {
public BitcoinURI(Network network, String input) throws BitcoinURIParseException {
String scheme = BITCOIN_SCHEME;
// Attempt to form the URI (fail fast syntax checking to official standards).
@ -132,7 +133,7 @@ public class BitcoinURI {
if(!addressToken.isEmpty()) {
// Attempt to parse the addressToken as a Bitcoin address for this network
try {
Address address = Address.fromString(addressToken);
Address address = Address.fromString(network, addressToken);
putWithValidation(FIELD_ADDRESS, address);
} catch(final InvalidAddressException e) {
throw new BitcoinURIParseException("Invalid address", e);
@ -294,11 +295,12 @@ public class BitcoinURI {
/**
* Constructs a new BitcoinURI from the given address.
*
* @param network The bitcoin network
* @param address The address forming the base of the URI
*/
public static BitcoinURI fromAddress(Address address) {
public static BitcoinURI fromAddress(Network network, Address address) {
try {
return new BitcoinURI(BITCOIN_SCHEME + ":" + address.toString());
return new BitcoinURI(network, BITCOIN_SCHEME + ":" + address.toString());
} catch(BitcoinURIParseException e) {
//Can't happen
return null;

View file

@ -5,6 +5,7 @@ import com.sparrowwallet.drongo.crypto.ECKey;
import com.sparrowwallet.drongo.policy.Miniscript;
import com.sparrowwallet.drongo.policy.Policy;
import com.sparrowwallet.drongo.policy.PolicyType;
import com.sparrowwallet.drongo.protocol.Network;
import com.sparrowwallet.drongo.protocol.NonStandardScriptException;
import com.sparrowwallet.drongo.protocol.Script;
import com.sparrowwallet.drongo.protocol.ScriptType;
@ -25,8 +26,8 @@ public class FinalizingPSBTWallet extends Wallet {
private final Map<WalletNode, List<ECKey>> signedNodeKeys = new LinkedHashMap<>();
private int numSignatures;
public FinalizingPSBTWallet(PSBT psbt) {
super("Finalizing PSBT Wallet");
public FinalizingPSBTWallet(Network network, PSBT psbt) {
super(network, "Finalizing PSBT Wallet");
if(!psbt.isSigned()) {
throw new IllegalArgumentException("Only a fully signed or finalized PSBT can be used");

View file

@ -21,6 +21,7 @@ public class Wallet {
public static final int DEFAULT_LOOKAHEAD = 20;
private String name;
private Network network;
private PolicyType policyType;
private ScriptType scriptType;
private Policy defaultPolicy;
@ -30,14 +31,17 @@ public class Wallet {
private Integer storedBlockHeight;
private Integer gapLimit;
public Wallet() {
public Wallet(Network network) {
this.network = network;
}
public Wallet(String name) {
public Wallet(Network network, String name) {
this.network = network;
this.name = name;
}
public Wallet(String name, PolicyType policyType, ScriptType scriptType) {
public Wallet(Network network, String name, PolicyType policyType, ScriptType scriptType) {
this.network = network;
this.name = name;
this.policyType = policyType;
this.scriptType = scriptType;
@ -45,6 +49,14 @@ public class Wallet {
this.defaultPolicy = Policy.getPolicy(policyType, scriptType, keystores, null);
}
public Network getNetwork() {
return network;
}
public void setNetwork(Network network) {
this.network = network;
}
public String getName() {
return name;
}
@ -200,11 +212,11 @@ public class Wallet {
public Address getAddress(KeyPurpose keyPurpose, int index) {
if(policyType == PolicyType.SINGLE) {
ECKey pubKey = getPubKey(keyPurpose, index);
return scriptType.getAddress(pubKey);
return scriptType.getAddress(network, pubKey);
} else if(policyType == PolicyType.MULTI) {
List<ECKey> pubKeys = getPubKeys(keyPurpose, index);
Script script = ScriptType.MULTISIG.getOutputScript(defaultPolicy.getNumSignaturesRequired(), pubKeys);
return scriptType.getAddress(script);
return scriptType.getAddress(network, script);
} else {
throw new UnsupportedOperationException("Cannot determine addresses for custom policies");
}
@ -861,7 +873,7 @@ public class Wallet {
}
public Wallet copy() {
Wallet copy = new Wallet(name);
Wallet copy = new Wallet(network, name);
copy.setPolicyType(policyType);
copy.setScriptType(scriptType);
copy.setDefaultPolicy(defaultPolicy.copy());

View file

@ -1,5 +1,7 @@
package com.sparrowwallet.drongo;
import com.sparrowwallet.drongo.protocol.Network;
import org.junit.Assert;
import org.junit.Test;
@ -10,43 +12,43 @@ public class OutputDescriptorTest {
@Test
public void electrumP2PKH() {
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor("xpub661MyMwAqRbcFT5HwyRoP5hebbeRDvy2RGDTH2uxFyDPaf5FLtu4njuishddViQxTABZKzoWKuwpy6MsgfPvTw9pKnRGDL5eBxDej9kF54Z");
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor(Network.BITCOIN, "xpub661MyMwAqRbcFT5HwyRoP5hebbeRDvy2RGDTH2uxFyDPaf5FLtu4njuishddViQxTABZKzoWKuwpy6MsgfPvTw9pKnRGDL5eBxDej9kF54Z");
Assert.assertEquals("pkh(xpub661MyMwAqRbcFT5HwyRoP5hebbeRDvy2RGDTH2uxFyDPaf5FLtu4njuishddViQxTABZKzoWKuwpy6MsgfPvTw9pKnRGDL5eBxDej9kF54Z)", descriptor.toString());
}
@Test
public void iancolemanP2PKH() {
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor("xpub6EEznxrqoN5HUXfD3QC3B8Vjw8Lj9UnRj17uTzNaBnEYN5xgwe6Un46Z443sSTBP2bzLZuDzygkdD1FtVWSexFmg4yAuCTxE2HxXFtz541z/*");
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor(Network.BITCOIN, "xpub6EEznxrqoN5HUXfD3QC3B8Vjw8Lj9UnRj17uTzNaBnEYN5xgwe6Un46Z443sSTBP2bzLZuDzygkdD1FtVWSexFmg4yAuCTxE2HxXFtz541z/*");
Assert.assertEquals("pkh(xpub6EEznxrqoN5HUXfD3QC3B8Vjw8Lj9UnRj17uTzNaBnEYN5xgwe6Un46Z443sSTBP2bzLZuDzygkdD1FtVWSexFmg4yAuCTxE2HxXFtz541z/*)", descriptor.toString());
}
@Test
public void electrumP2WPKH() {
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor("zpub6njbcfTHEfK4U96Z8dBaTULdb1LGWMtj73yYZ76kfmE9nuf3KhNSsXfzDefz5KV6TreWjnQbgvnSmSttudzTugesV2HFunYu7gWYJUD4eoR");
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor(Network.BITCOIN, "zpub6njbcfTHEfK4U96Z8dBaTULdb1LGWMtj73yYZ76kfmE9nuf3KhNSsXfzDefz5KV6TreWjnQbgvnSmSttudzTugesV2HFunYu7gWYJUD4eoR");
Assert.assertEquals("wpkh(xpub69551L7SwJE6mYiKTucL3J9dF53Nd7ujGpw6zKJyukUPgi2apP3KdQMiBEkp5WBFeaQuEqDUmc5LzsfmUFASKDHfkLtQjxuvaEPFXNDF4Kg)", descriptor.toString());
}
@Test
public void iancolemanP2SHP2WPKH() {
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor("ypub6Zken22QbjfomRUXki5v4ndP6T1DEtaBhGGZBvR4ocoooM44dFmnF8DyFmvcK76TKnuvdFfaPnicVvTAPdqEcbuEfKEqfnRoUjSkTB4u1os/*");
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor(Network.BITCOIN, "ypub6Zken22QbjfomRUXki5v4ndP6T1DEtaBhGGZBvR4ocoooM44dFmnF8DyFmvcK76TKnuvdFfaPnicVvTAPdqEcbuEfKEqfnRoUjSkTB4u1os/*");
Assert.assertEquals("sh(wpkh(xpub6EvPUMMVT48Kv8HQvMJHrhXsvUrmJGagn9kLQXXBRcRvkFEqNbcDd4ZqEZy2KCSXv9o7sn51w8N4cdqbfwRDpNDdnyYR5scKD1P74ZAKbGm/*))", descriptor.toString());
}
@Test
public void bip84P2WPKH() {
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor("zpub6rFR7y4Q2AijBEqTUquhVz398htDFrtymD9xYYfG1m4wAcvPhXNfE3EfH1r1ADqtfSdVCToUG868RvUUkgDKf31mGDtKsAYz2oz2AGutZYs");
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor(Network.BITCOIN, "zpub6rFR7y4Q2AijBEqTUquhVz398htDFrtymD9xYYfG1m4wAcvPhXNfE3EfH1r1ADqtfSdVCToUG868RvUUkgDKf31mGDtKsAYz2oz2AGutZYs");
Assert.assertEquals("wpkh(xpub6CatWdiZiodmUeTDp8LT5or8nmbKNcuyvz7WyksVFkKB4RHwCD3XyuvPEbvqAQY3rAPshWcMLoP2fMFMKHPJ4ZeZXYVUhLv1VMrjPC7PW6V)", descriptor.toString());
}
@Test
public void redditP2SHP2WPKH() {
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor("ypub6XiW9nhToS1gjVsFKzgmtWZuqo6V1YY7xaCns37aR3oYhFyAsTehAqV1iW2UCNtgWFQFkz3aNSZZbkfe5d1tD8MzjZuFJQn2XnczsxtjoXr");
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor(Network.BITCOIN, "ypub6XiW9nhToS1gjVsFKzgmtWZuqo6V1YY7xaCns37aR3oYhFyAsTehAqV1iW2UCNtgWFQFkz3aNSZZbkfe5d1tD8MzjZuFJQn2XnczsxtjoXr");
Assert.assertEquals("sh(wpkh(xpub6CtEr82YekUCtCg8Vdu9gRUQfpx34vYd3Tga5eDh33RfeA9wcoV8YmpshJ4tCUEm6cHT1WT1unD1iU45MvbsQtgPsECpiVxYG4ZMVKEKqGP))", descriptor.toString());
}
@Test
public void masterP2PKH() {
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor("pkh([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*)");
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor(Network.BITCOIN, "pkh([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*)");
Assert.assertEquals("pkh([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*)", descriptor.toString());
ExtendedKey extendedPublicKey = descriptor.getSingletonExtendedPublicKey();
KeyDerivation derivation = descriptor.getKeyDerivation(extendedPublicKey);
@ -57,7 +59,7 @@ public class OutputDescriptorTest {
@Test
public void singleP2SH_P2WPKH() {
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor("sh(wpkh([f09a3b29/49h/0h/0h]xpub6CjUWYtkq9KT1zkM5NPMxoJTCMm8JSFw7JPyMG6YLBzv5AsCTkASnsVyJhqL1aaqF5XSsFinHK3FDi8RoeEWcTG3DQA2TjqrZ6HJtatYbsU/0/*))");
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor(Network.BITCOIN, "sh(wpkh([f09a3b29/49h/0h/0h]xpub6CjUWYtkq9KT1zkM5NPMxoJTCMm8JSFw7JPyMG6YLBzv5AsCTkASnsVyJhqL1aaqF5XSsFinHK3FDi8RoeEWcTG3DQA2TjqrZ6HJtatYbsU/0/*))");
Assert.assertEquals("sh(wpkh([f09a3b29/49'/0'/0']xpub6CjUWYtkq9KT1zkM5NPMxoJTCMm8JSFw7JPyMG6YLBzv5AsCTkASnsVyJhqL1aaqF5XSsFinHK3FDi8RoeEWcTG3DQA2TjqrZ6HJtatYbsU/0/*))", descriptor.toString());
ExtendedKey extendedPublicKey = descriptor.getSingletonExtendedPublicKey();
KeyDerivation derivation = descriptor.getKeyDerivation(extendedPublicKey);
@ -68,7 +70,7 @@ public class OutputDescriptorTest {
@Test
public void multisigP2WSH() {
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor("wsh(sortedmulti(2,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/0/*,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/*))");
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor(Network.BITCOIN, "wsh(sortedmulti(2,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/0/*,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/*))");
Assert.assertEquals("wsh(sortedmulti(2,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/0/*,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/*))", descriptor.toString());
Assert.assertEquals(2, descriptor.getMultisigThreshold());
Assert.assertEquals("bc1qf5l7g5t5v2tp2wnwfeqlktkds7zvprmm7afjn6f85fdesc2pwedsh42kcl", descriptor.getAddress(KeyDerivation.parsePath("0/0")).toString());
@ -76,7 +78,7 @@ public class OutputDescriptorTest {
@Test
public void multisigP2WSH2() {
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor("wsh(sortedmulti(2,[04fefef0/48h/0h/0h/2h]xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/0/*,[04ba1ef0/48h/0h/0h/2h]xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/*))");
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor(Network.BITCOIN, "wsh(sortedmulti(2,[04fefef0/48h/0h/0h/2h]xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/0/*,[04ba1ef0/48h/0h/0h/2h]xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/*))");
Set<ExtendedKey> extendedPublicKeys = descriptor.getExtendedPublicKeys();
Iterator<ExtendedKey> iter = extendedPublicKeys.iterator();
ExtendedKey extendedPublicKey1 = iter.next();
@ -94,7 +96,7 @@ public class OutputDescriptorTest {
@Test
public void testChecksum() {
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor("sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5t");
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor(Network.BITCOIN, "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5t");
Assert.assertEquals("sh(sortedmulti(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#s66h0xn6", descriptor.toString(true));
}
}

View file

@ -1,5 +1,7 @@
package com.sparrowwallet.drongo;
import com.sparrowwallet.drongo.protocol.Network;
import org.junit.Assert;
import org.junit.Test;
@ -7,7 +9,7 @@ public class WatchWalletTest {
@Test
public void electrumP2PKH() {
WatchWallet wallet = new WatchWallet("", "xpub661MyMwAqRbcFT5HwyRoP5hebbeRDvy2RGDTH2uxFyDPaf5FLtu4njuishddViQxTABZKzoWKuwpy6MsgfPvTw9pKnRGDL5eBxDej9kF54Z");
WatchWallet wallet = new WatchWallet(Network.BITCOIN, "", "xpub661MyMwAqRbcFT5HwyRoP5hebbeRDvy2RGDTH2uxFyDPaf5FLtu4njuishddViQxTABZKzoWKuwpy6MsgfPvTw9pKnRGDL5eBxDej9kF54Z");
Assert.assertEquals("1QEjP9f7KRtJobfwmRuykpLjaR5QchGo8q", wallet.getReceivingAddress(0).toString());
Assert.assertEquals("17kCok3XAUHyL6kjzBF44e1YuzMmRXPuu5", wallet.getReceivingAddress(1).toString());
@ -16,7 +18,7 @@ public class WatchWalletTest {
@Test
public void iancolemanP2PKH() {
WatchWallet wallet = new WatchWallet("", "xpub6EEznxrqoN5HUXfD3QC3B8Vjw8Lj9UnRj17uTzNaBnEYN5xgwe6Un46Z443sSTBP2bzLZuDzygkdD1FtVWSexFmg4yAuCTxE2HxXFtz541z/*");
WatchWallet wallet = new WatchWallet(Network.BITCOIN, "", "xpub6EEznxrqoN5HUXfD3QC3B8Vjw8Lj9UnRj17uTzNaBnEYN5xgwe6Un46Z443sSTBP2bzLZuDzygkdD1FtVWSexFmg4yAuCTxE2HxXFtz541z/*");
Assert.assertEquals("179cMrkiyx6zD2E1sqBAQLg1SQPAS5vjQW", wallet.getReceivingAddress(0).toString());
Assert.assertEquals("1GdWCzdt5oDYh5n1qeZQCxg5rQKVTuTMJg", wallet.getReceivingAddress(1).toString());
@ -24,7 +26,7 @@ public class WatchWalletTest {
@Test
public void electrumP2WPKH() {
WatchWallet wallet = new WatchWallet("", "zpub6njbcfTHEfK4U96Z8dBaTULdb1LGWMtj73yYZ76kfmE9nuf3KhNSsXfzDefz5KV6TreWjnQbgvnSmSttudzTugesV2HFunYu7gWYJUD4eoR");
WatchWallet wallet = new WatchWallet(Network.BITCOIN, "", "zpub6njbcfTHEfK4U96Z8dBaTULdb1LGWMtj73yYZ76kfmE9nuf3KhNSsXfzDefz5KV6TreWjnQbgvnSmSttudzTugesV2HFunYu7gWYJUD4eoR");
Assert.assertEquals("bc1q4s5v0u9qmmcp25mnr3mfzhyftjzw8mccqawmwf", wallet.getReceivingAddress(0).toString());
Assert.assertEquals("bc1qffy90ge6wljh53t07q4al2pgsmuqgy48wrk8wq", wallet.getReceivingAddress(1).toString());
@ -33,7 +35,7 @@ public class WatchWalletTest {
@Test
public void iancolemanP2SHP2WPKH() {
WatchWallet wallet = new WatchWallet("", "ypub6Zken22QbjfomRUXki5v4ndP6T1DEtaBhGGZBvR4ocoooM44dFmnF8DyFmvcK76TKnuvdFfaPnicVvTAPdqEcbuEfKEqfnRoUjSkTB4u1os/*");
WatchWallet wallet = new WatchWallet(Network.BITCOIN, "", "ypub6Zken22QbjfomRUXki5v4ndP6T1DEtaBhGGZBvR4ocoooM44dFmnF8DyFmvcK76TKnuvdFfaPnicVvTAPdqEcbuEfKEqfnRoUjSkTB4u1os/*");
Assert.assertEquals("34SgiHwNwJt3nYCVUQcgJWhefVRBZ4aSHf", wallet.getReceivingAddress(0).toString());
Assert.assertEquals("3MgPnbF6UYM3FBhZWXoL2ebLPEa3zCCXLh", wallet.getReceivingAddress(1).toString());
@ -41,7 +43,7 @@ public class WatchWalletTest {
@Test
public void bip84P2WPKH() {
WatchWallet wallet = new WatchWallet("", "zpub6rFR7y4Q2AijBEqTUquhVz398htDFrtymD9xYYfG1m4wAcvPhXNfE3EfH1r1ADqtfSdVCToUG868RvUUkgDKf31mGDtKsAYz2oz2AGutZYs");
WatchWallet wallet = new WatchWallet(Network.BITCOIN, "", "zpub6rFR7y4Q2AijBEqTUquhVz398htDFrtymD9xYYfG1m4wAcvPhXNfE3EfH1r1ADqtfSdVCToUG868RvUUkgDKf31mGDtKsAYz2oz2AGutZYs");
Assert.assertEquals("bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu", wallet.getReceivingAddress(0).toString());
Assert.assertEquals("bc1qnjg0jd8228aq7egyzacy8cys3knf9xvrerkf9g", wallet.getReceivingAddress(1).toString());
@ -50,7 +52,7 @@ public class WatchWalletTest {
@Test
public void redditP2SHP2WPKH() {
WatchWallet wallet = new WatchWallet("", "ypub6XiW9nhToS1gjVsFKzgmtWZuqo6V1YY7xaCns37aR3oYhFyAsTehAqV1iW2UCNtgWFQFkz3aNSZZbkfe5d1tD8MzjZuFJQn2XnczsxtjoXr");
WatchWallet wallet = new WatchWallet(Network.BITCOIN, "", "ypub6XiW9nhToS1gjVsFKzgmtWZuqo6V1YY7xaCns37aR3oYhFyAsTehAqV1iW2UCNtgWFQFkz3aNSZZbkfe5d1tD8MzjZuFJQn2XnczsxtjoXr");
Assert.assertEquals("34TBBnwqv338BT6BVnTKqziFq8HWY6BNbw", wallet.getReceivingAddress(0).toString());
Assert.assertEquals("35Jhf9LGCpb1ihJjWH7uLZ8othr1diuspS", wallet.getChangeAddress(0).toString());
@ -58,7 +60,7 @@ public class WatchWalletTest {
@Test
public void electrumP2WSHMulti() {
WatchWallet wallet = new WatchWallet("", "wsh(multi(2,xpub699B7APGMoPLUrvPsXiBFrJRV8sTHDBHptpHSH36aESP5SLYs4VcEotnX1EvvA5ZoKF2rZ24Wh4U5ALxM21CfL5Kcj6Tu41PjRr2KKMkJTJ/0/*,xpub6Ds1jx5qxAtdczVBnJfHeGgpspzYuxnXHXLCoPZFFyyMoKJ7zzLgcERB1t7eDV1UuBQL1UKNxHFvcMJ7Zj6D2amdaA8gb21cZSXPrpG1bZr/0/*))");
WatchWallet wallet = new WatchWallet(Network.BITCOIN, "", "wsh(multi(2,xpub699B7APGMoPLUrvPsXiBFrJRV8sTHDBHptpHSH36aESP5SLYs4VcEotnX1EvvA5ZoKF2rZ24Wh4U5ALxM21CfL5Kcj6Tu41PjRr2KKMkJTJ/0/*,xpub6Ds1jx5qxAtdczVBnJfHeGgpspzYuxnXHXLCoPZFFyyMoKJ7zzLgcERB1t7eDV1UuBQL1UKNxHFvcMJ7Zj6D2amdaA8gb21cZSXPrpG1bZr/0/*))");
Assert.assertEquals("bc1q2jxsrw70ug8jgskmhynvs49h3q5h8fglkdl3trvrc6wsde07wuzqfz98z0", wallet.getReceivingAddress(0).toString());
Assert.assertEquals("bc1qzw9j02k6l7z598edcgjh5mks507xevhk34rmnerxv45ptsluf0pqyxmyve", wallet.getChangeAddress(0).toString());
@ -66,7 +68,7 @@ public class WatchWalletTest {
@Test
public void electrumP2WSHMulti2() {
WatchWallet wallet = new WatchWallet("", "wsh(multi(2,Zpub6yhnqjTYE82fc2U1UukQW6qEYsCcNoqsyPWPvL6Qi22YopXv8nD1a44zN87aUQcJr4YdE6DJKEA4xuBr5dzBQHZCBsbiUH7NAcFBgPyx3LB/0/*,Zpub74eXjdXzGCRsixpRAZT3U8ssQ15uhUa1dCFdRJvY3L2qo18He71qWUfpxfbL9e2EYuWKe1tH7qzgUSRVTAektLDVRKwCbAtyRW5j2yhqLiD/0/*))");
WatchWallet wallet = new WatchWallet(Network.BITCOIN, "", "wsh(multi(2,Zpub6yhnqjTYE82fc2U1UukQW6qEYsCcNoqsyPWPvL6Qi22YopXv8nD1a44zN87aUQcJr4YdE6DJKEA4xuBr5dzBQHZCBsbiUH7NAcFBgPyx3LB/0/*,Zpub74eXjdXzGCRsixpRAZT3U8ssQ15uhUa1dCFdRJvY3L2qo18He71qWUfpxfbL9e2EYuWKe1tH7qzgUSRVTAektLDVRKwCbAtyRW5j2yhqLiD/0/*))");
Assert.assertEquals("bc1qa842ug2njv36ycnhq8wjcg6wxjv7p7h4v0tnl40u6nfxxxffyjnq409pr9", wallet.getReceivingAddress(0).toString());
Assert.assertEquals("bc1q3auk6c8f77dda0w8y9dz4yd3wqhkf4eufzk8x2quszvzzcyjk6rqgz70pd", wallet.getChangeAddress(0).toString());
@ -74,7 +76,7 @@ public class WatchWalletTest {
@Test
public void electrumP2WSHMultiSingle() {
WatchWallet wallet = new WatchWallet("", "wsh(multi(2,xpub699B7APGMoPLUrvPsXiBFrJRV8sTHDBHptpHSH36aESP5SLYs4VcEotnX1EvvA5ZoKF2rZ24Wh4U5ALxM21CfL5Kcj6Tu41PjRr2KKMkJTJ/0/0,xpub6Ds1jx5qxAtdczVBnJfHeGgpspzYuxnXHXLCoPZFFyyMoKJ7zzLgcERB1t7eDV1UuBQL1UKNxHFvcMJ7Zj6D2amdaA8gb21cZSXPrpG1bZr/0/0))");
WatchWallet wallet = new WatchWallet(Network.BITCOIN, "", "wsh(multi(2,xpub699B7APGMoPLUrvPsXiBFrJRV8sTHDBHptpHSH36aESP5SLYs4VcEotnX1EvvA5ZoKF2rZ24Wh4U5ALxM21CfL5Kcj6Tu41PjRr2KKMkJTJ/0/0,xpub6Ds1jx5qxAtdczVBnJfHeGgpspzYuxnXHXLCoPZFFyyMoKJ7zzLgcERB1t7eDV1UuBQL1UKNxHFvcMJ7Zj6D2amdaA8gb21cZSXPrpG1bZr/0/0))");
Assert.assertEquals("bc1q2jxsrw70ug8jgskmhynvs49h3q5h8fglkdl3trvrc6wsde07wuzqfz98z0", wallet.getAddress(wallet.getOutputDescriptor().getChildDerivation()).toString());
}
}

View file

@ -1,5 +1,7 @@
package com.sparrowwallet.drongo.address;
import com.sparrowwallet.drongo.protocol.Network;
import org.junit.Assert;
import org.junit.Test;
@ -8,21 +10,41 @@ import java.security.SecureRandom;
public class AddressTest {
@Test
public void validAddressTest() throws InvalidAddressException {
Address address1 = Address.fromString("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4");
Address address1 = Address.fromString(Network.BITCOIN, "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4");
Assert.assertTrue(address1 instanceof P2WPKHAddress);
Assert.assertEquals("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4", address1.toString());
Address address2 = Address.fromString("bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3");
Address address2 = Address.fromString(Network.BITCOIN, "bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3");
Assert.assertTrue(address2 instanceof P2WSHAddress);
Assert.assertEquals("bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3", address2.toString());
Address address3 = Address.fromString("19Sp9dLinHy3dKo2Xxj53ouuZWAoVGGhg8");
Address address3 = Address.fromString(Network.BITCOIN, "19Sp9dLinHy3dKo2Xxj53ouuZWAoVGGhg8");
Assert.assertTrue(address3 instanceof P2PKHAddress);
Assert.assertEquals("19Sp9dLinHy3dKo2Xxj53ouuZWAoVGGhg8", address3.toString());
Address address4 = Address.fromString("34jnjFM4SbaB7Q8aMtNDG849RQ1gUYgpgo");
Address address4 = Address.fromString(Network.BITCOIN, "34jnjFM4SbaB7Q8aMtNDG849RQ1gUYgpgo");
Assert.assertTrue(address4 instanceof P2SHAddress);
Assert.assertEquals("34jnjFM4SbaB7Q8aMtNDG849RQ1gUYgpgo", address4.toString());
Address address5 = Address.fromString(Network.TESTNET, "tb1qawkzyj2l5yck5jq4wyhkc4837x088580y9uyk8");
Assert.assertTrue(address5 instanceof P2WPKHAddress);
Assert.assertEquals("tb1qawkzyj2l5yck5jq4wyhkc4837x088580y9uyk8", address5.toString());
Address address6 = Address.fromString(Network.TESTNET, "tb1q8kdkthp5a6vfrdas84efkpv25ul3s9wpzc755cra8av48xq4a7wsjcsdma");
Assert.assertTrue(address6 instanceof P2WSHAddress);
Assert.assertEquals("tb1q8kdkthp5a6vfrdas84efkpv25ul3s9wpzc755cra8av48xq4a7wsjcsdma", address6.toString());
Address address7 = Address.fromString(Network.TESTNET, "mng6R5oLWBBo8iFWU9Mx4zFy5pWhrWMeW2");
Assert.assertTrue(address7 instanceof P2PKHAddress);
Assert.assertEquals("mng6R5oLWBBo8iFWU9Mx4zFy5pWhrWMeW2", address7.toString());
Address address8 = Address.fromString(Network.TESTNET, "n1S1rnnZm3RdW9iuAF6Hjk3gLZWGc59zDi");
Assert.assertTrue(address8 instanceof P2PKHAddress);
Assert.assertEquals("n1S1rnnZm3RdW9iuAF6Hjk3gLZWGc59zDi", address8.toString());
Address address9 = Address.fromString(Network.TESTNET, "2NCZUtUt6gzXyBiPEQi5yQyrgR6f6F6Ki6A");
Assert.assertTrue(address9 instanceof P2SHAddress);
Assert.assertEquals("2NCZUtUt6gzXyBiPEQi5yQyrgR6f6F6Ki6A", address9.toString());
}
@Test
@ -32,39 +54,39 @@ public class AddressTest {
for(int i = 0; i < 100; i++) {
random.nextBytes(values);
Address address = (i % 2 == 0 ? new P2PKHAddress(values) : new P2WPKHAddress(values));
Address address = (i % 2 == 0 ? new P2PKHAddress(Network.BITCOIN, values) : new P2WPKHAddress(Network.BITCOIN, values));
String strAddress = address.toString();
Address checkAddress = Address.fromString(strAddress);
Address checkAddress = Address.fromString(Network.BITCOIN, strAddress);
Assert.assertArrayEquals(values, checkAddress.getHash());
}
byte[] values32 = new byte[32];
for(int i = 0; i < 100; i++) {
random.nextBytes(values32);
Address address = new P2WSHAddress(values32);
Address address = new P2WSHAddress(Network.BITCOIN, values32);
String strAddress = address.toString();
Address checkAddress = Address.fromString(strAddress);
Address checkAddress = Address.fromString(Network.BITCOIN, strAddress);
Assert.assertArrayEquals(values32, checkAddress.getHash());
}
}
@Test(expected = InvalidAddressException.class)
public void invalidCharacterAddressTest() throws InvalidAddressException {
Address address1 = Address.fromString("bc1qw508d6qejxtdg4y5R3zarvary0c5xw7kv8f3t4");
Address address1 = Address.fromString(Network.BITCOIN, "bc1qw508d6qejxtdg4y5R3zarvary0c5xw7kv8f3t4");
}
@Test(expected = InvalidAddressException.class)
public void invalidVersionAddressTest() throws InvalidAddressException {
Address address1 = Address.fromString("44jnjFM4SbaB7Q8aMtNDG849RQ1gUYgpgo");
Address address1 = Address.fromString(Network.BITCOIN, "44jnjFM4SbaB7Q8aMtNDG849RQ1gUYgpgo");
}
@Test(expected = InvalidAddressException.class)
public void invalidChecksumAddressTest() throws InvalidAddressException {
Address address1 = Address.fromString("34jnjFM4SbaB7Q7aMtNDG849RQ1gUYgpgo");
Address address1 = Address.fromString(Network.BITCOIN, "34jnjFM4SbaB7Q7aMtNDG849RQ1gUYgpgo");
}
@Test(expected = InvalidAddressException.class)
public void invalidChecksumAddressTest2() throws InvalidAddressException {
Address address1 = Address.fromString("bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmb3");
Address address1 = Address.fromString(Network.BITCOIN, "bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmb3");
}
}

View file

@ -4,6 +4,7 @@ import com.sparrowwallet.drongo.Utils;
import com.sparrowwallet.drongo.address.Address;
import com.sparrowwallet.drongo.address.InvalidAddressException;
import com.sparrowwallet.drongo.crypto.ECKey;
import com.sparrowwallet.drongo.protocol.Network;
import org.junit.Assert;
import org.junit.Test;
@ -142,7 +143,7 @@ public class TransactionTest {
}
for(TransactionOutput txOutput : parsedTransaction.getOutputs()) {
Address address = txOutput.getScript().getToAddresses()[0];
Address address = txOutput.getScript().getToAddresses(Network.BITCOIN)[0];
transaction.addOutput(txOutput.getValue(), address);
}
@ -168,7 +169,7 @@ public class TransactionTest {
}
for(TransactionOutput txOutput : parsedTransaction.getOutputs()) {
Address address = txOutput.getScript().getToAddresses()[0];
Address address = txOutput.getScript().getToAddresses(Network.BITCOIN)[0];
transaction.addOutput(txOutput.getValue(), address);
}
@ -196,7 +197,7 @@ public class TransactionTest {
}
for(TransactionOutput txOutput : parsedTransaction.getOutputs()) {
Address address = txOutput.getScript().getToAddresses()[0];
Address address = txOutput.getScript().getToAddresses(Network.BITCOIN)[0];
transaction.addOutput(txOutput.getValue(), address);
}
@ -228,8 +229,8 @@ public class TransactionTest {
Transaction transaction = new Transaction();
spent0ScriptType.addSpendingInput(transaction, spent0Output, key0, signature0);
transaction.addOutput(3000000000L, Address.fromString("1GWUbNagGsvpwygRCjoczegGVDvpm5fLV8"));
transaction.addOutput(2000000000L, Address.fromString("19jCd38mHkNcXiGF4AjUCoJBSo7iqqjRHT"));
transaction.addOutput(3000000000L, Address.fromString(Network.BITCOIN, "1GWUbNagGsvpwygRCjoczegGVDvpm5fLV8"));
transaction.addOutput(2000000000L, Address.fromString(Network.BITCOIN, "19jCd38mHkNcXiGF4AjUCoJBSo7iqqjRHT"));
Assert.assertEquals(spendingTransaction.getLength(), transaction.getLength());
@ -271,8 +272,8 @@ public class TransactionTest {
spent0ScriptType.addSpendingInput(transaction, spent0Output, pubKey0, signature0);
spent1ScriptType.addSpendingInput(transaction, spent1Output, pubKey1, signature1);
transaction.addOutput(922, Address.fromString("1JVsQ4L4HAcn58Gj5uF16dvgFNdVTarY6i"));
transaction.addOutput(9984568, Address.fromString("1Q7CEaM3CQ6ejGHgDZNbdTTAkoLcPk63nQ"));
transaction.addOutput(922, Address.fromString(Network.BITCOIN, "1JVsQ4L4HAcn58Gj5uF16dvgFNdVTarY6i"));
transaction.addOutput(9984568, Address.fromString(Network.BITCOIN, "1Q7CEaM3CQ6ejGHgDZNbdTTAkoLcPk63nQ"));
Assert.assertEquals(spendingTransaction.getLength(), transaction.getLength());
@ -311,10 +312,10 @@ public class TransactionTest {
Transaction transaction = new Transaction();
spent0ScriptType.addMultisigSpendingInput(transaction, spent0Output, 2, pubKeySignatures);
transaction.addOutput(833300, Address.fromString("31mKrRn3xQoGppLY5dU92Dbm4kN4ddkknE"));
transaction.addOutput(1222480000, Address.fromString("1CL9kj1seXif6agPfeh6vpKkzc2Hxq1UpM"));
transaction.addOutput(332000, Address.fromString("1B6ifpYaSvBkjJTf4W1tjYgDYajFua3NU8"));
transaction.addOutput(8993844, Address.fromString("3Pwp5u7PwgrMw3gAAyLAkDKYKRrFuFkneG"));
transaction.addOutput(833300, Address.fromString(Network.BITCOIN, "31mKrRn3xQoGppLY5dU92Dbm4kN4ddkknE"));
transaction.addOutput(1222480000, Address.fromString(Network.BITCOIN, "1CL9kj1seXif6agPfeh6vpKkzc2Hxq1UpM"));
transaction.addOutput(332000, Address.fromString(Network.BITCOIN, "1B6ifpYaSvBkjJTf4W1tjYgDYajFua3NU8"));
transaction.addOutput(8993844, Address.fromString(Network.BITCOIN, "3Pwp5u7PwgrMw3gAAyLAkDKYKRrFuFkneG"));
Assert.assertEquals(spendingTransaction.getLength(), transaction.getLength());
@ -348,9 +349,9 @@ public class TransactionTest {
TransactionInput input = ScriptType.P2SH_P2WPKH.addSpendingInput(transaction, spent0Output, pubKey0, signature0);
input.setSequenceNumber(TransactionInput.SEQUENCE_RBF_ENABLED);
transaction.addOutput(4000, Address.fromString("1LiQZqSwPqb615uyxDKTaN9Tg4CER98cgJ"));
transaction.addOutput(361206, Address.fromString("32B5Pv7Nvhh8iQ3Z2xK8cbKBW5f2bGMoqp"));
transaction.addOutput(27100, Address.fromString("3KzUpFMVKXiNETUy19VVW9Re5EimboDuyX"));
transaction.addOutput(4000, Address.fromString(Network.BITCOIN, "1LiQZqSwPqb615uyxDKTaN9Tg4CER98cgJ"));
transaction.addOutput(361206, Address.fromString(Network.BITCOIN, "32B5Pv7Nvhh8iQ3Z2xK8cbKBW5f2bGMoqp"));
transaction.addOutput(27100, Address.fromString(Network.BITCOIN, "3KzUpFMVKXiNETUy19VVW9Re5EimboDuyX"));
Assert.assertEquals(spendingTransaction.getLength(), transaction.getLength());
@ -391,8 +392,8 @@ public class TransactionTest {
transaction.setSegwitVersion(1);
TransactionInput input = ScriptType.P2SH_P2WSH.addMultisigSpendingInput(transaction, spent0Output, 2, pubKeySignatures);
transaction.addOutput(59287429, Address.fromString("3PBjKH4FRuEKy4sD3NfL7tqfZTG5K42owu"));
transaction.addOutput(212571, Address.fromString("3KRUgU4XGuErXkjBtFhksPzTGJ4AMwF4jB"));
transaction.addOutput(59287429, Address.fromString(Network.BITCOIN, "3PBjKH4FRuEKy4sD3NfL7tqfZTG5K42owu"));
transaction.addOutput(212571, Address.fromString(Network.BITCOIN, "3KRUgU4XGuErXkjBtFhksPzTGJ4AMwF4jB"));
Assert.assertEquals(spendingTransaction.getLength(), transaction.getLength());
@ -425,8 +426,8 @@ public class TransactionTest {
transaction.setSegwitVersion(1);
spent0ScriptType.addSpendingInput(transaction, spent0Output, key0, signature0);
transaction.addOutput(211584990, Address.fromString("bc1q9k6aan6ncahvlslw8w54jzv897k55zh077un6s"));
transaction.addOutput(1806203, Address.fromString("3QLFcgKFNzo262FYRFgGfrUNiUurpQbDZv"));
transaction.addOutput(211584990, Address.fromString(Network.BITCOIN, "bc1q9k6aan6ncahvlslw8w54jzv897k55zh077un6s"));
transaction.addOutput(1806203, Address.fromString(Network.BITCOIN, "3QLFcgKFNzo262FYRFgGfrUNiUurpQbDZv"));
Assert.assertEquals(spendingTransaction.getLength(), transaction.getLength());
@ -467,9 +468,9 @@ public class TransactionTest {
transaction.setSegwitVersion(1);
spent0ScriptType.addMultisigSpendingInput(transaction, spent0Output, 2, pubKeySignatures);
transaction.addOutput(10900000, Address.fromString("3Dt17mpd8FDXBjP56rCD7a4Sx7wpL91uhn"));
transaction.addOutput(332500000, Address.fromString("1K6igqzm36x8jxRTavPhgWXLVcVZVDTGc9"));
transaction.addOutput(156694315, Address.fromString("bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej"));
transaction.addOutput(10900000, Address.fromString(Network.BITCOIN, "3Dt17mpd8FDXBjP56rCD7a4Sx7wpL91uhn"));
transaction.addOutput(332500000, Address.fromString(Network.BITCOIN, "1K6igqzm36x8jxRTavPhgWXLVcVZVDTGc9"));
transaction.addOutput(156694315, Address.fromString(Network.BITCOIN, "bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej"));
Assert.assertEquals(spendingTransaction.getLength(), transaction.getLength());

View file

@ -14,115 +14,115 @@ public class PSBTTest {
@Test(expected = PSBTParseException.class)
public void invalidNotPSBT() throws PSBTParseException {
String psbt = "AgAAAAEmgXE3Ht/yhek3re6ks3t4AAwFZsuzrWRkFxPKQhcb9gAAAABqRzBEAiBwsiRRI+a/R01gxbUMBD1MaRpdJDXwmjSnZiqdwlF5CgIgATKcqdrPKAvfMHQOwDkEIkIsgctFg5RXrrdvwS7dlbMBIQJlfRGNM1e44PTCzUbbezn22cONmnCry5st5dyNv+TOMf7///8C09/1BQAAAAAZdqkU0MWZA8W6woaHYOkP1SGkZlqnZSCIrADh9QUAAAAAF6kUNUXm4zuDLEcFDyTT7rk8nAOUi8eHsy4TAA==";
PSBT.fromString(psbt);
PSBT.fromString(Network.BITCOIN, psbt);
}
@Test(expected = PSBTParseException.class)
public void missingOutputs() throws PSBTParseException {
String psbt = "cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAA==";
PSBT.fromString(psbt);
PSBT.fromString(Network.BITCOIN, psbt);
}
@Test(expected = PSBTParseException.class)
public void unsignedTxWithScriptSig() throws PSBTParseException {
String psbt = "cHNidP8BAP0KAQIAAAACqwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QAAAAAakcwRAIgR1lmF5fAGwNrJZKJSGhiGDR9iYZLcZ4ff89X0eURZYcCIFMJ6r9Wqk2Ikf/REf3xM286KdqGbX+EhtdVRs7tr5MZASEDXNxh/HupccC1AaZGoqg7ECy0OIEhfKaC3Ibi1z+ogpL+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAABASAA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHhwEEFgAUhdE1N/LiZUBaNNuvqePdoB+4IwgAAAA=";
PSBT.fromString(psbt);
PSBT.fromString(Network.BITCOIN, psbt);
}
@Test(expected = PSBTParseException.class)
public void noTransactionOnlyInputs() throws PSBTParseException {
String psbt = "cHNidP8AAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAA==";
PSBT.fromString(psbt);
PSBT.fromString(Network.BITCOIN, psbt);
}
@Test(expected = PSBTParseException.class)
public void duplicateInputKeys() throws PSBTParseException {
String psbt = "cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAQA/AgAAAAH//////////////////////////////////////////wAAAAAA/////wEAAAAAAAAAAANqAQAAAAAAAAAA";
PSBT.fromString(psbt);
PSBT.fromString(Network.BITCOIN, psbt);
}
@Test(expected = PSBTParseException.class)
public void invalidGlobalTransactionKeyType() throws PSBTParseException {
String psbt = "cHNidP8CAAFVAgAAAAEnmiMjpd+1H8RfIg+liw/BPh4zQnkqhdfjbNYzO1y8OQAAAAAA/////wGgWuoLAAAAABl2qRT/6cAGEJfMO2NvLLBGD6T8Qn0rRYisAAAAAAABASCVXuoLAAAAABepFGNFIA9o0YnhrcDfHE0W6o8UwNvrhyICA7E0HMunaDtq9PEjjNbpfnFn1Wn6xH8eSNR1QYRDVb1GRjBDAiAEJLWO/6qmlOFVnqXJO7/UqJBkIkBVzfBwtncUaUQtBwIfXI6w/qZRbWC4rLM61k7eYOh4W/s6qUuZvfhhUduamgEBBCIAIHcf0YrUWWZt1J89Vk49vEL0yEd042CtoWgWqO1IjVaBAQVHUiEDsTQcy6doO2r08SOM1ul+cWfVafrEfx5I1HVBhENVvUYhA95V0eHayAXj+KWMH7+blMAvPbqv4Sf+/KSZXyb4IIO9Uq4iBgOxNBzLp2g7avTxI4zW6X5xZ9Vp+sR/HkjUdUGEQ1W9RhC0prpnAAAAgAAAAIAEAACAIgYD3lXR4drIBeP4pYwfv5uUwC89uq/hJ/78pJlfJvggg70QtKa6ZwAAAIAAAACABQAAgAAA";
PSBT.fromString(psbt);
PSBT.fromString(Network.BITCOIN, psbt);
}
@Test(expected = PSBTParseException.class)
public void invalidInputWitnessUtxoKeyType() throws PSBTParseException {
String psbt = "cHNidP8BAFUCAAAAASeaIyOl37UfxF8iD6WLD8E+HjNCeSqF1+Ns1jM7XLw5AAAAAAD/////AaBa6gsAAAAAGXapFP/pwAYQl8w7Y28ssEYPpPxCfStFiKwAAAAAAAIBACCVXuoLAAAAABepFGNFIA9o0YnhrcDfHE0W6o8UwNvrhyICA7E0HMunaDtq9PEjjNbpfnFn1Wn6xH8eSNR1QYRDVb1GRjBDAiAEJLWO/6qmlOFVnqXJO7/UqJBkIkBVzfBwtncUaUQtBwIfXI6w/qZRbWC4rLM61k7eYOh4W/s6qUuZvfhhUduamgEBBCIAIHcf0YrUWWZt1J89Vk49vEL0yEd042CtoWgWqO1IjVaBAQVHUiEDsTQcy6doO2r08SOM1ul+cWfVafrEfx5I1HVBhENVvUYhA95V0eHayAXj+KWMH7+blMAvPbqv4Sf+/KSZXyb4IIO9Uq4iBgOxNBzLp2g7avTxI4zW6X5xZ9Vp+sR/HkjUdUGEQ1W9RhC0prpnAAAAgAAAAIAEAACAIgYD3lXR4drIBeP4pYwfv5uUwC89uq/hJ/78pJlfJvggg70QtKa6ZwAAAIAAAACABQAAgAAA";
PSBT.fromString(psbt);
PSBT.fromString(Network.BITCOIN, psbt);
}
@Test(expected = PSBTParseException.class)
public void invalidInputPartialSignatureKeyType() throws PSBTParseException {
String psbt = "cHNidP8BAFUCAAAAASeaIyOl37UfxF8iD6WLD8E+HjNCeSqF1+Ns1jM7XLw5AAAAAAD/////AaBa6gsAAAAAGXapFP/pwAYQl8w7Y28ssEYPpPxCfStFiKwAAAAAAAEBIJVe6gsAAAAAF6kUY0UgD2jRieGtwN8cTRbqjxTA2+uHIQIDsTQcy6doO2r08SOM1ul+cWfVafrEfx5I1HVBhENVvUYwQwIgBCS1jv+qppThVZ6lyTu/1KiQZCJAVc3wcLZ3FGlELQcCH1yOsP6mUW1guKyzOtZO3mDoeFv7OqlLmb34YVHbmpoBAQQiACB3H9GK1FlmbdSfPVZOPbxC9MhHdONgraFoFqjtSI1WgQEFR1IhA7E0HMunaDtq9PEjjNbpfnFn1Wn6xH8eSNR1QYRDVb1GIQPeVdHh2sgF4/iljB+/m5TALz26r+En/vykmV8m+CCDvVKuIgYDsTQcy6doO2r08SOM1ul+cWfVafrEfx5I1HVBhENVvUYQtKa6ZwAAAIAAAACABAAAgCIGA95V0eHayAXj+KWMH7+blMAvPbqv4Sf+/KSZXyb4IIO9ELSmumcAAACAAAAAgAUAAIAAAA==";
PSBT.fromString(psbt);
PSBT.fromString(Network.BITCOIN, psbt);
}
@Test(expected = PSBTParseException.class)
public void invalidInputRedeemScriptKeyType() throws PSBTParseException {
String psbt = "cHNidP8BAFUCAAAAASeaIyOl37UfxF8iD6WLD8E+HjNCeSqF1+Ns1jM7XLw5AAAAAAD/////AaBa6gsAAAAAGXapFP/pwAYQl8w7Y28ssEYPpPxCfStFiKwAAAAAAAEBIJVe6gsAAAAAF6kUY0UgD2jRieGtwN8cTRbqjxTA2+uHIgIDsTQcy6doO2r08SOM1ul+cWfVafrEfx5I1HVBhENVvUZGMEMCIAQktY7/qqaU4VWepck7v9SokGQiQFXN8HC2dxRpRC0HAh9cjrD+plFtYLisszrWTt5g6Hhb+zqpS5m9+GFR25qaAQIEACIAIHcf0YrUWWZt1J89Vk49vEL0yEd042CtoWgWqO1IjVaBAQVHUiEDsTQcy6doO2r08SOM1ul+cWfVafrEfx5I1HVBhENVvUYhA95V0eHayAXj+KWMH7+blMAvPbqv4Sf+/KSZXyb4IIO9Uq4iBgOxNBzLp2g7avTxI4zW6X5xZ9Vp+sR/HkjUdUGEQ1W9RhC0prpnAAAAgAAAAIAEAACAIgYD3lXR4drIBeP4pYwfv5uUwC89uq/hJ/78pJlfJvggg70QtKa6ZwAAAIAAAACABQAAgAAA";
PSBT.fromString(psbt);
PSBT.fromString(Network.BITCOIN, psbt);
}
@Test(expected = PSBTParseException.class)
public void invalidInputWitnessScriptKeyType() throws PSBTParseException {
String psbt = "cHNidP8BAFUCAAAAASeaIyOl37UfxF8iD6WLD8E+HjNCeSqF1+Ns1jM7XLw5AAAAAAD/////AaBa6gsAAAAAGXapFP/pwAYQl8w7Y28ssEYPpPxCfStFiKwAAAAAAAEBIJVe6gsAAAAAF6kUY0UgD2jRieGtwN8cTRbqjxTA2+uHIgIDsTQcy6doO2r08SOM1ul+cWfVafrEfx5I1HVBhENVvUZGMEMCIAQktY7/qqaU4VWepck7v9SokGQiQFXN8HC2dxRpRC0HAh9cjrD+plFtYLisszrWTt5g6Hhb+zqpS5m9+GFR25qaAQEEIgAgdx/RitRZZm3Unz1WTj28QvTIR3TjYK2haBao7UiNVoECBQBHUiEDsTQcy6doO2r08SOM1ul+cWfVafrEfx5I1HVBhENVvUYhA95V0eHayAXj+KWMH7+blMAvPbqv4Sf+/KSZXyb4IIO9Uq4iBgOxNBzLp2g7avTxI4zW6X5xZ9Vp+sR/HkjUdUGEQ1W9RhC0prpnAAAAgAAAAIAEAACAIgYD3lXR4drIBeP4pYwfv5uUwC89uq/hJ/78pJlfJvggg70QtKa6ZwAAAIAAAACABQAAgAAA";
PSBT.fromString(psbt);
PSBT.fromString(Network.BITCOIN, psbt);
}
@Test(expected = PSBTParseException.class)
public void invalidInputBip32KeyType() throws PSBTParseException {
String psbt = "cHNidP8BAFUCAAAAASeaIyOl37UfxF8iD6WLD8E+HjNCeSqF1+Ns1jM7XLw5AAAAAAD/////AaBa6gsAAAAAGXapFP/pwAYQl8w7Y28ssEYPpPxCfStFiKwAAAAAAAEBIJVe6gsAAAAAF6kUY0UgD2jRieGtwN8cTRbqjxTA2+uHIgIDsTQcy6doO2r08SOM1ul+cWfVafrEfx5I1HVBhENVvUZGMEMCIAQktY7/qqaU4VWepck7v9SokGQiQFXN8HC2dxRpRC0HAh9cjrD+plFtYLisszrWTt5g6Hhb+zqpS5m9+GFR25qaAQEEIgAgdx/RitRZZm3Unz1WTj28QvTIR3TjYK2haBao7UiNVoEBBUdSIQOxNBzLp2g7avTxI4zW6X5xZ9Vp+sR/HkjUdUGEQ1W9RiED3lXR4drIBeP4pYwfv5uUwC89uq/hJ/78pJlfJvggg71SriEGA7E0HMunaDtq9PEjjNbpfnFn1Wn6xH8eSNR1QYRDVb0QtKa6ZwAAAIAAAACABAAAgCIGA95V0eHayAXj+KWMH7+blMAvPbqv4Sf+/KSZXyb4IIO9ELSmumcAAACAAAAAgAUAAIAAAA==";
PSBT.fromString(psbt);
PSBT.fromString(Network.BITCOIN, psbt);
}
@Test(expected = PSBTParseException.class)
public void invalidInputNonWitnessUtxoKeyType() throws PSBTParseException {
String psbt = "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAIAALsCAAAAAarXOTEBi9JfhK5AC2iEi+CdtwbqwqwYKYur7nGrZW+LAAAAAEhHMEQCIFj2/HxqM+GzFUjUgcgmwBW9MBNarULNZ3kNq2bSrSQ7AiBKHO0mBMZzW2OT5bQWkd14sA8MWUL7n3UYVvqpOBV9ugH+////AoDw+gIAAAAAF6kUD7lGNCFpa4LIM68kHHjBfdveSTSH0PIKJwEAAAAXqRQpynT4oI+BmZQoGFyXtdhS5AY/YYdlAAAAAQfaAEcwRAIgdAGK1BgAl7hzMjwAFXILNoTMgSOJEEjn282bVa1nnJkCIHPTabdA4+tT3O+jOCPIBwUUylWn3ZVE8VfBZ5EyYRGMAUgwRQIhAPYQOLMI3B2oZaNIUnRvAVdyk0IIxtJEVDk82ZvfIhd3AiAFbmdaZ1ptCgK4WxTl4pB02KJam1dgvqKBb2YZEKAG6gFHUiEClYO/Oa4KYJdHrRma3dY0+mEIVZ1sXNObTCGD8auW4H8hAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXUq4AAQEgAMLrCwAAAAAXqRS39fr0Dj1ApaRZsds1NfK3L6kh6IcBByMiACCMI1MXN0O1ld+0oHtyuo5C43l9p06H/n2ddJfjsgKJAwEI2gQARzBEAiBi63pVYQenxz9FrEq1od3fb3B1+xJ1lpp/OD7/94S8sgIgDAXbt0cNvy8IVX3TVscyXB7TCRPpls04QJRdsSIo2l8BRzBEAiBl9FulmYtZon/+GnvtAWrx8fkNVLOqj3RQql9WolEDvQIgf3JHA60e25ZoCyhLVtT/y4j3+3Weq74IqjDym4UTg9IBR1IhAwidwQx6xttU+RMpr2FzM9s4jOrQwjH3IzedG5kDCwLcIQI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8Oc1KuACICA6mkw39ZltOqJdusa1cK8GUDlEkpQkYLNUdT7Z7spYdxENkMak8AAACAAAAAgAQAAIAAIgICf2OZdX0u/1WhNq0CxoSxg4tlVuXxtrNCgqlLa1AFEJYQ2QxqTwAAAIAAAACABQAAgAA=";
PSBT.fromString(psbt);
PSBT.fromString(Network.BITCOIN, psbt);
}
@Test(expected = PSBTParseException.class)
public void invalidInputFinalScriptSigKeyType() throws PSBTParseException {
String psbt = "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAACBwDaAEcwRAIgdAGK1BgAl7hzMjwAFXILNoTMgSOJEEjn282bVa1nnJkCIHPTabdA4+tT3O+jOCPIBwUUylWn3ZVE8VfBZ5EyYRGMAUgwRQIhAPYQOLMI3B2oZaNIUnRvAVdyk0IIxtJEVDk82ZvfIhd3AiAFbmdaZ1ptCgK4WxTl4pB02KJam1dgvqKBb2YZEKAG6gFHUiEClYO/Oa4KYJdHrRma3dY0+mEIVZ1sXNObTCGD8auW4H8hAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXUq4AAQEgAMLrCwAAAAAXqRS39fr0Dj1ApaRZsds1NfK3L6kh6IcBByMiACCMI1MXN0O1ld+0oHtyuo5C43l9p06H/n2ddJfjsgKJAwEI2gQARzBEAiBi63pVYQenxz9FrEq1od3fb3B1+xJ1lpp/OD7/94S8sgIgDAXbt0cNvy8IVX3TVscyXB7TCRPpls04QJRdsSIo2l8BRzBEAiBl9FulmYtZon/+GnvtAWrx8fkNVLOqj3RQql9WolEDvQIgf3JHA60e25ZoCyhLVtT/y4j3+3Weq74IqjDym4UTg9IBR1IhAwidwQx6xttU+RMpr2FzM9s4jOrQwjH3IzedG5kDCwLcIQI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8Oc1KuACICA6mkw39ZltOqJdusa1cK8GUDlEkpQkYLNUdT7Z7spYdxENkMak8AAACAAAAAgAQAAIAAIgICf2OZdX0u/1WhNq0CxoSxg4tlVuXxtrNCgqlLa1AFEJYQ2QxqTwAAAIAAAACABQAAgAA=";
PSBT.fromString(psbt);
PSBT.fromString(Network.BITCOIN, psbt);
}
@Test(expected = PSBTParseException.class)
public void invalidInputFinalScriptWitnessKeyType() throws PSBTParseException {
String psbt = "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAABB9oARzBEAiB0AYrUGACXuHMyPAAVcgs2hMyBI4kQSOfbzZtVrWecmQIgc9Npt0Dj61Pc76M4I8gHBRTKVafdlUTxV8FnkTJhEYwBSDBFAiEA9hA4swjcHahlo0hSdG8BV3KTQgjG0kRUOTzZm98iF3cCIAVuZ1pnWm0KArhbFOXikHTYolqbV2C+ooFvZhkQoAbqAUdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSrgABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohwEHIyIAIIwjUxc3Q7WV37Sge3K6jkLjeX2nTof+fZ10l+OyAokDAggA2gQARzBEAiBi63pVYQenxz9FrEq1od3fb3B1+xJ1lpp/OD7/94S8sgIgDAXbt0cNvy8IVX3TVscyXB7TCRPpls04QJRdsSIo2l8BRzBEAiBl9FulmYtZon/+GnvtAWrx8fkNVLOqj3RQql9WolEDvQIgf3JHA60e25ZoCyhLVtT/y4j3+3Weq74IqjDym4UTg9IBR1IhAwidwQx6xttU+RMpr2FzM9s4jOrQwjH3IzedG5kDCwLcIQI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8Oc1KuACICA6mkw39ZltOqJdusa1cK8GUDlEkpQkYLNUdT7Z7spYdxENkMak8AAACAAAAAgAQAAIAAIgICf2OZdX0u/1WhNq0CxoSxg4tlVuXxtrNCgqlLa1AFEJYQ2QxqTwAAAIAAAACABQAAgAA=";
PSBT.fromString(psbt);
PSBT.fromString(Network.BITCOIN, psbt);
}
@Test(expected = PSBTParseException.class)
public void invalidOutputBip32PubKey() throws PSBTParseException {
String psbt = "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAABB9oARzBEAiB0AYrUGACXuHMyPAAVcgs2hMyBI4kQSOfbzZtVrWecmQIgc9Npt0Dj61Pc76M4I8gHBRTKVafdlUTxV8FnkTJhEYwBSDBFAiEA9hA4swjcHahlo0hSdG8BV3KTQgjG0kRUOTzZm98iF3cCIAVuZ1pnWm0KArhbFOXikHTYolqbV2C+ooFvZhkQoAbqAUdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSrgABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohwEHIyIAIIwjUxc3Q7WV37Sge3K6jkLjeX2nTof+fZ10l+OyAokDAQjaBABHMEQCIGLrelVhB6fHP0WsSrWh3d9vcHX7EnWWmn84Pv/3hLyyAiAMBdu3Rw2/LwhVfdNWxzJcHtMJE+mWzThAlF2xIijaXwFHMEQCIGX0W6WZi1mif/4ae+0BavHx+Q1Us6qPdFCqX1aiUQO9AiB/ckcDrR7blmgLKEtW1P/LiPf7dZ6rvgiqMPKbhROD0gFHUiEDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtwhAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zUq4AIQIDqaTDf1mW06ol26xrVwrwZQOUSSlCRgs1R1PtnuylhxDZDGpPAAAAgAAAAIAEAACAACICAn9jmXV9Lv9VoTatAsaEsYOLZVbl8bazQoKpS2tQBRCWENkMak8AAACAAAAAgAUAAIAA";
PSBT.fromString(psbt);
PSBT.fromString(Network.BITCOIN, psbt);
}
@Test(expected = PSBTParseException.class)
public void invalidInputSigHashKeyType() throws PSBTParseException {
String psbt = "cHNidP8BAHMCAAAAATAa6YblFqHsisW0vGVz0y+DtGXiOtdhZ9aLOOcwtNvbAAAAAAD/////AnR7AQAAAAAAF6kUA6oXrogrXQ1Usl1jEE5P/s57nqKHYEOZOwAAAAAXqRS5IbG6b3IuS/qDtlV6MTmYakLsg4cAAAAAAAEBHwDKmjsAAAAAFgAU0tlLZK4IWH7vyO6xh8YB6Tn5A3wCAwABAAAAAAEAFgAUYunpgv/zTdgjlhAxawkM0qO3R8sAAQAiACCHa62DLx0WgBXtQSMqnqZaGBXZ7xPA74dZ9ktbKyeKZQEBJVEhA7fOI6AcW0vwCmQlN836uzFbZoMyhnR471EwnSvVf4qHUa4A";
PSBT.fromString(psbt);
PSBT.fromString(Network.BITCOIN, psbt);
}
@Test(expected = PSBTParseException.class)
public void invalidOutputRedeemScriptKeyType() throws PSBTParseException {
String psbt = "cHNidP8BAHMCAAAAATAa6YblFqHsisW0vGVz0y+DtGXiOtdhZ9aLOOcwtNvbAAAAAAD/////AnR7AQAAAAAAF6kUA6oXrogrXQ1Usl1jEE5P/s57nqKHYEOZOwAAAAAXqRS5IbG6b3IuS/qDtlV6MTmYakLsg4cAAAAAAAEBHwDKmjsAAAAAFgAU0tlLZK4IWH7vyO6xh8YB6Tn5A3wAAgAAFgAUYunpgv/zTdgjlhAxawkM0qO3R8sAAQAiACCHa62DLx0WgBXtQSMqnqZaGBXZ7xPA74dZ9ktbKyeKZQEBJVEhA7fOI6AcW0vwCmQlN836uzFbZoMyhnR471EwnSvVf4qHUa4A";
PSBT.fromString(psbt);
PSBT.fromString(Network.BITCOIN, psbt);
}
@Test(expected = PSBTParseException.class)
public void invalidOutputWitnessScriptKeyType() throws PSBTParseException {
String psbt = "cHNidP8BAHMCAAAAATAa6YblFqHsisW0vGVz0y+DtGXiOtdhZ9aLOOcwtNvbAAAAAAD/////AnR7AQAAAAAAF6kUA6oXrogrXQ1Usl1jEE5P/s57nqKHYEOZOwAAAAAXqRS5IbG6b3IuS/qDtlV6MTmYakLsg4cAAAAAAAEBHwDKmjsAAAAAFgAU0tlLZK4IWH7vyO6xh8YB6Tn5A3wAAQAWABRi6emC//NN2COWEDFrCQzSo7dHywABACIAIIdrrYMvHRaAFe1BIyqeploYFdnvE8Dvh1n2S1srJ4plIQEAJVEhA7fOI6AcW0vwCmQlN836uzFbZoMyhnR471EwnQbVf4qHUa4A";
PSBT.fromString(psbt);
PSBT.fromString(Network.BITCOIN, psbt);
}
@Test
public void validP2pkhOneInputEmptyOutputs() throws PSBTParseException, NonStandardScriptException {
String psbt = "cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAAAA";
PSBT psbt1 = PSBT.fromString(psbt);
PSBT psbt1 = PSBT.fromString(Network.BITCOIN, psbt);
Assert.assertEquals(1, psbt1.getPsbtInputs().size());
Assert.assertEquals(2, psbt1.getPsbtOutputs().size());
@ -133,11 +133,11 @@ public class PSBTTest {
Assert.assertEquals(4294967294L, psbt1.getTransaction().getInputs().get(0).getSequenceNumber());
Assert.assertEquals(99999699L, psbt1.getTransaction().getOutputs().get(0).getValue());
Assert.assertEquals("1L2tGENeoh4mSoiUZrSbs1J3jazSdJH9QS", psbt1.getTransaction().getOutputs().get(0).getScript().getToAddresses()[0].toString());
Assert.assertEquals("1L2tGENeoh4mSoiUZrSbs1J3jazSdJH9QS", psbt1.getTransaction().getOutputs().get(0).getScript().getToAddresses(Network.BITCOIN)[0].toString());
Assert.assertEquals("76a914d0c59903c5bac2868760e90fd521a4665aa7652088ac", psbt1.getTransaction().getOutputs().get(0).getScript().getProgramAsHex());
Assert.assertEquals("OP_DUP OP_HASH160 d0c59903c5bac2868760e90fd521a4665aa76520 OP_EQUALVERIFY OP_CHECKSIG", psbt1.getTransaction().getOutputs().get(0).getScript().toString());
Assert.assertEquals(100000000L, psbt1.getTransaction().getOutputs().get(1).getValue());
Assert.assertEquals("36YhUacEtcnkfhSbxwm11wDCexLGBLgJF6", psbt1.getTransaction().getOutputs().get(1).getScript().getToAddresses()[0].toString());
Assert.assertEquals("36YhUacEtcnkfhSbxwm11wDCexLGBLgJF6", psbt1.getTransaction().getOutputs().get(1).getScript().getToAddresses(Network.BITCOIN)[0].toString());
Assert.assertEquals("a9143545e6e33b832c47050f24d3eeb93c9c03948bc787", psbt1.getTransaction().getOutputs().get(1).getScript().getProgramAsHex());
Assert.assertEquals("OP_HASH160 3545e6e33b832c47050f24d3eeb93c9c03948bc7 OP_EQUAL", psbt1.getTransaction().getOutputs().get(1).getScript().toString());
@ -158,7 +158,7 @@ public class PSBTTest {
@Test
public void validP2pkhP2shP2wpkhOneInputEmptyOutputs() throws PSBTParseException {
String psbt = "cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEHakcwRAIgR1lmF5fAGwNrJZKJSGhiGDR9iYZLcZ4ff89X0eURZYcCIFMJ6r9Wqk2Ikf/REf3xM286KdqGbX+EhtdVRs7tr5MZASEDXNxh/HupccC1AaZGoqg7ECy0OIEhfKaC3Ibi1z+ogpIAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIAAAA";
PSBT psbt1 = PSBT.fromString(psbt);
PSBT psbt1 = PSBT.fromString(Network.BITCOIN, psbt);
Assert.assertEquals(2, psbt1.getPsbtInputs().size());
Assert.assertEquals(2, psbt1.getPsbtOutputs().size());
@ -170,7 +170,7 @@ public class PSBTTest {
@Test
public void validP2pkhWithSigHash() throws PSBTParseException {
String psbt = "cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAQMEAQAAAAAAAA==";
PSBT psbt1 = PSBT.fromString(psbt);
PSBT psbt1 = PSBT.fromString(Network.BITCOIN, psbt);
Assert.assertEquals(SigHash.ALL, psbt1.getPsbtInputs().get(0).getSigHash());
Assert.assertEquals(301L, psbt1.getFee().longValue());
}
@ -178,7 +178,7 @@ public class PSBTTest {
@Test
public void validP2pkhP2shP2wpkhTwoInputsTwoOutputs() throws PSBTParseException {
String psbt = "cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEA3wIAAAABJoFxNx7f8oXpN63upLN7eAAMBWbLs61kZBcTykIXG/YAAAAAakcwRAIgcLIkUSPmv0dNYMW1DAQ9TGkaXSQ18Jo0p2YqncJReQoCIAEynKnazygL3zB0DsA5BCJCLIHLRYOUV663b8Eu3ZWzASECZX0RjTNXuOD0ws1G23s59tnDjZpwq8ubLeXcjb/kzjH+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIACICAurVlmh8qAYEPtw94RbN8p1eklfBls0FXPaYyNAr8k6ZELSmumcAAACAAAAAgAIAAIAAIgIDlPYr6d8ZlSxVh3aK63aYBhrSxKJciU9H2MFitNchPQUQtKa6ZwAAAIABAACAAgAAgAA=";
PSBT psbt1 = PSBT.fromString(psbt);
PSBT psbt1 = PSBT.fromString(Network.BITCOIN, psbt);
Assert.assertEquals("001485d13537f2e265405a34dbafa9e3dda01fb82308", psbt1.getPsbtInputs().get(1).getRedeemScript().getProgramAsHex());
Assert.assertEquals("b4a6ba67", psbt1.getPsbtOutputs().get(0).getDerivedPublicKeys().values().iterator().next().getMasterFingerprint());
@ -188,7 +188,7 @@ public class PSBTTest {
@Test
public void validP2shP2wpkhMultisigPartialSignature() throws PSBTParseException {
String psbt = "cHNidP8BAFUCAAAAASeaIyOl37UfxF8iD6WLD8E+HjNCeSqF1+Ns1jM7XLw5AAAAAAD/////AaBa6gsAAAAAGXapFP/pwAYQl8w7Y28ssEYPpPxCfStFiKwAAAAAAAEBIJVe6gsAAAAAF6kUY0UgD2jRieGtwN8cTRbqjxTA2+uHIgIDsTQcy6doO2r08SOM1ul+cWfVafrEfx5I1HVBhENVvUZGMEMCIAQktY7/qqaU4VWepck7v9SokGQiQFXN8HC2dxRpRC0HAh9cjrD+plFtYLisszrWTt5g6Hhb+zqpS5m9+GFR25qaAQEEIgAgdx/RitRZZm3Unz1WTj28QvTIR3TjYK2haBao7UiNVoEBBUdSIQOxNBzLp2g7avTxI4zW6X5xZ9Vp+sR/HkjUdUGEQ1W9RiED3lXR4drIBeP4pYwfv5uUwC89uq/hJ/78pJlfJvggg71SriIGA7E0HMunaDtq9PEjjNbpfnFn1Wn6xH8eSNR1QYRDVb1GELSmumcAAACAAAAAgAQAAIAiBgPeVdHh2sgF4/iljB+/m5TALz26r+En/vykmV8m+CCDvRC0prpnAAAAgAAAAIAFAACAAAA=";
PSBT psbt1 = PSBT.fromString(psbt);
PSBT psbt1 = PSBT.fromString(Network.BITCOIN, psbt);
Assert.assertEquals("0020771fd18ad459666dd49f3d564e3dbc42f4c84774e360ada16816a8ed488d5681", psbt1.getPsbtInputs().get(0).getRedeemScript().getProgramAsHex());
Assert.assertEquals("522103b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd462103de55d1e1dac805e3f8a58c1fbf9b94c02f3dbaafe127fefca4995f26f82083bd52ae", psbt1.getPsbtInputs().get(0).getWitnessScript().getProgramAsHex());
@ -198,7 +198,7 @@ public class PSBTTest {
@Test
public void validP2wshMultisigWithXpubs() throws PSBTParseException {
String psbt = "cHNidP8BAFICAAAAAZ38ZijCbFiZ/hvT3DOGZb/VXXraEPYiCXPfLTht7BJ2AQAAAAD/////AfA9zR0AAAAAFgAUezoAv9wU0neVwrdJAdCdpu8TNXkAAAAATwEENYfPAto/0AiAAAAAlwSLGtBEWx7IJ1UXcnyHtOTrwYogP/oPlMAVZr046QADUbdDiH7h1A3DKmBDck8tZFmztaTXPa7I+64EcvO8Q+IM2QxqT64AAIAAAACATwEENYfPAto/0AiAAAABuQRSQnE5zXjCz/JES+NTzVhgXj5RMoXlKLQH+uP2FzUD0wpel8itvFV9rCrZp+OcFyLrrGnmaLbyZnzB1nHIPKsM2QxqT64AAIABAACAAAEBKwBlzR0AAAAAIgAgLFSGEmxJeAeagU4TcV1l82RZ5NbMre0mbQUIZFuvpjIBBUdSIQKdoSzbWyNWkrkVNq/v5ckcOrlHPY5DtTODarRWKZyIcSEDNys0I07Xz5wf6l0F1EFVeSe+lUKxYusC4ass6AIkwAtSriIGAp2hLNtbI1aSuRU2r+/lyRw6uUc9jkO1M4NqtFYpnIhxENkMak+uAACAAAAAgAAAAAAiBgM3KzQjTtfPnB/qXQXUQVV5J76VQrFi6wLhqyzoAiTACxDZDGpPrgAAgAEAAIAAAAAAACICA57/H1R6HV+S36K6evaslxpL0DukpzSwMVaiVritOh75EO3kXMUAAACAAAAAgAEAAIAA";
PSBT psbt1 = PSBT.fromString(psbt);
PSBT psbt1 = PSBT.fromString(Network.BITCOIN, psbt);
Assert.assertEquals("00202c5486126c4978079a814e13715d65f36459e4d6ccaded266d0508645bafa632", psbt1.getPsbtInputs().get(0).getWitnessUtxo().getScript().getProgramAsHex());
Assert.assertEquals("5221029da12cdb5b235692b91536afefe5c91c3ab9473d8e43b533836ab456299c88712103372b34234ed7cf9c1fea5d05d441557927be9542b162eb02e1ab2ce80224c00b52ae", psbt1.getPsbtInputs().get(0).getWitnessScript().getProgramAsHex());
@ -207,7 +207,7 @@ public class PSBTTest {
@Test
public void validUnknownInputs() throws PSBTParseException {
String psbt = "cHNidP8BAD8CAAAAAf//////////////////////////////////////////AAAAAAD/////AQAAAAAAAAAAA2oBAAAAAAAACg8BAgMEBQYHCAkPAQIDBAUGBwgJCgsMDQ4PAAA=";
PSBT psbt1 = PSBT.fromString(psbt);
PSBT psbt1 = PSBT.fromString(Network.BITCOIN, psbt);
Assert.assertEquals(1, psbt1.getPsbtInputs().size());
}
@ -215,7 +215,7 @@ public class PSBTTest {
@Test
public void validP2wpkh2InputsWithXpub() throws PSBTParseException {
String psbt = "cHNidP8BAJ0BAAAAAnEOp2q0XFy2Q45gflnMA3YmmBgFrp4N/ZCJASq7C+U1AQAAAAD/////GQmU1qizyMgsy8+y+6QQaqBmObhyqNRHRlwNQliNbWcAAAAAAP////8CAOH1BQAAAAAZdqkUtrwsDuVlWoQ9ea/t0MzD991kNAmIrGBa9AUAAAAAFgAUEYjvjkzgRJ6qyPsUHL9aEXbmoIgAAAAATwEEiLIeA55TDKyAAAAAPbyKXJdp8DGxfnf+oVGGAyIaGP0Y8rmlTGyMGsdcvDUC8jBYSxVdHH8c1FEgplPEjWULQxtnxbLBPyfXFCA3wWkQJ1acUDEAAIAAAACAAAAAgAABAR8A4fUFAAAAABYAFDO5gvkbKPFgySC0q5XljOUN2jpKIgIDMJaA8zx9446mpHzU7NZvH1pJdHxv+4gI7QkDkkPjrVxHMEQCIC1wTO2DDFapCTRL10K2hS3M0QPpY7rpLTjnUlTSu0JFAiAthsQ3GV30bAztoITyopHD2i1kBw92v5uQsZXn7yj3cgEiBgMwloDzPH3jjqakfNTs1m8fWkl0fG/7iAjtCQOSQ+OtXBgnVpxQMQAAgAAAAIAAAACAAAAAAAEAAAAAAQEfAOH1BQAAAAAWABQ4j7lEMH63fvRRl9CwskXgefAR3iICAsd3Fh9z0LfHK57nveZQKT0T8JW8dlatH1Jdpf0uELEQRzBEAiBMsftfhpyULg4mEAV2ElQ5F5rojcqKncO6CPeVOYj6pgIgUh9JynkcJ9cOJzybFGFphZCTYeJb4nTqIA1+CIJ+UU0BIgYCx3cWH3PQt8crnue95lApPRPwlbx2Vq0fUl2l/S4QsRAYJ1acUDEAAIAAAACAAAAAgAAAAAAAAAAAAAAiAgLSDKUC7iiWhtIYFb1DqAY3sGmOH7zb5MrtRF9sGgqQ7xgnVpxQMQAAgAAAAIAAAACAAAAAAAQAAAAA";
PSBT psbt1 = PSBT.fromString(psbt);
PSBT psbt1 = PSBT.fromString(Network.BITCOIN, psbt);
ExtendedKey extendedPublicKey = psbt1.getExtendedPublicKeys().get(0);
KeyDerivation keyDerivation = psbt1.getKeyDerivation(extendedPublicKey);
@ -227,31 +227,31 @@ public class PSBTTest {
@Test(expected = PSBTParseException.class)
public void invalidWitnessUtxoForNonWitnessInput() throws PSBTParseException {
String psbt = "cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEBItPf9QUAAAAAGXapFNSO0xELlAFMsRS9Mtb00GbcdCVriKwAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIACICAurVlmh8qAYEPtw94RbN8p1eklfBls0FXPaYyNAr8k6ZELSmumcAAACAAAAAgAIAAIAAIgIDlPYr6d8ZlSxVh3aK63aYBhrSxKJciU9H2MFitNchPQUQtKa6ZwAAAIABAACAAgAAgAA=";
PSBT psbt1 = PSBT.fromString(psbt);
PSBT psbt1 = PSBT.fromString(Network.BITCOIN, psbt);
}
@Test(expected = PSBTParseException.class)
public void invalidNonWitnessUtxoDoesNotMatchRedeemScriptPubKey() throws PSBTParseException {
String psbt = "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU210gwRQIhAPYQOLMI3B2oZaNIUnRvAVdyk0IIxtJEVDk82ZvfIhd3AiAFbmdaZ1ptCgK4WxTl4pB02KJam1dgvqKBb2YZEKAG6gEBAwQBAAAAAQRHUiEClYO/Oa4KYJdHrRma3dY0+mEIVZ1sXNObTCGD8auW4H8hAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXUq8iBgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfxDZDGpPAAAAgAAAAIAAAACAIgYC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtcQ2QxqTwAAAIAAAACAAQAAgAABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohyICAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zRzBEAiBl9FulmYtZon/+GnvtAWrx8fkNVLOqj3RQql9WolEDvQIgf3JHA60e25ZoCyhLVtT/y4j3+3Weq74IqjDym4UTg9IBAQMEAQAAAAEEIgAgjCNTFzdDtZXftKB7crqOQuN5fadOh/59nXSX47ICiQMBBUdSIQMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3CECOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNSriIGAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zENkMak8AAACAAAAAgAMAAIAiBgMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3BDZDGpPAAAAgAAAAIACAACAACICA6mkw39ZltOqJdusa1cK8GUDlEkpQkYLNUdT7Z7spYdxENkMak8AAACAAAAAgAQAAIAAIgICf2OZdX0u/1WhNq0CxoSxg4tlVuXxtrNCgqlLa1AFEJYQ2QxqTwAAAIAAAACABQAAgAA=";
PSBT psbt1 = PSBT.fromString(psbt);
PSBT psbt1 = PSBT.fromString(Network.BITCOIN, psbt);
}
@Test(expected = PSBTParseException.class)
public void invalidWitnessUtxoDoesNotMatchRedeemScriptPubKey() throws PSBTParseException {
String psbt = "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU210gwRQIhAPYQOLMI3B2oZaNIUnRvAVdyk0IIxtJEVDk82ZvfIhd3AiAFbmdaZ1ptCgK4WxTl4pB02KJam1dgvqKBb2YZEKAG6gEBAwQBAAAAAQRHUiEClYO/Oa4KYJdHrRma3dY0+mEIVZ1sXNObTCGD8auW4H8hAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXUq4iBgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfxDZDGpPAAAAgAAAAIAAAACAIgYC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtcQ2QxqTwAAAIAAAACAAQAAgAABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohyICAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zRzBEAiBl9FulmYtZon/+GnvtAWrx8fkNVLOqj3RQql9WolEDvQIgf3JHA60e25ZoCyhLVtT/y4j3+3Weq74IqjDym4UTg9IBAQMEAQAAAAEEIgAgjCNTFzdDtZXftKB7crqOQuN5fadOh/59nXSX47ICiQABBUdSIQMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3CECOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNSriIGAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zENkMak8AAACAAAAAgAMAAIAiBgMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3BDZDGpPAAAAgAAAAIACAACAACICA6mkw39ZltOqJdusa1cK8GUDlEkpQkYLNUdT7Z7spYdxENkMak8AAACAAAAAgAQAAIAAIgICf2OZdX0u/1WhNq0CxoSxg4tlVuXxtrNCgqlLa1AFEJYQ2QxqTwAAAIAAAACABQAAgAA=";
PSBT psbt1 = PSBT.fromString(psbt);
PSBT psbt1 = PSBT.fromString(Network.BITCOIN, psbt);
}
@Test(expected = PSBTParseException.class)
public void invalidWitnessUtxoDoesNotMatchWitnessScriptPubKey() throws PSBTParseException {
String psbt = "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU210gwRQIhAPYQOLMI3B2oZaNIUnRvAVdyk0IIxtJEVDk82ZvfIhd3AiAFbmdaZ1ptCgK4WxTl4pB02KJam1dgvqKBb2YZEKAG6gEBAwQBAAAAAQRHUiEClYO/Oa4KYJdHrRma3dY0+mEIVZ1sXNObTCGD8auW4H8hAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXUq4iBgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfxDZDGpPAAAAgAAAAIAAAACAIgYC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtcQ2QxqTwAAAIAAAACAAQAAgAABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohyICAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zRzBEAiBl9FulmYtZon/+GnvtAWrx8fkNVLOqj3RQql9WolEDvQIgf3JHA60e25ZoCyhLVtT/y4j3+3Weq74IqjDym4UTg9IBAQMEAQAAAAEEIgAgjCNTFzdDtZXftKB7crqOQuN5fadOh/59nXSX47ICiQMBBUdSIQMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3CECOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNSrSIGAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zENkMak8AAACAAAAAgAMAAIAiBgMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3BDZDGpPAAAAgAAAAIACAACAACICA6mkw39ZltOqJdusa1cK8GUDlEkpQkYLNUdT7Z7spYdxENkMak8AAACAAAAAgAQAAIAAIgICf2OZdX0u/1WhNq0CxoSxg4tlVuXxtrNCgqlLa1AFEJYQ2QxqTwAAAIAAAACABQAAgAA=";
PSBT psbt1 = PSBT.fromString(psbt);
PSBT psbt1 = PSBT.fromString(Network.BITCOIN, psbt);
}
@Test
public void validCreatorTwoInputsTwoOutputs() throws PSBTParseException {
String psbt = "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAAAAAA=";
PSBT psbt1 = PSBT.fromString(psbt);
PSBT psbt1 = PSBT.fromString(Network.BITCOIN, psbt);
Assert.assertEquals(2, psbt1.getPsbtInputs().size());
Assert.assertEquals(2, psbt1.getPsbtOutputs().size());
@ -260,7 +260,7 @@ public class PSBTTest {
@Test
public void validUpdaterTwoInputsTwoOutputs() throws PSBTParseException {
String psbt = "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAABAwQBAAAAAQRHUiEClYO/Oa4KYJdHrRma3dY0+mEIVZ1sXNObTCGD8auW4H8hAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXUq4iBgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfxDZDGpPAAAAgAAAAIAAAACAIgYC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtcQ2QxqTwAAAIAAAACAAQAAgAABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohwEDBAEAAAABBCIAIIwjUxc3Q7WV37Sge3K6jkLjeX2nTof+fZ10l+OyAokDAQVHUiEDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtwhAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zUq4iBgI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8OcxDZDGpPAAAAgAAAAIADAACAIgYDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtwQ2QxqTwAAAIAAAACAAgAAgAAiAgOppMN/WZbTqiXbrGtXCvBlA5RJKUJGCzVHU+2e7KWHcRDZDGpPAAAAgAAAAIAEAACAACICAn9jmXV9Lv9VoTatAsaEsYOLZVbl8bazQoKpS2tQBRCWENkMak8AAACAAAAAgAUAAIAA";
PSBT psbt1 = PSBT.fromString(psbt);
PSBT psbt1 = PSBT.fromString(Network.BITCOIN, psbt);
Assert.assertEquals("75ddabb27b8845f5247975c8a5ba7c6f336c4570708ebe230caf6db5217ae858", psbt1.getPsbtInputs().get(0).getNonWitnessUtxo().getTxId().toString());
Assert.assertEquals(null, psbt1.getPsbtInputs().get(0).getWitnessUtxo());
@ -269,7 +269,7 @@ public class PSBTTest {
@Test
public void validSignerTwoInputsTwoOutputs() throws PSBTParseException {
String psbt = "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU210gwRQIhAPYQOLMI3B2oZaNIUnRvAVdyk0IIxtJEVDk82ZvfIhd3AiAFbmdaZ1ptCgK4WxTl4pB02KJam1dgvqKBb2YZEKAG6gEBAwQBAAAAAQRHUiEClYO/Oa4KYJdHrRma3dY0+mEIVZ1sXNObTCGD8auW4H8hAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXUq4iBgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfxDZDGpPAAAAgAAAAIAAAACAIgYC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtcQ2QxqTwAAAIAAAACAAQAAgAABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohyICAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zRzBEAiBl9FulmYtZon/+GnvtAWrx8fkNVLOqj3RQql9WolEDvQIgf3JHA60e25ZoCyhLVtT/y4j3+3Weq74IqjDym4UTg9IBAQMEAQAAAAEEIgAgjCNTFzdDtZXftKB7crqOQuN5fadOh/59nXSX47ICiQMBBUdSIQMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3CECOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNSriIGAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zENkMak8AAACAAAAAgAMAAIAiBgMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3BDZDGpPAAAAgAAAAIACAACAACICA6mkw39ZltOqJdusa1cK8GUDlEkpQkYLNUdT7Z7spYdxENkMak8AAACAAAAAgAQAAIAAIgICf2OZdX0u/1WhNq0CxoSxg4tlVuXxtrNCgqlLa1AFEJYQ2QxqTwAAAIAAAACABQAAgAA=";
PSBT psbt1 = PSBT.fromString(psbt);
PSBT psbt1 = PSBT.fromString(Network.BITCOIN, psbt);
Assert.assertEquals("3044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d201", Hex.toHexString(psbt1.getPsbtInputs().get(1).getPartialSignatures().values().iterator().next().encodeToBitcoin()));
}
@ -277,7 +277,7 @@ public class PSBTTest {
@Test
public void validCombinerTwoInputsTwoOutputs() throws PSBTParseException {
String psbt = "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgf0cwRAIgdAGK1BgAl7hzMjwAFXILNoTMgSOJEEjn282bVa1nnJkCIHPTabdA4+tT3O+jOCPIBwUUylWn3ZVE8VfBZ5EyYRGMASICAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXSDBFAiEA9hA4swjcHahlo0hSdG8BV3KTQgjG0kRUOTzZm98iF3cCIAVuZ1pnWm0KArhbFOXikHTYolqbV2C+ooFvZhkQoAbqAQEDBAEAAAABBEdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSriIGApWDvzmuCmCXR60Zmt3WNPphCFWdbFzTm0whg/GrluB/ENkMak8AAACAAAAAgAAAAIAiBgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU21xDZDGpPAAAAgAAAAIABAACAAAEBIADC6wsAAAAAF6kUt/X69A49QKWkWbHbNTXyty+pIeiHIgIDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtxHMEQCIGLrelVhB6fHP0WsSrWh3d9vcHX7EnWWmn84Pv/3hLyyAiAMBdu3Rw2/LwhVfdNWxzJcHtMJE+mWzThAlF2xIijaXwEiAgI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8Oc0cwRAIgZfRbpZmLWaJ//hp77QFq8fH5DVSzqo90UKpfVqJRA70CIH9yRwOtHtuWaAsoS1bU/8uI9/t1nqu+CKow8puFE4PSAQEDBAEAAAABBCIAIIwjUxc3Q7WV37Sge3K6jkLjeX2nTof+fZ10l+OyAokDAQVHUiEDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtwhAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zUq4iBgI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8OcxDZDGpPAAAAgAAAAIADAACAIgYDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtwQ2QxqTwAAAIAAAACAAgAAgAAiAgOppMN/WZbTqiXbrGtXCvBlA5RJKUJGCzVHU+2e7KWHcRDZDGpPAAAAgAAAAIAEAACAACICAn9jmXV9Lv9VoTatAsaEsYOLZVbl8bazQoKpS2tQBRCWENkMak8AAACAAAAAgAUAAIAA";
PSBT psbt1 = PSBT.fromString(psbt);
PSBT psbt1 = PSBT.fromString(Network.BITCOIN, psbt);
Assert.assertEquals("3044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01", Hex.toHexString(psbt1.getPsbtInputs().get(1).getPartialSignatures().values().iterator().next().encodeToBitcoin()));
}
@ -285,7 +285,7 @@ public class PSBTTest {
@Test
public void validFinalizerTwoInputsTwoOutputs() throws PSBTParseException {
String psbt = "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAABB9oARzBEAiB0AYrUGACXuHMyPAAVcgs2hMyBI4kQSOfbzZtVrWecmQIgc9Npt0Dj61Pc76M4I8gHBRTKVafdlUTxV8FnkTJhEYwBSDBFAiEA9hA4swjcHahlo0hSdG8BV3KTQgjG0kRUOTzZm98iF3cCIAVuZ1pnWm0KArhbFOXikHTYolqbV2C+ooFvZhkQoAbqAUdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSrgABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohwEHIyIAIIwjUxc3Q7WV37Sge3K6jkLjeX2nTof+fZ10l+OyAokDAQjaBABHMEQCIGLrelVhB6fHP0WsSrWh3d9vcHX7EnWWmn84Pv/3hLyyAiAMBdu3Rw2/LwhVfdNWxzJcHtMJE+mWzThAlF2xIijaXwFHMEQCIGX0W6WZi1mif/4ae+0BavHx+Q1Us6qPdFCqX1aiUQO9AiB/ckcDrR7blmgLKEtW1P/LiPf7dZ6rvgiqMPKbhROD0gFHUiEDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtwhAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zUq4AIgIDqaTDf1mW06ol26xrVwrwZQOUSSlCRgs1R1Ptnuylh3EQ2QxqTwAAAIAAAACABAAAgAAiAgJ/Y5l1fS7/VaE2rQLGhLGDi2VW5fG2s0KCqUtrUAUQlhDZDGpPAAAAgAAAAIAFAACAAA==";
PSBT psbt1 = PSBT.fromString(psbt);
PSBT psbt1 = PSBT.fromString(Network.BITCOIN, psbt);
Assert.assertEquals("00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae", psbt1.getPsbtInputs().get(0).getFinalScriptSig().getProgramAsHex());
Assert.assertEquals("2200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903", psbt1.getPsbtInputs().get(1).getFinalScriptSig().getProgramAsHex());
@ -295,19 +295,19 @@ public class PSBTTest {
@Test
public void serializeRoundTrip() throws PSBTParseException {
String psbtStr1 = "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAABB9oARzBEAiB0AYrUGACXuHMyPAAVcgs2hMyBI4kQSOfbzZtVrWecmQIgc9Npt0Dj61Pc76M4I8gHBRTKVafdlUTxV8FnkTJhEYwBSDBFAiEA9hA4swjcHahlo0hSdG8BV3KTQgjG0kRUOTzZm98iF3cCIAVuZ1pnWm0KArhbFOXikHTYolqbV2C+ooFvZhkQoAbqAUdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSrgABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohwEHIyIAIIwjUxc3Q7WV37Sge3K6jkLjeX2nTof+fZ10l+OyAokDAQjaBABHMEQCIGLrelVhB6fHP0WsSrWh3d9vcHX7EnWWmn84Pv/3hLyyAiAMBdu3Rw2/LwhVfdNWxzJcHtMJE+mWzThAlF2xIijaXwFHMEQCIGX0W6WZi1mif/4ae+0BavHx+Q1Us6qPdFCqX1aiUQO9AiB/ckcDrR7blmgLKEtW1P/LiPf7dZ6rvgiqMPKbhROD0gFHUiEDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtwhAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zUq4AIgIDqaTDf1mW06ol26xrVwrwZQOUSSlCRgs1R1Ptnuylh3EQ2QxqTwAAAIAAAACABAAAgAAiAgJ/Y5l1fS7/VaE2rQLGhLGDi2VW5fG2s0KCqUtrUAUQlhDZDGpPAAAAgAAAAIAFAACAAA==";
PSBT psbt1 = PSBT.fromString(psbtStr1);
PSBT psbt1 = PSBT.fromString(Network.BITCOIN, psbtStr1);
Assert.assertEquals(psbtStr1, psbt1.toBase64String());
String psbtStr2 = "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgf0cwRAIgdAGK1BgAl7hzMjwAFXILNoTMgSOJEEjn282bVa1nnJkCIHPTabdA4+tT3O+jOCPIBwUUylWn3ZVE8VfBZ5EyYRGMASICAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXSDBFAiEA9hA4swjcHahlo0hSdG8BV3KTQgjG0kRUOTzZm98iF3cCIAVuZ1pnWm0KArhbFOXikHTYolqbV2C+ooFvZhkQoAbqAQEDBAEAAAABBEdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSriIGApWDvzmuCmCXR60Zmt3WNPphCFWdbFzTm0whg/GrluB/ENkMak8AAACAAAAAgAAAAIAiBgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU21xDZDGpPAAAAgAAAAIABAACAAAEBIADC6wsAAAAAF6kUt/X69A49QKWkWbHbNTXyty+pIeiHIgIDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtxHMEQCIGLrelVhB6fHP0WsSrWh3d9vcHX7EnWWmn84Pv/3hLyyAiAMBdu3Rw2/LwhVfdNWxzJcHtMJE+mWzThAlF2xIijaXwEiAgI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8Oc0cwRAIgZfRbpZmLWaJ//hp77QFq8fH5DVSzqo90UKpfVqJRA70CIH9yRwOtHtuWaAsoS1bU/8uI9/t1nqu+CKow8puFE4PSAQEDBAEAAAABBCIAIIwjUxc3Q7WV37Sge3K6jkLjeX2nTof+fZ10l+OyAokDAQVHUiEDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtwhAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zUq4iBgI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8OcxDZDGpPAAAAgAAAAIADAACAIgYDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtwQ2QxqTwAAAIAAAACAAgAAgAAiAgOppMN/WZbTqiXbrGtXCvBlA5RJKUJGCzVHU+2e7KWHcRDZDGpPAAAAgAAAAIAEAACAACICAn9jmXV9Lv9VoTatAsaEsYOLZVbl8bazQoKpS2tQBRCWENkMak8AAACAAAAAgAUAAIAA";
PSBT psbt2 = PSBT.fromString(psbtStr2);
PSBT psbt2 = PSBT.fromString(Network.BITCOIN, psbtStr2);
Assert.assertEquals(psbtStr2, psbt2.toBase64String());
String psbtStr3 = "cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEHakcwRAIgR1lmF5fAGwNrJZKJSGhiGDR9iYZLcZ4ff89X0eURZYcCIFMJ6r9Wqk2Ikf/REf3xM286KdqGbX+EhtdVRs7tr5MZASEDXNxh/HupccC1AaZGoqg7ECy0OIEhfKaC3Ibi1z+ogpIAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIAAAA";
PSBT psbt3 = PSBT.fromString(psbtStr3);
PSBT psbt3 = PSBT.fromString(Network.BITCOIN, psbtStr3);
Assert.assertEquals(psbtStr3, psbt3.toBase64String());
String psbtStr4 = "cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAQMEAQAAAAAAAA==";
PSBT psbt4 = PSBT.fromString(psbtStr4);
PSBT psbt4 = PSBT.fromString(Network.BITCOIN, psbtStr4);
Assert.assertEquals(psbtStr4, psbt4.toBase64String());
}
@ -320,7 +320,7 @@ public class PSBTTest {
transaction.addInput(Sha256Hash.wrap("75ddabb27b8845f5247975c8a5ba7c6f336c4570708ebe230caf6db5217ae858"), 0, new Script(new byte[0]));
transaction.addInput(Sha256Hash.wrap("1dea7cd05979072a3578cab271c02244ea8a090bbb46aa680a65ecd027048d83"), 1, new Script(new byte[0]));
PSBT psbt = new PSBT(transaction);
PSBT psbt = new PSBT(Network.BITCOIN, transaction);
Assert.assertEquals("70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f000000000000000000", psbt.toString());
psbt.getPsbtInputs().get(0).setRedeemScript(new Script(Utils.hexToBytes("5221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae")));
@ -353,10 +353,10 @@ public class PSBTTest {
@Test
public void combinerBip() throws PSBTParseException {
String strPsbt1 = "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgf0cwRAIgdAGK1BgAl7hzMjwAFXILNoTMgSOJEEjn282bVa1nnJkCIHPTabdA4+tT3O+jOCPIBwUUylWn3ZVE8VfBZ5EyYRGMAQEDBAEAAAABBEdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSriIGApWDvzmuCmCXR60Zmt3WNPphCFWdbFzTm0whg/GrluB/ENkMak8AAACAAAAAgAAAAIAiBgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU21xDZDGpPAAAAgAAAAIABAACAAAEBIADC6wsAAAAAF6kUt/X69A49QKWkWbHbNTXyty+pIeiHIgIDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtxHMEQCIGLrelVhB6fHP0WsSrWh3d9vcHX7EnWWmn84Pv/3hLyyAiAMBdu3Rw2/LwhVfdNWxzJcHtMJE+mWzThAlF2xIijaXwEBAwQBAAAAAQQiACCMI1MXN0O1ld+0oHtyuo5C43l9p06H/n2ddJfjsgKJAwEFR1IhAwidwQx6xttU+RMpr2FzM9s4jOrQwjH3IzedG5kDCwLcIQI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8Oc1KuIgYCOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnMQ2QxqTwAAAIAAAACAAwAAgCIGAwidwQx6xttU+RMpr2FzM9s4jOrQwjH3IzedG5kDCwLcENkMak8AAACAAAAAgAIAAIAAIgIDqaTDf1mW06ol26xrVwrwZQOUSSlCRgs1R1Ptnuylh3EQ2QxqTwAAAIAAAACABAAAgAAiAgJ/Y5l1fS7/VaE2rQLGhLGDi2VW5fG2s0KCqUtrUAUQlhDZDGpPAAAAgAAAAIAFAACAAA==";
PSBT psbt1 = PSBT.fromString(strPsbt1);
PSBT psbt1 = PSBT.fromString(Network.BITCOIN, strPsbt1);
String strPsbt2 = "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU210gwRQIhAPYQOLMI3B2oZaNIUnRvAVdyk0IIxtJEVDk82ZvfIhd3AiAFbmdaZ1ptCgK4WxTl4pB02KJam1dgvqKBb2YZEKAG6gEBAwQBAAAAAQRHUiEClYO/Oa4KYJdHrRma3dY0+mEIVZ1sXNObTCGD8auW4H8hAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXUq4iBgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfxDZDGpPAAAAgAAAAIAAAACAIgYC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtcQ2QxqTwAAAIAAAACAAQAAgAABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohyICAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zRzBEAiBl9FulmYtZon/+GnvtAWrx8fkNVLOqj3RQql9WolEDvQIgf3JHA60e25ZoCyhLVtT/y4j3+3Weq74IqjDym4UTg9IBAQMEAQAAAAEEIgAgjCNTFzdDtZXftKB7crqOQuN5fadOh/59nXSX47ICiQMBBUdSIQMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3CECOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNSriIGAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zENkMak8AAACAAAAAgAMAAIAiBgMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3BDZDGpPAAAAgAAAAIACAACAACICA6mkw39ZltOqJdusa1cK8GUDlEkpQkYLNUdT7Z7spYdxENkMak8AAACAAAAAgAQAAIAAIgICf2OZdX0u/1WhNq0CxoSxg4tlVuXxtrNCgqlLa1AFEJYQ2QxqTwAAAIAAAACABQAAgAA=";
PSBT psbt2 = PSBT.fromString(strPsbt2);
PSBT psbt2 = PSBT.fromString(Network.BITCOIN, strPsbt2);
psbt1.combine(psbt2);
@ -366,7 +366,7 @@ public class PSBTTest {
@Test
public void extractorBip() throws PSBTParseException {
String strPsbt = "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAABB9oARzBEAiB0AYrUGACXuHMyPAAVcgs2hMyBI4kQSOfbzZtVrWecmQIgc9Npt0Dj61Pc76M4I8gHBRTKVafdlUTxV8FnkTJhEYwBSDBFAiEA9hA4swjcHahlo0hSdG8BV3KTQgjG0kRUOTzZm98iF3cCIAVuZ1pnWm0KArhbFOXikHTYolqbV2C+ooFvZhkQoAbqAUdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSrgABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohwEHIyIAIIwjUxc3Q7WV37Sge3K6jkLjeX2nTof+fZ10l+OyAokDAQjaBABHMEQCIGLrelVhB6fHP0WsSrWh3d9vcHX7EnWWmn84Pv/3hLyyAiAMBdu3Rw2/LwhVfdNWxzJcHtMJE+mWzThAlF2xIijaXwFHMEQCIGX0W6WZi1mif/4ae+0BavHx+Q1Us6qPdFCqX1aiUQO9AiB/ckcDrR7blmgLKEtW1P/LiPf7dZ6rvgiqMPKbhROD0gFHUiEDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtwhAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zUq4AIgIDqaTDf1mW06ol26xrVwrwZQOUSSlCRgs1R1Ptnuylh3EQ2QxqTwAAAIAAAACABAAAgAAiAgJ/Y5l1fS7/VaE2rQLGhLGDi2VW5fG2s0KCqUtrUAUQlhDZDGpPAAAAgAAAAIAFAACAAA==";
PSBT psbt = PSBT.fromString(strPsbt);
PSBT psbt = PSBT.fromString(Network.BITCOIN, strPsbt);
Transaction transaction = psbt.extractTransaction();
Assert.assertEquals("0200000000010258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd7500000000da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752aeffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d01000000232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f000400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00000000", Utils.bytesToHex(transaction.bitcoinSerialize()));

View file

@ -6,6 +6,7 @@ import com.sparrowwallet.drongo.crypto.Key;
import com.sparrowwallet.drongo.crypto.KeyDeriver;
import com.sparrowwallet.drongo.policy.Policy;
import com.sparrowwallet.drongo.policy.PolicyType;
import com.sparrowwallet.drongo.protocol.Network;
import com.sparrowwallet.drongo.protocol.ScriptType;
import org.junit.Assert;
import org.junit.Test;
@ -15,7 +16,7 @@ public class WalletTest {
public void encryptTest() throws MnemonicException {
String words = "absent essay fox snake vast pumpkin height crouch silent bulb excuse razor";
DeterministicSeed seed = new DeterministicSeed(words, "pp", 0, DeterministicSeed.Type.BIP39);
Wallet wallet = new Wallet();
Wallet wallet = new Wallet(Network.BITCOIN);
wallet.setPolicyType(PolicyType.SINGLE);
wallet.setScriptType(ScriptType.P2PKH);
Keystore keystore = Keystore.fromSeed(seed, wallet.getScriptType().getDefaultDerivation());
@ -31,7 +32,7 @@ public class WalletTest {
@Test
public void makeLabelsUnique() {
Wallet wallet = new Wallet();
Wallet wallet = new Wallet(Network.BITCOIN);
Keystore keystore1 = new Keystore("BIP39");
wallet.getKeystores().add(keystore1);
@ -91,7 +92,7 @@ public class WalletTest {
public void p2pkhDerivationTest() throws MnemonicException {
String words = "absent essay fox snake vast pumpkin height crouch silent bulb excuse razor";
DeterministicSeed seed = new DeterministicSeed(words, "pp", 0, DeterministicSeed.Type.BIP39);
Wallet wallet = new Wallet();
Wallet wallet = new Wallet(Network.BITCOIN);
wallet.setPolicyType(PolicyType.SINGLE);
wallet.setScriptType(ScriptType.P2PKH);
Keystore keystore = Keystore.fromSeed(seed, wallet.getScriptType().getDefaultDerivation());
@ -106,7 +107,7 @@ public class WalletTest {
public void p2shP2wpkhDerivationTest() throws MnemonicException {
String words = "absent essay fox snake vast pumpkin height crouch silent bulb excuse razor";
DeterministicSeed seed = new DeterministicSeed(words, "pp", 0, DeterministicSeed.Type.BIP39);
Wallet wallet = new Wallet();
Wallet wallet = new Wallet(Network.BITCOIN);
wallet.setPolicyType(PolicyType.SINGLE);
wallet.setScriptType(ScriptType.P2SH_P2WPKH);
Keystore keystore = Keystore.fromSeed(seed, wallet.getScriptType().getDefaultDerivation());
@ -121,7 +122,7 @@ public class WalletTest {
public void p2wpkhDerivationTest() throws MnemonicException {
String words = "absent essay fox snake vast pumpkin height crouch silent bulb excuse razor";
DeterministicSeed seed = new DeterministicSeed(words, "pp", 0, DeterministicSeed.Type.BIP39);
Wallet wallet = new Wallet();
Wallet wallet = new Wallet(Network.BITCOIN);
wallet.setPolicyType(PolicyType.SINGLE);
wallet.setScriptType(ScriptType.P2WPKH);
Keystore keystore = Keystore.fromSeed(seed, wallet.getScriptType().getDefaultDerivation());
@ -140,7 +141,7 @@ public class WalletTest {
String words2 = "chef huge whisper year move obscure post pepper play minute foster lawn";
DeterministicSeed seed2 = new DeterministicSeed(words2, "", 0, DeterministicSeed.Type.BIP39);
Wallet wallet = new Wallet();
Wallet wallet = new Wallet(Network.BITCOIN);
wallet.setPolicyType(PolicyType.MULTI);
wallet.setScriptType(ScriptType.P2SH);
Keystore keystore = Keystore.fromSeed(seed, ScriptType.P2PKH.getDefaultDerivation());
@ -165,7 +166,7 @@ public class WalletTest {
String words2 = "chef huge whisper year move obscure post pepper play minute foster lawn";
DeterministicSeed seed2 = new DeterministicSeed(words2, "", 0, DeterministicSeed.Type.BIP39);
Wallet wallet = new Wallet();
Wallet wallet = new Wallet(Network.BITCOIN);
wallet.setPolicyType(PolicyType.MULTI);
wallet.setScriptType(ScriptType.P2SH_P2WSH);
Keystore keystore = Keystore.fromSeed(seed, ScriptType.P2PKH.getDefaultDerivation());
@ -190,7 +191,7 @@ public class WalletTest {
String words2 = "chef huge whisper year move obscure post pepper play minute foster lawn";
DeterministicSeed seed2 = new DeterministicSeed(words2, "", 0, DeterministicSeed.Type.BIP39);
Wallet wallet = new Wallet();
Wallet wallet = new Wallet(Network.BITCOIN);
wallet.setPolicyType(PolicyType.MULTI);
wallet.setScriptType(ScriptType.P2WSH);
Keystore keystore = Keystore.fromSeed(seed, ScriptType.P2PKH.getDefaultDerivation());