Neil Booth
8 years ago
1 changed files with 738 additions and 0 deletions
@ -0,0 +1,738 @@ |
|||||
|
================= |
||||
|
Electrum Protocol |
||||
|
================= |
||||
|
|
||||
|
Until now there was no written specification of the Electrum protocol |
||||
|
that I am aware of; this document is an attempt to fill that gap. It |
||||
|
is intended to be a reference for client and server authors alike. |
||||
|
|
||||
|
I have attempted to ensure what is written is correct for the three |
||||
|
known server implementations: electrum-server, jelectrum and |
||||
|
ElectrumX, and also for Electrum clients of the 2.x series. We know |
||||
|
other clients exist but I am not aware of the source of any being |
||||
|
publicly available. |
||||
|
|
||||
|
|
||||
|
Message Stream |
||||
|
-------------- |
||||
|
|
||||
|
Clients and servers communicate using JSON RPC over an unspecified |
||||
|
underlying stream transport protocol, typically TCP or SSL. |
||||
|
|
||||
|
`JSON RPC 1.0`_ and `JSON RPC 2.0`_ are specified; use of version 2.0 |
||||
|
is encouraged but not required. Server support of batch requests is |
||||
|
encouraged for version 1.0 but not required. Clients making batch |
||||
|
requests should limit their size depending on the nature of their |
||||
|
query, because servers will limit response size as an anti-DoS |
||||
|
mechanism. |
||||
|
|
||||
|
RPC calls and responses are separated by newlines in the stream. The |
||||
|
JSON specification does not permit control characters within strings, |
||||
|
so no confusion is possible there. However it does permit newlines as |
||||
|
extraneous whitespace between elements; client and server MUST NOT use |
||||
|
newlines in such a way. |
||||
|
|
||||
|
If using JSON RPC 2.0's feature of parameter passing by name, the |
||||
|
names shown in the protocol versions's description MUST be used. |
||||
|
|
||||
|
A server advertising support for a particular protocol version MUST |
||||
|
support each method documented for that protocol version, unless the |
||||
|
method is explicitly marked optional. It may support other methods or |
||||
|
additional parameters with unspecified behaviour. Use of additional |
||||
|
parameters is discouraged as it may conflict with future versions of |
||||
|
the protocol. |
||||
|
|
||||
|
Notifications |
||||
|
------------- |
||||
|
|
||||
|
Some methods are subscriptions, which will respond with notifications |
||||
|
when the thing subscribed to changes. The `method` of the |
||||
|
notification is the same as the method of the subscription, and the |
||||
|
`params` of the notification (and their names) are given in the |
||||
|
documentation of the method. |
||||
|
|
||||
|
|
||||
|
Protocol Negotiation |
||||
|
-------------------- |
||||
|
|
||||
|
It is desirable to have a way to enhance and improve the protocol |
||||
|
without forcing servers and clients to upgrade at the same time. |
||||
|
Protocol negotiation is not implemented in any client or server at |
||||
|
present to the best of my knowledge, so care is needed to ensure |
||||
|
current clients and servers continue to operate as expected. |
||||
|
|
||||
|
Protocol versions are denoted by [major_number, minor_number] pairs, |
||||
|
for example protocol version 1.15 is [1, 15] as a pair. |
||||
|
|
||||
|
A party to a connection speak all protocol versions in a range, say |
||||
|
from `protocol_min` to `protocol_max`. This min and max may be the |
||||
|
same. When a connection is made, both client and server must |
||||
|
initially assume the protocol to use is their own `protocol_min`. |
||||
|
|
||||
|
The client should send a `server.version` RPC call as early as |
||||
|
possible in order to negotiate the precise protocol version; see its |
||||
|
description for more detail. All responses received in the stream |
||||
|
from and including the server's response to this call will use the |
||||
|
negotiated protocol version. |
||||
|
|
||||
|
|
||||
|
Protocol Version 1.0 |
||||
|
-------------------- |
||||
|
|
||||
|
server.version |
||||
|
============== |
||||
|
|
||||
|
Identifies the client to the server. |
||||
|
|
||||
|
server.version(**client_name**, **protocol_version**) |
||||
|
|
||||
|
**client_name** |
||||
|
|
||||
|
An optional string identifying the connecting client software. |
||||
|
|
||||
|
**protocol_verion** |
||||
|
|
||||
|
Optional. The value passed is ignored. |
||||
|
|
||||
|
**Response** |
||||
|
|
||||
|
A string identifying the server software. |
||||
|
|
||||
|
**Example**:: |
||||
|
|
||||
|
server.version("2.7.11", "1.0") |
||||
|
|
||||
|
|
||||
|
blockchain.address.get_balance |
||||
|
============================== |
||||
|
|
||||
|
Return the confirmed and unconfirmed balances of a bitcoin address. |
||||
|
|
||||
|
blockchain.address.get_balance(**address**) |
||||
|
|
||||
|
**address** |
||||
|
|
||||
|
The address as a Base58 string. |
||||
|
|
||||
|
**Response** |
||||
|
|
||||
|
A dictionary with keys *confirmed* and *unconfirmed*. The value of |
||||
|
each is the appropriate balance in coin units as a string. |
||||
|
|
||||
|
**Response Example**:: |
||||
|
|
||||
|
{ |
||||
|
"confirmed": "1.03873966", |
||||
|
"unconfirmed": "0.236844" |
||||
|
} |
||||
|
|
||||
|
|
||||
|
blockchain.address.get_history |
||||
|
============================== |
||||
|
|
||||
|
Return the confirmed and unconfirmed history of a bitcoin address. |
||||
|
|
||||
|
blockchain.address.get_history(**address**) |
||||
|
|
||||
|
**address** |
||||
|
|
||||
|
The address as a Base58 string. |
||||
|
|
||||
|
**Response** |
||||
|
|
||||
|
A list of confirmed transactions in blockchain order, with the |
||||
|
output of *blockchain.address.get_mempool* appended to the list. |
||||
|
Each transaction is a dictionary with keys *height* and *tx_hash*. |
||||
|
*height* is the integer height of the block the transaction was |
||||
|
confirmed in, and *tx_hash* the transaction hash in hexadecimal. |
||||
|
|
||||
|
**Response Examples** |
||||
|
|
||||
|
:: |
||||
|
|
||||
|
[ |
||||
|
{ |
||||
|
"height": 200004, |
||||
|
"tx_hash": "acc3758bd2a26f869fcc67d48ff30b96464d476bca82c1cd6656e7d506816412" |
||||
|
}, |
||||
|
{ |
||||
|
"height": 215008, |
||||
|
"tx_hash": "f3e1bf48975b8d6060a9de8884296abb80be618dc00ae3cb2f6cee3085e09403" |
||||
|
} |
||||
|
] |
||||
|
|
||||
|
:: |
||||
|
|
||||
|
[ |
||||
|
{ |
||||
|
"fee": 20000, |
||||
|
"height": 0, |
||||
|
"tx_hash": "9fbed79a1e970343fcd39f4a2d830a6bde6de0754ed2da70f489d0303ed558ec" |
||||
|
} |
||||
|
] |
||||
|
|
||||
|
|
||||
|
blockchain.address.get_mempool |
||||
|
============================== |
||||
|
|
||||
|
Return the unconfirmed transactions of a bitcoin address. |
||||
|
|
||||
|
blockchain.address.get_mempool(**address**) |
||||
|
|
||||
|
**address** |
||||
|
|
||||
|
The address as a Base58 string. |
||||
|
|
||||
|
**Response** |
||||
|
|
||||
|
A list of mempool transactions in arbitrary order. Each |
||||
|
transaction is a dictionary with keys *height* , *tx_hash* and |
||||
|
*fee*. *tx_hash* the transaction hash in hexadecimal, *height* is |
||||
|
`0` if all inputs are confirmed, and `-1` otherwise, and *fee* is |
||||
|
the transaction fee in coin units. |
||||
|
|
||||
|
**Response Examples** |
||||
|
|
||||
|
:: |
||||
|
|
||||
|
[ |
||||
|
{ |
||||
|
"tx_hash": "45381031132c57b2ff1cbe8d8d3920cf9ed25efd9a0beb764bdb2f24c7d1c7e3", |
||||
|
"height": 0, |
||||
|
"fee": 24310 |
||||
|
} |
||||
|
] |
||||
|
|
||||
|
|
||||
|
blockchain.address.get_proof |
||||
|
============================ |
||||
|
|
||||
|
This method is optional and deprecated, and hence its response will |
||||
|
not be described here. |
||||
|
|
||||
|
blockchain.address.get_proof(**address**) |
||||
|
|
||||
|
**address** |
||||
|
|
||||
|
The address as a Base58 string. |
||||
|
|
||||
|
|
||||
|
blockchain.address.listunspent |
||||
|
============================== |
||||
|
|
||||
|
Return an ordered list of UTXOs sent to a bitcoin address. |
||||
|
|
||||
|
blockchain.address.listunspent(**address**) |
||||
|
|
||||
|
**address** |
||||
|
|
||||
|
The address as a Base58 string. |
||||
|
|
||||
|
**Response** |
||||
|
|
||||
|
A list of unspent outputs in blockchain order. Each transaction |
||||
|
is a dictionary with keys *height* , *tx_pos*, *tx_height* and |
||||
|
*value* keys. *height* is the integer height of the block the |
||||
|
transaction was confirmed in, *tx_hash* the transaction hash in |
||||
|
hexadecimal, *tx_pos* the zero-based index of the output in the |
||||
|
transaction's list of outputs, and *value* its integer value in |
||||
|
minimum coin units (satoshis in the case of Bitcoin). |
||||
|
|
||||
|
**Response Example** |
||||
|
|
||||
|
:: |
||||
|
|
||||
|
[ |
||||
|
{ |
||||
|
"tx_pos": 0, |
||||
|
"value": 45318048, |
||||
|
"tx_hash": "9f2c45a12db0144909b5db269415f7319179105982ac70ed80d76ea79d923ebf", |
||||
|
"height": 437146 |
||||
|
}, |
||||
|
{ |
||||
|
"tx_pos": 0, |
||||
|
"value": 919195, |
||||
|
"tx_hash": "3d2290c93436a3e964cfc2f0950174d8847b1fbe3946432c4784e168da0f019f", |
||||
|
"height": 441696 |
||||
|
} |
||||
|
] |
||||
|
|
||||
|
|
||||
|
blockchain.address.subscribe |
||||
|
============================ |
||||
|
|
||||
|
Subscribe to a bitcoin address. |
||||
|
|
||||
|
blockchain.address.subscribe(**address**) |
||||
|
|
||||
|
**address** |
||||
|
|
||||
|
The address as a Base58 string. |
||||
|
|
||||
|
**Response** |
||||
|
|
||||
|
The *status* [1]_ of the address. |
||||
|
|
||||
|
**Notifications** |
||||
|
|
||||
|
As this is a subcription, the client will receive a notification |
||||
|
when the status of the address changes. The parameters are: |
||||
|
|
||||
|
[**address**, **status**] |
||||
|
|
||||
|
.. [1] To calculate the *status* of an address, order confirmed |
||||
|
transactions touching the address by height (and position in |
||||
|
the block if there are more than one in a block). Form a |
||||
|
string that is the concatenation of strings 'tx_hash:height:' |
||||
|
for each transaction in order. *tx_hash* is the transaction |
||||
|
hash in hexadecimal, *height* the height of the block it is in. |
||||
|
Next, with mempool transactions in any order, append a string |
||||
|
that is the same, but where *height* is `-1` if the transaction |
||||
|
has at least one unconfirmed input, and `0` if all inputs are |
||||
|
confirmed. The *status* is the **sha256** hash of this string |
||||
|
expressed in hexadecimal. |
||||
|
|
||||
|
|
||||
|
blockchain.block.get_header |
||||
|
=========================== |
||||
|
|
||||
|
Return the *deserialized header* [2]_ of the block at the given height. |
||||
|
|
||||
|
blockchain.block.get_chunk(**height**) |
||||
|
|
||||
|
**height** |
||||
|
|
||||
|
The height of the block, an integer. |
||||
|
|
||||
|
**Response** |
||||
|
|
||||
|
.. [2] The *deserialized header* of a block is a dictionary like |
||||
|
so:: |
||||
|
|
||||
|
{ |
||||
|
"block_height": <integer>, |
||||
|
'version': <integer>, |
||||
|
'prev_block_hash': <hexadecimal string>, |
||||
|
'merkle_root': <hexadecimal string>, |
||||
|
'timestamp': <integer>, |
||||
|
'bits': <integer>, |
||||
|
'nonce': <integer>, |
||||
|
} |
||||
|
|
||||
|
|
||||
|
blockchain.block.get_chunk |
||||
|
========================== |
||||
|
|
||||
|
Return a concatenated chunk of block headers. A chunk consists of a |
||||
|
fixed number of block headers over at the end of which difficulty is |
||||
|
retargeted. |
||||
|
|
||||
|
So in the case of Bitcoin a chunk is 2,016 headers, each of 80 bytes, |
||||
|
and chunk 5 is the block headers from height 10,080 to 12,095 |
||||
|
inclusive. When encoded as hexadecimal, the response string is twice |
||||
|
as long, so for Bitcoin it is 322,560 bytes long, making this a |
||||
|
bandwidth-intensive request. |
||||
|
|
||||
|
blockchain.block.get_chunk(**index**) |
||||
|
|
||||
|
**index** |
||||
|
|
||||
|
The zero-based index of the chunk, an integer. |
||||
|
|
||||
|
**Response** |
||||
|
|
||||
|
The binary block headers, as hexadecimal strings, in order |
||||
|
concatenated together. |
||||
|
|
||||
|
|
||||
|
blockchain.estimatefee |
||||
|
====================== |
||||
|
|
||||
|
Return the estimated transaction fee per kilobyte for a transaction to |
||||
|
be confirmed within a certain number of blocks. |
||||
|
|
||||
|
blockchain.block.get_chunk(**number**) |
||||
|
|
||||
|
**number** |
||||
|
|
||||
|
The number of blocks to target for confirmation. |
||||
|
|
||||
|
**Response** |
||||
|
|
||||
|
The estimated transaction fee in coin units per kilobyte, as a |
||||
|
floating point number. If the daemon does not have enough |
||||
|
information to make an estimate, the integer `-1` is returned. |
||||
|
|
||||
|
**Example Response** |
||||
|
|
||||
|
:: |
||||
|
0.00101079 |
||||
|
|
||||
|
|
||||
|
blockchain.headers.subscribe |
||||
|
============================ |
||||
|
|
||||
|
Subscribe to receive block headers when a new block is found. |
||||
|
|
||||
|
blockchain.headers.subscribe() |
||||
|
|
||||
|
**Response** |
||||
|
|
||||
|
The *deserialized header* [2]_ of the current block. |
||||
|
|
||||
|
**Notification Parameters** |
||||
|
|
||||
|
As this is a subcription, the client will receive a notification |
||||
|
when a new block is found. The parameters are: |
||||
|
|
||||
|
[**header**] |
||||
|
|
||||
|
|
||||
|
blockchain.numblocks.subscribe |
||||
|
============================== |
||||
|
|
||||
|
Subscribe to receive the block height when a new block is found. This |
||||
|
subscription is deprecated in favour of *blockchain.headers.subscribe* |
||||
|
which provides more detailed information. |
||||
|
|
||||
|
blockchain.numblocks.subscribe() |
||||
|
|
||||
|
**Response** |
||||
|
|
||||
|
The height of the current block, an integer |
||||
|
|
||||
|
**Notification Parameters** |
||||
|
|
||||
|
As this is a subcription, the client will receive a notification |
||||
|
when a new block is found. The parameters are: |
||||
|
|
||||
|
[**height**] |
||||
|
|
||||
|
|
||||
|
blockchain.relayfee |
||||
|
=================== |
||||
|
|
||||
|
Return the minimum fee a low-priority tx must pay in order to be accepted |
||||
|
to the daemon's memory pool. |
||||
|
|
||||
|
blockchain.relayfee() |
||||
|
|
||||
|
**Response** |
||||
|
|
||||
|
The fee in coin units as a floating point number. |
||||
|
|
||||
|
**Example Responses** |
||||
|
|
||||
|
:: |
||||
|
1e-05 |
||||
|
|
||||
|
:: |
||||
|
0.0 |
||||
|
|
||||
|
blockchain.transaction.broadcast |
||||
|
================================ |
||||
|
|
||||
|
Broadcast a transaction to the network. |
||||
|
|
||||
|
blockchain.transaction.broadcast(**raw_tx**) |
||||
|
|
||||
|
**raw_tx** |
||||
|
|
||||
|
The raw transaction as a hexadecimal string. |
||||
|
|
||||
|
**Response** |
||||
|
|
||||
|
Unfortunately the protocol version 1.0 API does not obey the JSON |
||||
|
specification for the response; this will be fixed in a future |
||||
|
version of the protocol. |
||||
|
|
||||
|
If the daemon accepts the transaction, return the transaction hash |
||||
|
as a hexadecimal string. If the daemon rejects the transaction, the |
||||
|
server must not return an error, but instead return the error |
||||
|
message string as the result. The client needs to determine if an |
||||
|
error occurred by comparing the result to the expected transaction |
||||
|
hash. |
||||
|
|
||||
|
**Response Examples** |
||||
|
|
||||
|
:: |
||||
|
|
||||
|
'a76242fce5753b4212f903ff33ac6fe66f2780f34bdb4b33b175a7815a11a98e' |
||||
|
|
||||
|
:: |
||||
|
|
||||
|
'258: txn-mempool-conflict' |
||||
|
|
||||
|
|
||||
|
blockchain.transaction.get |
||||
|
========================== |
||||
|
|
||||
|
Return a raw transaction. |
||||
|
|
||||
|
blockchain.transaction.get(**tx_hash**, **height**) |
||||
|
|
||||
|
**tx_hash** |
||||
|
|
||||
|
The transaction hash as a hexadecimal string. |
||||
|
|
||||
|
**height** |
||||
|
|
||||
|
The height at which it was confirmed, an integer. This parameter |
||||
|
is optional and ignored; it is recommended that clients do not |
||||
|
send it as it will be removed in a future protocol version. |
||||
|
|
||||
|
**Response** |
||||
|
|
||||
|
The raw transaction as a hexadecimal string. |
||||
|
|
||||
|
|
||||
|
blockchain.transaction.get_merkle |
||||
|
================================= |
||||
|
|
||||
|
Return the markle branch to a confirmed transaction given its hash |
||||
|
and height. |
||||
|
|
||||
|
blockchain.transaction.get(**tx_hash**, **height**) |
||||
|
|
||||
|
**tx_hash** |
||||
|
|
||||
|
The transaction hash as a hexadecimal string. |
||||
|
|
||||
|
**height** |
||||
|
|
||||
|
The height at which it was confirmed, an integer. |
||||
|
|
||||
|
**Response** |
||||
|
|
||||
|
A dictionary with keys *block_height*, *merkle* and *pos*. |
||||
|
*block_height* is the height of the block the transaction was |
||||
|
confirmed in. *merkle* is a list of transaction hashes the current |
||||
|
hash is paired with, recursively, in order to trace up to obtain |
||||
|
merkle root of the block, deepest pairing first. *pos* is the |
||||
|
0-based index of the position of the transaction in the ordered list |
||||
|
of transactions in the block. |
||||
|
|
||||
|
**Response Examples** |
||||
|
|
||||
|
:: |
||||
|
|
||||
|
{ |
||||
|
"merkle": |
||||
|
[ |
||||
|
"713d6c7e6ce7bbea708d61162231eaa8ecb31c4c5dd84f81c20409a90069cb24", |
||||
|
"03dbaec78d4a52fbaf3c7aa5d3fccd9d8654f323940716ddf5ee2e4bda458fde", |
||||
|
"e670224b23f156c27993ac3071940c0ff865b812e21e0a162fe7a005d6e57851", |
||||
|
"369a1619a67c3108a8850118602e3669455c70cdcdb89248b64cc6325575b885", |
||||
|
"4756688678644dcb27d62931f04013254a62aeee5dec139d1aac9f7b1f318112", |
||||
|
"7b97e73abc043836fd890555bfce54757d387943a6860e5450525e8e9ab46be5", |
||||
|
"61505055e8b639b7c64fd58bce6fc5c2378b92e025a02583303f69930091b1c3", |
||||
|
"27a654ff1895385ac14a574a0415d3bbba9ec23a8774f22ec20d53dd0b5386ff", |
||||
|
"5312ed87933075e60a9511857d23d460a085f3b6e9e5e565ad2443d223cfccdc", |
||||
|
"94f60b14a9f106440a197054936e6fb92abbd69d6059b38fdf79b33fc864fca0", |
||||
|
"2d64851151550e8c4d337f335ee28874401d55b358a66f1bafab2c3e9f48773d" |
||||
|
], |
||||
|
"block_height": 450538, |
||||
|
"pos": 710 |
||||
|
} |
||||
|
|
||||
|
|
||||
|
blockchain.utxo.get_address |
||||
|
=========================== |
||||
|
|
||||
|
Return the address paid to by a UTXO. This method is optional and |
||||
|
deprecated. |
||||
|
|
||||
|
blockchain.utxo.get_address(**tx_hash**, **index**) |
||||
|
|
||||
|
**tx_hash** |
||||
|
|
||||
|
The transaction hash as a hexadecimal string. |
||||
|
|
||||
|
**index** |
||||
|
|
||||
|
The zero-based index of the UTXO in the transaction. |
||||
|
|
||||
|
**Response** |
||||
|
|
||||
|
A Base58 address string, or *null*. If the transaction doesn't |
||||
|
exist, the index is out of range, or the output is not paid to and |
||||
|
address, *null* must be returned. If the output is spent *null* may |
||||
|
be returned. |
||||
|
|
||||
|
|
||||
|
server.banner |
||||
|
============= |
||||
|
|
||||
|
Return a banner to be shown in the Electrum console. |
||||
|
|
||||
|
server.banner() |
||||
|
|
||||
|
The return value is a string. |
||||
|
|
||||
|
|
||||
|
server.donation_address |
||||
|
======================= |
||||
|
|
||||
|
Return a server donation address. |
||||
|
|
||||
|
server.donation_address() |
||||
|
|
||||
|
The return value is a string. |
||||
|
|
||||
|
|
||||
|
server.peers.subscribe |
||||
|
====================== |
||||
|
|
||||
|
Return a list of peer servers. Despite the name this is not a |
||||
|
subscription and the server must send no notifications. |
||||
|
|
||||
|
server.peers.subscribe() |
||||
|
|
||||
|
**Response** |
||||
|
|
||||
|
An array of peer servers. Each entry is a triple like |
||||
|
|
||||
|
["107.150.45.210", "e.anonyhost.org", ["v1.0", "p10000", "t", "s995"]] |
||||
|
|
||||
|
The first element is the IP address, the second is the host name |
||||
|
(which might also be an IP address), and the third is a list of |
||||
|
server features. Each feature and starts with a letter. 'v' |
||||
|
indicates the server minimum protocol version, 'p' its pruning limit |
||||
|
and is omitted if it does not prune, 't' is the TCP port number, and |
||||
|
's' is the SSL port number. If a port is not given for 's' or 't' |
||||
|
the default port for the coin network is implied. If 's' or 't' is |
||||
|
missing then the server does not support that transport. |
||||
|
|
||||
|
|
||||
|
Version 1.1 (provisional) |
||||
|
------------------------- |
||||
|
|
||||
|
This protocol version is the same as version `1.0` except for the |
||||
|
following changes: |
||||
|
|
||||
|
* improved semantics of `server.version` to aid protocol negotiation |
||||
|
* deprecated methods `blockchain.address.get_proof`, |
||||
|
'blockchain.utxo.get_address' and `blockchain.numblocks.subscribe` |
||||
|
have been removed. |
||||
|
* method `blockchain.transaction.get` no longer takes a *height* |
||||
|
argument |
||||
|
* method `blockchain.transaction.broadcast` returns errors like any |
||||
|
other JSON RPC call. A *tx_hash* result is only returned on |
||||
|
success. |
||||
|
* new methods `server.features` and `server.add_peer` |
||||
|
|
||||
|
|
||||
|
server.version |
||||
|
============== |
||||
|
|
||||
|
Identify the client and inform the server the range of understood |
||||
|
protocol versions. |
||||
|
|
||||
|
server.version(**client_name**, **protocol_version** = ((1, 1), (1, 1))) |
||||
|
|
||||
|
**client_name** |
||||
|
|
||||
|
An optional string identifying the connecting client software. |
||||
|
|
||||
|
**protocol_verion** |
||||
|
|
||||
|
Optional with default value ((1, 1), (1, 1)). |
||||
|
|
||||
|
It must be a pair [`protocol_min`, `protocol_max`], each of which is |
||||
|
itself a [major_version, minor_version] pair. |
||||
|
|
||||
|
If a string was passed it should be interpreted as `protocol_min` and |
||||
|
`protocol_max` both being [1, 0]. |
||||
|
|
||||
|
The server should use the highest protocol version both support: |
||||
|
|
||||
|
protocol_version_to_use = min(client.protocol_max, server.protocol_max) |
||||
|
|
||||
|
If this is below |
||||
|
|
||||
|
min(client.protocol_min, server.protocol_min) |
||||
|
|
||||
|
there is no protocol version in common and the server must close the |
||||
|
connection. Otherwise it should send a response appropriate for that |
||||
|
protocol version. |
||||
|
|
||||
|
**Response** |
||||
|
|
||||
|
A pair |
||||
|
|
||||
|
[identifying_string, protocol_version] |
||||
|
|
||||
|
identifying the server and the protocol version that will be used |
||||
|
for future communication. |
||||
|
|
||||
|
**Example** |
||||
|
|
||||
|
:: |
||||
|
|
||||
|
server.version('2.7.11', ((1, 0), (2, 0))) |
||||
|
|
||||
|
|
||||
|
server.add_peer |
||||
|
=============== |
||||
|
|
||||
|
This call is intended for a new server to get itself into the server's |
||||
|
peers list. |
||||
|
|
||||
|
server.add_peer(**features**) |
||||
|
|
||||
|
* **features** |
||||
|
|
||||
|
The same information as a call to the client server's |
||||
|
**server.features** RPC call would return. |
||||
|
|
||||
|
|
||||
|
server.features |
||||
|
=============== |
||||
|
|
||||
|
Get a list of features and services supported by the server. |
||||
|
|
||||
|
server.features() |
||||
|
|
||||
|
**Response** |
||||
|
|
||||
|
A dictionary of keys and values. Each key represents a feature or |
||||
|
service of the server, and the value gives additional information. |
||||
|
|
||||
|
The following features MUST be reported by the server. Additional |
||||
|
key-value pairs may be returned. |
||||
|
|
||||
|
* **hosts** |
||||
|
|
||||
|
A dictionary of host names the server can be reached at. Each |
||||
|
value is a dictionary with keys "ssl_port" and "tcp_port" at which |
||||
|
the given host can be reached. If there is no open port for a |
||||
|
transport, its value should be *null*. |
||||
|
|
||||
|
* **server_version** |
||||
|
|
||||
|
The same identifying string as returned in response to *server.version*. |
||||
|
|
||||
|
* **protocol_version** |
||||
|
|
||||
|
A pair [`protocol_min`, `protocol_max`] of the protocols supported |
||||
|
by the server, each of which is itself a [major_version, |
||||
|
minor_version] pair. |
||||
|
|
||||
|
* **pruning** |
||||
|
|
||||
|
The history pruning limit of the server. If the server does not |
||||
|
prune return *null*. |
||||
|
|
||||
|
**Example Response** |
||||
|
|
||||
|
:: |
||||
|
|
||||
|
{ |
||||
|
"server_version": "ElectrumX 0.10.14", |
||||
|
"protocol_version": [[1, 0], [1, 1]], |
||||
|
"hosts": {"14.3.140.101": {"ssl_port": 50002, "tcp_port": 50001}}, |
||||
|
"pruning": null |
||||
|
} |
||||
|
|
||||
|
.. _JSON RPC 1.0: http://json-rpc.org/wiki/specification |
||||
|
.. _JSON RPC 2.0: http://json-rpc.org/specification |
Loading…
Reference in new issue