Documentation ¶
Overview ¶
Package wire implements the bitcoin wire protocol.
For the complete details of the bitcoin protocol, see the official wiki entry at https://en.bitcoin.it/wiki/Protocol_specification. The following only serves as a quick overview to provide information on how to use the package.
At a high level, this package provides support for marshalling and unmarshalling supported bitcoin messages to and from the wire. This package does not deal with the specifics of message handling such as what to do when a message is received. This provides the caller with a high level of flexibility.
Bitcoin Message Overview ¶
The bitcoin cash protocol consists of exchanging messages between peers. Each message is preceded by a header which identifies information about it such as which bitcoin network it is a part of, its type, how big it is, and a checksum to verify validity. All encoding and decoding of message headers is handled by this package.
To accomplish this, there is a generic interface for bitcoin cash messages named Message which allows messages of any type to be read, written, or passed around through channels, functions, etc. In addition, concrete implementations of most of the currently supported bitcoin messages are provided. For these supported messages, all of the details of marshalling and unmarshalling to and from the wire using bitcoin encoding are handled so the caller doesn't have to concern themselves with the specifics.
Message Interaction ¶
The following provides a quick summary of how the bitcoin cash messages are intended to interact with one another. As stated above, these interactions are not indirectly handled by this package. For more in-depth details about the appropriate interactions, see the official bitcoin cash protocol wiki entry at https://en.bitcoin.it/wiki/Protocol_specification.
The initial handshake consists of two peers sending each other a version message (MsgVersion) followed by responding with a verack message (MsgVerAck). Both peers use the information in the version message (MsgVersion) to negotiate things such as protocol version and supported services with each other. Once the initial handshake is complete, the following chart indicates message interactions in no particular order.
Peer A Sends Peer B Responds ---------------------------------------------------------------------------- getaddr message (MsgGetAddr) addr message (MsgAddr) getblocks message (MsgGetBlocks) inv message (MsgInv) inv message (MsgInv) getdata message (MsgGetData) getdata message (MsgGetData) block message (MsgBlock) -or- tx message (MsgTx) -or- notfound message (MsgNotFound) getheaders message (MsgGetHeaders) headers message (MsgHeaders) ping message (MsgPing) pong message (MsgHeaders)* -or- (none -- Ability to send message is enough) NOTES: * The pong message was not added until later protocol versions as defined in BIP0031. The BIP0031Version constant can be used to detect a recent enough protocol version for this purpose (version > BIP0031Version).
Common Parameters ¶
There are several common parameters that arise when using this package to read and write bitcoin cash messages. The following sections provide a quick overview of these parameters so the next sections can build on them.
Protocol Version ¶
The protocol version should be negotiated with the remote peer at a higher level than this package via the version (MsgVersion) message exchange, however, this package provides the wire.ProtocolVersion constant which indicates the latest protocol version this package supports and is typically the value to use for all outbound connections before a potentially lower protocol version is negotiated.
Bitcoin Cash Network ¶
The bitcoin cash network is a magic number which is used to identify the start of a message and which bitcoin cash network the message applies to. This package provides the following constants:
wire.MainNet wire.TestNet (Regression test network) wire.TestNet3 (Test network version 3) wire.SimNet (Simulation test network)
Determining Message Type ¶
As discussed in the bitcoin cash message overview section, this package reads and writes bitcoin cash messages using a generic interface named Message. In order to determine the actual concrete type of the message, use a type switch or type assertion. An example of a type switch follows:
// Assumes msg is already a valid concrete message such as one created // via NewMsgVersion or read via ReadMessage. switch msg := msg.(type) { case *wire.MsgVersion: // The message is a pointer to a MsgVersion struct. fmt.Printf("Protocol version: %v", msg.ProtocolVersion) case *wire.MsgBlock: // The message is a pointer to a MsgBlock struct. fmt.Printf("Number of tx in block: %v", msg.Header.TxnCount) }
Reading Messages ¶
In order to unmarshall bitcoin cash messages from the wire, use the ReadMessage function. It accepts any io.Reader, but typically this will be a net.Conn to a remote node running a bitcoin cash peer. Example syntax is:
// Reads and validates the next bitcoin cash message from conn using the // protocol version pver and the bitcoin cash network bchnet. The returns // are a wire.Message, a []byte which contains the unmarshalled // raw payload, and a possible error. msg, rawPayload, err := wire.ReadMessage(conn, pver, bchnet) if err != nil { // Log and handle the error }
Writing Messages ¶
In order to marshall bitcoin cash messages to the wire, use the WriteMessage function. It accepts any io.Writer, but typically this will be a net.Conn to a remote node running a bitcoin cash peer. Example syntax to request addresses from a remote peer is:
// Create a new getaddr bitcoin cash message. msg := wire.NewMsgGetAddr() // Writes a bitcoin cash message msg to conn using the protocol version // pver, and the bitcoin cash network bchnet. The return is a possible // error. err := wire.WriteMessage(conn, msg, pver, bchnet) if err != nil { // Log and handle the error }
Errors ¶
Errors returned by this package are either the raw errors provided by underlying calls to read/write from streams such as io.EOF, io.ErrUnexpectedEOF, and io.ErrShortWrite, or of type wire.MessageError. This allows the caller to differentiate between general IO errors and malformed messages through type assertions.
Bitcoin Improvement Proposals ¶
This package includes spec changes outlined by the following BIPs:
BIP0014 (https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki) BIP0031 (https://github.com/bitcoin/bips/blob/master/bip-0031.mediawiki) BIP0035 (https://github.com/bitcoin/bips/blob/master/bip-0035.mediawiki) BIP0037 (https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki) BIP0111 (https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki) BIP0130 (https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki) BIP0133 (https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki)
Index ¶
- Constants
- func RandomUint64() (uint64, error)
- func ReadVarBytes(r io.Reader, pver uint32, maxAllowed uint32, fieldName string) ([]byte, error)
- func ReadVarInt(r io.Reader, pver uint32) (uint64, error)
- func ReadVarString(r io.Reader, pver uint32) (string, error)
- func VarIntSerializeSize(val uint64) int
- func WriteTxOut(w io.Writer, pver uint32, version int32, to *TxOut) error
- func WriteVarBytes(w io.Writer, pver uint32, bytes []byte) error
- func WriteVarInt(w io.Writer, pver uint32, val uint64) error
- func WriteVarString(w io.Writer, pver uint32, str string) error
- type MessageEncoding
- type MessageError
- type MsgTx
- func (msg *MsgTx) AddTxIn(ti *TxIn)
- func (msg *MsgTx) AddTxOut(to *TxOut)
- func (msg *MsgTx) BchDecode(r io.Reader, pver uint32, enc MessageEncoding) error
- func (msg *MsgTx) BchEncode(w io.Writer, pver uint32, enc MessageEncoding) error
- func (msg *MsgTx) Command() string
- func (msg *MsgTx) Copy() *MsgTx
- func (msg *MsgTx) Deserialize(r io.Reader) error
- func (msg *MsgTx) MaxPayloadLength(pver uint32) uint32
- func (msg *MsgTx) PkScriptLocs() []int
- func (msg *MsgTx) Serialize(w io.Writer) error
- func (msg *MsgTx) SerializeSize() int
- func (msg *MsgTx) TxHash() chainhash.Hash
- type OutPoint
- type TxIn
- type TxOut
Constants ¶
const ( // CommandSize is the fixed size of all commands in the common bitcoin message // header. Shorter commands must be zero padded. CommandSize = 12 // MaxVarIntPayload is the maximum payload size for a variable length integer. MaxVarIntPayload = 9 )
const ( // BaseEncoding encodes all messages in the default format specified // for the Bitcoin wire protocol. BaseEncoding MessageEncoding = 1 << iota // HashSize of array used to store hashes. See Hash. HashSize = 32 // MaxMessagePayload is the maximum bytes a message can be regardless of other // individual limits imposed by messages themselves. MaxMessagePayload = uint32(1024*1024*32) * 2 // 32MB )
const ( // TxVersion is the current latest supported transaction version. TxVersion = 1 // MaxTxInSequenceNum is the maximum sequence number the sequence field // of a transaction input can be. MaxTxInSequenceNum uint32 = 0xffffffff // MaxPrevOutIndex is the maximum index the index field of a previous // outpoint can be. MaxPrevOutIndex uint32 = 0xffffffff // SequenceLockTimeDisabled is a flag that if set on a transaction // input's sequence number, the sequence number will not be interpreted // as a relative locktime. SequenceLockTimeDisabled = 1 << 31 // SequenceLockTimeIsSeconds is a flag that if set on a transaction // input's sequence number, the relative locktime has units of 512 // seconds. SequenceLockTimeIsSeconds = 1 << 22 // SequenceLockTimeMask is a mask that extracts the relative locktime // when masked against the transaction input sequence number. SequenceLockTimeMask = 0x0000ffff // SequenceLockTimeGranularity is the defined time based granularity // for seconds-based relative time locks. When converting from seconds // to a sequence number, the value is right shifted by this amount, // therefore the granularity of relative time locks in 512 or 2^9 // seconds. Enforced relative lock times are multiples of 512 seconds. SequenceLockTimeGranularity = 9 // MinTxOutPayload is the minimum payload size for a transaction output. // Value 8 bytes + Varint for PkScript length 1 byte. MinTxOutPayload = 9 )
Variables ¶
This section is empty.
Functions ¶
func RandomUint64 ¶
RandomUint64 returns a cryptographically random uint64 value.
func ReadVarBytes ¶
ReadVarBytes reads a variable length byte array. A byte array is encoded as a varInt containing the length of the array followed by the bytes themselves. An error is returned if the length is greater than the passed maxAllowed parameter which helps protect against memory exhaustion attacks and forced panics through malformed messages. The fieldName parameter is only used for the error message so it provides more context in the error.
func ReadVarInt ¶
ReadVarInt reads a variable length integer from r and returns it as a uint64.
func ReadVarString ¶
ReadVarString reads a variable length string from r and returns it as a Go string. A variable length string is encoded as a variable length integer containing the length of the string followed by the bytes that represent the string itself. An error is returned if the length is greater than the maximum block payload size since it helps protect against memory exhaustion attacks and forced panics through malformed messages.
func VarIntSerializeSize ¶
VarIntSerializeSize returns the number of bytes it would take to serialize val as a variable length integer.
func WriteTxOut ¶
WriteTxOut encodes to into the bitcoin protocol encoding for a transaction output (TxOut) to w.
NOTE: This function is exported in order to allow txscript to compute the new sighashes for witness transactions (BIP0143).
func WriteVarBytes ¶
WriteVarBytes serializes a variable length byte array to w as a varInt containing the number of bytes, followed by the bytes themselves.
func WriteVarInt ¶
WriteVarInt serializes val to w using a variable number of bytes depending on its value.
Types ¶
type MessageEncoding ¶
type MessageEncoding uint32
MessageEncoding represents the wire message encoding format to be used.
type MessageError ¶
type MessageError struct { Func string // Function name Description string // Human readable description of the issue }
MessageError describes an issue with a message. An example of some potential issues are messages from the wrong bitcoin network, invalid commands, mismatched checksums, and exceeding max payloads.
This provides a mechanism for the caller to type assert the error to differentiate between general io errors such as io.EOF and issues that resulted from malformed messages.
func (*MessageError) Error ¶
func (e *MessageError) Error() string
Error satisfies the error interface and prints human-readable errors.
type MsgTx ¶
MsgTx implements the Message interface and represents a bitcoin tx message. It is used to deliver transaction information in response to a getdata message (MsgGetData) for a given transaction.
Use the AddTxIn and AddTxOut functions to build up the list of transaction inputs and outputs.
func NewMsgTx ¶
NewMsgTx returns a new bitcoin tx message that conforms to the Message interface. The return instance has a default version of TxVersion and there are no transaction inputs or outputs. Also, the lock time is set to zero to indicate the transaction is valid immediately as opposed to some time in future.
func (*MsgTx) BchDecode ¶
BchDecode decodes r using the bitcoin protocol encoding into the receiver. This is part of the Message interface implementation. See Deserialize for decoding transactions stored to disk, such as in a database, as opposed to decoding transactions from the wire.
func (*MsgTx) BchEncode ¶
BchEncode encodes the receiver to w using the bitcoin protocol encoding. This is part of the Message interface implementation. See Serialize for encoding transactions to be stored to disk, such as in a database, as opposed to encoding transactions for the wire.
func (*MsgTx) Command ¶
Command returns the protocol command string for the message. This is part of the Message interface implementation.
func (*MsgTx) Copy ¶
Copy creates a deep copy of a transaction so that the original does not get modified when the copy is manipulated.
func (*MsgTx) Deserialize ¶
Deserialize decodes a transaction from r into the receiver using a format that is suitable for long-term storage such as a database while respecting the Version field in the transaction. This function differs from BchDecode in that BchDecode decodes from the bitcoin wire protocol as it was sent across the network. The wire encoding can technically differ depending on the protocol version and doesn't even really need to match the format of a stored transaction at all. As of the time this comment was written, the encoded transaction is the same in both instances, but there is a distinct difference and separating the two allows the API to be flexible enough to deal with changes.
func (*MsgTx) MaxPayloadLength ¶
MaxPayloadLength returns the maximum length the payload can be for the receiver. This is part of the Message interface implementation.
func (*MsgTx) PkScriptLocs ¶
PkScriptLocs returns a slice containing the start of each public key script within the raw serialized transaction. The caller can easily obtain the length of each script by using len on the script available via the appropriate transaction output entry.
func (*MsgTx) Serialize ¶
Serialize encodes the transaction to w using a format that suitable for long-term storage such as a database while respecting the Version field in the transaction. This function differs from BchEncode in that BchEncode encodes the transaction to the bitcoin wire protocol in order to be sent across the network. The wire encoding can technically differ depending on the protocol version and doesn't even really need to match the format of a stored transaction at all. As of the time this comment was written, the encoded transaction is the same in both instances, but there is a distinct difference and separating the two allows the API to be flexible enough to deal with changes.
func (*MsgTx) SerializeSize ¶
SerializeSize returns the number of bytes it would take to serialize the the transaction.
type OutPoint ¶
OutPoint defines a bitcoin data type that is used to track previous transaction outputs.
func NewOutPoint ¶
NewOutPoint returns a new bitcoin transaction outpoint point with the provided hash and index.
type TxIn ¶
TxIn defines a bitcoin transaction input.
func NewTxIn ¶
NewTxIn returns a new bitcoin transaction input with the provided previous outpoint point and signature script with a default sequence of MaxTxInSequenceNum.
func (*TxIn) SerializeSize ¶
SerializeSize returns the number of bytes it would take to serialize the the transaction input.
type TxOut ¶
TxOut defines a bitcoin transaction output.
func NewTxOut ¶
NewTxOut returns a new bitcoin transaction output with the provided transaction value and public key script.
func (*TxOut) SerializeSize ¶
SerializeSize returns the number of bytes it would take to serialize the the transaction output.