3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-11 17:55:53 +00:00

Add Dogecoin payment protocol support

Add Dogecoin payment protocol support, and remove unused proto definition
files.
This commit is contained in:
Ross Nicoll 2015-08-08 22:47:46 +01:00
parent 922243e503
commit 049fa77002
No known key found for this signature in database
GPG Key ID: 9142E5F7E533CE3B
9 changed files with 6081 additions and 817 deletions

62
pom.xml
View File

@ -2,9 +2,68 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.altcoinj</groupId>
<artifactId>altcoinj</artifactId>
<artifactId>libdohj</artifactId>
<version>0.14-SNAPSHOT</version>
<packaging>jar</packaging>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<!-- Dummy block to make Maven Central happy: authors list is in AUTHORS -->
<developers>
<developer>
<name>The bitcoinj and libdohj teams.</name>
<email>info@dogecoin.com</email>
</developer>
</developers>
<profiles>
<profile>
<id>update-protobuf</id>
<activation>
<property>
<name>updateProtobuf</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>compile-protoc</id>
<phase>generate-sources</phase>
<configuration>
<tasks>
<path id="proto.path">
<fileset dir="src">
<include name="**/*.proto"/>
</fileset>
</path>
<pathconvert pathsep=" " property="proto.files" refid="proto.path"/>
<exec executable="protoc" failonerror="true">
<arg value="--java_out=${project.basedir}/src/main/java"/>
<arg value="-I${project.basedir}/src"/>
<arg line="${proto.files}"/>
</exec>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
@ -39,4 +98,5 @@
<maven.compiler.source>1.6</maven.compiler.source>
<maven.compiler.target>1.6</maven.compiler.target>
</properties>
<name>libdohj</name>
</project>

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +0,0 @@
/**
* High level protocols that build on top of Bitcoin go here: we have the payment protocol for sending transactions
* from sender to receiver with metadata, and a micropayment channels implementation.
*/
package org.altcoinj.protocols;

View File

@ -1,259 +0,0 @@
/** Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Authors: Mike Hearn, Matt Corallo
*/
/* Notes:
* - Endianness: All byte arrays that represent numbers (such as hashes and private keys) are Big Endian
* - To regenerate after editing, run mvn clean package -DupdateProtobuf
*/
package paymentchannels;
option java_package = "org.bitcoin.paymentchannel";
option java_outer_classname = "Protos";
// This message is designed to be either sent raw over the network (e.g. length prefixed) or embedded inside another
// protocol that is being extended to support micropayments. In this file "primary" typically can be read as "client"
// and "secondary" as "server".
message TwoWayChannelMessage {
enum MessageType {
CLIENT_VERSION = 1;
SERVER_VERSION = 2;
INITIATE = 3;
PROVIDE_REFUND = 4;
RETURN_REFUND = 5;
PROVIDE_CONTRACT = 6;
// Note that there are no optional fields set for CHANNEL_OPEN, it is sent from the
// secondary to the primary to indicate that the provided contract was received,
// verified, and broadcast successfully and the primary can now provide UPDATE messages
// at will to begin paying secondary. If the channel is interrupted after the
// CHANNEL_OPEN message (ie closed without an explicit CLOSE or ERROR) the primary may
// reopen the channel by setting the contract transaction hash in its CLIENT_VERSION
// message.
CHANNEL_OPEN = 7;
UPDATE_PAYMENT = 8;
// Sent by the server to the client after an UPDATE_PAYMENT message is successfully processed.
PAYMENT_ACK = 11;
// Either side can send this message. If the client sends it to the server, then the server
// takes the most recent signature it received in an UPDATE_PAYMENT and uses it to create a
// valid transaction, which it then broadcasts on the network.
//
// Once broadcast is complete, it sends back another CLOSE message with the settlement field set, containing
// the final state of the contract.
//
// The server is allowed to initiate settlement whenever it wants, in which case the client will
// asynchronously receive a CLOSE message with the settlement field set. The server is also allowed
// to send a CLOSE to mark the end of a connection without any settlement taking place, in which
// case this is just an equivalent to a TCP FIN packet. An explicit end-of-protocol markers can be
// useful when this protocol is embedded inside another.
CLOSE = 9;
// Used to indicate an error condition.
// Both parties should make an effort to send either an ERROR or a CLOSE immediately
// before closing the socket (unless they just received an ERROR or a CLOSE). This is important
// because the protocol may not run over TCP.
ERROR = 10;
};
// This is required so if a new message type is added in future, old software aborts trying
// to read the message as early as possible. If the message doesn't parse, the socket should
// be closed.
required MessageType type = 1;
// Now one optional field for each message. Only the field specified by type should be read.
optional ClientVersion client_version = 2;
optional ServerVersion server_version = 3;
optional Initiate initiate = 4;
optional ProvideRefund provide_refund = 5;
optional ReturnRefund return_refund = 6;
optional ProvideContract provide_contract = 7;
optional UpdatePayment update_payment = 8;
optional PaymentAck payment_ack = 11;
optional Settlement settlement = 9;
optional Error error = 10;
}
// Sent by primary to secondary on opening the connection. If anything is received before this is
// sent, the socket is closed.
message ClientVersion {
required int32 major = 1;
optional int32 minor = 2 [default = 0];
// The hash of the multisig contract of a previous channel. This indicates that the primary
// wishes to reopen the given channel. If the server is willing to reopen it, it simply
// responds with a SERVER_VERSION and then immediately sends a CHANNEL_OPEN, it otherwise
// follows SERVER_VERSION with an Initiate representing a new channel
optional bytes previous_channel_contract_hash = 3;
// How many seconds should the channel be open, only used when a new channel is created.
// Defaults to 24 h minus 60 seconds, 24*60*60 - 60
optional uint64 time_window_secs = 4 [default = 86340];
}
// Send by secondary to primary upon receiving the ClientVersion message. If it is willing to
// speak the given major version, it sends back the same major version and the minor version it
// speaks. If it is not, it may send back a lower major version representing the highest version
// it is willing to speak, or sends a NO_ACCEPTABLE_VERSION Error. If the secondary sends back a
// lower major version, the secondary should either expect to continue with that version, or
// should immediately close the connection with a NO_ACCEPTABLE_VERSION Error. Backwards
// incompatible changes to the protocol bump the major version. Extensions bump the minor version
message ServerVersion {
required int32 major = 1;
optional int32 minor = 2 [default = 0];
}
// Sent from server to client once version nego is done.
message Initiate {
// This must be a raw pubkey in regular ECDSA form. Both compressed and non-compressed forms
// are accepted. It is used only in the creation of the multisig contract, as outputs are
// created entirely by the secondary
required bytes multisig_key = 1;
// Once a channel is exhausted a new one must be set up. So secondary indicates the minimum
// size it's willing to accept here. This can be lower to trade off resources against
// security but shouldn't be so low the transactions get rejected by the network as spam.
// Zero isn't a sensible value to have here, so we make the field required.
required uint64 min_accepted_channel_size = 2;
// Rough UNIX time for when the channel expires. This is determined by the block header
// timestamps which can be very inaccurate when miners use the obsolete RollNTime hack.
// Channels could also be specified in terms of block heights but then how do you know the
// current chain height if you don't have internet access? Trust the server? Probably opens up
// attack vectors. We can assume the client has an independent clock, however. If the client
// considers this value too far off (eg more than a day), it may send an ERROR and close the
// channel.
required uint64 expire_time_secs = 3;
// The amount of money the server requires for the initial payment. The act of opening a channel
// always transfers some quantity of money to the server: it's impossible to have a channel with
// zero value transferred. This rule ensures that you can't get a channel that can't be settled
// due to having paid under the dust limit. Because the dust limit will float in future, the
// server tells the client what it thinks it is, and the client is supposed to sanity check this
// value.
required uint64 min_payment = 4;
}
// Sent from primary to secondary after Initiate to begin the refund transaction signing.
message ProvideRefund {
// This must be a raw pubkey in regular ECDSA form. Both compressed and non-compressed forms
// are accepted. It is only used in the creation of the multisig contract.
required bytes multisig_key = 1;
// The serialized bytes of the return transaction in Satoshi format.
// * It must have exactly one input which spends the multisig output (see ProvideContract for
// details of exactly what that output must look like). This output must have a sequence
// number of 0.
// * It must have the lock time set to a time after the min_time_window_secs (from the
// Initiate message).
// * It must have exactly one output which goes back to the primary. This output's
// scriptPubKey will be reused to create payment transactions.
required bytes tx = 2;
}
// Sent from secondary to primary after it has done initial verification of the refund
// transaction. Contains the primary's signature which is required to spend the multisig contract
// to the refund transaction. Must be signed using SIGHASH_NONE|SIGHASH_ANYONECANPAY (and include
// the postfix type byte) to allow the client to add any outputs/inputs it wants as long as the
// input's sequence and transaction's nLockTime remain set.
message ReturnRefund {
required bytes signature = 1;
}
// Sent from the primary to the secondary to complete initialization.
message ProvideContract {
// The serialized bytes of the transaction in Satoshi format.
// * It must be signed and completely valid and ready for broadcast (ie it includes the
// necessary fees) TODO: tell the client how much fee it needs
// * Its first output must be a 2-of-2 multisig output with the first pubkey being the
// primary's and the second being the secondary's (ie the script must be exactly "OP_2
// ProvideRefund.multisig_key Initiate.multisig_key OP_2 OP_CHECKMULTISIG")
required bytes tx = 1;
// To open the channel, an initial payment of the server-specified dust limit value must be
// provided. This ensures that the channel is never in an un-settleable state due to either
// no payment tx having been provided at all, or a payment that is smaller than the dust
// limit being provided.
required UpdatePayment initial_payment = 2;
}
// This message can only be used by the primary after it has received a CHANNEL_OPEN message. It
// creates a new payment transaction. Note that we don't resubmit the entire TX, this is to avoid
// (re)parsing bugs and overhead. The payment transaction is created by the primary by:
// * Adding an input which spends the multisig contract
// * Setting this input's scriptSig to the given signature and a new signature created by the
// primary (the primary should ensure the signature provided correctly spends the multisig
// contract)
// * Adding an output who's scriptPubKey is the same as the refund output (the only output) in
// the refund transaction
// * Setting this output's value to client_change_value (which must be lower than the most recent
// client_change_value and lower than the multisig contract's output value)
// * Adding any number of additional outputs as desired (leaving sufficient fee, if necessary)
// * Adding any number of additional inputs as desired (eg to add more fee)
message UpdatePayment {
// The value which is sent back to the primary. The rest of the multisig output is left for
// the secondary to do with as they wish.
required uint64 client_change_value = 1;
// A SIGHASH_SINGLE|SIGHASH_ANYONECANPAY signature (including the postfix type byte) which
// spends the primary's part of the multisig contract's output. This signature only covers
// the primary's refund output and thus the secondary is free to do what they wish with their
// part of the multisig output.
required bytes signature = 2;
// Information about this update. Used to extend this protocol.
optional bytes info = 3;
}
// This message is sent as an acknowledgement of an UpdatePayment message
message PaymentAck {
// Information about this update. Used to extend this protocol
optional bytes info = 1;
}
message Settlement {
// A copy of the fully signed final contract that settles the channel. The client can verify
// the transaction is correct and then commit it to their wallet.
required bytes tx = 3;
}
// An Error can be sent by either party at any time
// Both parties should make an effort to send either an ERROR or a CLOSE immediately before
// closing the socket (unless they just received an ERROR or a CLOSE)
message Error {
enum ErrorCode {
TIMEOUT = 1; // Protocol timeout occurred (one party hung).
SYNTAX_ERROR = 2; // Generic error indicating some message was not properly
// formatted or was out of order.
NO_ACCEPTABLE_VERSION = 3; // We don't speak the version the other side asked for.
BAD_TRANSACTION = 4; // A provided transaction was not in the proper structure
// (wrong inputs/outputs, sequence, lock time, signature,
// etc)
TIME_WINDOW_UNACCEPTABLE = 5; // The expire time specified by the secondary was unacceptable
// for the primary
CHANNEL_VALUE_TOO_LARGE = 6; // The minimum channel value specified by the secondary was
// too large for the primary
MIN_PAYMENT_TOO_LARGE = 7; // The min "dust limit" specified by the server was too large for the client.
OTHER = 8;
};
optional ErrorCode code = 1 [default=OTHER];
optional string explanation = 2; // NOT SAFE FOR HTML WITHOUT ESCAPING
// Can be set by the client when erroring to the server if a value was out of range. Can help with debugging.
optional uint64 expected_value = 3;
}

View File

@ -1,46 +1,23 @@
/** Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Authors: Mike Hearn, Gavin Andresen
*/
/* Notes:
* - Endianness: All byte arrays that represent numbers (such as hashes and private keys) are Big Endian
* - To regenerate after editing, run mvn clean package -DupdateProtobuf
*/
//
// Simple Bitcoin Payment Protocol messages
// Simple Dogecoin Payment Protocol messages
// Derived fromthe Bitcoin Payment Protocol
//
// Use fields 100+ for extensions;
// to avoid conflicts, register extensions at:
// https://en.bitcoin.it/wiki/Payment_Request
// to avoid conflicts, register extensions via pull-req at:
// https://github.com/dogecoin/dips
//
package payments;
option java_package = "org.bitcoin.protocols.payments";
option java_package = "com.dogecoin.protocols.payments";
option java_outer_classname = "Protos";
// Generalized form of "send payment to this/these bitcoin addresses"
// Generalized form of "send payment to this/these dogecoin addresses"
message Output {
optional uint64 amount = 1 [default = 0]; // amount is integer-number-of-satoshis
required bytes script = 2; // usually one of the standard Script forms
}
message PaymentDetails {
optional string network = 1 [default = "main"]; // "main" or "test"
optional string genesis = 1 [default = "1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691"]; // Hash of the network genesis block
repeated Output outputs = 2; // Where payment should be sent
required uint64 time = 3; // Timestamp; when payment request created
optional uint64 expires = 4; // Timestamp; when this request should be considered invalid
@ -67,4 +44,4 @@ message Payment {
message PaymentACK {
required Payment payment = 1; // Payment message that triggered this ACK
optional string memo = 2; // human-readable message for customer
}
}

View File

@ -1,26 +0,0 @@
package org.bitcoin.crawler;
//
// A simple protocol for describing signed sets of IP addresses. Intended to be distributed via HTTP[S] or in files.
//
option java_package = "org.bitcoin.crawler";
option java_outer_classname = "PeerSeedProtos";
message PeerSeedData {
required string ip_address = 1;
required uint32 port = 2;
required uint32 services = 3;
}
message PeerSeeds {
repeated PeerSeedData seed = 1;
required uint64 timestamp = 2; // seconds since UNIX epoch
required string net = 3;
}
message SignedPeerSeeds {
required bytes peer_seeds = 1;
required bytes signature = 2;
required bytes pubkey = 3;
}

View File

@ -1,51 +0,0 @@
/** Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Authors: Mike Hearn, Matt Corallo
*/
/* Notes:
* - Endianness: All byte arrays that represent numbers (such as hashes and private keys) are Big Endian
* - To regenerate after editing, run mvn clean package -DupdateProtobuf
*/
package paymentchannels;
option java_package = "com.dogecoin.dogecoinj.protocols.channels";
option java_outer_classname = "ClientState";
// A set of StoredPaymentChannel's
message StoredClientPaymentChannels {
repeated StoredClientPaymentChannel channels = 1;
}
// A client-side payment channel in serialized form, which can be reloaded later if the client restarts and wants to
// reopen an existing channel
message StoredClientPaymentChannel {
required bytes id = 1;
required bytes contractTransaction = 2;
required bytes refundTransaction = 3;
required bytes myPublicKey = 8;
// Deprecated, key is already stored in the wallet, and found using myPublicKey;
required bytes myKey = 4;
required uint64 valueToMe = 5;
required uint64 refundFees = 6;
// When set, the hash of the transaction that was presented by the server for closure of the channel.
// It spends the contractTransaction and is expected to be broadcast to the network by the server.
// It's supposed to be in the wallet already.
optional bytes closeTransactionHash = 7;
}

View File

@ -1,44 +0,0 @@
/** Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Authors: Mike Hearn, Matt Corallo
*/
/* Notes:
* - Endianness: All byte arrays that represent numbers (such as hashes and private keys) are Big Endian
* - To regenerate after editing, run mvn clean package -DupdateProtobuf
*/
package paymentchannels;
option java_package = "com.dogecoin.dogecoinj.protocols.channels";
option java_outer_classname = "ServerState";
// A set of StoredPaymentChannel's
message StoredServerPaymentChannels {
repeated StoredServerPaymentChannel channels = 1;
}
// A server-side payment channel in serialized form, which can be reloaded later if the server restarts
message StoredServerPaymentChannel {
required uint64 bestValueToMe = 1;
optional bytes bestValueSignature = 2;
required uint64 refundTransactionUnlockTimeSecs = 3;
required bytes contractTransaction = 4;
required bytes clientOutput = 5;
required bytes myKey = 6;
}

View File

@ -1,400 +0,0 @@
/** Copyright 2013 Google Inc.
* Copyright 2014 Andreas Schildbach
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Authors: Jim Burton, Miron Cuperman, Andreas Schildbach
*/
/* Notes:
* - Endianness: All byte arrays that represent numbers (such as hashes and private keys) are Big Endian
* - To regenerate after editing, run: mvn generate-sources -DupdateProtobuf
*/
package wallet;
option java_package = "com.dogecoin.dogecoinj.wallet";
option java_outer_classname = "Protos";
message PeerAddress {
required bytes ip_address = 1;
required uint32 port = 2;
required uint64 services = 3;
}
message EncryptedData {
required bytes initialisation_vector = 1; // The initialisation vector for the AES encryption (16 bytes)
required bytes encrypted_private_key = 2; // The encrypted private key
}
/**
* Data attached to a Key message that defines the data needed by the BIP32 deterministic key hierarchy algorithm.
*/
message DeterministicKey {
// Random data that allows us to extend a key. Without this, we can't figure out the next key in the chain and
// should just treat it as a regular ORIGINAL type key.
required bytes chain_code = 1;
// The path through the key tree. Each number is encoded in the standard form: high bit set for private derivation
// and high bit unset for public derivation.
repeated uint32 path = 2;
// How many children of this key have been issued, that is, given to the user when they requested a fresh key?
// For the parents of keys being handed out, this is always less than the true number of children: the difference is
// called the lookahead zone. These keys are put into Bloom filters so we can spot transactions made by clones of
// this wallet - for instance when restoring from backup or if the seed was shared between devices.
//
// If this field is missing it means we're not issuing subkeys of this key to users.
optional uint32 issued_subkeys = 3;
optional uint32 lookahead_size = 4;
/**
* Flag indicating that this key is a root of a following chain. This chain is following the next non-following chain.
* Following/followed chains concept is used for married keychains, where the set of keys combined together to produce
* a single P2SH multisignature address
*/
optional bool isFollowing = 5;
// Number of signatures required to spend. This field is needed only for married keychains to reconstruct KeyChain
// and represents the N value from N-of-M CHECKMULTISIG script. For regular single keychains it will always be 1.
optional uint32 sigsRequiredToSpend = 6 [default = 1];
}
/**
* A key used 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 {
/** Unencrypted - Original bitcoin secp256k1 curve */
ORIGINAL = 1;
/** Encrypted with Scrypt and AES - Original bitcoin secp256k1 curve */
ENCRYPTED_SCRYPT_AES = 2;
/**
* Not really a key, but rather contains the mnemonic phrase for a deterministic key hierarchy in the private_key field.
* The label and public_key fields are missing. Creation timestamp will exist.
*/
DETERMINISTIC_MNEMONIC = 3;
/**
* A key that was derived deterministically. Note that the root seed that created it may NOT be present in the
* wallet, for the case of watching wallets. A deterministic key may or may not have the private key bytes present.
* However the public key bytes and the deterministic_key field are guaranteed to exist. In a wallet where there
* is a path from this key up to a key that has (possibly encrypted) private bytes, it's expected that the private
* key can be rederived on the fly.
*/
DETERMINISTIC_KEY = 4;
}
required Type type = 1;
// Either the private EC key bytes (without any ASN.1 wrapping), or the deterministic root seed.
// If the secret is encrypted, or this is a "watching entry" then this is missing.
optional bytes secret_bytes = 2;
// If the secret data is encrypted, then secret_bytes is missing and this field is set.
optional EncryptedData encrypted_data = 6;
// The public EC key derived from the private key. We allow both to be stored to avoid mobile clients having to
// do lots of slow EC math on startup. For DETERMINISTIC_MNEMONIC entries this is missing.
optional bytes public_key = 3;
// User-provided label associated with the key.
optional string label = 4;
// Timestamp stored as millis since epoch. Useful for skipping block bodies before this point. Only reason it's
// optional is that some very old wallets don't have this data.
optional int64 creation_timestamp = 5;
optional DeterministicKey deterministic_key = 7;
// The seed for a deterministic key hierarchy. Derived from the mnemonic,
// but cached here for quick startup. Only applicable to a DETERMINISTIC_MNEMONIC key entry.
optional bytes deterministic_seed = 8;
// Encrypted version of the seed
optional EncryptedData encrypted_deterministic_seed = 9;
}
message Script {
required bytes program = 1;
// Timestamp stored as millis since epoch. Useful for skipping block bodies before this point
// when watching for scripts on the blockchain.
required int64 creation_timestamp = 2;
}
message TransactionInput {
// Hash of the transaction this input is using.
required bytes transaction_out_point_hash = 1;
// Index of transaction output used by this input.
required uint32 transaction_out_point_index = 2;
// Script that contains the signatures/pubkeys.
required bytes script_bytes = 3;
// Sequence number. Currently unused, but intended for contracts in future.
optional uint32 sequence = 4;
// Value of connected output, if known
optional int64 value = 5;
}
message TransactionOutput {
required int64 value = 1;
required bytes script_bytes = 2; // script of transaction output
// If spent, the hash of the transaction doing the spend.
optional bytes spent_by_transaction_hash = 3;
// If spent, the index of the transaction input of the transaction doing the spend.
optional int32 spent_by_transaction_index = 4;
}
/**
* 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; // In best chain. If and only if appeared_at_height is present.
PENDING = 2; // Unconfirmed and sitting in the networks memory pools, waiting to be included in the chain.
NOT_IN_BEST_CHAIN = 3; // Deprecated: equivalent to PENDING.
DEAD = 4; // Either if overriding_transaction is present or transaction is dead coinbase
}
// This is optional in case we add confidence types to prevent parse errors - backwards compatible.
optional Type type = 1;
// If type == BUILDING then this is the chain height at which the transaction was included.
optional int32 appeared_at_height = 2;
// If set, hash of the transaction that double spent this one into oblivion. A transaction can be double spent by
// multiple transactions in the case of several inputs being re-spent by several transactions but we don't
// bother to track them all, just the first. This only makes sense if type = DEAD.
optional bytes overriding_transaction = 3;
// If type == BUILDING then this is the depth of the transaction in the blockchain.
// Zero confirmations: depth = 0, one confirmation: depth = 1 etc.
optional int32 depth = 4;
// deprecated - do not recycle this numeric identifier
// optional int64 work_done = 5;
repeated PeerAddress broadcast_by = 6;
// Where did we get this transaction from? Knowing the source may help us to risk analyze pending transactions.
enum Source {
SOURCE_UNKNOWN = 0; // We don't know where it came from, or this is a wallet from the future.
SOURCE_NETWORK = 1; // We received it from a network broadcast. This is the normal way to get payments.
SOURCE_SELF = 2; // We made it ourselves, so we know it should be valid.
// In future:
// - direct from trusted counterparty, eg via bluetooth/wifi direct
// - direct from untrusted counterparty
// - from a wallet that uses trusted computing/secure hardware that won't create double spends
}
optional Source source = 7;
}
/** A bitcoin transaction */
message Transaction {
/**
* This is a bitfield oriented enum, with the following bits:
*
* bit 0 - spent
* bit 1 - appears in alt chain
* bit 2 - appears in best chain
* bit 3 - double-spent
* bit 4 - pending (we would like the tx to go into the best chain)
*
* Not all combinations are interesting, just the ones actually used in the enum.
*/
enum Pool {
UNSPENT = 4; // In best chain, not all outputs spent
SPENT = 5; // In best chain, all outputs spent
INACTIVE = 2; // In non-best chain, not our transaction
DEAD = 10; // Double-spent by a transaction in the best chain
PENDING = 16; // Our transaction, not in any chain
PENDING_INACTIVE = 18; // In non-best chain, our transaction
}
// See Wallet.java for detailed description of pool semantics
required int32 version = 1;
required bytes hash = 2;
// If pool is not present, that means either:
// - This Transaction is either not in a wallet at all (the proto is re-used elsewhere)
// - Or it is stored but for other purposes, for example, because it is the overriding transaction of a double spend.
// - Or the Pool enum got a new value which your software is too old to parse.
optional Pool pool = 3;
optional uint32 lock_time = 4; // The nLockTime field is useful for contracts.
optional int64 updated_at = 5; // millis since epoch the transaction was last updated
repeated TransactionInput transaction_input = 6;
repeated TransactionOutput transaction_output = 7;
// A list of blocks in which the transaction has been observed (on any chain). Also, a number used to disambiguate
// ordering within a block.
repeated bytes block_hash = 8;
repeated int32 block_relativity_offsets = 11;
// Data describing where the transaction is in the chain.
optional TransactionConfidence confidence = 9;
// For what purpose the transaction was created.
enum Purpose {
// Old wallets or the purpose genuinely is a mystery (e.g. imported from some external source).
UNKNOWN = 0;
// Created in response to a user request for payment. This is the normal case.
USER_PAYMENT = 1;
// Created automatically to move money from rotated keys.
KEY_ROTATION = 2;
// Stuff used by Lighthouse.
ASSURANCE_CONTRACT_CLAIM = 3;
ASSURANCE_CONTRACT_PLEDGE = 4;
ASSURANCE_CONTRACT_STUB = 5;
// In future: de/refragmentation, privacy boosting/mixing, child-pays-for-parent fees, etc.
}
optional Purpose purpose = 10 [default = UNKNOWN];
// Exchange rate that was valid when the transaction was sent.
optional ExchangeRate exchange_rate = 12;
// Memo of the transaction. It can be used to record the memo of the payment request that initiated the
// transaction.
optional string memo = 13;
// Next tag: 14
}
/** The parameters used in the scrypt key derivation function.
* The default values are taken from http://www.tarsnap.com/scrypt/scrypt-slides.pdf.
* They can be increased - n is the number of iterations performed and
* r and p can be used to tweak the algorithm - see:
* http://stackoverflow.com/questions/11126315/what-are-optimal-scrypt-work-factors
*/
message ScryptParameters {
required bytes salt = 1; // Salt to use in generation of the wallet password (8 bytes)
optional int64 n = 2 [default = 16384]; // CPU/ memory cost parameter
optional int32 r = 3 [default = 8]; // Block size parameter
optional int32 p = 4 [default = 1]; // Parallelisation parameter
}
/** An extension to the wallet */
message Extension {
required string id = 1; // like org.whatever.foo.bar
required bytes data = 2;
// If we do not understand a mandatory extension, abort to prevent data loss.
// For example, this could be applied to a new type of holding, such as a contract, where
// dropping of an extension in a read/write cycle could cause loss of value.
required bool mandatory = 3;
}
/**
* A simple key->value mapping that has no interpreted content at all. A bit like the extensions mechanism except
* an extension is keyed by the ID of a piece of code that's loaded with the given data, and has the concept of
* being mandatory if that code isn't found. Whereas this is just a blind key/value store.
*/
message Tag {
required string tag = 1;
required bytes data = 2;
}
/**
* Data required to reconstruct TransactionSigner.
*/
message TransactionSigner {
// fully qualified class name of TransactionSigner implementation
required string class_name = 1;
// arbitrary data required for signer to function
optional bytes data = 2;
}
/** A bitcoin wallet */
message Wallet {
/**
* The encryption type of the wallet.
*
* The encryption type is UNENCRYPTED for wallets where the wallet does not support encryption - wallets prior to
* encryption support are grandfathered in as this wallet type.
* When a wallet is ENCRYPTED_SCRYPT_AES the keys are either encrypted with the wallet password or are unencrypted.
*/
enum EncryptionType {
UNENCRYPTED = 1; // All keys in the wallet are unencrypted
ENCRYPTED_SCRYPT_AES = 2; // All keys are encrypted with a passphrase based KDF of scrypt and AES encryption
}
required string network_identifier = 1; // the network used by this wallet
// org.bitcoin.production = main, production network (Satoshi genesis block)
// org.bitcoin.test = test network (Andresen genesis block)
// The SHA256 hash of the head of the best chain seen by this wallet.
optional bytes last_seen_block_hash = 2;
// The height in the chain of the last seen block.
optional uint32 last_seen_block_height = 12;
optional int64 last_seen_block_time_secs = 14;
repeated Key key = 3;
repeated Transaction transaction = 4;
repeated Script watched_script = 15;
optional EncryptionType encryption_type = 5 [default=UNENCRYPTED];
optional ScryptParameters encryption_parameters = 6;
// The version number of the wallet - used to detect wallets that were produced in the future
// (i.e. the wallet may contain some future format this protobuf or parser code does not know about).
// A version that's higher than the default is considered from the future.
optional int32 version = 7 [default = 1];
// deprecated - do not recycle this numeric identifier
// optional int32 minor_version = 8;
repeated Extension extension = 10;
// A UTF8 encoded text description of the wallet that is intended for end user provided text.
optional string description = 11;
// (The field number 12 is used by last_seen_block_height)
// UNIX time in seconds since the epoch. If set, then any keys created before this date are assumed to be no longer
// wanted. Money sent to them will be re-spent automatically to the first key that was created after this time. It
// can be used to recover a compromised wallet, or just as part of preventative defence-in-depth measures.
optional uint64 key_rotation_time = 13;
repeated Tag tags = 16;
// transaction signers added to the wallet
repeated TransactionSigner transaction_signers = 17;
// Next tag: 18
}
/** An exchange rate between Bitcoin and some fiat currency. */
message ExchangeRate {
// This much of satoshis (1E-8 fractions)
required int64 coin_value = 1;
// is worth this much of fiat (1E-4 fractions).
required int64 fiat_value = 2;
// ISO 4217 currency code (if available) of the fiat currency.
required string fiat_currency_code = 3;
// Next tag: 4
}