mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2025-02-24 14:50:57 +01:00
Be lenient in parsing tx confidence protobuf, store pubkeys, cleanup
This commit is contained in:
parent
1c28bd3972
commit
69ee4c7729
9 changed files with 350 additions and 208 deletions
|
@ -26,14 +26,24 @@ package wallet;
|
|||
option java_package = "org.bitcoinj.wallet";
|
||||
option java_outer_classname = "Protos";
|
||||
|
||||
/**
|
||||
* A key use to control Bitcoin spending
|
||||
*
|
||||
* Either the private key, the public key or both may be present. It is recommended that
|
||||
* if the private key is provided that the public key is provided too because deriving it is slow.
|
||||
*
|
||||
* If only the public key is provided, the key can only be used to watch the blockchain and verify
|
||||
* transactions, and not for spending.
|
||||
*/
|
||||
message Key {
|
||||
enum Type {
|
||||
ORIGINAL = 1; // Original bitcoin secp256k1 curve
|
||||
}
|
||||
required bytes private_key = 1; // integer representation of the EC private key
|
||||
required Type type = 2;
|
||||
optional string label = 3; // for presentation purposes
|
||||
optional int64 creation_timestamp = 4; // datetime stored as millis since epoch.
|
||||
required Type type = 1;
|
||||
optional bytes private_key = 2; // integer representation of the EC private key
|
||||
optional bytes public_key = 3; // integer representation of the EC public key
|
||||
optional string label = 4; // for presentation purposes
|
||||
optional int64 creation_timestamp = 5; // datetime stored as millis since epoch.
|
||||
}
|
||||
|
||||
message TransactionInput {
|
||||
|
@ -53,20 +63,30 @@ message TransactionOutput {
|
|||
// if spent, the index of the transaction output of the transaction doing the spend
|
||||
}
|
||||
|
||||
/**
|
||||
* A description of the confidence we have that a transaction cannot be reversed in the future.
|
||||
*
|
||||
* Parsing should be lenient, since this could change for different applications yet we should
|
||||
* maintain backward compatibility.
|
||||
*/
|
||||
|
||||
message TransactionConfidence {
|
||||
enum Type {
|
||||
UNKNOWN = 0;
|
||||
BUILDING = 1;
|
||||
NOT_SEEN_IN_CHAIN = 2;
|
||||
NOT_IN_BEST_CHAIN = 3;
|
||||
OVERRIDDEN_BY_DOUBLE_SPEND = 4;
|
||||
BUILDING = 1; // In best chain. If and only if appeared_at_height is present.
|
||||
NOT_SEEN_IN_CHAIN = 2; // Pending inclusion in best chain.
|
||||
NOT_IN_BEST_CHAIN = 3; // In non-best chain, pending inclusion in best chain.
|
||||
OVERRIDDEN_BY_DOUBLE_SPEND = 4; // If and only if overriding_transaction is present.
|
||||
}
|
||||
|
||||
required Type type = 1;
|
||||
// This is optional in case we add confidence types to prevent parse errors - backwards compatible.
|
||||
optional Type type = 1;
|
||||
optional int32 appeared_at_height = 2;
|
||||
optional bytes overriding_transaction = 3;
|
||||
optional bytes overriding_transaction = 3; // Hash of tx. Should be in this wallet.
|
||||
}
|
||||
|
||||
/** A bitcoin transaction */
|
||||
|
||||
message Transaction {
|
||||
/**
|
||||
* This is a bitfield oriented enum, with the following bits:
|
||||
|
@ -107,6 +127,7 @@ message Transaction {
|
|||
// Sha256Hash of block in block chain in which this transaction appears
|
||||
}
|
||||
|
||||
/** An extension to the wallet */
|
||||
message Extension {
|
||||
required string id = 1; // like org.whatever.foo.bar
|
||||
required bytes data = 2;
|
||||
|
@ -116,6 +137,7 @@ message Extension {
|
|||
required bool mandatory = 3;
|
||||
}
|
||||
|
||||
/** A bitcoin wallet */
|
||||
message Wallet {
|
||||
required string network_identifier = 1; // the network used by this wallet
|
||||
// org.bitcoin.production = production network (Satoshi genesis block)
|
||||
|
|
|
@ -49,6 +49,6 @@ public class DumpedPrivateKey extends VersionedChecksummedBytes {
|
|||
* Returns an ECKey created from this encoded private key.
|
||||
*/
|
||||
public ECKey getKey() {
|
||||
return new ECKey(new BigInteger(1, bytes), null);
|
||||
return new ECKey(new BigInteger(1, bytes));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ public class ECKey implements Serializable {
|
|||
* reference implementation in its wallet. Note that this is slow because it requires an EC point multiply.
|
||||
*/
|
||||
public static ECKey fromASN1(byte[] asn1privkey) {
|
||||
return new ECKey(extractPrivateKeyFromASN1(asn1privkey), null);
|
||||
return new ECKey(extractPrivateKeyFromASN1(asn1privkey));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -122,7 +122,7 @@ public class ECKey implements Serializable {
|
|||
* the public key already correctly matches the public key. If only the public key is supplied, this ECKey cannot
|
||||
* be used for signing.
|
||||
*/
|
||||
public ECKey(BigInteger privKey, BigInteger pubKey) {
|
||||
private ECKey(BigInteger privKey, byte[] pubKey) {
|
||||
this.priv = privKey;
|
||||
this.pub = null;
|
||||
if (pubKey == null && privKey != null) {
|
||||
|
@ -132,22 +132,27 @@ public class ECKey implements Serializable {
|
|||
// We expect the pubkey to be in regular encoded form, just as a BigInteger. Therefore the first byte is
|
||||
// a special marker byte.
|
||||
// TODO: This is probably not a useful API and may be confusing.
|
||||
this.pub = Utils.bigIntegerToBytes(pubKey, 65);
|
||||
this.pub = pubKey;
|
||||
}
|
||||
}
|
||||
|
||||
/** Creates an ECKey given the private key only. The public key is calculated from it (this is slow) */
|
||||
public ECKey(BigInteger privKey) {
|
||||
this(privKey, (byte[])null);
|
||||
}
|
||||
|
||||
/** A constructor variant with BigInteger pubkey. See {@link ECKey#ECKey(BigInteger, byte[])}. */
|
||||
public ECKey(BigInteger privKey, BigInteger pubKey) {
|
||||
this(privKey, Utils.bigIntegerToBytes(pubKey, 65));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ECKey given only the private key bytes. This is the same as using the BigInteger constructor, but
|
||||
* is more convenient if you are importing a key from elsewhere. The public key will be automatically derived
|
||||
* from the private key. Same as calling {@link ECKey#fromPrivKeyBytes(byte[])}.
|
||||
*/
|
||||
public ECKey(byte[] privKeyBytes, byte[] pubKeyBytes) {
|
||||
priv = privKeyBytes == null ? null : new BigInteger(1, privKeyBytes);
|
||||
pub = pubKeyBytes;
|
||||
if (pub == null && priv != null) {
|
||||
// Derive public from private.
|
||||
pub = publicKeyFromPrivate(priv);
|
||||
}
|
||||
public ECKey(byte[] privKeyBytes, byte[] pubKey) {
|
||||
this(privKeyBytes == null ? null : new BigInteger(1, privKeyBytes), pubKey);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -284,10 +289,6 @@ public class ECKey implements Serializable {
|
|||
return Utils.bigIntegerToBytes(priv, 32);
|
||||
}
|
||||
|
||||
public static ECKey fromPrivKeyBytes(byte[] bytes) {
|
||||
return new ECKey(new BigInteger(1, bytes), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports the private key in the form used by the Satoshi client "dumpprivkey" and "importprivkey" commands. Use
|
||||
* the {@link com.google.bitcoin.core.DumpedPrivateKey#toString()} method to get the string.
|
||||
|
|
|
@ -707,7 +707,7 @@ public class Transaction extends ChildMessage implements Serializable {
|
|||
return confidence;
|
||||
}
|
||||
|
||||
|
||||
/** Check if the transaction has a known confidence */
|
||||
public boolean hasConfidence() {
|
||||
return confidence != null && confidence.getConfidenceType() != TransactionConfidence.ConfidenceType.UNKNOWN;
|
||||
}
|
||||
|
|
|
@ -70,6 +70,9 @@ public class Utils {
|
|||
* @return 32 byte long array.
|
||||
*/
|
||||
public static byte[] bigIntegerToBytes(BigInteger b, int numBytes) {
|
||||
if (b == null) {
|
||||
return null;
|
||||
}
|
||||
byte[] bytes = new byte[numBytes];
|
||||
byte[] biBytes = b.toByteArray();
|
||||
int start = (biBytes.length == numBytes + 1) ? 1 : 0;
|
||||
|
|
|
@ -44,7 +44,7 @@ public class PrivateKeys {
|
|||
key = dumpedPrivateKey.getKey();
|
||||
} else {
|
||||
BigInteger privKey = Base58.decodeToBigInteger(args[0]);
|
||||
key = new ECKey(privKey, null);
|
||||
key = new ECKey(privKey);
|
||||
}
|
||||
System.out.println("Address from private key is: " + key.toAddress(params).toString());
|
||||
// And the address ...
|
||||
|
|
|
@ -31,6 +31,8 @@ import com.google.protobuf.ByteString;
|
|||
import com.google.protobuf.TextFormat;
|
||||
|
||||
import org.bitcoinj.wallet.Protos;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
@ -46,6 +48,8 @@ import java.util.Map;
|
|||
* @author Miron Cuperman
|
||||
*/
|
||||
public class WalletProtobufSerializer {
|
||||
private static final Logger log = LoggerFactory.getLogger(WalletProtobufSerializer.class);
|
||||
|
||||
// Used for de-serialization
|
||||
private Map<ByteString, Transaction> txMap;
|
||||
|
||||
|
@ -82,7 +86,9 @@ public class WalletProtobufSerializer {
|
|||
// .setCreationTimestamp() TODO
|
||||
// .setLabel() TODO
|
||||
.setType(Protos.Key.Type.ORIGINAL)
|
||||
.setPrivateKey(ByteString.copyFrom(key.getPrivKeyBytes())));
|
||||
.setPrivateKey(ByteString.copyFrom(key.getPrivKeyBytes()))
|
||||
.setPublicKey(ByteString.copyFrom(key.getPubKey()))
|
||||
);
|
||||
}
|
||||
return walletBuilder.build();
|
||||
}
|
||||
|
@ -126,9 +132,11 @@ public class WalletProtobufSerializer {
|
|||
.setValue(output.getValue().longValue());
|
||||
final TransactionInput spentBy = output.getSpentBy();
|
||||
if (spentBy != null) {
|
||||
Sha256Hash spendingHash = spentBy.getParentTransaction().getHash();
|
||||
outputBuilder
|
||||
.setSpentByTransactionHash(ByteString.copyFrom(spentBy.getParentTransaction().getHash().getBytes()))
|
||||
.setSpentByTransactionIndex(spentBy.getParentTransaction().getInputs().indexOf(spentBy));
|
||||
.setSpentByTransactionHash(hashToByteString(spendingHash))
|
||||
.setSpentByTransactionIndex(
|
||||
spentBy.getParentTransaction().getInputs().indexOf(spentBy));
|
||||
}
|
||||
txBuilder.addTransactionOutput(outputBuilder);
|
||||
}
|
||||
|
@ -136,7 +144,7 @@ public class WalletProtobufSerializer {
|
|||
// Handle which blocks tx was seen in
|
||||
if (tx.getAppearsInHashes() != null) {
|
||||
for (Sha256Hash hash : tx.getAppearsInHashes()) {
|
||||
txBuilder.addBlockHash(ByteString.copyFrom(hash.getBytes()));
|
||||
txBuilder.addBlockHash(hashToByteString(hash));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,20 +153,33 @@ public class WalletProtobufSerializer {
|
|||
Protos.TransactionConfidence.Builder confidenceBuilder =
|
||||
Protos.TransactionConfidence.newBuilder();
|
||||
|
||||
confidenceBuilder.setType(Protos.TransactionConfidence.Type.valueOf(confidence.getConfidenceType().getValue()));
|
||||
if (confidence.getConfidenceType() == ConfidenceType.BUILDING) {
|
||||
confidenceBuilder.setAppearedAtHeight(confidence.getAppearedAtChainHeight());
|
||||
}
|
||||
if (confidence.getConfidenceType() == ConfidenceType.OVERRIDDEN_BY_DOUBLE_SPEND) {
|
||||
confidenceBuilder.setOverridingTransaction(ByteString.copyFrom(confidence.getOverridingTransaction().getHash().getBytes()));
|
||||
}
|
||||
|
||||
txBuilder.setConfidence(confidenceBuilder);
|
||||
writeConfidence(txBuilder, confidence, confidenceBuilder);
|
||||
}
|
||||
|
||||
return txBuilder.build();
|
||||
}
|
||||
|
||||
private static void writeConfidence(
|
||||
Protos.Transaction.Builder txBuilder,
|
||||
TransactionConfidence confidence,
|
||||
Protos.TransactionConfidence.Builder confidenceBuilder) {
|
||||
confidenceBuilder.setType(
|
||||
Protos.TransactionConfidence.Type.valueOf(confidence.getConfidenceType().getValue()));
|
||||
if (confidence.getConfidenceType() == ConfidenceType.BUILDING) {
|
||||
confidenceBuilder.setAppearedAtHeight(confidence.getAppearedAtChainHeight());
|
||||
}
|
||||
if (confidence.getConfidenceType() == ConfidenceType.OVERRIDDEN_BY_DOUBLE_SPEND) {
|
||||
Sha256Hash overridingHash = confidence.getOverridingTransaction().getHash();
|
||||
confidenceBuilder.setOverridingTransaction(hashToByteString(overridingHash));
|
||||
}
|
||||
|
||||
txBuilder.setConfidence(confidenceBuilder);
|
||||
}
|
||||
|
||||
private static ByteString hashToByteString(Sha256Hash hash) {
|
||||
return ByteString.copyFrom(hash.getBytes());
|
||||
}
|
||||
|
||||
public static Wallet readWallet(InputStream input, NetworkParameters params)
|
||||
throws IOException {
|
||||
WalletProtobufSerializer serializer = new WalletProtobufSerializer();
|
||||
|
@ -175,7 +196,12 @@ public class WalletProtobufSerializer {
|
|||
if (keyProto.getType() != Protos.Key.Type.ORIGINAL) {
|
||||
throw new IllegalArgumentException("Unknown key type in wallet");
|
||||
}
|
||||
wallet.addKey(ECKey.fromPrivKeyBytes(keyProto.getPrivateKey().toByteArray()));
|
||||
if (!keyProto.hasPrivateKey()) {
|
||||
throw new IllegalArgumentException("Don't know how to handle pubkey-only keys");
|
||||
}
|
||||
|
||||
byte[] pubKey = keyProto.hasPublicKey() ? keyProto.getPublicKey().toByteArray() : null;
|
||||
wallet.addKey(new ECKey(keyProto.getPrivateKey().toByteArray(), pubKey));
|
||||
}
|
||||
|
||||
// Read all transactions and create outputs
|
||||
|
@ -205,7 +231,9 @@ public class WalletProtobufSerializer {
|
|||
|
||||
|
||||
private void readTransaction(Protos.Transaction txProto, NetworkParameters params) {
|
||||
Transaction tx = new Transaction(params, txProto.getVersion(), new Sha256Hash(txProto.getHash().toByteArray()));
|
||||
Transaction tx =
|
||||
new Transaction(params, txProto.getVersion(),
|
||||
new Sha256Hash(txProto.getHash().toByteArray()));
|
||||
if (txProto.hasUpdatedAt())
|
||||
tx.setUpdateTime(new Date(txProto.getUpdatedAt()));
|
||||
|
||||
|
@ -270,17 +298,43 @@ public class WalletProtobufSerializer {
|
|||
if(txProto.hasConfidence()) {
|
||||
Protos.TransactionConfidence confidenceProto = txProto.getConfidence();
|
||||
TransactionConfidence confidence = tx.getConfidence();
|
||||
confidence.setConfidenceType(TransactionConfidence.ConfidenceType.valueOf(confidenceProto.getType().getNumber()));
|
||||
if (confidenceProto.hasAppearedAtHeight()) {
|
||||
assert confidence.getConfidenceType() == ConfidenceType.BUILDING;
|
||||
confidence.setAppearedAtChainHeight(confidenceProto.getAppearedAtHeight());
|
||||
}
|
||||
if (confidenceProto.hasOverridingTransaction()) {
|
||||
assert confidence.getConfidenceType() == ConfidenceType.OVERRIDDEN_BY_DOUBLE_SPEND;
|
||||
confidence.setOverridingTransaction(txMap.get(confidenceProto.getOverridingTransaction()));
|
||||
}
|
||||
readConfidence(tx, confidenceProto, confidence);
|
||||
}
|
||||
|
||||
return new WalletTransaction(pool, tx);
|
||||
}
|
||||
|
||||
private void readConfidence(
|
||||
Transaction tx, Protos.TransactionConfidence confidenceProto,
|
||||
TransactionConfidence confidence) {
|
||||
// We are lenient here because tx confidence is not an essential part of the wallet.
|
||||
// If the tx has an unknown type of confidence, ignore.
|
||||
if (!confidenceProto.hasType()) {
|
||||
log.warn("Unknown confidence type for tx {}", tx.getHashAsString());
|
||||
return;
|
||||
}
|
||||
ConfidenceType confidenceType =
|
||||
TransactionConfidence.ConfidenceType.valueOf(confidenceProto.getType().getNumber());
|
||||
confidence.setConfidenceType(confidenceType);
|
||||
if (confidenceProto.hasAppearedAtHeight()) {
|
||||
if (confidence.getConfidenceType() != ConfidenceType.BUILDING) {
|
||||
log.warn("Have appearedAtHeight but not BUILDING for tx {}", tx.getHashAsString());
|
||||
return;
|
||||
}
|
||||
confidence.setAppearedAtChainHeight(confidenceProto.getAppearedAtHeight());
|
||||
}
|
||||
if (confidenceProto.hasOverridingTransaction()) {
|
||||
if (confidence.getConfidenceType() != ConfidenceType.OVERRIDDEN_BY_DOUBLE_SPEND) {
|
||||
log.warn("Have overridingTransaction but not OVERRIDDEN for tx {}", tx.getHashAsString());
|
||||
return;
|
||||
}
|
||||
Transaction overridingTransaction =
|
||||
txMap.get(confidenceProto.getOverridingTransaction());
|
||||
if (overridingTransaction == null) {
|
||||
log.warn("Have overridingTransaction that is not in wallet for tx {}", tx.getHashAsString());
|
||||
return;
|
||||
}
|
||||
confidence.setOverridingTransaction(overridingTransaction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,19 +11,23 @@ public final class Protos {
|
|||
public interface KeyOrBuilder
|
||||
extends com.google.protobuf.MessageOrBuilder {
|
||||
|
||||
// required bytes private_key = 1;
|
||||
boolean hasPrivateKey();
|
||||
com.google.protobuf.ByteString getPrivateKey();
|
||||
|
||||
// required .wallet.Key.Type type = 2;
|
||||
// required .wallet.Key.Type type = 1;
|
||||
boolean hasType();
|
||||
org.bitcoinj.wallet.Protos.Key.Type getType();
|
||||
|
||||
// optional string label = 3;
|
||||
// optional bytes private_key = 2;
|
||||
boolean hasPrivateKey();
|
||||
com.google.protobuf.ByteString getPrivateKey();
|
||||
|
||||
// optional bytes public_key = 3;
|
||||
boolean hasPublicKey();
|
||||
com.google.protobuf.ByteString getPublicKey();
|
||||
|
||||
// optional string label = 4;
|
||||
boolean hasLabel();
|
||||
String getLabel();
|
||||
|
||||
// optional int64 creation_timestamp = 4;
|
||||
// optional int64 creation_timestamp = 5;
|
||||
boolean hasCreationTimestamp();
|
||||
long getCreationTimestamp();
|
||||
}
|
||||
|
@ -122,31 +126,41 @@ public final class Protos {
|
|||
}
|
||||
|
||||
private int bitField0_;
|
||||
// required bytes private_key = 1;
|
||||
public static final int PRIVATE_KEY_FIELD_NUMBER = 1;
|
||||
private com.google.protobuf.ByteString privateKey_;
|
||||
public boolean hasPrivateKey() {
|
||||
return ((bitField0_ & 0x00000001) == 0x00000001);
|
||||
}
|
||||
public com.google.protobuf.ByteString getPrivateKey() {
|
||||
return privateKey_;
|
||||
}
|
||||
|
||||
// required .wallet.Key.Type type = 2;
|
||||
public static final int TYPE_FIELD_NUMBER = 2;
|
||||
// required .wallet.Key.Type type = 1;
|
||||
public static final int TYPE_FIELD_NUMBER = 1;
|
||||
private org.bitcoinj.wallet.Protos.Key.Type type_;
|
||||
public boolean hasType() {
|
||||
return ((bitField0_ & 0x00000002) == 0x00000002);
|
||||
return ((bitField0_ & 0x00000001) == 0x00000001);
|
||||
}
|
||||
public org.bitcoinj.wallet.Protos.Key.Type getType() {
|
||||
return type_;
|
||||
}
|
||||
|
||||
// optional string label = 3;
|
||||
public static final int LABEL_FIELD_NUMBER = 3;
|
||||
// optional bytes private_key = 2;
|
||||
public static final int PRIVATE_KEY_FIELD_NUMBER = 2;
|
||||
private com.google.protobuf.ByteString privateKey_;
|
||||
public boolean hasPrivateKey() {
|
||||
return ((bitField0_ & 0x00000002) == 0x00000002);
|
||||
}
|
||||
public com.google.protobuf.ByteString getPrivateKey() {
|
||||
return privateKey_;
|
||||
}
|
||||
|
||||
// optional bytes public_key = 3;
|
||||
public static final int PUBLIC_KEY_FIELD_NUMBER = 3;
|
||||
private com.google.protobuf.ByteString publicKey_;
|
||||
public boolean hasPublicKey() {
|
||||
return ((bitField0_ & 0x00000004) == 0x00000004);
|
||||
}
|
||||
public com.google.protobuf.ByteString getPublicKey() {
|
||||
return publicKey_;
|
||||
}
|
||||
|
||||
// optional string label = 4;
|
||||
public static final int LABEL_FIELD_NUMBER = 4;
|
||||
private java.lang.Object label_;
|
||||
public boolean hasLabel() {
|
||||
return ((bitField0_ & 0x00000004) == 0x00000004);
|
||||
return ((bitField0_ & 0x00000008) == 0x00000008);
|
||||
}
|
||||
public String getLabel() {
|
||||
java.lang.Object ref = label_;
|
||||
|
@ -174,19 +188,20 @@ public final class Protos {
|
|||
}
|
||||
}
|
||||
|
||||
// optional int64 creation_timestamp = 4;
|
||||
public static final int CREATION_TIMESTAMP_FIELD_NUMBER = 4;
|
||||
// optional int64 creation_timestamp = 5;
|
||||
public static final int CREATION_TIMESTAMP_FIELD_NUMBER = 5;
|
||||
private long creationTimestamp_;
|
||||
public boolean hasCreationTimestamp() {
|
||||
return ((bitField0_ & 0x00000008) == 0x00000008);
|
||||
return ((bitField0_ & 0x00000010) == 0x00000010);
|
||||
}
|
||||
public long getCreationTimestamp() {
|
||||
return creationTimestamp_;
|
||||
}
|
||||
|
||||
private void initFields() {
|
||||
privateKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
type_ = org.bitcoinj.wallet.Protos.Key.Type.ORIGINAL;
|
||||
privateKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
publicKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
label_ = "";
|
||||
creationTimestamp_ = 0L;
|
||||
}
|
||||
|
@ -195,10 +210,6 @@ public final class Protos {
|
|||
byte isInitialized = memoizedIsInitialized;
|
||||
if (isInitialized != -1) return isInitialized == 1;
|
||||
|
||||
if (!hasPrivateKey()) {
|
||||
memoizedIsInitialized = 0;
|
||||
return false;
|
||||
}
|
||||
if (!hasType()) {
|
||||
memoizedIsInitialized = 0;
|
||||
return false;
|
||||
|
@ -211,16 +222,19 @@ public final class Protos {
|
|||
throws java.io.IOException {
|
||||
getSerializedSize();
|
||||
if (((bitField0_ & 0x00000001) == 0x00000001)) {
|
||||
output.writeBytes(1, privateKey_);
|
||||
output.writeEnum(1, type_.getNumber());
|
||||
}
|
||||
if (((bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
output.writeEnum(2, type_.getNumber());
|
||||
output.writeBytes(2, privateKey_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
output.writeBytes(3, getLabelBytes());
|
||||
output.writeBytes(3, publicKey_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000008) == 0x00000008)) {
|
||||
output.writeInt64(4, creationTimestamp_);
|
||||
output.writeBytes(4, getLabelBytes());
|
||||
}
|
||||
if (((bitField0_ & 0x00000010) == 0x00000010)) {
|
||||
output.writeInt64(5, creationTimestamp_);
|
||||
}
|
||||
getUnknownFields().writeTo(output);
|
||||
}
|
||||
|
@ -233,19 +247,23 @@ public final class Protos {
|
|||
size = 0;
|
||||
if (((bitField0_ & 0x00000001) == 0x00000001)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(1, privateKey_);
|
||||
.computeEnumSize(1, type_.getNumber());
|
||||
}
|
||||
if (((bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeEnumSize(2, type_.getNumber());
|
||||
.computeBytesSize(2, privateKey_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(3, getLabelBytes());
|
||||
.computeBytesSize(3, publicKey_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000008) == 0x00000008)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeInt64Size(4, creationTimestamp_);
|
||||
.computeBytesSize(4, getLabelBytes());
|
||||
}
|
||||
if (((bitField0_ & 0x00000010) == 0x00000010)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeInt64Size(5, creationTimestamp_);
|
||||
}
|
||||
size += getUnknownFields().getSerializedSize();
|
||||
memoizedSerializedSize = size;
|
||||
|
@ -371,14 +389,16 @@ public final class Protos {
|
|||
|
||||
public Builder clear() {
|
||||
super.clear();
|
||||
privateKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
bitField0_ = (bitField0_ & ~0x00000001);
|
||||
type_ = org.bitcoinj.wallet.Protos.Key.Type.ORIGINAL;
|
||||
bitField0_ = (bitField0_ & ~0x00000001);
|
||||
privateKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
bitField0_ = (bitField0_ & ~0x00000002);
|
||||
label_ = "";
|
||||
publicKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
bitField0_ = (bitField0_ & ~0x00000004);
|
||||
creationTimestamp_ = 0L;
|
||||
label_ = "";
|
||||
bitField0_ = (bitField0_ & ~0x00000008);
|
||||
creationTimestamp_ = 0L;
|
||||
bitField0_ = (bitField0_ & ~0x00000010);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -420,18 +440,22 @@ public final class Protos {
|
|||
if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
|
||||
to_bitField0_ |= 0x00000001;
|
||||
}
|
||||
result.privateKey_ = privateKey_;
|
||||
result.type_ = type_;
|
||||
if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
to_bitField0_ |= 0x00000002;
|
||||
}
|
||||
result.type_ = type_;
|
||||
result.privateKey_ = privateKey_;
|
||||
if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
to_bitField0_ |= 0x00000004;
|
||||
}
|
||||
result.label_ = label_;
|
||||
result.publicKey_ = publicKey_;
|
||||
if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
|
||||
to_bitField0_ |= 0x00000008;
|
||||
}
|
||||
result.label_ = label_;
|
||||
if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
|
||||
to_bitField0_ |= 0x00000010;
|
||||
}
|
||||
result.creationTimestamp_ = creationTimestamp_;
|
||||
result.bitField0_ = to_bitField0_;
|
||||
onBuilt();
|
||||
|
@ -449,11 +473,14 @@ public final class Protos {
|
|||
|
||||
public Builder mergeFrom(org.bitcoinj.wallet.Protos.Key other) {
|
||||
if (other == org.bitcoinj.wallet.Protos.Key.getDefaultInstance()) return this;
|
||||
if (other.hasType()) {
|
||||
setType(other.getType());
|
||||
}
|
||||
if (other.hasPrivateKey()) {
|
||||
setPrivateKey(other.getPrivateKey());
|
||||
}
|
||||
if (other.hasType()) {
|
||||
setType(other.getType());
|
||||
if (other.hasPublicKey()) {
|
||||
setPublicKey(other.getPublicKey());
|
||||
}
|
||||
if (other.hasLabel()) {
|
||||
setLabel(other.getLabel());
|
||||
|
@ -466,10 +493,6 @@ public final class Protos {
|
|||
}
|
||||
|
||||
public final boolean isInitialized() {
|
||||
if (!hasPrivateKey()) {
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!hasType()) {
|
||||
|
||||
return false;
|
||||
|
@ -500,29 +523,34 @@ public final class Protos {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case 10: {
|
||||
bitField0_ |= 0x00000001;
|
||||
privateKey_ = input.readBytes();
|
||||
break;
|
||||
}
|
||||
case 16: {
|
||||
case 8: {
|
||||
int rawValue = input.readEnum();
|
||||
org.bitcoinj.wallet.Protos.Key.Type value = org.bitcoinj.wallet.Protos.Key.Type.valueOf(rawValue);
|
||||
if (value == null) {
|
||||
unknownFields.mergeVarintField(2, rawValue);
|
||||
unknownFields.mergeVarintField(1, rawValue);
|
||||
} else {
|
||||
bitField0_ |= 0x00000002;
|
||||
bitField0_ |= 0x00000001;
|
||||
type_ = value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 18: {
|
||||
bitField0_ |= 0x00000002;
|
||||
privateKey_ = input.readBytes();
|
||||
break;
|
||||
}
|
||||
case 26: {
|
||||
bitField0_ |= 0x00000004;
|
||||
publicKey_ = input.readBytes();
|
||||
break;
|
||||
}
|
||||
case 34: {
|
||||
bitField0_ |= 0x00000008;
|
||||
label_ = input.readBytes();
|
||||
break;
|
||||
}
|
||||
case 32: {
|
||||
bitField0_ |= 0x00000008;
|
||||
case 40: {
|
||||
bitField0_ |= 0x00000010;
|
||||
creationTimestamp_ = input.readInt64();
|
||||
break;
|
||||
}
|
||||
|
@ -532,34 +560,10 @@ public final class Protos {
|
|||
|
||||
private int bitField0_;
|
||||
|
||||
// required bytes private_key = 1;
|
||||
private com.google.protobuf.ByteString privateKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
public boolean hasPrivateKey() {
|
||||
return ((bitField0_ & 0x00000001) == 0x00000001);
|
||||
}
|
||||
public com.google.protobuf.ByteString getPrivateKey() {
|
||||
return privateKey_;
|
||||
}
|
||||
public Builder setPrivateKey(com.google.protobuf.ByteString value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000001;
|
||||
privateKey_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
public Builder clearPrivateKey() {
|
||||
bitField0_ = (bitField0_ & ~0x00000001);
|
||||
privateKey_ = getDefaultInstance().getPrivateKey();
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
// required .wallet.Key.Type type = 2;
|
||||
// required .wallet.Key.Type type = 1;
|
||||
private org.bitcoinj.wallet.Protos.Key.Type type_ = org.bitcoinj.wallet.Protos.Key.Type.ORIGINAL;
|
||||
public boolean hasType() {
|
||||
return ((bitField0_ & 0x00000002) == 0x00000002);
|
||||
return ((bitField0_ & 0x00000001) == 0x00000001);
|
||||
}
|
||||
public org.bitcoinj.wallet.Protos.Key.Type getType() {
|
||||
return type_;
|
||||
|
@ -568,22 +572,70 @@ public final class Protos {
|
|||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000002;
|
||||
bitField0_ |= 0x00000001;
|
||||
type_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
public Builder clearType() {
|
||||
bitField0_ = (bitField0_ & ~0x00000002);
|
||||
bitField0_ = (bitField0_ & ~0x00000001);
|
||||
type_ = org.bitcoinj.wallet.Protos.Key.Type.ORIGINAL;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
// optional string label = 3;
|
||||
// optional bytes private_key = 2;
|
||||
private com.google.protobuf.ByteString privateKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
public boolean hasPrivateKey() {
|
||||
return ((bitField0_ & 0x00000002) == 0x00000002);
|
||||
}
|
||||
public com.google.protobuf.ByteString getPrivateKey() {
|
||||
return privateKey_;
|
||||
}
|
||||
public Builder setPrivateKey(com.google.protobuf.ByteString value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000002;
|
||||
privateKey_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
public Builder clearPrivateKey() {
|
||||
bitField0_ = (bitField0_ & ~0x00000002);
|
||||
privateKey_ = getDefaultInstance().getPrivateKey();
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
// optional bytes public_key = 3;
|
||||
private com.google.protobuf.ByteString publicKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
public boolean hasPublicKey() {
|
||||
return ((bitField0_ & 0x00000004) == 0x00000004);
|
||||
}
|
||||
public com.google.protobuf.ByteString getPublicKey() {
|
||||
return publicKey_;
|
||||
}
|
||||
public Builder setPublicKey(com.google.protobuf.ByteString value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000004;
|
||||
publicKey_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
public Builder clearPublicKey() {
|
||||
bitField0_ = (bitField0_ & ~0x00000004);
|
||||
publicKey_ = getDefaultInstance().getPublicKey();
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
// optional string label = 4;
|
||||
private java.lang.Object label_ = "";
|
||||
public boolean hasLabel() {
|
||||
return ((bitField0_ & 0x00000004) == 0x00000004);
|
||||
return ((bitField0_ & 0x00000008) == 0x00000008);
|
||||
}
|
||||
public String getLabel() {
|
||||
java.lang.Object ref = label_;
|
||||
|
@ -599,39 +651,39 @@ public final class Protos {
|
|||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000004;
|
||||
bitField0_ |= 0x00000008;
|
||||
label_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
public Builder clearLabel() {
|
||||
bitField0_ = (bitField0_ & ~0x00000004);
|
||||
bitField0_ = (bitField0_ & ~0x00000008);
|
||||
label_ = getDefaultInstance().getLabel();
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
void setLabel(com.google.protobuf.ByteString value) {
|
||||
bitField0_ |= 0x00000004;
|
||||
bitField0_ |= 0x00000008;
|
||||
label_ = value;
|
||||
onChanged();
|
||||
}
|
||||
|
||||
// optional int64 creation_timestamp = 4;
|
||||
// optional int64 creation_timestamp = 5;
|
||||
private long creationTimestamp_ ;
|
||||
public boolean hasCreationTimestamp() {
|
||||
return ((bitField0_ & 0x00000008) == 0x00000008);
|
||||
return ((bitField0_ & 0x00000010) == 0x00000010);
|
||||
}
|
||||
public long getCreationTimestamp() {
|
||||
return creationTimestamp_;
|
||||
}
|
||||
public Builder setCreationTimestamp(long value) {
|
||||
bitField0_ |= 0x00000008;
|
||||
bitField0_ |= 0x00000010;
|
||||
creationTimestamp_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
public Builder clearCreationTimestamp() {
|
||||
bitField0_ = (bitField0_ & ~0x00000008);
|
||||
bitField0_ = (bitField0_ & ~0x00000010);
|
||||
creationTimestamp_ = 0L;
|
||||
onChanged();
|
||||
return this;
|
||||
|
@ -1721,7 +1773,7 @@ public final class Protos {
|
|||
public interface TransactionConfidenceOrBuilder
|
||||
extends com.google.protobuf.MessageOrBuilder {
|
||||
|
||||
// required .wallet.TransactionConfidence.Type type = 1;
|
||||
// optional .wallet.TransactionConfidence.Type type = 1;
|
||||
boolean hasType();
|
||||
org.bitcoinj.wallet.Protos.TransactionConfidence.Type getType();
|
||||
|
||||
|
@ -1840,7 +1892,7 @@ public final class Protos {
|
|||
}
|
||||
|
||||
private int bitField0_;
|
||||
// required .wallet.TransactionConfidence.Type type = 1;
|
||||
// optional .wallet.TransactionConfidence.Type type = 1;
|
||||
public static final int TYPE_FIELD_NUMBER = 1;
|
||||
private org.bitcoinj.wallet.Protos.TransactionConfidence.Type type_;
|
||||
public boolean hasType() {
|
||||
|
@ -1880,10 +1932,6 @@ public final class Protos {
|
|||
byte isInitialized = memoizedIsInitialized;
|
||||
if (isInitialized != -1) return isInitialized == 1;
|
||||
|
||||
if (!hasType()) {
|
||||
memoizedIsInitialized = 0;
|
||||
return false;
|
||||
}
|
||||
memoizedIsInitialized = 1;
|
||||
return true;
|
||||
}
|
||||
|
@ -2131,10 +2179,6 @@ public final class Protos {
|
|||
}
|
||||
|
||||
public final boolean isInitialized() {
|
||||
if (!hasType()) {
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2188,7 +2232,7 @@ public final class Protos {
|
|||
|
||||
private int bitField0_;
|
||||
|
||||
// required .wallet.TransactionConfidence.Type type = 1;
|
||||
// optional .wallet.TransactionConfidence.Type type = 1;
|
||||
private org.bitcoinj.wallet.Protos.TransactionConfidence.Type type_ = org.bitcoinj.wallet.Protos.TransactionConfidence.Type.UNKNOWN;
|
||||
public boolean hasType() {
|
||||
return ((bitField0_ & 0x00000001) == 0x00000001);
|
||||
|
@ -2590,12 +2634,6 @@ public final class Protos {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
if (hasConfidence()) {
|
||||
if (!getConfidence().isInitialized()) {
|
||||
memoizedIsInitialized = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
memoizedIsInitialized = 1;
|
||||
return true;
|
||||
}
|
||||
|
@ -3051,12 +3089,6 @@ public final class Protos {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
if (hasConfidence()) {
|
||||
if (!getConfidence().isInitialized()) {
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -5639,39 +5671,40 @@ public final class Protos {
|
|||
descriptor;
|
||||
static {
|
||||
java.lang.String[] descriptorData = {
|
||||
"\n\rbitcoin.proto\022\006wallet\"{\n\003Key\022\023\n\013privat" +
|
||||
"e_key\030\001 \002(\014\022\036\n\004type\030\002 \002(\0162\020.wallet.Key.T" +
|
||||
"ype\022\r\n\005label\030\003 \001(\t\022\032\n\022creation_timestamp" +
|
||||
"\030\004 \001(\003\"\024\n\004Type\022\014\n\010ORIGINAL\020\001\"\203\001\n\020Transac" +
|
||||
"tionInput\022\"\n\032transaction_out_point_hash\030" +
|
||||
"\001 \002(\014\022#\n\033transaction_out_point_index\030\002 \002" +
|
||||
"(\005\022\024\n\014script_bytes\030\003 \002(\014\022\020\n\010sequence\030\004 \001" +
|
||||
"(\r\"\177\n\021TransactionOutput\022\r\n\005value\030\001 \002(\003\022\024" +
|
||||
"\n\014script_bytes\030\002 \002(\014\022!\n\031spent_by_transac" +
|
||||
"tion_hash\030\003 \001(\014\022\"\n\032spent_by_transaction_",
|
||||
"index\030\004 \001(\005\"\366\001\n\025TransactionConfidence\0220\n" +
|
||||
"\004type\030\001 \002(\0162\".wallet.TransactionConfiden" +
|
||||
"ce.Type\022\032\n\022appeared_at_height\030\002 \001(\005\022\036\n\026o" +
|
||||
"verriding_transaction\030\003 \001(\014\"o\n\004Type\022\013\n\007U" +
|
||||
"NKNOWN\020\000\022\014\n\010BUILDING\020\001\022\025\n\021NOT_SEEN_IN_CH" +
|
||||
"AIN\020\002\022\025\n\021NOT_IN_BEST_CHAIN\020\003\022\036\n\032OVERRIDD" +
|
||||
"EN_BY_DOUBLE_SPEND\020\004\"\211\003\n\013Transaction\022\017\n\007" +
|
||||
"version\030\001 \002(\005\022\014\n\004hash\030\002 \002(\014\022&\n\004pool\030\003 \002(" +
|
||||
"\0162\030.wallet.Transaction.Pool\022\021\n\tlock_time" +
|
||||
"\030\004 \001(\r\022\022\n\nupdated_at\030\005 \001(\003\0223\n\021transactio",
|
||||
"n_input\030\006 \003(\0132\030.wallet.TransactionInput\022" +
|
||||
"5\n\022transaction_output\030\007 \003(\0132\031.wallet.Tra" +
|
||||
"nsactionOutput\022\022\n\nblock_hash\030\010 \003(\014\0221\n\nco" +
|
||||
"nfidence\030\t \001(\0132\035.wallet.TransactionConfi" +
|
||||
"dence\"Y\n\004Pool\022\013\n\007UNSPENT\020\004\022\t\n\005SPENT\020\005\022\014\n" +
|
||||
"\010INACTIVE\020\002\022\010\n\004DEAD\020\n\022\013\n\007PENDING\020\020\022\024\n\020PE" +
|
||||
"NDING_INACTIVE\020\022\"8\n\tExtension\022\n\n\002id\030\001 \002(" +
|
||||
"\t\022\014\n\004data\030\002 \002(\014\022\021\n\tmandatory\030\003 \002(\010\"\254\001\n\006W" +
|
||||
"allet\022\032\n\022network_identifier\030\001 \002(\t\022\034\n\024las" +
|
||||
"t_seen_block_hash\030\002 \001(\014\022\030\n\003key\030\003 \003(\0132\013.w",
|
||||
"allet.Key\022(\n\013transaction\030\004 \003(\0132\023.wallet." +
|
||||
"Transaction\022$\n\textension\030\n \003(\0132\021.wallet." +
|
||||
"ExtensionB\035\n\023org.bitcoinj.walletB\006Protos"
|
||||
"\n\rbitcoin.proto\022\006wallet\"\217\001\n\003Key\022\036\n\004type\030" +
|
||||
"\001 \002(\0162\020.wallet.Key.Type\022\023\n\013private_key\030\002" +
|
||||
" \001(\014\022\022\n\npublic_key\030\003 \001(\014\022\r\n\005label\030\004 \001(\t\022" +
|
||||
"\032\n\022creation_timestamp\030\005 \001(\003\"\024\n\004Type\022\014\n\010O" +
|
||||
"RIGINAL\020\001\"\203\001\n\020TransactionInput\022\"\n\032transa" +
|
||||
"ction_out_point_hash\030\001 \002(\014\022#\n\033transactio" +
|
||||
"n_out_point_index\030\002 \002(\005\022\024\n\014script_bytes\030" +
|
||||
"\003 \002(\014\022\020\n\010sequence\030\004 \001(\r\"\177\n\021TransactionOu" +
|
||||
"tput\022\r\n\005value\030\001 \002(\003\022\024\n\014script_bytes\030\002 \002(" +
|
||||
"\014\022!\n\031spent_by_transaction_hash\030\003 \001(\014\022\"\n\032",
|
||||
"spent_by_transaction_index\030\004 \001(\005\"\366\001\n\025Tra" +
|
||||
"nsactionConfidence\0220\n\004type\030\001 \001(\0162\".walle" +
|
||||
"t.TransactionConfidence.Type\022\032\n\022appeared" +
|
||||
"_at_height\030\002 \001(\005\022\036\n\026overriding_transacti" +
|
||||
"on\030\003 \001(\014\"o\n\004Type\022\013\n\007UNKNOWN\020\000\022\014\n\010BUILDIN" +
|
||||
"G\020\001\022\025\n\021NOT_SEEN_IN_CHAIN\020\002\022\025\n\021NOT_IN_BES" +
|
||||
"T_CHAIN\020\003\022\036\n\032OVERRIDDEN_BY_DOUBLE_SPEND\020" +
|
||||
"\004\"\211\003\n\013Transaction\022\017\n\007version\030\001 \002(\005\022\014\n\004ha" +
|
||||
"sh\030\002 \002(\014\022&\n\004pool\030\003 \002(\0162\030.wallet.Transact" +
|
||||
"ion.Pool\022\021\n\tlock_time\030\004 \001(\r\022\022\n\nupdated_a",
|
||||
"t\030\005 \001(\003\0223\n\021transaction_input\030\006 \003(\0132\030.wal" +
|
||||
"let.TransactionInput\0225\n\022transaction_outp" +
|
||||
"ut\030\007 \003(\0132\031.wallet.TransactionOutput\022\022\n\nb" +
|
||||
"lock_hash\030\010 \003(\014\0221\n\nconfidence\030\t \001(\0132\035.wa" +
|
||||
"llet.TransactionConfidence\"Y\n\004Pool\022\013\n\007UN" +
|
||||
"SPENT\020\004\022\t\n\005SPENT\020\005\022\014\n\010INACTIVE\020\002\022\010\n\004DEAD" +
|
||||
"\020\n\022\013\n\007PENDING\020\020\022\024\n\020PENDING_INACTIVE\020\022\"8\n" +
|
||||
"\tExtension\022\n\n\002id\030\001 \002(\t\022\014\n\004data\030\002 \002(\014\022\021\n\t" +
|
||||
"mandatory\030\003 \002(\010\"\254\001\n\006Wallet\022\032\n\022network_id" +
|
||||
"entifier\030\001 \002(\t\022\034\n\024last_seen_block_hash\030\002",
|
||||
" \001(\014\022\030\n\003key\030\003 \003(\0132\013.wallet.Key\022(\n\013transa" +
|
||||
"ction\030\004 \003(\0132\023.wallet.Transaction\022$\n\texte" +
|
||||
"nsion\030\n \003(\0132\021.wallet.ExtensionB\035\n\023org.bi" +
|
||||
"tcoinj.walletB\006Protos"
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||
|
@ -5683,7 +5716,7 @@ public final class Protos {
|
|||
internal_static_wallet_Key_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
internal_static_wallet_Key_descriptor,
|
||||
new java.lang.String[] { "PrivateKey", "Type", "Label", "CreationTimestamp", },
|
||||
new java.lang.String[] { "Type", "PrivateKey", "PublicKey", "Label", "CreationTimestamp", },
|
||||
org.bitcoinj.wallet.Protos.Key.class,
|
||||
org.bitcoinj.wallet.Protos.Key.Builder.class);
|
||||
internal_static_wallet_TransactionInput_descriptor =
|
||||
|
|
|
@ -31,7 +31,7 @@ public class ECKeyTest {
|
|||
// Test that we can construct an ECKey from a private key (deriving the public from the private), then signing
|
||||
// a message with it.
|
||||
BigInteger privkey = new BigInteger(1, Hex.decode("180cb41c7c600be951b5d3d0a7334acc7506173875834f7a6c4c786a28fcbb19"));
|
||||
ECKey key = new ECKey(privkey, null);
|
||||
ECKey key = new ECKey(privkey);
|
||||
byte[] message = new byte[32]; // All zeroes.
|
||||
byte[] output = key.sign(message);
|
||||
assertTrue(key.verify(message, output));
|
||||
|
@ -70,6 +70,35 @@ public class ECKeyTest {
|
|||
assertTrue(decodedKey.verify(message, roundtripKey.sign(message)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyPairRoundtrip() {
|
||||
byte[] privkeyASN1 = Hex.decode(
|
||||
"3082011302010104205c0b98e524ad188ddef35dc6abba13c34a351a05409e5d285403718b93336a4aa081a53081a2020101302c06072a8648ce3d0101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f300604010004010704410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101a144034200042af7a2aafe8dafd7dc7f9cfb58ce09bda7dce28653ab229b98d1d3d759660c672dd0db18c8c2d76aa470448e876fc2089ab1354c01a6e72cefc50915f4a963ee");
|
||||
ECKey decodedKey = ECKey.fromASN1(privkeyASN1);
|
||||
|
||||
// Now re-encode and decode the ASN.1 to see if it is equivalent (it does not produce the exact same byte
|
||||
// sequence, some integers are padded now).
|
||||
ECKey roundtripKey =
|
||||
new ECKey(decodedKey.getPrivKeyBytes(), decodedKey.getPubKey());
|
||||
|
||||
for (ECKey key : new ECKey[] {decodedKey, roundtripKey}) {
|
||||
byte[] message = reverseBytes(Hex.decode(
|
||||
"11da3761e86431e4a54c176789e41f1651b324d240d599a7067bee23d328ec2a"));
|
||||
byte[] output = key.sign(message);
|
||||
assertTrue(key.verify(message, output));
|
||||
|
||||
output = Hex.decode(
|
||||
"304502206faa2ebc614bf4a0b31f0ce4ed9012eb193302ec2bcaccc7ae8bb40577f47549022100c73a1a1acc209f3f860bf9b9f5e13e9433db6f8b7bd527a088a0e0cd0a4c83e9");
|
||||
assertTrue(key.verify(message, output));
|
||||
}
|
||||
|
||||
// Try to sign with one key and verify with the other.
|
||||
byte[] message = reverseBytes(Hex.decode(
|
||||
"11da3761e86431e4a54c176789e41f1651b324d240d599a7067bee23d328ec2a"));
|
||||
assertTrue(roundtripKey.verify(message, decodedKey.sign(message)));
|
||||
assertTrue(decodedKey.verify(message, roundtripKey.sign(message)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void base58Encoding() throws Exception {
|
||||
String addr = "mqAJmaxMcG5pPHHc3H3NtyXzY7kGbJLuMF";
|
||||
|
|
Loading…
Add table
Reference in a new issue