You've already forked specification
Merge remote-tracking branch 'verde/master'
This commit is contained in:
@@ -0,0 +1,8 @@
|
|||||||
|
# Block Version History
|
||||||
|
| Version Number | Proposed In | Released | Summary |
|
||||||
|
|--|--|---|
|
||||||
|
|||Aug 2017| Bitcoin Cash hard fork.|
|
||||||
|
|4|[BIP-0065](/history/bips)| Nov 2015<br>Bitcoin Core 0.11.2| Added support for `OP_CHECKLOCKTIMEVERIFY` opcode.|
|
||||||
|
|3|[BIP-0066](/history/bips)|Jul 2015<br>Bitcoin Core 0.10.0| Added enforcement of DER encoding of all ECDSA signatures in new blocks.|
|
||||||
|
|2|[BIP-0034](/history/bips)|Sep 2012<br>Bitcoin Core 0.7.0| Added the block height within the block coinbase.|
|
||||||
|
|1||Jan 2009|The format used in the genesis block.|
|
||||||
@@ -1,10 +1,17 @@
|
|||||||
# Network Protocol Version History
|
# Network Protocol Version History
|
||||||
|
| Version Number | Proposed In | Released | Summary |
|
||||||
| Version Number | Proposed In | Summary |
|
|--|--|---|
|
||||||
|--|--|--|
|
|||Aug 2017| Bitcoin Cash hard fork.|
|
||||||
| 106 | ??? | Added the following fields to the `version` message: `address-from`, `nonce`, `user-agent`, `current block height` |
|
|70 015|[BIP-0152](/history/bips)|Jun 2017<BR>Bitcoin Core 0.14.2|Modified banning behaviour for invalid compact blocks.|
|
||||||
| 209 | ??? | `address` message may accept a list of network addresses. |
|
|70 012| [BIP-0130](/history/bips)|Nov 2016<BR>Bitcoin Core 0.12.0| Added `sendheaders` message.|
|
||||||
|31 402| ??? | Time field added to `address` messages. |
|
|70 002|[BIP-0061](/history/bips)|Mar 2014<BR>Bitcoin Core 0.9.0| Added `reject` message.<BR>Send multiple `inv` messages in response to a `mempool` message if required (released but not in BIP).|
|
||||||
| | [BIP-0014](/history/bips) | Network Version decoupled from Block Version. User-agent replaced sub-version number. |
|
| 70 001 | [BIP-0037](/history/bips) | Feb 2013<br> Bitcoin Core 0.8.0 | Added `relay` flag to the `version` message.<br>Added `msg_filtered_block` inventory type to `getdata` message.<BR> Added `filterload`, `filteradd`, `filterclear` and `merkleblock` messages.<BR>Added `notfound` message (released but not in BIP).|
|
||||||
| 60 000 | [BIP-0031](/history/bips) | Added pong. |
|
| 60 002 | [BIP-0035](/history/bips) | Sep 2012<br> Bitcoin Core 0.7.0| Added `mempool` message. Extended `getdata` message to allow download of memory pool transactions.|
|
||||||
| 70 001 | [BIP-0037](/history/bips) | Added `relay` flag to the `version` message.|
|
| 60 001 | [BIP-0031](/history/bips) | May 2012<br> Bitcoin Core 0.6.1 |Added pong message. Added nonce field to `ping` message. |
|
||||||
|
| 60 000 | [BIP-0014](/history/bips) | Mar 2012<br> Bitcoin Core 0.6.0 |Network Version decoupled from Block Version. User-agent replaced sub-version number. |
|
||||||
|
|||Sep 2011|BIP process implemented|
|
||||||
|
|31 800 | |Dec 2010<br> Bitcoin Core 0.3.15| Added `getheaders` message and `headers` message.|
|
||||||
|
|31 402| | Oct 2010<br> Bitcoin Core 0.3.15| Time field added to `address` messages. |
|
||||||
|
| 311 ||Aug 2010<Br>Bitcoin Core 0.3.11| Added `alert` message.|
|
||||||
|
| 209 | |May 2010<br>Bitcoin Core 0.2.9 | `address` message may accept a list of network addresses. Added checksum field to message headers.|
|
||||||
|
| 106 | | Oct 2009<br> Bitcoin Core 0.1.6 | Added the following fields to the `version` message: `address-from`, `nonce`, `user-agent`, `current block height`. |
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# Transaction Version History
|
||||||
|
| Version Number | Proposed In | Released | Summary |
|
||||||
|
|--|--|---|
|
||||||
|
|||Aug 2017| Bitcoin Cash hard fork.|
|
||||||
|
|2|[BIP-0068](/history/bips)|May 2016<br>Bitcoin Core 0.12.1|Added relative lock-time (RLT) consensus-enforced semantics of the transaction input sequence number field.|
|
||||||
|
|1|||As used in the genesis block.|
|
||||||
@@ -22,16 +22,27 @@
|
|||||||
[Block-Level Validation Rules](/protocol/blockchain/transaction-validation/block-level-validation-rules) — [Network-Level Validation Rules](/protocol/blockchain/transaction-validation/network-level-validation-rules)
|
[Block-Level Validation Rules](/protocol/blockchain/transaction-validation/block-level-validation-rules) — [Network-Level Validation Rules](/protocol/blockchain/transaction-validation/network-level-validation-rules)
|
||||||
|
|
||||||
### Proof of Work (PoW)
|
### Proof of Work (PoW)
|
||||||
[Proof of Work](/protocol/blockchain/proof-of-work) — [Difficulty Adjustment Algorithm](/protocol/blockchain/proof-of-work/difficulty-adjustment-algorithm) — [Mining](/protocol/blockchain/proof-of-work/mining) — Stratum Protocol — Mining Pools
|
[Proof of Work](/protocol/blockchain/proof-of-work) — [Difficulty Adjustment Algorithm](/protocol/blockchain/proof-of-work/difficulty-adjustment-algorithm) — [Mining](/protocol/blockchain/proof-of-work/mining) — [Stratum Protocol](/mining/stratum-protocol) — [Mining Pools](/mining/mining-pools)
|
||||||
|
|
||||||
### Addresses
|
### Addresses
|
||||||
Pay To Public Key (P2PK) — Pay To Public Key Hash (P2PKH) — Pay To Script Hash (P2SH) — [Base58Check encoding (legacy)](/protocol/blockchain/encoding/base58check) — [Cashaddr Encoding](/protocol/blockchain/encoding/cashaddr)
|
[Address Types](/protocol/blockchain/addresses) — [Base58Check Encoding (legacy)](/protocol/blockchain/encoding/base58check) — [Cashaddr Encoding](/protocol/blockchain/encoding/cashaddr)
|
||||||
|
|
||||||
### Cryptography
|
### Cryptography
|
||||||
Secp256k1 — Public Key — Private Key — ECDSA Signatures — Schnorr Signatures — [Multisignature (M-of-N multisig)](/protocol/blockchain/cryptography/multisignature)
|
[Bitcoin Keys (Public/Private)](/protocol/blockchain/cryptography/keys) — [Signatures (ECDSA/Schnorr)](/protocol/blockchain/cryptography/signatures) — [Multisignature (M-of-N multisig)](/protocol/blockchain/cryptography/multisignature)
|
||||||
|
|
||||||
### Network upgrades
|
### Network upgrades
|
||||||
[Bip-16](/protocol/forks/bip-0016) — [Bip-34](/protocol/forks/bip-0034) — [Bip-37](/protocol/forks/bip-0037) — [Bip-65](/protocol/forks/bip-0065) — [Bip-66](/protocol/forks/bip-0066) — [Bip-68](/protocol/forks/bip-0068) — [Bip-112](/protocol/forks/bip-0112) — [Bip-113](/protocol/forks/bip-0113) — [Bip-157](/protocol/forks/bip-0157) — [Bip-158](/protocol/forks/bip-0158) — [Bip-159](/protocol/forks/bip-0159) — [BCH-UAHF (BUIP-55)](/protocol/forks/bch-uahf) — [HF-20171113](/protocol/forks/hf-20171113) — [HF-20180515](/protocol/forks/hf-20180515) — [HF-20181115](/protocol/forks/hf-20181115) — [HF-20190515](/protocol/forks/hf-20190515) — [HF-20191115](/protocol/forks/hf-20191115)
|
|
||||||
|
**Pre-BCH:** [Bip-9](/protocol/forks/bip-0009) — [Bip-16](/protocol/forks/bip-0016) — [Bip-34](/protocol/forks/bip-0034) — [Bip-37](/protocol/forks/bip-0037) — [Bip-65](/protocol/forks/bip-0065) — [Bip-66](/protocol/forks/bip-0066) — [Bip-68](/protocol/forks/bip-0068) — [Bip-112](/protocol/forks/bip-0112) — [Bip-113](/protocol/forks/bip-0113) — [Bip-133](/protocol/forks/bip-0133) — [Bip-157](/protocol/forks/bip-0157) — [Bip-158](/protocol/forks/bip-0158) — [Bip-159](/protocol/forks/bip-0159)
|
||||||
|
|
||||||
|
**2017:** [BCH-UAHF (BUIP-55)](/protocol/forks/bch-uahf) — [HF-20171113](/protocol/forks/hf-20171113)
|
||||||
|
|
||||||
|
**2018:** [HF-20180515](/protocol/forks/hf-20180515) — [HF-20181115](/protocol/forks/hf-20181115)
|
||||||
|
|
||||||
|
**2019:** [HF-20190515](/protocol/forks/hf-20190515) — [HF-20191115](/protocol/forks/hf-20191115)
|
||||||
|
|
||||||
|
**2020:** [HF-20200515](/protocol/forks/hf-20200515) — [HF-20201115](/protocol/forks/hf-20201115)
|
||||||
|
|
||||||
|
**2021:** [HF-20210515](/protocol/forks/hf-20210515)
|
||||||
|
|
||||||
### Network protocol
|
### Network protocol
|
||||||
|
|
||||||
@@ -56,8 +67,12 @@ Secp256k1 — Public Key — Private Key — ECDSA Signatures — Schnorr Signat
|
|||||||
[sendcmpct](/protocol/network/messages/sendcmpct) — [get_xthin](/protocol/network/messages/get_xthin) — [xthinblock](/protocol/network/messages/xthinblock) — [thinblock](/protocol/network/messages/thinblock) — [get_xblocktx](/protocol/network/messages/get_xblocktx) — [xblocktx](/protocol/network/messages/xblocktx) — [xupdate](/protocol/network/messages/xupdate) — [xversion](/protocol/network/messages/xversion) — [xverack](/protocol/network/messages/xverack)
|
[sendcmpct](/protocol/network/messages/sendcmpct) — [get_xthin](/protocol/network/messages/get_xthin) — [xthinblock](/protocol/network/messages/xthinblock) — [thinblock](/protocol/network/messages/thinblock) — [get_xblocktx](/protocol/network/messages/get_xblocktx) — [xblocktx](/protocol/network/messages/xblocktx) — [xupdate](/protocol/network/messages/xupdate) — [xversion](/protocol/network/messages/xversion) — [xverack](/protocol/network/messages/xverack)
|
||||||
|
|
||||||
### Simple Payment Verification (SPV)
|
### Simple Payment Verification (SPV)
|
||||||
[SPV](/protocol/spv) - [Bloom Filters](/protocol/spv/bloom-filter)
|
|
||||||
|
[SPV](/protocol/spv) — [Bloom Filters](/protocol/spv/bloom-filter)
|
||||||
|
|
||||||
### Simple Ledger Protocol
|
### Simple Ledger Protocol
|
||||||
[SLP](/protocol/slp)
|
|
||||||
|
[SLP Overview](/protocol/slp) — [GENESIS](/protocol/slp/genesis) — [MINT](/protocol/slp/mint) — [SEND](/protocol/slp/send) — [COMMIT](/protocol/slp/commit)
|
||||||
|
|
||||||
### Miscellaneous
|
### Miscellaneous
|
||||||
[Endian](/protocol/misc/endian)
|
[Endian](/protocol/misc/endian)
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# Mining Pools
|
||||||
|
|
||||||
|
Mining pools coordinate the efforts of a (typically large) group of miners.
|
||||||
|
When a block is mined, the [block reward](/protocol/blockchain/block#coinbase-transaction) is distributed amongst the contributing members of the pool.
|
||||||
|
This cooperation converts the discrete nature of block rewards into a continuous income for miners, allowing for all members to receive rewards whenever anyone in the pool successfully mines a new block.
|
||||||
|
|
||||||
|
Miners generally connect to pools using the [Stratum protocol](/mining/stratum-protocol).
|
||||||
|
While mining, miners submit shares in addition to valid blocks, allowing the pool to statistically verify that the miner is actively performing work toward the provided jobs.
|
||||||
|
This mechanism also allows pools to distribute the block reward proportionally, based on the amount of work performed by each miner.
|
||||||
|
The amount and timing of reward distribution varies by pool.
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
# Stratum Protocol
|
||||||
|
|
||||||
|
The stratum protocol is used by [ASIC](https://en.wikipedia.org/wiki/Application-specific_integrated_circuit) miners, devices created specifically for performing Bitcoin [mining](/protocol/blockchain/proof-of-work/mining).
|
||||||
|
|
||||||
|
Miners use this protocol to reach out to one or more servers (e.g. a mining pool) in order to obtain a template for a new [block](/protocol/blockchain/block).
|
||||||
|
The template has gaps where random data can be added until the the miner successfully creates a candidate block that meets the specified difficulty requirements.
|
||||||
|
|
||||||
|
## Message Format
|
||||||
|
|
||||||
|
Stratum uses the [JSON-RPC 2.0](https://en.wikipedia.org/wiki/JSON-RPC) message format.
|
||||||
|
That is, [JSON](https://en.wikipedia.org/wiki/JSON)-encoded messages, separated by newline (line feed) characters.
|
||||||
|
There are two high-level message formats: requests and responses.
|
||||||
|
|
||||||
|
### Requests
|
||||||
|
|
||||||
|
Requests all contain the following fields:
|
||||||
|
|
||||||
|
| Field | Format | Description |
|
||||||
|
|--|--|--|
|
||||||
|
| id | number or string | A message ID that must be unique per request that expects a response. For requests not expecting a response (called notifications), this is null. |
|
||||||
|
| method | string | Indicates the type of request the message represents. |
|
||||||
|
| params | array | Additional data which varies based on the request method. |
|
||||||
|
|
||||||
|
### Responses
|
||||||
|
|
||||||
|
Responses all contain the following fields:
|
||||||
|
|
||||||
|
| Field | Format | Description |
|
||||||
|
|--|--|--|
|
||||||
|
| id | number or string | The ID of the request that this message is a response to. |
|
||||||
|
| result | any | Data being returned in response to the request. Must be present, but may be a string, number, array, object, or null. |
|
||||||
|
| error | [error array](#error-array-format) | Indicates that the request could not be fulfilled and provides information about what went wrong. |
|
||||||
|
|
||||||
|
#### Error Array Format
|
||||||
|
|
||||||
|
The error array is a JSON array containing the following elements:
|
||||||
|
|
||||||
|
| Field | Format | Description |
|
||||||
|
|--|--|--|
|
||||||
|
| error code | number | An error code indicating the type of error. |
|
||||||
|
| message | string | A description of the error. |
|
||||||
|
| data | object | Additional data associated with the error (nullable). |
|
||||||
|
|
||||||
|
*Example error:* <code>{"result":null,"id":2,"error":[24,"Unauthorized worker",null]}</code>
|
||||||
|
|
||||||
|
Beyond those specified by JSON-RPC, the following error codes are used:
|
||||||
|
|
||||||
|
| Code | Description |
|
||||||
|
|--|--|
|
||||||
|
| 20 | Other/Unknown |
|
||||||
|
| 21 | Job not found (=stale) |
|
||||||
|
| 22 | Duplicate share |
|
||||||
|
| 23 | Low difficulty share |
|
||||||
|
| 24 | Unauthorized worker |
|
||||||
|
| 25 | Not subscribed |
|
||||||
|
|
||||||
|
## Client Methods
|
||||||
|
|
||||||
|
### mining.subscribe
|
||||||
|
|
||||||
|
Upon connecting to a server, clients are expected to send a subscribe request, described as follows.
|
||||||
|
|
||||||
|
| Field | Format | Description |
|
||||||
|
|--|--|--|
|
||||||
|
| method | string | "mining.subscribe" |
|
||||||
|
| params\[0\] | string | User agent and version, separated by a forward slash (e.g. "Node/1.0.0"). |
|
||||||
|
| params\[1\] | string | Suggested extra nonce value (optional). |
|
||||||
|
|
||||||
|
*Example request:* <code>{"id": 1, "method": "mining.subscribe", "params": ["Node/1.0.0"]}</code>
|
||||||
|
|
||||||
|
In response, the server will send the following data in its result object, which is a JSON array:
|
||||||
|
|
||||||
|
| Field | Format | Description |
|
||||||
|
|--|--|--|
|
||||||
|
| subscriptions | array | An array containing sub-array that described intended subscriptions. The first value in sub-arrays is the subscription type (e.g. "mining.set_difficulty"), the second is a subscription ID. |
|
||||||
|
| extra nonce 1 | string | The selected extra nonce 1 value. |
|
||||||
|
| extra nonce 2 byte count | number | The size, in bytes, that the extra nonce 2 should be. |
|
||||||
|
|
||||||
|
*Example response:* <code>{"result":[[["mining.set_difficulty","731ec5e0649606ff"],["mining.notify","731ec5e0649606ff"]],"e9695791",4],"id":1,"error":null}</code>
|
||||||
|
|
||||||
|
### mining.authorize
|
||||||
|
|
||||||
|
In order to authenticate itself, the client send an authorize message:
|
||||||
|
|
||||||
|
| Field | Format | Description |
|
||||||
|
|--|--|--|
|
||||||
|
| method | string | "mining.authorize" |
|
||||||
|
| params\[0\] | string | The client's user name. |
|
||||||
|
| params\[1\] | string | The client's password (if required by the server). |
|
||||||
|
|
||||||
|
*Example request:* <code>{"id": 1, "method": "mining.authorize", "params": ["username", "p4ssw0rd"]}</code>
|
||||||
|
|
||||||
|
Response format:
|
||||||
|
|
||||||
|
| Field | Format | Description |
|
||||||
|
|--|--|--|
|
||||||
|
| result | boolean | The value true if the client has been authorized; false otherwise. |
|
||||||
|
|
||||||
|
*Example response:* <code>{"id": 2, "result": true, "error": null}</code>
|
||||||
|
|
||||||
|
### mining.submit
|
||||||
|
|
||||||
|
Once the client has completed a job (received via [mining.notify](#miningnotify) following an accepted [mining.authorize](#miningauthorize)), it returns its result using a submit message.
|
||||||
|
This message is also used to submit shares to a mining pool.
|
||||||
|
The format is as follows:
|
||||||
|
|
||||||
|
| Field | Format | Description |
|
||||||
|
|--|--|--|
|
||||||
|
| method | string | "mining.submit" |
|
||||||
|
| params\[0\] | string | The client's user name. |
|
||||||
|
| params\[1\] | string | The job ID for the work being submitted. |
|
||||||
|
| params\[2\] | string | The hex-encoded value of extra nonce 2. |
|
||||||
|
| params\[3\] | string | The hex-encoded time value use in the block header. |
|
||||||
|
| params\[4\] | string | The hex-encoded nonce value to use in the block header. |
|
||||||
|
|
||||||
|
*Example request:* <code>{"id": 1, "method": "mining.submit", "params": ["username", "4f", "fe36a31b", "504e86ed", "e9695791"]}</code>
|
||||||
|
|
||||||
|
Response format:
|
||||||
|
|
||||||
|
| Field | Format | Description |
|
||||||
|
|--|--|--|
|
||||||
|
| result | boolean | The value true if the submission has been accepted; false if it was rejected. |
|
||||||
|
|
||||||
|
*Example response:* <code>{"id": 2, "result": true, "error": null}</code>
|
||||||
|
|
||||||
|
## Server Methods
|
||||||
|
|
||||||
|
### mining.notify
|
||||||
|
|
||||||
|
Once a client successfully connects using the [mining.subscribe](#miningsubscribe) and [mining.authorize](#miningauthorize) messages, the server may send a job to the client, informing it of everything it needs to know in order to mine a new block.
|
||||||
|
The notify message is a notification (does not expect a response) and has the following format:
|
||||||
|
|
||||||
|
| Field | Format | Description |
|
||||||
|
|--|--|--|
|
||||||
|
| method | string | "mining.notify" |
|
||||||
|
| params\[0\] | string | The job ID for the job being sent in this message. |
|
||||||
|
| params\[1\] | string | The hex-encoded previous block hash. |
|
||||||
|
| params\[2\] | string | The hex-encoded prefix of the coinbase transaction (to precede extra nonce 2). |
|
||||||
|
| params\[3\] | string | The hex-encoded suffix of the coinbase transaction (to follow extra nonce 2). |
|
||||||
|
| params\[4\] | array | A JSON array containing the hex-encoded hashes needed to compute the [merkle root](/protocol/blockchain/block/merkle-tree). See [Merkle Tree Hash Array](#merkle-tree-hash-array). |
|
||||||
|
| params\[5\] | string | The hex-encoded block version. |
|
||||||
|
| params\[6\] | string | The hex-encoded network difficulty required for the block. |
|
||||||
|
| params\[7\] | string | The hex-encoded current time for the block. |
|
||||||
|
| params\[8\] | boolean | Indicates whether the client should forget any prior jobs. If true, the server will reject any submissions for prior jobs and the miner should forget any prior job IDs so that they can be reused by the server. |
|
||||||
|
|
||||||
|
*Example request:* <code>{"id": null, "method": "mining.notify", "params": ["bf", "4d16b6f85af6e2198f44ae2a6de67f78487ae5611b77c6c0440b921e00000000",
|
||||||
|
"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff20020862062f503253482f04b8864e5008",
|
||||||
|
"072f736c7573682f000000000100f2052a010000001976a914d23fcdf86f7e756a64a7a9688ef9903327048ed988ac00000000", [],
|
||||||
|
"00000002", "1c2ac4af", "504e86b9", false]}</code>
|
||||||
|
|
||||||
|
#### Merkle Tree Hash Array
|
||||||
|
|
||||||
|
The array of merkle tree hashes in the [mining.notify](#miningnotify) request, denote (in order) the hashes that should be iteratively composed with the coinbase transaction has to ultimately generate the merkle root.
|
||||||
|
In the simplest case, where the block will only contain the coinbase transaction, the array is empty and the coinbase transaction hash becomes the merkle root.
|
||||||
|
When there are more transactions, however, the merkle tree hash array contains the leaf nodes of the partial merkle tree, as shown below.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
graph TD
|
||||||
|
|
||||||
|
root[Merkle Root] --- 0[Hash0]
|
||||||
|
root[Merkle Root] --- 1[Hash1]
|
||||||
|
0 --- 00[Hash00]
|
||||||
|
0 --- 01[Hash01]
|
||||||
|
00 --- 000[Hash000]
|
||||||
|
00 --- 001[Hash001]
|
||||||
|
000 --- coinbase[Coinbase]
|
||||||
|
|
||||||
|
style root stroke-width: 3px, stroke-dasharray: 5
|
||||||
|
style 0 stroke-width: 3px, stroke-dasharray: 5
|
||||||
|
style 00 stroke-width: 3px, stroke-dasharray: 5
|
||||||
|
style 000 stroke-width: 3px, stroke-dasharray: 5
|
||||||
|
style 1 stroke-width: 3px, stroke-bold: 5
|
||||||
|
style 01 stroke-width: 3px, stroke-bold: 5
|
||||||
|
style 001 stroke-width: 3px, stroke-bold: 5
|
||||||
|
```
|
||||||
|
|
||||||
|
In the example above, dashed lines indicate hashes that must be computed, while bold lines indicate hashes are are included in the merkle tree hash array, which in this case would be: <code>["Hash000", "Hash00", "Hash0"]</code>.
|
||||||
|
So after the coinbase transaction is created, it is hashed into `Hash000`.
|
||||||
|
Then `Hash000` and `Hash001` are hashed together to create `Hash00`, and so on until the Merkle Root is computed.
|
||||||
|
|
||||||
|
## mining.set_difficulty
|
||||||
|
|
||||||
|
When reporting shares to the server, clients are expected to default to a [difficulty](/protocol/blockchain/proof-of-work#difficulty) of 1 (a [target](/protocol/blockchain/proof-of-work#target) of: `0x00000000ffff0000000000000000000000000000000000000000000000000000`).
|
||||||
|
At any point, however, the server can change that threshold by sending a `set_difficulty` message:
|
||||||
|
|
||||||
|
| Field | Format | Description |
|
||||||
|
|--|--|--|
|
||||||
|
| method | string | "mining.set_difficulty" |
|
||||||
|
| params\[0\] | number | The new difficulty threshold for share reporting. Shares are reported using the [mining.submit](#miningsubmit) message. |
|
||||||
|
|
||||||
|
*Example request:* <code>{ "id": null, "method": "mining.set_difficulty", "params": [2]}</code>
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<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;
|
|
||||||
```
|
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
# Address Types
|
||||||
|
|
||||||
|
Addresses are commonly used identifiers that act as a shorthand for who can spend a given output.
|
||||||
|
Since Bitcoin Cash [transactions](/protocol/blockchain/transaction) do not inherently have a concept of accounts with balances, it is not always easy (or even possible) to determine which unspent outputs are spendable by a given person.
|
||||||
|
However, the [standard scripts](/protocol/blockchain/transaction/locking-script#standard-scripts) were designed to provide a straightforward structure that can be used to identify transactions that spendable in similar ways.
|
||||||
|
In most cases, the address contains all of the information necessary to create a transaction output that is spendable by the owner of the address.
|
||||||
|
Due to this and their compactness, addresses are the most common way to specify to others how ("where") they can receive funds.
|
||||||
|
|
||||||
|
Raw addresses are rarely used outside of scripts, though, as they lack context and redundancy.
|
||||||
|
Instead, addresses are typically encoded using the [Base58Check](/protocol/blockchain/encoding/base58check) or [CashAddr](/protocol/blockchain/encoding/cashaddr) formats to ensure they are received and interpreted correctly.
|
||||||
|
These encodings include checksums as well as information about the type of address being encoded.
|
||||||
|
CashAddr was created after Base58Check (also referred to as legacy encoding) to avoid conflicts with pre-existing BTC address.
|
||||||
|
|
||||||
|
## Pay to Public Key Hash (P2PKH) Addresses
|
||||||
|
|
||||||
|
[P2PKH](/protocol/blockchain/transaction/locking-script#pay-to-public-key-hash-p2pkh) addresses encode the hash of the public key that is locking the output (i.e. `RIPEMD-160(SHA-256(publicKey))`).
|
||||||
|
Mainnet P2PKH addresses always start with `1` in Base58Check encoding and `q` in CashAddr encoding:
|
||||||
|
|
||||||
|
Base58Check: 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
|
||||||
|
CashAddr: bitcoincash:qp3wjpa3tjlj042z2wv7hahsldgwhwy0rq9sywjpyy
|
||||||
|
|
||||||
|
The following diagram show the full creation process for a P2PKH address:
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
graph LR
|
||||||
|
PrivK["Private Key"] ==>PubK[Public key]
|
||||||
|
PubK == SHA256 and RIPEMD160 ==> PubKH[Public Key Hash]
|
||||||
|
PubKH ==> Address
|
||||||
|
Address ==> PubKH
|
||||||
|
style PubK fill:#F06,stroke:#333,stroke-width:2px;
|
||||||
|
style PrivK fill:#B06,stroke:#333,stroke-width:8px;
|
||||||
|
style PubKH fill:#0F6,stroke:#333,stroke-width:2px;
|
||||||
|
style Address fill:#0F6,stroke:#333,stroke-width:2px;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pay to Script Hash (P2SH) Addresses
|
||||||
|
|
||||||
|
[P2SH](/protocol/blockchain/transaction/locking-script#pay-to-script-hash-p2sh) addresses encode the redeem script hash (i.e. `RIPEMD-160(redeemScript)`).
|
||||||
|
Mainnet P2SH addresses always start with `3` in Base58Check encoding and `p` in CashAddr encoding.
|
||||||
|
|
||||||
|
Base58Check: 3N5i3Vs9UMyjYbBCFNQqU3ybSuDepX7oT3
|
||||||
|
CashAddr: bitcoincash:pr0662zpd7vr936d83f64u629v886aan7c77r3j5v5
|
||||||
|
|
||||||
|
## Multisig Addresses
|
||||||
|
|
||||||
|
Multisig addresses are occasionally referenced despite there not being a specific process for creating them.
|
||||||
|
This is because the addresses being referred to are actually P2SH addresses for redeem scripts that perform [multisignature](/protocol/blockchain/cryptography/multisignature) validation.
|
||||||
|
As such, they look exactly like P2SH addresses and are indistinguishable from them until the script is known and inspected.
|
||||||
|
Moreover, outputs created using multsig addresses use the P2SH script format, not the [Multisig (P2MS)](/protocol/blockchain/transaction/locking-script#multisig-p2ms) script format.
|
||||||
|
|
||||||
|
Alternatively, with the advent of [Schnorr signatures](/protocol/blockchain/cryptography/signatures#schnorr-signatures) in BCH, it is also possible perform n-of-n multisignature locking and unlocking using [aggregated keys and signatures](/protocol/blockchain/cryptography/multisignature#private-multisignature).
|
||||||
|
Only a single signature is produces, regardless of the number of parties involved, reducing the cost of multisignature validation and minimizing transaction size.
|
||||||
|
This also means it could fit in a P2PKH (or P2PK) script, and therefore have a typical address of that type.
|
||||||
|
This technique is newer, however, and not as widely implemented as the P2SH method.
|
||||||
@@ -16,9 +16,9 @@ Since validation of all the transactions in the block can be expensive, the abil
|
|||||||
|
|
||||||
| Field | Length | Format | Description |
|
| Field | Length | Format | Description |
|
||||||
|--|--|--|--|
|
|--|--|--|--|
|
||||||
| version | 4 bytes | unsigned integer<sup>[(LE)](/protocol/misc/endian/little)</sup> | The block format version. |
|
| version | 4 bytes | unsigned integer<sup>[(LE)](/protocol/misc/endian/little)</sup> | The block format version. Currently 0x04000000. <br>For more details refer to the [block version history](/history/block-version). |
|
||||||
| previous block hash | 32 bytes | [block hash](/protocol/blockchain/hash)<sup>[(LE)](/protocol/misc/endian/little)</sup> | The hash of the block immediately preceding this block in the blockchain. |
|
| previous block hash | 32 bytes | [block hash](/protocol/blockchain/hash)<sup>[(LE)](/protocol/misc/endian/little)</sup> | The hash of the block immediately preceding this block in the blockchain. |
|
||||||
| merkle root | 32 bytes | [merkle root](/protocol/blockchain/merkle-tree)<sup>[(LE)](/protocol/misc/endian/little)</sup> | The merkle tree root of the transactions in the block. |
|
| merkle root | 32 bytes | [merkle root](/protocol/blockchain/block/merkle-tree)<sup>[(LE)](/protocol/misc/endian/little)</sup> | The merkle tree root of the transactions in the block. |
|
||||||
| timestamp | 4 bytes | unix timestamp<sup>[(LE)](/protocol/misc/endian/little)</sup> | The epoch timestamp of the block in seconds. |
|
| timestamp | 4 bytes | unix timestamp<sup>[(LE)](/protocol/misc/endian/little)</sup> | The epoch timestamp of the block in seconds. |
|
||||||
| target | 4 bytes | [compressed target](#compressed-target-format)<sup>[(LE)](/protocol/misc/endian/little)</sup> | The target that the block hash must be below to be valid. This value is determined by the timestamps of previously mined blocks. See [Target](/protocol/blockchain/proof-of-work#target) for more information. |
|
| target | 4 bytes | [compressed target](#compressed-target-format)<sup>[(LE)](/protocol/misc/endian/little)</sup> | The target that the block hash must be below to be valid. This value is determined by the timestamps of previously mined blocks. See [Target](/protocol/blockchain/proof-of-work#target) for more information. |
|
||||||
| nonce | 4 bytes | bytes<sup>[(LE)](/protocol/misc/endian/little)</sup> | A random value that is repeatedly changes during block mining in order to achieve the block hash requirements. |
|
| nonce | 4 bytes | bytes<sup>[(LE)](/protocol/misc/endian/little)</sup> | A random value that is repeatedly changes during block mining in order to achieve the block hash requirements. |
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
# Bitcoin Keys
|
||||||
|
|
||||||
|
Bitcoin Cash transactions are secured through the use of key-pairs generated by all senders and receivers.
|
||||||
|
The key-pair is comprised of a **private key**, which is generated randomly and stored securely on a user's device, and a **public key**, which is calculated from the private key but can be sent to others without revealing the private key.
|
||||||
|
The private key can be used to generate [signatures](/protocol/blockchain/cryptography/signatures), which can then be verified using the public key.
|
||||||
|
|
||||||
|
## Private Key Generation
|
||||||
|
|
||||||
|
Bitcoin Cash uses [elliptic-curve cryptography (ECC)](https://en.wikipedia.org/wiki/Elliptic-curve_cryptography); in particular, the secp256k1 curve with 32-byte (256-bit) private keys.
|
||||||
|
|
||||||
|
From [SEC 2, ver. 2.0](https://www.secg.org/sec2-v2.pdf), the curve parameters are as follows:
|
||||||
|
|
||||||
|
> The elliptic curve domain parameters over Fp associated with a Koblitz curve secp256k1 are
|
||||||
|
> specified by the sextuple `T = (p, a, b, G, n, h)` where the finite field `F<sub>p</sub>` is defined by:
|
||||||
|
>
|
||||||
|
> p = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F
|
||||||
|
> = 2<sup>256</sup> − 2<sup>32</sup> − 2<sup>9</sup> − 2<sup>8</sup> − 2<sup>7</sup> − 2<sup>6</sup> − 2<sup>4</sup> − 1
|
||||||
|
>
|
||||||
|
> The curve E: `y<sup>2</sup> = x<sup>3</sup> + ax + b` over `F<sub>p</sub>` is defined by:
|
||||||
|
>
|
||||||
|
> a = 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
||||||
|
> 00000000
|
||||||
|
>
|
||||||
|
> b = 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
||||||
|
> 00000007
|
||||||
|
>
|
||||||
|
> The base point G in compressed form is:
|
||||||
|
>
|
||||||
|
> G = 02 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798
|
||||||
|
>
|
||||||
|
> and in uncompressed form is:
|
||||||
|
>
|
||||||
|
> G = 04 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9
|
||||||
|
> 59F2815B 16F81798 483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448
|
||||||
|
> A6855419 9C47D08F FB10D4B8
|
||||||
|
>
|
||||||
|
> Finally the order n of G and the cofactor are:
|
||||||
|
>
|
||||||
|
> n = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141
|
||||||
|
>
|
||||||
|
> h = 01
|
||||||
|
|
||||||
|
Private keys are then 256-bit values and can be chosen at [random](https://en.wikipedia.org/wiki/Cryptographically-secure_pseudorandom_number_generator) from the set `[1, n-1]`.
|
||||||
|
|
||||||
|
It is important that private keys are stored securely and never revealed to untrusted third-parties.
|
||||||
|
Anyone with access to a given private key would be able to control any funds secured with that key.
|
||||||
|
|
||||||
|
## Public Key Generation
|
||||||
|
|
||||||
|
Public keys are created by performing [scalar multiplication of the generator](https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication), G, with the private key.
|
||||||
|
|
||||||
|
This means that public keys are a point on the elliptic curve, represented as two 256-bit coordinates, `(x, y)`.
|
||||||
|
This means that a full public key is 512-bits (64 bytes) in length.
|
||||||
|
However, since elliptic curves are symmetrical across the x-axis, there are always two y-values that correspond to a given x-value, which can be calculated using the curve function, E.
|
||||||
|
These are also necessarily negations of each other mod p (i.e. y<sub>1</sub> = p - y<sub>2</sub>).
|
||||||
|
As a result, public keys are often **compressed** into 33 bytes, 32 bytes for the x-value and an additional bit (generally expanded to a full byte) indicating which y-value should be used.
|
||||||
|
|
||||||
|
When included in [scripts](/protocol/blockchain/script), public keys follow one of two formats:
|
||||||
|
|
||||||
|
### Uncompressed Public Key Format
|
||||||
|
|
||||||
|
| Field | Length | Format | Description |
|
||||||
|
|--|--|--|--|
|
||||||
|
| magic number | 1 byte | byte | Always `0x04`, indicating that this is an uncompressed public key. |
|
||||||
|
| x-value | 32 bytes | bytes | The zero-padded x-value of the public key. |
|
||||||
|
| y-value | 32 bytes | bytes | The zero-padded y-value of the public key. |
|
||||||
|
|
||||||
|
### Compressed Public Key Format
|
||||||
|
|
||||||
|
| Field | Length | Format | Description |
|
||||||
|
|--|--|--|--|
|
||||||
|
| magic number | 1 byte | byte | `0x02` if the (discarded) y-value was even, `0x03` if it was odd. This bytes indicates both that this is a compressed public key and which y-value should be used.<br/><br/>NOTE: this works because the y-values are negations of each other (mod p), so it is always that case that one is even and the other odd. |
|
||||||
|
| x-value | 32 bytes | bytes | The zero-padded x-value of the public key. |
|
||||||
@@ -4,7 +4,7 @@ Multisignature (often called "multisig") refers to requiring multiple keys to sp
|
|||||||
|
|
||||||
Multisignature scripts set a condition where N public keys are recorded in the script and at least M of those must provide signatures to unlock the funds. This is also known as *M-of-N multisignature scheme*, where N is the total number of keys and M is the threshold of signatures required for validation. The signatures used can either be ECDSA signatures or Schnorr signatures.
|
Multisignature scripts set a condition where N public keys are recorded in the script and at least M of those must provide signatures to unlock the funds. This is also known as *M-of-N multisignature scheme*, where N is the total number of keys and M is the threshold of signatures required for validation. The signatures used can either be ECDSA signatures or Schnorr signatures.
|
||||||
|
|
||||||
## Public multisignature: OP_CHECKMULTISIG(VERIFY)
|
## Public Multisignature: OP_CHECKMULTISIG(VERIFY)
|
||||||
|
|
||||||
Multisig schemes can be built with the opcodes `OP_CHECKMULTISIG` and `OP_CHECKMULTISIGVERIFY`, two opcodes of the Bitcoin Cash [scripting language](/protocol/blockchain/script). `OP_CHECKMULTISIGVERIFY` has the same implementation as `OP_CHECKMULTISIG`, except OP_VERIFY is executed afterward.
|
Multisig schemes can be built with the opcodes `OP_CHECKMULTISIG` and `OP_CHECKMULTISIGVERIFY`, two opcodes of the Bitcoin Cash [scripting language](/protocol/blockchain/script). `OP_CHECKMULTISIGVERIFY` has the same implementation as `OP_CHECKMULTISIG`, except OP_VERIFY is executed afterward.
|
||||||
|
|
||||||
@@ -78,7 +78,9 @@ If they want to use Schnorr, they have to sign the transaction with this algorit
|
|||||||
|
|
||||||
The value of the `dummy` element is 5, whose binary representation is `0b101`. This ensures that Alice's signature (`sigA`) is checked against her public key (`pubkeyA`), that Carol's signature (`sigC`) is not checked against Bob's public key (`pubkeyB`) but against her public key (`pubkeyC`).
|
The value of the `dummy` element is 5, whose binary representation is `0b101`. This ensures that Alice's signature (`sigA`) is checked against her public key (`pubkeyA`), that Carol's signature (`sigC`) is not checked against Bob's public key (`pubkeyB`) but against her public key (`pubkeyC`).
|
||||||
|
|
||||||
## Private multisignature
|
## Private Multisignature
|
||||||
|
|
||||||
Multisig schemes can also be implemented in P2PKH outputs, using Schnorr agregation property.
|
|
||||||
|
|
||||||
|
N-of-N multisig schemes can also be implemented in P2PKH outputs, using the Schnorr aggregation property.
|
||||||
|
By combining the public keys of the cooperating parties, a combined public key can be created and used in a locking script.
|
||||||
|
When spending the output, the parties can jointly create a signature that will validate as a normal Schnorr signature for the combined public key in the locking script.
|
||||||
|
For more details, see [MuSig](https://eprint.iacr.org/2018/068).
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# Signatures
|
||||||
|
|
||||||
|
Bitcoin transaction generally require at least one signature in order to be valid.
|
||||||
|
Signatures prove that the intended recipient(s) of the funds being spent were involved in the creation of the transaction.
|
||||||
|
Each signature is generated using a [private key](/protocol/blockchain/cryptography/keys) and indicates that the owner of that private key approves of certain data in the transaction.
|
||||||
|
This page describes how these signature are generated, given data to be signed and a private key.
|
||||||
|
For details on what data is signed when signing a transaction and how the signature is formatted, see [Transaction Signing](/protocol/blockchain/transaction/transaction-signing).
|
||||||
|
|
||||||
|
Bitcoin Cash permits two algorithms for transaction signatures: [ECDSA](#ecdsa-signatures) and [Schnorr](#schnorr-signatures).
|
||||||
|
|
||||||
|
## ECDSA Signatures
|
||||||
|
|
||||||
|
ECDSA, as defined in [RFC 6979](https://tools.ietf.org/html/rfc6979), can be thought of as taking three input parameters: the private key, the message to be signed, and a random value, **k**, taken from the [same domain as a private key](/protocol/blockchain/cryptography/keys#private-key-generation), `[1, n-1]`.
|
||||||
|
|
||||||
|
Generally with ECDSA, the message used is a hash of the data that is intended to be signed.
|
||||||
|
In the case of Bitcoin Cash, this is the hash of the transaction [preimage](/protocol/blockchain/transaction/transaction-signing#preimage-format) for the context in which the signature will be provided (i.e. for a given position in a script).
|
||||||
|
It is also common, and recommended, to use a **deterministic k** value (defined in [RFC 6979, section 3](https://tools.ietf.org/html/rfc6979#section-3)), which is dependent on the private key and the message being signed.
|
||||||
|
Using a deterministic k value guarantees that a different k will never be used to sign an identical message, a mistake which would reveal the user's private key.
|
||||||
|
However, since it is impossible to know the method used to generate k without the user's private key, it is impossible to enforce the use of this method.
|
||||||
|
|
||||||
|
The output of ECDSA is two values, **r** and **s** which can be used with the public key and message to verify the authenticity of the signature.
|
||||||
|
However, there are technically two valid s value that are possible, which are additive inverses (i.e. `s<sub>1</sub> + s<sub>2</sub> (mod p) = 0 (mod p)`).
|
||||||
|
By convention, and since [HF-20171113](/protocol/forks/hf-20171113), the lower s value must be used (this is known as the "LOW_S" rule).
|
||||||
|
|
||||||
|
## Schnorr Signatures
|
||||||
|
|
||||||
|
Schnorr signatures have been accepted in Bitcoin Cash since [HF-20190515](/protocol/forks/hf-20190515).
|
||||||
|
Details on the implementation of Schnorr used in Bitcoin Cash can be found [here](/protocol/forks/2019-05-15-schnorr).
|
||||||
|
Of particular importance are the following points:
|
||||||
|
|
||||||
|
- Pre-existing Public and Private Keys are valid for generating Schnorr signatures.
|
||||||
|
- Following activation of Schnorr signatures, all 64-byte signatures passed to OP_CHECKDATASIG/VERIFY and all 65-byte signatures passed to OP_CHECKSIG/VERIFY are interpretted as Schnorr signatures.
|
||||||
|
65-byte signatures passed to OP_CHECKMULTISIG/VERIFY will trigger script failure.
|
||||||
|
- Bitcoin Cash uses the (r, s) variant of Schnorr, instead of the (e, s) variant, with an altered approach from that originally proposed by Pieter Wuille.
|
||||||
|
- Both random and deterministic k values are considered secure, though care must be taken with deterministic k values to avoid conflicts with deterministic ECDSA k values.
|
||||||
|
|
||||||
@@ -1,22 +1,83 @@
|
|||||||
# Difficulty Adjustment Algorithm
|
# Difficulty Adjustment Algorithm
|
||||||
|
|
||||||
In order to correct for changes in the Bitcoin Cash network's total hashing power (i.e. as hardware improves or nodes are added to or removed from the network), the amount of work required to mine a block must change in tandem.
|
In order to correct for changes in the Bitcoin Cash network's total hashing power (i.e. as hardware improves or nodes are added to or removed from the network), the amount of work required to mine a block must change in tandem.
|
||||||
Bitcoin Cash solves this by adjusting the difficulty according to an algorithm that looks at recent block timestamps, infers the hashing power that led to those timestamps, and adjusts the difficulty for future blocks accordingly.
|
Bitcoin Cash solves this by adjusting the [target](/protocol/blockchain/proof-of-work#target) according to an algorithm that looks at recent block timestamps, infers the hashing power that led to those timestamps, and attempts to change the [difficulty](/protocol/blockchain/proof-of-work#difficulty) of mining future blocks accordingly.
|
||||||
|
The calculation used is referred to as the Difficulty Adjustment Algorithm, or DAA, and has changed a number of times.
|
||||||
|
In order to validate the blockchain, however, the difficulty must be verified using the DAA that was in use when that block was mined.
|
||||||
|
Consequently, the historical DAAs remain relevant to node implementation that wish to validate historical headers.
|
||||||
|
|
||||||
The current Bitcoin Cash difficulty adjustment algorithm attempts to ensure that the difficulty of new blocks is always closely tied to recent block difficulties.
|
The algorithms used, from newest to oldest, are:
|
||||||
|
|
||||||
|
- [ASERT](#asert)
|
||||||
|
- [CW-144](#cw-144)
|
||||||
|
- [Emergency DAA](#emergency-daa)
|
||||||
|
- [Legacy DAA](#legacy-daa)
|
||||||
|
|
||||||
|
## ASERT
|
||||||
|
|
||||||
|
Absolutely Scheduled Exponentially Rising Targets (ASERT), more specifically [aserti3-2d](/protocol/forks/2020-11-15-asert), was implemented as a part of [HF-20201115](/protocol/forks/hf-20201115).
|
||||||
|
It uses an [exponential moving average](https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average) approach that should theoretically always target a correction toward a 10 minute average block time.
|
||||||
|
ASERT bases it's calculations on the following components:
|
||||||
|
|
||||||
|
1. The **fork block**: The first block mined with the ASERT DAA
|
||||||
|
2. The **anchor block**: The parent of the fork block
|
||||||
|
3. The current head block
|
||||||
|
|
||||||
|
Though this is not used directly in practice, the exponential form of the calculation of the target for the next block is:
|
||||||
|
|
||||||
|
```
|
||||||
|
exponent = (time_delta - ideal_block_time * (height_delta + 1)) / halflife
|
||||||
|
next_target = anchor_target * 2**(exponent)
|
||||||
|
```
|
||||||
|
|
||||||
|
where:
|
||||||
|
|
||||||
|
- `anchor_target` is the unsigned 256 bit integer equivalent of the `nBits` value in
|
||||||
|
the header of the anchor block.
|
||||||
|
- `time_delta` is the difference, in signed integer seconds, between the
|
||||||
|
timestamp in the header of the current block and the timestamp in the
|
||||||
|
parent of the anchor block.
|
||||||
|
- `ideal_block_time` is a constant: 600 seconds, the targeted
|
||||||
|
average time between blocks.
|
||||||
|
- `height_delta` is the difference in block height between the current
|
||||||
|
block and the anchor block.
|
||||||
|
- `halflife` is a constant parameter sometimes referred to as
|
||||||
|
'tau', with a value of 172800 (seconds) on mainnet.
|
||||||
|
- `next_target` is the integer value of the target computed for the block
|
||||||
|
after the current block.
|
||||||
|
|
||||||
|
In order to avoid subtle platform-dependent floating point issues, however, ASERT is instead calculated using fixed-point integer arithmetic with a cubic polynomial approximation of the exponential.
|
||||||
|
See [ASERT:target computeration](/protocol/forks/2020-11-15-asert#target-computation) for the Python reference implementation and additional details on where new implementations of the algorithm must be cautious to ensure full compatibility.
|
||||||
|
|
||||||
|
## CW-144
|
||||||
|
|
||||||
|
CW-144 attempts to ensure that the difficulty of new blocks is always closely tied to the amount of work done on recent blocks.
|
||||||
|
The name referes to the fact that it evaluates the difference in [chainwork](/protocol/blockchain/proof-of-work#chainwork) (CW) across the most recent 144 blocks.
|
||||||
Put into place as a part of [HF-20171113](/protocol/forks/hf-20171113), it performs the following calculation to determine the difficulty of a block, <code>B<sub>n+1</sub></code>, with block height `n+1`:
|
Put into place as a part of [HF-20171113](/protocol/forks/hf-20171113), it performs the following calculation to determine the difficulty of a block, <code>B<sub>n+1</sub></code>, with block height `n+1`:
|
||||||
|
|
||||||
- Select <code>B<sub>new</sub></code>: The block with the median timestamp of the blocks <code>B<sub>n</sub></code>, <code>B<sub>n-1</sub></code>, and <code>B<sub>n-2</sub></code>
|
- Select <code>B<sub>new</sub></code>: The block with the median timestamp of the blocks <code>B<sub>n</sub></code>, <code>B<sub>n-1</sub></code>, and <code>B<sub>n-2</sub></code>
|
||||||
- Select <code>B<sub>old</sub></code>: The block with the median timestamp of the blocks <code>B<sub>n-144</sub></code>, <code>B<sub>n-145</sub></code>, and <code>B<sub>n-146</sub></code>.
|
- Select <code>B<sub>old</sub></code>: The block with the median timestamp of the blocks <code>B<sub>n-144</sub></code>, <code>B<sub>n-145</sub></code>, and <code>B<sub>n-146</sub></code>.
|
||||||
- Calculate `t`, the difference between the timestamps of <code>B<sub>new</sub></code> and <code>B<sub>old</sub></code>. If this difference is less than `72 * 600`, use `72 * 600`, if it is above `288 * 600`, use `288 * 600`.
|
- Calculate `t`, the difference between the timestamps of <code>B<sub>new</sub></code> and <code>B<sub>old</sub></code>. If this difference is less than `72 * 600`, use `72 * 600`, if it is above `288 * 600`, use `288 * 600`.
|
||||||
- Calculate `W`, the difference in [chainwork](/protocol/blockchain/proof-of-work#chainwork) between <code>B<sub>new</sub></code> and <code>B<sub>old</sub></code>.
|
- Calculate `W`, the difference in chainwork between <code>B<sub>new</sub></code> and <code>B<sub>old</sub></code>.
|
||||||
- Calculate `PW`, the projected work for the next block, as `(W * 600) / t`.
|
- Calculate `PW`, the projected work for the next block, as `(W * 600) / t`.
|
||||||
- Calculate `T`, the target difficulty, as <code>(2<sup>256</sup> - PW) / PW</code>. In 256-bit two's-complement arithmetic, this is equivalent to `(-PW) / PW`.
|
- Calculate `T`, the target difficulty, as <code>(2<sup>256</sup> - PW) / PW</code>. In 256-bit two's-complement arithmetic, this is equivalent to `(-PW) / PW`.
|
||||||
- If `T` is greater than the maximum target of `0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF`, use the maximum target. Otherwise, use `T`.
|
- If `T` is greater than the maximum target of `0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF`, use the maximum target. Otherwise, use `T`.
|
||||||
|
|
||||||
In other words, for any given block the projected work is be equal to the difference in chainwork multiplied by an adjustment. The adjustment is 600 seconds (the goal timeframe for a block to be mined) divided by the difference in timestamps between the median block (by timestamp) of its prior three immediate ancestors and its 144th, 145th, and 146th ancestors (bounded by `72 * 600` and `288 * 600`). The projected work is then converted into the target by subtracting it from 2<sup>256</sup> and then dividing the result by the projected work. Then minimum of that calculated value and the maximum target is then used as the target for that block.
|
In other words, for any given block the projected work is be equal to the difference in chainwork multiplied by an adjustment. The adjustment is 600 seconds (the goal timeframe for a block to be mined) divided by the difference in timestamps between the median block (by timestamp) of its prior three immediate ancestors and its 144th, 145th, and 146th ancestors (bounded by `72 * 600` and `288 * 600`). The projected work is then converted into the target by subtracting it from 2<sup>256</sup> and then dividing the result by the projected work. Then minimum of that calculated value and the maximum target is then used as the target for that block.
|
||||||
|
|
||||||
## Legacy Difficulty Adjustment Algorithm
|
## Emergency DAA
|
||||||
|
|
||||||
|
As a part of [BCH-UAHF](/protocol/forks/bch-uahf), due to the anticipated decrease in hashing power, the following adjustment to the legacy difficulty adjustment algorithm above was put into place:
|
||||||
|
|
||||||
|
>In case the MTP of the tip of the chain is 12h or more after the MTP 6 block before the tip, the proof of work target is increased by a quarter, or 25%, which corresponds to a difficulty reduction of 20% .
|
||||||
|
>
|
||||||
|
> RATIONALE: The hashrate supporting the chain is dependent on market price and hard to predict. In order to make sure the chain remains viable no matter what difficulty needs to adjust down in case of abrupt hashrate drop.
|
||||||
|
|
||||||
|
That is, if the block height is not divisible by 2016, the target may still be adjusted if the current MTP is more than 12 hours after the MTP from 6 blocks prior. In this case, the target is multiplied by 1.25.
|
||||||
|
|
||||||
|
This algorithm was superseded by the current difficulty adjustment algorithm as a part of HF-20171113.
|
||||||
|
|
||||||
|
## Legacy DAA
|
||||||
|
|
||||||
Prior to [BCH-UAHF](/protocol/forks/bch-uahf), the original Bitcoin difficulty adjustment algorithm was used.
|
Prior to [BCH-UAHF](/protocol/forks/bch-uahf), the original Bitcoin difficulty adjustment algorithm was used.
|
||||||
To determine the difficulty of a block, <code>B<sub>n+1</sub></code>, with block height `n+1`:
|
To determine the difficulty of a block, <code>B<sub>n+1</sub></code>, with block height `n+1`:
|
||||||
@@ -30,15 +91,3 @@ To determine the difficulty of a block, <code>B<sub>n+1</sub></code>, with block
|
|||||||
- If `T` is greater than the maximum target of `0x00000000FFFF0000000000000000000000000000000000000000000000000000`, use the maximum target instead. Otherwise, use `T`.
|
- If `T` is greater than the maximum target of `0x00000000FFFF0000000000000000000000000000000000000000000000000000`, use the maximum target instead. Otherwise, use `T`.
|
||||||
|
|
||||||
This boils down to a possible change in difficulty every 2016 blocks, where the new target (for the next 2016 blocks) is calculated by dividing the time taken for the last 2015 blocks by the time expectation for 2016 blocks (bounded by 0.25 and 4) and multiplying that ratio by the existing target.
|
This boils down to a possible change in difficulty every 2016 blocks, where the new target (for the next 2016 blocks) is calculated by dividing the time taken for the last 2015 blocks by the time expectation for 2016 blocks (bounded by 0.25 and 4) and multiplying that ratio by the existing target.
|
||||||
|
|
||||||
## Emergency Difficulty Adjustment Algorithm
|
|
||||||
|
|
||||||
As a part of BCH-UAHF, due to the anticipated decrease in hashing power, the following adjustment to the legacy difficulty adjustment algorithm above was put into place:
|
|
||||||
|
|
||||||
>In case the MTP of the tip of the chain is 12h or more after the MTP 6 block before the tip, the proof of work target is increased by a quarter, or 25%, which corresponds to a difficulty reduction of 20% .
|
|
||||||
>
|
|
||||||
> RATIONALE: The hashrate supporting the chain is dependent on market price and hard to predict. In order to make sure the chain remains viable no matter what difficulty needs to adjust down in case of abrupt hashrate drop.
|
|
||||||
|
|
||||||
That is, if the block height is not divisible by 2016, the target may still be adjusted if the current MTP is more than 12 hours after the MTP from 6 blocks prior. In this case, the target is multiplied by 1.25.
|
|
||||||
|
|
||||||
This algorithm was superseded by the current difficulty adjustment algorithm as a part of HF-20171113.
|
|
||||||
@@ -41,11 +41,14 @@ In general, though, this combined unlocking/locking script is then executed and
|
|||||||
Additionally, in order for the combined script to be valid, the following must be true:
|
Additionally, in order for the combined script to be valid, the following must be true:
|
||||||
|
|
||||||
- **Non-Empty Scripts** - both the locking and unlocking scripts must be non-empty.
|
- **Non-Empty Scripts** - both the locking and unlocking scripts must be non-empty.
|
||||||
- **Max Script Length** - the locking and unlocking script must each be less than the max script length of 10,000 bytes (for a combined script maximum of 20,000 bytes).
|
- **Max Script Length** - the locking and unlocking script, when executed, must each be less than the max script length of 10,000 bytes (for a combined script maximum of 20,000 bytes).
|
||||||
- **Contained Control Flow** - an IF/ELSE block cannot start in the unlocking script and end in the locking script, the script must be in the top-level scope when the locking script execution begins.
|
- **Contained Control Flow** - an IF/ELSE block cannot start in the unlocking script and end in the locking script, the script must be in the top-level scope when the locking script execution begins.
|
||||||
- **Permitted Operations Only** - the locking script must not include operations that are disallowed and must not execute operations that are disabled..
|
- **Permitted Operations Only** - the locking script must not include operations that are disallowed and must not execute operations that are disabled..
|
||||||
- **Push Only** - the unlocking script must contain only push operations (i.e. those with op codes 0x60 or less). Added in [HF-20181115](/protocol/forks/hf-20181115).
|
- **Push Only** - the unlocking script must contain only push operations (i.e. those with op codes 0x60 or less). Added in [HF-20181115](/protocol/forks/hf-20181115).
|
||||||
|
|
||||||
|
NOTE: violations of the above rules does not necessarily make a transaction invalid.
|
||||||
|
For example, a locking script may be longer than 10,000 bytes, but it would be unspendable, since the max script length is only checked when the scripts are combined before execution.
|
||||||
|
|
||||||
## Operation codes (opcodes)
|
## Operation codes (opcodes)
|
||||||
|
|
||||||
The table below lists the currently allocated op codes. Op codes marked with **(ignored)** are permitted but will do nothing when executed.
|
The table below lists the currently allocated op codes. Op codes marked with **(ignored)** are permitted but will do nothing when executed.
|
||||||
@@ -125,6 +128,8 @@ Op codes marked with **(do not use)** are disallowed and will make a transaction
|
|||||||
|
|
||||||
### Arithmetic
|
### Arithmetic
|
||||||
|
|
||||||
|
Numeric opcodes (OP_1ADD, etc) are restricted to operating on 4-byte integers. The semantics are subtle, though: operands must be in the range [-2^31 +1...2^31 -1], but results may overflow (and are valid as long as they are not used in a subsequent numeric operation).
|
||||||
|
|
||||||
|Word |Value |Hex |Input |Output | Description |
|
|Word |Value |Hex |Input |Output | Description |
|
||||||
|---------------------|-------|----|--------------|-----------------|------------------------------------------------------|
|
|---------------------|-------|----|--------------|-----------------|------------------------------------------------------|
|
||||||
|OP_1ADD | 139 |0x8b|in |out | 1 is added to the input. |
|
|OP_1ADD | 139 |0x8b|in |out | 1 is added to the input. |
|
||||||
@@ -138,8 +143,8 @@ Op codes marked with **(do not use)** are disallowed and will make a transaction
|
|||||||
|OP_ADD | 147 |0x93|a b |out | *a* is added to *b*. |
|
|OP_ADD | 147 |0x93|a b |out | *a* is added to *b*. |
|
||||||
|OP_SUB | 148 |0x94|a b |out | *b* is subtracted from *a*. |
|
|OP_SUB | 148 |0x94|a b |out | *b* is subtracted from *a*. |
|
||||||
|OP_MUL | 149 |0x95|a b |out | *a* is multiplied by *b*. **DISABLED** |
|
|OP_MUL | 149 |0x95|a b |out | *a* is multiplied by *b*. **DISABLED** |
|
||||||
|OP_DIV | 150 |0x96|a b |out | *a* is divided by *b*. |
|
|OP_DIV | 150 |0x96|a b |out | *a* is [divided](/protocol/blockchain/script/integer-division) by *b*. |
|
||||||
|OP_MOD | 151 |0x97|a b |out | Returns the remainder after *a* is divided by *b*. |
|
|OP_MOD | 151 |0x97|a b |out | Returns the remainder after *a* is [divided](/protocol/blockchain/script/integer-division) by *b*. |
|
||||||
|OP_LSHIFT | 152 |0x98|a b |out | Shifts *a* left *b* bits, preserving sign. **DISABLED** |
|
|OP_LSHIFT | 152 |0x98|a b |out | Shifts *a* left *b* bits, preserving sign. **DISABLED** |
|
||||||
|OP_RSHIFT | 153 |0x99|a b |out | Shifts *a* right *b* bits, preserving sign. **DISABLED** |
|
|OP_RSHIFT | 153 |0x99|a b |out | Shifts *a* right *b* bits, preserving sign. **DISABLED** |
|
||||||
|OP_BOOLAND | 154 |0x9a|a b |true / false | If both *a* and *b* are not 0, the output is 1. Otherwise 0. |
|
|OP_BOOLAND | 154 |0x9a|a b |true / false | If both *a* and *b* are not 0, the output is 1. Otherwise 0. |
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# Script Integer Division
|
||||||
|
|
||||||
|
The Bitcoin Script [OP_DIV](/protocol/blockchain/script#arithmetic) and [OP_MOD](/protocol/blockchain/script#arithmetic) operations are performed on script numbers, which are signed integers.
|
||||||
|
However, there are multiple valid approaches to signed integer division, particularly with respect to how negative values are handled, so this must be disambiguated.
|
||||||
|
|
||||||
|
The above operations follow [C](https://en.wikipedia.org/wiki/C_(programming_language))-style integer division semantics.
|
||||||
|
For a given `numerator` and `denominator`, if `OP_DIV` returns `quotient` and `OP_MOD` returns `remainder`, the following relation be true: `numerator = quotient * denominator + remainder`.
|
||||||
|
This allows for both negative quotients and remainders.
|
||||||
|
|
||||||
|
The following examples may provide clarity:
|
||||||
|
|
||||||
|
OP_DIV 5 2 -> 2
|
||||||
|
OP_MOD 5 2 -> 1
|
||||||
|
OP_DIV -5 2 -> -2
|
||||||
|
OP_MOD -5 2 -> -1
|
||||||
|
OP_DIV 5 -2 -> -2
|
||||||
|
OP_MOD 5 -2 -> 1
|
||||||
|
OP DIV -5 -2 -> 2
|
||||||
|
OP_MOD -5 -2 -> -1
|
||||||
@@ -1,8 +1,13 @@
|
|||||||
# Block-Level Validation Rules
|
# Block-Level Validation Rules
|
||||||
|
|
||||||
|
Block-level validation rules, also referred to as consensus rules, define what is permitted to be included in a block.
|
||||||
|
Block-level validation rules are absolute and any block or transaction that would cause a violation such a rule must be rejected.
|
||||||
|
These differ from [network-level validation rules](/protocol/blockchain/transaction-validation/network-level-validation-rules), also referred to as standardness rules, which can be circumvented by miners, should they wish to include a non-standard transaction in a block.
|
||||||
|
In short, consensus (block-level) rules define what is permitted in a block, while standardness (network-level) rules define recommended behavior for nodes on the network.
|
||||||
|
|
||||||
When validating a transaction, it must be done within the context of a block. That may be a historical (or new) block that the transaction is a part of or it may be as a part of a hypothetical "next" block. The latter category, often referred to as "mempool" transactions, represent transactions that a node is aware of, and considers valid, but that have not yet been added to a block. In this case, they are treated as though they are all in a new block that follows after the last block in the longest chain the node is currently aware of.
|
When validating a transaction, it must be done within the context of a block. That may be a historical (or new) block that the transaction is a part of or it may be as a part of a hypothetical "next" block. The latter category, often referred to as "mempool" transactions, represent transactions that a node is aware of, and considers valid, but that have not yet been added to a block. In this case, they are treated as though they are all in a new block that follows after the last block in the longest chain the node is currently aware of.
|
||||||
|
|
||||||
The reason that transaction validation is context-dependent in this way stems from what is probably the most important validation rule: the inputs to a transaction must be a UTXO. That is, transactions must spend transaction outputs that were created by a prior transaction but that have not been spent by another transaction in the target block or its history. Note that this means that blocks with divergent histories will treat different transactions as valid. For example, consider the following scenario:
|
The reason that transaction validation is context-dependent in this way stems from what is probably the most important validation rule: the inputs to a transaction must be UTXOs. That is, transactions must spend transaction outputs that were created by a prior transaction but that have not been spent by another transaction in the target block or its history. Note that this means that blocks with divergent histories will treat different transactions as valid. For example, consider the following scenario:
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
graph LR;
|
graph LR;
|
||||||
@@ -15,13 +20,39 @@ blockb --> blockb2(Block B')
|
|||||||
|
|
||||||
Since `Block A'` and `Block B'` are at the same block height, there may be some nodes that treat `Block A'` as the most recent block (e.g. `Node A`) and others that treat `Block B'` as the most recent block (e.g. `Node B`). If a transaction is submitted to both `Node A` and `Node B` that spends an output created in a transaction in `Block A`, `Node A` may consider the transaction valid while `Node B` would reject it on the grounds that it is dependent on a UTXO that is not a part of `Block B'`'s history, which only contains `Block B'`, `Block B`, and `Block N` (and its parents).
|
Since `Block A'` and `Block B'` are at the same block height, there may be some nodes that treat `Block A'` as the most recent block (e.g. `Node A`) and others that treat `Block B'` as the most recent block (e.g. `Node B`). If a transaction is submitted to both `Node A` and `Node B` that spends an output created in a transaction in `Block A`, `Node A` may consider the transaction valid while `Node B` would reject it on the grounds that it is dependent on a UTXO that is not a part of `Block B'`'s history, which only contains `Block B'`, `Block B`, and `Block N` (and its parents).
|
||||||
|
|
||||||
Other block-level validation rules include:
|
## Consensus Rules
|
||||||
|
|
||||||
|
- Double-Spend Validation
|
||||||
|
- The inputs of a transaction may only be spent once on a given blockchain fork.
|
||||||
|
- That is, if two transactions spend a given input, only one may be valid at any given time.
|
||||||
|
- See [blockchain reorganization](/protocol/blockchain#blockchain-reorganization) for information on how resolution of such conflicts is resolved.
|
||||||
|
- Transaction Input and Output Validation
|
||||||
|
- The total value of the outputs of a transaction may not exceed the total input value of the transaction, except in the case of [coinbase transactions](/protocol/blockchain/block#coinbase-transaction).
|
||||||
- Coinbase Transaction Reward Validation
|
- Coinbase Transaction Reward Validation
|
||||||
- The coinbase transaction in a block must collect the correct reward for the block height. For more information see [Coinbase Transaction](/protocol/blockchain/block#coinbase-transaction).
|
- The coinbase transaction in a block must collect the correct reward for the block height. For more information see [Coinbase Transaction](/protocol/blockchain/block#coinbase-transaction).
|
||||||
- Transaction Chaining Limit
|
- Coinbase Maturity
|
||||||
- Many nodes impose a limit of transactions that can be chained together in a single block. That is, if transaction Z spends an output of transaction Y, which spends an input of transaction X, and so on to Transaction A, the transaction may be rejected.
|
- Outputs of coinbase transactions may not be spent for 100 blocks.
|
||||||
- This limit is often set to 25 chained transactions.
|
- That is, the block reward from block 1,000 may not be spent until block 1,100.
|
||||||
- Coinbase Transaction Block Height
|
- Coinbase Transaction Block Height
|
||||||
- The coinbase transaction in a block must provide an unlocking script that that starts with a push operation which pushes the block height of the block it is contained in.
|
- The coinbase transaction in a block must provide an unlocking script that that starts with a push operation which pushes the block height of the block it is contained in.
|
||||||
- This requirement was added in [BIP-34](/protocol/forks/bip-0034) to ensure that coinbase transactions are unique.
|
- This requirement was added in [BIP-34](/protocol/forks/bip-0034) to ensure that coinbase transactions are unique.
|
||||||
|
- Signature Check Counting
|
||||||
|
- The number of signature checks in a transaction may not exceed 3,000.
|
||||||
|
- The number of signature checks in a block may not exceed the max block size divided by 141 (currently this is 226,950).
|
||||||
|
- For details on how signature checks are counted, see [SigChecks](#sigchecks)
|
||||||
|
- Transaction
|
||||||
|
|
||||||
|
### SigChecks
|
||||||
|
|
||||||
|
SigChecks was implemented as a part of [HF-20200515](/protocol/forks/hf-20200515) and replaced the existing system of signature operation counting (SigOps).
|
||||||
|
During script execution, signature checks are counted using the following rules:
|
||||||
|
|
||||||
|
- Executing OP_CHECKSIG / OP_CHECKSIGVERIFY / OP_CHECKDATASIG / OP_CHECKDATASIGVERIFY increments SigChecks by:
|
||||||
|
- +0, if signature is NULL.
|
||||||
|
- +1, if signature is non-NULL.
|
||||||
|
- Executing an M-of-N OP_CHECKMULTISIG / OP_CHECKMULTISIGVERIFY increments SigChecks by:
|
||||||
|
- +0, if all M signatures are NULL.
|
||||||
|
- +M, if at least one signature is non-NULL and the verification is in [New/Schnorr mode](/protocol/forks/2019-11-15-schnorrmultisig) (dummy element is non-NULL).
|
||||||
|
- +N, if at least one signature is non-NULL and the verification is in Old/ECDSA mode (dummy element is NULL).
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -14,11 +14,10 @@ Standard transactions are those that:
|
|||||||
- Have a version 1 or [version 2](/protocol/forks/bip-0068/)
|
- Have a version 1 or [version 2](/protocol/forks/bip-0068/)
|
||||||
- Have input scripts that only contain push operations
|
- Have input scripts that only contain push operations
|
||||||
- Have input scripts with unlocking scripts less or equal to 1650 bytes in length (see scriptSig limit below)
|
- Have input scripts with unlocking scripts less or equal to 1650 bytes in length (see scriptSig limit below)
|
||||||
- Have at most one [data output](/protocol/blockchain/transaction/locking-script#data-output), with a script no longer than 223 bytes (see [data output size limit](#data-output-size-limit) below)
|
- Have the total size of [data output](/protocol/blockchain/transaction/locking-script#data-output) locking scripts no larger than 223 bytes (see [data output size limit](#data-output-size-limit) below)
|
||||||
- For [multisig](/protocol/blockchain/transaction/locking-script#multisig) outputs, must have at most 3 parties and at least 1 required party (i.e. 1-of-1 through 3-of-3).
|
- For [multisig](/protocol/blockchain/transaction/locking-script#multisig) outputs, must have at most 3 parties and at least 1 required party (i.e. 1-of-1 through 3-of-3).
|
||||||
- Have non-data outputs with amount above the [dust](#dust) threshold
|
- Have non-data outputs with amount above the [dust](#dust) threshold
|
||||||
|
- Each input of the transaction, must require no more than `((scriptLength + 60) / 43)` [SigChecks](/protocol/blockchain/transaction-validation/block-level-validation-rules#sigchecks)
|
||||||
\* 223 bytes was chosen to allow for the `OP_RETURN` operation (1 byte), a push operations (2 bytes), and 220 bytes of pushed data.
|
|
||||||
|
|
||||||
Be aware, however, that these rules may vary from node-to-node as they are often configurable.
|
Be aware, however, that these rules may vary from node-to-node as they are often configurable.
|
||||||
Some nodes may also accept and relay non-standard transactions.
|
Some nodes may also accept and relay non-standard transactions.
|
||||||
@@ -44,6 +43,10 @@ The data output size limit is calculated as follows:
|
|||||||
* 2 bytes for a push operation
|
* 2 bytes for a push operation
|
||||||
* Up to 220 bytes of data to be "pushed"
|
* Up to 220 bytes of data to be "pushed"
|
||||||
|
|
||||||
|
In [HF-20210515](/protocol/forks/hf-20210515) this size limit was kept the same but allowed to apply to any number of data outputs in the transaction, provided the total size of data output locking scripts does not exceed the limit.
|
||||||
|
For example, a transaction is now allowed to have three locking scripts that are each 74 bytes in length.
|
||||||
|
However, a transaction with two data outputs each with 112-byte locking scripts would be invalid as `112 * 2 = 224` exceeds the 223-byte limit.
|
||||||
|
|
||||||
## Dust
|
## Dust
|
||||||
|
|
||||||
In order to limit the propagation of transactions with limited utility, outputs that would be cost-prohibitive to spend are rejected as "dust."
|
In order to limit the propagation of transactions with limited utility, outputs that would be cost-prohibitive to spend are rejected as "dust."
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ Verification of a transaction ensures that:
|
|||||||
|
|
||||||
| Field | Length | Format | Description |
|
| Field | Length | Format | Description |
|
||||||
|--|--|--|--|
|
|--|--|--|--|
|
||||||
| version | 4 bytes | unsigned integer<sup>[(LE)](/protocol/misc/endian/little)</sup> | The version of the transaction format. Currently `0x02000000`. |
|
| version | 4 bytes | unsigned integer<sup>[(LE)](/protocol/misc/endian/little)</sup> | The version of the transaction format. Currently `0x02000000`.<br>For more details refer to the [transaction version history](/history/transaction-version). |
|
||||||
| input count | variable | [variable length integer](/protocol/formats/variable-length-integer) | The number of inputs in the transaction. |
|
| input count | variable | [variable length integer](/protocol/formats/variable-length-integer) | The number of inputs in the transaction. |
|
||||||
| transaction inputs | variable | `input_count` [transaction inputs](#transaction-input) | Each of the transaction's inputs serialized in order. |
|
| transaction inputs | variable | `input_count` [transaction inputs](#transaction-input) | Each of the transaction's inputs serialized in order. |
|
||||||
| output count | variable | [variable length integer](/protocol/formats/variable-length-integer) | The number of output in the transaction. |
|
| output count | variable | [variable length integer](/protocol/formats/variable-length-integer) | The number of output in the transaction. |
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ If the signature is valid for the specified public key in the locking script, th
|
|||||||
| Operation | Description |
|
| Operation | Description |
|
||||||
|--|--|
|
|--|--|
|
||||||
| [OP_DATA_X](/protocol/blockchain/script/op-codes/op-data-x) (public key) | Add the recipient's public key to the stack. The data pushed must be either a compressed or uncompressed public key with appropriate length (33 bytes if the key is compressed, 65 bytes if it is not) for the type for the script to be recognized as P2PK. |
|
| [OP_DATA_X](/protocol/blockchain/script/op-codes/op-data-x) (public key) | Add the recipient's public key to the stack. The data pushed must be either a compressed or uncompressed public key with appropriate length (33 bytes if the key is compressed, 65 bytes if it is not) for the type for the script to be recognized as P2PK. |
|
||||||
| [OP_CHECKSIG](/protocol/blockchain/script/opcodes/op-checksig) | Check the public key at the top of the stack against the signature below it on the stack. |
|
| [OP_CHECKSIG](/protocol/blockchain/script#cryptography) | Check the public key at the top of the stack against the signature below it on the stack. |
|
||||||
|
|
||||||
<img src="/_static_/images/warning.png" /> **NOTE:** Pay to Public Key is a largely obsolete type of locking script due to its property of leaking the public key of the recipient before the output is unlocked, resulting in:
|
<img src="/_static_/images/warning.png" /> **NOTE:** Pay to Public Key is a largely obsolete type of locking script due to its property of leaking the public key of the recipient before the output is unlocked, resulting in:
|
||||||
|
|
||||||
@@ -31,18 +31,18 @@ That is, if it ever becomes possible to create a signature using a public key (n
|
|||||||
|
|
||||||
### Pay to Public Key Hash (P2PKH)
|
### Pay to Public Key Hash (P2PKH)
|
||||||
|
|
||||||
Pay to Public Key Hash is a widely used standard locking script format, that works similarly to P2PK but instead of pushing the public key, it pushes a hash of the public key, commonly referred to as an address.
|
Pay to Public Key Hash is a widely used standard locking script format, that works similarly to P2PK but instead of pushing the public key, it pushes a hash of the public key, commonly referred to as an [address](/protocol/blockchain/addresses).
|
||||||
This heavily reduces the risks associated with a plain P2PK script as the hashing algorithms used provide a considerable barrier to determining the public key a priori.
|
This heavily reduces the risks associated with a plain P2PK script as the hashing algorithms used provide a considerable barrier to determining the public key a priori.
|
||||||
To spend an output locked with this type of script, the unlocking script is expected to push a signature and then the public key corresponding to the private key that created the signature.
|
To spend an output locked with this type of script, the unlocking script is expected to push a signature and then the public key corresponding to the private key that created the signature.
|
||||||
If that public key hashes to the expected address, and the signature is valid, the output is allowed to be spent.
|
If that public key hashes to the expected address, and the signature is valid, the output is allowed to be spent.
|
||||||
|
|
||||||
| Operation | Description |
|
| Operation | Description |
|
||||||
|--|--|
|
|--|--|
|
||||||
| [OP_DUP](/protocol/blockchain/script/opcodes/op-dup) | Copy the value at the top of the stack (public key of the recipient). |
|
| [OP_DUP](/protocol/blockchain/script#stack) | Copy the value at the top of the stack (public key of the recipient). |
|
||||||
| [OP_HASH160](/protocol/blockchain/script/opcodes/op-hash160) | Perform a SHA-256 then a RIPEMD-160 on the copied value. |
|
| [OP_HASH160](/protocol/blockchain/script#cryptography) | Perform a SHA-256 then a RIPEMD-160 on the copied value. |
|
||||||
| [OP_DATA_X](/protocol/blockchain/script/op-codes/op-data-x) (20 bytes) | Push the expected 20 byte address. |
|
| [OP_DATA_X](/protocol/blockchain/script/op-codes/op-data-x) (20 bytes) | Push the expected 20 byte address. |
|
||||||
| [OP_EQUALVERIFY](/protocol/blockchain/script/opcodes/op-equalverify) | Verify that the hash of the copied value matches the expected hash that was pushed. |
|
| [OP_EQUALVERIFY](/protocol/blockchain/script#bitwise) | Verify that the hash of the copied value matches the expected hash that was pushed. |
|
||||||
| [OP_CHECKSIG](/protocol/blockchain/script/opcodes/op-checksig) | Verify that the stack now contains only a public key (which was duplicated, hashed, and checked against the expected value) and a signature and verify that the signature is valid for that public key. |
|
| [OP_CHECKSIG](/protocol/blockchain/script#cryptography) | Verify that the stack now contains only a public key (which was duplicated, hashed, and checked against the expected value) and a signature and verify that the signature is valid for that public key. |
|
||||||
|
|
||||||
### Pay to Script Hash (P2SH)
|
### Pay to Script Hash (P2SH)
|
||||||
|
|
||||||
@@ -53,9 +53,9 @@ If this redeem script finishes execution successfully, the output is allowed to
|
|||||||
|
|
||||||
| Operation | Description |
|
| Operation | Description |
|
||||||
|--|--|
|
|--|--|
|
||||||
| [OP_HASH160](/protocol/blockchain/script/opcodes/op-hash160) | Hash the data at the top of the stack, this should be the script to be executed. |
|
| [OP_HASH160](/protocol/blockchain/script#cryptography) | Hash the data at the top of the stack, this should be the script to be executed. |
|
||||||
| [OP_DATA_X](/protocol/blockchain/script/op-codes/op-data-x) (20 bytes) | Push the expected redeem script hash. |
|
| [OP_DATA_X](/protocol/blockchain/script/op-codes/op-data-x) (20 bytes) | Push the expected redeem script hash. |
|
||||||
| [OP_EQUAL](/protocol/blockchain/script/opcodes/op-equal) | Verify that the hash of the provided script is equal to the expected hash. |
|
| [OP_EQUAL](/protocol/blockchain/script#bitwise) | Verify that the hash of the provided script is equal to the expected hash. |
|
||||||
|
|
||||||
Due to the nature of this type of locking script, the following steps must be performed by a node executing this script:
|
Due to the nature of this type of locking script, the following steps must be performed by a node executing this script:
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ One drawback of this is that it is not possible to determine whether certain ins
|
|||||||
This makes retirement of opcodes impossible.
|
This makes retirement of opcodes impossible.
|
||||||
However, it's also possible for people to create transactions and not commit them to the blockchain, so the viability of opcode retirement is questionable anyway.
|
However, it's also possible for people to create transactions and not commit them to the blockchain, so the viability of opcode retirement is questionable anyway.
|
||||||
|
|
||||||
### Multisig
|
### Multisig (P2MS)
|
||||||
|
|
||||||
Multiple-signature, or multisig, scripts provide a mechanism to have multiple private keys coordinate with spending funds.
|
Multiple-signature, or multisig, scripts provide a mechanism to have multiple private keys coordinate with spending funds.
|
||||||
For example, three people could share funds and require that for some transactions any one of them could spend it while, for others, two of them would need to agree, and for others still, all three people would need to agree to spend the funds.
|
For example, three people could share funds and require that for some transactions any one of them could spend it while, for others, two of them would need to agree, and for others still, all three people would need to agree to spend the funds.
|
||||||
@@ -92,12 +92,14 @@ Each party's public key is included in the locking script along with the require
|
|||||||
|
|
||||||
An unlocking script is therefore expected to provide the required number of signatures which are then checked against the list of public keys. If a sufficient number of valid signatures are provided, the output is allowed to be spent.
|
An unlocking script is therefore expected to provide the required number of signatures which are then checked against the list of public keys. If a sufficient number of valid signatures are provided, the output is allowed to be spent.
|
||||||
|
|
||||||
|
These are also referred to as "bare multisig" scripts to disambiguate them from P2SH multisig scripts (see [Multisignature](/protocol/blockchain/cryptography/multisignature)).
|
||||||
|
|
||||||
| Operation | Description |
|
| Operation | Description |
|
||||||
|--|--|
|
|--|--|
|
||||||
| [OP_X](/protocol/blockchain/script/op-codes/op-x) | Push the number of parties required to provide signatures. |
|
| [OP_X](/protocol/blockchain/script/op-codes/op-x) | Push the number of parties required to provide signatures. |
|
||||||
| 1 or more [OP_DATA_X](/protocol/blockchain/script/op-codes/op-data-x) (public key) | Push 1 or more public keys, indicating all of the parties that could provide signatures. |
|
| 1 or more [OP_DATA_X](/protocol/blockchain/script/op-codes/op-data-x) (public key) | Push 1 or more public keys, indicating all of the parties that could provide signatures. |
|
||||||
| [OP_X](/protocol/blockchain/script/op-codes/op-x) | The total number of parties added (i.e. the number of public keys pushed). |
|
| [OP_X](/protocol/blockchain/script/op-codes/op-x) | The total number of parties added (i.e. the number of public keys pushed). |
|
||||||
| [OP_CHECKMULTISIG](/protocol/blockchain/script/op-codes/op-checkmultisig) | Check for signatures matching the number of required parties, verify that they correspond to permitted public keys, and that the signatures are valid. |
|
| [OP_CHECKMULTISIG](/protocol/blockchain/script#cryptography) | Check for signatures matching the number of required parties, verify that they correspond to permitted public keys, and that the signatures are valid. |
|
||||||
|
|
||||||
NOTE: due to a historical bug, the locking script must push an additional value before the signatures. Traditionally this is done via [OP_0](/protocol/blockchain/script/op-codes/op-x). The value is not used but is popped off of the stack by the OP_CHECKMULTISIG at the end of the locking script.
|
NOTE: due to a historical bug, the locking script must push an additional value before the signatures. Traditionally this is done via [OP_0](/protocol/blockchain/script/op-codes/op-x). The value is not used but is popped off of the stack by the OP_CHECKMULTISIG at the end of the locking script.
|
||||||
|
|
||||||
@@ -109,5 +111,5 @@ As such, outputs locked with data scripts generally have zero satoshis associate
|
|||||||
|
|
||||||
| Operation | Description |
|
| Operation | Description |
|
||||||
|--|--|
|
|--|--|
|
||||||
| [OP_RETURN](/protocol/blockchain/script/opcodes/op-return) | Fail execution immediately. |
|
| [OP_RETURN](/protocol/blockchain/script#flow-control) | Fail execution immediately. |
|
||||||
| Data | Any additional data is not executed and thus can be whatever data is desired by the script creator. |
|
| Data Pushes | Data may optionally be added as a series of push operations. However, these push operations are not executed and thus can push whatever arbitrary data is desired by the script creator. |
|
||||||
|
|||||||
@@ -52,15 +52,30 @@ Combining these, there are 6 valid signature hash types in Bitcoin Cash. Only t
|
|||||||
|
|
||||||
## Bitcoin Cash Signatures
|
## Bitcoin Cash Signatures
|
||||||
|
|
||||||
In Bitcoin Cash, transaction signatures use the transaction digest algorithm described in [BIP143](https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki), in order to minimize redundant data hashing in verification and to cover the input value by the signature.
|
In Bitcoin Cash, transaction signatures use the transaction digest algorithm described in a modification of [BIP143](/protocol/forks/replay-protected-sighash), in order to minimize redundant data hashing in verification and to cover the input value by the signature.
|
||||||
|
|
||||||
### Preimage Format
|
### Preimage Format
|
||||||
|
|
||||||
|
At a high level, the preimage format for a signature within a single input is a serialization of the following transaction components, **many of which are hashed, modified, or substituted** depending on the context:
|
||||||
|
|
||||||
|
1. Transaction version
|
||||||
|
2. Previous transaction outputs identifiers
|
||||||
|
3. Transaction input sequence numbers
|
||||||
|
4. The identifier of the output being spent
|
||||||
|
5. The locking script of the output being spent
|
||||||
|
6. The value of the output being spent
|
||||||
|
7. The sequence number of the transaction input
|
||||||
|
8. The created transaction outputs
|
||||||
|
9. Transaction locktime
|
||||||
|
10. The signature hash type
|
||||||
|
|
||||||
|
The following table specifies, in detail, the preimage format for a signature within a single input:
|
||||||
|
|
||||||
| Field | Length | Format | Description |
|
| Field | Length | Format | Description |
|
||||||
|--|--|--|--|
|
|--|--|--|--|
|
||||||
| transaction version | 4 bytes | unsigned integer<sup>[(LE)](/protocol/misc/endian/little)</sup> | The value of transaction's version field. |
|
| transaction version | 4 bytes | unsigned integer<sup>[(LE)](/protocol/misc/endian/little)</sup> | The value of transaction's version field. |
|
||||||
| previous outputs hash | 32 bytes | hash<sup>[(BE)](/protocol/misc/endian/big)</sup> | A double SHA-256 hash of the set of previous outputs spent by the inputs of the transaction. See [Previous Outputs](#previous-outputs-hash) for the hash preimage format.<br/><br/>If hash type is "ANYONE CAN PAY" then this is all `0x00` bytes. |
|
| previous outputs hash | 32 bytes | hash<sup>[(BE)](/protocol/misc/endian/big)</sup> | A double SHA-256 hash of the set of previous outputs spent by the inputs of the transaction. See [Previous Outputs](#previous-outputs-hash) for the hash preimage format.<br/><br/>If hash type is "ANYONECANPAY" then this is all `0x00` bytes. |
|
||||||
| sequence numbers hash | 32 bytes | hash<sup>[(BE)](/protocol/misc/endian/big)</sup> | A double SHA-256 hash of the set of sequence numbers of the inputs of the transaction. See [Sequence Numbers](#sequence-numbers-hash) for the hash preimage format.<br/><br/>If hash type is "ANYONE CAN PAY" then this is all `0x00` bytes. |
|
| sequence numbers hash | 32 bytes | hash<sup>[(BE)](/protocol/misc/endian/big)</sup> | A double SHA-256 hash of the set of sequence numbers of the inputs of the transaction. See [Sequence Numbers](#sequence-numbers-hash) for the hash preimage format.<br/><br/>If hash type is "ANYONECANPAY", "SINGLE", or "NONE" then this is all `0x00` bytes. |
|
||||||
| previous output hash | 32 bytes | hash<sup>[(LE)](/protocol/misc/endian/little)</sup> | The transaction ID of the previous output being spent. |
|
| previous output hash | 32 bytes | hash<sup>[(LE)](/protocol/misc/endian/little)</sup> | The transaction ID of the previous output being spent. |
|
||||||
| previous output index | 4 bytes | unsigned integer<sup>[(LE)](/protocol/misc/endian/little)</sup> | The index of the output to be spent. |
|
| previous output index | 4 bytes | unsigned integer<sup>[(LE)](/protocol/misc/endian/little)</sup> | The index of the output to be spent. |
|
||||||
| modified locking script length | variable | [variable length integer](/protocol/format/variable-length-integer) | The number of bytes for `modified_locking_script`. |
|
| modified locking script length | variable | [variable length integer](/protocol/format/variable-length-integer) | The number of bytes for `modified_locking_script`. |
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
# 2019-MAY-15 Schnorr Signature specification
|
# 2019-MAY-15 Schnorr Signature specification
|
||||||
|
|
||||||
layout: specification
|
layout: specification
|
||||||
title: 2019-MAY-15 Schnorr Signature specification
|
title: 2019-MAY-15 Schnorr Signature specification
|
||||||
date: 2019-02-15
|
date: 2019-02-15
|
||||||
category: spec
|
category: spec
|
||||||
activation: 1557921600
|
activation: 1557921600
|
||||||
version: 0.5
|
version: 0.5
|
||||||
author: Mark B. Lundeberg
|
author: Mark B. Lundeberg
|
||||||
|
|
||||||
# Summary
|
# Summary
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ The other two ECDSA opcodes, `OP_CHECKMULTISIG` and `OP_CHECKMULTISIGVERIFY`, wi
|
|||||||
|
|
||||||
# Motivation
|
# Motivation
|
||||||
|
|
||||||
(for more detail, see Motivation and Applications sections of [Pieter Wuille's Schnorr specification](https://github.com/sipa/bips/blob/bip-schnorr/bip-schnorr.mediawiki))
|
(for more detail, see Motivation and Applications sections of [Pieter Wuille's Schnorr specification](/protocol/forks/schnorr/bip-schnorr-archive))
|
||||||
|
|
||||||
Schnorr signatures have some slightly improved properties over the ECDSA signatures currently used in bitcoin:
|
Schnorr signatures have some slightly improved properties over the ECDSA signatures currently used in bitcoin:
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ The formerly supported ECDSA hybrid keys (see [X9.62 §4.3.6](citeseerx.ist.psu.
|
|||||||
|
|
||||||
## Signature verification algorithm
|
## Signature verification algorithm
|
||||||
|
|
||||||
We follow essentially what is an older variant of Pieter Wuille's [BIP-Schnorr](https://github.com/sipa/bips/blob/bip-schnorr/bip-schnorr.mediawiki).
|
We follow essentially what is an older variant of Pieter Wuille's [BIP-Schnorr](/protocol/forks/schnorr/bip-schnorr-archive).
|
||||||
Notable design choices:
|
Notable design choices:
|
||||||
|
|
||||||
* Operates on secp256k1 curve.
|
* Operates on secp256k1 curve.
|
||||||
@@ -245,7 +245,7 @@ Curiously, however, aggregate signatures cannot be "second-party" malleated; pro
|
|||||||
|
|
||||||
The Bitcoin ABC implementation involved a number of Diffs: https://reviews.bitcoinabc.org/T527
|
The Bitcoin ABC implementation involved a number of Diffs: https://reviews.bitcoinabc.org/T527
|
||||||
|
|
||||||
Pieter Wuille's specification comes with a handy set of test vectors for checking cryptographic corner cases: https://github.com/sipa/bips/blob/bip-schnorr/bip-schnorr/test-vectors.csv
|
Pieter Wuille's specification comes with a handy set of test vectors for checking cryptographic corner cases: [test-vectors.csv](/protocol/forks/schnorr/bip-schnorr/test-vectors.csv)
|
||||||
|
|
||||||
# Acknowledgements
|
# Acknowledgements
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
# 2020-05-15 IFP
|
||||||
|
|
||||||
|
layout: specification
|
||||||
|
title: Infrastructure Funding Plan Specification
|
||||||
|
category: spec
|
||||||
|
date: 2020-04-10
|
||||||
|
activation: 1589544000
|
||||||
|
version: 0.1
|
||||||
|
author: Antony Zegers
|
||||||
|
|
||||||
|
## Infrastructure Funding Plan
|
||||||
|
|
||||||
|
The purpose of the Infrastructure Funding Plan (IFP) is to provide funding to development projects working on common Bitcoin Cash infrastructure. If activated, it enforces that 5% of the block reward is spent to one of a set of specified addresses.
|
||||||
|
|
||||||
|
## IFP Destination Addresses
|
||||||
|
|
||||||
|
The IFP contains four destination addresses, each associated with a separate BIP 9 activation `bit` as follows:
|
||||||
|
|
||||||
|
| Name | Destination Address | BIP 9 `bit` |
|
||||||
|
| ---------------------------- | ------------------------------------------ | ----------- |
|
||||||
|
| MinerFundDestination | pqv2r67sgz3qumufap3h2uuj0zfmnzuv8vqhqfgddk | 0 |
|
||||||
|
| MinerABCDestination | qzvz0es48sf8wrqy7kn5j5cugka95ztskcanc9laay | 1 |
|
||||||
|
| MinerBCHDDestination | qrhea03074073ff3zv9whh0nggxc7k03ssh8jv9mkx | 2 |
|
||||||
|
| MinerElectronCashDestination | pp8d685l8kecnmtyy52ndvq625arz2qwmu42qeeqek | 3 |
|
||||||
|
|
||||||
|
## Activation
|
||||||
|
|
||||||
|
Activation is triggered separately for each destination address via [BIP 9](https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki), with the following parameters:
|
||||||
|
* `activation threshold` is set to 1344 (which is ~66.6% of the 2016 block retarget periods)
|
||||||
|
* `starttime` is set to 1573819200 (Nov 15, 2019 12:00:00 UTC)
|
||||||
|
* `timeout` is set to 1589544000 (May 15, 2020 12:00:00 UTC ** note:** this is the same time as the May 15, 2020 upgrade activation)
|
||||||
|
* `bit` is set according to the table above.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
If activated, the IFP enforcement begins once the 15th May 2020 upgrade is activated.
|
||||||
|
|
||||||
|
If one or more IFP destination addresses are activated, then the coinbase transaction in each block must contain an output sending 5% of the block reward to one of the activated addresses.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
[1] [BIP 9](https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki)
|
||||||
|
|
||||||
|
[2] [Sample implementation](https://reviews.bitcoinabc.org/D5282)
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
# 2020-05-15 OP_REVERSEBYTES
|
||||||
|
|
||||||
|
layout: specification
|
||||||
|
title: OP_REVERSEBYTES Specification
|
||||||
|
category: spec
|
||||||
|
date: 2019-05-29
|
||||||
|
activation: 1589544000
|
||||||
|
version: 0.2
|
||||||
|
author: Tobias Ruck
|
||||||
|
|
||||||
|
## OP_REVERSEBYTES
|
||||||
|
|
||||||
|
OP_REVERSEBYTES reverses the bytes of the top stackitem.
|
||||||
|
|
||||||
|
### Rationale
|
||||||
|
|
||||||
|
Bitcoin's protocol almost exclusively uses little-endian encoding [[8]](#references), and Script provides various tools for using integers encoded in little endian, such as `OP_NUM2BIN` and `OP_BIN2NUM` [[11]](#references). Using covenants [[2]](#references), sophisticated smart contracts can be created, and Script already has a great arsenal of arithmetic operators (opcodes 139 to 165) to enforce e.g. how input and output amounts of transactions have to be related.
|
||||||
|
|
||||||
|
However, many protocols do not use little endian encoding, and it is by no means clear that one is superior to the other. Both AMQP [[12]](#references) and Apache Thrift [[13]](#references), for instance, use big-endian encoding. The Simple Ledger Protocol (SLP) uses big-endian encoding as well [[1]](#references). Bitdb, when using the `hN` elements, returns stack items in a format that can be directly interpreted as base16 big-endian encoded numbers, and to use this feature, it has to be possible to encode values as big-endian.
|
||||||
|
|
||||||
|
Further, now that oracles using OP_CHECKDATASIG are possible, likely used to retrieve numeric data, it would be unnecessarily limiting to assume all oracles will use little-endian encoding.
|
||||||
|
|
||||||
|
Among the mentioned protocols, SLP tokens are likely the most important ones. Various new use cases combining the power of covenants and looping transactions [[5]](#references) emerge, among them:
|
||||||
|
|
||||||
|
* Decentralized exchanges (such as SLP Agora or SLPDEX) [[3, 4, 6]](#references)
|
||||||
|
* Donation mintable tokens
|
||||||
|
* DAOs, which charge a fee for services and distribute revenue proportional to shares [[7]](#references)
|
||||||
|
* Native tokens (not yet possible)
|
||||||
|
|
||||||
|
Note that values can be converted to big-endian encoding if the size of the encoding is both fixed and not too large. Currently, Script only supports 32-bit integers, and they can be encoded in big-endian using OP_SPLIT, OP_SWAP and OP_CAT:
|
||||||
|
|
||||||
|
```
|
||||||
|
// initial: // <value>
|
||||||
|
// convert to little-endian
|
||||||
|
PUSH 4 // <value> 4
|
||||||
|
OP_NUM2BIN // <value 4-byte little endian>
|
||||||
|
|
||||||
|
// split into individual bytes
|
||||||
|
PUSH 1 // <value 4-byte little endian> 1
|
||||||
|
OP_SPLIT // <value 1st byte> <value 2nd-4th byte>
|
||||||
|
PUSH 1 // <value 1st byte> <value 2nd-4th byte> 1
|
||||||
|
OP_SPLIT // <value 1st byte> <value 2nd byte> <value 3rd-4th byte>
|
||||||
|
PUSH 1 // <value 1st byte> <value 2nd byte> <value 3rd-4th byte> 1
|
||||||
|
OP_SPLIT // <value 1st byte> <value 2nd byte> <value 3rd byte> <value 4th byte>
|
||||||
|
|
||||||
|
// reverse individual bytes and concat
|
||||||
|
// results in 4-byte big endian
|
||||||
|
OP_SWAP // <value 1st byte> <value 2nd byte> <value 4th byte> <value 3rd byte>
|
||||||
|
OP_CAT // <value 1st byte> <value 2nd byte> <value 4th, 3rd byte>
|
||||||
|
OP_SWAP // <value 1st byte> <value 4th, 3rd byte> <value 2nd byte>
|
||||||
|
OP_CAT // <value 1st byte> <value 4th, 3rd, 2nd byte>
|
||||||
|
OP_SWAP // <value 4th, 3rd, 2nd byte> <value 1st byte>
|
||||||
|
OP_CAT // <value 4-byte big endian>
|
||||||
|
```
|
||||||
|
|
||||||
|
However, if with OP_REVERSEBYTES, this becomes trivial:
|
||||||
|
|
||||||
|
```
|
||||||
|
// convert to bytes
|
||||||
|
PUSH 4 // <SLP value> 4
|
||||||
|
OP_NUM2BIN // <SLP value 4-byte little endian>
|
||||||
|
OP_REVERSEBYTES // <SLP value 4-byte big endian>
|
||||||
|
```
|
||||||
|
|
||||||
|
That's 11 bytes (9 operations and 3 pushdata) saved.
|
||||||
|
|
||||||
|
There are multiple reasons why the second version would be preferable:
|
||||||
|
|
||||||
|
* Covenants and looping scripts usually take the script code of the preimage [[9]](#references) as input, which means every operation counts twice: Once for the stack item containing the script code, and once for the P2SH script stack item [[10]](#references). For a conversion to 8-byte big-endian, this would save 32 bytes per conversion, and if there's, say, three of those conversions in a script, it would already amount to 96 bytes - a non-trivial number of bytes for a transaction.
|
||||||
|
* The cognitive load of developing scripts using the larger snippet above is increased unnecessarily. Developing scripts, by hand or by using tools such as macros or Spedn, already puts a lot of cognitive load on developers, and errors can be devastating to the community. A prominent example of such a failure is the contentious hard-fork on the Ethereum blockchain that was caused by a bug in The DAO smart contract.
|
||||||
|
* The first version assumes that Script uses 32-bit numbers, however, once integers with larger width are implemented, the script gets linearly longer (4 bytes/byte) with each additional byte. For 256-bit numbers, it would require a whopping 124 bytes (93 operations and 31 pushdata) to convert to big-endian. As the opcode limit currently is 201, that wouldn't leave much room for other operations. In contrast, `<N> OP_NUM2BIN OP_REVERSEBYTES` always encodes integers as N-byte big-endian number, with a constant script size independent of N.
|
||||||
|
|
||||||
|
Also, suppose an oracle returns an ordered list of 1-byte items (e.g. indices), however, if the script requires the bytes to be in the reversed order, then OP_REVERSEBYTES would allow to do this trivially.
|
||||||
|
|
||||||
|
### A Note On Signs
|
||||||
|
|
||||||
|
For unsigned integers, the behavior is always the expected one: the number will be encoded as unsigned big-endian integer. However, as integers in Script are encoded rather curiously, signed integers might result in unexpected behavior:
|
||||||
|
|
||||||
|
`-1 4 OP_NUM2BIN OP_REVERSEBYTES -> {0x80, 0x00, 0x00, 0x01}`
|
||||||
|
|
||||||
|
Here, the sign bit is the first bit of the resulting stackitem. Usually, negative numbers are encoded in two's complement, and the number should be `{0xff, 0xff, 0xff, 0xff}`. However, as long as developers are aware of this quite Script specific encoding, there's no issue at hand.
|
||||||
|
|
||||||
|
## OP_REVERSEBYTES Specification
|
||||||
|
|
||||||
|
This specification uses the same syntax for the stack/stackitems as [[11]](#references).
|
||||||
|
|
||||||
|
### Semantics
|
||||||
|
|
||||||
|
`a OP_REVERSEBYTES -> b`.
|
||||||
|
|
||||||
|
OP_REVERSEBYTES fails immediately if the stack is empty.
|
||||||
|
|
||||||
|
Otherwise, the top stack item is removed from the stack, and a byte-reversed version is pushed onto the stack.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
* `{} OP_REVERSEBYTES -> {}`
|
||||||
|
* `{0x01} OP_REVERSEBYTES -> {0x01}`
|
||||||
|
* `{0x01, 0x02, 0x03, 0x04} OP_REVERSEBYTES -> {0x04, 0x03, 0x02, 0x01}`
|
||||||
|
|
||||||
|
### Opcode Number
|
||||||
|
|
||||||
|
OP_REVERSEBYTES proposes to use the previously unused opcode with number 188 (0xbc in hex encoding), which comes after the most recently added opcode, `OP_CHECKDATASIGVERIFY`.
|
||||||
|
|
||||||
|
### Name
|
||||||
|
|
||||||
|
The naming of this opcode turned out to become a bit of a bikeshed. In a previous proposal, this opcode has been named `OP_REVERSE`. After that, it has been renamed to `OP_BSWAP`, as that is a more technically accurate term, which is commonly used for reversing the byteorder of integers [[14, 15]](#references). However, after some more consideration, it has been renamed to `OP_ENDIAN_REVERSE` following Boost‘s nomenclature [[16]](#references), then to `OP_REVERSEENDIAN` and finally to `OP_REVERSEBYTES`, which are both more consistent with Script‘s opcode naming system. However, as, “endian” is usually used for numbers which are a power of two—which isn‘t the case for this opcode—`OP_REVERSEBYTES` is the prefered choice here.
|
||||||
|
|
||||||
|
`OP_REVERSEBYTES` is preferable to `OP_BSWAP` because `OP_BSWAP` is lexically very similar to the already existing `OP_SWAP` and would make Script harder to read. Also, while the technical term for the instruction is indeed `bswap`, it isn‘t well known for developers of higher level languages and could thus spark confusion that would be avoided by using the name `OP_REVERSEBYTES`, which is more self-descriptive.
|
||||||
|
|
||||||
|
### Activation
|
||||||
|
|
||||||
|
The opcode will be activated during the 15th May 2020 hardfork.
|
||||||
|
|
||||||
|
### Unit Tests
|
||||||
|
|
||||||
|
The following unit tests are used by the ABC implementation of the opcode as of Feb 17th 2020.
|
||||||
|
- `<item> OP_REVERSEBYTES` fails if 15th May 2020 protocol upgrade is not yet activated.
|
||||||
|
- `OP_REVERSEBYTES` fails if the stack is empty.
|
||||||
|
- `{} OP_REVERSEBYTES -> {}`
|
||||||
|
- `{99} OP_REVERSEBYTES -> {99}`
|
||||||
|
- `{0xde, 0xad} OP_REVERSEBYTES -> {0xad, 0xde}`
|
||||||
|
- `{0xde, 0xad, 0xa1} OP_REVERSEBYTES -> {0xa1, 0xad, 0xde}`
|
||||||
|
- `{0xde, 0xad, 0xbe, 0xef} OP_REVERSEBYTES -> {0xef, 0xbe, 0xad, 0xde}`
|
||||||
|
- `{0x12, 0x34, 0x56} OP_REVERSEBYTES -> {0x56, 0x34, 0x12}`
|
||||||
|
- for all n ∈ [0; 520]: `{i mod 256 | i < n} OP_REVERSEBYTES -> {(n - i - 1) mod 256 | i < n}`
|
||||||
|
- for all n ∈ [0; 520]: `{(if (i < (n + 1) / 2) then (i) else (n - i - 1)) % 256) | i < n} OP_DUP OP_REVERSEBYTES OP_EQUAL -> OP_TRUE`
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
[1] SLP Token specification: https://github.com/simpleledger/slp-specifications/blob/master/slp-token-type-1.md
|
||||||
|
|
||||||
|
[2] Spending constraints with OP_CHECKDATASIG: https://honest.cash/pein_sama/spending-constraints-with-op_checkdatasig-172
|
||||||
|
|
||||||
|
[3] SLP Agora: https://github.com/EyeOfPython/slpagora
|
||||||
|
|
||||||
|
[4] Sample SLPDEX transaction: https://blockchair.com/bitcoin-cash/transaction/2e69f47a985673c5a645e20ad09025a0892321f096224679657f98e6152c845c
|
||||||
|
|
||||||
|
[5] Let's play chess on the BCH Blockchain: https://tobiasruck.com/content/lets-play-chess-on-bch/
|
||||||
|
|
||||||
|
[6] SLPDEX (discontinued): slpdex.cash
|
||||||
|
|
||||||
|
[7] DAO: https://en.wikipedia.org/wiki/Decentralized_autonomous_organization
|
||||||
|
|
||||||
|
[8] Bitcoin protocol documentation, common structures: https://en.bitcoin.it/wiki/Protocol_documentation#Common_structures
|
||||||
|
|
||||||
|
[9] BIP143: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki
|
||||||
|
|
||||||
|
[10] BIP16: https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki
|
||||||
|
|
||||||
|
[11] May 2018, reenabled opcodes: https://github.com/EyeOfPython/bitcoincash.org/blob/master/spec/may-2018-reenabled-opcodes.md
|
||||||
|
|
||||||
|
[12] AMQP specification, page 14: http://www.amqp.org/sites/amqp.org/files/amqp.pdf
|
||||||
|
|
||||||
|
[13] Apache Thrift binary protocol: https://github.com/apache/thrift/blob/master/doc/specs/thrift-binary-protocol.md
|
||||||
|
|
||||||
|
[14] https://docs.rs/bswap/1.0.0/bswap/
|
||||||
|
|
||||||
|
[15] https://www.npmjs.com/package/bswap
|
||||||
|
|
||||||
|
[16] https://www.boost.org/doc/libs/1_63_0/libs/endian/doc/conversion.html#endian_reverse
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 145 KiB |
@@ -0,0 +1,167 @@
|
|||||||
|
# 2020-05-15 SigChecks
|
||||||
|
|
||||||
|
layout: specification
|
||||||
|
title: 2020-MAY-15 script SigChecks counting and limiting specification
|
||||||
|
date: 2020-03-05
|
||||||
|
category: spec
|
||||||
|
activation: 1589544000
|
||||||
|
version: 0.2 (DRAFT)
|
||||||
|
author: Mark B. Lundeberg
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
|
||||||
|
Bitcoin Cash's SigOps counting and limiting system will be replaced with a new system, referred to as SigChecks.
|
||||||
|
|
||||||
|
# Motivation
|
||||||
|
|
||||||
|
Since early days, Bitcoin has had a SigOps counting rule for limiting the amount of CPU usage possible in a given transaction or block, based on the principle that signature verifications are by far the most CPU-intense operations.
|
||||||
|
|
||||||
|
Although partly effective, there are well known issues with sigops, which mainly stem from the fact that SigOps are judged by parsing scripts, rather than executing them.
|
||||||
|
Bitcoin splits scripts into two transactions (the scriptPubKey of the transaction that creates a coin, and the scriptSig of the transaction that spends it), yet the actual CPU work of verifying a transaction solely happens in the spending transaction, and this leads to some paradoxical situations: a transaction/block that contains high sigops might involve very little CPU work, and conversely a transaction with low sigops may require very high CPU work.
|
||||||
|
|
||||||
|
The essential idea of SigChecks is to perform counting solely in the spending transaction, and count actual executed signature check operations.
|
||||||
|
|
||||||
|
# Specification
|
||||||
|
|
||||||
|
## Counting rule
|
||||||
|
|
||||||
|
The SigChecks count for a given script is discovered during execution of the script.
|
||||||
|
|
||||||
|
- Executing OP_CHECKSIG / OP_CHECKSIGVERIFY / OP_CHECKDATASIG / OP_CHECKDATASIGVERIFY increments SigChecks by:
|
||||||
|
- +0, if signature is NULL.
|
||||||
|
- +1, if signature is non-NULL.
|
||||||
|
- Executing an M-of-N OP_CHECKMULTISIG / OP_CHECKMULTISIGVERIFY increments SigChecks by:
|
||||||
|
- +0, if all M signatures are NULL.
|
||||||
|
- +M, if at least one signature is non-NULL and the verification is in [New/Schnorr mode](/protocol/forks/2019-11-15-schnorrmultisig) (dummy element is non-NULL).
|
||||||
|
- +N, if at least one signature is non-NULL and the verification is in Old/ECDSA mode (dummy element is NULL).
|
||||||
|
|
||||||
|
Here NULL means a script stack element that has length 0; passing NULL in place of an expected signature is the canonical way of cancelling the signature check, i.e., making the signature checking opcode fail / return false (and the only way permitted way to cause this result ever since NULLFAIL rule activated).
|
||||||
|
|
||||||
|
## Per-block limitation (consensus rule)
|
||||||
|
|
||||||
|
After activation, any block where the total number of SigChecks accumulated (during all script executions - scriptSig, scriptPubKey, and P2SH redeemScript - in all inputs excepting coinbase) violates the following limit based on the maximum block size shall be rejected:
|
||||||
|
|
||||||
|
block_SigChecks <= max_Blocksize // 141
|
||||||
|
|
||||||
|
Here, max_Blocksize refers to the consensus limit that is enforced on the full serialized block size (including block header, transaction counter, and all serialized transaction).
|
||||||
|
|
||||||
|
Currently, `max_BlockSize` = 32000000 so the maximum allowed `block_SigChecks` would be 226950 for all blocks. However, in future block size increases, it should be assumed that the SigChecks limit increases proportionally.
|
||||||
|
|
||||||
|
## Per-transaction limits (consensus rule)
|
||||||
|
|
||||||
|
After activation, any transaction where the total number of SigChecks accumulated (during all script executions - scriptSig, scriptPubKey, and P2SH redeemScript - in all inputs excepting coinbase) violates the following limit shall be rejected:
|
||||||
|
|
||||||
|
transaction_SigChecks <= 3000
|
||||||
|
|
||||||
|
## Per-input limitation (standardness rule)
|
||||||
|
|
||||||
|
For a given transaction input, the number of SigChecks accumulated during all script execution (scriptSig, scriptPubKey, and P2SH redeemScript) is to be limited according to the byte-length of the scriptSig, `len_scriptSig`:
|
||||||
|
|
||||||
|
txin_SigChecks <= (len_scriptSig + 60) // 43, where // indicates floor division.
|
||||||
|
- or equivalently -
|
||||||
|
len_scriptSig >= 43 * txin_SigChecks - 60
|
||||||
|
|
||||||
|
Any transaction that contains an input violating this limit should be rejected from nodes' mempools and not relayed. However, blocks may contain inputs that violate this limit.
|
||||||
|
|
||||||
|
This is only a non-consensus standardness (transaction relay) rule, meaning that transactions within blocks do not need to obey this rule. Nodes should only enforce this rule starting at the activation time, and if any transactions in mempool violate this rule at precisely the time of activation, they should be ejected.
|
||||||
|
|
||||||
|
## Removal of SigOps
|
||||||
|
|
||||||
|
After the activation, nodes shall disable the all consensus rules and all standardness rules relating to the old SigOps counting mechanism. There are four such rules:
|
||||||
|
|
||||||
|
- The consensus limit of 20000 sigops per MB of block shall be disabled.
|
||||||
|
- The consensus limit of 20000 sigops per transaction shall be disabled.
|
||||||
|
- The standardness limit of 4000 sigops per transaction shall be disabled.
|
||||||
|
- The standardness limit of 15 sigops per P2SH input shall be disabled.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- The question of whether all signatures are null is not precisely the inverse of whether the opcode returns true/false to stack: consider the case of 0-of-N OP_CHECKMULTISIG, which always returns true, yet also has "all null" signatures. Also, historically pre-NULLFAIL opcodes would return false for non-null invalid signatures, instead of failing.
|
||||||
|
|
||||||
|
# Rationale and commentary on design decisions
|
||||||
|
|
||||||
|
## Counting rule
|
||||||
|
|
||||||
|
The proposed counting rule is easy to implement, but it's not the simplest / most obvious approach. There is one primary design feature we wanted to ensure: *The proposed counting rule means that the sigchecks count can be evaluated by executing a script with a 'dummy'/deferred signature verifier, i.e., without performing any CPU-intensive elliptic curve math.*
|
||||||
|
|
||||||
|
We currently have the NULLFAIL rule, which means that signature check opcodes will either:
|
||||||
|
- fail with error, because the non-null signatures were not valid, or there was a mixture of null / non-null signatures, or because the checked public keys were incorrectly encoded, or some other reason.
|
||||||
|
- return true, if all signatures are non-null and valid, or,
|
||||||
|
- return false, if all signatures are null and there is at least 1 signature.
|
||||||
|
|
||||||
|
Right now, nodes can optionally use this fact to defer public key and signature checks until after script execution, simply placing true/false on stack depending on whether the signatures are null or not, and continuing execution as if the checks were done.
|
||||||
|
Later, after the script has finished executing successfully, the deferred checks can be finally executed to determine whether the script should in fact be failed entirely.
|
||||||
|
This deferment allows some efficiency advantages (like allowing Schnorr batch validation, fast rejection of some invalid blocks/transactions, etc.).
|
||||||
|
|
||||||
|
The simplest imaginable rule would be to only count signature check function calls that are actually done.
|
||||||
|
The main problem with this approach is that M-of-N ECDSA multisig verifications perform a variable number of signature checks, at least M but as many as N.
|
||||||
|
Some of these checks fail, some succeed. The count would then be only determinable by actually performing full signature checks.
|
||||||
|
With the deferment mentioned above, this would mean that any limits on sigchecks could not be accurately enforced before actually carrying out the signature checks.
|
||||||
|
|
||||||
|
A secondary aspect of counting is that when all signatures are null, we assign a sigchecks count of 0.
|
||||||
|
This is a rare case since most scripts want only valid signatures anyway.
|
||||||
|
However, it does increase accuracy of the count, and it can be useful in smart contracting to use null signatures instead of booleans to control branching flows (booleans pushed from scriptSig can be malleated).
|
||||||
|
Since it is easy to implement the 0 sigchecks counting and it's more accurate that way, we decided to include this.
|
||||||
|
|
||||||
|
## Why have limits?
|
||||||
|
|
||||||
|
The SigOps and SigChecks limits exist solely to limit the impact of denial of service attacks. There are a variety of attacks that might occur, but these are the main ones:
|
||||||
|
- An attacking miner can craft valid/invalid blocks packed full with valid and CPU-intensive non-standard scripts that would require huge amounts of time (perhaps hours) to validate.
|
||||||
|
- Anyone may flood the mempool with valid but CPU-intensive transactions. Since these are valid, they will be propagated to all nodes 'for free' and load down the network.
|
||||||
|
|
||||||
|
While these might sound bad, it's worth noting that the disruption would be temporary.
|
||||||
|
The mempool and block attack vectors are essentially decoupled since efficient nodes use transaction validity caching: if they have accepted a transaction already, they don't need to re-verify it when they see it mined in a block.
|
||||||
|
Also, CPU-intensive blocks do not cause any kind of "permanent damage" to new nodes coming online, since again efficient nodes typically provide for an 'assume-valid' setting that only requires fully verifying recent blocks.
|
||||||
|
|
||||||
|
*Blocks*:
|
||||||
|
Slow blocks can be made without any setup, but the slowest possible block would require a many setup blocks to be mined beforehand that generate attack outputs.
|
||||||
|
These attack outputs would then all be spent in the attack block.
|
||||||
|
Since scripts are limited to 201 opcodes and inputs are at least 41 bytes, this could achieve about 5 signature checks for every byte in the spending block, or 160 million signature checks with today's maximum block size.
|
||||||
|
As a rough rule of thumb, each signature check takes 50 microseconds, so such a block would take a couple of CPU-hours to validate (though this is trivially parallelized).
|
||||||
|
The proposed limit of 141 bytes / sigcheck cuts the worst case down by a factor of 700.
|
||||||
|
The main motivation here isn't just to ensure nondisruption with current block sizes, but also to make sure future block size increases can be made with needing to worry so much about slow block attacks.
|
||||||
|
|
||||||
|
*Mempool*:
|
||||||
|
As far as mempool attacks go, these currently are already greatly limited by standardness rules on mainnet that 1) whitelist only certain allowed output script templates and 2) limit P2SH to 15 sigops.
|
||||||
|
If either rule were simply removed, it would permit abusive scripts that perform a large number of verifications in a tight space.
|
||||||
|
Since we are planning to remove sigops, then something needs to go in place of that P2SH sigops rule.
|
||||||
|
Besides limiting the density of CPU usage, it also makes sense to limit signature checks density in transactions as a *support* for the block limit: we don't want that the mempool can be totally filled with high-sigchecks transactions that take ages to clear out (since each block can only consume so many of them).
|
||||||
|
|
||||||
|
It's worth pointing out some of the indirect limits that are created as a result:
|
||||||
|
- As mentioned above it is impossible for the number of SigChecks in an input to exceed 201, which is the current limit on the 'opcode count' for a single script.
|
||||||
|
- However, a mainnet standard transaction cannot have a scriptSig longer than 1650 bytes, which means an input in a standard transaction won't be able to have more than 39 SigChecks.
|
||||||
|
- The per-input rule means that the overall density of SigChecks in a standard transaction cannot exceed 33.5 bytes / SigCheck. This occurs with many inputs having each two SigChecks in a scriptSig of length 26, i.e., an input of size 26+41 = 67 bytes.
|
||||||
|
- Due to additional script template standardness rules on mainnet, it is practically not possible to produce such a short scriptSig containing two sigchecks. So, practically one can only achieve 36.67 bytes/SigCheck (three SigChecks in a scriptSig of length 69), using 1-of-3 bare multisignatures or some P2SH tricks.
|
||||||
|
- Likewise standard transactions on mainnet are limited to 100000 bytes, so a standard transaction won't be able to have more than 3000 sigchecks.
|
||||||
|
|
||||||
|
## Choice of numbers
|
||||||
|
|
||||||
|
The numbers proposed for the per-input and per-block limits are based on an examination of current typical uses, and an examination of the historical blockchain.
|
||||||
|
|
||||||
|
The per-input limit is designed to support the two most extreme standard use cases, which deserve continuing support and (though rare) are still used occasionally:
|
||||||
|
|
||||||
|
* Spending a bare 1-of-3 multisignature in ECDSA mode will have 3 SigChecks in around 73 bytes. (Bare multisigs like 1-of-4 and beyond are nonstandard to fund.)
|
||||||
|
* Spending a P2SH 1-of-15 multisignature in ECDSA mode will have 15 SigChecks in around 589 bytes.
|
||||||
|
|
||||||
|
The proposed per-input rule is a line interpolating between those two cases, with a spare allowance of 4 bytes for each (since ECDSA signatures are variable size, and very rarely are they shorter than this in normal usage).
|
||||||
|
|
||||||
|
Typical use cases are much much lower density than these. P2PK and P2PKH have 1 SigCheck in ~70 bytes and ~105 bytes respectively, and most P2SH multisignatures are 2-of-3 spent with ECDSA which have 3 SigChecks in a ~250 byte scriptSig. I've plotted the common standard use cases below. As can be seen
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
The block limit is based on an examination of normal usage patterns and observations on historical blocks. Historically, the bulk (75%) of blocks have had a density of between 150 and 250 bytes/SigCheck, and the average density of the whole chain is 176 bytes/SigCheck. Only 2% of blocks have been more dense than 141 bytes/SigCheck. This matches the fact that the vast majority of inputs/outputs are P2PKH, which on the whole (considering funding and spending) have a density of around 182 bytes/SigCheck. Rarely, one sees a block that is packed full of an unusually high fraction of P2SH 2-of-3 multisignature consolidations, which pushes down to the 100 bytes/SigCheck level. Blocks more dense than 98 bytes/SigCheck have been extremely rare, making up 0.01% of blocks.
|
||||||
|
|
||||||
|
The exact number of 141 bytes/SigCheck comes from considering a fairly common use case, which is consolidating many P2PKH inputs. If done with Schnorr signatures then each input is 141 bytes and one SigCheck.
|
||||||
|
|
||||||
|
The choice of 141 bytes/SigCheck for a block is ~4x times more aggressive than the ~36.67 bytes/SigCheck standardness rule. It's worth emphasizing however that this block limit is based on the maximum block size. Thus, it may happen that a normally mined block has an actual density of ~36.67 bytes/SigCheck, however, such a block could not be more than ~1/4th of the maximum block byte size.
|
||||||
|
|
||||||
|
A histogram of historical block densities is plotted below:
|
||||||
|

|
||||||
|
|
||||||
|
# Implementation
|
||||||
|
|
||||||
|
**Implementation information to be added - TBD**
|
||||||
|
|
||||||
|
# Acknowledgements
|
||||||
|
|
||||||
|
Thanks to Amaury Sechet, Josh Green, Tobias Ruck, Tyler Smith, Calin Culianu, and Andrew Stone for valuable feedback.
|
||||||
Binary file not shown.
@@ -0,0 +1,428 @@
|
|||||||
|
# 2020-11-15 ASERT
|
||||||
|
|
||||||
|
layout: specification
|
||||||
|
title: ASERT Difficulty Adjustment Algorithm (aserti3-2d)
|
||||||
|
date: 2020-08-17
|
||||||
|
category: spec
|
||||||
|
activation: 1605441600
|
||||||
|
version: 0.6.3
|
||||||
|
author: freetrader, Jonathan Toomim, Calin Culianu, Mark Lundeberg, Tobias Ruck
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
Activation of a new new difficulty adjustment algorithm 'aserti3-2d'
|
||||||
|
(or 'ASERT' for short) for the November 2020 Bitcoin Cash upgrade. Activation will be
|
||||||
|
based on MTP, with the last pre-fork block used as the anchor block.
|
||||||
|
|
||||||
|
## Motivation
|
||||||
|
|
||||||
|
- To eliminate periodic oscillations in difficulty and hashrate
|
||||||
|
- To reduce the difference in profitability between steady miners and
|
||||||
|
those who switch to mining other blockchains.
|
||||||
|
- To maintain average block intervals close to the 10 minute target.
|
||||||
|
- To bring the average transaction confirmation time close to target time.
|
||||||
|
|
||||||
|
## Technical background
|
||||||
|
|
||||||
|
The November 2017 Bitcoin Cash upgrade introduced a simple moving average as
|
||||||
|
difficulty adjustment algorithm. This change unfortunately introduced daily
|
||||||
|
periodic difficulty oscillations, which resulted in long confirmation times
|
||||||
|
followed by a burst of rapid blocks. This harms the user experience of Bitcoin
|
||||||
|
Cash, and punishes steady hashrate miners.
|
||||||
|
|
||||||
|
Research into the family of difficulty algorithms based on an exponential
|
||||||
|
moving average (EMA) resulted in ASERT (Absolutely Scheduled Exponentially
|
||||||
|
Rising Targets) [[1]](#references), which has been developed by Mark Lundeberg in 2019 and
|
||||||
|
fully described by him in 2020. An equivalent formula was independently
|
||||||
|
discovered in 2018 by Jacob Eliosoff and in 2020 by Werner et. al [[6]](#references).
|
||||||
|
|
||||||
|
ASERT does not have the same oscillations as the DAA introduced in the November
|
||||||
|
2017 upgrade and has a range of other attractive qualities such as robustness
|
||||||
|
against singularities [[15]](#references) without a need for additional rules, and absence of
|
||||||
|
accumulation of rounding/approximation errors.
|
||||||
|
|
||||||
|
In extensive simulation against a range of other stable algorithms [[2]](#references),
|
||||||
|
an ASERT algorithm performed best across criteria that included:
|
||||||
|
|
||||||
|
- Average block times closest to an ideal target time of 600 seconds.
|
||||||
|
- Average transaction confirmation times closest to the target time.
|
||||||
|
- Reducing the advantage of non-steady mining strategies, thereby maximizing
|
||||||
|
the relative profitability of steady mining.
|
||||||
|
|
||||||
|
## Specification
|
||||||
|
|
||||||
|
### Terms and conventions
|
||||||
|
|
||||||
|
* Fork block: The first block mined according to the new consensus rules.
|
||||||
|
* Anchor block: The parent of the fork block.
|
||||||
|
|
||||||
|
|
||||||
|
### Requirements
|
||||||
|
|
||||||
|
#### Target computation
|
||||||
|
The current block's target bits are calculated by the following algorithm.
|
||||||
|
|
||||||
|
The aserti3-2d algorithm can be described by the following formula:
|
||||||
|
|
||||||
|
```
|
||||||
|
next_target = anchor_target * 2**((time_delta - ideal_block_time * (height_delta + 1)) / halflife)
|
||||||
|
```
|
||||||
|
|
||||||
|
where:
|
||||||
|
|
||||||
|
- `anchor_target` is the unsigned 256 bit integer equivalent of the `nBits` value in
|
||||||
|
the header of the anchor block.
|
||||||
|
- `time_delta` is the difference, in signed integer seconds, between the
|
||||||
|
timestamp in the header of the current block and the timestamp in the
|
||||||
|
parent of the anchor block.
|
||||||
|
- `ideal_block_time` is a constant: 600 seconds, the targeted
|
||||||
|
average time between blocks.
|
||||||
|
- `height_delta` is the difference in block height between the current
|
||||||
|
block and the anchor block.
|
||||||
|
- `halflife` is a constant parameter sometimes referred to as
|
||||||
|
'tau', with a value of 172800 (seconds) on mainnet.
|
||||||
|
- `next_target` is the integer value of the target computed for the block
|
||||||
|
after the current block.
|
||||||
|
|
||||||
|
The algorithm below implements the above formula using fixed-point integer
|
||||||
|
arithmetic and a cubic polynomial approximation to the 2^x term.
|
||||||
|
|
||||||
|
The 'target' values used as input and output are the compact representations
|
||||||
|
of actual 256-bit integer targets as specified for the 'nBits' field in the
|
||||||
|
block header.
|
||||||
|
|
||||||
|
|
||||||
|
Python-code, uses Python 3 syntax:
|
||||||
|
|
||||||
|
```python
|
||||||
|
def next_target_aserti3_2d(
|
||||||
|
anchor_height: int, # height of the anchor block.
|
||||||
|
anchor_parent_time: int, # timestamp (nTime) of the parent of the anchor block.
|
||||||
|
anchor_bits: int, # 'nBits' value of the anchor block.
|
||||||
|
current_height: int, # height of the current block.
|
||||||
|
current_time: int, # timestamp of the current block.
|
||||||
|
) -> int: # 'target' nBits of the current block.
|
||||||
|
ideal_block_time = 600 # in seconds
|
||||||
|
halflife = 172_800 # 2 days (in seconds)
|
||||||
|
radix = 2**16 # 16 bits for decimal part of fixed-point integer arithmetic
|
||||||
|
max_bits = 0x1d00_ffff # maximum target in nBits representation
|
||||||
|
max_target = bits_to_target(max_bits) # maximum target as integer
|
||||||
|
|
||||||
|
anchor_target = bits_to_target(anchor_bits)
|
||||||
|
time_delta = current_time - anchor_parent_time
|
||||||
|
height_delta = current_height - anchor_height # can be negative
|
||||||
|
# `//` is truncating division (int.__floordiv__) - see note 3 below
|
||||||
|
exponent = time_delta - ideal_block_time * (height_delta + 1) // halflife
|
||||||
|
|
||||||
|
# Compute equivalent of `num_shifts = math.floor(exponent / 2**16)`
|
||||||
|
num_shifts = exponent >> 16
|
||||||
|
|
||||||
|
exponent = exponent - num_shifts * radix
|
||||||
|
factor = ((195_766_423_245_049 * exponent +
|
||||||
|
971_821_376 * exponent**2 +
|
||||||
|
5_127 * exponent**3 +
|
||||||
|
2**47) >> 48) + radix
|
||||||
|
next_target = anchor_target * factor
|
||||||
|
|
||||||
|
# Calculate `next_target = math.floor(next_target * 2**factor)`
|
||||||
|
if num_shifts < 0:
|
||||||
|
next_target >>= -num_shifts
|
||||||
|
else:
|
||||||
|
# Implementations should be careful of overflow here (see note 6 below).
|
||||||
|
next_target <<= num_shifts
|
||||||
|
|
||||||
|
next_target >>= 16
|
||||||
|
if next_target == 0:
|
||||||
|
return target_to_bits(1) # hardest valid target
|
||||||
|
|
||||||
|
if next_target > max_target:
|
||||||
|
return max_bits # limit on easiest target
|
||||||
|
return target_to_bits(next_target)
|
||||||
|
```
|
||||||
|
|
||||||
|
Note 1: The reference implementations make use of signed integer arithmetic.
|
||||||
|
Alternative implementations may use strictly unsigned integer
|
||||||
|
arithmetic.
|
||||||
|
|
||||||
|
Note 2: All implementations should strictly avoid use of floating point
|
||||||
|
arithmetic in the computation of the exponent.
|
||||||
|
|
||||||
|
Note 3: In the calculation of the exponent, truncating integer division [[7, 10]](#references)
|
||||||
|
must be used, as indicated by the `//` division operator (`int.__floordiv__`).
|
||||||
|
|
||||||
|
Note 5: The convenience functions `bits_to_target()` and `target_to_bits()`
|
||||||
|
are assumed to be available for conversion between compact 'nBits'
|
||||||
|
and unsigned 256-bit integer representations of targets.
|
||||||
|
Examples of such functions are available in the C++ and Python3
|
||||||
|
reference implementations.
|
||||||
|
|
||||||
|
Note 6: If a limited-width integer type is used for `current_target`, then the `<<`
|
||||||
|
operator may cause an overflow exception or silent discarding of
|
||||||
|
most-significant bits.
|
||||||
|
Implementations must detect and handle such cases to correctly emulate
|
||||||
|
the behaviour of an unlimited-width calculation. Note that if the result
|
||||||
|
at this point would exceed `radix * max_target` then `max_bits` may be returned
|
||||||
|
immediately.
|
||||||
|
|
||||||
|
Note 7: The polynomial approximation that computes `factor` must be performed
|
||||||
|
with 64 bit unsigned integer arithmetic or better. It *will*
|
||||||
|
overflow a signed 64 bit integer. Since exponent is signed, it may be
|
||||||
|
necessary to cast it to unsigned 64 bit integer. In languages like
|
||||||
|
Java where long is always signed, an unsigned shift `>>> 48` must be
|
||||||
|
used to divide by 2^48.
|
||||||
|
|
||||||
|
|
||||||
|
#### Activation
|
||||||
|
|
||||||
|
The ASERT algorithm will be activated according to the top-level upgrade spec [[3]](#references).
|
||||||
|
|
||||||
|
#### Anchor block
|
||||||
|
|
||||||
|
ASERT requires the choice of an anchor block to schedule future target
|
||||||
|
computations.
|
||||||
|
|
||||||
|
The first block with an MTP that is greater/equal to the upgrade activation time
|
||||||
|
will be used as the anchor block for subsequent ASERT calculations.
|
||||||
|
|
||||||
|
This corresponds to the last block mined under the pre-ASERT DAA rules.
|
||||||
|
|
||||||
|
Note 1: The anchor block is the block whose height and target
|
||||||
|
(nBits) are used as the 'absolute' basis for ASERT's
|
||||||
|
scheduled target. The timestamp (nTime) of the anchor block's
|
||||||
|
*parent* is used.
|
||||||
|
|
||||||
|
Note 2: The height, timestamp, and nBits of this block are not known ahead of
|
||||||
|
the upgrade. Implementations MUST dynamically determine it across the
|
||||||
|
upgrade. Once the network upgrade has been consolidated by
|
||||||
|
sufficient chain work or a checkpoint, implementations can simply
|
||||||
|
hard-code the known height, nBits and associated (parent) timestamp
|
||||||
|
this anchor block. Implementations MAY also hard-code other equivalent
|
||||||
|
representations, such as an nBits value and a time offset from the
|
||||||
|
genesis block.
|
||||||
|
|
||||||
|
|
||||||
|
#### REQ-ASERT-TESTNET-DIFF-RESET (testnet difficulty reset)
|
||||||
|
|
||||||
|
On testnet, an additional rule will be included: Any block with a timestamp
|
||||||
|
that is more than 1200 seconds after its parent's timestamp must use an
|
||||||
|
nBits value of `max_bits` (`0x1d00ffff`).
|
||||||
|
|
||||||
|
|
||||||
|
## Rationale and commentary on requirements / design decisions
|
||||||
|
|
||||||
|
1. Choice of anchor block determination
|
||||||
|
|
||||||
|
Choosing an anchor block that is far enough in the past would result
|
||||||
|
in slightly simpler coding requirements but would create the possibility
|
||||||
|
of a significant difficulty adjustment at the upgrade.
|
||||||
|
|
||||||
|
The last block mined according to the old DAA was chosen since this block is
|
||||||
|
the most proximal anchor and allows for the smoothest transition to the new
|
||||||
|
algorithm.
|
||||||
|
|
||||||
|
2. Avoidance of floating point calculations
|
||||||
|
|
||||||
|
Compliance with IEEE-754 floating point arithmetic is not generally
|
||||||
|
guaranteed by programming languages on which a new DAA needs to be
|
||||||
|
implemented. This could result in floating point calculations yielding
|
||||||
|
different results depending on compilers, interpreters or hardware.
|
||||||
|
|
||||||
|
It is therefore highly advised to perform all calculations purely using
|
||||||
|
integers and highly specific operators to ensure identical difficulty
|
||||||
|
targets are enforced across all implementations.
|
||||||
|
|
||||||
|
3. Choice of half-life
|
||||||
|
|
||||||
|
A half-life of 2 days (`halflife = 2 * 24 * 3600`), equivalent to an e^x-based
|
||||||
|
time constant of `2 * 144 * ln(2)` or aserti3-415.5, was chosen because it reaches
|
||||||
|
near-optimal performance in simulations by balancing the need to buffer
|
||||||
|
against statistical noise and the need to respond rapidly to swings in price
|
||||||
|
or hashrate, while also being easy for humans to understand: For every 2 days
|
||||||
|
ahead of schedule a block's timestamp becomes, the difficulty doubles.
|
||||||
|
|
||||||
|
4. Choice of approximation polynomial
|
||||||
|
|
||||||
|
The DAA is part of a control system feedback loop that regulates hashrate,
|
||||||
|
and the exponential function and its integer approximation comprise its
|
||||||
|
transfer function. As such, standard guidelines for ensuring control system
|
||||||
|
stability apply. Control systems tend to be far more sensitive to
|
||||||
|
differential nonlinearity (DNL) than integral nonlinearity (INL) in their
|
||||||
|
transfer functions. Our requirements were to have a transfer function that
|
||||||
|
was (a) monotonic, (b) contained no abrupt changes, (c) had precision and
|
||||||
|
differential nonlinearity that was better than our multi-block statistical
|
||||||
|
noise floor, (d) was simple to implement, and (e) had integral nonlinearity
|
||||||
|
that was no worse than our single-block statistical noise floor.
|
||||||
|
|
||||||
|
A simple, fast to compute cubic approximation of 2^x for 0 <= x < 1 was
|
||||||
|
found to satisfy all of these requirements. It maintains an absolute error
|
||||||
|
margin below 0.013% over this range [8]. In order to address the full
|
||||||
|
(-infinity, +infinity) domain of the exponential function, we found the
|
||||||
|
`2**(x + n) = 2**n * 2**x` identity to be of use. Our cubic approximation gives
|
||||||
|
the exactly correct values `f(0) == 1` and `f(1) == 2`, which allows us to
|
||||||
|
use this identity without concern for discontinuities at the edges of the
|
||||||
|
approximation's domain.
|
||||||
|
|
||||||
|
First, there is the issue of DNL. Our goal was to ensure that our algorithm
|
||||||
|
added no more than 25% as much noise as is inherent in our dataset. Our
|
||||||
|
algorithm is effectively trying to estimate the characteristic hashrate over
|
||||||
|
the recent past, using a 2-day (~288-block) half-life. Our expected
|
||||||
|
exponential distribution of block intervals has a standard deviation (stddev)
|
||||||
|
of 600 seconds. Over a 2-day half-life, our noise floor in our estimated
|
||||||
|
hashrate should be about `sqrt(1 / 288) * 600` seconds, or 35.3 seconds. Our
|
||||||
|
chosen approximation method is able to achieve precision of 3 seconds in most
|
||||||
|
circumstances, limited in two places by 16-bit operations:
|
||||||
|
`172800 sec / 65536 = 2.6367 sec`
|
||||||
|
Our worst-case precision is 8 seconds, and is limited by the worst-case
|
||||||
|
15-bit precision of the nBits value. This 8 second worst-case is not within
|
||||||
|
the scope of this work to address, as it would require a change to the block
|
||||||
|
header. Our worst-case step size is 0.00305%,[[11]](#references) due to the worst-case
|
||||||
|
15-bit nBits mantissa issue. Outside the 15-bit nBits mantissa range, our
|
||||||
|
approximation has a worst-case precision of 0.0021%. Overall, we considered
|
||||||
|
this to be satisfactory DNL performance.
|
||||||
|
|
||||||
|
Second, there is the issue of INL. Simulation testing showed that difficulty
|
||||||
|
and hashrate regulation performance was remarkably insensitive to
|
||||||
|
integral non-linearity. We found that even the use of `f(x) = 1 + x` as an
|
||||||
|
approximation of `2**x` in the `aserti1` algorithm was satisfactory when
|
||||||
|
coupled with the `2**(x + n) = 2^n * 2^x` identity, despite having 6%
|
||||||
|
worst-case INL.[[12, 13]](#references) An approximation with poor INL will still show good
|
||||||
|
hashrate regulation ability, but will have a different amount of drift for a
|
||||||
|
given change in hashrate depending on where in the \[0, 1) domain our exponent
|
||||||
|
(modulo 1) lies. With INL of +/- 1%, for any given difficulty (or target), a
|
||||||
|
block's timestamp might end up being 1% of 172800 seconds ahead of or behind
|
||||||
|
schedule. However, out of an abundance of caution, and because achieving
|
||||||
|
higher precision was easy, we chose to aim for INL that would be comparable
|
||||||
|
to or less than the typical drift that can be caused by one block. Out of
|
||||||
|
a 2-day half-life window, one block's variance comprises:
|
||||||
|
`600 / 172800 = 0.347%`
|
||||||
|
Our cubic approximation's INL performance is better than 0.013%,[[14]](#references) which
|
||||||
|
exceeds that requirement by a comfortable margin.
|
||||||
|
|
||||||
|
5. Conversion of difficulty bits (nBits) to 256-bit target representations
|
||||||
|
|
||||||
|
As there are few calculations in ASERT which involve 256-bit integers
|
||||||
|
and the algorithm is executed infrequently, it was considered unnecessary
|
||||||
|
to require more complex operations such as doing arithmetic directly on
|
||||||
|
the compact target representations (nBits) that are the inputs/output of
|
||||||
|
the difficulty algorithm.
|
||||||
|
|
||||||
|
Furthermore, 256-bit (or even bignum) arithmetic is available in existing
|
||||||
|
implementation and used within the previous DAA. Performance impacts are
|
||||||
|
negligible.
|
||||||
|
|
||||||
|
6. Choice of 16-bits of precision for fixed-point math
|
||||||
|
|
||||||
|
The nBits format is comprised of 8 bits of base_256 exponent, followed by a
|
||||||
|
24-bit mantissa. The mantissa must have a value of at least 0x008000, which
|
||||||
|
means that the worst-case scenario gives the mantissa only 15 bits of
|
||||||
|
precision. The choice of 16-bit precision in our fixed point math ensures
|
||||||
|
that overall precision is limited by this 15-bit nBits limit.
|
||||||
|
|
||||||
|
7. Choice of name
|
||||||
|
|
||||||
|
The specific algorithm name 'aserti3-2d' was chosen based on:
|
||||||
|
|
||||||
|
- the 'i' refers to the integer-only arithmetic
|
||||||
|
- the '3' refers to the cubic approximation of the exponential
|
||||||
|
- the '2d' refers to the 2-day (172800 second) halflife
|
||||||
|
|
||||||
|
|
||||||
|
## Implementation advice
|
||||||
|
|
||||||
|
Implementations must not make any rounding errors during their calculations.
|
||||||
|
Rounding must be done exactly as specified in the algorithm. In practice,
|
||||||
|
to guarantee that, you likely need to use integer arithmetic exclusively.
|
||||||
|
|
||||||
|
Implementations which use signed integers and use bit-shifting must ensure
|
||||||
|
that the bit-shifting is arithmetic.
|
||||||
|
|
||||||
|
Note 1: In C++ compilers, right shifting negative signed integers
|
||||||
|
is formally unspecified behavior until C++20 when it
|
||||||
|
will become standard [[5]](#references). In practice, C/C++ compilers
|
||||||
|
commonly implement arithmetic bit shifting for signed
|
||||||
|
numbers. Implementers are advised to verify good behavior
|
||||||
|
through compile-time assertions or unit tests.
|
||||||
|
|
||||||
|
|
||||||
|
## Reference implementations
|
||||||
|
|
||||||
|
- C++ code for aserti3-2d (see pow.cpp): https://reviews.bitcoinabc.org/D7174
|
||||||
|
- Python3 code (see contrib/testgen/validate_nbits_aserti3_2d.py): https://gitlab.com/bitcoin-cash-node/bitcoin-cash-node/-/merge_requests/692
|
||||||
|
- Java code: https://github.com/pokkst/asert-java
|
||||||
|
|
||||||
|
|
||||||
|
## Test vectors
|
||||||
|
|
||||||
|
Test vectors suitable for validating further implementations of the aserti3-2d
|
||||||
|
algorithm are available at:
|
||||||
|
|
||||||
|
[Here](/protocol/forks/2020-11-15-asert-test-vectors.zip)
|
||||||
|
|
||||||
|
alternatively at:
|
||||||
|
|
||||||
|
https://gitlab.com/bitcoin-cash-node/bchn-sw/qa-assets/-/tree/master/test_vectors/aserti3-2d
|
||||||
|
|
||||||
|
and alternatively at:
|
||||||
|
|
||||||
|
https://download.bitcoincashnode.org/misc/data/asert/test_vectors
|
||||||
|
|
||||||
|
|
||||||
|
## Acknowledgements
|
||||||
|
|
||||||
|
Thanks to Mark Lundeberg for granting permission to publish the ASERT paper [[1]](#references),
|
||||||
|
Jonathan Toomim for developing the initial Python and C++ implementations,
|
||||||
|
upgrading the simulation framework [[9]](#references) and evaluating the various difficulty
|
||||||
|
algorithms.
|
||||||
|
|
||||||
|
Thanks to Jacob Eliosoff, Tom Harding and Scott Roberts for evaluation work
|
||||||
|
on the families of EMA and other algorithms considered as replacements for
|
||||||
|
the Bitcoin Cash DAA, and thanks to the following for review and their
|
||||||
|
valuable suggestions for improvement:
|
||||||
|
|
||||||
|
- Andrea Suisani (sickpig)
|
||||||
|
- BigBlockIfTrue
|
||||||
|
- Fernando Pellicioni
|
||||||
|
- imaginary_username
|
||||||
|
- mtrycz
|
||||||
|
- Jochen Hoenicke
|
||||||
|
- John Nieri (emergent_reasons)
|
||||||
|
- Tom Zander
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
[1] "[Static difficulty adjustments, with absolutely scheduled exponentially rising targets (DA-ASERT) -- v2](http://toom.im/files/da-asert.pdf)", Mark B. Lundeberg, July 31, 2020
|
||||||
|
|
||||||
|
[2] "[BCH upgrade proposal: Use ASERT as the new DAA](https://read.cash/@jtoomim/bch-upgrade-proposal-use-asert-as-the-new-daa-1d875696)", Jonathan Toomim, 8 July 2020
|
||||||
|
|
||||||
|
[3] [Bitcoin Cash November 15, 2020 Upgrade Specification](2020-11-15-upgrade.md).
|
||||||
|
|
||||||
|
[4] <https://en.wikipedia.org/wiki/Arithmetic_shift>
|
||||||
|
|
||||||
|
[5] <https://en.cppreference.com/w/cpp/language/operator_arithmetic>
|
||||||
|
|
||||||
|
[6] "[Unstable Throughput: When the Difficulty Algorithm Breaks](https://arxiv.org/pdf/2006.03044.pdf)", Sam M. Werner, Dragos I. Ilie, Iain Stewart, William J. Knottenbelt, June 2020
|
||||||
|
|
||||||
|
[7] "[Different kinds of integer division](https://harry.garrood.me/blog/integer-division)", Harry Garrood, blog, 2018
|
||||||
|
|
||||||
|
[8] [Error in a cubic approximation of 2^x for 0 <= x < 1](https://twitter.com/MarkLundeberg/status/1191831127306031104)
|
||||||
|
|
||||||
|
[9] Jonathan Toomim adaptation of kyuupichan's difficulty algorithm simulator: <https://github.com/jtoomim/difficulty/tree/comparator>
|
||||||
|
|
||||||
|
[10] "[The Euclidean definition of the functions div and mod](dl.acm.org/doi/10.1145/128861.128862)", Raymond T. Boute, 1992, ACM Transactions on Programming Languages and Systems (TOPLAS). 14. 127-144. 10.1145/128861.128862
|
||||||
|
|
||||||
|
[11] <http://toom.im/bch/aserti3_step_size.html>
|
||||||
|
|
||||||
|
[12] [f(x) = (1 + x)/2^x for 0<x<1](https://www.wolframalpha.com/input/?i=f%28x%29+%3D+%281+%2B+x%29%2F2%5Ex+for+0%3Cx%3C1), WolframAlpha.
|
||||||
|
|
||||||
|
[13] <https://github.com/zawy12/difficulty-algorithms/issues/62#issuecomment-647060200>
|
||||||
|
|
||||||
|
[14] <http://toom.im/bch/aserti3_approx_error.html>
|
||||||
|
|
||||||
|
[15] <https://github.com/zawy12/difficulty-algorithms/issues/62#issuecomment-646187957>
|
||||||
|
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This specification is dual-licensed under the Creative Commons CC0 1.0 Universal and
|
||||||
|
GNU All-Permissive licenses.
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
@@ -0,0 +1,229 @@
|
|||||||
|
# BIP-0009
|
||||||
|
BIP: 9
|
||||||
|
Title: Version bits with timeout and delay
|
||||||
|
Author: Pieter Wuille <pieter.wuille@gmail.com>
|
||||||
|
Peter Todd <pete@petertodd.org>
|
||||||
|
Greg Maxwell <greg@xiph.org>
|
||||||
|
Rusty Russell <rusty@rustcorp.com.au>
|
||||||
|
Comments-Summary: No comments yet.
|
||||||
|
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0009
|
||||||
|
Status: Final
|
||||||
|
Type: Informational
|
||||||
|
Created: 2015-10-04
|
||||||
|
License: PD
|
||||||
|
|
||||||
|
## Abstract
|
||||||
|
|
||||||
|
This document specifies a proposed change to the semantics of the 'version' field in Bitcoin blocks, allowing multiple backward-compatible changes (further called "soft forks") to be deployed in parallel. It relies on interpreting the version field as a bit vector, where each bit can be used to track an independent change. These are tallied each retarget period. Once the consensus change succeeds or times out, there is a "fallow" pause after which the bit can be reused for later changes.
|
||||||
|
|
||||||
|
## Motivation
|
||||||
|
|
||||||
|
[BIP 34](/protocol/forks/bip-0034) introduced a mechanism for doing soft-forking changes without a predefined flag timestamp (or flag block height), instead relying on measuring miner support indicated by a higher version number in block headers. As it relies on comparing version numbers as integers however, it only supports one single change being rolled out at once, requiring coordination between proposals, and does not allow for permanent rejection: as long as one soft fork is not fully rolled out, no future one can be scheduled.
|
||||||
|
|
||||||
|
In addition, BIP 34 made the integer comparison (nVersion >= 2) a consensus rule after its 95% threshold was reached, removing 2<sup>31</sup>+2 values from the set of valid version numbers (all negative numbers, as nVersion is interpreted as a signed integer, as well as 0 and 1). This indicates another downside this approach: every upgrade permanently restricts the set of allowed nVersion field values. This approach was later reused in [BIP 66](/protocol/forks/bip-0066) and [BIP 65](/protocol/forks/bip-0065), which further removed nVersions 2 and 3 as valid options. As will be shown further, this is unnecessary.
|
||||||
|
|
||||||
|
## Specification
|
||||||
|
|
||||||
|
Each soft fork deployment is specified by the following per-chain parameters (further elaborated below):
|
||||||
|
|
||||||
|
1. The **name** specifies a very brief description of the soft fork, reasonable for use as an identifier. For deployments described in a single BIP, it is recommended to use the name "bipN" where N is the appropriate BIP number.
|
||||||
|
2. The **bit** determines which bit in the nVersion field of the block is to be used to signal the soft fork lock-in and activation. It is chosen from the set {0,1,2,...,28}.
|
||||||
|
3. The **starttime** specifies a minimum median time past of a block at which the bit gains its meaning.
|
||||||
|
4. The **timeout** specifies a time at which the deployment is considered failed. If the median time past of a block >= timeout and the soft fork has not yet locked in (including this block's bit state), the deployment is considered failed on all descendants of the block.
|
||||||
|
|
||||||
|
### Selection guidelines
|
||||||
|
|
||||||
|
The following guidelines are suggested for selecting these parameters for a soft fork:
|
||||||
|
|
||||||
|
1. **name** should be selected such that no two softforks, concurrent or otherwise, ever use the same name.
|
||||||
|
2. **bit** should be selected such that no two concurrent softforks use the same bit.
|
||||||
|
3. **starttime** should be set to some date in the future, approximately one month after a software release date including the soft fork. This allows for some release delays, while preventing triggers as a result of parties running pre-release software.
|
||||||
|
4. **timeout** should be 1 year (31536000 seconds) after starttime.
|
||||||
|
|
||||||
|
A later deployment using the same bit is possible as long as the starttime is after the previous one's
|
||||||
|
timeout or activation, but it is discouraged until necessary, and even then recommended to have a pause in between to detect buggy software.
|
||||||
|
|
||||||
|
### States
|
||||||
|
|
||||||
|
With each block and soft fork, we associate a deployment state. The possible states are:
|
||||||
|
|
||||||
|
1. **DEFINED** is the first state that each soft fork starts out as. The genesis block is by definition in this state for each deployment.
|
||||||
|
2. **STARTED** for blocks past the starttime.
|
||||||
|
3. **LOCKED_IN** for one retarget period after the first retarget period with STARTED blocks of which at least threshold have the associated bit set in nVersion.
|
||||||
|
4. **ACTIVE** for all blocks after the LOCKED_IN retarget period.
|
||||||
|
5. **FAILED** for one retarget period past the timeout time, if LOCKED_IN was not reached.
|
||||||
|
|
||||||
|
### Bit flags
|
||||||
|
|
||||||
|
The nVersion block header field is to be interpreted as a 32-bit little-endian integer (as present), and bits are selected within this integer as values (1 << N) where N is the bit number.
|
||||||
|
|
||||||
|
Blocks in the STARTED state get an nVersion whose bit position bit is set to 1. The top 3 bits of such blocks must be
|
||||||
|
001, so the range of actually possible nVersion values is [0x20000000...0x3FFFFFFF], inclusive.
|
||||||
|
|
||||||
|
Due to the constraints set by BIP 34, BIP 66 and BIP 65, we only have 0x7FFFFFFB possible nVersion values available.
|
||||||
|
This restricts us to at most 30 independent deployments. By restricting the top 3 bits to 001 we get 29 out of those
|
||||||
|
for the purposes of this proposal, and support two future upgrades for different mechanisms (top bits 010 and 011).
|
||||||
|
When a block nVersion does not have top bits 001, it is treated as if all
|
||||||
|
bits are 0 for the purposes of deployments.
|
||||||
|
|
||||||
|
Miners should continue setting the bit in LOCKED_IN phase so uptake is visible, though this has no effect on
|
||||||
|
consensus rules.
|
||||||
|
|
||||||
|
### New consensus rules
|
||||||
|
|
||||||
|
The new consensus rules for each soft fork are enforced for each block that has ACTIVE state.
|
||||||
|
|
||||||
|
### State transitions
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
The genesis block has state DEFINED for each deployment, by definition.
|
||||||
|
|
||||||
|
State GetStateForBlock(block) {
|
||||||
|
if (block.height == 0) {
|
||||||
|
return DEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
All blocks within a retarget period have the same state. This means that if
|
||||||
|
floor(block1.height / 2016) = floor(block2.height / 2016), they are guaranteed to have the same state for every
|
||||||
|
deployment.
|
||||||
|
|
||||||
|
if ((block.height % 2016) != 0) {
|
||||||
|
return GetStateForBlock(block.parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
Otherwise, the next state depends on the previous state:
|
||||||
|
|
||||||
|
switch (GetStateForBlock(GetAncestorAtHeight(block, block.height - 2016))) {
|
||||||
|
|
||||||
|
We remain in the initial state until either we pass the start time or the timeout. GetMedianTimePast in the code below
|
||||||
|
refers to the median nTime of a block and its 10 predecessors. The expression GetMedianTimePast(block.parent) is
|
||||||
|
referred to as MTP in the diagram above, and is treated as a monotonic clock defined by the chain.
|
||||||
|
|
||||||
|
case DEFINED:
|
||||||
|
if (GetMedianTimePast(block.parent) >= timeout) {
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
if (GetMedianTimePast(block.parent) >= starttime) {
|
||||||
|
return STARTED;
|
||||||
|
}
|
||||||
|
return DEFINED;
|
||||||
|
|
||||||
|
After a period in the STARTED state, if we're past the timeout, we switch to FAILED. If not, we tally the bits set,
|
||||||
|
and transition to LOCKED_IN if a sufficient number of blocks in the past period set the deployment bit in their
|
||||||
|
version numbers. The threshold is ≥1916 blocks (95% of 2016), or ≥1512 for testnet (75% of 2016).
|
||||||
|
The transition to FAILED takes precedence, as otherwise an ambiguity can arise.
|
||||||
|
There could be two non-overlapping deployments on the same bit, where the first one transitions to LOCKED_IN while the
|
||||||
|
other one simultaneously transitions to STARTED, which would mean both would demand setting the bit.
|
||||||
|
|
||||||
|
Note that a block's state never depends on its own nVersion; only on that of its ancestors.
|
||||||
|
|
||||||
|
case STARTED:
|
||||||
|
if (GetMedianTimePast(block.parent) >= timeout) {
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
int count = 0;
|
||||||
|
walk = block;
|
||||||
|
for (i = 0; i < 2016; i++) {
|
||||||
|
walk = walk.parent;
|
||||||
|
if (walk.nVersion & 0xE0000000 == 0x20000000 && (walk.nVersion >> bit) & 1 == 1) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count >= threshold) {
|
||||||
|
return LOCKED_IN;
|
||||||
|
}
|
||||||
|
return STARTED;
|
||||||
|
|
||||||
|
After a retarget period of LOCKED_IN, we automatically transition to ACTIVE.
|
||||||
|
|
||||||
|
case LOCKED_IN:
|
||||||
|
return ACTIVE;
|
||||||
|
|
||||||
|
And ACTIVE and FAILED are terminal states, which a deployment stays in once they're reached.
|
||||||
|
|
||||||
|
case ACTIVE:
|
||||||
|
return ACTIVE;
|
||||||
|
|
||||||
|
case FAILED:
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
**Implementation**
|
||||||
|
|
||||||
|
It should be noted that the states are maintained along block chain
|
||||||
|
branches, but may need recomputation when a reorganization happens.
|
||||||
|
|
||||||
|
Given that the state for a specific block/deployment combination is completely determined by its ancestry before the
|
||||||
|
current retarget period (i.e. up to and including its ancestor with height block.height - 1 - (block.height % 2016)),
|
||||||
|
it is possible to implement the mechanism above efficiently and safely by caching the resulting state of every multiple-of-2016
|
||||||
|
block, indexed by its parent.
|
||||||
|
|
||||||
|
### Warning mechanism
|
||||||
|
|
||||||
|
To support upgrade warnings, an extra "unknown upgrade" is tracked, using the "implicit bit" mask = (block.nVersion & ~expectedVersion) != 0. Mask will be non-zero whenever an unexpected bit is set in nVersion. Whenever LOCKED_IN for the unknown upgrade is detected, the software should warn loudly about the upcoming soft fork. It should warn even more loudly after the next retarget period (when the unknown upgrade is in the ACTIVE state).
|
||||||
|
|
||||||
|
### getblocktemplate changes
|
||||||
|
|
||||||
|
The template request Object is extended to include a new item:
|
||||||
|
|
||||||
|
**template request**
|
||||||
|
|
||||||
|
| Key | Required | Type | Description |
|
||||||
|
|------|-----------|-------|---------------|
|
||||||
|
| rules | No | Array of Strings | list of supported softfork deployments, by name |
|
||||||
|
|
||||||
|
The template Object is also extended:
|
||||||
|
|
||||||
|
**template**
|
||||||
|
|
||||||
|
| Key | Required | Type | Description |
|
||||||
|
|------|-----------|-------|---------------|
|
||||||
|
| rules | Yes | Array of Strings | list of softfork deployments, by name, that are active state |
|
||||||
|
| vbavailable | Yes | Object | set of pending, supported softfork deployments; each uses the softfork name as the key, and the softfork bit as its value |
|
||||||
|
| vbrequired | No | Number | bit mask of softfork deployment version bits the server requires enabled in submissions |
|
||||||
|
|
||||||
|
The "version" key of the template is retained, and used to indicate the server's preference of deployments.
|
||||||
|
If versionbits is being used, "version" MUST be within the versionbits range of [0x20000000...0x3FFFFFFF].
|
||||||
|
Miners MAY clear or set bits in the block version WITHOUT any special "mutable" key, provided they are listed among the template's "vbavailable" and (when clearing is desired) NOT included as a bit in "vbrequired".
|
||||||
|
|
||||||
|
Softfork deployment names listed in "rules" or as keys in "vbavailable" may be prefixed by a '!' character.
|
||||||
|
Without this prefix, GBT clients may assume the rule will not impact usage of the template as-is; typical examples of this would be when previously valid transactions cease to be valid, such as BIPs [16](/protocol/forks/bip-0016), [65](/protocol/forks/bip-0065), [66](/protocol/forks/bip-0066), [68](/protocol/forks/bip-0068), [112](/protocol/forks/bip-0112), and [113](/protocol/forks/bip-0113).
|
||||||
|
If a client does not understand a rule without the prefix, it may use it unmodified for mining.
|
||||||
|
On the other hand, when this prefix is used, it indicates a more subtle change to the block structure or generation transaction; examples of this would be BIP 34 (because it modifies coinbase construction) and 141 (since it modifies the txid hashing and adds a commitment to the generation transaction).
|
||||||
|
A client that does not understand a rule prefixed by '!' must not attempt to process the template, and must not attempt to use it for mining even unmodified.
|
||||||
|
|
||||||
|
## Support for future changes
|
||||||
|
|
||||||
|
The mechanism described above is very generic, and variations are possible for future soft forks. Here are some ideas that can be taken into account.
|
||||||
|
|
||||||
|
**Modified thresholds**
|
||||||
|
|
||||||
|
The 1916 threshold (based on in BIP 34's 95%) does not have to be maintained for eternity, but changes should take the effect on the warning system into account. In particular, having a lock-in threshold that is incompatible with the one used for the warning system may have long-term effects, as the warning system cannot rely on a permanently detectable condition anymore.
|
||||||
|
|
||||||
|
**Conflicting soft forks**
|
||||||
|
At some point, two mutually exclusive soft forks may be proposed. The naive way to deal with this is to never create software that implements both, but that is making a bet that at least one side is guaranteed to lose. Better would be to encode "soft fork X cannot be locked-in" as consensus rule for the conflicting soft fork - allowing software that supports both, but can never trigger conflicting changes.
|
||||||
|
|
||||||
|
**Multi-stage soft forks**
|
||||||
|
Soft forks right now are typically treated as booleans: they go from an inactive to an active state in blocks. Perhaps at some point there is demand for a change that has a larger number of stages, with additional validation rules that get enabled one by one. The above mechanism can be adapted to support this, by interpreting a combination of bits as an integer, rather than as isolated bits. The warning system is compatible with this, as (nVersion & ~nExpectedVersion) will always be non-zero for increasing integers.
|
||||||
|
|
||||||
|
## Rationale
|
||||||
|
|
||||||
|
The failure timeout allows eventual reuse of bits even if a soft fork was
|
||||||
|
never activated, so it's clear that the new use of the bit refers to a
|
||||||
|
new BIP. It's deliberately very coarse-grained, to take into account
|
||||||
|
reasonable development and deployment delays. There are unlikely to be
|
||||||
|
enough failed proposals to cause a bit shortage.
|
||||||
|
|
||||||
|
The fallow period at the conclusion of a soft fork attempt allows some
|
||||||
|
detection of buggy clients, and allows time for warnings and software
|
||||||
|
upgrades for successful soft forks.
|
||||||
|
|
||||||
|
## Deployments
|
||||||
|
|
||||||
|
~~A living list of deployment proposals can be found [here](https://github.com/bitcoin/bips/blob/master/bip-0009/assignments.mediawiki)~~.
|
||||||
|
|
||||||
|
## Copyright
|
||||||
|
|
||||||
|
This document is placed in the public domain.
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
# BIP-0133
|
||||||
|
|
||||||
|
BIP: 133
|
||||||
|
Layer: Peer Services
|
||||||
|
Title: feefilter message
|
||||||
|
Author: Alex Morcos <morcos@chaincode.com>
|
||||||
|
Comments-Summary: No comments yet.
|
||||||
|
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0133
|
||||||
|
Status: Draft
|
||||||
|
Type: Standards Track
|
||||||
|
Created: 2016-02-13
|
||||||
|
License: PD
|
||||||
|
|
||||||
|
# Abstract
|
||||||
|
|
||||||
|
Add a new message, "feefilter", which serves to instruct peers not to send "inv"'s to the node for transactions with fees below the specified fee rate.
|
||||||
|
|
||||||
|
## Motivation
|
||||||
|
|
||||||
|
The concept of a limited mempool was introduced in Bitcoin Core 0.12 to provide protection against attacks or spam transactions of low fees that are not being mined. A reject filter was also introduced to help prevent repeated requests for the same transaction that might have been recently rejected for insufficient fee. These methods help keep resource utilization on a node from getting out of control.
|
||||||
|
|
||||||
|
However, there are limitations to the effectiveness of these approaches. The reject filter is reset after every block which means transactions that are inv'ed over a longer time period will be rerequested and there is no method to prevent requesting the transaction the first time. Furthermore, inv data is sent at least once either to or from each peer for every transaction accepted to the mempool and there is no mechanism by which to know that an inv sent to a given peer would not result in a getdata request because it represents a transaction with too little fee.
|
||||||
|
|
||||||
|
After receiving a feefilter message, a node can know before sending an inv that a given transaction's fee rate is below the minimum currently required by a given peer, and therefore the node can skip relaying an inv for that transaction to that peer.
|
||||||
|
|
||||||
|
## Specification
|
||||||
|
|
||||||
|
- The feefilter message is defined as a message containing an int64_t where pchCommand == "feefilter"
|
||||||
|
- Upon receipt of a "feefilter" message, the node will be permitted, but not required, to filter transaction invs for transactions that fall below the feerate provided in the feefilter message interpreted as satoshis per kilobyte.
|
||||||
|
- The fee filter is additive with a bloom filter for transactions so if an SPV client were to load a bloom filter and send a feefilter message, transactions would only be relayed if they passed both filters.
|
||||||
|
- Inv's generated from a mempool message are also subject to a fee filter if it exists.
|
||||||
|
- Feature discovery is enabled by checking protocol version >= 70013
|
||||||
|
|
||||||
|
## Considerations
|
||||||
|
The propagation efficiency of transactions across the network should not be adversely affected by this change. In general, transactions which are not accepted to a node's mempool are not relayed by this node and the functionality implemented with this message is meant only to filter those transactions. There could be a small number of edge cases where a node's mempool min fee is actually less than the filter value a peer is aware of and transactions with fee rates between these values will now be newly inhibited.
|
||||||
|
|
||||||
|
Feefilter messages are not sent to whitelisted peers if the "-whitelistforcerelay" option is set. In that case, transactions are intended to be relayed even if they are not accepted to the mempool.
|
||||||
|
|
||||||
|
There are privacy concerns with deanonymizing a node by the fact that it is broadcasting identifying information about its mempool min fee. To help ameliorate this concern, the implementation quantizes the filter value broadcast with a small amount of randomness, in addition, the messages are broadcast to different peers at individually randomly distributed times.
|
||||||
|
|
||||||
|
If a node is using prioritisetransaction to accept transactions whose actual fee rates might fall below the node's mempool min fee, it may want to consider disabling the fee filter to make sure it is exposed to all possible txid's.
|
||||||
|
|
||||||
|
## Backward compatibility
|
||||||
|
|
||||||
|
Older clients remain fully compatible and interoperable after this change. Also, clients implementing this BIP can choose to not send any feefilter messages.
|
||||||
|
|
||||||
|
## Implementation
|
||||||
|
|
||||||
|
https://github.com/bitcoin/bitcoin/pull/7542
|
||||||
|
|
||||||
|
## Copyright
|
||||||
|
This document is placed in the public domain.
|
||||||
@@ -0,0 +1,205 @@
|
|||||||
|
# CHIP: Multiple OP_RETURNs for Bitcoin Cash
|
||||||
|
|
||||||
|
This CHIP was included in [HF-20210515](/protocol/forks/hf-20210515).
|
||||||
|
|
||||||
|
Title: Multiple OP_RETURNs for Bitcoin Cash
|
||||||
|
First Submission Date: 2021-03-12
|
||||||
|
Owner: Benjamin Scherrey @proteusguy on Telegram
|
||||||
|
Authors: Benjamin Scherrey
|
||||||
|
Earlier concept - Jonathan Silverblood
|
||||||
|
Technical spec - BigBlockIfTrue
|
||||||
|
Type: Technical
|
||||||
|
Is consensus change: No
|
||||||
|
Status: FINAL
|
||||||
|
Last Edit Date: 2021-05-17
|
||||||
|
|
||||||
|
## Discussions
|
||||||
|
|
||||||
|
[CHIP Discussion at Bitcoincashresearch.org](https://bitcoincashresearch.org/t/multiple-op-returns-this-time-for-real/315)
|
||||||
|
|
||||||
|
[Issues/PRs for this CHIP](https://github.com/ActorForth/Auction-Protocol/issues)
|
||||||
|
|
||||||
|
Our team is available for chat on the [ActorForth gitter](https://gitter.im/ActorForth/community).
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
We propose to make presence of multiple OP_RETURN outputs qualify as standard transactions subject to the existing 223 byte limit for OP_RETURNs across all outputs of the transaction. We are silent in this proposal as to whether or not the [223 byte limit](https://github.com/bitcoincashorg/bitcoincash.org/blob/1b2008d3ac2b30a2ab26193dc8d3652fc33fb798/spec/may-2018-hardfork.md) is the correct one for BCH but are content to leave that alone in order to improve the chances of getting consensus for this change for the May 2021 fork. This makes the impact on nodes and miners as minimal and risk-free as possible while allowing developers to use OP_RETURN in a manner that justifies its core benefit - experimentation of new features/protocol updates without breaking existing systems or stressing the block chain with extraneous UTXOs which is an undesirable alternative option should this improvement not be accepted.
|
||||||
|
|
||||||
|
## Motivation and Benefits
|
||||||
|
|
||||||
|
Quite early in Bitcoin history, attempts to inject miscellaneous data into the block chain were made that made correct parsing and identification of transactions more difficult but, most importantly, bloated the UTXOs with superfluous data that potentially had a very real negative impact on operators of nodes, miners, and wallet users. The introduction of OP_RETURN with a restricted size limit that was deemed unspendable by the protocol was the compromise that protected everyone's interests. Allowing this data to be inserted but then also ignored by all who didn't care about it gave BCH developers an excellent tool in which to try out development ideas and protocol improvements in an isolated manner without introducing backwards or forward incompatibilities. Perhaps more importantly, it gave the entire BCH community an experimental model that allowed a natural maturity for protocol proposals to mature informed by actual use on the block chain rather than depend entirely on theoretical opinions on how such a protocol change might impact the BCH chain. SLP is an excellent example of such a circumstance where, after considerable efforts and real-life trials have been made, has resulted in serious proposals such as OP_GROUP to be able to be realistically considered for incorporation into the core protocol with significantly less risk than would otherwise have been possible.
|
||||||
|
|
||||||
|
The primary limitation of OP_RETURN is that the protocol standard only allows for one instance of an OP_RETURN output per transaction which means developers who want to build on top of other OP_RETURN utilizing capabilities must either create complex parsing scripts or divide their efforts across multiple transactions. Both of these options introduce incredible complexity and often are simply not viable for demonstrating a real-world use case for how the feature would behave on the BCH chain should it be incorporated into the core protocol.
|
||||||
|
|
||||||
|
This proposal aims to correct this minor oversight in order to bring the full potential of OP_RETURN's experimental expressiveness to the BCH chain without incurring any additional trade-offs that were part of its original design.
|
||||||
|
|
||||||
|
The benefits of this proposal also reach users and businesses in drastically reducing foodprint when dealing with several OP_RETURN for their given use cases. Users will be able to use OP_RETURN space more efficiently, pack information in fewer transactions, use less space in mined blocks and save fees while mempool will see fewer congestions –for this specific cause.
|
||||||
|
|
||||||
|
## Specification
|
||||||
|
|
||||||
|
The only technical elements we've identified are changes to the existing node systems to remove the limit of a single OP_RETURN and to enforce the existing size limit for OP_RETURN based outputs across all aggregate OP_RETURN outputs in the transaction.
|
||||||
|
|
||||||
|
Formally, we set the rules as follows:
|
||||||
|
|
||||||
|
* An OP_RETURN output is an output with a locking script consisting of the OP_RETURN opcode followed by zero or more data pushes.
|
||||||
|
* A transaction is non-standard if the total byte size of the locking scripts of all OP_RETURN outputs is greater than 223.
|
||||||
|
* While the [BIP113](https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki) median time is less than 1621080000 (2021-05-15T12:00:00Z), a transaction is also non-standard if the number of OP_RETURN outputs is greater than one.
|
||||||
|
|
||||||
|
Some remarks:
|
||||||
|
|
||||||
|
* The size of the locking script is not just the raw data size, but includes the OP_RETURN opcode and the data push opcodes. In case of a single OP_RETURN output, only up to 220 bytes of data can be stored, because you need 1 byte for the OP_RETURN opcode, 1 byte for the OP_PUSHDATA1 opcode, and 1 byte for the length of the data. More bytes are lost if there is more than one data push operation, e.g. when the [4-byte prefix guideline](https://upgradespecs.bitcoincashnode.org/op_return-prefix-guideline/) is followed.
|
||||||
|
* In case of a single OP_RETURN output, the rules are identical to the status quo.
|
||||||
|
* In the extreme case, the rules imply a maximum of 223 OP_RETURN outputs, because the locking script of every OP_RETURN output is at least one byte (the OP_RETURN opcode itself).
|
||||||
|
|
||||||
|
## Current Implementations
|
||||||
|
|
||||||
|
* [Full implementation of the rules in Bitcoin Cash Node, including activation logic](https://gitlab.com/bitcoin-cash-node/bitcoin-cash-node/-/merge_requests/1115).
|
||||||
|
* [Implementation of the rules in Flowee, without activation logic](https://gitlab.com/FloweeTheHub/thehub/-/blob/master/libs/server/policy/policy.cpp) (allows multiple outputs immediately instead of only after 2021-05-15T12:00:00Z).
|
||||||
|
|
||||||
|
Both implementations introduce `"oversize-op-return"` as a new standardness error code, besides the existing `"multi-op-return"` error which becomes obsolete after multiple OP_RETURN outputs are allowed. In both implementations, the number 223 used in the rules can be overridden with the `-datacarriersize=<n>` command-line option.
|
||||||
|
|
||||||
|
* [Implementation of the rules in Bitcoin Unlimited, without activation logic](https://gitlab.com/bitcoinunlimited/BCHUnlimited/-/merge_requests/2453).
|
||||||
|
|
||||||
|
|
||||||
|
## Implementation Costs and Risks
|
||||||
|
|
||||||
|
Evaluating the changes required across the popular nodes demonstrates that the impact in terms of lines of code affected are minor and isolated. For Bitcoin Unlimited there's an existing check that only one OP_RETURN exists which can be removed. A mechanism for counting the aggregate size of all the OP_RETURNs is quite simple to introduce in the same source file. Unit tests would be approximately twice the implementation size which we find typical of well designed C++ code.
|
||||||
|
|
||||||
|
APIs that want to support multiple OP_RETURN are also easy to modify.
|
||||||
|
|
||||||
|
## Ongoing Costs and Risks
|
||||||
|
|
||||||
|
After the initial changes are made to the core node systems no ongoing costs are anticipated. Risks are restricted to other non-standard experimental development code that may depend/demand that there only be a single OP_RETURN but, unless the code serves some purpose such as a linter or tx compliance tool, it's unlikely that such code was appropriate in the first place.
|
||||||
|
|
||||||
|
Presently the [SLP specification](https://github.com/simpleledger/slp-specifications/blob/master/slp-token-type-1.md#consensus-rules) requires its OP_RETURN to be at vout[0]. Any protocol code seeking to co-exist with SLP would want to ensure that it be in a later output to appear in the transaction in order to prevent accidental conflicts. We recommend that OP_RETURN based protocols no longer specify a positional requirement for their data but, instead, establish another mechanism for identifying which OP_RETURN belongs to them.
|
||||||
|
|
||||||
|
Now that the limit of a single OP_RETURN has been removed, future well behaved development utilizing OP_RETURN would no longer be designed with such a presumption in mind.
|
||||||
|
|
||||||
|
### Design & Implementation Process Timeline
|
||||||
|
|
||||||
|
2020-09-21 [Initial comment on bitcoincashresearch.org](https://bitcoincashresearch.org/t/2021-bch-upgrade-items-brainstorm/130/23).
|
||||||
|
|
||||||
|
2020-10-14 [Trial implementation of proposal on Bitcoin Unlimited node](https://github.com/ActorForth/BitcoinUnlimited/commit/fd10cbd9872b157d906a03d3a4ccf7c0ddd42c65). (note: this doesn't implement aggregate size limit)
|
||||||
|
|
||||||
|
2020-10-?? Trial modifications to a [test fork of the Javascript bch-js API](https://github.com/ActorForth/bch-js) and the python Bitcash API libraries (currently in a private repo) completed.
|
||||||
|
|
||||||
|
2021-02-24 [Proposal to be introduced for the May 2021 fork](https://bitcoincashresearch.org/t/multiple-op-returns-this-time-for-real/315).
|
||||||
|
|
||||||
|
2021-03-21 This CHIP created.
|
||||||
|
|
||||||
|
2021-03-24 Proposed completion for PRs to public Bitcoin Unlimited, Bitcoin Cash Node, bch-js API, and Bitcash API projects to support this CHIP. Basically T+9 days after proposal is approved.
|
||||||
|
|
||||||
|
2021-03-13 [Flowee PR](https://gitlab.com/FloweeTheHub/thehub/-/commit/a9d3c2ee9279f2aa46890d74ce26f6e252623e72), [2](https://gitlab.com/FloweeTheHub/thehub/-/commit/45dd785f3916caa336a628d879dc7228fb73e520) support implemented by Tom Zander.
|
||||||
|
|
||||||
|
2021-03-14 [BCHN PR](https://gitlab.com/bitcoin-cash-node/bitcoin-cash-node/-/merge_requests/1115) support implemented by BigBlockIfTrue.
|
||||||
|
|
||||||
|
2021-03-25 [Bitcoin Unlimited PR](https://gitlab.com/bitcoinunlimited/BCHUnlimited/-/merge_requests/2453) support implemented by Nicolai Skye.
|
||||||
|
|
||||||
|
2021-05-15 Deployment to BCH Mainnet Chain
|
||||||
|
|
||||||
|
## Evaluation of Alternatives
|
||||||
|
|
||||||
|
Alternatives to this proposal amount to restating original alternatives to OP_RETURN (such as the multi-sig data hack), introducing complex parsing requirements to OP_RETURN outputs, or dividing OP_RETURN dependent submissions across multiple transactions. All are more complex and risky than this proposal.
|
||||||
|
|
||||||
|
Jonathan Silverblood identified 3 other alternative proposals considered in 2020, [BUIP149: Delimited OP_RETURNs](https://bitco.in/forum/threads/buip149-delimited-op_returns.26362/), [BUIP139](https://bitco.in/forum/threads/buip139-multiple-op_return-with-less-rules.24951/), and [BUIP140](https://bitco.in/forum/threads/buip140-multiple-op_return-with-shared-size-limit.24952/).
|
||||||
|
|
||||||
|
BUIP149 puts multiple OP_RETURNs in a single output and requires complex parsing scripts and potentially could collide with existing protocols using OP_RETURNs already including SLP. It also proposes to change the maximum size of OP_RETURN data in a transaction. Community efforts to incorporate this option are significantly higher than this CHIP.
|
||||||
|
|
||||||
|
BUIP139 is actually quite similar to this CHIP except it proposes that there be some fixed limit to the number of OP_RETURNs. One reason why BUIP139 should be considered inferior is because it makes it more difficult to change the op_return max bytes in the future, as it would magnify the impact, for example:
|
||||||
|
|
||||||
|
If BUIP139 took place, and was set to 4 op_returns / transaction, then if we want to change the byte size it now has to be an even number of 4. If we naively increase by 10 bytes, then a total of 40 more bytes can be used, rather than the 10 byte intended.
|
||||||
|
|
||||||
|
BUIP140 is similar to this CHIP but was just not taken forward. Major difference is that it debates or introduces the explicit possibility of increasing the total size of OP_RETURN data but does not require it.
|
||||||
|
|
||||||
|
Without the aggregate size consideration, the future impact of changing the legal sizes of OP_RETURN becomes more profound and possibly difficult to predict but saves tx creators from having to track a total across all OP_RETURNs. The opinion of the author is that the days of being able to consider parts of transactions independent of others are long gone so this is not a meaningful shortcoming. Size reductions would be profound and dangerous changes and are unlikely to be practical to deploy. Size increases should be based on empirical demonstrations of value through experimental apps that push these limits while demonstrating real value to the BCH ecosystem. Regardless of the ultimate size, having that quantity come from a shared pool helps allow OP_RETURN based protocols to be expressed naturally in a manner more closely resembling what their ultimate core protocol implementations would look like rather than having to perform hacks to fit within a per-OP_RETURN limit that would necessarily be smaller. Again these are future considerations outside of the direct scope of this CHIP.
|
||||||
|
|
||||||
|
## List of Major Stakeholders
|
||||||
|
|
||||||
|
|
||||||
|
## Statements
|
||||||
|
|
||||||
|
### Full node developers
|
||||||
|
|
||||||
|
from Tom Zander, owner [Flowee](https://flowee.org)
|
||||||
|
|
||||||
|
> This change will have little to no cost on our ecosystem while enabling more usecases to be added over time, to be developed without touching consensus rules in the traditional permissionless manner. I fully support this proposal and have code ready to ship for this.
|
||||||
|
|
||||||
|
from freetrader, lead maintainer of Bitcoin Cash Node
|
||||||
|
|
||||||
|
> This is a simple and logical change that provides more flexibility for OP_RETURN users without affecting the trade-offs associated with the limit. The proposal has been implemented in a BCHN change request and a majority of BCHN maintainers supports activating this change on 15 May 2021.
|
||||||
|
|
||||||
|
> While this CHIP arrived at a fairly late moment, we believe that sufficient awareness has been raised such that it can nevertheless be activated in May provided all major full node clients can implement it by then.
|
||||||
|
|
||||||
|
### Major businesses
|
||||||
|
|
||||||
|
from Benjaim Scherrey
|
||||||
|
|
||||||
|
> My company, [Biggest Fan Productions](https://biggestfan.net), has developed a [protocol](https://github.com/ActorForth/Auction-Protocol/blob/main/proposal-spec.md) that utilizes SLP NFTs & FTs to perform on-chain tracked open call auctions for assets such as concert tickets. To fully be able to represent the state of the auction in a trustless manner it requires an additional OP_RETURN to be allowed in BCH transactions. This is notice of my support and personal interest in this CHIP.
|
||||||
|
|
||||||
|
### Miners and pools
|
||||||
|
|
||||||
|
I have sought out contacts for such organizations and have received no responses. Appreciate any follow up on contacting these entities.
|
||||||
|
|
||||||
|
### Wallets and clients
|
||||||
|
|
||||||
|
I have sought out contacts for such organizations and have received few responses. Appreciate any follow up on contacting these entities.
|
||||||
|
|
||||||
|
An ElectronCash SLP wallet dev had no strong opinion on this CHIP (or the CHIP process) and registered no objection when asked.
|
||||||
|
|
||||||
|
### Application Developers
|
||||||
|
|
||||||
|
from Jonathan Silverblood:
|
||||||
|
|
||||||
|
> I believe multiple OP_RETURNs should be adopted, it is highly valuable as it makes it possible for OP_RETURN based protocols to work together to create value. I also believe that counting the aggregate number of bytes is in line with the intent of the original functionality.
|
||||||
|
|
||||||
|
from Joey Masterpig
|
||||||
|
|
||||||
|
> I would like to add my support to this proposal as a Stakeholder. Founder of the upcoming SLP NFT game enter-the-sphere.com . Co-Founder of Spice Token, and a Director of the SLP Foundation.
|
||||||
|
|
||||||
|
> I believe having multiple_opreturns will add some interesting possibilities for NFTs for Enter The Sphere, our token solution needs to be as competitive as possible, and anything that expands the chance of something innovative being done on SLP, is something I support.
|
||||||
|
|
||||||
|
> As I understand, implementation of this change will allow multiple assets to be on a single tx, something that can be very useful for pairing NFTs with other assets. A function that allows us to link NFT items with other assets easier than current.
|
||||||
|
|
||||||
|
> This is my personal opinion and support as a non-technical stakeholder, this is not a technical endorsement nor have i reviewed deeply about whether these changes have cons on a technical basis (as far as I understand there is none).
|
||||||
|
|
||||||
|
Stoyan Zhekov, bch-js developer
|
||||||
|
|
||||||
|
> I think Multiple OP_RETURN CHIP will provide a way for better NFTs - both NFT (SLP) payload and BCP payload can be parts of one transaction, which will reduce the number of queries to retrieve the external content.
|
||||||
|
|
||||||
|
### Users
|
||||||
|
|
||||||
|
from Leandro Di Marco
|
||||||
|
|
||||||
|
> I see this initiative with great value for users, who will engage with the OP_RETURN resource more efficiently. And while such optimization would seem samll at the moment, it will surely become more relevant as Bitcoin Cash grows in adoption.
|
||||||
|
|
||||||
|
## Copyright
|
||||||
|
|
||||||
|
BSD 3-Clause License
|
||||||
|
|
||||||
|
Copyright (c) 2018, 2020 Benjamin Scherrey, BiggestFan Productions Co. Ltd
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
# CHIP: Unconfirmed Transaction Chain Limit
|
||||||
|
|
||||||
|
This CHIP was included in [HF-20210515](/protocol/forks/hf-20210515).
|
||||||
|
|
||||||
|
## Authors
|
||||||
|
|
||||||
|
**CHIP Owner:**
|
||||||
|
Josh Green, Software Verde
|
||||||
|
|
||||||
|
**Contributors:**
|
||||||
|
|
||||||
|
John Jamiel, Software Verde
|
||||||
|
Doug McCollough, City of Dublin, OH
|
||||||
|
Emil Oldenburg, Bitcoin.com
|
||||||
|
Roger Ver, Bitcoin.com
|
||||||
|
Mark Lamb, CoinFLEX
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
**Version 1.2.1**
|
||||||
|
|
||||||
|
When a transaction is first transmitted on the Bitcoin Cash network, it is considered “unconfirmed” until it is “mined” into a block. These transactions that are not yet mined are also referred to as “zero-conf” transactions. Transactions are dependent upon other transactions, such that they are chained together; the value allocated by one transaction is then spent by a subsequent transaction.
|
||||||
|
|
||||||
|
Currently, the Bitcoin Cash network only permits transactions to be chained together 50 times before a block must include them. Transactions exceeding the 50th chain are often ignored by the network, despite being valid. Once a transaction is submitted to the network, it cannot be revoked. This situation, when encountered, can be extremely difficult to remedy with today’s available tools and simultaneously creates an unnecessary amount of complexity when being accounted for by network and applications developers. This CHIP is a formal request to remove the unconfirmed transaction chain limit=depth (50tx) and size (101kb) entirely from the Bitcoin Cash ecosystem.
|
||||||
|
|
||||||
|
**Discussion URL:** https://bitcoincashresearch.org/t/chip-unconfirmed-transaction-chain-limit/302/32
|
||||||
|
|
||||||
|
**Full Change History URL:** https://github.com/softwareverde/bitcoin-cash-chips/blob/master/unconfirmed-transaction-chain-limit.md
|
||||||
|
|
||||||
|
|
||||||
|
## Motivations
|
||||||
|
|
||||||
|
Transactions exceeding the unconfirmed transaction chaining limit are often ignored by the network, despite being considered a valid transaction. For these transactions, this leaves the value transferred in an ambiguous state: it has been transferred, but some (or all) of the network may not record this transfer. Once value has been transferred by a transaction, the balance may not be distributed in a different proportion or to a separate receiver (often known as a “double-spend”) due to the network’s convention to prefer the first-seen transfer rather than the newer transfer. Therefore, the only viable path forward in this scenario is to transmit the same (perfectly identical) transaction again to the network. However, if the wallet or service is connected to peers that accepted the transaction, rebroadcasting the same transaction does not cause the connected peers to retransmit it themselves--causing the transaction to be stuck with no recourse other than hoping to connect to a new peer that has not yet seen the transaction. For this reason, it is important that all nodes agree on the unconfirmed transaction chain limit.
|
||||||
|
|
||||||
|
Additionally, determining if the transaction was not accepted by the network is a difficult to solve problem with the current available toolset. Error-responses from nodes rejecting a transaction have not been standardized, and often times nodes will silently reject the transaction--sometimes the node may not even be aware that the transaction is invalid because its dependent has not been seen yet, and the node itself cannot determine the transaction’s chain depth.
|
||||||
|
|
||||||
|
It is also not always known to the user, service, or wallet how deep the unconfirmed transaction already is when it’s received; it’s entirely possible the coins received are at the limit, and determining that state can be near-impossible without the help of a full-node.
|
||||||
|
|
||||||
|
The problem from a user/app’s perspective is that they have created a valid transaction and are given little indication that it will not be mined within a block. The tools for recourse are limited, and the tools for monitoring for such a situation is also limited.
|
||||||
|
|
||||||
|
|
||||||
|
The unconfirmed transaction chain limit is mostly an artifact of a relatively unused feature heldover from artificially restricting block size, a feature called “Child Pays for Parent”. According to research conducted by Tom Zander found [here](https://flowee.org/news/2020-07-cpfp-research/), there is very limited usage of CPfP on the BCH network. In short, in his 3 months of monitoring network activity there were only 7 valid use cases where CPfP was used to lift the transaction above the 1-sat-per-byte. This feature is not used in BCH yet still restricts the user experience and increases the complexity of development of wallets and applications built on top of Bitcoin Cash.
|
||||||
|
|
||||||
|
Issues with transaction chaining are exacerbated by the long block times periodically seen in Bitcoin Cash, the causes of which have been discussed elsewhere and were a major motivating factor in switching to the ASERT difficult adjustment algorithm. Having a static transaction chaining limit while blocks somewhat frequently take over an hour (or even two hours) to be mined, results in a scenario where transactions could be significantly more at risk than normal. Note, though, that even without these extenuating circumstances, this is always a risk with the proof of work system.
|
||||||
|
|
||||||
|
Given the motivations for implementing the transaction chaining limit are largely no longer relevant, the lack of sufficient tooling to allow SPV clients to account for it, and its poor interaction with the current semantics of transaction relaying, it appears that the transaction chaining limit provides little value while simultaneously increasing the difficulty of transacting on the Bitcoin Cash network.
|
||||||
|
|
||||||
|
**Personal Impacts**
|
||||||
|
|
||||||
|
During a Dublin Identity beta test with real users, an issue occurred causing sign-ups to periodically fail. After investigation, it was identified that users’ transactions from the server used to fund SLP token transfers were not being accepted by the network due to the transaction chain limit being enforced. This problem has since been mitigated by the limit being increased to 50, along with some process changes.
|
||||||
|
|
||||||
|
CoinFLEX uses SLP to distribute FLEX token dividends to its users. The server distributes these dividends periodically, via chaining transactions. These distributions were found to periodically fail due to reaching the unconfirmed transaction chaining limit. CoinFLEX is mitigating this problem by using multiple UTXOs to spawn the chains, however their large user base and small limit of 50 transactions per UTXO, are causing disproportionate complexity within their system. Raising the limit combined with increasing the base number of originating UTXOs helps to limit backend complexity. Removing the limit would remove significant complexity for rejection edge-cases where a rejection was unable to be determined or was left unnoticed.
|
||||||
|
|
||||||
|
During Bitcoin Cash meetups it is not uncommon for users of the Bitcoin.com wallet to make more than 50 transactions within the timespan of a block, especially due to the encouraged behavior of brand-new users to transfer their BCH to other members of the meetup to “try it out”. The user experience and “wow” factor of the technology is quickly doused when a new user’s transaction fails to send because their received UTXO is deeply chained. Varying block times exacerbates this problem.
|
||||||
|
|
||||||
|
Software Verde has developed multiple applications that create and distribute transactions across the BCH network. Managing multiple UTXO pools in order to handle appropriately scaling is doable but creates additional unwanted complexity. While transactions will likely never completely be “fire and forget” on BCH, creating a balance with a larger buffer (i.e. supporting a longer chain limit) and having better available tools would allow us to produce applications more reliably and for less cost, facilitating the adoption of Bitcoin Cash to businesses and enterprises.
|
||||||
|
|
||||||
|
|
||||||
|
## Technical Description
|
||||||
|
|
||||||
|
The current policy limit of 50 unconfirmed ancestors or descendants, and the 101kb chain limit, is to be removed entirely once MTP >= 1621080000 and this limit removal remains in affect even in the case of a subsequent re-org to below that MTP.
|
||||||
|
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
Uncoordinated changes to mempool rules would likely result in a degradation of 0-conf transaction security. 0-conf transaction security is dependent on the network’s solution to circumventing double-spends. If nodes do not agree to enforce the same limits, merchants accepting transactions that have exceeded the unconfirmed transaction chaining limit would be at an increased risk of encountering and accepting a double-spend transaction.
|
||||||
|
|
||||||
|
Example: A malicious user submits a transaction exceeding the current chaining limit, knowing the merchant is connected to a node that does not enforce the limit. The node accepts this transaction as it is considered valid and the merchant believes they’ve received a payment from a valid 0-conf transaction. Due to its unconfirmed chain depth, for this transaction to propagate the node in question must wait to broadcast the transaction to its peers until after a new block has been found. During this time a malicious user could prepare a second transaction spending the same coin. If submitted immediately after the new block has been found the two transactions will be in a race. Since the first transaction has not yet been broadcast to the rest of the network, there is an increased likelihood the second transaction could be seen by the majority of the network before the first transaction has had an opportunity to propagate. This situation is exacerbated if the node accepting the longer unconfirmed chain depth transaction does not also re-relay the transaction after a new block is mined that does not contain the transaction.
|
||||||
|
|
||||||
|
|
||||||
|
## Implementation Costs and Risks
|
||||||
|
|
||||||
|
From our research and discussions removal of the Unconfirmed Transaction Chain Limit does not present any apparent risks if conducted in a coordinated manner and presents zero risk of a network split. According to the research conducted by developer FreeTrader of BCHN, there is no apparent loss of performance in BCHN with the limit removed. However, if changes to the mempool rules are not coordinated by the different node implementations, 0-conf transaction facility and security will likely suffer.
|
||||||
|
|
||||||
|
Costs associated with implementing this change are hard to encapsulate in this proposal. At a minimum, this CHIP recognizes there is an operational burden that coordinated network upgrades place on node developers and users. Overall, this change will require a non-negligible amount of development time to implement, translating to a cost of labor, of which is bound to vary depending on the full-node implementation and route to resolution.
|
||||||
|
|
||||||
|
Additionally, the cost of investigating solutions for the unconfirmed transaction chaining limit have been significant for those who have undertaken the task. Based on an informal survey of BU and BCHN members, General Protocols has estimated approximately 500 engineering hours have been invested in development and general investigation of increasing the chained tx limit. This commitment of hours has been useful to understand the potential limitations bounding the limit from being completely removed. After thorough investigation, no ill effect on performance has been found.
|
||||||
|
|
||||||
|
|
||||||
|
## Evaluation of Alternatives
|
||||||
|
|
||||||
|
If it is deemed necessary to keep the unconfirmed transaction chain limit in some capacity then a significantly larger increase to the limit would be a reasonable alternative.
|
||||||
|
|
||||||
|
From our research, there isn’t a resource that becomes exhausted by a deep 0-conf chain. If there is indeed a technical limit, then we would advocate for node-developers to find what a responsible value is for that limit and suggest that here.
|
||||||
|
|
||||||
|
For the purposes of proposing an alternative solution: a 32MB block can hold approximately 135k transactions. This limit could serve as a hypothetical starting point.
|
||||||
|
|
||||||
|
|
||||||
|
## Stakeholders
|
||||||
|
|
||||||
|
Stakeholders relative to this proposal include:
|
||||||
|
|
||||||
|
Full-node implementations
|
||||||
|
Node Developers
|
||||||
|
Wallet Developers
|
||||||
|
Bitcoin Cash related businesses.
|
||||||
|
|
||||||
|
In our previous discussion we have engaged with several key stakeholders to understand their position on the requested change.
|
||||||
|
|
||||||
|
**Stakeholders Engaged in Discussion**
|
||||||
|
|
||||||
|
BCHN
|
||||||
|
Bitcoin Unlimited
|
||||||
|
Bitcoin Verde
|
||||||
|
General Protocols
|
||||||
|
Bitcoin.com
|
||||||
|
Coinflex
|
||||||
|
Flowee
|
||||||
|
General Protocols
|
||||||
|
|
||||||
|
**Stakeholders Position Unknown**
|
||||||
|
|
||||||
|
BCHD
|
||||||
|
Knuth
|
||||||
|
|
||||||
|
## Stakeholders Statements
|
||||||
|
|
||||||
|
Jonathan Silverblood - Casual Wallet
|
||||||
|
>I believe that for money to be useful, it needs to be able to move at low cost and with ease. The current unconfirmed transaction chain limitation is effectively friction that makes Bitcoin Cash less useful as money, and I support a complete removal of the limit.
|
||||||
|
|
||||||
|
John Nieri - General Protocols
|
||||||
|
>GP supports the updated recommendations of this CHIP and commits any reasonable resources toward its realization. There is still room to expand security considerations and costs which are not trivial. Although this is a non-consensus CHIP, the expansion would make it an even better precedent for the high bar that we want to establish in the BCH ecosystem.
|
||||||
|
|
||||||
|
## CHIP Sponsors
|
||||||
|
|
||||||
|
**Software Verde** is a custom software development company based out of Columbus, Ohio, USA that has been in operation since 2011 and working within public and crypto sectors since early 2017. Software Verde has extensive experience working with local governments to promote the adoption of blockchain technology and utilization of cryptocurrencies, and is the author and maintainer of the BCH Full Node, Bitcoin Verde.
|
||||||
|
|
||||||
|
**City of Dublin, OH** is a municipality of approximately 50k residents that has made an investment into the adoption of blockchain technology. In turn, Dublin has built a blockchain-based digital identity management system utilizing BCH SLP tokens as a reward mechanism. In late 2019, Dublin’s identity management project moved into a beta-testing phase where Software Verde was tasked with creating digital IDs for city employees and rewarding them with tokens for their participation.
|
||||||
|
|
||||||
|
**Bitcoin.com** is a provider of Bitcoin Cash related financial services and the owners of the Bitcoin.com wallet, one of Bitcoin Cash’s most popular non-custodial mobile friendly wallets. Their website provides important services such as a cryptocurrency exchange, reporting network related news, and providing information to help influence the growth and adoption of Bitcoin Cash and Bitcoin Cash related businesses.
|
||||||
|
|
||||||
|
**CoinFLEX** is a popular cryptocurrency exchange service as well as the providers of the first Bitcoin Cash futures and lending exchange. CoinFLEX is the primary distributor of Flex Coins, an SLP token used to pay dividends to their users. Their business provides several unique financial services that attract cryptocurrency investors to the network, as well as foster a culture of professional trading within the Bitcoin Cash community.
|
||||||
|
|
||||||
|
## Timeline
|
||||||
|
|
||||||
|
This proposal is low risk and stands to provide high benefit to the network as a whole. In addition, this request is a network-change only and therefore is not at risk of causing a chain split; however, uncoordinated changes to mempool rules by different full-nodes would likely result in a degradation of 0-conf transaction security. For these reasons, it is requested that this change be implemented in a coordinated manner on May 15th.
|
||||||
|
|
||||||
|
Choosing this date in particular is not significant in and of itself, although there seems to be no reason to deviate from history purely for the sake of it.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
To the extent possible under law, this work has waived all copyright and related or neighboring rights to this work under CC0.
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
# HF-20200515
|
||||||
|
|
||||||
|
layout: specification
|
||||||
|
title: 2020-MAY-15 Network Upgrade Specification
|
||||||
|
date: 2020-04-26
|
||||||
|
category: spec
|
||||||
|
activation: 1589544000
|
||||||
|
version: 0.4
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
When the median time past [[1]](#references) of the most recent 11 blocks (MTP-11) is greater than or equal to UNIX timestamp 1589544000 (May 15th, 2020, 12:00PM UTC),
|
||||||
|
Bitcoin Cash will execute an upgrade of the network consensus rules according to this specification.
|
||||||
|
Starting from the next block these consensus rules changes will take effect:
|
||||||
|
|
||||||
|
* Bitcoin Cash's SigOps counting and limiting system is replaced with a new system, referred to as SigChecks.
|
||||||
|
* A new opcode called OP_REVERSEBYTES has been added to the script system.
|
||||||
|
* Enforcement of the Infrastructure Funding Plan, subject to activation by [BIP 9](https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki) miner signalling.
|
||||||
|
|
||||||
|
The following are not consensus changes, but are recommended policy changes for Bitcoin Cash implementations:
|
||||||
|
|
||||||
|
* The default for max number of in-mempool ancestors is changed from 25 to 50.
|
||||||
|
* The default for max number of in-mempool descendants is changed from 25 to 50.
|
||||||
|
* Automatic replay protection for future upgrade.
|
||||||
|
|
||||||
|
## SigChecks
|
||||||
|
|
||||||
|
Enforcement of sigops limits is removed, and replaced with new limits based on the number of signature checks that are actually executed when running a script. This new system is called SigChecks.
|
||||||
|
|
||||||
|
Details can be found in the [full specification: SigChecks](/protocol/forks/2020-05-15-sigchecks).
|
||||||
|
|
||||||
|
## OP_REVERSEBYTES
|
||||||
|
|
||||||
|
This new opcode reverses the order of bytes in a string. It can be used to change endianness.
|
||||||
|
|
||||||
|
Details can be found in the [full specification: OP_REVERSEBYTES](/protocol/forks/2020-05-15-op_reversebytes).
|
||||||
|
|
||||||
|
## Infrastructure Funding Plan
|
||||||
|
|
||||||
|
The purpose of the Infrastructure Funding Plan (IFP) is to provide funding to development projects working on common Bitcoin Cash infrastructure.
|
||||||
|
If activated, it enforces that 5% of the block reward is spent to one of a set of specified addresses.
|
||||||
|
Activation is triggered via [BIP 9](https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki) version bits signalling prior to the May 15 upgrade.
|
||||||
|
|
||||||
|
More detailed can be found in the [full specification](/protocol/forks/2020-05-15-ifp).
|
||||||
|
|
||||||
|
## Automatic Replay Protection
|
||||||
|
|
||||||
|
The purpose of Automatic Replay Protection is to serve as a full node version-deprecation mechanism. It is intended to cause
|
||||||
|
full validating nodes which do not upgrade, to automatically separate themselves from the main network after the next
|
||||||
|
upgrade on 15 May 2020. Nodes which implement the next upgrade will remove this automatic replay protection, and thus all regular
|
||||||
|
wallets can continue using the default ForkID with no change to follow the main upgraded chain.
|
||||||
|
|
||||||
|
When the median time past [[1]](#references) of the most recent 11 blocks (MTP-11) is less than UNIX timestamp 1605441600 (Nov 2020 upgrade)
|
||||||
|
Bitcoin Cash full nodes MUST enforce the following rule:
|
||||||
|
|
||||||
|
* `forkid` [[2]](#references) to be equal to 0.
|
||||||
|
|
||||||
|
When the median time past [[1]](#references) of the most recent 11 blocks (MTP-11) is greater than or equal to UNIX timestamp 1605441600
|
||||||
|
(Nov 2020 upgrade) Bitcoin Cash full nodes implementing the May 2020 consensus rules SHOULD enforce the following change:
|
||||||
|
|
||||||
|
* Update `forkid` [[2]](#references) to be equal to `0xFFXXXX`, where `XXXX` is some arbitrary hex value.
|
||||||
|
ForkIDs beginning with 0xFF will be reserved for future protocol upgrades.
|
||||||
|
|
||||||
|
This particular consensus rule MUST NOT be implemented by Bitcoin Cash wallet software. Wallets that follow the upgrade
|
||||||
|
should not have to change anything.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
[1] Median Time Past is described [here](/protocol/blockchain/transaction#median-time-past).
|
||||||
|
It is guaranteed by consensus rules to be monotonically increasing.
|
||||||
|
|
||||||
|
[2] The `forkId` is defined as per the [replay protected sighash](/protocol/forks/replay-protected-sighash) specification.
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
# HF-20201115
|
||||||
|
|
||||||
|
layout: specification
|
||||||
|
title: 2020-NOV-15 Network Upgrade Specification
|
||||||
|
date: 2020-08-15
|
||||||
|
category: spec
|
||||||
|
activation: 1605441600
|
||||||
|
version: 0.1
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
When the median time past [[1]](#references) of the most recent 11 blocks (MTP-11) is greater than or equal to UNIX timestamp 1605441600 (Nov 15th, 2020, 12:00PM UTC),
|
||||||
|
Bitcoin Cash will execute an upgrade of the network consensus rules according to this specification.
|
||||||
|
Starting from the next block these consensus rules changes will take effect:
|
||||||
|
|
||||||
|
* Bitcoin Cash's Difficulty Adjustment Algorithm (DAA) is replaced with a new system, referred to as aserti3-2d.
|
||||||
|
* The addition of a new coinbase rule.
|
||||||
|
|
||||||
|
The following are not consensus changes, but are recommended policy changes for Bitcoin Cash implementations:
|
||||||
|
|
||||||
|
* Automatic replay protection for future upgrade.
|
||||||
|
|
||||||
|
## Difficulty Adjustment Algorithm
|
||||||
|
|
||||||
|
Bitcoin Cash's Difficulty Adjustment Algorithm (DAA) is replaced with a new algorithm called [ASERT](http://toom.im/files/da-asert.pdf).
|
||||||
|
|
||||||
|
The specific implementation is called aserti3-2d. Details can be found in the [full specification: ASERT](/protocol/forks/2020-11-15-asert).
|
||||||
|
|
||||||
|
## Coinbase Rule
|
||||||
|
|
||||||
|
The purpose of the new coinbase rule is to provide funding to development projects working on common Bitcoin Cash infrastructure.
|
||||||
|
|
||||||
|
The coinbase rule enforces that at least 8% of the block reward must be spent as a single output to the following Bitcoin Cash address:
|
||||||
|
`bitcoincash:pqnqv9lt7e5vjyp0w88zf2af0l92l8rxdgnlxww9j9`.
|
||||||
|
|
||||||
|
The amount of the output must be equal to or greater than the integer `required`, calculated as follows using integer math:
|
||||||
|
```
|
||||||
|
required = (8 * blockReward) / 100
|
||||||
|
```
|
||||||
|
|
||||||
|
## Automatic Replay Protection
|
||||||
|
|
||||||
|
The purpose of Automatic Replay Protection is to serve as a full node version-deprecation mechanism. It is intended to cause
|
||||||
|
full validating nodes which do not upgrade, to automatically separate themselves from the main network after the next
|
||||||
|
upgrade on 15 May 2021. Nodes which implement the next upgrade will remove this automatic replay protection, and thus all regular
|
||||||
|
wallets can continue using the default ForkID with no change to follow the main upgraded chain.
|
||||||
|
|
||||||
|
When the median time past [[1]](#references) of the most recent 11 blocks (MTP-11) is less than UNIX timestamp 1621080000 (May 2021 upgrade)
|
||||||
|
Bitcoin Cash full nodes MUST enforce the following rule:
|
||||||
|
|
||||||
|
* `forkid` [[2]](#references) to be equal to 0.
|
||||||
|
|
||||||
|
When the median time past [[1]](#references) of the most recent 11 blocks (MTP-11) is greater than or equal to UNIX timestamp 1621080000
|
||||||
|
(May 2021 upgrade) Bitcoin Cash full nodes implementing the Nov 2020 consensus rules SHOULD enforce the following change:
|
||||||
|
|
||||||
|
* Update `forkid` [[2]](#references) to be equal to `0xFFXXXX`, where `XXXX` is some arbitrary hex value.
|
||||||
|
ForkIDs beginning with 0xFF will be reserved for future protocol upgrades.
|
||||||
|
|
||||||
|
This particular consensus rule MUST NOT be implemented by Bitcoin Cash wallet software. Wallets that follow the upgrade
|
||||||
|
should not have to change anything.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
[1] Median Time Past is described [here](/protocol/blockchain/transaction#median-time-past).
|
||||||
|
It is guaranteed by consensus rules to be monotonically increasing.
|
||||||
|
|
||||||
|
[2] The `forkId` is defined as per the [replay protected sighash](/protocol/forks/replay-protected-sighash) specification.
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# HF-20210515
|
||||||
|
|
||||||
|
The May 2021 hard fork was the first to be comprised of [CHIPs](#chips).
|
||||||
|
|
||||||
|
## CHIPs
|
||||||
|
|
||||||
|
A CasH Improvement Proposal (CHIP) is a change request for the Bitcoin Cash protocol.
|
||||||
|
CHIPs can be written and published by any member of the Bitcoin Cash community.
|
||||||
|
They are evaluated publicly, giving the authors an opportunity to make any clarifications or adjustments based on feedback from the rest of the community.
|
||||||
|
Once there is sufficient support for a CHIP amongst node developers, it is scheduled for release in a future hard fork.
|
||||||
|
Changes from multiple CHIPs may be included in a single hard fork.
|
||||||
|
|
||||||
|
Along with the creation of the CHIP system, the expectation of biannual releases was relaxed.
|
||||||
|
If no CHIPs have support, there will be no hard-fork.
|
||||||
|
|
||||||
|
## Contents
|
||||||
|
|
||||||
|
The May 2021 hard fork is comprised the following CHIPs:
|
||||||
|
|
||||||
|
1. [Unconfirmed Transaction Chain Limit](/protocol/forks/chips/2021-05-unconfirmed-transaction-chain-limit)
|
||||||
|
2. [Multiple OP_RETURNs for Bitcoin Cash](/protocol/forks/chips/2021-05-multiple-op-returns-for-bitcoin-cash)
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
This document describes proposed requirements and design for a reusable signing mechanism ensuring replay protection in the event of a chain split.
|
This document describes proposed requirements and design for a reusable signing mechanism ensuring replay protection in the event of a chain split.
|
||||||
It provides a way for users to create transactions which are invalid on forks lacking support for the mechanism and a fork-specific ID.
|
It provides a way for users to create transactions which are invalid on forks lacking support for the mechanism and a fork-specific ID.
|
||||||
|
|
||||||
The proposed digest algorithm is adapted from BIP143[1][1] as it minimizes redundant data hashing in verification, covers the input value by the signature and is already implemented in a wide variety of applications[2][2].
|
The proposed digest algorithm is adapted from BIP143<sup>[1][1]</sup> as it minimizes redundant data hashing in verification, covers the input value by the signature and is already implemented in a wide variety of applications<sup>[2][2]</sup>.
|
||||||
|
|
||||||
The proposed digest algorithm is used when the `SIGHASH_FORKID` bit is set in the signature's sighash type.
|
The proposed digest algorithm is used when the `SIGHASH_FORKID` bit is set in the signature's sighash type.
|
||||||
The verification of signatures which do not set this bit is not affected.
|
The verification of signatures which do not set this bit is not affected.
|
||||||
@@ -53,7 +53,7 @@ The proposed digest algorithm computes the double SHA256 of the serialization of
|
|||||||
9. nLocktime of the transaction (4-byte little endian)
|
9. nLocktime of the transaction (4-byte little endian)
|
||||||
10. sighash type of the signature (4-byte little endian)
|
10. sighash type of the signature (4-byte little endian)
|
||||||
|
|
||||||
Items 1, 4, 7 and 9 have the same meaning as in the original algorithm[3][3].
|
Items 1, 4, 7 and 9 have the same meaning as in the original algorithm<sup>[3][3]</sup>.
|
||||||
|
|
||||||
#### hashPrevouts
|
#### hashPrevouts
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ The 8-byte value of the amount of Bitcoin this input contains.
|
|||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
1. In the original algorithm[3][OP_CHECKSIG], a `uint256` of `0x0000......0001` is committed if the input index for a `SINGLE` signature is greater than or equal to the number of outputs.
|
1. In the original algorithm<sup>[3][3]</sup>, a `uint256` of `0x0000......0001` is committed if the input index for a `SINGLE` signature is greater than or equal to the number of outputs.
|
||||||
In this BIP a `0x0000......0000` is committed, without changing the semantics.
|
In this BIP a `0x0000......0000` is committed, without changing the semantics.
|
||||||
|
|
||||||
#### sighash type
|
#### sighash type
|
||||||
@@ -205,16 +205,20 @@ Gating code:
|
|||||||
|
|
||||||
## Note
|
## Note
|
||||||
|
|
||||||
In the UAHF, a `fork id` of 0 is used (see [4][4] REQ-6-2 NOTE 4), i.e.
|
In the UAHF, a `fork id` of 0 is used (see UAHF<sup>[4][4]</sup> REQ-6-2 NOTE 4), i.e.
|
||||||
the GetForkID() function returns zero.
|
the GetForkID() function returns zero.
|
||||||
In that case the code can be simplified to omit the function.
|
In that case the code can be simplified to omit the function.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[1]: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki
|
[1]: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki
|
||||||
|
\[1]: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki
|
||||||
|
|
||||||
[2]: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#Motivation
|
[2]: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#Motivation
|
||||||
|
\[2]: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#Motivation
|
||||||
|
|
||||||
[3]: https://en.bitcoin.it/wiki/OP_CHECKSIG
|
[3]: https://en.bitcoin.it/wiki/OP_CHECKSIG
|
||||||
|
\[3]: https://en.bitcoin.it/wiki/OP_CHECKSIG
|
||||||
|
|
||||||
[4]: https://github.com/bitcoincashorg/bitcoincash.org/blob/master/spec/uahf-technical-spec.md
|
[4]: https://github.com/bitcoincashorg/bitcoincash.org/blob/master/spec/uahf-technical-spec.md
|
||||||
|
\[4]: https://github.com/bitcoincashorg/bitcoincash.org/blob/master/spec/uahf-technical-spec.md
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Files adapted/copied from:
|
||||||
|
|
||||||
|
https://github.com/sipa/bips/
|
||||||
|
Commit b65cd694676096dd31ea790485a2019ca653b34f by Mark Lundeburg
|
||||||
@@ -0,0 +1,223 @@
|
|||||||
|
# BIP-Schnorr (Archive)
|
||||||
|
|
||||||
|
BIP: ?
|
||||||
|
Title: Schnorr Signatures for secp256k1
|
||||||
|
Author: Pieter Wuille <pieter.wuille@gmail.com>
|
||||||
|
Status: Draft
|
||||||
|
Type: Informational
|
||||||
|
License: BSD-2-Clause
|
||||||
|
Post-History: 2018-07-06: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-July/016203.html [bitcoin-dev] Schnorr signatures BIP
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
### Abstract
|
||||||
|
|
||||||
|
This document proposes a standard for 64-byte Schnorr signatures over the elliptic curve `secp256k1`.
|
||||||
|
|
||||||
|
### Copyright
|
||||||
|
|
||||||
|
This document is licensed under the 2-clause BSD license.
|
||||||
|
|
||||||
|
### Motivation
|
||||||
|
|
||||||
|
Bitcoin has traditionally used
|
||||||
|
[ECDSA](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm) signatures over the [secp256k1 curve](http://www.secg.org/sec2-v2.pdf) for authenticating
|
||||||
|
transactions. These are [standardized](http://www.secg.org/sec1-v2.pdf), but have a number of downsides
|
||||||
|
compared to [Schnorr signatures](https://en.wikipedia.org/wiki/Schnorr_signature) over the same curve:
|
||||||
|
|
||||||
|
* **Security proof**: The security of Schnorr signatures is easily [provable](https://www.di.ens.fr/~pointche/Documents/Papers/2000_joc.pdf) in the random oracle model assuming the elliptic curve discrete logarithm problem (ECDLP) is hard. Such a proof does not exist for ECDSA.
|
||||||
|
* **Non-malleability**: ECDSA signatures are inherently malleable; a third party without access to the private key can alter an existing valid signature for a given public key and message into another signature that is valid for the same key and message. This issue is discussed in [BIP62](https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki) and [BIP66](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki). On the other hand, Schnorr signatures are provably non-malleable<sup>[1](#footnotes)</sup>.
|
||||||
|
* **Linearity**: Schnorr signatures have the remarkable property that multiple parties can collaborate to produce a signature that is valid for the sum of their public keys. This is the building block for various higher-level constructions that improve efficiency and privacy, such as multisignatures and others (see Applications below).
|
||||||
|
|
||||||
|
For all these advantages, there are virtually no disadvantages, apart
|
||||||
|
from not being standardized. This document seeks to change that. As we
|
||||||
|
propose a new standard, a number of improvements not specific to Schnorr signatures can be
|
||||||
|
made:
|
||||||
|
|
||||||
|
* **Signature encoding**: Instead of [DER](https://en.wikipedia.org/wiki/X.690#DER_encoding)-encoding for signatures (which are variable size, and up to 72 bytes), we can use a simple fixed 64-byte format.
|
||||||
|
* **Batch verification**: The specific formulation of ECDSA signatures that is standardized cannot be verified more efficiently in batch compared to individually, unless additional witness data is added. Changing the signature scheme offers an opportunity to avoid this.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
This graph shows the ratio between the time it takes to verify `n` signatures individually and to verify a batch of `n` signatures. This ratio goes up logarithmically with the number of signatures, or in other words: the total time to verify `n` signatures grows with `O(n / log n)`.
|
||||||
|
|
||||||
|
By reusing the same curve as Bitcoin has used for ECDSA, private and public keys remain identical for Schnorr signatures, and we avoid introducing new assumptions about elliptic curve group security.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
We first build up the algebraic formulation of the signature scheme by
|
||||||
|
going through the design choices. Afterwards, we specify the exact
|
||||||
|
encodings and operations.
|
||||||
|
|
||||||
|
### Design
|
||||||
|
|
||||||
|
**Schnorr signature variant** Elliptic Curve Schnorr signatures for message `m` and public key `P` generally involve a point `R`, integers `e` and `s` picked by the signer, and generator `G` which satisfy `e = H(R || m)` and `sG = R + eP`. Two formulations exist, depending on whether the signer reveals `e` or `R`:
|
||||||
|
|
||||||
|
1. Signatures are `(e,s)` that satisfy `e = H(sG - eP || m)`. This avoids minor complexity introduced by the encoding of the point `R` in the signature (see paragraphs "Encoding the sign of R" and "Implicit Y coordinate" further below in this subsection).
|
||||||
|
2. Signatures are `(R,s)` that satisfy `sG = R + H(R || m)P`. This supports batch verification, as there are no elliptic curve operations inside the hashes.
|
||||||
|
|
||||||
|
We choose the `R`-option to support batch verification.
|
||||||
|
|
||||||
|
**Key prefixing** When using the verification rule above directly, it is possible for a third party to convert a signature `(R,s)` for key `P` into a signature `(R,s + aH(R || m))` for key `P + aG` and the same message, for any integer `a`. This is not a concern for Bitcoin currently, as all signature hashes indirectly commit to the public keys. However, this may change with proposals such as SIGHASH_NOINPUT ([BIP 118](https://github.com/bitcoin/bips/blob/master/bip-0118.mediawiki)), or when the signature scheme is used for other purposes—especially in combination with schemes like [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)'s unhardened derivation. To combat this, we choose `key prefixed`<sup>[2](#footnotes)</sup> Schnorr signatures; changing the equation to `sG = R + H(R || P || m)P`.
|
||||||
|
|
||||||
|
**Encoding the sign of R** As we chose the `R`-option above, we're required to encode the point `R` into the signature. Several possibilities exist:
|
||||||
|
|
||||||
|
1. Encoding the full X and Y coordinate of R, resulting in a 96-byte signature.
|
||||||
|
2. Encoding the full X coordinate, but only whether Y is even or odd (like compressed public keys). This would result in 65-byte signatures.
|
||||||
|
3. Encoding only the X coordinate, leaving us with 64-byte signature.
|
||||||
|
|
||||||
|
Using the first option would be slightly more efficient for verification (around 5%), but we prioritize compactness, and therefore choose option 3.
|
||||||
|
|
||||||
|
**Implicit Y coordinate** In order to support batch verification, the Y coordinate of `R` cannot be ambiguous (every valid X coordinate has two possible Y coordinates). We have a choice between several options for symmetry breaking:
|
||||||
|
|
||||||
|
1. Implicitly choosing the Y coordinate that is in the lower half.
|
||||||
|
2. Implicitly choosing the Y coordinate that is even<sup>[3](#footnotes)</sup>.
|
||||||
|
3. Implicitly choosing the Y coordinate that is a quadratic residue (has a square root modulo the field size)<sup>[4](#footnotes)</sup>.
|
||||||
|
|
||||||
|
The third option is slower at signing time but a bit faster to verify, as the quadratic residue of the Y coordinate can be computed directly for points represented in
|
||||||
|
[Jacobian coordinates](https://en.wikibooks.org/wiki/Cryptography/Prime_Curve/Jacobian_Coordinates) (a common optimization to avoid modular inverses
|
||||||
|
for elliptic curve operations). The two other options require a possibly
|
||||||
|
expensive conversion to affine coordinates first. This would even be the case if the sign or oddness were explicitly coded (option 2 in the previous design choice). We therefore choose option 3.
|
||||||
|
|
||||||
|
**Final scheme** As a result, our final scheme ends up using signatures `(r,s)` where `r` is the X coordinate of a point `R` on the curve whose Y coordinate is a quadratic residue, and which satisfies `sG = R + H(r || P || m)P`.
|
||||||
|
|
||||||
|
### Specification
|
||||||
|
|
||||||
|
We first describe the verification algorithm, and then the signature algorithm.
|
||||||
|
|
||||||
|
The following convention is used, with constants as defined for secp256k1:
|
||||||
|
* Lowercase variables represent integers or byte arrays.
|
||||||
|
* The constant `p` refers to the field size, `0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F`.
|
||||||
|
* The constant `n` refers to the curve order, `0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141`.
|
||||||
|
* Uppercase variables refer to points on the curve with equation `y<sup>2</sup> = x<sup>3</sup> + 7` over the integers modulo `p`.
|
||||||
|
* `infinite(P)` returns whether or not `P` is the point at infinity.
|
||||||
|
* `x(P)` and `y(P)` are integers in the range `0..p-1` and refer to the X and Y coordinates of a point `P` (assuming it is not infinity).
|
||||||
|
* The constant `G` refers to the generator, for which `x(G) = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798` and `y(G) = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8`.
|
||||||
|
* Addition of points refers to the usual [elliptic curve group operation](https://en.wikipedia.org/wiki/Elliptic_curve#The_group_law).
|
||||||
|
* [Multiplication of an integer and a point](https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication) refers to the repeated application of the group operation.
|
||||||
|
* Functions and operations:
|
||||||
|
* `||` refers to byte array concatenation.
|
||||||
|
* The function `x[i:j]`, where `x` is a byte array, returns a `(j - i)`-byte array with a copy of the `i`-th byte (inclusive) to the `j`-th byte (exclusive) of `x`.
|
||||||
|
* The function `bytes(x)`, where `x` is an integer, returns the 32-byte encoding of `x`, most significant byte first.
|
||||||
|
* The function `bytes(P)`, where `P` is a point, returns `bytes(0x02 + (y(P) & 1)) || bytes(x(P))`<sup>[5](#footnotes)</sup>.
|
||||||
|
* The function `int(x)`, where `x` is a 32-byte array, returns the 256-bit unsigned integer whose most significant byte encoding is `x`.
|
||||||
|
* The function `lift_x(x)`, where `x` is an integer in range `0..p-1`, returns the point `P` for which `x(P) = x` and `y(P)` is a quadratic residue modulo `p`, or fails if no such point exists<ref>Given an candidate X coordinate `x` in the range `0..p-1`, there exist either exactly two or exactly zero valid Y coordinates. If no valid Y coordinate exists, then `x` is not a valid X coordinate either, i.e., no point `P` exists for which `x(P) = x`. Given a candidate `x`, the valid Y coordinates are the square roots of `c = x<sup>3</sup> + 7 mod p` and they can be computed as `y = ±c<sup>(p+1)/4</sup> mod p` (see [Quadratic residue](https://en.wikipedia.org/wiki/Quadratic_residue#Prime_or_prime_power_modulus)) if they exist, which can be checked by squaring and comparing with `c`. Due to [Euler's criterion](https://en.wikipedia.org/wiki/Euler%27s_criterion) it then holds that `c<sup>(p-1)/2</sup> = 1 mod p`. The same criterion applied to `y` results in `y<sup>(p-1)/2</sup> mod p = ±c<sup>((p+1)/4)((p-1)/2)</sup> mod p = ±1 mod p`. Therefore `y = +c<sup>(p+1)/4</sup> mod p` is a quadratic residue and `-y mod p` is not.</ref>. The function `lift_x(x)` is equivalent to the following pseudocode:
|
||||||
|
* Let `y = c<sup>(p+1)/4</sup> mod p`.
|
||||||
|
* Fail if `c ≠ y<sup>2</sup> mod p`.
|
||||||
|
* Return `(r, y)`.
|
||||||
|
* The function `point(x)`, where `x` is a 33-byte array, returns the point `P` for which `x(P) = int(x[1:33])` and `y(P) & 1 = int(x[0:1]) - 0x02)`, or fails if no such point exists. The function `point(x)` is equivalent to the following pseudocode:
|
||||||
|
* Fail if (`x[0:1] ≠ 0x02` and `x[0:1] ≠ 0x03`).
|
||||||
|
* Set flag `odd` if `x[0:1] = 0x03`.
|
||||||
|
* Let `(r, y) = lift_x(x)`; fail if `lift_x(x)` fails.
|
||||||
|
* If (flag `odd` is set and `y` is an even integer) or (flag `odd` is not set and `y` is an odd integer):
|
||||||
|
* Let `y = p - y`.
|
||||||
|
* Return `(r, y)`.
|
||||||
|
* The function `hash(x)`, where `x` is a byte array, returns the 32-byte SHA256 hash of `x`.
|
||||||
|
* The function `jacobi(x)`, where `x` is an integer, returns the [Jacobi symbol](https://en.wikipedia.org/wiki/Jacobi_symbol) of `x / p`. It is equal to `x<sup>(p-1)/2</sup> mod p` ([Euler's criterion](https://en.wikipedia.org/wiki/Euler%27s_criterion))<sup>[6](#footnotes)</sup>.
|
||||||
|
|
||||||
|
#### Verification
|
||||||
|
|
||||||
|
Input:
|
||||||
|
* The public key `pk`: a 33-byte array
|
||||||
|
* The message `m`: a 32-byte array
|
||||||
|
* A signature `sig`: a 64-byte array
|
||||||
|
|
||||||
|
The signature is valid if and only if the algorithm below does not fail.
|
||||||
|
* Let `P = point(pk)`; fail if `point(pk)` fails.
|
||||||
|
* Let `r = int(sig[0:32])`; fail if `r ≥ p`.
|
||||||
|
* Let `s = int(sig[32:64])`; fail if `s ≥ n`.
|
||||||
|
* Let `e = int(hash(bytes(r) || bytes(P) || m)) mod n`.
|
||||||
|
* Let `R = sG - eP`.
|
||||||
|
* Fail if `infinite(R)`.
|
||||||
|
* Fail if `jacobi(y(R)) ≠ 1` or `x(R) ≠ r`.
|
||||||
|
|
||||||
|
#### Batch Verification
|
||||||
|
|
||||||
|
Input:
|
||||||
|
* The number `u` of signatures
|
||||||
|
* The public keys `pk<sub>1..u</sub>`: `u` 33-byte arrays
|
||||||
|
* The messages `m<sub>1..u</sub>`: `u` 32-byte arrays
|
||||||
|
* The signatures `sig<sub>1..u</sub>`: `u` 64-byte arrays
|
||||||
|
|
||||||
|
All provided signatures are valid with overwhelming probability if and only if the algorithm below does not fail.
|
||||||
|
* Generate `u-1` random integers `a<sub>2...u</sub>` in the range `1...n-1`. They are generated deterministically using a [CSPRNG](https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator) seeded by a cryptographic hash of all inputs of the algorithm, i.e. `seed = seed_hash(pk<sub>1</sub>..pk<sub>u</sub> || m<sub>1</sub>..m<sub>u</sub> || sig<sub>1</sub>..sig<sub>u</sub> )`. A safe choice is to instantiate `seed_hash` with SHA256 and use [ChaCha20](https://tools.ietf.org/html/rfc8439) with key `seed` as a CSPRNG to generate 256-bit integers, skipping integers not in the range `1...n-1`.
|
||||||
|
* For `i = 1 .. u`:
|
||||||
|
** Let `P<sub>i</sub> = point(pk<sub>i</sub>)`; fail if `point(pk<sub>i</sub>)` fails.
|
||||||
|
** Let `r = int(sig<sub>i</sub>[0:32])`; fail if `r ≥ p`.
|
||||||
|
** Let `s<sub>i</sub> = int(sig<sub>i</sub>[32:64])`; fail if `s<sub>i</sub> ≥ n`.
|
||||||
|
** Let `e<sub>i</sub> = int(hash(bytes(r) || bytes(P<sub>i</sub>) || m<sub>i</sub>)) mod n`.
|
||||||
|
** Let `R<sub>i</sub> = lift_x(r)`; fail if `lift_x(r)` fails.
|
||||||
|
* Fail if `(s<sub>1</sub> + a<sub>2</sub>s<sub>2</sub> + ... + a<sub>u</sub>s<sub>u</sub>)G ≠ R<sub>1</sub> + a<sub>2</sub>R<sub>2</sub> + ... + a<sub>u</sub>R<sub>u</sub> + e<sub>1</sub>P<sub>1</sub> + (a<sub>2</sub>e<sub>2</sub>)P<sub>2</sub> + ... + (a<sub>u</sub>e<sub>u</sub>)P<sub>u</sub>`.
|
||||||
|
|
||||||
|
#### Signing
|
||||||
|
|
||||||
|
Input:
|
||||||
|
* The secret key `d`: an integer in the range `1..n-1`.
|
||||||
|
* The message `m`: a 32-byte array
|
||||||
|
|
||||||
|
To sign `m` for public key `dG`:
|
||||||
|
* Let `k' = int(hash(bytes(d) || m)) mod n`<ref>Note that in general, taking the output of a hash function modulo the curve order will produce an unacceptably biased result. However, for the secp256k1 curve, the order is sufficiently close to `2<sup>256</sup>` that this bias is not observable (`1 - n / 2<sup>256</sup>` is around `1.27 * 2<sup>-128</sup>`).</ref>.
|
||||||
|
* Fail if `k' = 0`.
|
||||||
|
* Let `R = k'G`.
|
||||||
|
* Let `k = k' ` if `jacobi(y(R)) = 1`, otherwise let `k = n - k' `.
|
||||||
|
* Let `e = int(hash(bytes(x(R)) || bytes(dG) || m)) mod n`.
|
||||||
|
* The signature is `bytes(x(R)) || bytes((k + ed) mod n)`.
|
||||||
|
|
||||||
|
**Above deterministic derivation of `R` is designed specifically for this signing algorithm and may not be secure when used in other signature schemes.**
|
||||||
|
For example, using the same derivation in the MuSig multi-signature scheme leaks the secret key (see the [MuSig paper](https://eprint.iacr.org/2018/068) for details).
|
||||||
|
|
||||||
|
Note that this is not a `unique signature` scheme: while this algorithm will always produce the same signature for a given message and public key, `k` (and hence `R`) may be generated in other ways (such as by a CSPRNG) producing a different, but still valid, signature.
|
||||||
|
|
||||||
|
### Optimizations
|
||||||
|
|
||||||
|
Many techniques are known for optimizing elliptic curve implementations. Several of them apply here, but are out of scope for this document. Two are listed below however, as they are relevant to the design decisions:
|
||||||
|
|
||||||
|
**Jacobi symbol** The function `jacobi(x)` is defined as above, but can be computed more efficiently using an [extended GCD algorithm](https://en.wikipedia.org/wiki/Jacobi_symbol#Calculating_the_Jacobi_symbol).
|
||||||
|
|
||||||
|
**Jacobian coordinates** Elliptic Curve operations can be implemented more efficiently by using [Jacobian coordinates](https://en.wikibooks.org/wiki/Cryptography/Prime_Curve/Jacobian_Coordinates). Elliptic Curve operations implemented this way avoid many intermediate modular inverses (which are computationally expensive), and the scheme proposed in this document is in fact designed to not need any inversions at all for verification. When operating on a point `P` with Jacobian coordinates `(x,y,z)` which is not the point at infinity and for which `x(P)` is defined as `x / z<sup>2</sup>` and `y(P)` is defined as `y / z<sup>3</sup>`:
|
||||||
|
* `jacobi(y(P))` can be implemented as `jacobi(yz mod p)`.
|
||||||
|
* `x(P) ≠ r` can be implemented as `x ≠ z<sup>2</sup>r mod p`.
|
||||||
|
|
||||||
|
## Applications
|
||||||
|
|
||||||
|
There are several interesting applications beyond simple signatures.
|
||||||
|
While recent academic papers claim that they are also possible with ECDSA, consensus support for Schnorr signature verification would significantly simplify the constructions.
|
||||||
|
|
||||||
|
### Multisignatures and Threshold Signatures
|
||||||
|
|
||||||
|
By means of an interactive scheme such as [MuSig](https://eprint.iacr.org/2018/068), participants can produce a combined public key which they can jointly sign for. This allows n-of-n multisignatures which, from a verifier's perspective, are no different from ordinary signatures, giving improved privacy and efficiency versus `CHECKMULTISIG` or other means.
|
||||||
|
|
||||||
|
Further, by combining Schnorr signatures with [Pedersen Secret Sharing](https://link.springer.com/content/pdf/10.1007/3-540-46766-1_9.pdf), it is possible to obtain [an interactive threshold signature scheme](http://cacr.uwaterloo.ca/techreports/2001/corr2001-13.ps) that ensures that signatures can only be produced by arbitrary but predetermined sets of signers. For example, k-of-n threshold signatures can be realized this way. Furthermore, it is possible to replace the combination of participant keys in this scheme with MuSig, though the security of that combination still needs analysis.
|
||||||
|
|
||||||
|
### Adaptor Signatures
|
||||||
|
|
||||||
|
[Adaptor signatures](https://download.wpsoftware.net/bitcoin/wizardry/mw-slides/2018-05-18-l2/slides.pdf) can be produced by a signer by offsetting his public nonce with a known point `T = tG`, but not offsetting his secret nonce.
|
||||||
|
A correct signature (or partial signature, as individual signers' contributions to a multisignature are called) on the same message with same nonce will then be equal to the adaptor signature offset by `t`, meaning that learning `t` is equivalent to learning a correct signature.
|
||||||
|
This can be used to enable atomic swaps or even [general payment channels](https://eprint.iacr.org/2018/472) in which the atomicity of disjoint transactions is ensured using the signatures themselves, rather than Bitcoin script support. The resulting transactions will appear to verifiers to be no different from ordinary single-signer transactions, except perhaps for the inclusion of locktime refund logic.
|
||||||
|
|
||||||
|
Adaptor signatures, beyond the efficiency and privacy benefits of encoding script semantics into constant-sized signatures, have additional benefits over traditional hash-based payment channels. Specifically, the secret values `t` may be reblinded between hops, allowing long chains of transactions to be made atomic while even the participants cannot identify which transactions are part of the chain. Also, because the secret values are chosen at signing time, rather than key generation time, existing outputs may be repurposed for different applications without recourse to the blockchain, even multiple times.
|
||||||
|
|
||||||
|
### Blind Signatures
|
||||||
|
|
||||||
|
Schnorr signatures admit a very [simple **blind signature** construction](https://www.math.uni-frankfurt.de/~dmst/research/papers/schnorr.blind_sigs_attack.2001.pdf) which is a signature that a signer produces at the behest of another party without learning what he has signed.
|
||||||
|
These can for example be used in [Partially Blind Atomic Swaps](https://github.com/jonasnick/scriptless-scripts/blob/blind-swaps/md/partially-blind-swap.md), a construction to enable transferring of coins, mediated by an untrusted escrow agent, without connecting the transactors in the public blockchain transaction graph.
|
||||||
|
|
||||||
|
While the traditional Schnorr blind signatures are vulnerable to [Wagner's attack](https://www.iacr.org/archive/crypto2002/24420288/24420288.pdf), there are [a number of mitigations](https://www.math.uni-frankfurt.de/~dmst/teaching/SS2012/Vorlesung/EBS5.pdf) which allow them to be usable in practice without any known attacks. Nevertheless, more analysis is required to be confident about the security of the blind signature scheme.
|
||||||
|
|
||||||
|
## Test Vectors and Reference Code
|
||||||
|
|
||||||
|
For development and testing purposes, we provide a [collection of test vectors in CSV format](/protocol/forks/schnorr/bip-schnorr/test-vectors.csv) and a naive but highly inefficient and non-constant time [pure Python 3.7 reference implementation of the signing and verification algorithm](/protocol/forks/schnorr/bip-schnorr/reference.py).
|
||||||
|
The reference implementation is for demonstration purposes only and not to be used in production environments.
|
||||||
|
|
||||||
|
## Footnotes
|
||||||
|
|
||||||
|
1. More precisely they are ***strongly** unforgeable under chosen message attacks* (SUF-CMA), which informally means that without knowledge of the secret key but given a valid signature of a message, it is not possible to come up with a second valid signature for the same message. A security proof in the random oracle model can be found for example in [a paper by Kiltz, Masny and Pan](https://eprint.iacr.org/2016/191), which essentially restates [the original security proof of Schnorr signatures by Pointcheval and Stern](https://www.di.ens.fr/~pointche/Documents/Papers/2000_joc.pdf) more explicitly. These proofs are for the Schnorr signature variant using `(e,s)` instead of `(R,s)` (see Design above). Since we use a unique encoding of `R`, there is an efficiently computable bijection that maps `(R, s)` to `(e, s)`, which allows to convert a successful SUF-CMA attacker for the `(e, s)` variant to a successful SUF-CMA attacker for the `(r, s)` variant (and vice-versa). Furthermore, the aforementioned proofs consider a variant of Schnorr signatures without key prefixing (see Design above), but it can be verified that the proofs are also correct for the variant with key prefixing. As a result, the aforementioned security proofs apply to the variant of Schnorr signatures proposed in this document.
|
||||||
|
2. A limitation of committing to the public key (rather than to a short hash of it, or not at all) is that it removes the ability for public key recovery or verifying signatures against a short public key hash. These constructions are generally incompatible with batch verification.
|
||||||
|
3. Since `p` is odd, negation modulo `p` will map even numbers to odd numbers and the other way around. This means that for a valid X coordinate, one of the corresponding Y coordinates will be even, and the other will be odd.
|
||||||
|
4. A product of two numbers is a quadratic residue when either both or none of the factors are quadratic residues. As `-1` is not a quadratic residue, and the two Y coordinates corresponding to a given X coordinate are each other's negation, this means exactly one of the two must be a quadratic residue.
|
||||||
|
5. This matches the `compressed` encoding for elliptic curve points used in Bitcoin already, following section 2.3.3 of the [SEC 1](http://www.secg.org/sec1-v2.pdf) standard.
|
||||||
|
6. For points `P` on the secp256k1 curve it holds that `jacobi(y(P)) ≠ 0`.
|
||||||
|
|
||||||
|
## Acknowledgements
|
||||||
|
|
||||||
|
This document is the result of many discussions around Schnorr based signatures over the years, and had input from Johnson Lau, Greg Maxwell, Jonas Nick, Andrew Poelstra, Tim Ruffing, Rusty Russell, and Anthony Towns.
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
import hashlib
|
||||||
|
import binascii
|
||||||
|
|
||||||
|
p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
|
||||||
|
n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
|
||||||
|
G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)
|
||||||
|
|
||||||
|
def point_add(P1, P2):
|
||||||
|
if (P1 is None):
|
||||||
|
return P2
|
||||||
|
if (P2 is None):
|
||||||
|
return P1
|
||||||
|
if (P1[0] == P2[0] and P1[1] != P2[1]):
|
||||||
|
return None
|
||||||
|
if (P1 == P2):
|
||||||
|
lam = (3 * P1[0] * P1[0] * pow(2 * P1[1], p - 2, p)) % p
|
||||||
|
else:
|
||||||
|
lam = ((P2[1] - P1[1]) * pow(P2[0] - P1[0], p - 2, p)) % p
|
||||||
|
x3 = (lam * lam - P1[0] - P2[0]) % p
|
||||||
|
return (x3, (lam * (P1[0] - x3) - P1[1]) % p)
|
||||||
|
|
||||||
|
def point_mul(P, n):
|
||||||
|
R = None
|
||||||
|
for i in range(256):
|
||||||
|
if ((n >> i) & 1):
|
||||||
|
R = point_add(R, P)
|
||||||
|
P = point_add(P, P)
|
||||||
|
return R
|
||||||
|
|
||||||
|
def bytes_from_int(x):
|
||||||
|
return x.to_bytes(32, byteorder="big")
|
||||||
|
|
||||||
|
def bytes_from_point(P):
|
||||||
|
return (b'\x03' if P[1] & 1 else b'\x02') + bytes_from_int(P[0])
|
||||||
|
|
||||||
|
def point_from_bytes(b):
|
||||||
|
if b[0] in [b'\x02', b'\x03']:
|
||||||
|
odd = b[0] - 0x02
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
x = int_from_bytes(b[1:33])
|
||||||
|
y_sq = (pow(x, 3, p) + 7) % p
|
||||||
|
y0 = pow(y_sq, (p + 1) // 4, p)
|
||||||
|
if pow(y0, 2, p) != y_sq:
|
||||||
|
return None
|
||||||
|
y = p - y0 if y0 & 1 != odd else y0
|
||||||
|
return [x, y]
|
||||||
|
|
||||||
|
def int_from_bytes(b):
|
||||||
|
return int.from_bytes(b, byteorder="big")
|
||||||
|
|
||||||
|
def hash_sha256(b):
|
||||||
|
return hashlib.sha256(b).digest()
|
||||||
|
|
||||||
|
def jacobi(x):
|
||||||
|
return pow(x, (p - 1) // 2, p)
|
||||||
|
|
||||||
|
def schnorr_sign(msg, seckey):
|
||||||
|
if len(msg) != 32:
|
||||||
|
raise ValueError('The message must be a 32-byte array.')
|
||||||
|
if not (1 <= seckey <= n - 1):
|
||||||
|
raise ValueError('The secret key must be an integer in the range 1..n-1.')
|
||||||
|
k0 = int_from_bytes(hash_sha256(bytes_from_int(seckey) + msg)) % n
|
||||||
|
if k0 == 0:
|
||||||
|
raise RuntimeError('Failure. This happens only with negligible probability.')
|
||||||
|
R = point_mul(G, k0)
|
||||||
|
k = n - k0 if (jacobi(R[1]) != 1) else k0
|
||||||
|
e = int_from_bytes(hash_sha256(bytes_from_int(R[0]) + bytes_from_point(point_mul(G, seckey)) + msg)) % n
|
||||||
|
return bytes_from_int(R[0]) + bytes_from_int((k + e * seckey) % n)
|
||||||
|
|
||||||
|
def schnorr_verify(msg, pubkey, sig):
|
||||||
|
if len(msg) != 32:
|
||||||
|
raise ValueError('The message must be a 32-byte array.')
|
||||||
|
if len(pubkey) != 33:
|
||||||
|
raise ValueError('The public key must be a 33-byte array.')
|
||||||
|
if len(sig) != 64:
|
||||||
|
raise ValueError('The signature must be a 64-byte array.')
|
||||||
|
P = point_from_bytes(pubkey)
|
||||||
|
if (P is None):
|
||||||
|
return False
|
||||||
|
r = int_from_bytes(sig[0:32])
|
||||||
|
s = int_from_bytes(sig[32:64])
|
||||||
|
if (r >= p or s >= n):
|
||||||
|
return False
|
||||||
|
e = int_from_bytes(hash_sha256(sig[0:32] + bytes_from_point(P) + msg)) % n
|
||||||
|
R = point_add(point_mul(G, s), point_mul(P, n - e))
|
||||||
|
if R is None or jacobi(R[1]) != 1 or R[0] != r:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
#
|
||||||
|
# The following code is only used to verify the test vectors.
|
||||||
|
#
|
||||||
|
import csv
|
||||||
|
|
||||||
|
def test_vectors():
|
||||||
|
all_passed = True
|
||||||
|
with open('test-vectors.csv', newline='') as csvfile:
|
||||||
|
reader = csv.reader(csvfile)
|
||||||
|
reader.__next__()
|
||||||
|
for row in reader:
|
||||||
|
(index, seckey, pubkey, msg, sig, result, comment) = row
|
||||||
|
pubkey = bytes.fromhex(pubkey)
|
||||||
|
msg = bytes.fromhex(msg)
|
||||||
|
sig = bytes.fromhex(sig)
|
||||||
|
result = result == 'TRUE'
|
||||||
|
print('\nTest vector #%-3i: ' % int(index))
|
||||||
|
if seckey != '':
|
||||||
|
seckey = int(seckey, 16)
|
||||||
|
sig_actual = schnorr_sign(msg, seckey)
|
||||||
|
if sig == sig_actual:
|
||||||
|
print(' * Passed signing test.')
|
||||||
|
else:
|
||||||
|
print(' * Failed signing test.')
|
||||||
|
print(' Excepted signature:', sig.hex())
|
||||||
|
print(' Actual signature:', sig_actual.hex())
|
||||||
|
all_passed = False
|
||||||
|
result_actual = schnorr_verify(msg, pubkey, sig)
|
||||||
|
if result == result_actual:
|
||||||
|
print(' * Passed verification test.')
|
||||||
|
else:
|
||||||
|
print(' * Failed verification test.')
|
||||||
|
print(' Excepted verification result:', result)
|
||||||
|
print(' Actual verification result:', result_actual)
|
||||||
|
if comment:
|
||||||
|
print(' Comment:', comment)
|
||||||
|
all_passed = False
|
||||||
|
print()
|
||||||
|
if all_passed:
|
||||||
|
print('All test vectors passed.')
|
||||||
|
else:
|
||||||
|
print('Some test vectors failed.')
|
||||||
|
return all_passed
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test_vectors()
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,17 @@
|
|||||||
|
index,secret key,public key,message,signature,verification result,comment
|
||||||
|
1,0000000000000000000000000000000000000000000000000000000000000001,0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,0000000000000000000000000000000000000000000000000000000000000000,787A848E71043D280C50470E8E1532B2DD5D20EE912A45DBDD2BD1DFBF187EF67031A98831859DC34DFFEEDDA86831842CCD0079E1F92AF177F7F22CC1DCED05,TRUE,
|
||||||
|
2,B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF,02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659,243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89,2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD,TRUE,
|
||||||
|
3,C90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B14E5C7,03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B,5E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C,00DA9B08172A9B6F0466A2DEFD817F2D7AB437E0D253CB5395A963866B3574BE00880371D01766935B92D2AB4CD5C8A2A5837EC57FED7660773A05F0DE142380,TRUE,
|
||||||
|
4,,03DEFDEA4CDB677750A420FEE807EACF21EB9898AE79B9768766E4FAA04A2D4A34,4DF3C3F68FCC83B27E9D42C90431A72499F17875C81A599B566C9889B9696703,00000000000000000000003B78CE563F89A0ED9414F5AA28AD0D96D6795F9C6302A8DC32E64E86A333F20EF56EAC9BA30B7246D6D25E22ADB8C6BE1AEB08D49D,TRUE,
|
||||||
|
5,,031B84C5567B126440995D3ED5AABA0565D71E1834604819FF9C17F5E9D5DD078F,0000000000000000000000000000000000000000000000000000000000000000,52818579ACA59767E3291D91B76B637BEF062083284992F2D95F564CA6CB4E3530B1DA849C8E8304ADC0CFE870660334B3CFC18E825EF1DB34CFAE3DFC5D8187,TRUE,"test fails if jacobi symbol of x(R) instead of y(R) is used"
|
||||||
|
6,,03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B,FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,570DD4CA83D4E6317B8EE6BAE83467A1BF419D0767122DE409394414B05080DCE9EE5F237CBD108EABAE1E37759AE47F8E4203DA3532EB28DB860F33D62D49BD,TRUE,"test fails if msg is reduced modulo p or n"
|
||||||
|
7,,03EEFDEA4CDB677750A420FEE807EACF21EB9898AE79B9768766E4FAA04A2D4A34,4DF3C3F68FCC83B27E9D42C90431A72499F17875C81A599B566C9889B9696703,00000000000000000000003B78CE563F89A0ED9414F5AA28AD0D96D6795F9C6302A8DC32E64E86A333F20EF56EAC9BA30B7246D6D25E22ADB8C6BE1AEB08D49D,FALSE,"public key not on the curve"
|
||||||
|
8,,02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659,243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89,2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1DFA16AEE06609280A19B67A24E1977E4697712B5FD2943914ECD5F730901B4AB7,FALSE,"incorrect R residuosity"
|
||||||
|
9,,03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B,5E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C, 00DA9B08172A9B6F0466A2DEFD817F2D7AB437E0D253CB5395A963866B3574BED092F9D860F1776A1F7412AD8A1EB50DACCC222BC8C0E26B2056DF2F273EFDEC,FALSE,"negated message"
|
||||||
|
10,,0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,0000000000000000000000000000000000000000000000000000000000000000,787A848E71043D280C50470E8E1532B2DD5D20EE912A45DBDD2BD1DFBF187EF68FCE5677CE7A623CB20011225797CE7A8DE1DC6CCD4F754A47DA6C600E59543C,FALSE,"negated s value"
|
||||||
|
11,,03DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659,243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89,2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD,FALSE,"negated public key"
|
||||||
|
12,,02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659,243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89,00000000000000000000000000000000000000000000000000000000000000009E9D01AF988B5CEDCE47221BFA9B222721F3FA408915444A4B489021DB55775F,FALSE,"sG - eP is infinite. Test fails in single verification if jacobi(y(inf)) is defined as 1 and x(inf) as 0"
|
||||||
|
13,,02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659,243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89,0000000000000000000000000000000000000000000000000000000000000001D37DDF0254351836D84B1BD6A795FD5D523048F298C4214D187FE4892947F728,FALSE,"sG - eP is infinite. Test fails in single verification if jacobi(y(inf)) is defined as 1 and x(inf) as 1"
|
||||||
|
14,,02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659,243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89,4A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD,FALSE,"sig[0:32] is not an X coordinate on the curve"
|
||||||
|
15,,02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659,243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89,FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2F1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD,FALSE,"sig[0:32] is equal to field size"
|
||||||
|
16,,02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659,243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89,2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141,FALSE,"sig[32:64] is equal to curve order"
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# Variable Length Integer
|
# Compact Variable Length Integer
|
||||||
|
|
||||||
A variable-width data format for unsigned integers allowing a more compact representation for smaller values.
|
A variable-width data format for unsigned integers allowing a more compact representation for smaller values. This is sometimes referred to as "compact size" or "var int".
|
||||||
|
|
||||||
## Format
|
## Format
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,5 @@
|
|||||||
# Endianness
|
# Endian
|
||||||
|
|
||||||
|
[Endianness](https://en.wikipedia.org/wiki/Endianness) refers to the implies order of bytes for a given value.
|
||||||
|
|
||||||
|
Values are generally either [big-endian](/protocol/misc/endian/big), with the most significant bytes come first, or [little-endian](/protocol/misc/endian/little), with the least significant values first. Bitcoin Cash used a mix of little- and big-endian values, with little-endian byte order generally being used for integers.
|
||||||
@@ -9,7 +9,7 @@ Provides the contents of a block.
|
|||||||
| version number | 4 bytes | signed integer | The block format version number. |
|
| version number | 4 bytes | signed integer | The block format version number. |
|
||||||
| previous block hash | 32 bytes | bytes | The hash of the block preceding this one in the blockchain. |
|
| previous block hash | 32 bytes | bytes | The hash of the block preceding this one in the blockchain. |
|
||||||
| merkle root | 32 bytes | bytes | The root hash of the merkle tree comprised of the block's transactions. |
|
| merkle root | 32 bytes | bytes | The root hash of the merkle tree comprised of the block's transactions. |
|
||||||
| timestamp | 8 bytes | unix timestamp<sup>[(LE)](/protocol/misc/endian/little)</sup> | The time the block was generated. |
|
| timestamp | 4 bytes | unix timestamp<sup>[(LE)](/protocol/misc/endian/little)</sup> | The time the block was generated. |
|
||||||
| hash target | 4 bytes | [compressed target](/protocol/blockchain/block/block-header#compressed-target-format) | The target that the hash of this block is expected to satisfy. See [Target](/protocol/blockchain/proof-of-work#target). |
|
| hash target | 4 bytes | [compressed target](/protocol/blockchain/block/block-header#compressed-target-format) | The target that the hash of this block is expected to satisfy. See [Target](/protocol/blockchain/proof-of-work#target). |
|
||||||
| nonce | 4 bytes | bytes | Nonce used to update the block hash during mining. See [Proof of Work](/protocol/blockchain/proof-of-work). |
|
| nonce | 4 bytes | bytes | Nonce used to update the block hash during mining. See [Proof of Work](/protocol/blockchain/proof-of-work). |
|
||||||
| transaction count | variable | [variable length integer](/protocol/formats/variable-length-integer) | The number of transactions in the block (and therefore following in this message). |
|
| transaction count | variable | [variable length integer](/protocol/formats/variable-length-integer) | The number of transactions in the block (and therefore following in this message). |
|
||||||
|
|||||||
@@ -1,103 +1,101 @@
|
|||||||
# Announcement: Double Spend Proof ("dsproof-beta")
|
# Announcement: Double Spend Proof ("dsproof-beta")
|
||||||
|
|
||||||
This message is meant to inform participants of attempts of double
|
This message is meant to inform participants of attempts of double spending an unconfirmed transaction by providing cryptographic provable evidence that one UTXO entry was spent twice by the owner(s) of the funds.
|
||||||
spending an unconfirmed transaction by providing cryptographic provable
|
|
||||||
evidence that one UTXO entry was spent twice by the owner(s) of the funds.
|
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
A double spend attack can be used, for instance, to redirect payments meant for a specific
|
A double spend attack can be used, for instance, to redirect payments sent to a specific merchant to a different target and thus defraud the merchant.
|
||||||
merchant to a different target and thus defraud the merchant we want to pay to. The basic
|
The basic concept of a double spend is that (at least) one unspent output is spent twice in different transactions which forces miners to pick one of them to mine.
|
||||||
concept of a double spend is that (at least) one unspent output is spent
|
|
||||||
twice in different transactions which forces miners to pick one of them to mine.
|
|
||||||
|
|
||||||
At its most basic we can detect this by finding two signed inputs both
|
At its most basic level, this can be detected by finding two signed inputs both spending the same output.
|
||||||
spending the same output. In the case of pay-to-public-key-hash (P2PKH)
|
In the case of pay-to-public-key-hash (P2PKH) this means two signatures from the same public key.
|
||||||
this means two signatures signing the same public key.
|
|
||||||
|
|
||||||
Cryptographic signatures in Bitcoin Cash follow the 'fork-id' algorithm described
|
Cryptographic signatures in Bitcoin Cash follow the "fork-id" algorithm described [here](/protocol/forks/replay-protected-sighash).
|
||||||
[here](/protocol/forks/replay-protected-sighash),
|
Since a hash of the transaction is signed, the protocol sends only the intermediate components used to build the preimage for the hash, while still allowing receivers to validate both signatures of the same public key, and therefore proving that a double spend has taken place.
|
||||||
which explains a change made to the Satoshi designed algorithm, a change after which the containing transaction itself is not signed, but a unique hash of that
|
|
||||||
transaction is being signed. This gives us the opportunity to send only
|
|
||||||
the intermediate hashes instead of the whole transaction while allowing
|
|
||||||
receivers to still validate both signatures of the same public
|
|
||||||
key. And therefore prove that a double spend has taken place.
|
|
||||||
|
|
||||||
## Network specification
|
## Network specification
|
||||||
|
|
||||||
A node that finds itself in possession of a correct double-spend-proof
|
A node that finds itself in possession of a correct double-spend-proof
|
||||||
shall notify its peers using the INV message, using a 'type' field with
|
shall notify its peers using the [inventory](/protocol/network/messages/inv) message, using a "type" field with the value **`0x94A0`**.
|
||||||
number **0x94a0**. This will be changed to another number as this spec
|
This inventory type value will be changed to another number once double-spend proofs move out of beta and is finalized.
|
||||||
is finalized.
|
|
||||||
|
|
||||||
The hash-ID for the double-spend-proof is a double sha256 over the entire
|
The hash-ID for the double-spend-proof is a double sha256 over the entire serialized content of the proof, as defined next.
|
||||||
serialized content of the proof, as defined next.
|
|
||||||
|
|
||||||
In response to an INV any peer can issue a `getdata` message which will
|
In response to an inventory message, any peer can issue a [getdata](/protocol/network/messages/getdata) message which will cause a reply with the following message.
|
||||||
cause a reply with the following message. The name of the message (until
|
This type of message is **`dsproof-beta`** but will be changed to another identifier once double-spend proofs move out of beta and is finalized.
|
||||||
this spec is finalized) is **`dsproof-beta`**.
|
|
||||||
|
|
||||||
|
| Field | Length | Format | Description |
|
||||||
| Field Size | Description | Data Type | Comments |
|
|
||||||
| -----------|:-----------:| ----------:|---------:|
|
| -----------|:-----------:| ----------:|---------:|
|
||||||
| 32 | TxInPrevHash | sha256 | The txid being spent |
|
| previous [transaction output](/protocol/blockchain/transaction#transaction-output)'s transaction hash | 32 | sha256<sup>[(LE)](/protocol/misc/endian/little)</sup> | The **transaction hash** of the output being spent |
|
||||||
| 4 | TxInPrevIndex | int | The output being spent |
|
| previous [transaction output](/protocol/blockchain/transaction#transaction-output)'s index | 4 | unsigned integer<sup>[(LE)](/protocol/misc/endian/little)</sup> | The **index** of the transaction output being spent |
|
||||||
| | FirstSpender | spender | the first sorted spender |
|
| first spender | variable | spender<sup>[(BE)](/protocol/misc/endian/big)</sup> | The preimage data structure needed to validate a transaction's signature. |
|
||||||
| | DoubleSpender | spender | the second spender |
|
| second spender | variable | spender<sup>[(BE)](/protocol/misc/endian/big)</sup> | The preimage data structure needed to validate a transaction's signature. |
|
||||||
|
|
||||||
A double-spend-proof essentially describes two inputs, both spending the
|
A double-spend-proof describes two inputs, both spending the same output.
|
||||||
same output. As such the prev-hash and prev-index point to the output and
|
As such the previous transaction output's hash and previous transaction output's index point to the output and the spenders each describe inputs.
|
||||||
the spenders each describe inputs.
|
|
||||||
|
|
||||||
The details required to validate one input are provided in the spender field;
|
### Spender Format
|
||||||
|
|
||||||
| Field Size | Description | Data Type | Comments |
|
The `spender` format is as follows.
|
||||||
|
Each field in the (below) table's `description` column loosely corresponds to the name of the preimage component used when generating transaction signatures per the [transaction signing algorithm](/protocol/blockchain/transaction/transaction-signing).
|
||||||
|
|
||||||
|
| Field | Length | Format | [Signature Preimage](/protocol/blockchain/transaction/transaction-signing#preimage-format) Component | Description |
|
||||||
| -----------|:-----------:| ----------:|---------:|
|
| -----------|:-----------:| ----------:|---------:|
|
||||||
| 4 | tx-version | unsigned int | Copy of the transactions version field |
|
| tx version | 4 | unsigned integer<sup>[(LE)](/protocol/misc/endian/little)</sup> | #1 | Copy of the transactions version field |
|
||||||
| 4 | sequence | unsigned int | Copy of the sequence field of the input |
|
| sequence | 4 | unsigned integer<sup>[(LE)](/protocol/misc/endian/little)</sup> | #7 | Copy of the sequence field of the input |
|
||||||
| 4 | locktime | unsigned int | Copy of the transactions locktime field |
|
| locktime | 4 | unsigned integer<sup>[(LE)](/protocol/misc/endian/little)</sup> | #9 | Copy of the transactions locktime field |
|
||||||
| 32 | hash-prevoutputs | sha256 | Transaction hash of prevoutputs |
|
| hash prevoutputs | 32 | sha256 | #2 | Transaction hash of prevoutputs |
|
||||||
| 32 | hash-sequence | sha256 | Transaction hash of sequences |
|
| hash sequence | 32 | sha256 | #3 | Transaction hash of sequences |
|
||||||
| 32 | hash-outputs | sha256 | Transaction hash of outputs |
|
| hash outputs | 32 | sha256 | #8 | Transaction hash of outputs |
|
||||||
| 1-9 | list-size | var-int | Number of items in the push-data list |
|
| push-data count | variable | [variable length integer](/protocol/formats/variable-length-integer) | | Number of push-data objects within in the push-data list |
|
||||||
| | push-data | byte-array | Raw byte-array of a push-data. For instance a signature |
|
| push-data | variable | bytes | #10 | List of push-data objects |
|
||||||
|
|
||||||
|
### Push Data Format
|
||||||
|
|
||||||
|
The `push data` format is as follows.
|
||||||
|
Each item is a value pushed by the [unlocking script](/protocol/blockchain/transaction/unlocking-script).
|
||||||
|
|
||||||
|
| Field | Length | Format | Description |
|
||||||
|
| -----------|:-----------:| ----------:|---------:|
|
||||||
|
| byte count | variable | [variable length integer](/protocol/formats/variable-length-integer) | The number of bytes in this push-data object |
|
||||||
|
| bytes | variable | bytes <sup>[(BE)](/protocol/misc/endian/big)</sup> | The resulting bytes pushed by an [unlocking script](/protocol/blockchain/transaction/unlocking-script)'s push [operation](/protocol/blockchain/script#operation-codes-opcodes) (ex. signature data). |
|
||||||
|
|
||||||
## Validation
|
## Validation
|
||||||
|
|
||||||
It is required that nodes validate the proof before using it or forward it to other
|
It is required that nodes validate the proof before using it or forwarding it to other nodes.
|
||||||
nodes. Please check against the matching transaction in your mempool for
|
Double spend proofs only apply to transactions within the [memory pool](/protocol/blockchain/memory-pool).
|
||||||
addresses so you can limit sending the proof only to interested nodes that
|
Validated double spend proofs should be advertised (via [inventory message](/protocol/network/messages/inv)) to all connected peers.
|
||||||
have registered a bloom filter.
|
If a peer has a bloom filter set, nodes should only relay double spend proofs that the [bloom filter](/protocol/spv/bloom-filter).
|
||||||
|
|
||||||
Validation includes a short list of requirements;
|
Validation includes a short list of requirements;
|
||||||
|
|
||||||
1. The DSP message is well-formed and contains all fields. It is allowed (by
|
1. The message is well-formed and contains all fields.
|
||||||
nature of Bitcoin Cash) for some hashes to be all-zeros.
|
It is allowed for some hashes to be all-zeros.
|
||||||
2. The two spenders are different, specifically the signature (push data)
|
2. The two `spenders` must be different.
|
||||||
has to be different.
|
3. The first & double `spender`s are sorted via the following algorithm:
|
||||||
3. The first & double spenders are sorted with two hashes as keys.
|
|
||||||
Compare on the hash-outputs, and if those are equal, then compare on
|
|
||||||
hash-prevoutputs.
|
|
||||||
The sorting order is in numerically ascending order of the hash,
|
|
||||||
interpreted as 256-bit little endian integers.
|
|
||||||
4. The double spent output is still available in the UTXO database,
|
|
||||||
implying no spending transaction has been mined.
|
|
||||||
5. No other valid proof is known.
|
|
||||||
|
|
||||||
Further validation can be done by essentially validating the signature that
|
3a. sort via the `hash-outputs` field of the `spender`.
|
||||||
was copied from the inputs of both transactions against the output a node
|
|
||||||
should have in either its memory pool or its UTXO database.
|
|
||||||
|
|
||||||
To validate a spender of the proof, a node requires to have;
|
3b. if `hash-outputs` are equal, then compare on `hash-prevoutputs`.
|
||||||
|
|
||||||
|
The sorting order is in numerically ascending order of the hash, interpreted as 256-bit [little endian](/protocol/misc/endian/little) integers.
|
||||||
|
|
||||||
|
4. The double spent output is still available in the UTXO database, implying no spending transaction has been mined.
|
||||||
|
|
||||||
|
5. The push data elements of the two signers are different.
|
||||||
|
|
||||||
|
6. No other valid proof is known.
|
||||||
|
|
||||||
|
Further validation can be done by validating the signature that
|
||||||
|
was copied from the inputs of both transactions against the (soon to be spent) previous transaction output.
|
||||||
|
|
||||||
|
To validate a spender of the proof, a node is required to have;
|
||||||
|
|
||||||
* The output being spent (mempool or UTXO)
|
* The output being spent (mempool or UTXO)
|
||||||
* One of the transactions trying to spend the output.
|
* One of the transactions trying to spend the output.
|
||||||
* The double-spend-proof.
|
* The double-spend-proof.
|
||||||
|
|
||||||
As the forkid
|
As the forkid [specification](/protocol/blockchain/transaction/transaction-signing#preimage-format) details, the digest algorithm hashes 10 items in order to receive a sha256 hash, which is then signed.
|
||||||
[specification](/protocol/forks/replay-protected-sighash)
|
|
||||||
details, the digest algorithm hashes 10 items in order to receive a sha256
|
|
||||||
hash, which is then signed.
|
|
||||||
|
|
||||||
These 10 items are;
|
These 10 items are;
|
||||||
|
|
||||||
@@ -112,22 +110,42 @@ These 10 items are;
|
|||||||
9. nLocktime of the transaction (4-byte little endian)
|
9. nLocktime of the transaction (4-byte little endian)
|
||||||
10. sighash type of the signature (4-byte little endian)
|
10. sighash type of the signature (4-byte little endian)
|
||||||
|
|
||||||
In the double spend message we include items: 1, 2, 3, 4, 7, 8, 9 and 10.
|
The double spend message includes items: 1, 2, 3, 4, 7, 8, 9 and 10.
|
||||||
|
|
||||||
From the output we are trying to spend you can further obtain items: 5 & 6
|
Items 5 & 6 can be obtained from the output being spent.
|
||||||
|
|
||||||
The full transaction also spending the same output which you found in your
|
The transaction that first spent the output within the node's [memory pool](/protocol/blockchain/memory-pool), can be used to get the public key required to validate that the signature within the `push-data` field of the double spend proof is correct.
|
||||||
mempool, can be used to get the public key which you can use to validate
|
|
||||||
that the signature is actually correct.
|
|
||||||
|
|
||||||
When all rules are followed, the proof is valid.
|
When all rules are followed, the proof is valid.
|
||||||
|
|
||||||
## Limitation and risks
|
## Limitation and risks
|
||||||
|
|
||||||
Not all types and all combinations of transactions are supported. Wallets
|
Not all types and all combinations of transactions are supported.
|
||||||
and point-of-sale applications are suggested to give a rating of how secure
|
Wallets and point-of-sale applications are suggested to give a rating of how secure an unconfirmed transaction is based on various factors.
|
||||||
an unconfirmed transaction is based on various factors.
|
|
||||||
|
|
||||||
Transactions that spend all, confirmed, P2PKH outputs with all inputs
|
Transactions that spend all, confirmed, P2PKH outputs with all inputs signed `SIGHASH_ALL` without `ANYONECANPAY`, are double-spend-proof's "protected transactions".
|
||||||
signed SIGHASH\_ALL without ANYONECANPAY, are double-spend-proof's
|
|
||||||
"protected transactions".
|
## Node-Specific Behavior
|
||||||
|
|
||||||
|
### Bitcoin Verde
|
||||||
|
|
||||||
|
Bitcoin Verde supports an extended form of the `dsproof-beta` message.
|
||||||
|
For P2PKH outputs, the format is as described above for compatibility with other nodes.
|
||||||
|
For all other script types, the following changes are made to the existing data:
|
||||||
|
|
||||||
|
1. `hash prevoutputs` is always the non-zero version of hash (e.g. for `SIGHASH_ALL`, **not** `ANYONECANPAY` hash types).
|
||||||
|
2. `hash sequence` is always the non-zero version of the hash (e.g. for `SIGHASH_ALL`, **not** `ANYONECANPAY` hash types).
|
||||||
|
3. `hash outputs` is always all zero (0x00) bytes.
|
||||||
|
4. `push data` is defined to be the values push by every (push) operation in the unlocking scripts, except for P2SH, where the last value (the redeem script) is left off.
|
||||||
|
|
||||||
|
The following extra data is also appended after the second spender:
|
||||||
|
|
||||||
|
| Field | Length | Format | Description |
|
||||||
|
| -----------|:-----------:| ----------|---------|
|
||||||
|
| hash type count | 1 byte | [variable length integer](/protocol/formats/variable-length-integer) | The number of hashes to follow (always 2 with current signature rules). |
|
||||||
|
| hash type indicator 0 | 1 byte | byte | The hash type of the following hash (always 0x01 for `SIGHASH_ALL`). |
|
||||||
|
| hash outputs 0 | 32 bytes | sha256 | The hash outputs, as used in the signature preimage for a `SIGHASH_ALL` signature. |
|
||||||
|
| hash type indicator 1 | 1 byte | byte | The hash type of the following hash (always 0x03 for `SIGHASH_SINGLE`). |
|
||||||
|
| hash outputs 1 | 32 bytes | sha256 | The hash outputs, as used in the signature preimage for a `SIGHASH_SINGLE` signature. |
|
||||||
|
|
||||||
|
This format corresponds with Bitcoin Verde's proposal for an alternate double spend proof message that supports all script types.
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
# Request: Filter Fee (“filterfee”)
|
# Request: Fee Filter (“feefilter”)
|
||||||
|
|
||||||
Requests that the recipient withhold transactions that provide less than the given threshold of fees, in satoshis per byte.
|
Requests that the recipient withhold transactions that provide less than the given threshold of fees, in satoshis per kilobyte (1000 bytes).
|
||||||
|
|
||||||
The recipient node may, but is not required to, begin to perform this filtering and send only transactions that have fees at or above this threshold to the sender.
|
The recipient node may, but is not required to, begin to perform this filtering and send only transactions that have fees at or above this threshold to the sender.
|
||||||
|
|
||||||
|
Defined in [BIP-133](/protocol/forks/bip-0133).
|
||||||
|
|
||||||
## Message Format
|
## Message Format
|
||||||
|
|
||||||
| Field | Length | Format | Description |
|
| Field | Length | Format | Description |
|
||||||
|--|--|--|--|
|
|--|--|--|--|
|
||||||
| minimum fee per byte | 8 bytes | unsigned 64 bit integer<sup>[(LE)](/protocol/misc/endian/little)</sup> | The minimum number of satoshis per byte in fees desired by the sender.
|
| minimum fee per byte | 8 bytes | unsigned integer<sup>[(LE)](/protocol/misc/endian/little)</sup> | The minimum number of satoshis, per 1000 bytes, desired by the sender in fees. |
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ If a bloom filter has been sent to this node via [filterload](/protocol/network/
|
|||||||
| Field | Length | Format | Description |
|
| Field | Length | Format | Description |
|
||||||
|--|--|--|--|
|
|--|--|--|--|
|
||||||
| inventory count | variable | [variable length integer](/protocol/formats/variable-length-integer) | The number of inventory items in this message. |
|
| inventory count | variable | [variable length integer](/protocol/formats/variable-length-integer) | The number of inventory items in this message. |
|
||||||
| inventory items | `inventory_count` * 36 bytes | `inventory_count` [inventory items](#inventory-item-format) | The set of inventory items being transmitted. |
|
| inventory items | `inventory_count` * 36 bytes | `inventory_count` [inventory items](#inventory-item-format) | The set of inventory items being transmitted. Up to 50,000 inventory items can be sent in a single inventory message.|
|
||||||
|
|
||||||
NOTE: Since a block header is a relatively small data structure, and block propagation speed is an important network metric, a peer may send [headers](/protocol/network/messages/headers) messages in place of inventory messages when a block arrives. This behavior can be requested using the [sendheaders](/protocol/network/messages/sendheaders) message.
|
NOTE: Since a block header is a relatively small data structure, and block propagation speed is an important network metric, a peer may send [headers](/protocol/network/messages/headers) messages in place of inventory messages when a block arrives. This behavior can be requested using the [sendheaders](/protocol/network/messages/sendheaders) message.
|
||||||
|
|
||||||
@@ -32,11 +32,11 @@ The type of the object that is available.
|
|||||||
|
|
||||||
| Type | Value|
|
| Type | Value|
|
||||||
|------|------|
|
|------|------|
|
||||||
| 1 | Transaction |
|
| 0x0001 | Transaction |
|
||||||
| 2 | Block |
|
| 0x0002 | Block |
|
||||||
| 3 | Filtered Block (partial block with merkle proof)
|
| 0x0003 | Filtered Block (partial block with merkle proof)
|
||||||
| 4 | Compact block
|
| 0x0004 | Compact block
|
||||||
| 5 | Xthin block (Bitcoin Unlimited)
|
| 0x0005 | Xthin block (Bitcoin Unlimited)
|
||||||
| 6 | Graphene Block (Bitcoin Unlimited)
|
| 0x0006 | Graphene Block (Bitcoin Unlimited)
|
||||||
| 0x94a0 | [DSProof](/protocol/network/messages/dsproof-beta) |
|
| 0x94A0 | [Double Spend Proof](/protocol/network/messages/dsproof-beta) |
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ Users and creators of the tokens can utilize the computational power and other b
|
|||||||
Simple Ledger Protocol (SLP) is one of the most prevalent token systems on Bitcoin Cash.
|
Simple Ledger Protocol (SLP) is one of the most prevalent token systems on Bitcoin Cash.
|
||||||
SLP employs a “colored coins” design that associates token amounts with BCH [transaction](/protocol/blockchain/transaction) outputs.
|
SLP employs a “colored coins” design that associates token amounts with BCH [transaction](/protocol/blockchain/transaction) outputs.
|
||||||
An SLP transaction will utilize a [data output](/protocol/blockchain/transaction/locking-script#data-output) to include a message in one of four predefined formats to annotate the SLP transaction information associated with each transaction output in the same transaction.
|
An SLP transaction will utilize a [data output](/protocol/blockchain/transaction/locking-script#data-output) to include a message in one of four predefined formats to annotate the SLP transaction information associated with each transaction output in the same transaction.
|
||||||
The predefined formats include: [GENESIS](/protocol/slp/genesis), [MINT](protocol/slp/mint), [SEND](/protocol/slp/send), and [COMMIT](/protocol/slp/commit).
|
The predefined formats include: [GENESIS](/protocol/slp/genesis), [MINT](/protocol/slp/mint), [SEND](/protocol/slp/send), and [COMMIT](/protocol/slp/commit).
|
||||||
The GENESIS message defines the SLP token and issues the first batch of tokens.
|
The GENESIS message defines the SLP token and issues the first batch of tokens.
|
||||||
The MINT message issues further batches of tokens.
|
The MINT message issues further batches of tokens.
|
||||||
The SEND message denotes the number of tokens sent to each output.
|
The SEND message denotes the number of tokens sent to each output.
|
||||||
|
|||||||
@@ -23,6 +23,6 @@ The set will be carefully chosen to satisfy the above requirements with a minima
|
|||||||
**Transaction outputs**:
|
**Transaction outputs**:
|
||||||
|
|
||||||
| v<sub>out</sub> | ScriptPubKey ("Address") | BCH amount |
|
| v<sub>out</sub> | ScriptPubKey ("Address") | BCH amount |
|
||||||
|-|-|-|
|
|--|--|--|
|
||||||
| 0 | OP_RETURN<br><lokad_id: 'SLP\x00'> (4 bytes, ascii)<br><token_type: 1> (1 to 2 byte integer)<br><transaction_type: 'COMMIT'> (6 bytes, ascii)<br><token_id> (32 bytes)<br><for_bitcoin_block_hash> (32 bytes)<br><block_height> (8 byte integer)<br><token_txn_set_hash> (32 bytes)<br><txn_set_data_url> (0 to ∞ bytes, ascii) [to be determined] | any |
|
| 0 | OP_RETURN<br><lokad_id: 'SLP\x00'> (4 bytes, ascii)<br><token_type: 1> (1 to 2 byte integer)<br><transaction_type: 'COMMIT'> (6 bytes, ascii)<br><token_id> (32 bytes)<br><for_bitcoin_block_hash> (32 bytes)<br><block_height> (8 byte integer)<br><token_txn_set_hash> (32 bytes)<br><txn_set_data_url> (0 to ∞ bytes, ascii) [to be determined] | any |
|
||||||
| ... | Any | any |
|
| ... | Any | any |
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ The genesis transaction includes an initial minting of `initial_token_mint_quant
|
|||||||
**Transaction outputs**:
|
**Transaction outputs**:
|
||||||
|
|
||||||
| v<sub>out</sub> | ScriptPubKey ("Address")| BCH amount| Implied token amount (base units) |
|
| v<sub>out</sub> | ScriptPubKey ("Address")| BCH amount| Implied token amount (base units) |
|
||||||
| - | - | - | - |
|
|--|--|--|--|
|
||||||
| 0 | OP_RETURN<br><lokad_id: 'SLP\x00'> (4 bytes, ascii)<sup>1</sup><br><token_type: 1> (1 to 2 byte integer)<br><transaction_type: 'GENESIS'> (7 bytes, ascii)<br><token_ticker> (0 to ∞ bytes, suggested utf-8)<br><token_name> (0 to ∞ bytes, suggested utf-8)<br><token_document_url> (0 to ∞ bytes, suggested ascii)<br><token_document_hash> (0 bytes or 32 bytes)<br><decimals> (1 byte in range 0x00-0x09)<br><mint_baton_vout> (0 bytes, or 1 byte in range 0x02-0xff)<br><initial_token_mint_quantity> (8 byte integer)<br> | any<sup>2</sup> | 0 |
|
| 0 | OP_RETURN<br><lokad_id: 'SLP\x00'> (4 bytes, ascii)<sup>1</sup><br><token_type: 1> (1 to 2 byte integer)<br><transaction_type: 'GENESIS'> (7 bytes, ascii)<br><token_ticker> (0 to ∞ bytes, suggested utf-8)<br><token_name> (0 to ∞ bytes, suggested utf-8)<br><token_document_url> (0 to ∞ bytes, suggested ascii)<br><token_document_hash> (0 bytes or 32 bytes)<br><decimals> (1 byte in range 0x00-0x09)<br><mint_baton_vout> (0 bytes, or 1 byte in range 0x02-0xff)<br><initial_token_mint_quantity> (8 byte integer)<br> | any<sup>2</sup> | 0 |
|
||||||
| 1 | Initial mint receiver | any<sup>2</sup> | initial_token_mint_quantity |
|
| 1 | Initial mint receiver | any<sup>2</sup> | initial_token_mint_quantity |
|
||||||
| ... | Any | any<sup>2</sup> | 0 |
|
| ... | Any | any<sup>2</sup> | 0 |
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ This makes it possible to prove end-of-minting capabilities for a token even aft
|
|||||||
**Transaction outputs**:
|
**Transaction outputs**:
|
||||||
|
|
||||||
| v<sub>out</sub> | ScriptPubKey ("Address") | BCH amount | Implied token amount (base units) |
|
| v<sub>out</sub> | ScriptPubKey ("Address") | BCH amount | Implied token amount (base units) |
|
||||||
|-|-|-|-|
|
|--|--|--|--|
|
||||||
| 0 | OP_RETURN<br>< lokad_id: 'SLP\x00'> (4 bytes, ascii)<br>< token_type: 1> (1 to 2 byte integer)<br>< transaction_type: 'MINT'> (4 bytes, ascii)<br>< token_id> (32 bytes)<br>< mint_baton_vout> (0 bytes or 1 byte between 0x02-0xff)<br>< additional_token_quantity> (8 byte integer) | any | 0 |
|
| 0 | OP_RETURN<br>< lokad_id: 'SLP\x00'> (4 bytes, ascii)<br>< token_type: 1> (1 to 2 byte integer)<br>< transaction_type: 'MINT'> (4 bytes, ascii)<br>< token_id> (32 bytes)<br>< mint_baton_vout> (0 bytes or 1 byte between 0x02-0xff)<br>< additional_token_quantity> (8 byte integer) | any | 0 |
|
||||||
| 1 | Token mint receiver | any | additional_token_quantity |
|
| 1 | Token mint receiver | any | additional_token_quantity |
|
||||||
| ... | Any | any | 0 |
|
| ... | Any | any | 0 |
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ Tokens will be assigned to the outputs with indexes 1 to 19 as indicated within
|
|||||||
Any number of additional BCH-only outputs will be allowed.
|
Any number of additional BCH-only outputs will be allowed.
|
||||||
A BCH-only output can come before token outputs, but a token quantity of 0 must be specified for this output.
|
A BCH-only output can come before token outputs, but a token quantity of 0 must be specified for this output.
|
||||||
|
|
||||||
**Transaction inputs**: Any number of inputs or content of inputs, in any order, but must include sufficient tokens coming from valid token transactions of matching `token_id`, `token_type` (see [Consensus Rules](/protocol/slp#Consensus-Rules)).
|
**Transaction inputs**: Any number of inputs or content of inputs, in any order, but must include sufficient tokens coming from valid token transactions of matching `token_id`, `token_type` (see [SLP consensus rules](/protocol/slp#consensus-rules)).
|
||||||
|
|
||||||
**Transaction outputs**:
|
**Transaction outputs**:
|
||||||
|
|
||||||
| v<sub>out</sub> | ScriptPubKey ("Address") | BCH amount | Implied token amount (base units) |
|
| v<sub>out</sub> | ScriptPubKey ("Address") | BCH amount | Implied token amount (base units) |
|
||||||
|-|-|-|-|
|
|--|--|--|--|
|
||||||
| 0 | OP_RETURN<br><lokad id: 'SLP\x00'> (4 bytes, ascii)<br><token_type: 1> (1 to 2 byte integer)<br><transaction_type: 'SEND'> (4 bytes, ascii)<br><token_id> (32 bytes)<br><token_output_quantity1> (required, 8 byte integer)<br><token_output_quantity2> (optional, 8 byte integer)<br>...<br><token_output_quantity19> (optional, 8 byte integer)<br>| any | 0 |
|
| 0 | OP_RETURN<br><lokad id: 'SLP\x00'> (4 bytes, ascii)<br><token_type: 1> (1 to 2 byte integer)<br><transaction_type: 'SEND'> (4 bytes, ascii)<br><token_id> (32 bytes)<br><token_output_quantity1> (required, 8 byte integer)<br><token_output_quantity2> (optional, 8 byte integer)<br>...<br><token_output_quantity19> (optional, 8 byte integer)<br>| any | 0 |
|
||||||
| 1 | Receiver 1 | any | token_output_quantity1 |
|
| 1 | Receiver 1 | any | token_output_quantity1 |
|
||||||
| ... | ... | any | ... |
|
| ... | ... | any | ... |
|
||||||
|
|||||||
Reference in New Issue
Block a user