You've already forked specification
Initial commit
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 bitcoin-unlimited
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1 @@
|
||||
test C
|
||||
@@ -0,0 +1,91 @@
|
||||
<div class="cwikmeta">
|
||||
{
|
||||
"title": "CWIK"
|
||||
} </div>
|
||||
|
||||
## Overview
|
||||
|
||||
*Cwik* (pronounced 'quick') is an editable documentation web site (wiki) that is quite different from what has been done before:
|
||||
|
||||
- All pages are stored in an enhanced Markdown format
|
||||
- Pages are stored in a source control system (git)
|
||||
- Edits are signed by cryptocurrency tokens
|
||||
- Integrated with source code documentation generators
|
||||
|
||||
## Enhanced Markdown
|
||||
Here are some examples:
|
||||
|
||||
### Math
|
||||
[Full Documentation](https://katex.org/docs/supported.html)
|
||||
The *Gamma function* satisfying $\Gamma(n) = (n-1)!\quad\forall n\in\mathbb N$ is via the Euler integral
|
||||
$$
|
||||
\Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,.
|
||||
$$
|
||||
|
||||
### Flowchart
|
||||
[Full Documentation](https://mermaidjs.github.io/#/flowchart)
|
||||
```mermaid
|
||||
graph LR
|
||||
A[Square Rect] -- paren type controls shape --> B((Circle))
|
||||
A --> C(Round Rect)
|
||||
B --> D{Rhombus}
|
||||
C --> D
|
||||
```
|
||||
|
||||
```mermaid
|
||||
graph BT
|
||||
A["bottom"] == Link text ==> B[TOP]
|
||||
style B fill:#906,stroke:#333,stroke-width:2px;
|
||||
style A fill:#ff6,stroke:#333,stroke-width:8px;
|
||||
```
|
||||
```mermaid
|
||||
graph RL
|
||||
%% Comments after double percent signs
|
||||
A(("(){}[]"))-->B>";place special chars in quotes"]
|
||||
```
|
||||
|
||||
### Protocol (Sequence) diagram
|
||||
[Full Documentation](https://mermaidjs.github.io/#/sequenceDiagram)
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
Alice ->> Bob: Hello Bob, how are you?
|
||||
Bob-->>John: How about you John?
|
||||
Bob--x Alice: I am good thanks!
|
||||
Bob-x John: I am good thanks!
|
||||
Note right of John: Bob thinks a long<br/>long time, so long<br/>that the text does<br/>not fit on a row.
|
||||
|
||||
Bob-->Alice: Checking with John...
|
||||
Alice->John: Yes... John, how are you?
|
||||
```
|
||||
|
||||
## Git storage
|
||||
|
||||
Your changes accumulate in local storage on the server. Press the "commit" button (upper right) to commit all edits.
|
||||
|
||||
Look here: https://github.com/bitcoin-unlimited/BUwiki to see the backing repository.
|
||||
|
||||
## Token Integration
|
||||
TBD
|
||||
|
||||
## Source Documentation Generation
|
||||
**To be implemented**
|
||||
|
||||
This system is able to integrate multiple Git-hosted repositories. A typical configuration would be one documentation focused repository and multiple source repositories. These source repositories can provide inline documentation that is extracted via various documentation generators (subsequently called "codedoc") and provide access to "raw" source code.
|
||||
|
||||
Linking between documentation and code/codedoc or codedoc to codedoc occurs via a special syntax that allows references to code blocks, is tolerant of some code reorganizations, and identifies and records broken links for human repair.
|
||||
|
||||
There is a processing step to convert these links to .md format. So the full source data preparation steps are:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
A["git source code"] == doc generator ==> B["code doc"]
|
||||
D["git doc files"] ==> E(("Link resolver"))
|
||||
A ==> E
|
||||
B ==> E
|
||||
E ==> F["Markdown files"]
|
||||
E ==> G["broken link report<br/>(markdown file)"]
|
||||
style A fill:#ff6,stroke:#333,stroke-width:8px;
|
||||
style D fill:#ff6,stroke:#333,stroke-width:8px;
|
||||
style F fill:#3A3,stroke:#334,stroke-width:4px;
|
||||
style G fill:#3A3,stroke:#334,stroke-width:4px;
|
||||
```
|
||||
@@ -0,0 +1 @@
|
||||
edit 1
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
<div class="cwikmeta">
|
||||
{
|
||||
"title":"Glossary",
|
||||
"related":["/glossary/UTXO","/glossary/UTXO__set"]
|
||||
}
|
||||
</div>
|
||||
|
||||
|
||||
## [A](#A)
|
||||
## [B](#B)
|
||||
[Block](/glossary/block)
|
||||
## [C](#C)
|
||||
[Constraint Script](/glossary/constraint__script)
|
||||
## [H](#H)
|
||||
[Hash Identifier](/glossary/hash__identifier)
|
||||
## [O](#O)
|
||||
[Outpoint](/glossary/outpoint)
|
||||
[Output Script](/glossary/output__script)
|
||||
## [P](#P)
|
||||
[P2PKH](/glossary/p2pkh)
|
||||
[P2SH](/glossary/p2sh)
|
||||
|
||||
## [R](#R)
|
||||
[Redeem Script](/glossary/redeem__script)
|
||||
|
||||
## [T](#T)
|
||||
[Transaction](/glossary/transaction)
|
||||
|
||||
## [U](#U)
|
||||
[UTXO](/glossary/utxo)
|
||||
[UTXO set](/glossary/utxo__set)
|
||||
@@ -0,0 +1,8 @@
|
||||
<div class="cwikmeta">
|
||||
{
|
||||
"title":"Block",
|
||||
"related":[]
|
||||
} </div>
|
||||
|
||||
|
||||
A block is a group of (transactions)[/glossary/transaction] that have been committed to the blockchain.
|
||||
@@ -0,0 +1,10 @@
|
||||
<div class="cwikmeta">
|
||||
{
|
||||
"title":"Constraint Script",
|
||||
"related":["/glossary/output__script","/glossary/redeem__script","/glossary/input__script"]
|
||||
}
|
||||
</div>
|
||||
|
||||
Bitcoins are not sent to addresses, they are actually encumbered by a program (generally called a script, which is a term for a short, simple program that typically focuses on one thing). Spending transactions supply input parameters (in the form of an input script) to this constraint script. If the constraint script returns success, the coins are able to be spent. Otherwise the transaction is invalid.
|
||||
|
||||
The term "constraint script" refers generally to any script that adds spending constraints. In Bitcoin, there are actually two different scripts that can do this -- the [output script](/glossary/output__script) and the [redeem script](/glossary/redeem__script).
|
||||
@@ -0,0 +1,11 @@
|
||||
A hash identifier is sequence of bytes derived from some source data that forms a probabilistically globally unique identifier that can be used to reference the source data.
|
||||
|
||||
Hash identifiers are calculated by running a cryptographically secure hash function on the source data. Due to the properties of cryptographic hash functions, it is theoretically very hard (and in practice, impossible given current or future processing power) to find 2 different pieces of source data that form the same hash identifier in a reasonable time frame.
|
||||
|
||||
This allows hash identifiers to be used in multiple applications, most importantly:
|
||||
|
||||
- As a global "pointer" or "reference" to a piece of source data
|
||||
- As a "fingerprint" that identifies source data.
|
||||
- As a "commitment" that allows an entity to prove it knows some data at this time, without revealing that data until a later time.
|
||||
|
||||
In Bitcoin, hash identifiers (sometimes just called a "hash" for short) are generally calculated using a double sha256 algorithm: SHA256(SHA256(source data)), resulting an a 32 byte hash identifier. However, when a smaller hash is desirable and Wagner's Birthday attack cannot be deployed, bitcoin sometimes uses RIPEMD(SHA256(source data)) which results in a 20 byte hash identifier. Notably, this is used in standard ([P2PKH](/glossary/p2pkh)) bitcoin addresses.
|
||||
@@ -0,0 +1 @@
|
||||
see [outpoint](/glossary/outpoint)
|
||||
@@ -0,0 +1 @@
|
||||
An outpoint is a (transaction [hash identifier](/glossary/hash__identifier), index pair) that uniquely identifies a particular [UTXO](/glossary/UTXO).
|
||||
@@ -0,0 +1,8 @@
|
||||
<div class="cwikmeta">
|
||||
{
|
||||
"title":"Output Script",
|
||||
"related":["/glossary/redeem__script","/glossary/input__script"]
|
||||
}
|
||||
</div>
|
||||
|
||||
The output script constrains the subsequent spend of Bitcoins.
|
||||
@@ -0,0 +1,4 @@
|
||||
<!-- TITLE: P2PKH -->
|
||||
<!-- SUBTITLE: Pay to Public Key Hash (script) -->
|
||||
|
||||
A P2PKH script is the most common [constraint script](/glossary/constraint_script).
|
||||
@@ -0,0 +1,12 @@
|
||||
<!-- TITLE: P2SH -->
|
||||
<!-- SUBTITLE: Pay To Script Hash (script) -->
|
||||
|
||||
Pay to script hash is a special payment destination that consists of two [constraint scripts](/glossary/constraint__script). The first is the output script which must follow a specific form that is recognised by bitcoin software. This output script requires a parameter which is actually another constraint script, called the [redeem script](/glossary/redeem_script). To spend a P2SH output, the input script therefore supplies the redeem script and additional data as stack parameters. The bitcoin software verifies that the redeem script's hash matches that in the output script, and then executes the redeem script (which uses the additional data pushed by the input script). Since the redeem script stack item is executed without any explicit instruction to do so, the P2SH script form breaks the original [script execution model](script/execution__model).
|
||||
|
||||
## Comparison with P2PKH
|
||||
|
||||
The P2SH form places all interesting constraints in the redeem script, whereas previously these constraints were placed in the output script. It is arguably better to place constraints in the redeem script for several reasons:
|
||||
1. Simple Addresses: P2SH allows the receiver to have funds sent to any constraint script, by providing the sender with an address. Previously, a new address form had to be created for every new script type, or in theory the entire constraint script could be sent from receiver to sender (no protocol to do this has been specced or implemented).
|
||||
2. Information Containment: In the original model, the sender places constraints on the receiver's __next__ spend. But what the receiver does with the money next is and should be irrelevant to the sender, except in special circumstances. In those circumstances, P2SH still works -- the receiver and sender can agree on the redeem script beforehand.
|
||||
3. Space Efficiency: P2SH defers providing the redeem script until it is used, replacing it with a 20 byte hash. For non-trivial scripts, this will make the [UTXO set](/glossary/UTXO__set) smaller.
|
||||
4. Privacy: P2SH does not reveal the script contents until it is spent. One drawback of this is that it is not possible to determine whether certain instructions are in use or not. This makes retirement of opcodes impossible. However, its also possible for people to create transactions and not commit them to the blockchain, so the viability of opcode retirement is questionable anyway.
|
||||
@@ -0,0 +1,3 @@
|
||||
<!-- TITLE: Redeem Script -->
|
||||
|
||||
The redeem script is a constraint script that is used in the P2SH payment mode. The redeem script is provided by the spender's input script, however, it is chosen by the original spender. This is possible because the output script constrains the redeem script's hash to match a specific value. In P2SH this is the only constraint allowed by the output script, so the redeem script must implement all other constraints (such as signature checking).
|
||||
@@ -0,0 +1 @@
|
||||
SPV is an acronym for "Simplified Payment Validation".
|
||||
@@ -0,0 +1,4 @@
|
||||
<!-- TITLE: Transaction -->
|
||||
<!-- SUBTITLE: means of transfer -->
|
||||
|
||||
A transaction is how transfers are made in the blockchain. It comprises of a set of input [UTXOs](/glossary/UTXO) which will be spent to a set of output [UTXOs](/glossary/UTXO). The blockchain mining and full node software ensures that every transaction follows the blockchain's rules before admitting the transaction into a block. Verification of a transaction ensures that the input UTXOs have not already been spent, that quantity of input coins is greater than or equal to the quantity of output coins (any extra is given to the miner as a transaction fee), and that the transaction satisifies all spending constraints specified by the UTXO's constraint scripts.
|
||||
@@ -0,0 +1,4 @@
|
||||
<!-- TITLE: UTXO -->
|
||||
<!-- SUBTITLE: Unspent Transaction Output -->
|
||||
|
||||
An unspent transaction output, also called a "coin", is a record in the blockchain of money that can be spent (used as an input in a new transaction). It is essentially a positive balance in the blockchain ledger, and contains a quantity and a spending constraint script.
|
||||
@@ -0,0 +1,6 @@
|
||||
<!-- TITLE: UTXO Set -->
|
||||
<!-- SUBTITLE: Unspent Transaction Output Set -->
|
||||
|
||||
The UTXO set contains information that describes the current spending constraints on every coin in the blockchain at a particular moment (generally "now"). This information is used to determine the validity of new transactions, and to report information such as wallet balances.
|
||||
|
||||
This data is extracted from the blockchain, which contains the full history (all transfers, spent or unspent) of all coins since their creation.
|
||||
@@ -0,0 +1,37 @@
|
||||
<div class="cwikmeta">
|
||||
{
|
||||
"title":"Home",
|
||||
"related":[]
|
||||
}</div>
|
||||
|
||||
## Concepts
|
||||
[Blockchain](blockchain.md)
|
||||
|
||||
[Bloom filter](objects/bloom__filter)
|
||||
|
||||
[Final transactions](/final__transactions.md)
|
||||
|
||||
[Hash reference](hash__reference)
|
||||
|
||||
[Proof of work](proof__of__work)
|
||||
|
||||
[Standard transactions](/standard__transactions.md)
|
||||
|
||||
[Wallet private keys, public keys, and addresses](objects/wallet__objects)
|
||||
|
||||
## Protocols
|
||||
[Full Node (P2P) Protocol](protocol)
|
||||
|
||||
[Light Client (Electron Cash) Protocol](electrs__protocol)
|
||||
|
||||
[Identity Protocol (Login)](identity__protocol)
|
||||
## Software
|
||||
|
||||
[Bitcoin Unlimited Cash Full Node](bu_bitcoind)
|
||||
|
||||
[Cwik (This site's software)](cwik)
|
||||
|
||||
## Miscellaneous
|
||||
[Glossary](glossary)
|
||||
|
||||
[test recursive dir](/newdir/nd/test.md)
|
||||
@@ -0,0 +1,180 @@
|
||||
# Identity Protocol (Login)
|
||||
The identity protocol allows software to interface with a server, securely supplying information such as login credentials and identity information. This “crypto-identity software” could be embedded into bitcoin wallets or be a special purpose app.
|
||||
|
||||
## Overview
|
||||
|
||||
Passwords are a pain and are insecure. If you use the internet, you have no doubt experienced the pain. And much has been written about how human-interaction problems create insecurities -- people choose short or simple passwords, repeat passwords across time and sites, write passwords down, etc. These problems are addressed by password manager programs, but these programs have their own problems -- passwords are either backed up on the "cloud" (less secure), or cannot be easily transferred between browsers and computers.
|
||||
|
||||
We all know that entering your password into an untrusted computer is dangerous, and that entering your password into a trusted computer on an untrusted or insecure web site is dangerous. But [homograph attacks](https://en.wikipedia.org/wiki/IDN_homograph_attack) can make this very hard to see, and typosquatting can fool the unwary.
|
||||
|
||||
If a password needs to be entered, it should be entered only into hardware that is provided by (and presumably more trusted by) the person who knows the password.
|
||||
|
||||
Entering your password into a trusted computer on a trusted, secure web site is not entirely secure -- an IT professional working inside the organization could serve you a patched web site with a bit of javascript that sends him/her your password. Or a deep dependency could insert some malicious code that goes live when the engineers upgrade the site's software to the latest versions. The password entry handling software should not be separately implemented by every web site and served every time the web site is accessed. The volume and rapid update cycles makes independent validation infeasible. Instead, a few software implementation should handle password entry for many sites, and should be updated rarely.
|
||||
|
||||
Fundamentally, the act of entering passwords into untrusted software on untrusted machines creates a large number of vulnerabilities.
|
||||
|
||||
Let's fix these problems.
|
||||
|
||||
## Operation
|
||||
|
||||
This system is implemented in an crypto-identity app or sub-function of a Bitcoin Cash wallet, most commonly located on a phone or tablet (mobile device). The login function of the system works in 2 modes: using a password-optional public/private key login scheme, and as a traditional password manager.
|
||||
|
||||
In password manager mode, a browser plugin is used to communicate between the browser and phone. The vulnerabilities that a password manager solves and does not solve are well known so this operation mode is not the main focus of this document.
|
||||
|
||||
The password-optional login requires server-side changes but is much more secure. To begin, the server/web site is provided a Bitcoin Cash address during the sign-up process. The server will use this address to verify a user by checking that the user knows the associate private key.
|
||||
|
||||
During login, the web site provides the user's crypto-identity app with a challenge string consisting of random data. This challenge string is transmitted to the user's app visually via a QR code, directly via a link, or via a browser plug-in that has previously been securely introduced to the crypto-identity app. After an optional password entry unlocks the crypto-identity app, and/or a site-specific very secure password is entered, the app generates a private key based on a key derived from the wallet's master private key and the optional site-specific password. The app uses this key to sign a message consisting of the website's domain, the operation being performed (login), and the challenge string. This is communicated directly from the crypto-identity app to the web site via a HTTP get request to effect a log in.
|
||||
|
||||
|
||||
### Problems Solved
|
||||
|
||||
In the "overview" section I identified a few problems with current log in schemes. This section lists these problems and how they are solved:
|
||||
|
||||
1. *Remembering passwords*: Secret keys are stored on the user's phone -- the only password that must be remembered is to unlock the phone and/or the Bitcoin Cash wallet app, for low security websites.
|
||||
2. *Repeating passwords*: The login process does not use passwords, or provides a different password to each web site (when in password-manager mode).
|
||||
3. *Entering passwords into untrusted machines or software*: Login is passwordless -- the only passwords needed unlocks the crypto-identity app or is used to derive a private key on the users phone . This is entered into the user's own device, running dedicated software. This is not a guarantee of security -- but it is arguably a lot more secure than running arbitrary software on unknown machines.
|
||||
4. *Backing up password manager data*: The app uses a Bitcoin Cash Hierarchical Deterministic (HD) wallet. This means that the wallet can be backed up once upon creation by saving a 12 word recovery phrase. This means that it is possible to recover logins that did not exist at the time this phrase was written down, so it is unnecessary to back up the wallet periodically. This makes it unnecessary to store this sensitive data in the "cloud".
|
||||
5. *Use on multiple machines*: Password data does not need to be synchronized across machines as is required with password managers, since it can be located on a portable device. Regardless, it is possible to place the user's wallet on multiple devices (or to upgrade a device) by entering the recovery phrase.
|
||||
6. *Homograph/typosquatting attacks*: An app is not fooled by visually similar domain names so it will not recognize the web site that is requesting a login. Even if the user is fooled into registering with the attacking site, a different public key is provided to that site. The wallet also incorporates the domain name of the requesting web site into the message it signs, so this signature cannot be successfully replayed on the legitimate web site. As stated in the caveats, a combined homograph/typosquatting and MITM attack is still possible to gain a session with the targeted server as the targeted user, if a QR code is used rather than a plugin. However, the username and password is not compromised, and the engineering capability "bar" to pull off this attack is raised.
|
||||
7. *login using an insecure/public computer*: In the challenge-type login, the secret key never leaves your phone, and the signed message is not communicated through the insecure computer, so a compromised computer cannot access it. There is also no chance that the user accidentally saves his login information in the browser.
|
||||
8. *IT professional code injection*: The challenge-type login never communicates a password that can be stolen, and the signed challenge cannot be used to access any other web site or session within this site.
|
||||
|
||||
### Caveats
|
||||
|
||||
*“A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools.”*
|
||||
― Douglas Adams, [Mostly Harmless](https://www.goodreads.com/work/quotes/2842984)
|
||||
|
||||
Like a password manager, all your passwords are in one place. Compromising the password protecting this app or the app itself will expose all passwords.
|
||||
|
||||
Storing passwords in app on your personal mobile phone may give attackers greater opportunity for physical access than a using a computer that does not leave your home.
|
||||
|
||||
If two factor authentication (2FA) is also enabled, use a yublikey or other dedicated device. Loading both crypto-identity software and 2FA software on the same device defeats the purpose.
|
||||
|
||||
A combination homograph/MITM attack is possible if QR codes are used to send the login offer to the phone. In this scenario, Alice wants to connect to Sally, but is fooled via a homograph or typosquatting URL into connecting to Mallory. Mallory contacts Sally, is allocated a session, and receives the login page. Mallory presents it to Alice. Alice uses the crypto-identity app to scan the provided QR code and log in by communicating directly to Sally (if a plugin is used, the plugin would detect that the domain in the login URI does not match the domain serving the login offer, defeating the attack). This authenticates Mallory's session, allowing him to access for as long as the session is open. Note that this attack is also possible using traditional login techniques, and in that situation Mallory gains Alice's username and password. One possible solution to this problem is to have Alice sign every http get and put request she sends to Sally, and of course Sally validates these signatures. With this change, Mallory can spy on the session, but cannot issue his own requests. However, this is a major change to the operation of the server and is beyond the scope of this document.
|
||||
|
||||
In some situations, it is possible for a remote attacker to request a login to your app. For example, s/he could send you a photo of the login QR code, or a paired browser plugin might automatically connect to your crypto-identity app. This could be a feature to give someone temporary access. But don't OK a login if you are not sure where its coming from!
|
||||
|
||||
*Given these caveats, this system may be more appropriately used for the many low security logins needed by the typical internet user, rather than the few high security logins!*
|
||||
|
||||
## Protocol Description
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Phone
|
||||
participant Browser
|
||||
participant Server
|
||||
Browser ->> Server: HTTP get
|
||||
Server ->> Browser: Login page (HTTP response)
|
||||
Browser ->> Phone: Login Offer (via QR code or plugin)
|
||||
Phone ->> Server: Login offer response (signed challenge)
|
||||
Server ->> Phone: Login OK/ERROR
|
||||
alt login ok
|
||||
Server ->> Browser: Redirect to home page
|
||||
else unknown identity
|
||||
Server ->> Browser: Opt redirect to signup page
|
||||
end
|
||||
```
|
||||
|
||||
### Login Offer
|
||||
The server provides a URI (or a QR-encoded URI) of the following format (bold indicated variable fields):
|
||||
|
||||
bchidentity://**domain**/**path**?op=login&chal=**challengeString**&cookie=**cookie**
|
||||
|
||||
**Fields**:
|
||||
|
||||
**domain**: domain name of the site to log into (e.g. "www.bitcoinunlimited.net". Also include the port using the standard :number format if it is not the default http port. Use ":443" to request a https response.
|
||||
**path**: where to send the response (e.g. "/login/auto")
|
||||
**challengeString**: an arbitrary string chosen by the server that is unique for every login and contains sufficient entropy to make repeats incredibly unlikely. The challenge string MUST only contain ASCII alphanumeric characters (A-Z, a-z, 0-9, and _).
|
||||
**cookie**: arbitrary data chosen by the server that will be sent back to the server during the login response. For web sites, this is often the originating session identifier since the login response will likely arrive in a different session.
|
||||
|
||||
All fields MUST be supplied.
|
||||
|
||||
### Communication
|
||||
|
||||
If the login is to a web site, the server presents the login offer as a link and optionally a QR code. The server listens for a HTTP or HTTPS "get" message to **domain**/**path**, described below.
|
||||
|
||||
For other server types, communication of this URI is beyond the scope of this document.
|
||||
|
||||
The crypto-identity app should register itself as the handler for the "bchidentity" URI protocol identifier in the fashion appropriate to the platform it runs on. This will ensure that clicking on a web link or the generic processing of this QR code will open the crypto-identity app.
|
||||
|
||||
On desktop platforms, a browser plugin may register the "bchidentity" URI, and be used to proxy the bchidentity URIs to a paired mobile phone.
|
||||
|
||||
### Login Offer Response
|
||||
|
||||
For web servers, the crypto-identity app creates and issues a http "get" request of the following format:
|
||||
|
||||
http://**domain**[**:port**]/**path**?op=login&addr=**identity address**&sig=**signature**
|
||||
|
||||
**domain**, **port**, **path**: These parameters are provided by the login offer.
|
||||
|
||||
**identity address**: This is the Bitcoin Cash address that this site knows as your identity. This MUST be sent in "cashaddr" format.
|
||||
|
||||
**signature**: The URL-encoded signature calculated as described in the *Signature Computation* section of this document.
|
||||
|
||||
Additional fields are ignored (not an error).
|
||||
|
||||
#### Server response to a login attempt
|
||||
|
||||
The server MUST reply to the Login Response message with the following error codes and strings:
|
||||
|
||||
*200: "login accepted"*
|
||||
Success! Along with sending this response to the crypto-identity app, the server SHOULD redirect or update the client's browser away from the login screen.
|
||||
|
||||
*200: "bad signature"*
|
||||
The signature is incorrect
|
||||
|
||||
*404: "unknown session"*
|
||||
The cookie does not match any known session. The session has probably expired in the server and the user needs to reload the web page.
|
||||
|
||||
*404: "unknown operation"*
|
||||
The desired operation is not supported by this server
|
||||
|
||||
*401: "unknown identity"*
|
||||
The supplied bitcoincash address does not match any registered users. The server MAY redirect or update the client's browser away from the login screen, to a new user signup screen. But the server SHOULD still accept at least 33 login attempts (the wallet recovery process requires testing a few possible identities) before invalidating the login offer (it is best to not invalidate the login offer at all until the session expires).
|
||||
|
||||
## Crypto-identity App Operation
|
||||
|
||||
### Identity management
|
||||
The crypto-identity app has the concept of "common identities" and "unique identities". A common identity is deliberately used across multiple domains to link accounts. A unique identity is probabilistically given to just one web site.
|
||||
|
||||
Apps can use any method to organize identities. However, to ensure seed recovery compatibility, apps SHOULD follow these procedures to choose a private key or username/password for every log in.
|
||||
|
||||
#### Choosing a public/private key for challenge based authentication
|
||||
|
||||
First use BIP32 compliant HD wallets with the following BIP44 compliant derivation path:
|
||||
|
||||
m/44'/0x1c3b1c3b'/0'/0/**index**
|
||||
|
||||
If the user enters a site-specific passphrase then the actual private key is the SHA256( derivation key + passphrase), otherwise the derivation key itself is used as the private key.
|
||||
|
||||
**index**: use 0-31 if a "common identity" is desired, otherwise, derive an index from the server domain name using the following algorithm:
|
||||
```
|
||||
uniquifier = DeriveChildKey(m/44'/0x1c3b1c3b'/0'/0/0xffffffff)
|
||||
bytes = SHA256(SHA256(domain name + uniquifier)) # where + is string concatenation
|
||||
index = bytes[0]&~31 + bytes[1]*256 + bytes[2]*256*256 + hash[3]*256*256*256
|
||||
```
|
||||
The purpose of the uniquifier is to make sure that a web site cannot engineer an identity collision with another site.
|
||||
|
||||
|
||||
This organization provides 32 possible "common identities", and an algorithmic way to recover unique identities from the HD wallet seed. If the user cannot remember whether a common or unique identity was used, it is possible to try logging in with all 33 identities. In practice it is unlikely that a user will need more than a few common identities, so an efficient recovery algorithm would be to try the unique identity first and then the common identities starting with 0. But, if implemented simply, this may allow a server to infer a relationship between the common identities -- a paranoid implementation will need to recover identities slowly and through separate networks and sessions. Finally, it should be emphasized that this is only a concern for the last-resort option of key recovery from seed phrase. A privacy conscious user should back up his wallet regularly to avoid this situation, or use unique identities and a single common identity.
|
||||
|
||||
#### Choosing a username/password for traditional authentication
|
||||
TBD
|
||||
|
||||
### Signature computation
|
||||
|
||||
The crypto-identity app signs the following string using a Bitcoin-standard pubkey recoverable ECDSA signature algorithm:
|
||||
|
||||
"Bitcoin Signed Message:\n**domain**[**:port**]\_bchidentity_**op**\_**challengeString**"
|
||||
|
||||
The first component of the string to be signed is "Bitcoin Signed Message:\n". This is automatically prepended to every non-transaction message signed by most current bitcoin wallets and bitcoin libraries so you may not need to include it.
|
||||
|
||||
**domain**: the domain name of the login request. To defeat some "man-in-the-middle" attacks, signing apps MUST ensure that this string actually IS the domain to which the response is sent.
|
||||
|
||||
**port**: If the port is 80 (http) or 443 (https) then the port and preceding colon MUST be omitted.
|
||||
|
||||
**op**: This is the operation specified in the request URI. Currently this must equal "login".
|
||||
|
||||
**challengeString**: This is the challengeString received in the login offer. The signer MUST ensure that it complies with the challengeString rules (as stated above).
|
||||
|
||||
The reason the prefixes, domain name, and operation is included in the signature, and the content of the challenge string is restricted, is to make it extremely unlikely that a challenge string can be replayed in another context. For example, if just the challenge string was signed, a server could send the app a valid bitcoin transaction as the challenge, potentially stealing money. If the operation was omitted, a server could make it seem like an individual signed a legal document or embarrassing statement. If the domain was omitted, it may be possible to replay the signature on another site.
|
||||
@@ -0,0 +1 @@
|
||||
test
|
||||
@@ -0,0 +1,17 @@
|
||||
<div class="cwikmeta">{
|
||||
"title":"Bloom Filter",
|
||||
"related":["/protocol/p2p/filterload"]
|
||||
}</div>
|
||||
|
||||
A bloom filter is an imperfect but efficient set membership test. The filter will never incorrectly report that member is NOT in the set. However, it may report that a member is in a set when it is actually not. See [wikipedia](https://en.wikipedia.org/wiki/Bloom_filter), or the [original paper](https://dl.acm.org/citation.cfm?id=362686.362692) for details.
|
||||
|
||||
Therefore bloom filters are often used during set membership testing as a quick pre-check to eliminate most elements.
|
||||
|
||||
### Use in the Bitcoin Peer-to-Peer Protocol
|
||||
Bloom filters are used in the bitcoin peer-to-peer protocol to filter the transactions and blocks that a client is sent from another node. The client first "installs" a bloom filter that contains information about the objects it is interested in by sending a [FILTERLOAD](/protocol/p2p/filterload) message to a peer. The peer will subsequently only provide objects that match the installed filter.
|
||||
|
||||
At a minimum, an [SPV](/glossary/SPV) client must insert addresses and [outpoints](/glossary/outpoint) into the bloom filter. The addresses will cause every transaction that pays INTO the wallet to be reported, and the outpoints will cause every transaction that pays OUT OF the wallet to be reported.
|
||||
|
||||
Bitcoin Bloom filters have an additional feature. Based on the setting of a flag byte, it is possible to direct the peer to automatically insert new data into the bloom filter based on transactions that match. In particular, outpoints will be automatically inserted that correspond to the outputs of addresses that match the filter. This facility is extremely important because if a receive and spend occur within the same transaction, the client does not have the opportunity to update the filter. Bloom filters should therefore be sized with the expectation that new elements will be inserted.
|
||||
|
||||
However, due to the bloom filter's tendency to have false positives, these insertions means that unnecessary data will be inserted into the filter, creating even more false positives in a positive feedback loop. Eventually the node will start sending a lot of unnecessary traffic to the client. Therefore, it is essential for clients to periodically refresh (using [FILTERLOAD](/protocol/p2p/filterload)) the bloom filter to remove these unnecessary entries.
|
||||
@@ -0,0 +1,19 @@
|
||||
<div class="cwikmeta">
|
||||
{
|
||||
"title": "Wallet Objects"
|
||||
} </div>
|
||||
|
||||
The following graph shows the derivation relationship between wallet objects.
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
PrivK["Private Key"] ==>PubK[Public key]
|
||||
PubK == RIPEMD and SHA256 ==> PubKH[Public Key Hash]
|
||||
PubKH==>Address
|
||||
Address==>PubKH
|
||||
Script==>Address
|
||||
style PubK fill:#906,stroke:#333,stroke-width:2px;
|
||||
style PrivK fill:#f06,stroke:#333,stroke-width:8px;
|
||||
style PubKH fill:#2f6,stroke:#333,stroke-width:2px;
|
||||
style Address fill:#2f6,stroke:#333,stroke-width:2px;
|
||||
```
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
<div class="cwikmeta">
|
||||
{
|
||||
"title":"P2P Protocol",
|
||||
"related":[]
|
||||
} </div>
|
||||
|
||||
The Bitcoin P2P protocol is comprised of messages over TCP. These messages are serialized using a custom format. Unlike RPC protocols, messages do not necessarily have a reply and there is no way to unambiguously connect a sent message to a reply, although many communications are often request/response pairs. High performance full node software may handle incoming messages in parallel, so it is not appropriate to assume a message reply order. Messages that cannot be fulfilled are sometimes dropped with no reply, and sometimes replied to via a REJECT message.
|
||||
|
||||
These legacy design decisions can make the protocol difficult to implement on the client side, but are generally needed when a robust implementation communicates with untrusted/uncooperative partners. A good strategy is to wait for any message that provides the required data, with a timeout, and then separately issue the request in a retry loop to multiple peers. If a timeout occurs, return to higher level software which should re-assess whether the data is still needed, since in nodes in the network may have converged to a competing block or transaction, and therefore not be serving the data you are requesting (nodes only serve data on the most-difficult chain, even if they have some data pertaining to lower-difficulty splits).
|
||||
|
||||
## Serialization Format
|
||||
|
||||
Bitcoin uses a custom serialization format that is generally little-endian.
|
||||
|
||||
|
||||
## Message Envelope
|
||||
|
||||
The following table describes the message header:
|
||||
|
||||
| network identifier | command | size | checksum | contents |
|
||||
|-------------|--------------|-------------|----------------|------------|
|
||||
| 0: 4 bytes | 4: 12 bytes | 16: 4 bytes | 20: 4 bytes | 24: size bytes |
|
||||
|*BCH*:E3,E1,F3,E8<br>*BTC*:F9,BE,B4,D9<br>*tBCH*:F4,E5,F3,F4<BR>*tBTC*:0B,11,09,07 | ascii null extended | little endian uint32 | little endian uint32 | depends on command
|
||||
|
||||
### Network Identifier
|
||||
The network identifier is used to separate blockchains and test networks. This reduces unnecessary load on peers, allowing them to rapidly ban nodes rather then forcing the peer to do a blockchain analysis before banning.
|
||||
|
||||
Unfortunately, the BCH and BSV blockchains use the same network identifier.
|
||||
|
||||
### Command
|
||||
The command is the exact lowercase bytes in the titles of each subsection in the Message Types section below followed by zeros -- e.g. the INV message's command is literally the 12 bytes: 'i','n',v',0,0,0,0,0,0,0,0,0. This is not a "C" string. If a command was exactly 12 bytes, there would be no null terminator!
|
||||
|
||||
### Size
|
||||
Size is the size of the contents field in bytes, not the size of the entire message.
|
||||
|
||||
### Checksum
|
||||
This field is a message checksum. The checksum is calculated by first computing the double SHA256 of the *contents* portion of the message. The first 4 bytes of this hash is the checksum. See [C++ generate](https://github.com/BitcoinUnlimited/BitcoinUnlimited/blob/bucash1.7.0.0/src/net.cpp#L3179), [python verify](https://github.com/BitcoinUnlimited/BitcoinUnlimited/blob/eb264e627e231f7219e60eef41b4e37cc52d6d9d/qa/rpc-tests/test_framework/mininode.py#L409), [python generate](https://github.com/BitcoinUnlimited/BitcoinUnlimited/blob/eb264e627e231f7219e60eef41b4e37cc52d6d9d/qa/rpc-tests/test_framework/mininode.py#L449).
|
||||
|
||||
Since TCP has message integrity checksums, and a peer can cause another node to waste processing power validating bad checksums, it is not recommended that nodes verify this checksum. That is, this field should be considered obsolete.
|
||||
|
||||
However, senders should calculate and fill this checksum field to be compatible with all software, unless the [XVERSION](/protocol/p2p/xversion.md) message is used to tell peers that this checksum will not be verified (currently supported by *Bitcoin Unlimited*). In this case the field **SHOULD** be set to 0 (but not enforced as 0 on the receiver's side). This may allow a future reuse of this field.
|
||||
|
||||
|
||||
### Contents
|
||||
The contents of messages are described in the next section.
|
||||
|
||||
## Message Contents
|
||||
|
||||
### Announcements (unsolicited messages with no response)
|
||||
#### [FILTERADD](/protocol/p2p/filteradd)
|
||||
*Add a single item into an existing filter*
|
||||
|
||||
#### [FILTERCLEAR](/protocol/p2p/filterclear)
|
||||
*Remove an existing filter*
|
||||
|
||||
#### [FILTERLOAD](/protocol/p2p/filterload)
|
||||
*Inserts a transaction and merkle block filter into the peer*
|
||||
|
||||
#### [INV](protocol/p2p/inv)
|
||||
*Notifies peers about the existence of some information (generally a block or transaction)*
|
||||
|
||||
#### [XUPDATE](/protocol/p2p/xupdate)
|
||||
*Communicates a change in peer capabilities*
|
||||
|
||||
### Requests
|
||||
|
||||
#### [GETBLOCKS](/protocol/p2p/getblocks)
|
||||
*Requests block hash identifiers*
|
||||
|
||||
#### [GETDATA](/protocol/p2p/getdata)
|
||||
*Requests information (generally previously announced via an INV) from a peer*
|
||||
|
||||
#### [GETHEADERS](/protocol/p2p/getheaders)
|
||||
*Requests block headers from a peer*
|
||||
|
||||
#### [PING](/protocol/p2p/ping)
|
||||
*Keep-alive*
|
||||
|
||||
#### [VERSION](/protocol/p2p/version)
|
||||
*Describes peer capabilities*
|
||||
|
||||
#### [XVERSION](/protocol/p2p/xversion)
|
||||
*Describes peer capabilities in an extensible manner*
|
||||
*Currently supported by Bitcoin Unlimited only*
|
||||
|
||||
#### Responses
|
||||
Note that some of these "response" messages can also be sent without solicitation (i.e. without a request).
|
||||
|
||||
#### [ADDR](/protocol/p2p/addr)
|
||||
*Provides a peer with the addresses of other peers*
|
||||
|
||||
#### BLOCK, THINBLOCK, XTHINBLOCK, GRAPHENEBLOCK, CMPCTBLOCK
|
||||
*Provides a block*
|
||||
|
||||
#### [HEADERS](/protocol/p2p/headers)
|
||||
*Provides a set of block headers (unsolicited or GETHEADERS response)*
|
||||
|
||||
|
||||
#### [MERKLEBLOCK](protocol/p2p/merkleblock)
|
||||
*Provides a provable subset of a block's transactions, as filtered by FILTERADD*
|
||||
|
||||
#### [PONG](/protocol/p2p/pong)
|
||||
*Reply to a ping message*
|
||||
|
||||
#### [REJECT](/protocol/p2p/reject)
|
||||
*General response by well-behaved clients if a message cannot be handled*
|
||||
|
||||
|
||||
#### [TX](/protocol/p2p/tx)
|
||||
*Transaction object*
|
||||
|
||||
#### [VERACK](/protocol/p2p/verack)
|
||||
*Respond to a [version](/protocol/p2p/version) message*
|
||||
|
||||
#### [XVERACK](/protocol/p2p/xverack)
|
||||
*Respond to an [xversion](/protocol/p2p/xversion) message*
|
||||
@@ -0,0 +1,18 @@
|
||||
<div class="cwikmeta">{
|
||||
"title":"ADDR",
|
||||
"related":["/protocol","/protocol/p2p/getaddr"]
|
||||
}</div>
|
||||
|
||||
Provide information about other prospective P2P protocol peers. Peers SHOULD not send this message unsolicited, and nodes that receive an unsolicited ADDR message MUST ignore it. This behavior helps prevent eclipse and partitioning attacks by not allowing an attacker to aggressively seed peer connection tables with its own nodes.
|
||||
|
||||
| compact int | 4 bytes | 8 bytes | 16 bytes | 2 bytes |
|
||||
|----------------------------------------|---------|----------|----------|---------|
|
||||
|[vector](/protocol/p2p/vector) size N of| time | services | IP address | port
|
||||
|
||||
*services* is a bit field describing supported functionality, that is also used in the [version](/protocol/p2p/version) message. See [services field](/protocol/p2p/services__field) for bit definitions.
|
||||
|
||||
*time* is a 4 byte unsigned little-endian integer denoting the last time in epoch seconds that this node was known to be "live".
|
||||
|
||||
*IP address* is the IPv4 or IPv6 address of the prospective node.
|
||||
|
||||
*port* is the IP port of the prospective node, serialized as an unsigned 2 byte big-endian value.
|
||||
@@ -0,0 +1,5 @@
|
||||
The block header appears in several P2P messages. It's serialization format is as follows:
|
||||
|
||||
| 4 bytes | 32 bytes | 32 bytes | 4 bytes | 4 bytes | 4 bytes
|
||||
|----|---------------|-----------|------------|---------|------
|
||||
| version | hash of previous block | hash of merkle root | block time in epoch seconds | difficulty in "bits" format | nonce
|
||||
@@ -0,0 +1,20 @@
|
||||
A "compact int" is serialized as follows:
|
||||
|
||||
*If the number < 253, store it in 1 byte
|
||||
*If the number fits in 16 bits: store a 1 byte value 253, and the 2 byte little-endian number.
|
||||
|
||||
| 0 | 1 | 2 |
|
||||
|--------|---------|---------|
|
||||
| 0xfd | val&255 | val>>8 |
|
||||
|
||||
* If the number fits in 32 bits (but not 8 or 16): store a 1 byte value 254, and the 4 byte little-endian number
|
||||
|
||||
| 0 | 1 | 2 | 3 | 4 |
|
||||
|--------|---------|---------|---------|---------|
|
||||
| 0xfe | val&255 | (val>>8)&255 | (val>>16)&255 | (val>>24)&255 |
|
||||
|
||||
* If the number fits in 64 bits (but not 8, 16, or 32): store a 1 byte value 255 and the 8 byte little-endian number
|
||||
|
||||
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
||||
|--------|---------|---------|---------|---------|---------|---------|---------|--------|
|
||||
| 0xff | val&255 | val>>8 | val>>16 | val>>24 | val>>32 | val>>40 | val>>48 | val>>56 |
|
||||
@@ -0,0 +1,12 @@
|
||||
<div class="cwikmeta">{
|
||||
"title":"FILTERADD",
|
||||
"related":["/protocol","/protocol/p2p/getdata","/protocol/p2p/filterload","/protocol/p2p/filterclear"]
|
||||
}</div>
|
||||
|
||||
Add an entry into the installed bloom filter.
|
||||
|
||||
| compact int | N bytes |
|
||||
|-------------|---------|
|
||||
|[vector](/protocol/p2p/vector) size N of| data
|
||||
|
||||
*data* is inserted into the bloom filter, exactly as if the [insert](https://github.com/BitcoinUnlimited/BitcoinUnlimited/blob/eb264e627e231f7219e60eef41b4e37cc52d6d9d/src/bloom.cpp#L116) operation had been called locally before sending the filter.
|
||||
@@ -0,0 +1,8 @@
|
||||
<div class="cwikmeta">{
|
||||
"title":"FILTERCLEAR",
|
||||
"related":["/protocol","/protocol/p2p/getdata","/protocol/p2p/filterload","/protocol/p2p/filterclear"]
|
||||
}</div>
|
||||
|
||||
Remove the installed bloom filter, and therefore disable bloom filtering.
|
||||
|
||||
This message has no contents.
|
||||
@@ -0,0 +1,28 @@
|
||||
<div class="cwikmeta">{
|
||||
"title":"INV",
|
||||
"related":["/protocol","/protocol/p2p/filterclear", "/protocol/p2p/inv", "/protocol/p2p/MERKLEBLOCK"]
|
||||
}</div>
|
||||
|
||||
|
||||
*Inserts a transaction and merkle block filter into the peer*
|
||||
|
||||
| up to 36000 bytes |
|
||||
|-------------------|
|
||||
| [bloom filter](objects/bloom_filter) |
|
||||
|
||||
### Effect on Transactions
|
||||
|
||||
This message installs a bloom filter into the peer. Subsequent INV notifications and MERKLEBLOCK messages only provide transactions that in match this bloom filter in some manner. The following items in a transaction are checked against the bloom filter:
|
||||
|
||||
- The transaction hash
|
||||
- Each data field in every [output script](glossary/output__script) in the transaction
|
||||
- Most importantly, this allows public keys and public key hashes (essentially bitcoin addresses) to be added to the bloom filter, allowing a wallet to detect an incoming transfer.
|
||||
- Each [previous output](glossary/previous__output) in the transaction
|
||||
- This allows a wallet to detect that a different wallet has spent funds that are co-controlled
|
||||
- Each data field in every [input script](glossary/input__script) in the transaction.
|
||||
|
||||
See [CBloomFilter::MatchAndInsertOutputs](https://github.com/BitcoinUnlimited/BitcoinUnlimited/blob/bucash1.7.0.0/src/bloom.cpp#L186), and [CBloomFilter::MatchInputs](https://github.com/BitcoinUnlimited/BitcoinUnlimited/blob/eb264e627e231f7219e60eef41b4e37cc52d6d9d/src/bloom.cpp#L234)
|
||||
|
||||
### Effect on Merkle Blocks
|
||||
|
||||
If a [filtered block](https://github.com/BitcoinUnlimited/BitcoinUnlimited/blob/bucash1.7.0.0/src/protocol.h#L483) is requested via in [INV](/protocols/p2p/inv) message, the installed bloom filter is used to choose which transactions are included in the response using the same matching algorithm as described above for transaction INVs.
|
||||
@@ -0,0 +1,25 @@
|
||||
<div class="cwikmeta">{
|
||||
"title":"GETBLOCKS",
|
||||
"related":["/protocol","/protocol/p2p/getdata","/protocol/p2p/getheaders"]
|
||||
}</div>
|
||||
|
||||
Request the sequence of blocks that occur after a specific block. If the specified block is on the server's most-work chain, the server responds with a set of up to 500 [INV](/protocol/p2p/inv) messages identifying the next blocks on that chain. If the specified block is not on the most-work chain, the server uses block information in the *locator* structure to determine the fork point and provides [INV](/protocol/p2p/inv) messages from that point.
|
||||
|
||||
| locator | stop at hash |
|
||||
|-----------------------------------------------------------------------------------------------|----------|
|
||||
| [vector](/protocol/p2p/vector) of 32 byte block [hash identifiers](/glossary/hash__identifier)| 32 bytes |
|
||||
|
||||
|
||||
### Locator
|
||||
|
||||
See [GETHEADERS](/protocol/p2p/getheaders) for a detailed description of the Locator object.
|
||||
|
||||
The response will begin at **the child of** the first hash in the locator list that matches a block hash identifier held by the responder. If no hashes match, there will be no INV messages sent.
|
||||
|
||||
*Use an empty locator to get an INV for block 1, and GETHEADERS that block to discover the genesis block hash in the prevBlock field*
|
||||
|
||||
### Stop At Hash
|
||||
|
||||
The sender will stop sending INVs if it encounters this hash. If the hash is never encountered, the sender will stop after 500 INV messages or when it hits the blockchain tip.
|
||||
|
||||
Server Implementations: [Bitcoin Unlimited](https://github.com/BitcoinUnlimited/BitcoinUnlimited/blob/bucash1.7.0.0/src/net_processing.cpp#L1077)
|
||||
@@ -0,0 +1,19 @@
|
||||
<div class="cwikmeta">{
|
||||
"title":"GETDATA",
|
||||
"related":["/protocol","/protocol/p2p/inv"]
|
||||
}</div>
|
||||
|
||||
Requests information (generally previously announced via an INV) from a peer.
|
||||
|
||||
A GETDATA request is formatted as a vector of INV data:
|
||||
|
||||
| compact int | 4 bytes | 32 bytes | ... | additional objects |
|
||||
|---------------|-----------|------------|--|------|
|
||||
| [vector](/protocol/p2p/vector) size N elements of | element 1 type | element 1 hash | ... | element N type and hash
|
||||
|
||||
### Type
|
||||
|
||||
The type of the desired object. See [INV](/protocol/p2p/inv) for specific values
|
||||
|
||||
### Hash
|
||||
The [hash identifier](glossary/hash__identifier) of the desired object.
|
||||
@@ -0,0 +1,34 @@
|
||||
<div class="cwikmeta">
|
||||
{
|
||||
"title":"GETHEADERS",
|
||||
"related":["/protocol"]
|
||||
} </div>
|
||||
|
||||
Request a sequence of block hash identifiers
|
||||
|
||||
| locator | stop at hash |
|
||||
|-----------------------------------------------------------------------------------------------|----------|
|
||||
| [vector](/protocol/p2p/vector) of 32 byte block [hash identifiers](/glossary/hash__identifier)| 32 bytes |
|
||||
|
||||
|
||||
### Locator
|
||||
|
||||
The locator is an array of block hash identifiers whose purpose is to communicate a position in a blockchain that may be forked from the blockchain that the receiver sees as having the most work. It does so by providing a series of block hash identifiers ranging from the desired height to the genesis block. The locator solves both major currency forks and minor forks caused by near-simultaneous block discovery.
|
||||
|
||||
The first hash in the locator is the parent of the desired identifiers. Subsequent elements are ancestors of previous elements, chosen by the client. A common strategy is to provide M direct ancestors and then make the M+Nth element the 2^Nth ancestor, finishing with the genesis block. This results in an amount of data that is approximately the log of the length of the chain ([C++](https://github.com/BitcoinUnlimited/BitcoinUnlimited/blob/eb264e627e231f7219e60eef41b4e37cc52d6d9d/src/chain.cpp#L32)).
|
||||
|
||||
The response will begin at **the child of** the first hash in the locator list that matches a block hash identifier held by the responder. If no hashes match, the response will begin at block height 1 (child of the genesis block).
|
||||
|
||||
If the locator has no entries, the locator is ignored (see Stop At Hash).
|
||||
|
||||
*Use a valid locator whose first element is your chain tip and a zero "Stop At Hash" to request up to 2000 headers that extend your chain tip.*
|
||||
|
||||
### Stop At Hash
|
||||
|
||||
If a non-empty locator is provided, when constructing a response message, the sender will stop at the provided hash. If the hash is never encountered, the sender will stop after 2000 block hash identifiers are included in the reply.
|
||||
|
||||
If the locator is empty, the response includes only the header identified by this field (note it **includes** this hash, which differs from the behavior of the locator). In this case, if this hash is not found in the blockchain, the request is silently ignored.
|
||||
|
||||
*Use an empty locator and a valid block hash identifier to request the header of a specific block.*
|
||||
|
||||
Server Implementations: [Bitcoin Unlimited](https://github.com/BitcoinUnlimited/BitcoinUnlimited/blob/bucash1.7.0.0/src/net_processing.cpp#L1131)
|
||||
@@ -0,0 +1,18 @@
|
||||
<div class="cwikmeta">{
|
||||
"title":"HEADERS",
|
||||
"related":["/protocol","/protocol/p2p/getheaders"]
|
||||
}</div>
|
||||
|
||||
*Provides a contiguous set of block headers*
|
||||
|
||||
**HEADERS Message Format**
|
||||
|
||||
| compact int | ... | compact int |
|
||||
|----|---------------|-----------|------------|
|
||||
| [vector](/protocol/p2p/vector) size N containing: | [block header](/protocol/p2p/block__header)| number tx in block |
|
||||
|
||||
*[vector](/protocol/p2p/vector) size N containing*: This message contains a vector of block headers. No more than 2000 block headers may be sent at one time.
|
||||
|
||||
*block header*: A block header. Block headers in this array MUST be sequential.
|
||||
|
||||
*number tx in block*: **DEPRECATED** This field should be ignored and servers may send 0 regardless of the actual number of transactions in the block.
|
||||
@@ -0,0 +1,32 @@
|
||||
<div class="cwikmeta">{
|
||||
"title":"INV",
|
||||
"related":["/protocol","/protocol/p2p/getdata","/protocol/p2p/filterload","/protocol/p2p/filterclear"]
|
||||
}</div>
|
||||
|
||||
*Notifies peers about the existence of some information (block or transaction)*
|
||||
Based on selected services in the [VERSION]("/protocol/p2p/version") message, INV messages may not be sent.
|
||||
|
||||
If a bloom filter has been sent to this node via [FILTERLOAD](/protocol/p2p/filterload), transaction INVs will only be sent if they match the bloom filter.
|
||||
|
||||
| compact int | 4 bytes | 32 bytes |... | 4 bytes | 32 bytes |
|
||||
|----------|---------|----------|---|---------|----------|
|
||||
|[vector](/protocol/p2p/vector) size N of| type 1 | hash 1 | | type N | hash N
|
||||
|
||||
NOTE: Since a block header is a relatively small data structure, and block propagation speed is an important network metric, a peer may send HEADER messages in place of INV messages when a block arrives.
|
||||
|
||||
##### Type
|
||||
The type of the object that is available.
|
||||
|
||||
| Type | Value|
|
||||
|------|------|
|
||||
| 1 | Transaction |
|
||||
| 2 | Block |
|
||||
| 3 | Filtered Block (partial block with merkle proof)
|
||||
| 4 | Compact block
|
||||
| 5 | Xthin block (Bitcoin Unlimited)
|
||||
| 6 | Graphene Block (Bitcoin Unlimited)
|
||||
|
||||
Implementations: [C++](https://github.com/BitcoinUnlimited/BitcoinUnlimited/blob/eb264e627e231f7219e60eef41b4e37cc52d6d9d/src/protocol.h#L477)
|
||||
|
||||
##### Hash
|
||||
The [hash identifier](/glossary/hash__identifier) of the available object.
|
||||
@@ -0,0 +1,16 @@
|
||||
<div class="cwikmeta">{
|
||||
"title":"MERKLEBLOCK",
|
||||
"related":["/protocol", "/protocol/p2p/filteradd"]
|
||||
}</div>
|
||||
|
||||
*Provides a block header and partial merkle proof tree to show that selected transaction ids exist in the block.*
|
||||
|
||||
Transactions are selected by honest servers if they match the bloom filter installed by the client. However, note that servers can omit transactions and this cannot be detected except by receiving a MERKLEBLOCK message from an honest server.
|
||||
|
||||
All selected transactions are subsequently sent as separate TX messages. Due to multi-threading on the server, clients should not assume that these TX messages directly follow the MERKLEBLOCK message.
|
||||
|
||||
**MERKLEBLOCK Message Format**
|
||||
|
||||
| ... | 4 bytes | ... | ...|
|
||||
|----|---------------|-----------|------------|
|
||||
| [block header](/protocol/p2p/block__header)| # tx in block | [vector](/protocol/p2p/vector) of 32 byte hashes | [vector](/protocol/p2p/vector) of bytes that define the merkle block traversal
|
||||
@@ -0,0 +1,13 @@
|
||||
<div class="cwikmeta" style="visibility:hidden;">
|
||||
{
|
||||
"title":"PING",
|
||||
"related":["/protocol/p2p/pong"]
|
||||
} </div>
|
||||
|
||||
Connection keep-alive, "aliveness" and latency discovery.
|
||||
|
||||
| nonce |
|
||||
|---------|
|
||||
| 8 bytes |
|
||||
|
||||
If a node receives a PING message, it replies as quickly as possible with a [PONG](/protocol/p2p/pong) message with the provided *nonce*.
|
||||
@@ -0,0 +1,13 @@
|
||||
<div class="cwikmeta" style="visibility:hidden;">
|
||||
{
|
||||
"title":"PONG",
|
||||
"related":["/protocol/p2p/ping"]
|
||||
} </div>
|
||||
|
||||
Connection keep-alive, "aliveness" and latency discovery.
|
||||
|
||||
| nonce |
|
||||
|---------|
|
||||
| 8 bytes |
|
||||
|
||||
This message is sent in response to a [PING](/protocol/p2p/ping) message.
|
||||
@@ -0,0 +1,31 @@
|
||||
<div class="cwikmeta">{
|
||||
"title":"REJECT",
|
||||
"related":["/protocol"]
|
||||
}</div>
|
||||
|
||||
*Notifies peer that a message is invalid*
|
||||
|
||||
|
||||
| [compact int](/protocol/p2p/compact__int.md) N (max 12) | N bytes | 1 byte | [compact int](/protocol/p2p/compact__int.md) M (max 111) | M bytes |
|
||||
|----------------|---------|-------------|---------------|---------|
|
||||
| command length | command | error code | reason length | reason string |
|
||||
|
||||
*command length* and *command* form a [vector](/protocol/p2p/vector.md) of bytes that identify the type of the problem message. These bytes (less padded nulls) match the *command* field in the protocol [message envelope](/protocol.md).
|
||||
|
||||
*reason length* and *reason string* form a [vector](/protocol/p2p/vector.md) of bytes that is a string providing a human language explanation of the reason the message was rejected. This string is subject to change so client software **SHOULD NOT** use it programatically.
|
||||
|
||||
*error code* provides a succinct machine-interpretable reason why the message was rejected.
|
||||
|
||||
### Reject Error Codes
|
||||
|
||||
| Name | Value | Response To | Description
|
||||
|-------------|-------|---------------|-----------|
|
||||
| REJECT_MALFORMED | 0x01 | any | message cannot be deserialized |
|
||||
| REJECT_INVALID | 0x10 | BLOCK, TX, FILTERSIZEXTHIN | block or transaction is invalid, or xthin filter size is too small |
|
||||
| REJECT_OBSOLETE | 0x11 | VERSION | This node no longer supports your client protocol version |
|
||||
| REJECT_DUPLICATE | 0x12 | unused | |
|
||||
| REJECT_NONSTANDARD | 0x40 | TX | Transaction is [non-standard](/standard__transactions.md), or [not final](/final__transactions.md) as per BIP68 |
|
||||
| REJECT_DUST | 0x41 | TX | Transaction has an output that is too small |
|
||||
| REJECT_INSUFFICIENTFEE | 0x42 | TX | Transaction does not pay enough to be relayed |
|
||||
| REJECT_CHECKPOINT | 0x43 | unused | |
|
||||
| REJECT_WAITING | 0x44 | TX | This transaction is [not final](/final__transactions.md) |
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
The services field is an 8 byte little-endian-serialized bitfield that described peer capabilities. The following capabilities are defined, by bit position:
|
||||
|
||||
* 0: NODE_NETWORK
|
||||
The node is capable of serving the complete block chain. It is currently set by all full nodes, and is unset by SPV clients or other peers that just want network services but don't provide them.
|
||||
|
||||
* 1: NODE_GETUTXO
|
||||
The node is capable of responding to the getutxo protocol request. See [BIP 64](https://github.com/bitcoin/bips/blob/master/bip-0064.mediawiki) for details on how this is implemented. *Supported by Bitcoin XT only*
|
||||
|
||||
* 2: NODE_BLOOM
|
||||
The node is capable and willing to handle bloom-filtered connections.
|
||||
|
||||
* 3: NODE_WITNESS
|
||||
Indicates that a node can be asked for blocks and transactions including witness data.
|
||||
*Bitcoin Cash nodes do not have witness data so this flag should be ignored on receipt and set to 0 when sent*
|
||||
|
||||
|
||||
* 4: NODE_XTHIN
|
||||
The node supports Xtreme Thinblocks
|
||||
*Supported by Bitcoin Unlimited only*
|
||||
|
||||
* 5: NODE_BITCOIN_CASH
|
||||
The node supports the BCH chain. This is intended to be just a temporary service bit until the BTC/BCH fork actually happens.
|
||||
|
||||
* 6: NODE_GRAPHENE
|
||||
The node supports Graphene blocks. If this is turned off then the node will not service graphene requests nor make graphene requests.
|
||||
*Supported by Bitcoin Unlimited only*
|
||||
|
||||
* 7: NODE_WEAKBLOCKS
|
||||
The node supports Storm weak block (currently no node supports these in production, so this is a placeholder).
|
||||
|
||||
* 8: NODE_CF
|
||||
Indicates the node is capable of serving compact block filters to SPV clients, AKA the "Neutrino" protocol ([BIP157](https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki), and [BIP158](https://github.com/bitcoin/bips/blob/master/bip-0158.mediawiki)).
|
||||
|
||||
* 9: NODE_NETWORK_LIMITED
|
||||
This means the same as NODE_NETWORK with the limitation of only serving a small subset of the blockchain. See [BIP159](https://github.com/bitcoin/bips/blob/master/bip-0159.mediawiki) for details on how this is implemented.
|
||||
|
||||
* 24-31: Experimental
|
||||
These bits are reserved for temporary experiments. Just pick a bit that isn't getting used, or one not being used much, and notify the community. Remember that service bits are just unauthenticated advertisements, so your code must be robust against collisions and other cases where nodes may be advertising a service they do not actually support.
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
Vectors (and arrays, lists, maps, etc) are serialized by first serializing the number of elements and then serializing each element. The number of elements is serialized in [compact int](/protocol/p2p/compact__int) format.
|
||||
|
||||
| vector element count | object #0 | object #1 | ... | object #count-1 |
|
||||
|-------------|--------------|-------------|----------------|------------|
|
||||
| [compact int](/protocol/p2p/compact__int) | object specific serialization | ... | ... | ... |
|
||||
|
|
||||
@@ -0,0 +1,18 @@
|
||||
<div class="cwikmeta">{
|
||||
"title":"XUPDATE",
|
||||
"related":["/protocol","/protocol/p2p/xversion"]
|
||||
}</div>
|
||||
|
||||
*Notifies peers about an XVERSION configuration value update*
|
||||
|
||||
This message notifies a peer about changes to protocol parameters. It follows the same format as [XVERSION](/protocol/p2p/xversion.md) protocol parameters. Implementations **SHOULD** only send changed parameters, rather than every parameter. Note that some XVERSION parameters are not changeable and therefore will be ignored if they appear in this message.
|
||||
|
||||
See the [XVERSION](/protocol/p2p/xversion.md) message for detailed information about each parameter.
|
||||
|
||||
| compact int | compact int | variable bytes |... | compact int | 32 bytes |
|
||||
|----------|---------|----------|---|---------|----------|
|
||||
|[vector](/protocol/p2p/vector) size N of| key 1 | [vector](/protocol/p2p/vector) of bytes | | key N | [vector](/protocol/p2p/vector) of bytes
|
||||
|
||||
|
||||
### Support
|
||||
Supported by: **Bitcoin Unlimited**
|
||||
@@ -0,0 +1,11 @@
|
||||
<div class="cwikmeta">{
|
||||
"title":"XVERACK",
|
||||
"related":["/protocol","/protocol/p2p/xversion","/protocol/p2p/xupdate"]
|
||||
}</div>
|
||||
|
||||
*Notifies peers that an XVERSION message was received*.
|
||||
|
||||
This message has no *contents*.
|
||||
|
||||
### Support
|
||||
Supported by: **Bitcoin Unlimited**
|
||||
@@ -0,0 +1,38 @@
|
||||
<div class="cwikmeta">{
|
||||
"title":"XVERSION",
|
||||
"related":["/protocol","/protocol/p2p/xupdate"]
|
||||
}</div>
|
||||
|
||||
*Notifies peers about a protocol configuration value*
|
||||
|
||||
This message notifies a peer about extended protocol parameters. This message MAY be sent during connection initialization. If sent, it MUST be sent immediately subsequent to the receipt of the [VERACK](/protocol/p2p/verack.md) message, and before other non-initialization messages are sent.
|
||||
|
||||
| compact int | compact int | variable bytes |... | compact int | variable bytes |
|
||||
|----------|---------|----------|---|---------|----------|
|
||||
|[vector](/protocol/p2p/vector) size N of| key 1 | value 1 [vector](/protocol/p2p/vector) of bytes | | key N | value N [vector](/protocol/p2p/vector) of bytes
|
||||
|
||||
The *value* is a vector of bytes. These bytes can be an object that is itself serialized, but **MUST** exist within the vector "envelope" so that implementations that do not recognize a field can skip it. The serialization format of the bytes inside the "envelope" is defined by the creator of the key, however, Bitcoin P2P network serialization is recommended since it is also used to encode/decode all the messages of this protocol.
|
||||
|
||||
See [XVERSION specification](https://github.com/BitcoinUnlimited/BitcoinUnlimited/blob/bucash1.7.0.0/doc/xversionmessage.md) for additional details.
|
||||
|
||||
### XVERSION Fields
|
||||
|
||||
XVERSION field identifiers are 32 bits and split into a 16 bit prefix and 16 bit suffix. Each development group is assigned a prefix so that new identifiers do not accidentally conflict. Once a field identifier is created by group A, it should be used by other software both to receive that information from A and to present that information to other software. Therefore, group A **MUST NOT** change the syntax or semantics of a field once defined. To change a field, create a new identifier and deprecate (by no longer using the original identifier).
|
||||
|
||||
#### Prefix Assignments
|
||||
| Group | Value |
|
||||
|-------------------|-------|
|
||||
| Bitcoin ABC | 0 |
|
||||
| Bitcoin Unlimited | 2 |
|
||||
|
||||
|
||||
#### Field Assignments
|
||||
|
||||
See [xversionkeys.dat](https://github.com/BitcoinUnlimited/BitcoinUnlimited/blob/bucash1.7.0.0/src/xversionkeys.dat) for the most up-to-date field definitions defined by the BitcoinUnlimited full node.
|
||||
Note that:
|
||||
* *u64c* refers to a [compact int](/protocol/p2p/compact__int.md) serialization of an unsigned 64-bit value.
|
||||
* *Changeable* fields MAY be changed during the course of a connection via the [XUPDATE](/protocol/p2p/xupdate) message.
|
||||
|
||||
### Support
|
||||
|
||||
Supported by: **Bitcoin Unlimited**
|
||||
Reference in New Issue
Block a user