Merge pull request #393 from bitcoin/devel-docs
Add Developer Guide To Bitcoin.org
294
_autocrossref.yaml
Normal file
|
@ -0,0 +1,294 @@
|
|||
---
|
||||
## List of words to match with references in _includes/references.md
|
||||
## in developer documentation, used by autocrossref.rb plugin.
|
||||
## "pattern to match in file" => "reference to give it"
|
||||
|
||||
51 percent attack:
|
||||
address:
|
||||
addresses: address
|
||||
'`amount`': pp amount
|
||||
base-58: base58check
|
||||
base58: base58check
|
||||
base58check:
|
||||
## bitcoin -- Recommend against bitcoin (singular) because of confusion between protocol, software, denomination
|
||||
bitcoins:
|
||||
bitcoin QR code: URI QR code
|
||||
bitcoin QR codes: URI QR code
|
||||
'`bitcoin:` URI': bitcoin uri
|
||||
'`bitcoin:` URIs': bitcoin uri
|
||||
block:
|
||||
block chain:
|
||||
block-chain: block chain
|
||||
block header:
|
||||
block height:
|
||||
block reward:
|
||||
block time:
|
||||
block version:
|
||||
blocks: block
|
||||
broadcast:
|
||||
broadcasts: broadcast
|
||||
broadcasting:
|
||||
certificate chain:
|
||||
chain code:
|
||||
change address:
|
||||
change addresses: change address
|
||||
change output:
|
||||
change outputs: change output
|
||||
child key:
|
||||
child keys: child key
|
||||
child public key:
|
||||
child public keys: child public key
|
||||
coinbase: coinbase transaction
|
||||
coinbase transaction:
|
||||
coinbase transactions: coinbase transaction
|
||||
coinbase field:
|
||||
confirm:
|
||||
confirmed:
|
||||
confirmation:
|
||||
confirmations:
|
||||
confirmed transactions:
|
||||
denomination:
|
||||
denominations: denomination
|
||||
DER format: der
|
||||
DER-formatted: der
|
||||
difficulty:
|
||||
double spend:
|
||||
double-spend: double spend
|
||||
double spending: double spend
|
||||
double-spent: double spend
|
||||
ECDSA:
|
||||
escrow contract:
|
||||
'`expires`': pp expires
|
||||
extended key:
|
||||
extended keys: extended key
|
||||
extended private key:
|
||||
extended public key:
|
||||
fiat:
|
||||
fork: accidental fork
|
||||
genesis block:
|
||||
hardened extended private key:
|
||||
HD protocol:
|
||||
header nonce:
|
||||
high-priority transaction: high-priority transactions
|
||||
high-priority transactions:
|
||||
inputs: input
|
||||
input:
|
||||
intermediate certificate:
|
||||
intermediate certificates: intermediate certificate
|
||||
key index:
|
||||
key pair:
|
||||
'`label`': label
|
||||
leaf certificate:
|
||||
locktime:
|
||||
long-term fork:
|
||||
mainnet:
|
||||
master chain code:
|
||||
master private key:
|
||||
'`memo`': pp memo
|
||||
'`message`': message
|
||||
'`merchant_data`': pp merchant data
|
||||
merkle root:
|
||||
merkle tree:
|
||||
merge:
|
||||
Merge avoidance:
|
||||
micropayment channel:
|
||||
micropayment channels: micropayment channel
|
||||
mine:
|
||||
miner:
|
||||
miners: miner
|
||||
minimum fee:
|
||||
mining: mine
|
||||
millibit: millibits
|
||||
millibits:
|
||||
multisig:
|
||||
network:
|
||||
null data:
|
||||
'`op_checkmultisig`': op_checkmultisig
|
||||
'`op_checksig`': op_checksig
|
||||
op code:
|
||||
op codes: op code
|
||||
'`op_dup`': op_dup
|
||||
'`op_equal`': op_equal
|
||||
'`op_equalverify`': op_equalverify
|
||||
'`op_hash160`': op_hash160
|
||||
'`op_return`': op_return
|
||||
'`op_verify`': op_verify
|
||||
orphan:
|
||||
orphan: orphaned
|
||||
outputs: output
|
||||
output:
|
||||
output index:
|
||||
p2pkh:
|
||||
p2sh:
|
||||
p2sh multisig:
|
||||
parent chain code:
|
||||
parent private key:
|
||||
parent public key:
|
||||
Payment message: pp payment
|
||||
payment protocol:
|
||||
"payment protocol's": payment protocol
|
||||
PaymentACK:
|
||||
PaymentDetails:
|
||||
PaymentRequest:
|
||||
PaymentRequests: paymentrequest
|
||||
'`payment_url`': pp payment url
|
||||
peer:
|
||||
peers: peer
|
||||
peer-to-peer network: network
|
||||
pki:
|
||||
'`pki_type`': pp pki type
|
||||
'`point()`': point function
|
||||
private key:
|
||||
private keys: private key
|
||||
proof of work:
|
||||
proof-of-work: proof of work
|
||||
protocol buffer: protobuf
|
||||
protocol buffers: protobuf
|
||||
pubkey hash:
|
||||
pubkey hashes: pubkey hash
|
||||
public key:
|
||||
public keys: public key
|
||||
public key infrastructure: pki
|
||||
'`r`': r
|
||||
raw format:
|
||||
rawtransaction format: raw format
|
||||
receipt:
|
||||
recurrent rebilling:
|
||||
redeemScript:
|
||||
refund:
|
||||
refunds: refund
|
||||
'`refund_to`': pp refund to
|
||||
root certificate:
|
||||
root seed:
|
||||
RPCs: rpc
|
||||
RPC:
|
||||
satoshi:
|
||||
satoshis: satoshi
|
||||
script:
|
||||
'`script`': pp script
|
||||
script hash:
|
||||
scripts: script
|
||||
scriptSig:
|
||||
scriptSigs: scriptSig
|
||||
secp256k1:
|
||||
sequence number:
|
||||
sequence numbers: sequence number
|
||||
SIGHASH: signature hash
|
||||
'`SIGHASH_ANYONECANPAY`': shacp
|
||||
'`SIGHASH_ALL`': sighash_all
|
||||
'`SIGHASH_ALL|SIGHASH_ANYONECANPAY`': sha_shacp
|
||||
'`SIGHASH_NONE`': sighash_none
|
||||
'`SIGHASH_NONE|SIGHASH_ANYONECANPAY`': shn_shacp
|
||||
'`SIGHASH_SINGLE|SIGHASH_ANYONECANPAY`': shs_shacp
|
||||
signature:
|
||||
signature hash:
|
||||
signatures: signature
|
||||
SPV:
|
||||
stack:
|
||||
standard script:
|
||||
standard scripts: standard script
|
||||
standard transaction: standard script
|
||||
standard transactions: standard script
|
||||
target:
|
||||
testnet:
|
||||
#transaction -- Recommend we don't autocrossref this; it occurs too often
|
||||
transaction fee:
|
||||
transaction fees: transaction fee
|
||||
transaction malleability:
|
||||
transaction object format:
|
||||
transaction version number:
|
||||
'`transactions`': pp transactions
|
||||
txid:
|
||||
txids: txid
|
||||
unconfirmed:
|
||||
unconfirmed transactions:
|
||||
unique address: unique addresses
|
||||
unique addresses:
|
||||
utxo:
|
||||
utxos: utxo
|
||||
verified payments:
|
||||
version 2 blocks: v2 block
|
||||
wallet:
|
||||
wallets: wallet
|
||||
wallet import format:
|
||||
x.509: x509
|
||||
X509Certificates:
|
||||
|
||||
## BIPS in numerical order; don't use padding zeros (e.g. BIP70 not BIP0070)
|
||||
BIP21:
|
||||
BIP32:
|
||||
BIP39:
|
||||
BIP70:
|
||||
|
||||
## RPCs
|
||||
'`addmultisigaddress`': rpc addmultisigaddress
|
||||
'`addnode`': rpc addnode
|
||||
'`backupwallet`': rpc backupwallet
|
||||
'`createmultisig`': rpc createmultisig
|
||||
'`createrawtransaction`': rpc createrawtransaction
|
||||
'`decoderawtransaction`': rpc decoderawtransaction
|
||||
'`decodescript`': rpc decodescript
|
||||
'`dumpprivkey`': rpc dumpprivkey
|
||||
'`dumpwallet`': rpc dumpwallet
|
||||
'`getaccount`': rpc getaccount
|
||||
'`getaccountaddress`': rpc getaccountaddress
|
||||
'`getaddednodeinfo`': rpc getaddednodeinfo
|
||||
'`getaddressesbyaccount`': rpc getaddressesbyaccount
|
||||
'`getbalance`': rpc getbalance
|
||||
'`getbestblockhash`': rpc getbestblockhash
|
||||
'`getblock`': rpc getblock
|
||||
'`getblockcount`': rpc getblockcount
|
||||
'`getblockhash`': rpc getblockhash
|
||||
'`getblocktemplate`': rpc getblocktemplate
|
||||
'`getconnectioncount`': rpc getconnectioncount
|
||||
'`getdifficulty`': rpc getdifficulty
|
||||
'`getgenerate`': rpc getgenerate
|
||||
'`gethashespersec`': rpc gethashespersec
|
||||
'`getinfo`': rpc getinfo
|
||||
'`getmininginfo`': rpc getmininginfo
|
||||
'`getnettotals`': rpc getnettotals
|
||||
'`getnetworkhashps`': rpc getnetworkhashps
|
||||
'`getnewaddress`': rpc getnewaddress
|
||||
'`getpeerinfo`': rpc getpeerinfo
|
||||
'`getrawchangeaddress`': rpc getrawchangeaddress
|
||||
'`getrawmempool`': rpc getrawmempool
|
||||
'`getrawtransaction`': rpc getrawtransaction
|
||||
'`getreceivedbyaccount`': rpc getreceivedbyaccount
|
||||
'`getreceivedbyaddress`': rpc getreceivedbyaddress
|
||||
'`gettransaction`': rpc gettransaction
|
||||
'`gettxout`': rpc gettxout
|
||||
'`gettxoutsetinfo`': rpc gettxoutsetinfo
|
||||
'`getunconfirmedbalance`': rpc getunconfirmedbalance
|
||||
'`getwork`': rpc getwork
|
||||
'`help`': rpc help
|
||||
'`importprivkey`': rpc importprivkey
|
||||
'`importwallet`': rpc importwallet
|
||||
'`keypoolrefill`': rpc keypoolrefill
|
||||
'`listaccounts`': rpc listaccounts
|
||||
'`listaddressgroupings`': rpc listaddressgroupings
|
||||
'`listlockunspent`': rpc listlockunspent
|
||||
'`listreceivedbyaccount`': rpc listreceivedbyaccount
|
||||
'`listreceivedbyaddress`': rpc listreceivedbyaddress
|
||||
'`listsinceblock`': rpc listsinceblock
|
||||
'`listtransactions`': rpc listtransactions
|
||||
'`listunspent`': rpc listunspent
|
||||
'`lockunspent`': rpc lockunspent
|
||||
'`move`': rpc move
|
||||
'`ping`': rpc ping
|
||||
'`sendfrom`': rpc sendfrom
|
||||
'`sendmany`': rpc sendmany
|
||||
'`sendrawtransaction`': rpc sendrawtransaction
|
||||
'`sendtoaddress`': rpc sendtoaddress
|
||||
'`setaccount`': rpc setaccount
|
||||
'`setgenerate`': rpc setgenerate
|
||||
'`settxfee`': rpc settxfee
|
||||
'`signmessage`': rpc signmessage
|
||||
'`signrawtransaction`': rpc signrawtransaction
|
||||
'`stop`': rpc stop
|
||||
'`submitblock`': rpc submitblock
|
||||
'`validateaddress`': rpc validateaddress
|
||||
'`verifychain`': rpc verifychain
|
||||
'`verifymessage`': rpc verifymessage
|
||||
'`walletlock`': rpc walletlock
|
||||
'`walletpassphrase`': rpc walletpassphrase
|
||||
'`walletpassphrasechange`': rpc walletpassphrasechange
|
242
_includes/guide_block_chain.md
Normal file
|
@ -0,0 +1,242 @@
|
|||
## Block Chain
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
The block chain provides Bitcoin's public ledger, a timestamped record
|
||||
of all confirmed transactions. This system is used to protect against double spending
|
||||
and modification of previous transaction records, using proof of
|
||||
work verified by the peer-to-peer network to maintain a global consensus.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Block Chain Overview
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||

|
||||
|
||||
The illustration above shows a simplified version of a block chain.
|
||||
A [block][]{:#term-block}{:.term} of one or more new transactions
|
||||
is collected into the transaction data part of a block.
|
||||
Copies of each transaction are hashed, and the hashes are then paired,
|
||||
hashed, paired again, and hashed again until a single hash remains, the
|
||||
[Merkle root][]{:#term-merkle-root}{:.term} of a Merkle tree.
|
||||
|
||||
The Merkle root is stored in the block header. Each block also
|
||||
stores the hash of the previous block's header, chaining the blocks
|
||||
together. This ensures a transaction cannot be modified without
|
||||
modifying the block that records it and all following blocks.
|
||||
|
||||
Transactions are also chained together. Bitcoin wallet software gives
|
||||
the impression that satoshis are sent from and to addresses, but
|
||||
bitcoins really move from transaction to transaction. Each standard
|
||||
transaction spends the satoshis previously spent in one or more earlier
|
||||
transactions, so the input of one transaction is the output of a
|
||||
previous transaction.
|
||||
|
||||

|
||||
|
||||
A single transaction can spend bitcoins to multiple outputs, as would be
|
||||
the case when sending satoshis to multiple addresses, but each output of
|
||||
a particular transaction can only be used as an input once in the
|
||||
block chain. Any subsequent reference is a forbidden double
|
||||
spend---an attempt to spend the same satoshis twice.
|
||||
|
||||
Outputs are not the same as Bitcoin addresses. You can use the same
|
||||
address in multiple transactions, but you can only use each output once.
|
||||
Outputs are tied to [transaction identifiers (TXIDs)][txid]{:#term-txid}{:.term}, which are the hashes
|
||||
of signed transactions.
|
||||
|
||||
Because each output of a particular transaction can only be spent once,
|
||||
all transactions included in the block chain can be categorized as either
|
||||
[Unspent Transaction Outputs (UTXOs)][utxo]{:#term-utxo}{:.term} or spent transaction outputs. For a
|
||||
payment to be valid, it must only use UTXOs as inputs.
|
||||
|
||||
Satoshis cannot be left in a UTXO after a transaction or they will be
|
||||
irretrievably lost, so any difference between the number of satoshis in a
|
||||
transaction's inputs and outputs is given as a [transaction fee][]{:#term-transaction-fee}{:.term} to
|
||||
the Bitcoin [miner][]{:#term-miner}{:.term} who creates the block containing that transaction.
|
||||
For example, in the illustration above, each transaction spends 10,000 satoshis
|
||||
fewer than it receives from its combined inputs, effectively paying a 10,000
|
||||
satoshi transaction fee.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Proof Of Work
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
The block chain is collaboratively maintained on a peer-to-peer network, so
|
||||
Bitcoin requires each block prove a significant amount of work was invested in
|
||||
its creation to ensure that untrustworthy peers who want to modify past blocks have
|
||||
to work harder than trustworthy peers who only want to add new blocks to the
|
||||
block chain.
|
||||
|
||||
Chaining blocks together makes it impossible to modify transactions included
|
||||
in any block without modifying all following blocks. As a
|
||||
result, the cost to modify a particular block increases with every new block
|
||||
added to the block chain, magnifying the effect of the proof of work.
|
||||
|
||||
The [proof of work][]{:#term-proof-of-work}{:.term} used in Bitcoin
|
||||
takes advantage of the apparently random nature of cryptographic hashes.
|
||||
A good cryptographic hash algorithm converts arbitrary data into a
|
||||
seemingly-random number. If the data is modified in any way and
|
||||
the hash re-run, a new seemingly-random number is produced, so there is
|
||||
no way to modify the data to make the hash number predictable.
|
||||
|
||||
To prove you did some extra work to create a block, you must create a
|
||||
hash of the block header which does not exceed a certain value. For
|
||||
example, if the maximum possible hash value is <span
|
||||
class="math">2<sup>256</sup> − 1</span>, you can prove that you
|
||||
tried up to two combinations by producing a hash value less than <span
|
||||
class="math">2<sup>256</sup> − 1</span>.
|
||||
|
||||
In the example given above, you will almost certainly produce a
|
||||
successful hash on your first try. You can even estimate the probability
|
||||
that a given hash attempt will generate a number below the [target][]{:#term-target}{:.term}
|
||||
threshold. Bitcoin itself does not track probabilities but instead
|
||||
simply assumes that the lower it makes the target threshold, the more
|
||||
hash attempts, on average, will need to be tried.
|
||||
|
||||
New blocks will only be added to the block chain if their hash is at
|
||||
least as challenging as a [difficulty][]{:#term-difficulty}{:.term} value expected by the peer-to-peer
|
||||
network. Every 2,016 blocks, the network uses timestamps stored in each
|
||||
block header to calculate the number of seconds elapsed between generation
|
||||
of the first and last of those last 2,016 blocks. The ideal value is
|
||||
1,209,600 seconds (two weeks).
|
||||
|
||||
* If it took fewer than two weeks to generate the 2,016 blocks,
|
||||
the expected difficulty value is increased proportionally (by as much
|
||||
as 300%) so that the next 2,016 blocks should take exactly two weeks
|
||||
to generate if hashes are checked at the same rate.
|
||||
|
||||
* If it took more than two weeks to generate the blocks, the expected
|
||||
difficulty value is decreased proportionally (by as much as 75%) for
|
||||
the same reason.
|
||||
|
||||
(Note: an off-by-one error in the Bitcoin Core implementation causes the
|
||||
difficulty to be updated every 2,01*6* blocks using timestamps from only
|
||||
2,01*5* blocks, creating a slight skew.)
|
||||
|
||||
Because each block header must hash to a value below the target
|
||||
threshold, and because each block is linked to the block that
|
||||
preceded it, it requires (on average) as much hashing power to
|
||||
propagate a modified block as the entire Bitcoin network expended
|
||||
between the time the original block was created and the present time.
|
||||
Only if you acquired a majority of the network's hashing power
|
||||
could you reliably execute such a [51 percent attack][]{:#term-51-attack}{:.term} against
|
||||
transaction history.
|
||||
|
||||
The block header provides several easy-to-modify fields, such as a
|
||||
dedicated nonce field, so obtaining new hashes doesn't require waiting
|
||||
for new transactions. Also, only the 80-byte block header is hashed for
|
||||
proof-of-work, so adding more bytes of transaction data to
|
||||
a block does not slow down hashing with extra I/O.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Block Height And Forking
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Any Bitcoin miner who successfully hashes a block header to a value
|
||||
below the target threshold can add the entire block to the block chain.
|
||||
(Assuming the block is otherwise valid.) These blocks are commonly addressed
|
||||
by their [block height][]{:#term-block-height}{:.term}---the number of blocks between them and the first Bitcoin
|
||||
block (block 0, most commonly known as the [genesis block]{:#term-genesis-block}{:.term}). For example,
|
||||
block 2016 is where difficulty could have been first adjusted.
|
||||
|
||||

|
||||
|
||||
Multiple blocks can all have the same block height, as is common when
|
||||
two or more miners each produce a block at roughly the same time. This
|
||||
creates an apparent [fork][accidental fork]{:#term-accidental-fork}{:.term} in the block chain, as shown in the
|
||||
illustration above.
|
||||
|
||||
When miners produce simultaneous blocks at the end of the block chain, each
|
||||
peer individually chooses which block to trust. (In the absence of
|
||||
other considerations, discussed below, peers usually trust the first
|
||||
block they see.)
|
||||
|
||||
Eventually a miner produces another block which attaches to only one of
|
||||
the competing simultaneously-mined blocks. This makes that side of
|
||||
the fork longer than the other side. Assuming a fork only contains valid
|
||||
blocks, normal peers always follow the longest fork (the most difficult chain
|
||||
to recreate) and throw away ([orphan][]{:#term-orphan}{:.term}) blocks belonging to shorter forks.
|
||||
|
||||
[Long-term forks][long-term fork]{:#term-long-term-fork}{:.term} are possible if different miners work at cross-purposes,
|
||||
such as some miners diligently working to extend the block chain at the
|
||||
same time other miners are attempting a 51 percent attack to revise
|
||||
transaction history.
|
||||
|
||||
Since multiple blocks can have the same height during a block chain fork, block
|
||||
height should not be used as a globally unique identifier. Instead, blocks
|
||||
are usually referenced by the SHA256(SHA256()) hash of their header.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Transaction Data
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Every block must include one or more transactions. The first one of these
|
||||
transactions must be a coinbase transaction which should collect and
|
||||
spend the block reward and any transaction fees paid by transactions included in this block.
|
||||
|
||||
The UTXO of a coinbase transaction has the special condition that
|
||||
it cannot be spent (used as an input) for at least 100 blocks. This temporarily
|
||||
prevents a miner from spending the transaction fees and block reward from a
|
||||
block that may later be orphaned (destroyed) after a block chain fork.
|
||||
|
||||
Blocks are not required to include any non-coinbase transactions, but
|
||||
miners almost always do include additional transactions in order to
|
||||
collect their transaction fees.
|
||||
|
||||
All transactions, including the coinbase transaction, are encoded into
|
||||
blocks in binary rawtransaction format prefixed by a block transaction
|
||||
sequence number.
|
||||
|
||||
The rawtransaction format is hashed to create the transaction
|
||||
identifier (txid). From these txids, the [Merkle tree][]{:#term-merkle-tree}{:.term} is constructed by pairing each
|
||||
txid with one other txid and then hashing them together. If there are
|
||||
an odd number of txids, the txid without a partner is hashed with a
|
||||
copy of itself.
|
||||
|
||||
The resulting hashes themselves are each paired with one other hash and
|
||||
hashed together. Any hash without a partner is hashed with itself. The
|
||||
process repeats until only one hash remains, the Merkle root.
|
||||
|
||||
For example, if transactions were merely joined (not hashed), a
|
||||
five-transaction Merkle tree would look like the following text diagram:
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
ABCDEEEE .......Merkle root
|
||||
/ \
|
||||
ABCD EEEE
|
||||
/ \ /
|
||||
AB CD EE .......E is paired with itself
|
||||
/ \ / \ /
|
||||
A B C D E .........Transactions
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
As discussed in the Simplified Payment Verification (SPV) subsection,
|
||||
the Merkle tree allows clients to verify for
|
||||
themselves that a transaction was included in a block by obtaining the
|
||||
Merkle root from a block header and a list of the intermediate hashes
|
||||
from a full peer. The full peer does not need to be trusted: it is
|
||||
expensive to fake block headers and the intermediate hashes cannot be faked or
|
||||
the verification will fail.
|
||||
|
||||
For example, to verify transaction D was added to the
|
||||
block, an SPV client only needs a copy of the C, AB, and EEEE hashes in addition to the
|
||||
Merkle root; the client doesn't need to know anything about any of the
|
||||
other transactions. If the five transactions in this block were all at
|
||||
the maximum size, downloading the entire block would require over
|
||||
500,000 bytes---but downloading three hashes plus the block header
|
||||
requires only 140 bytes.
|
||||
|
||||
{% endautocrossref %}
|
281
_includes/guide_contracts.md
Normal file
|
@ -0,0 +1,281 @@
|
|||
## Contracts
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Contracts are
|
||||
transactions which use the decentralized Bitcoin system to enforce financial
|
||||
agreements.
|
||||
Bitcoin contracts can often be crafted to minimize dependency on outside
|
||||
agents, such as the court system, which significantly decreases the risk
|
||||
of dealing with unknown entities in financial transactions.
|
||||
|
||||
The following subsections will describe a variety of Bitcoin contracts
|
||||
already in use. Because contracts deal with real people, not just
|
||||
transactions, they are framed below in story format.
|
||||
|
||||
Besides the contract types described below, many other contract types
|
||||
have been proposed. Several of them are collected on the [Contracts
|
||||
page](https://en.bitcoin.it/wiki/Contracts) of the Bitcoin Wiki.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Escrow And Arbitration
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Charlie-the-customer wants to buy a product from Bob-the-businessman,
|
||||
but neither of them trusts the other person, so they use a contract to
|
||||
help ensure Charlie gets his merchandise and Bob gets his payment.
|
||||
|
||||
A simple contract could say that Charlie will spend satoshis to an
|
||||
output which can only be spent if Charlie and Bob both sign the input
|
||||
spending it. That means Bob won't get paid unless Charlie gets his
|
||||
merchandise, but Charlie can't get the merchandise and keep his payment.
|
||||
|
||||
This simple contract isn't much help if there's a dispute, so Bob and
|
||||
Charlie enlist the help of Alice-the-arbitrator to create an [escrow
|
||||
contract][]{:#term-escrow-contract}{:.term}. Charlie spends his satoshis
|
||||
to an output which can only be spent if two of the three people sign the
|
||||
input. Now Charlie can pay Bob if everything is ok, Bob can refund
|
||||
Charlie's money if there's a problem, or Alice can arbitrate and decide
|
||||
who should get the satoshis if there's a dispute.
|
||||
|
||||
To create a multiple-signature ([multisig][]{:#term-multisig}{:.term})
|
||||
output, they each give the others a public key. Then Bob creates the
|
||||
following [P2SH multisig][]{:#term-p2sh-multisig}{:.term} redeemScript:
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
OP_2 [A's pubkey] [B's pubkey] [C's pubkey] OP_3 OP_CHECKMULTISIG
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
(Op codes to push the public keys onto the stack are not shown.)
|
||||
|
||||
`OP_2` and `OP_3` push the actual numbers 2 and 3 onto the
|
||||
stack. `OP_2`
|
||||
specifies that 2 signatures are required to sign; `OP_3` specifies that
|
||||
3 public keys (unhashed) are being provided. This is a 2-of-3 multisig
|
||||
script, more generically called a m-of-n script (where *m* is the
|
||||
*minimum* matching signatures required and *n* in the *number* of public
|
||||
keys provided).
|
||||
|
||||
Bob gives the redeemScript to Charlie, who checks to make sure his
|
||||
public key and Alice's public key are included. Then he hashes the
|
||||
redeemScript, puts it in a P2SH output, and pays the satoshis to it. Bob
|
||||
sees the payment get added to the block chain and ships the merchandise.
|
||||
|
||||
Unfortunately, the merchandise gets slightly damaged in transit. Charlie
|
||||
wants a full refund, but Bob thinks a 10% refund is sufficient. They
|
||||
turn to Alice to resolve the issue. Alice asks for photo evidence from
|
||||
Charlie along with a copy of the unhashed redeemScript Bob created and
|
||||
Charlie checked.
|
||||
|
||||
After looking at the evidence, Alice thinks a 40% refund is sufficient,
|
||||
so she creates and signs a transaction with two outputs, one that spends 60%
|
||||
of the satoshis to Bob's public key and one that spends the remaining
|
||||
40% to Charlie's public key.
|
||||
|
||||
In the input section of the script, Alice puts her signature
|
||||
and a copy of the unhashed serialized redeemScript
|
||||
that Bob created. She gives a copy of the incomplete transaction to
|
||||
both Bob and Charlie. Either one of them can complete it by adding
|
||||
his signature to create the following input
|
||||
script:
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
OP_0 [A's signature] [B's or C's signature] [serialized redeemScript]
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
(Op codes to push the signatures and redeemScript onto the stack are
|
||||
not shown. `OP_0` is a workaround for an off-by-one error in the original
|
||||
implementation which must be preserved for compatibility.)
|
||||
|
||||
When the transaction is broadcast to the network, each peer checks the
|
||||
input script against the P2SH output Charlie previously paid,
|
||||
ensuring that the redeemScript matches the redeemScript hash previously
|
||||
provided. Then the redeemScript is evaluated, with the two signatures
|
||||
being used as input<!--noref--> data. Assuming the redeemScript
|
||||
validates, the two transaction outputs show up in Bob's and Charlie's
|
||||
wallets as spendable balances.
|
||||
|
||||
However, if Alice created and signed a transaction neither of them would
|
||||
agree to, such as spending all the satoshis to herself, Bob and Charlie
|
||||
can find a new arbitrator and sign a transaction spending the satoshis
|
||||
to another 2-of-3 multisig redeemScript hash, this one including a public
|
||||
key from that second arbitrator. This means that Bob and Charlie never
|
||||
need to worry about their arbitrator stealing their money.
|
||||
|
||||
**Resource:** [BitRated](https://www.bitrated.com/) provides a multisig arbitration
|
||||
service interface using HTML/JavaScript on a GNU AGPL-licensed website.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Micropayment Channel
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
<!-- SOMEDAY: try to rewrite using a more likely real-world example without
|
||||
making the text or illustration more complicated -->
|
||||
|
||||
Alice also works part-time moderating forum posts for Bob. Every time
|
||||
someone posts to Bob's busy forum, Alice skims the post to make sure it
|
||||
isn't offensive or spam. Alas, Bob often forgets to pay her, so Alice
|
||||
demands to be paid immediately after each post she approves or rejects.
|
||||
Bob says he can't do that because hundreds of small payments will cost
|
||||
him thousands of satoshis in transaction fees, so Alice suggests they use a
|
||||
[micropayment channel][]{:#term-micropayment-channel}{:.term}.
|
||||
|
||||
Bob asks Alice for her public key and then creates two transactions.
|
||||
The first transaction pays 100 millibits to a P2SH output whose
|
||||
2-of-2 multisig redeemScript requires signatures from both Alice and Bob.
|
||||
This is the bond transaction.
|
||||
Broadcasting this transaction would let Alice hold the millibits
|
||||
hostage, so Bob keeps this transaction private for now and creates a
|
||||
second transaction.
|
||||
|
||||
The second transaction spends all of the first transaction's millibits
|
||||
(minus a transaction fee) back to Bob after a 24 hour delay enforced
|
||||
by locktime. This is the refund transaction. Bob can't sign the refund transaction by himself, so he gives
|
||||
it to Alice to sign, as shown in the
|
||||
illustration below.
|
||||
|
||||

|
||||
|
||||
Alice checks that the refund transaction's locktime is 24 hours in the
|
||||
future, signs it, and gives a copy of it back to Bob. She then asks Bob
|
||||
for the bond transaction and checks that the refund transaction spends
|
||||
the output of the bond transaction. She can now broadcast the bond
|
||||
transaction to the network to ensure Bob has to wait for the time lock
|
||||
to expire before further spending his millibits. Bob hasn't actually
|
||||
spent anything so far, except possibly a small transaction fee, and
|
||||
he'll be able to broadcast the refund transaction in 24 hours for a
|
||||
full refund.
|
||||
|
||||
Now, when Alice does some work worth 1 millibit, she asks Bob to create
|
||||
and sign a new version of the refund transaction. Version two of the
|
||||
transaction spends 1 millibit to Alice and the other 99 back to Bob; it does
|
||||
not have a locktime, so Alice can sign it and spend it whenever she
|
||||
wants. (But she doesn't do that immediately.)
|
||||
|
||||
Alice and Bob repeat these work-and-pay steps until Alice finishes for
|
||||
the day, or until the time lock is about to expire. Alice signs the
|
||||
final version of the refund transaction and broadcasts it, paying
|
||||
herself and refunding any remaining balance to Bob. The next day, when
|
||||
Alice starts work, they create a new micropayment channel.
|
||||
|
||||
If Alice fails to broadcast a version of the refund transaction before
|
||||
its time lock expires, Bob can broadcast the first version and receive a
|
||||
full refund. This is one reason micropayment channels are best suited to
|
||||
small payments---if Alice's Internet service goes out for a few hours
|
||||
near the time lock expiry, she could be cheated out of her payment.
|
||||
|
||||
Transaction malleability, discussed above in the Transactions section,
|
||||
is another reason to limit the value of micropayment channels.
|
||||
If someone uses transaction malleability to break the link between the
|
||||
two transactions, Alice could hold Bob's 100 millibits hostage even if she
|
||||
hadn't done any work.
|
||||
|
||||
For larger payments, Bitcoin transaction fees are very low as a
|
||||
percentage of the total transaction value, so it makes more sense to
|
||||
protect payments with immediately-broadcast separate transactions.
|
||||
|
||||
**Resource:** The [bitcoinj](http://bitcoinj.org) Java library
|
||||
provides a complete set of micropayment functions, an example
|
||||
implementation, and [a
|
||||
tutorial](https://bitcoinj.github.io/working-with-micropayments)
|
||||
all under an Apache license.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### CoinJoin
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Alice is concerned about her privacy. She knows every transaction gets
|
||||
added to the public block chain, so when Bob and Charlie pay her, they
|
||||
can each easily track those satoshis to learn what Bitcoin
|
||||
addresses she pays, how much she pays them, and possibly how many
|
||||
satoshis she has left.
|
||||
|
||||
Because Alice isn't a criminal, she doesn't want to use some shady
|
||||
Bitcoin laundering service; she just wants plausible deniability about
|
||||
where she has spent her satoshis and how many she has left, so she
|
||||
starts up the Tor anonymity service on her computer and logs into an
|
||||
IRC chatroom as "AnonGirl."
|
||||
|
||||
Also in the chatroom are "Nemo" and "Neminem." They collectively
|
||||
agree to transfer satoshis between each other so no one besides them
|
||||
can reliably determine who controls which satoshis. But they're faced
|
||||
with a dilemma: who transfers their satoshis to one of the other two
|
||||
pseudonymous persons first? The CoinJoin-style contract, shown in the
|
||||
illustration below, makes this decision easy: they create a single
|
||||
transaction which does all of the spending simultaneously, ensuring none
|
||||
of them can steal the others' satoshis.
|
||||
|
||||

|
||||
|
||||
Each contributor looks through their collection of Unspent Transaction
|
||||
Outputs (UTXOs) for 100 millibits they can spend. They then each generate
|
||||
a brand new public key and give UTXO details and pubkey hashes to the
|
||||
facilitator. In this case, the facilitator is AnonGirl; she creates
|
||||
a transaction spending each of the UTXOs to three equally-sized outputs.
|
||||
One output goes to each of the contributors' pubkey hashes.
|
||||
|
||||
AnonGirl then signs her inputs using `SIGHASH_ALL` to ensure nobody can
|
||||
change the input or output details. She gives the partially-signed
|
||||
transaction to Nemo who signs his inputs the same way and passes it
|
||||
to Neminem, who also signs it the same way. Neminem then broadcasts
|
||||
the transaction to the peer-to-peer network, mixing all of the millibits in
|
||||
a single transaction.
|
||||
|
||||
As you can see in the illustration, there's no way for anyone besides
|
||||
AnonGirl, Nemo, and Neminem to confidently determine who received
|
||||
which output, so they can each spend their output with plausible
|
||||
deniability.
|
||||
|
||||
Now when Bob or Charlie try to track Alice's transactions through the
|
||||
block chain, they'll also see transactions made by Nemo and
|
||||
Neminem. If Alice does a few more CoinJoins, Bob and Charlie might
|
||||
have to guess which transactions made by dozens or hundreds of people
|
||||
were actually made by Alice.
|
||||
|
||||
The complete history of Alice's satoshis is still in the block chain,
|
||||
so a determined investigator could talk to the people AnonGirl
|
||||
CoinJoined with to find out the ultimate origin of her satoshis and
|
||||
possibly reveal AnonGirl as Alice. But against anyone casually browsing
|
||||
block chain history, Alice gains plausible deniability.
|
||||
|
||||
The CoinJoin technique described above costs the participants a small
|
||||
amount of satoshis to pay the transaction fee. An alternative
|
||||
technique, purchaser CoinJoin, can actually save them satoshis and
|
||||
improve their privacy at the same time.
|
||||
|
||||
AnonGirl waits in the IRC chatroom until she wants to make a purchase.
|
||||
She announces her intention to spend satoshis and waits until someone
|
||||
else wants to make a purchase, likely from a different merchant. Then
|
||||
they combine their inputs the same way as before but set the outputs
|
||||
to the separate merchant addresses so nobody will be able to figure
|
||||
out solely from block chain history which one of them bought what from
|
||||
the merchants.
|
||||
|
||||
Since they would've had to pay a transaction fee to make their purchases
|
||||
anyway, AnonGirl and her co-spenders don't pay anything extra---but
|
||||
because they reduced overhead by combining multiple transactions, saving
|
||||
bytes, they may be able to pay a smaller aggregate transaction fee,
|
||||
saving each one of them a tiny amount of satoshis.
|
||||
|
||||
**Resource:** An alpha-quality (as of this writing) implementation of decentralized
|
||||
CoinJoin is [CoinMux](http://coinmux.com/), available under the Apache
|
||||
license. A centralized version of purchaser CoinJoin is available at the
|
||||
[SharedCoin](https://sharedcoin.com/) website (part of Blockchain.info),
|
||||
whose [implementation](https://github.com/blockchain/Sharedcoin) is
|
||||
available under the 4-clause BSD license.
|
||||
|
||||
{% endautocrossref %}
|
62
_includes/guide_intro.md
Normal file
|
@ -0,0 +1,62 @@
|
|||
{% autocrossref %}
|
||||
|
||||
The Developer Guide aims to provide the information you need to start
|
||||
building Bitcoin-based applications. To make the best use of this guide,
|
||||
you may want to install the current version of Bitcoin Core, either from
|
||||
[source][core git] or from a [pre-compiled executable][core executable].
|
||||
|
||||
Once installed, you'll have access to three programs: `bitcoind`,
|
||||
`bitcoin-qt`, and `bitcoin-cli`. When run with no arguments, all three
|
||||
programs default to Bitcoin's main network ([mainnet][mainnet]{:#term-mainnet}{:.term}) which will require
|
||||
you purchase satoshis in order to generate transactions.
|
||||
|
||||
However, for development, it's safer and cheaper to use Bitcoin's test
|
||||
network ([testnet][testnet]{:#term-testnet}{:.term}) where the satoshis spent have no real-world value.
|
||||
Testnet also relaxes some restrictions (such as standard transaction
|
||||
checks) so you can test functions which might currently be disabled by
|
||||
default on mainnet.
|
||||
|
||||
To use testnet, use the argument `-testnet`<!--noref--> with each program or add
|
||||
`testnet=1`<!--noref--> to your `bitcoin.conf` file. To get
|
||||
free satoshis for testing, use [Piotr Piasecki's testnet faucet][].
|
||||
Testnet is a public resource provided for free by members of the
|
||||
community, so please don't abuse it.
|
||||
|
||||
You can speed up development further using the [regression test mode][]
|
||||
which creates a new testnet local to your computer. This regtest mode
|
||||
will let you generate blocks almost instantly with a RPC command so you
|
||||
can generate your own satoshis and add transactions to the block chain
|
||||
immediately.
|
||||
|
||||
* `bitcoin-qt` provides a combination full Bitcoin peer and wallet
|
||||
frontend. From the Help menu, you can access a console where you can
|
||||
enter the RPC commands used throughout this document.
|
||||
|
||||
* `bitcoind` is more useful for programming: it provides a full peer
|
||||
which you can interact with through RPCs to port 8332 (or 18332
|
||||
for testnet).
|
||||
|
||||
* `bitcoin-cli` allows you to send RPC commands to `bitcoind` from the
|
||||
command line. For example, `bitcoin-cli help`
|
||||
|
||||
All three programs get settings from `bitcoin.conf` in the `Bitcoin`
|
||||
application directiory:
|
||||
|
||||
* Windows: `%APPDATA%\Bitcoin\`
|
||||
|
||||
* OSX: `$HOME/Library/Application Support/Bitcoin/`
|
||||
|
||||
* Linux: `$HOME/.bitcoin/`
|
||||
|
||||
Questions about Bitcoin development are best sent to the Bitcoin [Forum][forum
|
||||
tech support] and [IRC channels][]. Errors or suggestions related to
|
||||
documentation on Bitcoin.org can be [submitted as an issue][docs issue]
|
||||
or posted to the [bitcoin-documentation mailing list][].
|
||||
|
||||
In the following guide,
|
||||
some strings have been shortened or wrapped: "[...]" indicates extra data was removed, and lines ending in a single backslash "\\" are continued below.
|
||||
If you hover your mouse over a paragraph, cross-reference links will be
|
||||
shown in blue. If you hover over a cross-reference link, a brief
|
||||
definition of the term will be displayed in a tooltip.
|
||||
|
||||
{% endautocrossref %}
|
202
_includes/guide_mining.md
Normal file
|
@ -0,0 +1,202 @@
|
|||
## Mining
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Mining adds new blocks to the block chain, making transaction history
|
||||
hard to modify. Mining today takes on two forms:
|
||||
|
||||
* Solo mining, where the miner attempts to generate new blocks on his
|
||||
own, with the proceeds from the block reward and transaction fees
|
||||
going entirely to himself, allowing him to receive large payments with
|
||||
a higher variance (longer time between payments)
|
||||
|
||||
* Pooled mining, where the miner pools resources with other miners to
|
||||
find blocks more often, with the proceeds being shared among the pool
|
||||
miners in rough correlation to the amount of hashing power
|
||||
they each contributed, allowing the miner to receive small
|
||||
payments with a lower variance (shorter time between payments).
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Solo Mining
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
As illustrated below, solo miners typically use `bitcoind` to get new
|
||||
transactions from the network. Their mining software periodically polls
|
||||
`bitcoind` for new transactions using the `getblocktemplate` RPC, which
|
||||
provides the list of new transactions plus the public key to which the
|
||||
coinbase transaction should be sent.
|
||||
|
||||

|
||||
|
||||
The mining software constructs a block using the template (described below) and creates a
|
||||
block header. It then sends the 80-byte block header to its mining
|
||||
hardware (an ASIC) along with a target threshold (difficulty setting).
|
||||
The mining hardware iterates through every possible value for the block
|
||||
header nonce and generates the corresponding hash.
|
||||
|
||||
If none of the hashes are below the threshold, the mining hardware gets
|
||||
an updated block header with a new Merkle root from the mining software;
|
||||
this new block header is created by adding extra nonce data to the
|
||||
coinbase field of the coinbase transaction.
|
||||
|
||||
On the other hand, if a hash is found below the target threshold, the
|
||||
mining hardware returns the block header with the successful nonce to
|
||||
the mining software. The mining software combines the header with the
|
||||
block and sends the completed block to `bitcoind` to be broadcast to the network for addition to the
|
||||
block chain.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Pool Mining
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Pool miners follow a similar workflow, illustrated below, which allows
|
||||
mining pool operators to pay miners based on their share of the work
|
||||
done. The mining pool gets new transactions from the network using
|
||||
`bitcoind`. Using one of the methods discussed later, each miner's mining
|
||||
software connects to the pool and requests the information it needs to
|
||||
construct block headers.
|
||||
|
||||

|
||||
|
||||
In pooled mining, the mining pool sets the target threshold a few orders
|
||||
of magnitude higher (less difficult) than the network
|
||||
difficulty. This causes the mining hardware to return many block headers
|
||||
which don't hash to a value eligible for inclusion on the block chain
|
||||
but which do hash below the pool's target, proving (on average) that the
|
||||
miner checked a percentage of the possible hash values.
|
||||
|
||||
The miner then sends to the pool a copy of the information the pool
|
||||
needs to validate that the header will hash below the target and that
|
||||
the the block of transactions referred to by the header Merkle root field
|
||||
is valid for the pool's purposes. (This usually means that the coinbase
|
||||
transaction must pay the pool.)
|
||||
|
||||
The information the miner sends to the pool is called a share because it
|
||||
proves the miner did a share of the work. By chance, some shares the
|
||||
pool receives will also be below the network target---the mining pool
|
||||
sends these to the network to be added to the block chain.
|
||||
|
||||
The block reward and transaction fees that come from mining that block
|
||||
are paid to the mining pool. The mining pool pays out a portion of
|
||||
these proceeds to individual miners based on how many shares they generated. For
|
||||
example, if the mining pool's target threshold is 100 times lower than
|
||||
the network target threshold, 100 shares will need to be generated on
|
||||
average to create a successful block, so the mining pool can pay 1/100th
|
||||
of its payout for each share received. Different mining pools use
|
||||
different reward distribution systems based on this basic share system.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Block Prototypes
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
In both solo and pool mining, the mining software needs to get the
|
||||
information necessary to construct block headers. This subsection
|
||||
describes, in a linear way, how that information is transmitted and
|
||||
used. However, in actual implementations, parallel threads and queuing
|
||||
are used to keep ASIC hashers working at maximum capacity,
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
#### getwork RPC
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
The simplest and earliest method was the now-deprecated Bitcoin Core
|
||||
`getwork` RPC, which constructs a header for the miner directly. Since a
|
||||
header only contains a single 4-byte nonce good for about 4 gigahashes,
|
||||
many modern miners need to make dozens or hundreds of `getwork` requests
|
||||
a second. Solo miners may still use `getwork`, but most pools today
|
||||
discourage or disallow its use.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
#### getblocktemplate RPC
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
An improved method is the Bitcoin Core `getblocktemplate` RPC. This
|
||||
provides the mining software with much more information:
|
||||
|
||||
1. The information necessary to construct a coinbase transaction
|
||||
paying the pool or the solo miner's `bitcoind` wallet.
|
||||
|
||||
2. A complete dump of the transactions `bitcoind` or the mining pool
|
||||
suggests including in the block, allowing the mining software to
|
||||
inspect the transactions, optionally add additional transactions, and
|
||||
optionally remove non-required transactions.
|
||||
|
||||
3. Other information necessary to construct a block header for the next
|
||||
block: the block version, previous block hash, and bits (target).
|
||||
|
||||
4. The mining pool's current target threshold for accepting shares. (For
|
||||
solo miners, this is the network target.)
|
||||
|
||||
Using the transactions received, the mining software adds a nonce to the
|
||||
coinbase extra nonce field and then converts all the transactions into a
|
||||
Merkle tree to derive a Merkle root it can use in a block header.
|
||||
Whenever the extra nonce field needs to be changed, the mining software
|
||||
rebuilds the necessary parts of the Merkle tree and updates the time and
|
||||
Merkle root fields in the block header.
|
||||
|
||||
Like all `bitcoind` RPCs, `getblocktemplate` is sent over HTTP. To
|
||||
ensure they get the most recent work, most miners use [HTTP longpoll][] to
|
||||
leave a `getblocktemplate` request open at all times. This allows the
|
||||
mining pool to push a new `getblocktemplate` to the miner as soon as any
|
||||
miner on the peer-to-peer network publishes a new block or the pool
|
||||
wants to send more transactions to the mining software.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
#### Stratum
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
A widely used alternative to `getblocktemplate` is the [Stratum mining
|
||||
protocol][]. Stratum focuses on giving miners the minimal information they
|
||||
need to construct block headers on their own:
|
||||
|
||||
1. The information necessary to construct a coinbase transaction
|
||||
paying the pool.
|
||||
|
||||
2. The parts of the Merkle tree which need to be re-hashed to
|
||||
create a new Merkle root when the coinbase transaction is
|
||||
updated with a new extra nonce. The other parts of the Merkle
|
||||
tree, if any, are not sent, effectively limiting the amount of data which needs
|
||||
to be sent to (at most) about a kilobyte at current transaction
|
||||
volume.
|
||||
|
||||
3. All of the other non-Merkle root information necessary to construct a
|
||||
block header for the next block.
|
||||
|
||||
4. The mining pool's current target threshold for accepting shares.
|
||||
|
||||
Using the coinbase transaction received, the mining software adds a
|
||||
nonce to the coinbase extra nonce field, hashes the coinbase
|
||||
transaction, and adds the hash to the received parts of the Merkle tree.
|
||||
The tree is hashed as necessary to create a Merkle root, which is added
|
||||
to the block header information received. Whenever the extra nonce field
|
||||
needs to be changed, the mining software updates and re-hashes the
|
||||
coinbase transaction, rebuilds the Merkle root, and updates the header
|
||||
Merkle root field.
|
||||
|
||||
Unlike `getblocktemplate`, miners using Stratum cannot inspect or add
|
||||
transactions to the block they're currently mining. Also unlike
|
||||
`getblocktemplate`, the Stratum protocol uses a two-way TCP socket directly,
|
||||
so miners don't need to use HTTP longpoll to ensure they receive
|
||||
immediate updates from mining pools when a new block is broadcast to the
|
||||
peer-to-peer network.
|
||||
|
||||
<!-- SOMEDAY: describe p2pool -->
|
||||
|
||||
**Resources:** For more information, please see the [BFGMiner][] mining
|
||||
software licensed under GPLv3 or the [Eloipool][] mining pool software
|
||||
licensed under AGPLv3. A number of other mining and pool programs
|
||||
exist, although many are forks of BFGMiner or Eloipool.
|
||||
|
||||
{% endautocrossref %}
|
91
_includes/guide_operating_modes.md
Normal file
|
@ -0,0 +1,91 @@
|
|||
## Operating Modes
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Currently there are two primary methods of validating the block chain as a client: Full nodes and SPV clients. Other methods, such as server-trusting methods, are not discussed as they are not recommended.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Full Node
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
The first and most secure model is the one followed by Bitcoin Core, also known as a “thick” or “full chain” client. This security model assures the validity of the block chain by downloading and validating blocks from the genesis block all the way to the most recently discovered block. This is known as using the *height* of a particular block to verify the client’s view of the network.
|
||||
|
||||
For a client to be fooled, an adversary would need to give a complete alternative block chain history that is of greater difficulty than the current “true” chain, which is impossible due to the fact that the longest chain is by definition the true chain. After the suggested six confirmations, the ability to fool the client become intractable, as only a single honest network node is needed to have the complete state of the block chain.
|
||||
|
||||

|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Simplified Payment Verification (SPV)
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
An alternative approach detailed in the [original Bitcoin paper][bitcoinpdf] is a client that only downloads the headers of blocks during the initial syncing process and then requests transactions from full nodes as needed. This scales linearly with the height of the block chain at only 80 bytes per block header, or up to 4.2MB per year, regardless of total block size.
|
||||
|
||||
As described in the white paper, the Merkle root in the block header along with a Merkle branch can prove to the SPV client that the transaction in question is embedded in a block in the block chain. This does not guarantee validity of the transactions that are embedded. Instead it demonstrates the amount of work required to perform a double-spend attack.
|
||||
|
||||
The block's depth in the block chain corresponds to the cumulative difficulty that has been performed to build on top of that particular block. The SPV client knows the Merkle root and associated transaction information, and requests the respective Merkle branch from a full node. Once the Merkle branch has been retrieved, proving the existence of the transaction in the block, the SPV client can then look to block *depth* as a proxy for transaction validity and security. The cost of an attack on a user by a malicious node who inserts an invalid transaction grows with the cumulative difficulty built on top of that block, since the malicious node alone will be mining this forged chain.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
#### Potential SPV Weaknesses
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
If implemented naively, an SPV client has a few important weaknesses.
|
||||
|
||||
First, while the SPV client can not be easily fooled into thinking a transaction is in a block when it is not, the reverse is not true. A full node can simply lie by omission, leading an SPV client to believe a transaction has not occurred. This can be considered a form of Denial of Service. One mitigation strategy is to connect to a number of full nodes, and send the requests to each node. However this can be defeated by network partitioning or Sybil attacks, since identities are essentially free, and can be bandwidth intensive. Care must be taken to ensure the client is not cut off from honest nodes.
|
||||
|
||||
Second, the SPV client only requests transactions from full nodes corresponding to keys it owns. If the SPV client downloads all blocks and then discards unneeded ones, this can be extremely bandwidth intensive. If they simply ask full nodes for blocks with specific transactions, this allows full nodes a complete view of the public addresses that correspond to the user. This is a large privacy leak, and allows for tactics such as denial of service for clients, users, or addresses that are disfavored by those running full nodes, as well as trivial linking of funds. A client could simply spam many fake transaction requests, but this creates a large strain on the SPV client, and can end up defeating the purpose of thin clients altogether.
|
||||
|
||||
To mitigate the latter issue, Bloom filters have been implemented as a method of obfuscation and compression of block data requests.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
#### Bloom Filters
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
A Bloom filter is a space-efficient probabilistic data structure that is used to test membership of an element. The data structure achieves great data compression at the expense of a prescribed false positive rate.
|
||||
|
||||
A Bloom filter starts out as an array of n bits all set to 0. A set of k random hash functions are chosen, each of which output<!--noref--> a single integer between the range of 1 and n.
|
||||
|
||||
When adding an element to the Bloom filter, the element is hashed k times separately, and for each of the k outputs<!--noref-->, the corresponding Bloom filter bit at that index is set to 1.
|
||||
|
||||
<!-- Add picture here from wikipedia to explain the bits -->
|
||||
|
||||
Querying of the Bloom filter is done by using the same hash functions as before. If all k bits accessed in the bloom filter are set to 1, this demonstrates with high probability that the element lies in the set. Clearly, the k indices could have been set to 1 by the addition of a combination of other elements in the domain, but the parameters allow the user to choose the acceptable false positive rate.
|
||||
|
||||
Removal of elements can only be done by scrapping the bloom filter and re-creating it from scratch.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
#### Application Of Bloom Filters
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Rather than viewing the false positive rates as a liability, it is used to create a tunable parameter that represents the desired privacy level and bandwidth trade-off. A SPV client creates their Bloom filter and sends it to a full node using the message `filterload`, which sets the filter for which transactions are desired. The command `filteradd` allows addition of desired data to the filter without needing to send a totally new Bloom filter, and `filterclear` allows the connection to revert to standard block discovery mechanisms. If the filter has been loaded, then full nodes will send a modified form of blocks, called a merkleblock. The merkleblock is simply the block header with the merkle branch associated with the set Bloom filter.
|
||||
|
||||
An SPV client can not only add transactions as elements to the filter, but also public keys, data from input and outputs scripts, and more. This enables P2SH transaction finding.
|
||||
|
||||
If a user is more privacy-conscious, he can set the Bloom filter to include more false positives, at the expense of extra bandwidth used for transaction discovery. If a user is on a tight bandwidth budget, he can set the false-positive rate to low, knowing that this will allow full nodes a clear view of what transactions are associated with his client.
|
||||
|
||||
**Resources:** [BitcoinJ](http://bitcoinj.org), a Java implementation of Bitcoin that is based on the SPV security model and Bloom filters. Used in most Android wallets.
|
||||
|
||||
Bloom filters were standardized for use via [BIP37](https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki). Review the BIP for implementation details.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Future Proposals
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
There are future proposals such as Unused Output Tree (UOT) in the block chain to find a more satisfactory middle-ground for clients between needing a complete copy of the block chain, or trusting that a majority of your connected peers are not lying. UOT would enable a very secure client using a finite amount of storage using a data structure that is authenticated in the block chain. These type of proposals are, however, in very early stages, and will require soft forks in the network.
|
||||
|
||||
Until these types of operating modes are implemented, modes should be chosen based on the likely threat model, computing and bandwidth constraints, and liability in bitcoin value.
|
||||
|
||||
**Resources:** [Original Thread on UOT](https://bitcointalk.org/index.php?topic=88208.0), [UOT Prefix Tree BIP Proposal](https://github.com/maaku/bips/blob/master/drafts/auth-trie.mediawiki)
|
||||
|
||||
{% endautocrossref %}
|
78
_includes/guide_p2p_network.md
Normal file
|
@ -0,0 +1,78 @@
|
|||
## P2P Network
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
The Bitcoin [network][network]{:#term-network}{:.term} uses simple methods to perform peer discovery and communicate between nodes. The following section applies to both full nodes and SPV clients, with the exception that SPV's Bloom filters take the role of block discovery.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Peer Discovery
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Bitcoin Core maintains a list of [peers][peer]{:#term-peer}{:.term} to connect to on startup. When a full node is started for the first time, it must be bootstrapped to the network. This is done automatically today in Bitcoin Core by a short list of trusted DNS seeds. The option `-dnsseed` can be set to define this behavior, though the default is `1`. DNS requests return a list of IP addresses that can be connected to. From there, the client can start connecting the Bitcoin network.
|
||||
|
||||
Alternatively, bootstrapping can be done by using the option `-seednode=<ip>`, allowing the user to predefine what seed server to connect to, then disconnect after building a peer list. Another method is starting Bitcoin Core with `-connect=<ip>` which disallows the node from connecting to any peers except those specified. Lastly, the argument `-addnode=<ip>` simply allows the user to add a single node to his peer list.
|
||||
|
||||
After bootstrapping, nodes send out a `addr` message containing their own IP to peers. Each peer of that node then forwards this message to a couple of their own peers to expand the pool of possible connections.
|
||||
|
||||
To see which peers one is connected with (and associated data), use the `getpeerinfo` RPC.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Connecting To Peers
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Connecting to a peer is done by sending a `version` message, which contains your version number, block, and current time to the remote node. Once the message is received by the remote node, it must respond with a `verack` message, which may be followed by its own `version` message if the node desires to peer.
|
||||
|
||||
Once connected, the client can send to the remote node `getaddr` and `addr` messages to gather additional peers.
|
||||
|
||||
In order to maintain a connection with a peer, nodes by default will send a message to peers before 30 minutes of inactivity. If 90 minutes pass without a message being received by a peer, the client will assume that connection has closed.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Block Broadcasting
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
At the start of a connection with a peer, both nodes send `getblocks` messages containing the hash of the latest known block. If a peer believes they have newer blocks or a longer chain, that peer will send an `inv` message which includes a list of up to 500 hashes of newer blocks, stating that it has the longer chain. The receiving node would then request these blocks using the command `getdata`, and the remote peer would reply via `block`<!--noref--> messages. After all 500 blocks have been processed, the node can request another set with `getblocks`, until the node is caught up with the network. Blocks are only accepted when validated by the receiving node.
|
||||
|
||||
New blocks are also discovered as miners publish their found blocks, and these messages are propagated in a similar manner. Through previously established connections, an `inv` message is sent with the new block hashed, and the receiving node requests the block via the `getdata` message.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Transaction Broadcasting
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
In order to send a transaction to a peer, an `inv` message is sent. If a `getdata` response message is received, the transaction is sent using `tx`. The peer receiving this transaction also forwards the transaction in the same manner, given that it is a valid transaction. If the transaction is not put into a block for an extended period of time, it will be dropped from mempool, and the client of origin will have to re-broadcast the message.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Misbehaving Nodes
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Take note that for both types of broadcasting, mechanisms are in place to punish misbehaving peers who take up bandwidth and computing resources by sending false information. If a peer gets a banscore above the `-banscore=<n>` threshold, he will be banned for the number of seconds defined by `-bantime=<n>`, which is 86,400 by default (24 hours).
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Alerts
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
In case of a bug or attack,
|
||||
the Bitcoin Core developers provide a
|
||||
[Bitcoin alert service](https://bitcoin.org/en/alerts) with an RSS feed
|
||||
and users of Bitcoin Core can check the error field of the `getinfo` RPC
|
||||
results to get currently active alerts for their specific version of
|
||||
Bitcoin Core.
|
||||
|
||||
These messages are aggressively broadcast using the `alert` message, being sent to each peer upon connect for the duration of the alert.
|
||||
|
||||
These messages are signed by a specific ECDSA private key that only a small number of developers control.
|
||||
|
||||
**Resource:** More details about the structure of messages and a complete list of message types can be found at the [Protocol Specification](https://en.bitcoin.it/wiki/Protocol_specification) page of the Bitcoin Wiki.
|
||||
|
||||
{% endautocrossref %}
|
1291
_includes/guide_payment_processing.md
Normal file
677
_includes/guide_transactions.md
Normal file
|
@ -0,0 +1,677 @@
|
|||
## Transactions
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
<!-- reference tx (made by Satoshi in block 170):
|
||||
bitcoind decoderawtransaction $( bitcoind getrawtransaction f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16 )
|
||||
-->
|
||||
|
||||
<!-- SOMEDAY: we need more terms than just output/input to denote the
|
||||
various ways the outputs/inputs are used, such as "prevout", "nextout",
|
||||
"curout", "curin", "nextin". (Is there any use for "previn"?) Someday,
|
||||
when I'm terribly bored, I should rewrite this whole transaction section
|
||||
to use those terms and then get feedback to see if it actually helps. -harding -->
|
||||
|
||||
Transactions let users spend satoshis. Each transaction is constructed
|
||||
out of several parts which enable both simple direct payments and complex
|
||||
transactions. This section will describe each part and
|
||||
demonstrate how to use them together to build complete transactions.
|
||||
|
||||
To keep things simple, this section pretends coinbase transactions do
|
||||
not exist. Coinbase transactions can only be created by Bitcoin miners
|
||||
and they're an exception to many of the rules listed below. Instead of
|
||||
pointing out the coinbase exception to each rule, we invite you to read
|
||||
about coinbase transactions in the block chain section of this guide.
|
||||
|
||||

|
||||
|
||||
The figure above shows the core parts of a Bitcoin transaction. Each
|
||||
transaction has at least one input and one output. Each [input][]{:#term-input}{:.term} spends the
|
||||
satoshis paid to a previous output. Each [output][]{:#term-output}{:.term} then waits as an Unspent
|
||||
Transaction Output (UTXO) until a later input spends it. When your
|
||||
Bitcoin wallet tells you that you have a 10,000 satoshi balance, it really
|
||||
means that you have 10,000 satoshis waiting in one or more UTXOs.
|
||||
|
||||
Each transaction is prefixed by a four-byte [transaction version number][]{:#term-transaction-version-number}{:.term} which tells
|
||||
Bitcoin peers and miners which set of rules to use to validate it. This
|
||||
lets developers create new rules for future transactions without
|
||||
invalidating previous transactions.
|
||||
|
||||
The figures below help illustrate the other transaction features by
|
||||
showing the workflow Alice uses to send Bob a transaction and which Bob
|
||||
later uses to spend that transaction. Both Alice and Bob will use the
|
||||
most common form of the standard Pay-To-Public-Key-Hash (P2PKH) transaction
|
||||
type. [P2PKH][]{:#term-p2pkh}{:.term} lets Alice spend satoshis to a typical Bitcoin address,
|
||||
and then lets Bob further spend those satoshis using a simple
|
||||
cryptographic key pair.
|
||||
|
||||

|
||||
|
||||
Bob must first generate a private/public [key pair][]{:#term-key-pair}{:.term} before Alice can create the
|
||||
first transaction. Standard Bitcoin [private keys][private
|
||||
key]{:#term-private-key}{:.term} are 256 bits of random
|
||||
data. A copy of that data is deterministically transformed into a [public
|
||||
key][]{:#term-public-key}{:.term}. Because the transformation can be reliably repeated later, the
|
||||
public key does not need to be stored.
|
||||
|
||||
The public key is then cryptographically hashed. This pubkey hash can
|
||||
also be reliably repeated later, so it also does not need to be stored.
|
||||
The hash shortens and obfuscates the public key, making manual
|
||||
transcription easier and providing security against
|
||||
unanticipated problems which might allow reconstruction of private keys
|
||||
from public key data at some later point.
|
||||
|
||||
<!-- Editors: from here on I will typically use the terms "pubkey hash"
|
||||
and "full public key" to provide quick differentiation between the
|
||||
different states of a public key and to help the text better match the
|
||||
space-constrained diagrams where "public-key hash" wouldn't fit. -harding -->
|
||||
|
||||
Bob provides the [pubkey hash][]{:#term-pubkey-hash}{:.term} to Alice. Pubkey hashes are almost always
|
||||
sent encoded as Bitcoin [addresses][]{:#term-address}{:.term}, which are base58-encoded strings
|
||||
containing an address version number, the hash, and an error-detection
|
||||
checksum to catch typos. The address can be transmitted
|
||||
through any medium, including one-way mediums which prevent the spender
|
||||
from communicating with the receiver, and it can be further encoded
|
||||
into another format, such as a QR code containing a `bitcoin:`
|
||||
URI.
|
||||
|
||||
Once Alice has the address and decodes it back into a standard hash, she
|
||||
can create the first transaction. She creates a standard P2PKH
|
||||
transaction output containing instructions which allow anyone to spend that
|
||||
output if they can prove they control the private key corresponding to
|
||||
Bob's hashed public key. These instructions are called the output [script][]{:#term-script}{:.term}.
|
||||
|
||||
Alice broadcasts the transaction and it is added to the block chain.
|
||||
The network categorizes it as an Unspent Transaction Output (UTXO), and Bob's
|
||||
wallet software displays it as a spendable balance.
|
||||
|
||||
When, some time later, Bob decides to spend the UTXO, he must create an
|
||||
input which references the transaction Alice created by its hash, called
|
||||
a Transaction Identifier (txid), and the specific output she used by its
|
||||
index number ([output index][]{:#term-output-index}{:.term}). He must then create a [scriptSig][]{:#term-scriptsig}{:.term}---a
|
||||
collection of data parameters which satisfy the conditions Alice placed
|
||||
in the previous output's script.
|
||||
|
||||

|
||||
|
||||
Bob does not need to communicate with Alice to do this; he must simply
|
||||
prove to the Bitcoin peer-to-peer network that he can satisfy the
|
||||
script's conditions. For a P2PKH-style output, Bob's scriptSig will
|
||||
contain the following two pieces of data:
|
||||
|
||||
1. His full (unhashed) public key, so the script can check that it
|
||||
hashes to the same value as the pubkey hash provided by Alice.
|
||||
|
||||
2. A [signature][]{:#term-signature}{:.term} made by using the ECDSA cryptographic formula to combine
|
||||
certain transaction data (described below) with Bob's private key.
|
||||
This lets the script verify that Bob owns the private key which
|
||||
created the public key.
|
||||
|
||||
Bob's signature doesn't just prove Bob controls his private key; it also
|
||||
makes the rest of his transaction tamper-proof so Bob can safely
|
||||
broadcast it over the peer-to-peer network.
|
||||
|
||||

|
||||
|
||||
As illustrated in the figure above, the data Bob signs includes the
|
||||
txid and output index of the previous transaction, the previous
|
||||
output's script, the script Bob creates which will let the next
|
||||
recipient spend this transaction's output, and the amount of satoshis to
|
||||
spend to the next recipient. In essence, the entire transaction is
|
||||
signed except for any scriptSigs, which hold the full public keys and
|
||||
signatures.
|
||||
|
||||
After putting his signature and public key in the scriptSig, Bob
|
||||
broadcasts the transaction to Bitcoin miners through the peer-to-peer
|
||||
network. Each peer and miner independently validates the transaction
|
||||
before broadcasting it further or attempting to include it in a new block of
|
||||
transactions.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### P2PKH Script Validation
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
The validation procedure requires evaluation of the script. In a P2PKH
|
||||
output, the script is:
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
OP_DUP OP_HASH160 <PubkeyHash> OP_EQUALVERIFY OP_CHECKSIG
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
The spender's scriptSig is evaluated and prefixed to the beginning of the
|
||||
script. In a P2PKH transaction, the scriptSig contains a signature (sig)
|
||||
and full public key (pubkey), creating the following concatenation:
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
<Sig> <PubKey> OP_DUP OP_HASH160 <PubkeyHash> OP_EQUALVERIFY OP_CHECKSIG
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
The script language is a
|
||||
[Forth-like](https://en.wikipedia.org/wiki/Forth_%28programming_language%29)
|
||||
[stack][]{:#term-stack}{:.term}-based language deliberately designed to be stateless and not
|
||||
Turing complete. Statelessness ensures that once a transaction is added
|
||||
to the block chain, there is no condition which renders it permanently
|
||||
unspendable. Turing-incompleteness (specifically, a lack of loops or
|
||||
gotos) makes the script language less flexible and more predictable,
|
||||
greatly simplifying the security model.
|
||||
|
||||
<!-- Editors: please do not substitute for the words push or pop in
|
||||
sections about stacks. These are programming terms. Also "above",
|
||||
"below", "top", and "bottom" are commonly used relative directions or
|
||||
locations in stack descriptions. -harding -->
|
||||
|
||||
To test whether the transaction is valid, scriptSig and script arguments
|
||||
are pushed to the stack one item at a time, starting with Bob's scriptSig
|
||||
and continuing to the end of Alice's script. The figure below shows the
|
||||
evaluation of a standard P2PKH script; below the figure is a description
|
||||
of the process.
|
||||
|
||||

|
||||
|
||||
* The signature (from Bob's scriptSig) is added (pushed) to an empty stack.
|
||||
Because it's just data, nothing is done except adding it to the stack.
|
||||
The public key (also from the scriptSig) is pushed on top of the signature.
|
||||
|
||||
* From Alice's script, the `OP_DUP` operation is pushed. `OP_DUP` replaces
|
||||
itself with a copy of the data from one level below it---in this
|
||||
case creating a copy of the public key Bob provided.
|
||||
|
||||
* The operation pushed next, `OP_HASH160`, replaces itself with a hash
|
||||
of the data from one level below it---in this case, Bob's public key.
|
||||
This creates a hash of Bob's public key.
|
||||
|
||||
* Alice's script then pushes the pubkey hash that Bob gave her for the
|
||||
first transaction. At this point, there should be two copies of Bob's
|
||||
pubkey hash at the top of the stack.
|
||||
|
||||
* Now it gets interesting: Alice's script adds `OP_EQUALVERIFY` to the
|
||||
stack. `OP_EQUALVERIFY` expands to `OP_EQUAL` and `OP_VERIFY` (not shown).
|
||||
|
||||
`OP_EQUAL` (not shown) checks the two values below it; in this
|
||||
case, it checks whether the pubkey hash generated from the full
|
||||
public key Bob provided equals the pubkey hash Alice provided when
|
||||
she created transaction #1. `OP_EQUAL` then replaces itself and
|
||||
the two values it compared with the result of that comparison:
|
||||
zero (*false*) or one (*true*).
|
||||
|
||||
`OP_VERIFY` (not shown) checks the value immediately below it. If
|
||||
the value is *false* it immediately terminates stack evaluation and
|
||||
the transaction validation fails. Otherwise it pops both itself and
|
||||
the *true* value off the stack.
|
||||
|
||||
* Finally, Alice's script pushes `OP_CHECKSIG`, which checks the
|
||||
signature Bob provided against the now-authenticated public key he
|
||||
also provided. If the signature matches the public key and was
|
||||
generated using all of the data required to be signed, `OP_CHECKSIG`
|
||||
replaces itself with *true.*
|
||||
|
||||
If *true* is at the top of the stack after the script has been
|
||||
evaluated, the transaction is valid (provided there are no other
|
||||
problems with it).
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### P2SH Scripts
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Output scripts are created by spenders who have little interest in the
|
||||
long-term security or usefulness of the particular satoshis they're
|
||||
currently spending. Receivers do care about the conditions imposed on
|
||||
the satoshis by the output script and, if they want, they can ask
|
||||
spenders to use a particular script. Unfortunately, custom scripts are
|
||||
less convenient than short Bitcoin addresses and more difficult to
|
||||
secure than P2PKH pubkey hashes.
|
||||
|
||||
To solve these problems, pay-to-script-hash
|
||||
([P2SH][]{:#term-p2sh}{:.term}) transactions were created in 2012 to let
|
||||
a spender create an output script containing a [hash of a second
|
||||
script][script hash]{:#term-script-hash}{:.term}, the
|
||||
[redeemScript][]{:#term-redeemscript}{:.term}.
|
||||
|
||||
The basic P2SH workflow, illustrated below, looks almost identical to
|
||||
the P2PKH workflow. Bob creates a redeemScript with whatever script he
|
||||
wants, hashes the redeemScript, and provides the redeemScript
|
||||
hash to Alice. Alice creates a P2SH-style output containing
|
||||
Bob's redeemScript hash.
|
||||
|
||||

|
||||
|
||||
When Bob wants to spend the output, he provides his signature along with
|
||||
the full (serialized) redeemScript in the input scriptSig. The
|
||||
peer-to-peer network ensures the full redeemScript hashes to the same
|
||||
value as the script hash Alice put in her output; it then processes the
|
||||
redeemScript exactly as it would if it were the primary script, letting
|
||||
Bob spend the output if the redeemScript returns true.
|
||||
|
||||

|
||||
|
||||
The hash of the redeemScript has the same properties as a pubkey
|
||||
hash---so it can be transformed into the standard Bitcoin address format
|
||||
with only one small change to differentiate it from a standard address.
|
||||
This makes collecting a P2SH-style address as simple as collecting a
|
||||
P2PKH-style address. The hash also obfuscates any public keys in the
|
||||
redeemScript, so P2SH scripts are as secure as P2PKH pubkey hashes.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Standard Transactions
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Care must be taken to avoid non-standard output scripts. As of Bitcoin Core
|
||||
0.9, the standard script types are:
|
||||
|
||||
**Pubkey Hash (P2PKH)**
|
||||
|
||||
P2PKH is the most common form of script used to send a transaction to one
|
||||
or multiple Bitcoin addresses.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
script: OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
|
||||
scriptSig: <sig> <pubkey>
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
**Script Hash (P2SH)**
|
||||
|
||||
P2SH is used to send a transaction to a script hash. Each of the standard
|
||||
scripts can be used inside a P2SH redeemScript, but in practice only the
|
||||
multisig script makes sense until more transaction types are made standard.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
script: OP_HASH160 <redeemscripthash> OP_EQUAL
|
||||
scriptSig: <sig> [sig] [sig...] <redeemscript>
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
**Multisig**
|
||||
|
||||
Although P2SH multisig is now generally used for multisig transactions, this base script
|
||||
can be used to require multiple signatures before a UTXO can be spent.
|
||||
|
||||
In multisig scripts, called m-of-n, *m* is the *minimum* number of signatures
|
||||
which must match a public key; *n* is the *number* of public keys being
|
||||
provided. Both *m* and *n* should be op codes `OP_1` through `OP_16`,
|
||||
corresponding to the number desired.
|
||||
|
||||
Because of an off-by-one error in the original Bitcoin implementation
|
||||
which must be preserved for compatibility, `OP_CHECKMULTISIG`
|
||||
consumes one more value from the stack than indicated by *m*, so the
|
||||
list of signatures in the scriptSig must be prefaced with an extra value
|
||||
(`OP_0`) which will be consumed but not used.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
script: <m> <pubkey> [pubkey] [pubkey...] <n> OP_CHECKMULTISIG
|
||||
scriptSig: OP_0 <sig> [sig] [sig...]
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Although it’s not a separate transaction type, this is a P2SH multisig with 2-of-3:
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
script: OP_HASH160 <redeemscripthash> OP_EQUAL
|
||||
redeemScript: <OP_2> <pubkey> <pubkey> <pubkey> <OP_3> OP_CHECKMULTISIG
|
||||
scriptSig: OP_0 <sig> <sig> <redeemscript>
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
**Pubkey**
|
||||
|
||||
[Pubkey][]{:#term-pubkey}{:.term} scripts are a simplified form of the P2PKH script,
|
||||
but they aren’t as
|
||||
secure as P2PKH, so they generally
|
||||
aren’t used in new transactions anymore.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
script: <pubkey> OP_CHECKSIG
|
||||
scriptSig: <sig>
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
**Null Data**
|
||||
|
||||
[Null data][]{:#term-null-data}{:.term} scripts let you add a small amount of arbitrary data to the block
|
||||
chain in exchange for paying a transaction fee, but doing so is discouraged.
|
||||
(Null data is a standard script type only because some people were adding data
|
||||
to the block chain in more harmful ways.)
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
script: OP_RETURN <data>
|
||||
(Null data scripts cannot be spent, so there's no scriptSig)
|
||||
~~~
|
||||
|
||||
#### Non-Standard Transactions
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
If you use anything besides a standard script in an output, peers
|
||||
and miners using the default Bitcoin Core settings will neither
|
||||
accept, broadcast, nor mine your transaction. When you try to broadcast
|
||||
your transaction to a peer running the default settings, you will
|
||||
receive an error.
|
||||
|
||||
Unfortunately, if you create a non-standard redeemScript, hash it, and use the hash
|
||||
in a P2SH output, the network sees only the hash, so it will accept the
|
||||
output as valid no matter what the redeemScript says. When you go to
|
||||
spend that output, however, peers and miners using the default settings
|
||||
will see the non-standard redeemScript and reject it. It will be
|
||||
impossible to spend that output until you find a miner who disables the
|
||||
default settings.
|
||||
|
||||
As of Bitcoin Core 0.9, standard transactions must also meet the following
|
||||
conditions:
|
||||
|
||||
* The transaction must be finalized: either its locktime must be in the
|
||||
past (or less than or equal to the current block height), or all of its sequence
|
||||
numbers must be 0xffffffff.
|
||||
|
||||
* The transaction must be smaller than 100,000 bytes. That's around 200
|
||||
times larger than a typical single-input, single-output P2PKH
|
||||
transaction.
|
||||
|
||||
* Each of the transaction's inputs must be smaller than 500 bytes.
|
||||
That's large enough to allow 3-of-3 multisig transactions in P2SH.
|
||||
Multisig transactions which require more than 3 public keys are
|
||||
currently non-standard.
|
||||
|
||||
* The transaction's scriptSig must only push data to the script
|
||||
evaluation stack. It cannot push new OP codes, with the exception of
|
||||
OP codes which solely push data to the stack.
|
||||
|
||||
* If any of the transaction's outputs spend less than a minimal value
|
||||
(currently 546 satoshis), the transaction must pay
|
||||
a minimum transaction fee (currently 10,000 satoshis).
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Signature Hash Types
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
`OP_CHECKSIG` extracts a non-stack argument from each signature it
|
||||
evaluates, allowing the signer to decide which parts of the transaction
|
||||
to sign. Since the signature protects those parts of the transaction
|
||||
from modification, this lets signers selectively choose to let other
|
||||
people modify their transactions.
|
||||
|
||||
The various options for what to sign are
|
||||
called [signature hash][]{:#term-signature-hash}{:.term} types. There are three base SIGHASH types
|
||||
currently available:
|
||||
|
||||
* [`SIGHASH_ALL`][sighash_all]{:#term-sighash-all}{:.term}, the default, signs all the inputs and outputs,
|
||||
protecting everything except the scriptSigs against modification.
|
||||
|
||||
* [`SIGHASH_NONE`][sighash_none]{:#term-sighash-none}{:.term} signs all of the inputs but none of the outputs,
|
||||
allowing anyone to change where the satoshis are going unless other
|
||||
signatures using other signature hash flags protect the outputs.
|
||||
|
||||
* [`SIGHASH_SINGLE`][sighash_single]{:#term-sighash-single}{:.term} signs only this input and only one corresponding
|
||||
output (the output with the same output index number as the input), ensuring
|
||||
nobody can change your part of the transaction but allowing other
|
||||
signers to change their part of the transaction. The corresponding
|
||||
output must exist or the value "1" will be signed, breaking the security
|
||||
scheme.
|
||||
|
||||
The base types can be modified with the [`SIGHASH_ANYONECANPAY`][shacp]{:#term-sighash-anyonecanpay}{:.term} (anyone can
|
||||
pay) flag, creating three new combined types:
|
||||
|
||||
* [`SIGHASH_ALL|SIGHASH_ANYONECANPAY`][sha_shacp]{:#term-sighash-all-sighash-anyonecanpay}{:.term} signs all of the outputs but only
|
||||
this one input, and it also allows anyone to add or remove other
|
||||
inputs, so anyone can contribute additional satoshis but they cannot
|
||||
change how many satoshis are sent nor where they go.
|
||||
|
||||
* [`SIGHASH_NONE|SIGHASH_ANYONECANPAY`][shn_shacp]{:#term-sighash-none-sighash-anyonecanpay}{:.term} signs only this one input and
|
||||
allows anyone to add or remove other inputs or outputs, so anyone who
|
||||
gets a copy of this input can spend it however they'd like.
|
||||
|
||||
* [`SIGHASH_SINGLE|SIGHASH_ANYONECANPAY`][shs_shacp]{:#term-sighash-single-sighash-anyonecanpay}{:.term} signs only this input and only
|
||||
one corresponding output, but it also allows anyone to add or remove
|
||||
other inputs.
|
||||
|
||||
Because each input is signed, a transaction with multiple inputs can
|
||||
have multiple signature hash types signing different parts of the transaction. For
|
||||
example, a single-input transaction signed with `NONE` could have its
|
||||
output changed by the miner who adds it to the block chain. On the other
|
||||
hand, if a two-input transaction has one input signed with `NONE` and
|
||||
one input signed with `ALL`, the `ALL` signer can choose where to spend
|
||||
the satoshis without consulting the `NONE` signer---but nobody else can
|
||||
modify the transaction.
|
||||
|
||||
<!-- TODO: describe useful combinations maybe using a 3x3 grid;
|
||||
do something similar for the multisig section with different hashtypes
|
||||
between different sigs -->
|
||||
|
||||
<!-- TODO: add to the technical section details about what the different
|
||||
hash types sign, including the procedure for inserting the subscript -->
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Locktime And Sequence Number
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
One thing all signature hash types sign is the transaction's [locktime][]{:#term-locktime}{:.term}.
|
||||
The locktime indicates the earliest time a transaction can be added to
|
||||
the block chain.
|
||||
|
||||
Locktime allows signers to create time-locked transactions which will
|
||||
only become valid in the future, giving the signers a chance to change
|
||||
their minds.
|
||||
|
||||
If any of the signers change their mind, they can create a new
|
||||
non-locktime transaction. The new transaction will use, as one of
|
||||
its inputs, one of the same outputs which was used as an input to
|
||||
the locktime transaction. This makes the locktime transaction
|
||||
invalid if the new transaction is added to the block chain before
|
||||
the time lock expires.
|
||||
|
||||
Care must be taken near the expiry time of a time lock. The peer-to-peer
|
||||
network allows block time to be up to two hours ahead of
|
||||
real time, so a locktime transaction can be added to the block chain up
|
||||
to two hours before its time lock officially expires. Also, blocks are
|
||||
not created at guaranteed intervals, so any attempt to cancel a valuable
|
||||
transaction should be made a few hours before the time lock expires.
|
||||
|
||||
Previous versions of Bitcoin Core provided a feature which prevented
|
||||
transaction signers from using the method described above to cancel a
|
||||
time-locked transaction, but a necessary part of this feature was
|
||||
disabled to prevent denial of service attacks. A legacy of this system are four-byte
|
||||
[sequence numbers][sequence number]{:#term-sequence-number}{:.term} in every input. Sequence numbers were meant to allow
|
||||
multiple signers to agree to update a transaction; when they finished
|
||||
updating the transaction, they could agree to set every input's
|
||||
sequence number to the four-byte unsigned maximum (0xffffffff),
|
||||
allowing the transaction to be added to a block even if its time lock
|
||||
had not expired.
|
||||
|
||||
Even today, setting all sequence numbers to 0xffffffff (the default in
|
||||
Bitcoin Core) can still disable the time lock, so if you want to use
|
||||
locktime, at least one input must have a sequence number below the
|
||||
maximum. Since sequence numbers are not used by the network for any
|
||||
other purpose, setting any sequence number to zero is sufficient to
|
||||
enable locktime.
|
||||
|
||||
Locktime itself is an unsigned 4-byte number which can be parsed two ways:
|
||||
|
||||
* If less than 500 million, locktime is parsed as a block height. The
|
||||
transaction can be added to any block which has this height or higher.
|
||||
|
||||
* If greater than or equal to 500 million, locktime is parsed using the
|
||||
Unix epoch time format (the number of seconds elapsed since
|
||||
1970-01-01T00:00 UTC---currently over 1.395 billion). The transaction
|
||||
can be added to any block whose block time is greater
|
||||
than the locktime.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Transaction Fees And Change
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Transactions typically pay transaction fees based on the total byte size
|
||||
of the signed transaction. The transaction fee is given to the
|
||||
Bitcoin miner, as explained in the [block chain section][block chain], and so it is
|
||||
ultimately up to each miner to choose the minimum transaction fee they
|
||||
will accept.
|
||||
|
||||
<!-- TODO: check: 50 KB or 50 KiB? Not that transactors care... -->
|
||||
|
||||
By default, miners reserve 50 KB of each block for [high-priority
|
||||
transactions][]{:#term-high-priority-transactions}{:.term} which spend satoshis that haven't been spent for a long
|
||||
time. The remaining space in each block is typically allocated to transactions
|
||||
based on their fee per byte, with higher-paying transactions being added
|
||||
in sequence until all of the available space is filled.
|
||||
|
||||
As of Bitcoin Core 0.9, transactions which do not count as high-priority transactions
|
||||
need to pay a [minimum fee][]{:#term-minimum-fee}{:.term} of 10,000 satoshis to be
|
||||
broadcast across the network. Any transaction paying the minimum fee
|
||||
should be prepared to wait a long time before there's enough spare space
|
||||
in a block to include it. Please see the [verifying payment section][section verifying payment]
|
||||
for why this could be important.
|
||||
|
||||
Since each transaction spends Unspent Transaction Outputs (UTXOs) and
|
||||
because a UTXO can only be spent once, the full value of the included
|
||||
UTXOs must be spent or given to a miner as a transaction fee. Few
|
||||
people will have UTXOs that exactly match the amount they want to pay,
|
||||
so most transactions include a change output.
|
||||
|
||||
[Change outputs][change output]{:#term-change-output}{:.term} are regular outputs which spend the surplus satoshis
|
||||
from the UTXOs back to the spender. They can reuse the same P2PKH pubkey hash
|
||||
or P2SH script hash as was used in the UTXO, but for the reasons
|
||||
described in the [next subsection](#avoiding-key-reuse), it is highly recommended that change
|
||||
outputs be sent to a new P2PKH or P2SH address.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Avoiding Key Reuse
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
In a transaction, the spender and receiver each reveal to each other all
|
||||
public keys or addresses used in the transaction. This allows either
|
||||
person to use the public block chain to track past and future
|
||||
transactions involving the other person's same public keys or addresses.
|
||||
|
||||
If the same public key is reused often, as happens when people use
|
||||
Bitcoin addresses (hashed public keys) as static payment addresses,
|
||||
other people can easily track the receiving and spending habits of that
|
||||
person, including how many satoshis they control in known addresses.
|
||||
|
||||
It doesn't have to be that way. If each public key is used exactly
|
||||
twice---once to receive a payment and once to spend that payment---the
|
||||
user can gain a significant amount of financial privacy.
|
||||
|
||||
Even better, using new public keys or [unique
|
||||
addresses][]{:#term-unique-address}{:.term} when accepting payments or creating
|
||||
change outputs can be combined with other techniques discussed later,
|
||||
such as CoinJoin or merge avoidance, to make it extremely difficult to
|
||||
use the block chain by itself to reliably track how users receive and
|
||||
spend their satoshis.
|
||||
|
||||
Avoiding key reuse can also provide security against attacks which might
|
||||
allow reconstruction of private keys from public keys (hypothesized) or
|
||||
from signature comparisons (possible today under certain circumstances
|
||||
described below, with more general attacks hypothesized).
|
||||
|
||||
1. Unique (non-reused) P2PKH and P2SH addresses protect against the first
|
||||
type of attack by keeping ECDSA public keys hidden (hashed) until the
|
||||
first time satoshis sent to those addresses are spent, so attacks
|
||||
are effectively useless unless they can reconstruct private keys in
|
||||
less than the hour or two it takes for a transaction to be well
|
||||
protected by the block chain.
|
||||
|
||||
2. Unique (non-reused) private keys protect against the second type of
|
||||
attack by only generating one signature per private key, so attackers
|
||||
never get a subsequent signature to use in comparison-based attacks.
|
||||
Existing comparison-based attacks are only practical today when
|
||||
insufficient entropy is used in signing or when the entropy used
|
||||
is exposed by some means, such as a
|
||||
[side-channel attack](https://en.wikipedia.org/wiki/Side_channel_attack).
|
||||
|
||||
So, for both privacy and security, we encourage you to build your
|
||||
applications to avoid public key reuse and, when possible, to discourage
|
||||
users from reusing addresses. If your application needs to provide a
|
||||
fixed URI to which payments should be sent, please see the
|
||||
[`bitcoin:` URI section][bitcoin URI subsection] below.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Transaction Malleability
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
None of Bitcoin's signature hash types protect the scriptSig, leaving
|
||||
the door open for a limited denial of service attack called [transaction
|
||||
malleability][]{:.term}{:#term-transaction-malleability}. The scriptSig
|
||||
contains the signature, which can't sign itself, allowing attackers to
|
||||
make non-functional modifications to a transaction without rendering it
|
||||
invalid. For example, an attacker can add some data to the scriptSig
|
||||
which will be dropped before the previous output script is processed.
|
||||
|
||||
Although the modifications are non-functional---so they do not change
|
||||
what inputs the transaction uses nor what outputs it pays---they do
|
||||
change the computed hash of the transaction. Since each transaction
|
||||
links to previous transactions using hashes as a transaction
|
||||
identifier (txid), a modified transaction will not have the txid its
|
||||
creator expected.
|
||||
|
||||
This isn't a problem for most Bitcoin transactions which are designed to
|
||||
be added to the block chain immediately. But it does become a problem
|
||||
when the output from a transaction is spent before that transaction is
|
||||
added to the block chain.
|
||||
|
||||
Bitcoin developers have been working to reduce transaction malleability
|
||||
among standard transaction types, but a complete fix is still only in
|
||||
the planning stages. At present, new transactions should not depend on
|
||||
previous transactions which have not been added to the block chain yet,
|
||||
especially if large amounts of satoshis are at stake.
|
||||
|
||||
Transaction malleability also affects payment tracking. Bitcoin Core's
|
||||
RPC interface lets you track transactions by their txid---but if that
|
||||
txid changes because the transaction was modified, it may appear that
|
||||
the transaction has disappeared from the network.
|
||||
|
||||
Current best practices for transaction tracking dictate that a
|
||||
transaction should be tracked by the transaction outputs (UTXOs) it
|
||||
spends as inputs, as they cannot be changed without invalidating the
|
||||
transaction.
|
||||
|
||||
<!-- TODO/harding: The paragraph above needs practical advice about how
|
||||
to do that. I'll need to find some time to look at somebody's wallet
|
||||
code. -harding -->
|
||||
|
||||
Best practices further dictate that if a transaction does seem to
|
||||
disappear from the network and needs to be reissued, that it be reissued
|
||||
in a way that invalidates the lost transaction. One method which will
|
||||
always work is to ensure the reissued payment spends all of the same
|
||||
outputs that the lost transaction used as inputs.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
346
_includes/guide_wallets.md
Normal file
|
@ -0,0 +1,346 @@
|
|||
## Wallets
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Bitcoin wallets at their core are a collection of private keys. These collections are stored digitally in a file, or can even be physically stored on pieces of paper.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Private Key Formats
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Private keys are what are used to unlock satoshis from a particular address. In Bitcoin, a private key in standard format is simply a 256-bit number, between the values:
|
||||
|
||||
0x1 and 0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE BAAE DCE6 AF48 A03B BFD2 5E8C D036 4141, representing nearly the entire range of 2<sup>256</sup>-1 values. The range is governed by the secp256k1 ECDSA encryption standard used by Bitcoin.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
#### Wallet Import Format (WIF)
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
In order to make copying of private keys less prone to error, [Wallet Import Format][]{:#term-wallet-import-format}{:.term} may be utilized. WIF uses base58Check encoding on an private key, greatly decreasing the chance of copying error, much like standard Bitcoin addresses.
|
||||
|
||||
1. Take a private key.
|
||||
|
||||
2. Add a 0x80 byte in front of it for mainnet addresses or 0xef for testnet addresses.
|
||||
|
||||
3. Perform a SHA-256 hash on the extended key.<!--noref-->
|
||||
|
||||
4. Perform a SHA-256 hash on result of SHA-256 hash.
|
||||
|
||||
5. Take the first four bytes of the second SHA-256 hash; this is the checksum.
|
||||
|
||||
6. Add the four checksum bytes from point 5 at the end of the extended key<!--noref--> from point 2.
|
||||
|
||||
7. Convert the result from a byte string into a Base58 string using Base58Check encoding.
|
||||
|
||||
The process is easily reversible, using the Base58 decoding function, and removing the padding.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
#### Mini Private Key Format
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Mini private key format is a method for encoding a private key in under 30 characters, enabling keys to be embedded in a small physical space, such as physical bitcoin tokens, and more damage-resistant QR codes.
|
||||
|
||||
1. The first character of mini keys is 'S'.
|
||||
|
||||
2. In order to determine if a mini private key is well-formatted, a question mark is added to the private key.
|
||||
|
||||
3. The SHA256 hash is calculated. If the first byte produced is a `00’, it is well-formatted. This key restriction acts as a typo-checking mechanism. A user brute forces the process using random numbers until a well-formatted mini private key is produced.
|
||||
|
||||
4. In order to derive the full private key, the user simply takes a single SHA256 hash of the original mini private key. This process is one-way: it is intractable to compute the mini private key format from the derived key.
|
||||
|
||||
Many implementations disallow the character '1' in the mini private key due to its visual similarity to 'l'.
|
||||
|
||||
**Resource:** A common tool to create and redeem these keys is the [Casascius Bitcoin Address Utility][casascius
|
||||
address utility].
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
|
||||
### Hierarchical Deterministic Key Creation
|
||||
|
||||
<!--
|
||||
For consistent word ordering:
|
||||
[normal|hardened|] [master|parent|child|grandchild] [extended|non-extended|] [private|public|chain] [key|code]
|
||||
-->
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
The hierarchical deterministic key creation and transfer protocol ([HD
|
||||
protocol][]{:#term-hd-protocol}{:.term}) greatly simplifies wallet
|
||||
backups, eliminates the need for repeated communication between multiple
|
||||
programs using the same wallet, permits creation of child accounts which
|
||||
can operate independently, gives each parent account the ability to
|
||||
monitor or control its children even if the child account is
|
||||
compromised, and divides each account into full-access and
|
||||
restricted-access parts so untrusted users or programs can be allowed to
|
||||
receive or monitor payments without being able to spend them.
|
||||
|
||||
The HD protocol takes advantage of the ECDSA public key creation
|
||||
function, [`point()`][point function]{:#term-point-function}{:.term},
|
||||
which takes a large integer (the private key) and turns it into a graph
|
||||
point (the public key):
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
point(private_key) == public_key
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Because of the way `point()` functions, it's possible to create a [child
|
||||
public key][]{:#term-child-public-key}{:.term} by combining an
|
||||
existing [(parent) public key][parent public
|
||||
key]{:#term-parent-public-key}{:.term} with another public key created from any
|
||||
integer (*i*) value. This child public key is the same public key which
|
||||
would be created by the `point()` function if you added the *i* value to
|
||||
the original (parent) private key and then found the remainder of that
|
||||
sum divided by a global constant used by all Bitcoin software (*G*):
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
point( (parent_private_key + i) % G ) == parent_public_key + point(i)
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
This means that two or more independent programs which agree on a
|
||||
sequence of integers can create a series of unique [child key][]{:#term-child-key}{:.term} pairs from
|
||||
a single parent key pair without any further communication.
|
||||
Moreover, the program which distributes new public keys for receiving
|
||||
payment can do so without any access to the private keys, allowing the
|
||||
public key distribution program to run on a possibly-insecure platform such as
|
||||
a public web server.
|
||||
|
||||
Child public keys can also create their own child public keys
|
||||
(grandchild public keys) by repeating the child key derivation
|
||||
operations:
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
point( (child_private_key + i) % G ) == child_public_key + point(i)
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Whether creating child public keys or further-descended public keys, a
|
||||
predictable sequence of integer values would be no better than using a
|
||||
single public key for all transactions, as anyone who knew one child
|
||||
public key could find all of the other child public keys created from
|
||||
the same parent public key. Instead, a random seed can be used to
|
||||
deterministically generate the sequence of integer values so that the
|
||||
relationship between the child public keys is invisible to anyone
|
||||
without that seed.
|
||||
|
||||
The HD protocol uses a single root seed to create a hierarchy of
|
||||
child, grandchild, and other descended keys with unlinkable
|
||||
deterministically-generated integer values. Each child key also gets
|
||||
a deterministically-generated seed from its parent, called a [chain
|
||||
code][]{:#term-chain-code}{:.term}, so the compromising of one chain
|
||||
code doesn't necessary compromise the integer sequence for the whole
|
||||
hierarchy, allowing the [master chain
|
||||
code][]{:#term-master-chain-code}{:.term} to continue being useful
|
||||
even if, for example, a web-based public key distribution program
|
||||
gets hacked.
|
||||
|
||||

|
||||
|
||||
As illustrated above, HD key derivation takes four inputs<!--noref-->:
|
||||
|
||||
* The *[parent private key][]{:#term-parent-private-key}{:.term}* and
|
||||
*parent public key* are regular uncompressed 256-bit ECDSA keys.
|
||||
|
||||
* The [parent chain code][]{:#term-parent-chain-code}{:.term} is 256
|
||||
bits of seemingly-random data.
|
||||
|
||||
* The [index][key index]{:#term-key-index}{:.term} number is a 32-bit integer specified by the program.
|
||||
|
||||
In the normal form shown in the above illustration, the parent chain
|
||||
code, the parent public key, and the index number are fed into a one-way cryptographic hash
|
||||
([HMAC-SHA512][]) to produce 512 bits of
|
||||
deterministically-generated-but-seemingly-random data. The
|
||||
seemingly-random 256 bits on the righthand side of the hash output are
|
||||
used as a new child chain code. The seemingly-random 256 bits on the
|
||||
lefthand side of the hash output are used as the integer value to be combined
|
||||
with either the parent private key or parent public key to,
|
||||
respectively, create either a child private key or child public key:
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
point( (parent_private_key + lefthand_hash_output) % G ) == child_public_key
|
||||
point(child_private_key) == parent_public_key + point(lefthand_hash_output)
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Specifying different index numbers will create different unlinkable
|
||||
child keys from the same parent keys. Repeating the procedure for the
|
||||
child keys using the child chain code will create unlinkable grandchild keys.
|
||||
|
||||
Because creating child keys requires both a key and a chain code, the
|
||||
key and chain code together are called the [extended
|
||||
key][]{:#term-extended-key}{:.term}. An [extended private
|
||||
key][]{:#term-extended-private-key}{:.term} and its corresponding
|
||||
[extended public key][]{:#term-extended-public-key}{:.term} have the
|
||||
same chain code. The (top-level parent) [master private
|
||||
key][]{:#term-master-private-key}{:.term} and master chain
|
||||
code are derived from random data,
|
||||
as illustrated below.
|
||||
|
||||

|
||||
|
||||
A [root seed][]{:#term-root-seed}{:.term} is created from either 128
|
||||
bits, 256 bits, or 512 bits of random data. This root seed of as little
|
||||
as 128 bits is the the only data the user needs to backup in order to
|
||||
derive every key created by a particular wallet program using
|
||||
particular settings.
|
||||
|
||||
(**Warning:** as of this writing, HD wallet programs are not expected to
|
||||
be fully compatible, so users must only use the same HD wallet program
|
||||
with the same HD-related settings for a particular root seed.)
|
||||
|
||||
The root seed is hashed to create 512 bits of seemingly-random data,
|
||||
from which the master private key and master chain code are created
|
||||
(together, the master extended private key). The master public key is
|
||||
derived from the master private key using `point()`, which, together
|
||||
with the master chain code, is the master extended public
|
||||
key. The master extended keys are functionally equivalent to other
|
||||
extended keys; it is only their location at the top of the hierarchy
|
||||
which makes them special.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
#### Hardened Keys
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Hardened extended keys fix a potential problem with normal extended keys.
|
||||
If an attacker gets a normal parent
|
||||
chain code and parent public key, he can brute-force find all chain
|
||||
codes deriving from it. If the attacker also obtains a child, grandchild, or
|
||||
further-descended private key, he can use the chain code to generate all
|
||||
of the extended private keys descending from that private key, as
|
||||
shown in the grandchild and great-grandchild generations of the illustration below.
|
||||
|
||||

|
||||
|
||||
Perhaps worse, the attacker can reverse the normal child private key
|
||||
derivation formula and subtract a parent chain code from a child private
|
||||
key to recover the parent private key, as shown in the child and
|
||||
parent generations of the illustration above. This means an attacker
|
||||
who acquires an extended public key and any private key descended from
|
||||
it can recover that public key's private key and all keys descended from
|
||||
it.
|
||||
|
||||
For this reason, the chain code part of an extended public key should be
|
||||
better secured than standard public keys and users should be advised
|
||||
against exporting even non-extended private keys to
|
||||
possibly-untrustworthy environments.
|
||||
|
||||
This can be fixed, with some tradeoffs, by replacing the the normal
|
||||
key derivation formula with a hardened key derivation formula.
|
||||
|
||||
The normal key derivation formula, described in the section above, combines
|
||||
together the index number, the parent chain code, and the parent public key to create the
|
||||
child chain code and the integer value which is combined with the parent
|
||||
private key to create the child private key.
|
||||
|
||||

|
||||
|
||||
The hardened formula, illustrated above, combines together the index
|
||||
number, the parent chain code, and the parent private key to create
|
||||
the data used to generate the child chain code and child private key.
|
||||
This formula makes it impossible to create child public keys without
|
||||
knowing the parent private key. In other words, parent extended public
|
||||
keys can't create hardened child public keys.
|
||||
|
||||
Because of that, a [hardened extended private
|
||||
key][]{:#term-hardened-extended-private-key}{:.term} is much less
|
||||
useful than a normal extended private key---however,
|
||||
hardened extended private keys create a firewall through which
|
||||
multi-level key derivation compromises cannot happen. Because hardened
|
||||
child extended public keys cannot generate grandchild chain codes on
|
||||
their own, the compromise of a parent extended public key cannot be
|
||||
combined with the compromise of a grandchild private key to create
|
||||
great-grandchild extended private keys.
|
||||
|
||||
The HD protocol uses different index numbers to indicate
|
||||
whether a normal or hardened key should be generated. Index numbers from
|
||||
0x00 to 0x7fffffff (0 to 2<sup>31</sup>-1) will generate a normal key; index
|
||||
numbers from 0x80000000 to 0xffffffff will generate a hardened key. To
|
||||
make descriptions easy, many developers use the [prime symbol][] to indicate
|
||||
hardened keys, so the first normal key (0x00) is 0 and the first hardened
|
||||
key (0x80000000) is 0´.
|
||||
|
||||
(Bitcoin developers typically use the ASCII apostrophe rather than
|
||||
the unicode prime symbol, a convention we will henceforth follow.)
|
||||
|
||||
This compact description is further combined with slashes prefixed by
|
||||
*m* or *M* to indicate hierarchy and key type, with *m* being a private
|
||||
key and *M* being a public key. For example, m/0'/0/122' refers to the
|
||||
123rd hardened private child (by index number) of the first normal child
|
||||
(by index) of the first hardened child (by index) of the master private
|
||||
key. The following hierarchy illustrates prime notation and hardened key
|
||||
firewalls.
|
||||
|
||||

|
||||
|
||||
Wallets following the BIP32 HD protocol only create hardened children of
|
||||
the master private key (*m*) to prevent a compromised child key from
|
||||
compromising the master key. As there are no normal children for the
|
||||
master keys, the master public key is not used in HD wallets. All other
|
||||
keys can have normal children, so the corresponding extended public keys
|
||||
may be used instead.
|
||||
|
||||
The HD protocol also describes a serialization format for extended
|
||||
public keys and extended private keys. For details, please see the
|
||||
[wallet section in the developer reference][devref wallets] or BIP32
|
||||
for the full HD protocol specification.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
#### Storing Root Seeds
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Root seeds in the HD protocol are 128, 256, or 512 bits of random data
|
||||
which must be backed up precisely. To make it more convenient to use
|
||||
non-digital backup methods, such as memorization or hand-copying, BIP39
|
||||
defines a method for creating a 512-bit root seed from a pseudo-sentence
|
||||
(mnemonic) of common natural-language words which was itself created
|
||||
from 128 to 256 bits of entropy and optionally protected by a password.
|
||||
|
||||
The number of words generated correlates to the amount of entropy used:
|
||||
|
||||
| Entropy Bits | Words |
|
||||
|--------------|--------|
|
||||
| 128 | 12 |
|
||||
| 160 | 15 |
|
||||
| 192 | 18 |
|
||||
| 224 | 21 |
|
||||
| 256 | 24 |
|
||||
|
||||
The passphrase can be of any length. It is simply appended to the mnemonic
|
||||
pseudo-sentence, and then both the mnemonic and password are hashed
|
||||
2,048 times using HMAC-SHA512, resulting in a seemingly-random 512-bit seed. Because any
|
||||
input<!--noref--> to the hash function creates a seemingly-random 512-bit seed,
|
||||
there is no fundamental way to prove the user entered the correct
|
||||
password, possibly allowing the user to protect a seed even when under
|
||||
duress.
|
||||
|
||||
For implementation details, please see BIP39.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
|
||||
|
||||
### Loose-Key Wallets
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Loose-Key wallets, also called "Just a Bunch Of Keys (JBOK)", are a deprecated form of wallet that originated from the Bitcoin Core client wallet. The Bitcoin Core client wallet would create 100 private key/public key pairs automatically via a Pseudo-Random-Number Generator (PRNG) for later use. Once all these keys are consumed or the RPC call `keypoolrefill` is run, another 100 key pairs would be created. This created considerable difficulty<!--noref--> in backing up one’s keys, considering backups have to be run manually to save the newly-generated private keys. If a new key pair set is generated, used, and then lost prior to a backup, the stored satoshis are likely lost forever. Many older-style mobile wallets followed a similar format, but only generated a new private key upon user demand.
|
||||
|
||||
This wallet type is being actively phased out and discouraged from being used due to the backup hassle.
|
||||
|
||||
{% endautocrossref %}
|
95
_includes/ref_block_chain.md
Normal file
|
@ -0,0 +1,95 @@
|
|||
## Block Chain
|
||||
|
||||
The following subsections briefly document core block details.
|
||||
|
||||
### Block Contents
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
This section describes [version 2 blocks][v2 block]{:#term-v2-block}{:.term}, which are any blocks with a
|
||||
block height greater than 227,835. (Version 1 and version 2 blocks were
|
||||
intermingled for some time before that point.) Future block versions may
|
||||
break compatibility with the information in this section. You can determine
|
||||
the version of any block by checking its `version` field using
|
||||
bitcoind RPC calls.
|
||||
|
||||
As of version 2 blocks, each block consists of four root elements:
|
||||
|
||||
1. A [magic number][block header magic]{:#term-block-header-magic}{:.term} (0xd9b4bef9).
|
||||
|
||||
2. A 4-byte unsigned integer indicating how many bytes follow until the
|
||||
end of the block. Although this field would suggest maximum block
|
||||
sizes of 4 GiB, max block size is currently capped at 1 MiB and the
|
||||
default max block size (used by most miners) is 350 KiB (although
|
||||
this will likely increase over time).
|
||||
|
||||
3. An 80-byte block header described in the section below.
|
||||
|
||||
4. One or more transactions.
|
||||
|
||||
The first transaction in a block must be a [coinbase transaction][]{:#term-coinbase-tx}{:.term} which should collect and
|
||||
spend any transaction fees paid by transactions included in this block.
|
||||
All blocks with a block height less than 6,930,000 are entitled to
|
||||
receive a [block reward][]{:#term-block-reward}{:.term} of newly created bitcoin value, which also
|
||||
should be spent in the coinbase transaction. (The block reward started
|
||||
at 50 bitcoins and is being halved approximately every four years. As of
|
||||
April 2014, it's 25 bitcoins.) A coinbase transaction is invalid if it
|
||||
tries to spend more value than is available from the transaction
|
||||
fees and block reward.
|
||||
|
||||
The coinbase transaction has the same basic format as any other
|
||||
transaction, but it references a single non-existent UTXO and a special
|
||||
[coinbase field][]{:#term-coinbase-field}{:.term} replaces the field that would normally hold a scriptSig and
|
||||
signature. In version 2 blocks, the coinbase parameter must begin with
|
||||
the current block's block height and may contain additional arbitrary
|
||||
data or a script up to a maximum total of 100 bytes.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
### Block Header
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
The 80-byte block header contains the following six fields:
|
||||
|
||||
| Field | Bytes | Format |
|
||||
|-------------------|--------|--------------------------------|
|
||||
| 1. Version | 4 | Unsigned Int |
|
||||
| 2. hashPrevBlock | 32 | Unsigned Int (SHA256 Hash) |
|
||||
| 3. hashMerkleRoot | 32 | Unsigned Int (SHA256 Hash) |
|
||||
| 4. Time | 4 | Unsigned Int (Epoch Time) |
|
||||
| 5. Bits | 4 | Internal Bitcoin Target Format |
|
||||
| 6. Nonce | 4 | (Arbitrary Data) |
|
||||
|
||||
1. The *[block version][]{:#term-block-version}{:.term}* number indicates which set of block validation rules
|
||||
to follow so Bitcoin Core developers can add features or
|
||||
fix bugs. As of block height 227,836, all blocks use version number
|
||||
2.
|
||||
|
||||
2. The *hash of the previous block header* puts this block on the
|
||||
block chain and ensures no previous block can be changed without also
|
||||
changing this block's header.
|
||||
|
||||
3. The *Merkle root* is a hash derived from hashes of all the
|
||||
transactions included in this block. It ensures no transactions can
|
||||
be modified in this block without changing the block header hash.
|
||||
|
||||
4. The *[block time][]{:#term-block-time}{:.term}* is the approximate time when this block was created in
|
||||
Unix Epoch time format (number of seconds elapsed since
|
||||
1970-01-01T00:00 UTC). The time value must be greater than the
|
||||
median time of the previous 11 blocks. No peer will accept a block with a
|
||||
time currently more than two hours in the future according to the
|
||||
peer's clock.
|
||||
|
||||
5. *Bits* translates into the target threshold value---the maximum allowed
|
||||
value for this block's hash. The bits value must match the network
|
||||
difficulty at the time the block was mined.
|
||||
|
||||
6. The *[header nonce][]{:#term-header-nonce}{:.term}* is an arbitrary input that miners can change to test different
|
||||
hash values for the header until they find a hash value less than or
|
||||
equal to the target threshold. If all values within the nonce's four
|
||||
bytes are tested, the time can be updated or the
|
||||
coinbase transaction can be changed and the Merkle
|
||||
root updated.
|
||||
|
||||
{% endautocrossref %}
|
3134
_includes/ref_core_rpcs-abcdefg.md
Normal file
1090
_includes/ref_core_rpcs-hijklmn.md
Normal file
872
_includes/ref_core_rpcs-opqrst.md
Normal file
|
@ -0,0 +1,872 @@
|
|||
#### ping
|
||||
|
||||
~~~
|
||||
ping
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Requests that a ping be sent to all other nodes, to measure ping time.
|
||||
Results provided in `getpeerinfo` pingtime and pingwait fields as
|
||||
decimal seconds. Ping command is handled in queue with all other
|
||||
commands, so it measures processing backlog, not just network ping.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Example**
|
||||
|
||||
~~~
|
||||
bitcoin-cli -testnet ping
|
||||
~~~
|
||||
|
||||
(Success: no result printed.)
|
||||
|
||||
|
||||
#### sendfrom
|
||||
|
||||
~~~
|
||||
sendfrom <account> <address> <amount> [confirmations] [comment] [label]
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Spend an amount from an account to a bitcoin address.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #1: From Account**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String, required:* the name of the account from which to spend the
|
||||
funds. Use "" for the default account.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #2: To Address**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String, required:* the address to which the funds should be
|
||||
spent. Use "" for the default account.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #3: Amount To Spend**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*Number; required:* the amount to spend in decimal bitcoins.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #4: Minimum Confirmations**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*Number; optional:* the minimum number of confirmations an incoming
|
||||
transaction must have before it will be spent. Previously spent UTXOs
|
||||
are not included regardless of the number of confirmations. Default is
|
||||
1; use 0 to spend unconfirmed transactions.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #5: A Comment**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String; optional:* a comment to associate with this transaction.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #6: A Label**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String; optional:* the label (name) to give the recipient.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Result: TXID**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
A txid for the transaction created.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Example**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Spend 0.1 bitcoins from the account "doc test" to the address indicated below
|
||||
using only UTXOs with at least six confirmations, giving the
|
||||
transaction the comment "Example spend" and labeling the spender
|
||||
"Example.com":
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
bitcoin-cli -testnet sendfrom "doc test" \
|
||||
mgnucj8nYqdrPFh2JfZSB1NmUThUGnmsqe \
|
||||
0.1 \
|
||||
6 \
|
||||
"Example spend" \
|
||||
"Example.com"
|
||||
~~~
|
||||
|
||||
Result:
|
||||
|
||||
~~~
|
||||
ca7cb6a5ffcc2f21036879493db4530c0ce9b5bff9648f9a3be46e2dfc8e0166
|
||||
~~~
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#### sendmany
|
||||
|
||||
~~~
|
||||
sendmany <account> <addresses & amounts> [confirmations] [memo]
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Create and broadcast a transaction which spends outputs to multiple addresses.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #1: Account From Which The Satoshis Should Be Sent**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String; required:* the wallet account from which the funds should be
|
||||
withdrawn. Can be "" for the default account.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #2: The Output Address/Amount Pairs**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String; required:* a JSON object with addresses as keys and amounts as values.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
{
|
||||
"<address>":<amount in decimal bitcoins>
|
||||
,[...]
|
||||
}
|
||||
~~~
|
||||
|
||||
**Argument #3: The Minimum Number Of Confirmations For Inputs**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*Number; optional:* the minimum number of confirmations an previously-received
|
||||
output must have before it will be spent. The default is 1
|
||||
confirmation.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #4: A Memo**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String, optional:* a memo to be recorded with this transaction for
|
||||
record-keeping purposes. The memo is not included in the transaction.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Result: A Transaction Identifier**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String:* a transaction identifier (txid) for the transaction created
|
||||
and broadcast to the peer-to-peer network.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Example**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
From the account *test1*, send 0.1 bitcoins to the first address and 0.2
|
||||
bitcoins to the second address, with a memo of "Example Transaction".
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
> bitcoin-cli -testnet sendmany \
|
||||
"test1" \
|
||||
'''
|
||||
{
|
||||
"mjSk1Ny9spzU2fouzYgLqGUD8U41iR35QN": 0.1,
|
||||
"mgnucj8nYqdrPFh2JfZSB1NmUThUGnmsqe": 0.2
|
||||
} ''' \
|
||||
6 \
|
||||
"Example Transaction"
|
||||
~~~
|
||||
|
||||
Result:
|
||||
|
||||
~~~
|
||||
ef7c0cbf6ba5af68d2ea239bba709b26ff7b0b669839a63bb01c2cb8e8de481e
|
||||
~~~
|
||||
|
||||
|
||||
#### sendrawtransaction
|
||||
|
||||
~~~
|
||||
sendrawtransaction <hex> [true|false]
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Broadcasts transaction in rawtransaction format to the peer-to-peer network.
|
||||
|
||||
See also: `createrawtransaction` and `signrawtransaction`
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #1: Raw Transaction**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String; required:* a fully-signed transaction in rawtransaction format
|
||||
(hex).
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #2: Whether To Allow High Fees**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*Boolean; optional:* whether or not to allow the transaction to have a
|
||||
high transaction fee. Transaction fees are the difference between the
|
||||
sum of the inputs and the sum of the outputs, so a raw transaction which
|
||||
accidentally leaves off a change output, for example, can have a
|
||||
transaction fee dozens or hundreds of times larger than the network
|
||||
norm. If *true* is specified, that will be allowed. If *false* (the
|
||||
default), the transaction will be rejected with an informative error
|
||||
message.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Result: A TXID Or Error Message**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
If successful, the transaction's txid (hash) will be returned. If
|
||||
unsuccessful, an error message will be returned.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Examples**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Create and sign a transaction spending over 0.2 bitcoins as fees:
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
> bitcoin-cli -testnet signrawtransaction $(
|
||||
bitcoin-cli -testnet createrawtransaction '''
|
||||
[
|
||||
{
|
||||
"txid": "ef7c0cbf6ba5af68d2ea239bba709b26ff7b0b669839a63bb01c2cb8e8de481e",
|
||||
"vout": 0
|
||||
}
|
||||
]''' '''
|
||||
{
|
||||
"mgnucj8nYqdrPFh2JfZSB1NmUThUGnmsqe": 0.1
|
||||
}'''
|
||||
)
|
||||
~~~
|
||||
|
||||
Result:
|
||||
|
||||
~~~
|
||||
{
|
||||
"hex" : "01000000011e48dee8b82c1cb03ba63998660b7bff269b70ba9\
|
||||
b23ead268afa56bbf0c7cef000000006b4830450221009c711c\
|
||||
e4df4cd8e22a10016ff6098e799f081e3a1706a9c0df14eeeb8\
|
||||
6c31bb302206323d29ab4f3138371df7b7bb794bb7c6a5e7e40\
|
||||
161e98b5c873f892d319d5230121027ce4f9db9f237fc75e420\
|
||||
742320c7df3b4ca95c44b6bc715400930f24870b2b1ffffffff\
|
||||
0180969800000000001976a9140dfc8bafc8419853b34d5e072\
|
||||
ad37d1a5159f58488ac00000000",
|
||||
"complete" : true
|
||||
}
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Now attempt to broadcast it:
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
> bitcoin-cli -testnet sendrawtransaction 01000000011e48dee8b82c\
|
||||
1cb03ba63998660b7bff269b70ba9b23ead268afa56bbf0c7cef00000000\
|
||||
6b4830450221009c711ce4df4cd8e22a10016ff6098e799f081e3a1706a9\
|
||||
c0df14eeeb86c31bb302206323d29ab4f3138371df7b7bb794bb7c6a5e7e\
|
||||
40161e98b5c873f892d319d5230121027ce4f9db9f237fc75e420742320c\
|
||||
7df3b4ca95c44b6bc715400930f24870b2b1ffffffff0180969800000000\
|
||||
001976a9140dfc8bafc8419853b34d5e072ad37d1a5159f58488ac00000000
|
||||
~~~
|
||||
|
||||
Result:
|
||||
|
||||
~~~
|
||||
error: {"code":-22,"message":"TX rejected"}
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Allow high fees to force it to spend:
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
> bitcoin-cli -testnet sendrawtransaction 01000000[...]00000000 true
|
||||
~~~
|
||||
|
||||
Result (success):
|
||||
|
||||
~~~
|
||||
6d62d3f74be5ca614e32a2fb662deabe87ff95c7d90228cd8615da39cc824e34
|
||||
~~~
|
||||
|
||||
|
||||
#### sendtoaddress
|
||||
|
||||
~~~
|
||||
sendtoaddress <address> <amount> <memo> <label>
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Spend an amount to a given address. Encrypted wallets must be unlocked first.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #1: Address**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String; required:* A bitcoin address which will received payment.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #2: Amount**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*Number; required:* the amount in decimal bitcoins.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #3: Memo**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String; optional:* the memo to give the transaction. This is not
|
||||
broadcast to the peer-to-peer network; it is stored in your wallet only.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #4: Label**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String; optional:* the label to give the transaction. This is not
|
||||
broadcast to the peer-to-peer network; it is stored in your wallet only.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Result: TXID**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
If the spend is successful, the txid is returned.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
|
||||
**Example**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Spend 0.1 bitcoins to the address below with the memo "sendtoadress
|
||||
example" and the label "Nemo From Example.com":
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
> bitcoin-cli -testnet sendtoaddress mmXgiR6KAhZCyQ8ndr2BCfEq1wNG2UnyG6 \
|
||||
0.1 "sendtoaddress example" "Nemo From Example.com"
|
||||
~~~
|
||||
|
||||
~~~
|
||||
85a98fdf1529f7d5156483ad020a51b7f3340e47448cf932f470b72ff01a6821
|
||||
~~~
|
||||
|
||||
|
||||
#### setaccount
|
||||
|
||||
~~~
|
||||
setaccount <address> <account>
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Puts the given address in the given account.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #1: A Bitcoin Address**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String; required:* the address to put in the account.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #2: An Account**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String; required:* the account in which to put the address.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Result: None On Success**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
No result generated on success.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Example**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Put the address indicated below in the "doc test" account.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
> bitcoin-cli -testnet setaccount \
|
||||
mmXgiR6KAhZCyQ8ndr2BCfEq1wNG2UnyG6 "doc test"
|
||||
~~~
|
||||
|
||||
(Success: no result displayed.)
|
||||
|
||||
|
||||
|
||||
|
||||
#### setgenerate
|
||||
|
||||
~~~
|
||||
setgenerate <true|false> [processors]
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Enable or disable hashing to attempt to find the next block.
|
||||
|
||||
See also: `getgenerate`
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #1: Whether To Enable Or Disable Generation**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*Boolean; required:* to enable generation, *true*; to disable, *false*.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #2: The Number Of Processors To Use**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*Number; optional:* the number of logical processors to use. Defaults
|
||||
to 1; use -1 to use all available processors.
|
||||
|
||||
*Note:* in regtest mode, this argument will automatically create that
|
||||
number of blocks. See example below.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Result: None On Success**
|
||||
|
||||
No result on success.
|
||||
|
||||
**Examples**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Enable generation using two logical processors (on this machine, two
|
||||
cores of one physical processor):
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
> bitcoin-cli -testnet setgenerate true 2
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
(Success: no result displayed. Process manager shows 200% CPU usage.)
|
||||
|
||||
Using regtest mode, generate 101 blocks (enough to be able to spend the
|
||||
coinbase transaction of the first block generated):
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
> bitcoin-cli -regtest setgenerate true 101
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
(Success: no result displayed. Wallet balance shows 50 bitcoins available.)
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
|
||||
|
||||
|
||||
#### settxfee
|
||||
|
||||
~~~
|
||||
settxfee amount
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Set the transaction fee per kilobyte.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument: Amount**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*Number; required:* the transaction fee in decimal bitcoins per kilobyte.
|
||||
Will be rounded up to the nearest satoshi (0.00000001).
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Result: True Or False**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*True* if successful.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Example**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Set the transaction fee per kilobyte to 100,000 satoshis (1 millibit).
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
> bitcoin-cli -testnet settxfee 0.00100000
|
||||
~~~
|
||||
|
||||
Result:
|
||||
|
||||
~~~
|
||||
true
|
||||
~~~
|
||||
|
||||
|
||||
|
||||
#### signmessage
|
||||
|
||||
~~~
|
||||
signmessage <address> <message>
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Sign a message with the private key of an address. Encrypted wallets
|
||||
must be unlocked first.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #1: Address**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String; required:* the Bitcoin address corresponding to the private key
|
||||
which should be used to sign the message.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #2: Message**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String; required:* The message to sign.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Result: Message Signature**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
The signature of the message encoded in base64.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Example**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Sign a the message "Hello, World!" using the following address:
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
> bitcoin-cli -testnet signmessage mgnucj8nYqdrPFh2JfZSB1NmUThUGnmsqe \
|
||||
'Hello, World!'
|
||||
~~~
|
||||
|
||||
Result:
|
||||
|
||||
~~~
|
||||
IOGreqb/7UgD1ifcojESd32ZJgH5RGzUXitmbl6ZbdenSmitipWoLSi73TskmLY7zhcD662bTw3RHoYQl/dOAhE=
|
||||
~~~
|
||||
|
||||
|
||||
|
||||
#### signrawtransaction
|
||||
|
||||
~~~
|
||||
signrawtransaction <raw transaction hex> [previous transactions] [private keys] [sighashtype]
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Sign inputs of a transaction in rawtransaction format using private keys
|
||||
stored in the wallet or provided in the call.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #1: The Transaction To Sign**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String; required:* the transaction to sign in rawtransaction format
|
||||
(hex).
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #2: P2SH Transaction Dependencies**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String; optional:* A JSON array of JSON objects. Each object contains
|
||||
details about an unknown-to-this-node P2SH transaction that this transaction
|
||||
depends upon.
|
||||
|
||||
Each previous P2SH transaction must include its *txid* in hex, output
|
||||
index number (*vout*), public key (*scriptPubKey*) in hex, and
|
||||
*redeemScript* in hex.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
|
||||
~~~
|
||||
[
|
||||
{
|
||||
"txid":"<txid>",
|
||||
"vout":<output index number>,
|
||||
"scriptPubKey": "<scriptPubKey in hex>",
|
||||
"redeemScript": "<redeemScript in hex>"
|
||||
}
|
||||
,[...]
|
||||
]
|
||||
~~~
|
||||
|
||||
**Argument #3: Private Keys For Signing**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String; optional:* A JSON array of base58check-encoded private keys to use
|
||||
for signing. If this argument is used, only the keys provided will be
|
||||
used to sign even if the wallet has other matching keys. If this
|
||||
argument is omitted, keys from the wallet will be used.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
[
|
||||
"<private key in base58check hex>"
|
||||
,[...]
|
||||
]
|
||||
~~~
|
||||
|
||||
**Argument #4: Sighash Type**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String, optional:* The type of signature hash to use for all of the
|
||||
signatures performed. (You must use separate calls to
|
||||
`signrawtransaction` if you want to use different sighash types for
|
||||
different signatures.)
|
||||
|
||||
The allowed values are *ALL*, *NONE*,
|
||||
*SINGLE*, *ALL|ANYONECANPAY*, *NONE|ANYONECANPAY*,
|
||||
and *SINGLE|ANYONECANPAY*.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
|
||||
**Result: Signed Transaction**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String:* a JSON object containing the transaction in *hex* with as many
|
||||
signatures as could be applied and a *complete* key indicating whether
|
||||
or not the the transaction is fully signed (0 indicates it is not
|
||||
complete).
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
{
|
||||
"hex": "<signed raw transaction hex>",
|
||||
"complete": <0|1>
|
||||
}
|
||||
~~~
|
||||
|
||||
**Example**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Sign the hex generated in the example section for the `rawtransaction`
|
||||
RPC:
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
> bitcoin-cli -testnet signrawtransaction 010000000189957b01aed5\
|
||||
96d3b361b576234eaeed3249246f14562d6bc6085166cd247d\
|
||||
5a0000000000ffffffff0180969800000000001976a9140dfc\
|
||||
8bafc8419853b34d5e072ad37d1a5159f58488ac00000000
|
||||
~~~
|
||||
|
||||
Result:
|
||||
|
||||
~~~
|
||||
{
|
||||
"hex" : "010000000189957b01aed596d3b361b576234eaeed3249246f145\
|
||||
62d6bc6085166cd247d5a000000006b483045022100c7a034fd7d\
|
||||
990b8a2bfba45fde44cae40b5ffbe42c5cf7d8143bfe317bdef3f\
|
||||
10220584e52f59b6a46d688322d65178efe83972a8517c9479630\
|
||||
6d40083af5b807c901210321eeeb46fd878ce8e62d5e0f408a0ea\
|
||||
b41d7c3a7872dc836ce360439536e423dffffffff018096980000\
|
||||
0000001976a9140dfc8bafc8419853b34d5e072ad37d1a5159f58\
|
||||
488ac00000000",
|
||||
"complete" : true
|
||||
}
|
||||
~~~
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#### stop
|
||||
|
||||
~~~
|
||||
stop
|
||||
~~~
|
||||
|
||||
Stop the Bitcoin Core server.
|
||||
|
||||
**Example**
|
||||
|
||||
~~~
|
||||
bitcoin-cli -testnet stop
|
||||
~~~
|
||||
|
||||
(Success: no result printed but `bitcoind` shutdown.)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#### submitblock
|
||||
|
||||
~~~
|
||||
submitblock <new block> [extra parameters]
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Attempts to broadcast a new block to network. Extra parameters are ignored
|
||||
by Bitcoin Core but may be used by mining pools or other programs.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #1: The New Block In Hex**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String; required:* the hex-encoded block data to broadcast to the
|
||||
peer-to-peer network.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #2: Extra Parameters**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String; optional:* A JSON object containing extra parameters for
|
||||
mining pools and other software, such as a work identifier (workid).
|
||||
The extra parameters will not be broadcast to the network.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
{
|
||||
"<key>" : "<value>"
|
||||
}
|
||||
~~~
|
||||
|
||||
**Result: None**
|
||||
|
||||
No result printed if successful. An error message if failed.
|
||||
|
||||
**Example**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Submit the following block with the workid, "test".
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
> bitcoin-cli -testnet submitblock 02000000df11c014a8d798395b505\
|
||||
9c722ebdf3171a4217ead71bf6e0e99f4c7000000004a6f6a2\
|
||||
db225c81e77773f6f0457bcb05865a94900ed11356d0b75228\
|
||||
efb38c7785d6053ffff001d005d43700101000000010000000\
|
||||
00000000000000000000000000000000000000000000000000\
|
||||
0000000ffffffff0d03b477030164062f503253482ffffffff\
|
||||
f0100f9029500000000232103adb7d8ef6b63de74313e0cd4e\
|
||||
07670d09a169b13e4eda2d650f529332c47646dac00000000\
|
||||
'{ "workid": "test" }'
|
||||
~~~
|
||||
|
299
_includes/ref_core_rpcs-uvwxyz.md
Normal file
|
@ -0,0 +1,299 @@
|
|||
#### validateaddress
|
||||
|
||||
~~~
|
||||
validateaddress <address>
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Return information about the given Bitcoin address.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument: An Address**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String; required:* A Bitcoin address.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Result: Information About The Address**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
A JSON object containing one or more values (the exact number depending
|
||||
on the information). The result of *isvalid* is always returned to
|
||||
indicated whether or not the address is valid. If it is valid, the
|
||||
validated *address* is returned plus *ismine* to indicate whether or not
|
||||
it belongs to this wallet and *account* to indicate which account it
|
||||
belongs to. If it's a P2SH address, *isscript* will be true. If it's a
|
||||
P2PKH address, *pubkey* will contain the public key and *compressed* will
|
||||
indicate whether or not the pubkey/address is compressed.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
{
|
||||
"isvalid" : <true|false>,
|
||||
"address" : "<address>",
|
||||
"ismine" : <true|false>,
|
||||
"isscript" : <true|false>,
|
||||
"pubkey" : "<public key hex>",
|
||||
"iscompressed" : <true|false>,
|
||||
"account" : "<account>"
|
||||
}
|
||||
~~~
|
||||
|
||||
**Example**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Validate the following address from the wallet:
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
> bitcoin-cli -testnet validateaddress mgnucj8nYqdrPFh2JfZSB1NmUThUGnmsqe
|
||||
~~~
|
||||
|
||||
Result:
|
||||
|
||||
~~~
|
||||
{
|
||||
"isvalid" : true,
|
||||
"address" : "mgnucj8nYqdrPFh2JfZSB1NmUThUGnmsqe",
|
||||
"ismine" : true,
|
||||
"isscript" : false,
|
||||
"pubkey" : "03bacb84c6464a58b3e0a53cc0ba4cb3b82848cd7bed25a7724b3cc75d76c9c1ba",
|
||||
"iscompressed" : true,
|
||||
"account" : "test label"
|
||||
}
|
||||
~~~
|
||||
|
||||
|
||||
#### verifychain
|
||||
|
||||
~~~
|
||||
verifychain [throughness] [blocks]
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Verify the local blockchain database.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #1: Throughness**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*Number; optional:* how thoroughly to check the database, from 0 to 4
|
||||
with 4 being the most through. Defaults to 3. <!-- TODO: what does each
|
||||
level do? -->
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #2: Number Of Blocks To Check**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*Number; optional:* check this number of the most recent blocks.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Result: Verified Or Not**
|
||||
|
||||
*True* if verified.
|
||||
|
||||
**Example**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Verify the most recent 10,000 blocks in the most through way:
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
> bitcoin-cli -testnet verifychain 4 10000
|
||||
~~~
|
||||
|
||||
Result (took 25 seconds on a generic PC laptop):
|
||||
|
||||
~~~
|
||||
true
|
||||
~~~
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#### verifymessage
|
||||
|
||||
~~~
|
||||
verifymessage <address> <signature> <message>
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Verify a signed message.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #1: The Address**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String; required:* the address corresponding to the private key used to
|
||||
create the signature.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #2: The Signature**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String; required:* the signature provided in the same base64 format
|
||||
generated by `signmessage`.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #3: The Message**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*String; required:* the exact message which was signed.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Result: True Or False**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
*True* if the message provided was signed by the private key corresponding to the
|
||||
address provided.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
**Example**
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Check the signature on the message created in the example for
|
||||
`signmessage`:
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
> bitcoin-cli -testnet verifymessage \
|
||||
mgnucj8nYqdrPFh2JfZSB1NmUThUGnmsqe \
|
||||
IOGreqb/7UgD1ifcojESd32ZJgH5RGzUXitmbl6ZbdenSmitipWoLSi73TskmLY7zhcD662bTw3RHoYQl/dOAhE= \
|
||||
'Hello, World!'
|
||||
~~~
|
||||
|
||||
Result:
|
||||
|
||||
~~~
|
||||
true
|
||||
~~~
|
||||
|
||||
|
||||
#### walletlock
|
||||
|
||||
~~~
|
||||
walletlock
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
Removes the wallet encryption key from memory, locking the wallet. After
|
||||
calling this method, you will need to call `walletpassphrase` again before
|
||||
being able to call any methods which require the wallet to be unlocked.
|
||||
{% endautocrossref %}
|
||||
|
||||
|
||||
**Return**
|
||||
|
||||
No return printed on success.
|
||||
|
||||
**Example**
|
||||
|
||||
~~~
|
||||
> bitcoin-cli -testnet walletlock
|
||||
~~~
|
||||
|
||||
(Success: nothing printed.)
|
||||
|
||||
|
||||
#### walletpassphrase
|
||||
|
||||
walletpassphrase <passphrase> <seconds>
|
||||
|
||||
{% autocrossref %}
|
||||
Stores the wallet decryption key in memory for the indicated number of
|
||||
seconds. Issuing the `walletpassphrase` command while the wallet is
|
||||
already unlocked will set a new unlock time that overrides the old one.
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #1: The Passphrase**
|
||||
|
||||
{% autocrossref %}
|
||||
*String; required:* the passphrase to unlock the encrypted wallet.
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #2: The Number Of Seconds To Leave The Wallet Unlocked**
|
||||
|
||||
{% autocrossref %}
|
||||
*Number; required:* The number of seconds after which the decryption key
|
||||
will be automatically deleted from memory.
|
||||
{% endautocrossref %}
|
||||
|
||||
**Result**
|
||||
|
||||
No result printed on success.
|
||||
|
||||
**Example**
|
||||
|
||||
{% autocrossref %}
|
||||
Unlock the wallet for 10 minutes (the passphrase is "test"):
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
> bitcoin-cli -testnet walletpassphrase test 600
|
||||
~~~
|
||||
|
||||
(Success: no result printed.)
|
||||
|
||||
|
||||
|
||||
#### walletpassphrasechange
|
||||
|
||||
~~~
|
||||
walletpassphrasechange <old passphrase> <new passphrase>
|
||||
~~~
|
||||
|
||||
{% autocrossref %}
|
||||
Changes the wallet passphrase from 'old passphrase' to 'new passphrase'.
|
||||
{% endautocrossref %}
|
||||
|
||||
**Argument #1: The Old Passphrase**
|
||||
|
||||
*String; required:* the current passphrase.
|
||||
|
||||
**Argument #2: The New Passphrase**
|
||||
|
||||
*String; required:* the new passphrase.
|
||||
|
||||
**Result**
|
||||
|
||||
No result printed on success.
|
||||
|
||||
**Example**
|
||||
|
||||
Change the wallet passphrase from "test" to "example":
|
||||
|
||||
~~~
|
||||
> bitcoin-cli -testnet walletpassphrasechange test example
|
||||
~~~
|
||||
|
||||
(Success: no result printed.)
|
||||
|
232
_includes/ref_transactions.md
Normal file
|
@ -0,0 +1,232 @@
|
|||
## Transactions
|
||||
|
||||
The following subsections briefly document core transaction details.
|
||||
|
||||
#### OP Codes
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
The op codes used in standard transactions are,
|
||||
|
||||
* Various data pushing op codes from 0x00 to 0x4e (1--78). These aren't
|
||||
typically shown in examples, but they must be used to push
|
||||
signatures and public keys onto the stack. See the link below this list
|
||||
for a description.
|
||||
|
||||
* `OP_1NEGATE` (0x4f), `OP_TRUE`/`OP_1` (0x51), and `OP_2` through
|
||||
`OP_16` (0x52--0x60), which (respectively) push the values -1, 1, and
|
||||
2--16 to the stack.
|
||||
|
||||
* [`OP_CHECKSIG`][op_checksig]{:#term-op-checksig}{:.term} consumes a signature and a full public key, and returns
|
||||
true if the the transaction data specified by the SIGHASH flag was
|
||||
converted into the signature using the same ECDSA private key that
|
||||
generated the public key. Otherwise, it returns false.
|
||||
|
||||
* [`OP_DUP`][op_dup]{:#term-op-dup}{:.term} returns a copy of the item on the stack below it.
|
||||
|
||||
* [`OP_HASH160`][op_hash160]{:#term-op-hash160}{:.term} consumes the item on the stack below it and returns with
|
||||
a RIPEMD-160(SHA256()) hash of that item.
|
||||
|
||||
* [`OP_EQUAL`][op_equal]{:#term-op-equal}{:.term} consumes the two items on the stack below it and returns
|
||||
true if they are the same. Otherwise, it returns false.
|
||||
|
||||
* [`OP_VERIFY`][op_verify]{:#term-op-verify}{:.term} consumes one value and returns nothing, but it will
|
||||
terminate the script in failure if the value consumed is zero (false).
|
||||
|
||||
* [`OP_EQUALVERIFY`][op_equalverify]{:#term-op-equalverify}{:.term} runs `OP_EQUAL` and then `OP_VERIFY` in sequence.
|
||||
|
||||
* [`OP_CHECKMULTISIG`][op_checkmultisig]{:#term-op-checkmultisig}{:.term} consumes the value (n) at the top of the stack,
|
||||
consumes that many of the next stack levels (public keys), consumes
|
||||
the value (m) now at the top of the stack, and consumes that many of
|
||||
the next values (signatures) plus one extra value. Then it compares
|
||||
each of public keys against each of the signatures looking for ECDSA
|
||||
matches; if n of the public keys match signatures, it returns true.
|
||||
Otherwise, it returns false.
|
||||
|
||||
The "one extra value" it consumes is the result of an off-by-one
|
||||
error in the Bitcoin Core implementation. This value is not used, so
|
||||
scriptSigs prefix the signatures with a single OP_0 (0x00).
|
||||
|
||||
* [`OP_RETURN`][op_return]{:#term-op-return}{:.term} terminates the script in failure,
|
||||
rendering the output unspendable and allowing a miner to claim the
|
||||
satoshis sent to that OP_RETURN output as an additional transaction fee.
|
||||
|
||||
A complete list of OP codes can be found on the Bitcoin Wiki [Script
|
||||
Page][wiki script], with an authoritative list in the `opcodetype` enum
|
||||
of the Bitcoin Core [script header file][core script.h]
|
||||
|
||||
Note: non-standard transactions can add non-data-pushing op codes to
|
||||
their scriptSig, but scriptSig is run separately from the script (with a
|
||||
shared stack), so scriptSig can't use arguments such as `OP_RETURN` to
|
||||
prevent the script from working as expected.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
#### Address Conversion
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
The hashes used in P2PKH and P2SH outputs are commonly encoded as Bitcoin
|
||||
addresses. This is the procedure to encode those hashes and decode the
|
||||
addresses.
|
||||
|
||||
First, get your hash. For P2PKH, you RIPEMD-160(SHA256()) hash a ECDSA
|
||||
public key derived from your 256-bit ECDSA private key (random data).
|
||||
For P2SH, you RIPEMD-160(SHA256()) hash a redeemScript serialized in the
|
||||
format used in raw transactions (described in a [following
|
||||
sub-section][raw transaction format]). Taking the resulting hash:
|
||||
|
||||
1. Add an address version byte in front of the hash. The version
|
||||
bytes commonly used by Bitcoin are:
|
||||
|
||||
* 0x00 for P2PKH addresses on the main Bitcoin network (mainnet)
|
||||
|
||||
* 0x6f for P2PKH addresses on the Bitcoin testing network (testnet)
|
||||
|
||||
* 0x05 for P2SH addresses on mainnet
|
||||
|
||||
* 0xc4 for P2SH addresses on testnet
|
||||
|
||||
2. Create a copy of the version and hash; then hash that twice with SHA256: `SHA256(SHA256(version . hash))`
|
||||
|
||||
3. Extract the four most significant bytes from the double-hashed copy.
|
||||
These are used as a checksum to ensure the base hash gets transmitted
|
||||
correctly.
|
||||
|
||||
4. Append the checksum to the version and hash, and encode it as a base58
|
||||
string: <!--[-->`BASE58(version . hash . checksum)`<!--]-->
|
||||
|
||||
Bitcoin's base58 encoding, called [Base58Check][]{:#term-base58check}{:.term} may not match other implementations. Tier
|
||||
Nolan provided the following example encoding algorithm to the Bitcoin
|
||||
Wiki [Base58Check
|
||||
encoding](https://en.bitcoin.it/wiki/Base58Check_encoding) page:
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
{% highlight c %}
|
||||
code_string = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||
x = convert_bytes_to_big_integer(hash_result)
|
||||
|
||||
output_string = ""
|
||||
|
||||
while(x > 0)
|
||||
{
|
||||
(x, remainder) = divide(x, 58)
|
||||
output_string.append(code_string[remainder])
|
||||
}
|
||||
|
||||
repeat(number_of_leading_zero_bytes_in_hash)
|
||||
{
|
||||
output_string.append(code_string[0]);
|
||||
}
|
||||
|
||||
output_string.reverse();
|
||||
{% endhighlight %}
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Bitcoin's own code can be traced using the [base58 header
|
||||
file][core base58.h].
|
||||
|
||||
To convert addresses back into hashes, reverse the base58 encoding, extract
|
||||
the checksum, repeat the steps to create the checksum and compare it
|
||||
against the extracted checksum, and then remove the version byte.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
#### Raw Transaction Format
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Bitcoin transactions are broadcast between peers and stored in the
|
||||
block chain in a serialized byte format, called [raw format][]{:#term-raw-format}{:.term}. Bitcoin Core
|
||||
and many other tools print and accept raw transactions encoded as hex.
|
||||
|
||||
A sample raw transaction is the first non-coinbase transaction, made in
|
||||
[block 170][block170]. To get the transaction, use the `getrawtransaction` RPC with
|
||||
that transaction's txid (provided below):
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
~~~
|
||||
> getrawtransaction \
|
||||
f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16
|
||||
|
||||
0100000001c997a5e56e104102fa209c6a852dd90660a20b2d9c352423e\
|
||||
dce25857fcd3704000000004847304402204e45e16932b8af514961a1d3\
|
||||
a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07d\
|
||||
e4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901ffffffff\
|
||||
0200ca9a3b00000000434104ae1a62fe09c5f51b13905f07f06b99a2f71\
|
||||
59b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7\
|
||||
303b8a0626f1baded5c72a704f7e6cd84cac00286bee000000004341041\
|
||||
1db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a690\
|
||||
9a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f\
|
||||
656b412a3ac00000000
|
||||
~~~
|
||||
|
||||
A byte-by-byte analysis by Amir Taaki (Genjix) of this transaction is
|
||||
provided below. (Originally from the Bitcoin Wiki
|
||||
[OP_CHECKSIG page](https://en.bitcoin.it/wiki/OP_CHECKSIG); Genjix's
|
||||
text has been updated to use the terms used in this document.)
|
||||
|
||||
~~~
|
||||
01 00 00 00 version number
|
||||
01 number of inputs (var_uint)
|
||||
|
||||
input 0:
|
||||
c9 97 a5 e5 6e 10 41 02 previous tx hash (txid)
|
||||
fa 20 9c 6a 85 2d d9 06
|
||||
60 a2 0b 2d 9c 35 24 23
|
||||
ed ce 25 85 7f cd 37 04
|
||||
00 00 00 00 previous output index
|
||||
|
||||
48 size of script (var_uint)
|
||||
47 push 71 bytes to stack
|
||||
30 44 02 20 4e 45 e1 69
|
||||
32 b8 af 51 49 61 a1 d3
|
||||
a1 a2 5f df 3f 4f 77 32
|
||||
e9 d6 24 c6 c6 15 48 ab
|
||||
5f b8 cd 41 02 20 18 15
|
||||
22 ec 8e ca 07 de 48 60
|
||||
a4 ac dd 12 90 9d 83 1c
|
||||
c5 6c bb ac 46 22 08 22
|
||||
21 a8 76 8d 1d 09 01
|
||||
ff ff ff ff sequence number
|
||||
|
||||
02 number of outputs (var_uint)
|
||||
|
||||
output 0:
|
||||
00 ca 9a 3b 00 00 00 00 amount = 10.00000000 BTC
|
||||
43 size of script (var_uint)
|
||||
script for output 0:
|
||||
41 push 65 bytes to stack
|
||||
04 ae 1a 62 fe 09 c5 f5
|
||||
1b 13 90 5f 07 f0 6b 99
|
||||
a2 f7 15 9b 22 25 f3 74
|
||||
cd 37 8d 71 30 2f a2 84
|
||||
14 e7 aa b3 73 97 f5 54
|
||||
a7 df 5f 14 2c 21 c1 b7
|
||||
30 3b 8a 06 26 f1 ba de
|
||||
d5 c7 2a 70 4f 7e 6c d8
|
||||
4c
|
||||
ac OP_CHECKSIG
|
||||
|
||||
output 1:
|
||||
00 28 6b ee 00 00 00 00 amount = 40.00000000 BTC
|
||||
43 size of script (var_uint)
|
||||
script for output 1:
|
||||
41 push 65 bytes to stack
|
||||
04 11 db 93 e1 dc db 8a
|
||||
01 6b 49 84 0f 8c 53 bc
|
||||
1e b6 8a 38 2e 97 b1 48
|
||||
2e ca d7 b1 48 a6 90 9a
|
||||
5c b2 e0 ea dd fb 84 cc
|
||||
f9 74 44 64 f8 2e 16 0b
|
||||
fa 9b 8b 64 f9 d4 c0 3f
|
||||
99 9b 86 43 f6 56 b4 12
|
||||
a3
|
||||
ac OP_CHECKSIG
|
||||
|
||||
00 00 00 00 locktime
|
||||
~~~
|
||||
|
25
_includes/ref_wallets.md
Normal file
|
@ -0,0 +1,25 @@
|
|||
## Wallets
|
||||
|
||||
### Deterministic Wallet Formats
|
||||
|
||||
#### Type 1: Single Chain Wallets
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||
Type 1 deterministic wallets are the simpler of the two, which can
|
||||
create a single series of keys from a single seed. A primary weakness is
|
||||
that if the seed is leaked, all funds are compromised, and wallet
|
||||
sharing is extremely limited.
|
||||
|
||||
{% endautocrossref %}
|
||||
|
||||
#### Type 2: Hierarchical Deterministic (HD) Wallets
|
||||
|
||||
{% autocrossref %}
|
||||
|
||||

|
||||
|
||||
For an overview of HD wallets, please see the [developer guide
|
||||
section][devguide wallets]. For details, please see BIP32.
|
||||
|
||||
{% endautocrossref %}
|
282
_includes/references.md
Normal file
|
@ -0,0 +1,282 @@
|
|||
[51 percent attack]: /en/developer-guide#term-51-attack "The ability of someone controlling a majority of hashing power to revise transactions history and prevent new transactions from confirming"
|
||||
[accidental fork]: /en/developer-guide#term-accidental-fork "When two or more blocks have the same block height, forking the block chain. Happens occasionally by accident"
|
||||
[addresses]: /en/developer-guide#term-address "A 20-byte hash formatted as a P2PKH or P2SH Bitcoin Address"
|
||||
[address]: /en/developer-guide#term-address "A 20-byte hash formatted as a P2PKH or P2SH Bitcoin Address"
|
||||
[base58Check]: /en/developer-reference#term-base58check "The method used in Bitcoin for converting 160-bit hashes into Bitcoin addresses"
|
||||
[bitcoin URI]: /en/developer-guide#term-bitcoin-uri "A URI which allows receivers to encode payment details so spenders don't have to manually enter addresses and other details"
|
||||
[bitcoins]: /en/developer-guide#term-bitcoins "A primary accounting unit used in Bitcoin; 100 million satoshis"
|
||||
[block]: /en/developer-guide#term-block "A block of transactions protected by proof of work"
|
||||
[blocks]: /en/developer-guide#term-block "Blocks of transactions protected by proof of work"
|
||||
[block chain]: /en/developer-guide#block-chain "A chain of blocks with each block linking to the block that preceded; the most-difficult-to-recreate chain is The Block Chain"
|
||||
[block header]: /en/developer-reference#block-header "An 80-byte header belonging to a single block which is hashed repeatedly to create proof of work"
|
||||
[block header magic]: /en/developer-reference#term-block-header-magic "A magic number used to separate block data from transaction data on the P2P network"
|
||||
[block height]: /en/developer-guide#term-block-height "The number of chained blocks preceding this block"
|
||||
[block reward]: /en/developer-reference#term-block-reward "New satoshis given to a miner for creating one of the first 6,929,999 blocks"
|
||||
[block time]: /en/developer-reference#term-block-time "The time field in the block header"
|
||||
[block version]: /en/developer-reference#term-block-version "The version field in the block header"
|
||||
[broadcast]: /en/developer-guide#transaction-broadcasting "Sending transactions or blocks to all other peers on the Bitcoin network (compare to privately transmitting to a single peer or partner"
|
||||
[broadcasts]: /en/developer-guide#transaction-broadcasting "Sending transactions or blocks to all other peers on the Bitcoin network (compare to privately transmitting to a single peer or partner"
|
||||
[broadcasting]: /en/developer-guide#transaction-broadcasting "Sending transactions or blocks to all other peers on the Bitcoin network (compare to privately transmitting to a single peer or partner)"
|
||||
[certificate chain]: /en/developer-guide#term-certificate-chain "A chain of certificates connecting a individual's leaf certificate to the certificate authority's root certificate"
|
||||
[chain code]: /en/developer-guide#term-chain-code "In HD wallets, 256 bits of entropy added to the master public and private keys to help them generate secure child keys; the chain code is usually derived from a seed along with the master private key"
|
||||
[change address]: /en/developer-guide#term-change-output "An output used by a spender to send back to himself some of the satoshis from the inputs"
|
||||
[change output]: /en/developer-guide#term-change-output "An output used by a spender to send back to himself some of the satoshis from the inputs"
|
||||
[child key]: /en/developer-guide#term-child-key "In HD wallets, a key derived from a parent key"
|
||||
[child public key]: /en/developer-guide#term-child-public-key "In HD wallets, a public key derived from a parent public key or a corresponding child private key"
|
||||
[coinbase field]: /en/developer-reference#term-coinbase-field "A special input-like field for coinbase transactions"
|
||||
[coinbase transaction]: /en/developer-reference#term-coinbase-tx "A special transaction which miners must create when they generate a block"
|
||||
[confirm]: /en/developer-guide#term-confirmation "A transaction included in a block currently on the block chain"
|
||||
[confirmed]: /en/developer-guide#term-confirmation "A transaction included in a block currently on the block chain"
|
||||
[confirmed transactions]: /en/developer-guide#term-confirmation "Transactions included in a block currently on the block chain"
|
||||
[confirmation]: /en/developer-guide#term-confirmation "The number of blocks which would need to be modified to remove or modify a transaction"
|
||||
[confirmations]: /en/developer-guide#term-confirmation "The number of blocks which would need to be modified to remove or modify a transaction"
|
||||
[denomination]: /en/developer-guide#term-denomination "bitcoins (BTC), bitcents (cBTC), millibits (mBTC), microbits (uBTC), or satoshis"
|
||||
[difficulty]: /en/developer-guide#term-difficulty "A number corresponding to the target threshold which indicates how difficult it will be to find the next block"
|
||||
[double spend]: /en/developer-guide#term-double-spend "Attempting to spend the same satoshis which were spent in a previous transaction"
|
||||
[extended key]: /en/developer-guide#term-extended-key "A public or private key extended with the chain code to allow them to derive child keys"
|
||||
[extended private key]: /en/developer-guide#term-extended-private-key "A private key extended with the chain code so that it can derive child private keys"
|
||||
[extended public key]: /en/developer-guide#term-extended-public-key "A public key extended with the chain code so that it can derive child public keys"
|
||||
[escrow contract]: /en/developer-guide#term-escrow-contract "A contract in which the spender and receiver store satoshis in a multisig output until both parties agree to release the satoshis"
|
||||
[fiat]: /en/developer-guide#term-fiat "National currencies such as the dollar or euro"
|
||||
[genesis block]: /en/developer-guide#term-genesis-block "The first block created; also called block 0"
|
||||
[hardened extended private key]: /en/developer-guide#term-hardened-extended-private-key "A private key whose corresponding public key cannot derive child keys"
|
||||
[HD protocol]: /en/developer-guide#term-hd-protocol "The Hierarchical Deterministic (HD) key creation and transfer protocol"
|
||||
[header nonce]: /en/developer-reference#term-header-nonce "Four bytes of arbitrary data in a block header used to let miners create headers with different hashes for proof of work"
|
||||
[high-priority transactions]: /en/developer-guide#term-high-priority-transactions "Transactions which don't pay a transaction fee; only transactions spending long-idle outputs are eligible"
|
||||
[input]: /en/developer-guide#term-input "The input to a transaction linking to the output of a previous transaction which permits spending of satoshis"
|
||||
[inputs]: /en/developer-guide#term-input "The input to a transaction linking to the output of a previous transaction which permits spending of satoshis"
|
||||
[intermediate certificate]: /en/developer-guide#term-intermediate-certificate "A intermediate certificate authority certificate which helps connect a leaf (receiver) certificate to a root certificate authority"
|
||||
[key index]: /en/developer-guide#term-key-index "An index number used in the HD wallet formula to generate child keys from a parent key"
|
||||
[key pair]: /en/developer-guide#term-key-pair "A private key and its derived public key"
|
||||
[label]: /en/developer-guide#term-label "The label parameter of a bitcoin: URI which provides the spender with the receiver's name (unauthenticated)"
|
||||
[leaf certificate]: /en/developer-guide#term-leaf-certificate "The end-node in a certificate chain; in the payment protocol, it is the certificate belonging to the receiver of satoshis"
|
||||
[locktime]: /en/developer-guide#term-locktime "Part of a transaction which indicates the earliest time or earliest block when that transaction can be added to the block chain"
|
||||
[long-term fork]: /en/developer-guide#term-long-term-fork "When a series of blocks have corresponding block heights, indicating a possibly serious problem"
|
||||
[mainnet]: /en/developer-guide#term-mainnet "The Bitcoin main network used to transfer satoshis (compare to testnet, the test network)"
|
||||
[master chain code]: /en/developer-guide#term-master-chain-code "The chain code derived from the root seed"
|
||||
[master private key]: /en/developer-guide#term-master-private-key "A private key derived from the root seed"
|
||||
[merge]: /en/developer-guide#term-merge "Spending, in the same transaction, multiple outputs which can be traced back to different previous spenders, leaking information about how many satoshis you control"
|
||||
[merge avoidance]: /en/developer-guide#term-merge-avoidance "A strategy for selecting which outputs to spend that avoids merging outputs with different histories that could leak private information"
|
||||
[message]: /en/developer-guide#term-message "A parameter of bitcoin: URIs which allows the receiver to optionally specify a message to the spender"
|
||||
[Merkle root]: /en/developer-guide#term-merkle-root "The root node of a Merkle tree descended from all the hashed pairs in the tree"
|
||||
[Merkle tree]: /en/developer-guide#term-merkle-tree "A tree constructed by hashing paired data, then pairing and hashing the results until a single hash remains, the Merkle root"
|
||||
[micropayment channel]: /en/developer-guide#term-micropayment-channel
|
||||
[millibits]: /en/developer-guide#term-millibits "0.001 bitcoins (100,000 satoshis)"
|
||||
[mine]: /en/developer-guide#term-miner "Creating Bitcoin blocks which solve proof-of-work puzzles in exchange for block rewards and transaction fees"
|
||||
[miner]: /en/developer-guide#term-miner "Creators of Bitcoin blocks who solve proof-of-work puzzles in exchange for block rewards and transaction fees"
|
||||
[miners]: /en/developer-guide#term-miner "Creators of Bitcoin blocks who solve proof-of-work puzzles in exchange for block rewards and transaction fees"
|
||||
[minimum fee]: /en/developer-guide#term-minimum-fee "The minimum fee a transaction must pay in must circumstances to be mined or broadcast by peers across the network"
|
||||
[multisig]: /en/developer-guide#term-multisig "An output script using OP_CHECKMULTISIG to check for multiple signatures"
|
||||
[network]: /en/developer-guide#term-network "The Bitcoin P2P network which broadcasts transactions and blocks"
|
||||
[Null data]: /en/developer-guide#term-null-data "A standard transaction type which allows adding 40 bytes of arbitrary data to the block chain up to once per transaction"
|
||||
[op_checkmultisig]: /en/developer-reference#term-op-checkmultisig "Op code which returns true if one or more provided signatures (m) sign the correct parts of a transaction and match one or more provided public keys (n)"
|
||||
[op_checksig]: /en/developer-reference#term-op-checksig "Op code which returns true if a signature signs the correct parts of a transaction and matches a provided public key"
|
||||
[op code]: /en/developer-reference#op-codes "Operation codes which run functions within a script"
|
||||
[op_dup]: /en/developer-reference#term-op-dup "Operation which duplicates the entry below it on the stack"
|
||||
[op_equal]: /en/developer-reference#term-op-equal "Operation which returns true if the two entries below it on the stack are equivalent"
|
||||
[op_equalverify]: /en/developer-reference#term-op-equalverify "Operation which terminates the script in failure unless the two entries below it on the stack are equivalent"
|
||||
[op_hash160]: /en/developer-reference#term-op-hash160 "Operation which converts the entry below it on the stack into a RIPEMD(SHA256()) hashed version of itself"
|
||||
[op_return]: /en/developer-reference#term-op-return "Operation which terminates the script in failure"
|
||||
[op_verify]: /en/developer-reference#term-op-verify "Operation which terminates the script if the entry below it on the stack is non-true (zero)"
|
||||
[orphan]: /en/developer-guide#term-orphan "Blocks which were successfully mined but which aren't included on the current valid block chain"
|
||||
[output]: /en/developer-guide#term-output "The output of a transaction which transfers value to a script"
|
||||
[output index]: /en/developer-guide#term-output-index "The sequentially-numbered index of outputs in a single transaction starting from 0"
|
||||
[outputs]: /en/developer-guide#term-output "The outputs of a transaction which transfer value to scripts"
|
||||
[P2PKH]: /en/developer-guide#term-p2pkh "A script which Pays To Pubkey Hashes (P2PKH), allowing spending of satoshis to anyone with a Bitcoin address"
|
||||
[P2SH]: /en/developer-guide#term-p2sh "A script which Pays To Script Hashes (P2SH), allowing convenient spending of satoshis to an address referencing a script"
|
||||
[P2SH multisig]: /en/developer-guide#term-p2sh-multisig "A multisig script embedded in the redeemScript of a pay-to-script-hash (P2SH) transaction"
|
||||
[parent chain code]: /en/developer-guide#term-parent-chain-code "A chain code which has helped create child public or private keys"
|
||||
[parent private key]: /en/developer-guide#term-parent-private-key "A private key which has created child private keys"
|
||||
[parent public key]: /en/developer-guide#term-parent-public-key "A public key corresponding to a parent private key which has child private keys"
|
||||
[payment protocol]: /en/developer-guide#term-payment-protocol "The protocol defined in BIP70 which lets spenders get signed payment details from receivers"
|
||||
[PaymentACK]: /en/developer-guide#term-paymentack "The PaymentACK of the payment protocol which allows the receiver to indicate to the spender that the payment is being processed"
|
||||
[PaymentDetails]: /en/developer-guide#term-paymentdetails "The PaymentDetails of the payment protocol which allows the receiver to specify the payment details to the spender"
|
||||
[PaymentRequest]: /en/developer-guide#term-paymentrequest "The PaymentRequest of the payment protocol which contains and allows signing of the PaymentDetails"
|
||||
[PaymentRequests]: /en/developer-guide#term-paymentrequest "The PaymentRequest of the payment protocol which contains and allows signing of the PaymentDetails"
|
||||
[peer]: /en/developer-guide#term-peer "Peer on the P2P network who receives and broadcasts transactions and blocks"
|
||||
[peers]: /en/developer-guide#term-peer "Peers on the P2P network who receive and broadcast transactions and blocks"
|
||||
[PKI]: /en/developer-guide#term-pki "Public Key Infrastructure; usually meant to indicate the X.509 certificate system used for HTTP Secure (https)."
|
||||
[point function]: /en/developer-guide#term-point-function "The ECDSA function used to create a public key from a private key"
|
||||
[private key]: /en/developer-guide#term-private-key "The private portion of a keypair which can create signatures which other people can verify using the public key"
|
||||
[private keys]: /en/developer-guide#term-private-key "The private portion of a keypair which can create signatures which other people can verify using the public key"
|
||||
[pubkey hash]: /en/developer-guide#term-pubkey-hash "The hash of a public key which can be included in a P2PKH output"
|
||||
[public key]: /en/developer-guide#term-public-key "The public portion of a keypair which can be safely distributed to other people so they can verify a signature created with the corresponding private key"
|
||||
[public keys]: /en/developer-guide#term-public-key "The public portion of a keypair which can be safely distributed to other people so they can verify a signature created with the corresponding private key"
|
||||
[pp amount]: /en/developer-guide#term-pp-amount "Part of the Output part of the PaymentDetails part of a payment protocol where receivers can specify the amount of satoshis they want paid to a particular output script"
|
||||
[pp expires]: /en/developer-guide#term-pp-expires "The expires field of a PaymentDetails where the receiver tells the spender when the PaymentDetails expires"
|
||||
[pp memo]: /en/developer-guide#term-pp-memo "The memo fields of PaymentDetails, Payment, and PaymentACK which allow spenders and receivers to send each other memos"
|
||||
[pp merchant data]: /en/developer-guide#term-pp-merchant-data "The merchant_data part of PaymentDetails and Payment which allows the receiver to send arbitrary data to the spender in PaymentDetails and receive it back in Payments"
|
||||
[pp Payment]: /en/developer-guide#term-pp-payment "The Payment message of the PaymentProtocol which allows the spender to send payment details to the receiver"
|
||||
[pp PKI data]: /en/developer-guide#term-pp-pki-data "The pki_data field of a PaymentRequest which provides details such as certificates necessary to validate the request"
|
||||
[pp pki type]: /en/developer-guide#term-pp-pki-type "The PKI field of a PaymentRequest which tells spenders how to validate this request as being from a specific recipient"
|
||||
[pp refund to]: /en/developer-guide#term-pp-refund-to "The refund_to field of a Payment where the spender tells the receiver what outputs to send refunds to"
|
||||
[pp script]: /en/developer-guide#term-pp-script "The script field of a PaymentDetails where the receiver tells the spender what output scripts to pay"
|
||||
[pp transactions]: /en/developer-guide#term-pp-transactions "The transactions field of a Payment where the spender provides copies of signed transactions to the receiver"
|
||||
[pp payment url]: /en/developer-guide#term-pp-payment-url "The payment_url of the PaymentDetails which allows the receiver to specify where the sender should post payment"
|
||||
[proof of work]: /en/developer-guide#term-proof-of-work "Proof that computationally-difficult work was performed which helps secure blocks against modification, protecting transaction history"
|
||||
[Pubkey]: /en/developer-guide#term-pubkey "A standard output script which specifies the full public key to match a signature; used in coinbase transactions"
|
||||
[r]: /en/developer-guide#term-r-parameter "The payment request parameter in a bitcoin: URI"
|
||||
[raw format]: /en/developer-reference#term-raw-format "Complete transactions in their binary format; often represented using hexidecimal"
|
||||
[receipt]: /en/developer-guide#term-receipt "A cryptographically-verifiable receipt created using parts of a payment request and a confirmed transaction"
|
||||
[recurrent rebilling]: /en/developer-guide#rebilling-recurring-payments "Billing a spender on a regular schedule"
|
||||
[redeemScript]: /en/developer-guide#term-redeemscript "A script created by the recipient, hashed, and given to the spender for use in a P2SH output"
|
||||
[refund]: /en/developer-guide#issuing-refunds "A transaction which refunds some or all satoshis received in a previous transaction"
|
||||
[root certificate]: /en/developer-guide#term-root-certificate "A certificate belonging to a certificate authority (CA)"
|
||||
[root seed]: /en/developer-guide#term-root-seed "A potentially-short value used as a seed to generate a master private key and master chain code for an HD wallet"
|
||||
[satoshi]: /en/developer-guide#term-satoshi "The smallest unit of Bitcoin value; 0.00000001 bitcoins. Also used generically for any value of bitcoins"
|
||||
[satoshis]: /en/developer-guide#term-satoshi "The smallest unit of Bitcoin value; 0.00000001 bitcoins. Also used generically for any value of bitcoins"
|
||||
[sequence number]: /en/developer-guide#term-sequence-number "A number intended to allow time locked transactions to be updated before being finalized; not currently used except to disable locktime in a transaction"
|
||||
[script]: /en/developer-guide#term-script "The part of an output which sets the conditions for spending of the satoshis in that output"
|
||||
[scripts]: /en/developer-guide#term-script "The part of an output which sets the conditions for spending of the satoshis in that output"
|
||||
[scriptSig]: /en/developer-guide#term-scriptsig "Data generated by a spender which is almost always used as variables to satisfy an output script"
|
||||
[script hash]: /en/developer-guide#term-script-hash "The hash of a redeemScript used to create a P2SH output"
|
||||
[sha_shacp]: /en/developer-guide#term-sighash-all-sighash-anyonecanpay "Signature hash type which allows other people to contribute satoshis without changing the number of satoshis sent nor where they go"
|
||||
[shacp]: /en/developer-guide#term-sighash-anyonecanpay "A signature hash type which modifies the behavior of other signature hash types"
|
||||
[shn_shacp]: /en/developer-guide#term-sighash-none-sighash-anyonecanpay "Signature hash type which allows unfettered modification of a transaction"
|
||||
[shs_shacp]: /en/developer-guide#term-sighash-single-sighash-anyonecanpay "Signature hash type which allows modification of the entire transaction except the signed input and the output with the same index number"
|
||||
[sighash_all]: /en/developer-guide#term-sighash-all "Default signature hash type which signs the entire transaction except any scriptSigs, preventing modification of the signed parts"
|
||||
[sighash_none]: /en/developer-guide#term-sighash-none "Signature hash type which only signs the inputs, allowing anyone to change the outputs however they'd like"
|
||||
[sighash_single]: /en/developer-guide#term-sighash-single "Signature hash type which only signs its input and the output with the same index value, allowing modification of other inputs and outputs"
|
||||
[signature]: /en/developer-guide#term-signature "The result of combining a private key and some data in an ECDSA signature operation which allows anyone with the corresponding public key to verify the signature"
|
||||
[signature hash]: /en/developer-guide#term-signature-hash "A byte appended onto signatures generated in Bitcoin which allows the signer to specify what data was signed, allowing modification of the unsigned data"
|
||||
[spv]: /en/developer-guide#simplified-payment-verification-spv "A method for verifying particular transactions were included in blocks without downloading the entire contents of the block chain"
|
||||
[ssl signature]: /en/developer-guide#term-ssl-signature "Signatures created and recognized by major SSL implementations such as OpenSSL"
|
||||
[stack]: /en/developer-guide#term-stack "An evaluation stack used in Bitcoin's script language"
|
||||
[standard script]: /en/developer-guide#standard-transactions "An output script which matches the isStandard() patterns specified in Bitcoin Core---or a transaction containing only standard outputs. Only standard transactions are mined or broadcast by peers running the default Bitcoin Core software"
|
||||
[target]: /en/developer-guide#term-target "The threshold below which a block header hash must be in order for the block to be added to the block chain"
|
||||
[testnet]: /en/developer-guide#term-testnet "A Bitcoin-like network where the satoshis have no real-world value to allow risk-free testing"
|
||||
[transaction fee]: /en/developer-guide#term-transaction-fee "The amount remaining when all outputs are subtracted from all inputs in a transaction; the fee is paid to the miner who includes that transaction in a block"
|
||||
[transaction fees]: /en/developer-guide#term-transaction-fee "The amount remaining when all outputs are subtracted from all inputs in a transaction; the fee is paid to the miner who includes that transaction in a block"
|
||||
[transaction malleability]: /en/developer-guide#transaction-malleability "The ability of an attacker to change the transaction identifier (txid) of unconfirmed transactions, making dependent transactions invalid"
|
||||
[txid]: /en/developer-guide#term-txid "A hash of a completed transaction which allows other transactions to spend its outputs"
|
||||
[transaction]: /en/developer-guide#transactions "A transaction spending satoshis"
|
||||
[transaction object format]: /en/developer-reference#term-transaction-object-format
|
||||
[transaction version number]: /en/developer-guide#term-transaction-version-number "A version number prefixed to transactions to allow upgrading""
|
||||
[transactions]: /en/developer-guide#transactions "A transaction spending satoshis"
|
||||
[unconfirmed]: /en/developer-guide#term-unconfirmed-transactions "A transaction which has not yet been added to the block chain"
|
||||
[unconfirmed transactions]: /en/developer-guide#term-unconfirmed-transactions "A transaction which has not yet been added to the block chain"
|
||||
[unique addresses]: /en/developer-guide#term-unique-address "Address which are only used once to protect privacy and increase security"
|
||||
[URI QR Code]: /en/developer-guide#term-uri-qr-code "A QR code containing a bitcoin: URI"
|
||||
[utxo]: /en/developer-guide#term-utxo "Unspent Transaction Output (UTXO) holding satoshis which have not yet been spent"
|
||||
[verified payments]: /en/developer-guide#verifying-payment "Payments which the receiver believes won't be double spent"
|
||||
[v2 block]: /en/developer-reference#term-v2-block "The current version of Bitcoin blocks"
|
||||
[wallet]: /en/developer-guide#wallets "Software which stores private keys to allow users to spend and receive satoshis"
|
||||
[Wallet Import Format]: /en/developer-guide#term-wallet-import-format "A private key specially formatted to allow easy import into a wallet"
|
||||
[wallets]: /en/developer-guide#wallets "Software which stores private keys to allow users to spend and receive satoshis"
|
||||
[X509Certificates]: /en/developer-guide#term-x509certificates
|
||||
|
||||
[BFGMiner]: https://github.com/luke-jr/bfgminer
|
||||
[BIP21]: https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki
|
||||
[BIP32]: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
|
||||
[BIP39]: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
|
||||
[BIP70]: https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki
|
||||
[bitcoin-documentation mailing list]: https://groups.google.com/forum/#!forum/bitcoin-documentation
|
||||
[bitcoinpdf]: https://bitcoin.org/bitcoin.pdf
|
||||
[block170]: http://blockexplorer.com/block/00000000d1145790a8694403d4063f323d499e655c83426834d4ce2f8dd4a2ee
|
||||
[casascius address utility]: https://github.com/casascius/Bitcoin-Address-Utility
|
||||
[core base58.h]: https://github.com/bitcoin/bitcoin/blob/master/src/base58.h
|
||||
[core executable]: /en/download
|
||||
[core git]: https://github.com/bitcoin/bitcoin
|
||||
[core paymentrequest.proto]: https://github.com/bitcoin/bitcoin/blob/master/src/qt/paymentrequest.proto
|
||||
[core script.h]: https://github.com/bitcoin/bitcoin/blob/master/src/script.h
|
||||
[DER]: https://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One
|
||||
[devguide wallets]: /en/developer-guide#wallets
|
||||
[devref wallets]: /en/developer-reference#wallets
|
||||
[docs issue]: https://github.com/bitcoin/bitcoin.org/issues
|
||||
[ECDSA]: https://en.wikipedia.org/wiki/Elliptic_Curve_DSA
|
||||
[Eloipool]: https://gitorious.org/bitcoin/eloipool
|
||||
[forum tech support]: https://bitcointalk.org/index.php?board=4.0
|
||||
[HMAC-SHA512]: https://en.wikipedia.org/wiki/HMAC
|
||||
[HTTP longpoll]: https://en.wikipedia.org/wiki/Push_technology#Long_polling
|
||||
[irc channels]: https://en.bitcoin.it/wiki/IRC_channels
|
||||
[MIME]: https://en.wikipedia.org/wiki/Internet_media_type
|
||||
[Merge Avoidance subsection]: /en/developer-guide#merge-avoidance
|
||||
[mozrootstore]: https://www.mozilla.org/en-US/about/governance/policies/security-group/certs/
|
||||
[Piotr Piasecki's testnet faucet]: https://tpfaucet.appspot.com/
|
||||
[prime symbol]: https://en.wikipedia.org/wiki/Prime_%28symbol%29
|
||||
[protobuf]: https://developers.google.com/protocol-buffers/
|
||||
[raw transaction format]: /en/developer-reference#raw-transaction-format
|
||||
[regression test mode]: https://bitcoinj.github.io/testing
|
||||
[rpc addmultisigaddress]: /en/developer-reference#addmultisigaddress
|
||||
[rpc addnode]: /en/developer-reference#addnode
|
||||
[rpc backupwallet]: /en/developer-reference#backupwallet
|
||||
[rpc createmultisig]: /en/developer-reference#createmultisig
|
||||
[rpc createrawtransaction]: /en/developer-reference#createrawtransaction
|
||||
[rpc decoderawtransaction]: /en/developer-reference#decoderawtransaction
|
||||
[rpc decodescript]: /en/developer-reference#decodescript
|
||||
[rpc dumpprivkey]: /en/developer-reference#dumpprivkey
|
||||
[rpc dumpwallet]: /en/developer-reference#dumpwallet
|
||||
[rpc getaccount]: /en/developer-reference#getaccount
|
||||
[rpc getaccountaddress]: /en/developer-reference#getaccountaddress
|
||||
[rpc getaddednodeinfo]: /en/developer-reference#getaddednodeinfo
|
||||
[rpc getaddressesbyaccount]: /en/developer-reference#getaddressesbyaccount
|
||||
[rpc getbalance]: /en/developer-reference#getbalance
|
||||
[rpc getbestblockhash]: /en/developer-reference#getbestblockhash
|
||||
[rpc getblock]: /en/developer-reference#getblock
|
||||
[rpc getblockcount]: /en/developer-reference#getblockcount
|
||||
[rpc getblockhash]: /en/developer-reference#getblockhash
|
||||
[rpc getblocktemplate]: /en/developer-reference#getblocktemplate
|
||||
[rpc getconnectioncount]: /en/developer-reference#getconnectioncount
|
||||
[rpc getdifficulty]: /en/developer-reference#getdifficulty
|
||||
[rpc getgenerate]: /en/developer-reference#getgenerate
|
||||
[rpc gethashespersec]: /en/developer-reference#gethashespersec
|
||||
[rpc getinfo]: /en/developer-reference#getinfo
|
||||
[rpc getmininginfo]: /en/developer-reference#getmininginfo
|
||||
[rpc getnettotals]: /en/developer-reference#getnettotals
|
||||
[rpc getnetworkhashps]: /en/developer-reference#getnetworkhashps
|
||||
[rpc getnewaddress]: /en/developer-reference#getnewaddress
|
||||
[rpc getpeerinfo]: /en/developer-reference#getpeerinfo
|
||||
[rpc getrawchangeaddress]: /en/developer-reference#getrawchangeaddress
|
||||
[rpc getrawmempool]: /en/developer-reference#getrawmempool
|
||||
[rpc getrawtransaction]: /en/developer-reference#getrawtransaction
|
||||
[rpc getreceivedbyaccount]: /en/developer-reference#getreceivedbyaccount
|
||||
[rpc getreceivedbyaddress]: /en/developer-reference#getreceivedbyaddress
|
||||
[rpc gettransaction]: /en/developer-reference#gettransaction
|
||||
[rpc gettxout]: /en/developer-reference#gettxout
|
||||
[rpc gettxoutsetinfo]: /en/developer-reference#gettxoutsetinfo
|
||||
[rpc getunconfirmedbalance]: /en/developer-reference#getunconfirmedbalance
|
||||
[rpc getwork]: /en/developer-reference#getwork
|
||||
[rpc help]: /en/developer-reference#help
|
||||
[rpc importprivkey]: /en/developer-reference#importprivkey
|
||||
[rpc importwallet]: /en/developer-reference#importwallet
|
||||
[rpc keypoolrefill]: /en/developer-reference#keypoolrefill
|
||||
[rpc listaccounts]: /en/developer-reference#listaccounts
|
||||
[rpc listaddressgroupings]: /en/developer-reference#listaddressgroupings
|
||||
[rpc listlockunspent]: /en/developer-reference#listlockunspent
|
||||
[rpc listreceivedbyaccount]: /en/developer-reference#listreceivedbyaccount
|
||||
[rpc listreceivedbyaddress]: /en/developer-reference#listreceivedbyaddress
|
||||
[rpc listsinceblock]: /en/developer-reference#listsinceblock
|
||||
[rpc listtransactions]: /en/developer-reference#listtransactions
|
||||
[rpc listunspent]: /en/developer-reference#listunspent
|
||||
[rpc lockunspent]: /en/developer-reference#lockunspent
|
||||
[rpc move]: /en/developer-reference#move
|
||||
[rpc ping]: /en/developer-reference#ping
|
||||
[rpc sendfrom]: /en/developer-reference#sendfrom
|
||||
[rpc sendmany]: /en/developer-reference#sendmany
|
||||
[rpc sendrawtransaction]: /en/developer-reference#sendrawtransaction
|
||||
[rpc sendtoaddress]: /en/developer-reference#sendtoaddress
|
||||
[rpc setaccount]: /en/developer-reference#setaccount
|
||||
[rpc setgenerate]: /en/developer-reference#setgenerate
|
||||
[rpc settxfee]: /en/developer-reference#settxfee
|
||||
[rpc signmessage]: /en/developer-reference#signmessage
|
||||
[rpc signrawtransaction]: /en/developer-reference#signrawtransaction
|
||||
[rpc stop]: /en/developer-reference#stop
|
||||
[rpc submitblock]: /en/developer-reference#submitblock
|
||||
[rpc validateaddress]: /en/developer-reference#validateaddress
|
||||
[rpc verifychain]: /en/developer-reference#verifychain
|
||||
[rpc verifymessage]: /en/developer-reference#verifymessage
|
||||
[rpc walletlock]: /en/developer-reference#walletlock
|
||||
[rpc walletpassphrase]: /en/developer-reference#walletpassphrase
|
||||
[rpc walletpassphrasechange]: /en/developer-reference#walletpassphrasechange
|
||||
[RPC]: /en/developer-reference#remote-procedure-calls-rpcs
|
||||
[RPCs]: /en/developer-reference#remote-procedure-calls-rpcs
|
||||
[secp256k1]: http://www.secg.org/index.php?action=secg,docs_secg
|
||||
[section verifying payment]: /en/developer-guide#verifying-payment
|
||||
[bitcoin URI subsection]: /en/developer-guide#bitcoin-uri
|
||||
[SHA256]: https://en.wikipedia.org/wiki/SHA-2
|
||||
[Stratum mining protocol]: http://mining.bitcoin.cz/stratum-mining
|
||||
[URI encoded]: https://tools.ietf.org/html/rfc3986
|
||||
[Verification subsection]: /en/developer-guide#verifying-payment
|
||||
[wiki script]: https://en.bitcoin.it/wiki/Script
|
||||
[x509]: https://en.wikipedia.org/wiki/X.509
|
||||
|
18
_less/ie.css
|
@ -163,18 +163,18 @@ body{
|
|||
}
|
||||
|
||||
.resources div{
|
||||
border-top:expression((this.parentNode!=this.parentNode.parentNode.getElementsByTagName('DIV')[0])?'1px solid #e0e0e0':'0');
|
||||
border-top:expression(this.parentNode.className=='resources'&&this!=this.parentNode.getElementsByTagName('DIV')[0]?'1px solid #e0e0e0':'0');
|
||||
}
|
||||
.resources div div{
|
||||
zoom:1;
|
||||
display:inline;
|
||||
padding-top:25px;
|
||||
position:relative;
|
||||
padding-right:expression(this.parentNode.getElementsByTagName('DIV')[0]==this?'40px':'');
|
||||
border-right:expression(this.parentNode.getElementsByTagName('DIV')[0]==this?'1px solid #e0e0e0':'');
|
||||
padding-left:expression(this.parentNode.getElementsByTagName('DIV')[1]==this?'40px':'');
|
||||
border-left:expression(this.parentNode.getElementsByTagName('DIV')[1]==this?'1px solid #e0e0e0':'');
|
||||
margin-left:expression(this.parentNode.getElementsByTagName('DIV')[1]==this?'-1px':'');
|
||||
padding-right:expression(this.parentNode.parentNode.className=='resources'&&this.parentNode.getElementsByTagName('DIV')[0]==this?'40px':'');
|
||||
border-right:expression(this.parentNode.parentNode.className=='resources'&&this.parentNode.getElementsByTagName('DIV')[0]==this?'1px solid #e0e0e0':'');
|
||||
padding-left:expression(this.parentNode.parentNode.className=='resources'&&this!=this.parentNode.getElementsByTagName('DIV')[0]?'40px':'');
|
||||
border-left:expression(this.parentNode.parentNode.className=='resources'&&this!=this.parentNode.getElementsByTagName('DIV')[0]?'1px solid #e0e0e0':'');
|
||||
margin-left:expression(this.parentNode.parentNode.className=='resources'&&this!=this.parentNode.getElementsByTagName('DIV')[0]?'-1px':'');
|
||||
}
|
||||
.resources>div>div:first-child+div{
|
||||
/*This one is for IE7 only*/
|
||||
|
@ -190,6 +190,12 @@ body{
|
|||
border-top:expression(this.parentNode.className=='resourcesorg'&&this.parentNode.getElementsByTagName('DIV')[0]!=this?'1px solid #e0e0e0':'0');
|
||||
}
|
||||
|
||||
.docreference a{
|
||||
zoom:1;
|
||||
display:inline;
|
||||
width:200px;
|
||||
}
|
||||
|
||||
.downloadbox{
|
||||
zoom:1;
|
||||
display:inline;
|
||||
|
|
|
@ -637,6 +637,255 @@ table td,table th{
|
|||
line-height:1.5em;
|
||||
}
|
||||
|
||||
.docreference{
|
||||
text-align:center;
|
||||
}
|
||||
.docreference a{
|
||||
display:inline-block;
|
||||
margin:0 15px 40px 15px;
|
||||
font-size:125%;
|
||||
}
|
||||
.docreference img{
|
||||
display:block;
|
||||
height:48px;
|
||||
width:48px;
|
||||
margin:0 auto 10px auto;
|
||||
}
|
||||
.docreference span{
|
||||
display:block;
|
||||
line-height:1.5em;
|
||||
}
|
||||
.docreference span+span{
|
||||
font-size:80%;
|
||||
}
|
||||
.toc{
|
||||
position:absolute;
|
||||
left:20px;
|
||||
text-align:left;
|
||||
padding-top:40px;
|
||||
margin-top:-40px;
|
||||
}
|
||||
.toc div{
|
||||
overflow-y:auto;
|
||||
overflow-x:hidden;
|
||||
width:240px;
|
||||
}
|
||||
.toc div.scroll{
|
||||
position:fixed;
|
||||
}
|
||||
.toc ul,
|
||||
.toc li{
|
||||
list-style:none;
|
||||
padding:0;
|
||||
margin:0;
|
||||
}
|
||||
.toc ul{
|
||||
width:220px;
|
||||
border-right:1px solid #e0e0e0;
|
||||
padding:0 19px 0 0;
|
||||
}
|
||||
.toc ul li{
|
||||
padding:0 0 10px 0;
|
||||
}
|
||||
.toc ul li ul{
|
||||
position:relative;
|
||||
top:0;
|
||||
padding:10px 0 0 0;
|
||||
border:0;
|
||||
display:none;
|
||||
}
|
||||
.toc ul li.active ul{
|
||||
display:block;
|
||||
}
|
||||
.toc ul li ul li{
|
||||
padding:0 0 4px 0;
|
||||
}
|
||||
.toc ul li ul li ul li{
|
||||
padding-left:10px;
|
||||
}
|
||||
.toc ul li a{
|
||||
padding-left:20px;
|
||||
font-weight:bold;
|
||||
}
|
||||
.toc ul li ul li a{
|
||||
font-weight:normal;
|
||||
}
|
||||
.toc ul li ul li a:hover:before,
|
||||
.toc ul li ul li a.active:before{
|
||||
content:">";
|
||||
position:absolute;
|
||||
font-weight:bold;
|
||||
left:0px;
|
||||
}
|
||||
.toc ul.goback{
|
||||
padding-top:8px;
|
||||
}
|
||||
.toc ul.goback li{
|
||||
background:url(/img/mini_ico_back.svg) no-repeat 0 3px;
|
||||
}
|
||||
.toc ul.reportissue li{
|
||||
background:url(/img/mini_ico_report.svg) no-repeat 0 3px;
|
||||
}
|
||||
.toc a,
|
||||
.toc a:link,
|
||||
.toc a:active,
|
||||
.toc a:visited{
|
||||
display:block;
|
||||
text-decoration:none;
|
||||
line-height:1.5em;
|
||||
}
|
||||
.toccontent{
|
||||
width:600px;
|
||||
margin:auto 0 auto auto;
|
||||
position:relative;
|
||||
}
|
||||
.toccontent h2{
|
||||
font-size:150%;
|
||||
color:#383838;
|
||||
}
|
||||
.toccontent h3{
|
||||
font-size:130%;
|
||||
color:#383838;
|
||||
}
|
||||
.toccontent h4{
|
||||
font-size:110%;
|
||||
color:#383838;
|
||||
}
|
||||
.toccontent h5,.toccontent h6{
|
||||
font-size:100%;
|
||||
color:#383838;
|
||||
}
|
||||
.toccontent img{
|
||||
max-width:100%;
|
||||
}
|
||||
.toccontent a.auto-link:link,
|
||||
.toccontent a.auto-link:visited{
|
||||
color:#646464;
|
||||
}
|
||||
.toccontent p:hover a.auto-link:link,
|
||||
.toccontent p:hover a.auto-link:visited{
|
||||
color:#2c6fad;
|
||||
}
|
||||
.toccontent p:hover a.auto-link:link:hover,
|
||||
.toccontent p:hover a.auto-link:visited:hover{
|
||||
color:#63a4e1;
|
||||
}
|
||||
.toccontent a:link.term,
|
||||
.toccontent a:visited.term,
|
||||
.toccontent p:hover a.auto-link.term:link,
|
||||
.toccontent p:hover a.auto-link.term:visited,
|
||||
.toccontent p:hover a.auto-link.term:link:hover,
|
||||
.toccontent p:hover a.auto-link.term:visited:hover{
|
||||
color:#000;
|
||||
}
|
||||
.toccontent a.term:link code,
|
||||
.toccontent a.term:visited code{
|
||||
color:#646464;
|
||||
}
|
||||
|
||||
.develdocdisclaimer{
|
||||
padding:30px 0;
|
||||
background:#fff;
|
||||
bottom:0;
|
||||
position:fixed;
|
||||
width:600px;
|
||||
z-index:1000;
|
||||
border-top:1px solid #e0e0e0;
|
||||
}
|
||||
.develdocdisclaimer div{
|
||||
border:2px dashed #ee9209;
|
||||
background:#fff8ea;
|
||||
padding:10px;
|
||||
line-height:1.5em;
|
||||
position:relative;
|
||||
}
|
||||
.develdocdisclaimerclose,
|
||||
.develdocdisclaimerclose:visited,
|
||||
.develdocdisclaimerclose:link,
|
||||
.develdocdisclaimerclose:active{
|
||||
display:block;
|
||||
padding:1px 8px 0 8px;
|
||||
color:#fff;
|
||||
background-color:#ee9209;
|
||||
position:absolute;
|
||||
top:-14px;
|
||||
right:-14px;
|
||||
font-weight:bold;
|
||||
cursor:pointer;
|
||||
border:2px solid #fff;
|
||||
-webkit-border-radius:20px;
|
||||
-moz-border-radius:20px;
|
||||
border-radius:20px;
|
||||
}
|
||||
.develdocdisclaimerclose:hover,
|
||||
.develdocdisclaimerclose:visited:hover,
|
||||
.develdocdisclaimerclose:link:hover,
|
||||
.develdocdisclaimerclose:active:hover{
|
||||
border:2px solid #ee9209;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
.highlight { background: #ffffff; }
|
||||
.highlight .c { color: #999988; font-style: italic } /* Comment */
|
||||
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
|
||||
.highlight .k { font-weight: bold } /* Keyword */
|
||||
.highlight .o { font-weight: bold } /* Operator */
|
||||
.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
|
||||
.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
|
||||
.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
|
||||
.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
|
||||
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
|
||||
.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
|
||||
.highlight .ge { font-style: italic } /* Generic.Emph */
|
||||
.highlight .gr { color: #aa0000 } /* Generic.Error */
|
||||
.highlight .gh { color: #999999 } /* Generic.Heading */
|
||||
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
|
||||
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
|
||||
.highlight .go { color: #888888 } /* Generic.Output */
|
||||
.highlight .gp { color: #555555 } /* Generic.Prompt */
|
||||
.highlight .gs { font-weight: bold } /* Generic.Strong */
|
||||
.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
|
||||
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
|
||||
.highlight .kc { font-weight: bold } /* Keyword.Constant */
|
||||
.highlight .kd { font-weight: bold } /* Keyword.Declaration */
|
||||
.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
|
||||
.highlight .kr { font-weight: bold } /* Keyword.Reserved */
|
||||
.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
|
||||
.highlight .m { color: #009999 } /* Literal.Number */
|
||||
.highlight .s { color: #d14 } /* Literal.String */
|
||||
.highlight .na { color: #008080 } /* Name.Attribute */
|
||||
.highlight .nb { color: #0086B3 } /* Name.Builtin */
|
||||
.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
|
||||
.highlight .no { color: #008080 } /* Name.Constant */
|
||||
.highlight .ni { color: #800080 } /* Name.Entity */
|
||||
.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
|
||||
.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
|
||||
.highlight .nn { color: #555555 } /* Name.Namespace */
|
||||
.highlight .nt { color: #000080 } /* Name.Tag */
|
||||
.highlight .nv { color: #008080 } /* Name.Variable */
|
||||
.highlight .ow { font-weight: bold } /* Operator.Word */
|
||||
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
|
||||
.highlight .mf { color: #009999 } /* Literal.Number.Float */
|
||||
.highlight .mh { color: #009999 } /* Literal.Number.Hex */
|
||||
.highlight .mi { color: #009999 } /* Literal.Number.Integer */
|
||||
.highlight .mo { color: #009999 } /* Literal.Number.Oct */
|
||||
.highlight .sb { color: #d14 } /* Literal.String.Backtick */
|
||||
.highlight .sc { color: #d14 } /* Literal.String.Char */
|
||||
.highlight .sd { color: #d14 } /* Literal.String.Doc */
|
||||
.highlight .s2 { color: #d14 } /* Literal.String.Double */
|
||||
.highlight .se { color: #d14 } /* Literal.String.Escape */
|
||||
.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
|
||||
.highlight .si { color: #d14 } /* Literal.String.Interpol */
|
||||
.highlight .sx { color: #d14 } /* Literal.String.Other */
|
||||
.highlight .sr { color: #009926 } /* Literal.String.Regex */
|
||||
.highlight .s1 { color: #d14 } /* Literal.String.Single */
|
||||
.highlight .ss { color: #990073 } /* Literal.String.Symbol */
|
||||
.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
|
||||
.highlight .vc { color: #008080 } /* Name.Variable.Class */
|
||||
.highlight .vg { color: #008080 } /* Name.Variable.Global */
|
||||
.highlight .vi { color: #008080 } /* Name.Variable.Instance */
|
||||
.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
|
||||
|
||||
.box{
|
||||
border:2px dashed #4892b2;
|
||||
padding:0 20px 0 20px;
|
||||
|
@ -735,6 +984,14 @@ table td,table th{
|
|||
font-size:115%;
|
||||
margin:6px 0;
|
||||
}
|
||||
.resources .resourcesext{
|
||||
margin-top:5px;
|
||||
min-height:0;
|
||||
}
|
||||
.resources .resourcesext p{
|
||||
padding-left:24px;
|
||||
background:url(/img/mini_ico_link.svg) no-repeat 0 4px;
|
||||
}
|
||||
|
||||
.resourcesorg{
|
||||
margin-bottom:40px;
|
||||
|
@ -1334,6 +1591,15 @@ h2 .rssicon{
|
|||
padding:0;
|
||||
border:0;
|
||||
}
|
||||
.toc{
|
||||
display:none;
|
||||
}
|
||||
.toccontent{
|
||||
width:auto;
|
||||
}
|
||||
.develdocdisclaimer{
|
||||
display:none;
|
||||
}
|
||||
}
|
||||
|
||||
/*Styles specific to mobiles*/
|
||||
|
@ -1443,6 +1709,59 @@ h2 .rssicon{
|
|||
.index li{
|
||||
padding:3px 0;
|
||||
}
|
||||
.docreference{
|
||||
width:220px;
|
||||
margin:0 0 40px 0;
|
||||
}
|
||||
.toc{
|
||||
position:static;
|
||||
margin-top:0px;
|
||||
padding:10px;
|
||||
border:2px dashed #4892b2;
|
||||
display:inline-block;
|
||||
}
|
||||
.toc div{
|
||||
width:auto;
|
||||
}
|
||||
.toc div.scroll{
|
||||
position:static;
|
||||
}
|
||||
.toc ul,
|
||||
.toc.scroll ul{
|
||||
width:auto;
|
||||
padding:0;
|
||||
border:0;
|
||||
}
|
||||
.toc ul li ul{
|
||||
display:block;
|
||||
}
|
||||
.toc ul li ul li ul li{
|
||||
padding-left:0;
|
||||
}
|
||||
.toc ul li a{
|
||||
padding:0;
|
||||
}
|
||||
.toc ul li ul li a:hover:before,
|
||||
.toc ul li ul li a.active:before{
|
||||
content:"";
|
||||
}
|
||||
.toc ul.goback li{
|
||||
background:none;
|
||||
}
|
||||
.toc ul.reportissue li{
|
||||
background:none;
|
||||
}
|
||||
.toccontent{
|
||||
width:auto;
|
||||
}
|
||||
.toccontent a.auto-link:link,
|
||||
.toccontent a.auto-link:visited{
|
||||
color:#2c6fad;
|
||||
}
|
||||
.develdocdisclaimer{
|
||||
padding:15px;
|
||||
width:auto;
|
||||
}
|
||||
.contributors{
|
||||
width:auto;
|
||||
}
|
||||
|
|
81
_plugins/autocrossref.rb
Normal file
|
@ -0,0 +1,81 @@
|
|||
## autocrossref.rb automatically adds cross reference links in documentation
|
||||
## texts using the list of words defined in _autocrossref.yaml.
|
||||
|
||||
## Example:
|
||||
## {% autocrossref %}
|
||||
## ...content...
|
||||
## {% endautocrossref %}
|
||||
|
||||
## If you have a patten you usually want to match (such as "satoshi"
|
||||
## (currency)) but which may appear a few times where you don't want it
|
||||
## to match (such as "Satoshi" (name)), append a <!--noref--> HTML comment.
|
||||
## E.g.: Bitcoin was invented by Satoshi<!--noref--> Nakamoto.
|
||||
|
||||
## An alternative match-prevention method, useful for strings inside ``
|
||||
## (code) is to make it look to the parser like the string is inside of
|
||||
## a do-not-parse [bracket] expression. E.g. [paymentrequest][] would
|
||||
## otherwise match this:
|
||||
## <!--[-->`src/qt/paymentrequest.proto`<!--]-->
|
||||
|
||||
module Jekyll
|
||||
|
||||
require 'yaml'
|
||||
|
||||
class AutoCrossRefBlock < Liquid::Block
|
||||
|
||||
def initialize(tag_name, text, tokens)
|
||||
super
|
||||
end
|
||||
|
||||
def render(context)
|
||||
output = super
|
||||
|
||||
## Workaround for inconsistent relative directory
|
||||
path = File.expand_path(File.dirname(__FILE__)) + "/.."
|
||||
## Load terms from file
|
||||
site = context.registers[:site].config
|
||||
if !site.has_key?("crossref")
|
||||
site['crossref'] = YAML.load_file(path + "/_autocrossref.yaml")
|
||||
end
|
||||
|
||||
## Sort terms by reverse length, so longest matches get linked
|
||||
## first (e.g. "block chain" before "block"). Otherwise short
|
||||
## terms would get linked first and there'd be nothing for long
|
||||
## terms to link to.
|
||||
site['crossref'].sort_by { |k, v| -k.length }.each { |term|
|
||||
|
||||
term[1] = term[0] if term[1].nil? || term[1].empty?
|
||||
|
||||
term[0] = Regexp.escape(term[0])
|
||||
|
||||
## Replace literal space with \s to match across newlines. This
|
||||
## can do weird things if you don't end sentences with a period,
|
||||
## such as linking together "standard" and "transactions" in
|
||||
## something like this:
|
||||
### * RFC1234 is a standard
|
||||
###
|
||||
### Transactions are cool
|
||||
term[0].gsub!('\ ', '\s+')
|
||||
|
||||
output.gsub!(/
|
||||
(?<!\w) ## Don't match inside words
|
||||
#{term[0]}('s)? ## Find our key
|
||||
(?![^\[]*\]) ## No subst if key inside [brackets]
|
||||
(?![^\{]*\}) ## No subst if key inside {braces}
|
||||
(?![^\s]*<!--noref-->) ## No subst if <!--noref--> after key
|
||||
(?![^\(]*(\.svg|\.png)) ## No subst if key inside an image name. This
|
||||
## simple regex has the side effect that we can't
|
||||
## use .svg or .png in non-image base text; if that
|
||||
## becomes an issue, we can devise a more complex
|
||||
## regex
|
||||
(?!\w) ## Don't match inside words
|
||||
/xmi, "[\\&][#{term[1]}]{:.auto-link}")
|
||||
}
|
||||
output.gsub!('<!--noref-->','') ## Remove all <!--noref--> comments
|
||||
|
||||
output
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('autocrossref', Jekyll::AutoCrossRefBlock)
|
|
@ -26,8 +26,6 @@ id: bitcoin-for-developers
|
|||
{% case page.lang %}
|
||||
{% when 'ar' or 'fa' or 'pl' or 'zh_TW' %}
|
||||
{% else %}
|
||||
<div class="introlink">{% translate serviceslist %}</div>
|
||||
<div class="introlink">{% translate apireference %}</div>
|
||||
<div class="mainbutton"><a href="{% translate getting-started url %}"><img src="/img/but_bitcoin.svg" alt="icon">{% translate getstarted layout %}</a></div>
|
||||
<div class="mainbutton"><a href="/en/developer-documentation"><img src="/img/but_bitcoin.svg" alt="icon">{% translate getstarted layout %}</a></div>
|
||||
{% endcase %}
|
||||
|
||||
|
|
|
@ -12,6 +12,12 @@ id: development
|
|||
<h2>{% translate spec %}</h2>
|
||||
<p>{% translate spectxt %}</p>
|
||||
<ul>
|
||||
{% case page.lang %}
|
||||
{% when 'ar' or 'bg' or 'de' or 'es' or 'fa' or 'fr' or 'hu' or 'id' or 'it' or 'nl' or 'pl' or 'ru' or 'tr' or 'zh_CN' or 'zh_TW' %}
|
||||
<li>{% translate speclinkguide development en %}</li>
|
||||
{% else %}
|
||||
<li>{% translate speclinkguide %}</li>
|
||||
{% endcase %}
|
||||
<li>{% translate speclink1 %}</li>
|
||||
<li>{% translate speclink2 %}</li>
|
||||
<li>{% translate speclink3 %}</li>
|
||||
|
|
|
@ -51,8 +51,6 @@ en:
|
|||
securitytext: "Most parts of the security are handled by the protocol. This means no need for PCI compliance and fraud detection is only required when services or products are delivered instantly. Storing your bitcoins in a <a href=\"#secure-your-wallet#\">secure environment</a> and securing payment requests displayed to the user should be your main concerns."
|
||||
micro: "Cheap micro payments"
|
||||
microtext: "Bitcoin offers the lowest payment processing fees and usually can be used to send micro payments as low as a few dollars in value. Bitcoin allows to design new creative online services that could not exist before only because of financial limitations. This includes various kinds of tipping systems and automated payment solutions."
|
||||
serviceslist: "Visit the <a href=\"https://en.bitcoin.it/wiki/How_to_accept_Bitcoin,_for_small_businesses#Merchant_Services\">merchant services list</a> on the wiki."
|
||||
apireference: "Or read bitcoind's <a href=\"https://en.bitcoin.it/wiki/API_reference_(JSON-RPC)\">API reference</a> and <a href=\"https://en.bitcoin.it/wiki/Original_Bitcoin_client/API_Calls_list\">API calls list</a>."
|
||||
bitcoin-for-individuals:
|
||||
title: "Bitcoin for Individuals - Bitcoin"
|
||||
pagetitle: "Bitcoin for Individuals"
|
||||
|
@ -135,6 +133,7 @@ en:
|
|||
summary: "Find more information about current specification, software and developers."
|
||||
spec: "Specification"
|
||||
spectxt: "If you are interested in learning more about the technical details of Bitcoin, it is recommended you start with these documents."
|
||||
speclinkguide: "<a href=\"/en/developer-documentation\">Developer documentation</a>"
|
||||
speclink1: "<a href=\"/bitcoin.pdf\">Bitcoin: A Peer-to-Peer Electronic Cash System</a>"
|
||||
speclink2: "<a href=\"https://en.bitcoin.it/wiki/Protocol_rules\">Protocol rules</a>"
|
||||
speclink3: "<a href=\"https://en.bitcoin.it/wiki/Category:Technical\">Bitcoin Wiki</a>"
|
||||
|
@ -348,7 +347,7 @@ en:
|
|||
processing: "Processing<a class=\"titlelight\"> - mining</a>"
|
||||
processingtxt: "Mining is a <b>distributed consensus system</b> that is used to <a href=\"#vocabulary##[vocabulary.confirmation]\"><i>confirm</i></a> waiting transactions by including them in the block chain. It enforces a chronological order in the block chain, protects the neutrality of the network, and allows different computers to agree on the state of the system. To be confirmed, transactions must be packed in a <a href=\"#vocabulary##[vocabulary.block]\"><i>block</i></a> that fits very strict cryptographic rules that will be verified by the network. These rules prevent previous blocks from being modified because doing so would invalidate all following blocks. Mining also creates the equivalent of a competitive lottery that prevents any individual from easily adding new blocks consecutively in the block chain. This way, no individuals can control what is included in the block chain or replace parts of the block chain to roll back their own spends."
|
||||
readmore: "Going down the rabbit hole"
|
||||
readmoretxt: "This is only a very short and concise summary of the system. If you want to get into the details, you can <a href=\"/bitcoin.pdf\">read the original paper</a> that describes the system's design, and explore the <a href=\"https://en.bitcoin.it/wiki/Main_Page\">Bitcoin wiki</a>."
|
||||
readmoretxt: "This is only a very short and concise summary of the system. If you want to get into the details, you can <a href=\"/bitcoin.pdf\">read the original paper</a> that describes the system's design, read the <a href=\"/en/developer-documentation\">developer documentation</a>, and explore the <a href=\"https://en.bitcoin.it/wiki/Main_Page\">Bitcoin wiki</a>."
|
||||
index:
|
||||
title: "Bitcoin - Open source P2P money"
|
||||
listintro: "Bitcoin is an innovative payment network and a new kind of money."
|
||||
|
|
74
en/developer-documentation.md
Normal file
|
@ -0,0 +1,74 @@
|
|||
---
|
||||
layout: base
|
||||
lang: en
|
||||
id: developer-documentation
|
||||
title: "Developer Documentation - Bitcoin"
|
||||
---
|
||||
|
||||
# Developer Documentation
|
||||
|
||||
<p class="summary">Find useful resources, guides and reference material for developers.</p>
|
||||
|
||||
<div class="docreference">
|
||||
<a href="/en/developer-guide"><img src="/img/main_ico_guide.svg" alt="icon"><span>Developer Guide</span><span>(How Bitcoin works)</span></a>
|
||||
<a href="/en/developer-reference"><img src="/img/main_ico_guide.svg" alt="icon"><span>Developer Reference</span><span>(Specifications and APIs)</span></a>
|
||||
</div>
|
||||
|
||||
<div class="resources">
|
||||
<div><div>
|
||||
<h2><img src="/img/ico_blockchain.svg" class="titleicon" alt="Icon">Block Chain</h2>
|
||||
<p><a href="/en/developer-guide#block-chain">Block Chain Guide</a></p>
|
||||
<p><a href="/en/developer-reference#block-chain">Block Chain Reference</a></p>
|
||||
</div><div>
|
||||
<h2><img src="/img/ico_micro.svg" class="titleicon" alt="Icon">Transactions</h2>
|
||||
<p><a href="/en/developer-guide#transactions">Transactions Guide</a></p>
|
||||
<p><a href="/en/developer-reference#transactions">Transactions Reference</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<h2><img src="/img/ico_contract.svg" class="titleicon" alt="Icon">Contracts</h2>
|
||||
<p><a href="/en/developer-guide#contracts">Contracts Guide</a></p>
|
||||
<div class="resourcesext">
|
||||
<p><a href="https://en.bitcoin.it/wiki/Contracts">More Contracts</a> - Wiki</p>
|
||||
<p><a href="https://bitcoinj.github.io/working-with-micropayments">Micropayment Channel Example</a> - bitcoinj</p>
|
||||
</div>
|
||||
</div><div>
|
||||
<h2><img src="/img/ico_key.svg" class="titleicon" alt="Icon">Wallets</h2>
|
||||
<p><a href="/en/developer-guide#wallets">Wallets Guide</a></p>
|
||||
<p><a href="/en/developer-reference#wallets">Wallets Reference</a></p>
|
||||
<div class="resourcesext">
|
||||
<p><a href="https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki">HD Wallets</a> - BIP32</p>
|
||||
<p><a href="https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki">Mnemonic Code</a> - BIP39</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<h2><img src="/img/ico_bill.svg" class="titleicon" alt="Icon">Payment Processing</h2>
|
||||
<p><a href="/en/developer-guide#payment-processing">Payment Processing Guide</a></p>
|
||||
<div class="resourcesext">
|
||||
<p><a href="https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki">Payment Protocol</a> - BIP70</p>
|
||||
</div>
|
||||
</div><div>
|
||||
<h2><img src="/img/ico_conf.svg" class="titleicon" alt="Icon">Operating Modes</h2>
|
||||
<p><a href="/en/developer-guide#operating-modes">Operating Modes Guide</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<h2><img src="/img/ico_network.svg" class="titleicon" alt="Icon">P2P Network</h2>
|
||||
<p><a href="/en/developer-guide#p2p-network">P2P Network Guide</a></p>
|
||||
<div class="resourcesext">
|
||||
<p><a href="https://en.bitcoin.it/wiki/Protocol_specification">Full Protocol Specification</a> - Wiki</p>
|
||||
</div>
|
||||
</div><div>
|
||||
<h2><img src="/img/ico_mining.svg" class="titleicon" alt="Icon">Mining</h2>
|
||||
<p><a href="/en/developer-guide#mining">Mining Guide</a></p>
|
||||
<div class="resourcesext">
|
||||
<p><a href="https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki">getworktemplate Fundamentals</a> - BIP22</p>
|
||||
<p><a href="https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki">getworktemplate Pooled Mining</a> - BIP23</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
58
en/developer-guide.md
Normal file
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
layout: base
|
||||
lang: en
|
||||
id: developer-guide
|
||||
title: "Developer Guide - Bitcoin"
|
||||
---
|
||||
|
||||
# Bitcoin Developer Guide
|
||||
|
||||
<p class="summary">Find detailed information about the Bitcoin protocol and related specifications.</p>
|
||||
|
||||
<div markdown="1" id="toc" class="toc"><div markdown="1">
|
||||
|
||||
* Table of contents
|
||||
{:toc}
|
||||
|
||||
<ul class="goback"><li><a href="/en/developer-documentation">Return To Overview</a></li></ul>
|
||||
<ul class="reportissue"><li><a href="https://github.com/bitcoin/bitcoin.org/issues/new" onmouseover="updateIssue(event);">Report An Issue</a></li></ul>
|
||||
|
||||
</div></div>
|
||||
|
||||
<div markdown="1" class="toccontent">
|
||||
|
||||
<!--Temporary disclaimer BEGIN-->
|
||||
<div id="develdocdisclaimer" class="develdocdisclaimer"><div>
|
||||
<b>BETA</b>: This documentation has been written recently and still needs more reviews to ensure all content is covered correctly and accurately; if you find a mistake, please <a href="https://github.com/bitcoin/bitcoin.org/issues/new" onmouseover="updateIssue(event);">report an issue</a> on GitHub. <a href="#" onclick="disclaimerClose(event);">Click here</a> to close this disclaimer.
|
||||
<a class="develdocdisclaimerclose" href="#" onclick="disclaimerClose(event);">X</a>
|
||||
</div></div>
|
||||
<script>disclaimerAutoClose();</script>
|
||||
<!--Temporary disclaimer END-->
|
||||
|
||||
<!-- includes should be separated by an empty line to prevent a
|
||||
paragraph at the end of one file from breaking the heading at the start
|
||||
of the following file. -->
|
||||
|
||||
{% include guide_intro.md %}
|
||||
|
||||
{% include guide_block_chain.md %}
|
||||
|
||||
{% include guide_transactions.md %}
|
||||
|
||||
{% include guide_contracts.md %}
|
||||
|
||||
{% include guide_wallets.md %}
|
||||
|
||||
{% include guide_payment_processing.md %}
|
||||
|
||||
{% include guide_operating_modes.md %}
|
||||
|
||||
{% include guide_p2p_network.md %}
|
||||
|
||||
{% include guide_mining.md %}
|
||||
|
||||
{% include references.md %}
|
||||
|
||||
</div>
|
||||
|
||||
<script>updateToc();</script>
|
61
en/developer-reference.md
Normal file
|
@ -0,0 +1,61 @@
|
|||
---
|
||||
layout: base
|
||||
lang: en
|
||||
id: developer-reference
|
||||
title: "Developer Reference - Bitcoin"
|
||||
---
|
||||
|
||||
# Bitcoin Developer Reference
|
||||
|
||||
<p class="summary">Find technical specifications and API documentation.</p>
|
||||
|
||||
<div markdown="1" id="toc" class="toc"><div markdown="1">
|
||||
|
||||
* Table of contents
|
||||
{:toc}
|
||||
|
||||
<ul class="goback"><li><a href="/en/developer-documentation">Return To Overview</a></li></ul>
|
||||
<ul class="reportissue"><li><a href="https://github.com/bitcoin/bitcoin.org/issues/new" onmouseover="updateIssue(event);">Report An Issue</a></li></ul>
|
||||
|
||||
</div></div>
|
||||
<div markdown="1" class="toccontent">
|
||||
|
||||
<!--Temporary disclaimer BEGIN-->
|
||||
<div id="develdocdisclaimer" class="develdocdisclaimer"><div>
|
||||
<b>BETA</b>: This documentation has been written recently and still needs more reviews to ensure all content is covered correctly and accurately; if you find a mistake, please <a href="https://github.com/bitcoin/bitcoin.org/issues/new" onmouseover="updateIssue(event);">report an issue</a> on GitHub. <a href="#" onclick="disclaimerClose(event);">Click here</a> to close this disclaimer.
|
||||
<a class="develdocdisclaimerclose" href="#" onclick="disclaimerClose(event);">X</a>
|
||||
</div></div>
|
||||
<script>disclaimerAutoClose();</script>
|
||||
<!--Temporary disclaimer END-->
|
||||
|
||||
{% include ref_block_chain.md %}
|
||||
{% include ref_transactions.md %}
|
||||
{% include ref_wallets.md %}
|
||||
|
||||
## Bitcoin Core APIs
|
||||
|
||||
<!-- TODO, Relevant links:
|
||||
-- * https://en.bitcoin.it/wiki/Original_Bitcoin_client/API_Calls_list
|
||||
-- * https://en.bitcoin.it/wiki/API_reference_(JSON-RPC)
|
||||
-->
|
||||
|
||||
### Remote Procedure Calls (RPCs)
|
||||
|
||||
**Warning:** the block chain and memory pool can include arbitrary data
|
||||
which several of the commands below will return in hex format. If you
|
||||
convert this data to another format in an executable context, it could
|
||||
be used in an exploit. For example, displaying an output script as
|
||||
ASCII text in a webpage could add arbitrary Javascript to that page and
|
||||
create a cross-site scripting (XSS) exploit. To avoid problems, please
|
||||
treat block chain and memory pool data as an arbitrary input from an
|
||||
untrusted source.
|
||||
|
||||
{% include ref_core_rpcs-abcdefg.md %}
|
||||
{% include ref_core_rpcs-hijklmn.md %}
|
||||
{% include ref_core_rpcs-opqrst.md %}
|
||||
{% include ref_core_rpcs-uvwxyz.md %}
|
||||
{% include references.md %}
|
||||
|
||||
</div>
|
||||
|
||||
<script>updateToc();</script>
|
36
img/dev/README
Normal file
|
@ -0,0 +1,36 @@
|
|||
The images are generated using dot from the graphviz package. For
|
||||
assistance with these files, feel free to contact dave@dtrt.org.
|
||||
|
||||
The following examples generate a .png or .svg file from a .dot file:
|
||||
|
||||
dot -T svg file.dot -o file.svg
|
||||
dot -T png file.dot -o file.png
|
||||
|
||||
You can change a .circo or .neato file into a .png or .svg using
|
||||
corresponding commands:
|
||||
|
||||
circo -T svg file.circo -o file.svg
|
||||
neato -T png file.neato -o file.png
|
||||
|
||||
Notice: Graphviz can be inconsistent across versions. All of the SVG and
|
||||
PNG images here were generated using graphviz version 2.26.3
|
||||
(20100126.1600) on Debian 7 using the following shell loop:
|
||||
|
||||
fn="fontname=Sans"
|
||||
for f in *dot
|
||||
do
|
||||
dot -N$fn -G$fn -E$fn -o ${f/.dot}.svg -T svg $f
|
||||
dot -N$fn -G$fn -E$fn -o ${f/.dot}.png -T png $f
|
||||
optipng -o7 ${f/.dot}.png
|
||||
done
|
||||
|
||||
For improved compatability between Graphviz versions, files created or
|
||||
updated after 6 May 2014 are recommend to include the following code
|
||||
near the top of the file:
|
||||
|
||||
edge [ fontname="Sans" ]
|
||||
node [ fontname="Sans" ]
|
||||
graph [ fontname="Sans" ]
|
||||
|
||||
Also, splines=ortho should not be used in new or updated files until
|
||||
Graphviz fixes its post-2.26.3 ortho code.
|
39
img/dev/en-block-height-vs-depth.dot
Normal file
|
@ -0,0 +1,39 @@
|
|||
digraph {
|
||||
size=6.25;
|
||||
rankdir=BT
|
||||
node [ shape = "box" ]
|
||||
|
||||
subgraph cluster_height {
|
||||
h0 [ label = "Block 0" ]
|
||||
h1 [ label = "Block 1" ]
|
||||
h100 [ label = "Block 100" ]
|
||||
h101 [ label = "Block 101" ]
|
||||
h102 [ label = "Block 102" ]
|
||||
|
||||
h0 -> h1
|
||||
h1 -> h100 [ style = dotted ];
|
||||
h100 -> h101 -> h102
|
||||
|
||||
label = "Block Height"
|
||||
labelloc = b;
|
||||
}
|
||||
|
||||
subgraph cluster_depth {
|
||||
edge [ dir = "back" ];
|
||||
|
||||
d0 [ label = "Depth 101" ]
|
||||
d1 [ label = "Depth 100" ]
|
||||
d100 [ label = "Depth 3" ]
|
||||
d101 [ label = "Depth 2" ]
|
||||
d102 [ label = "Depth 1" ]
|
||||
|
||||
d0 -> d1
|
||||
d1 -> d100 [ style = dotted];
|
||||
d100 -> d101 -> d102
|
||||
|
||||
label = "Block Depth"
|
||||
labelloc = b;
|
||||
}
|
||||
|
||||
label = "Block Height Compared\nTo Block Depth"
|
||||
}
|
BIN
img/dev/en-block-height-vs-depth.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
113
img/dev/en-block-height-vs-depth.svg
Normal file
|
@ -0,0 +1,113 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: _anonymous_0 Pages: 1 -->
|
||||
<svg width="242pt" height="431pt"
|
||||
viewBox="0.00 0.00 242.00 431.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 427)">
|
||||
<title>_anonymous_0</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-427 239,-427 239,5 -4,5"/>
|
||||
<text text-anchor="middle" x="117" y="-25.4" font-family="Sans" font-size="14.00">Block Height Compared</text>
|
||||
<text text-anchor="middle" x="117" y="-8.4" font-family="Sans" font-size="14.00">To Block Depth</text>
|
||||
<g id="graph2" class="cluster"><title>cluster_height</title>
|
||||
<polygon fill="none" stroke="black" points="8,-50 8,-415 112,-415 112,-50 8,-50"/>
|
||||
<text text-anchor="middle" x="60" y="-398.4" font-family="Sans" font-size="14.00">Block Height</text>
|
||||
</g>
|
||||
<g id="graph3" class="cluster"><title>cluster_depth</title>
|
||||
<polygon fill="none" stroke="black" points="120,-50 120,-415 226,-415 226,-50 120,-50"/>
|
||||
<text text-anchor="middle" x="173" y="-398.4" font-family="Sans" font-size="14.00">Block Depth</text>
|
||||
</g>
|
||||
<!-- h0 -->
|
||||
<g id="node2" class="node"><title>h0</title>
|
||||
<polygon fill="none" stroke="black" points="93,-94 27,-94 27,-58 93,-58 93,-94"/>
|
||||
<text text-anchor="middle" x="60" y="-71.9" font-family="Sans" font-size="14.00">Block 0</text>
|
||||
</g>
|
||||
<!-- h1 -->
|
||||
<g id="node3" class="node"><title>h1</title>
|
||||
<polygon fill="none" stroke="black" points="93,-166 27,-166 27,-130 93,-130 93,-166"/>
|
||||
<text text-anchor="middle" x="60" y="-143.9" font-family="Sans" font-size="14.00">Block 1</text>
|
||||
</g>
|
||||
<!-- h0->h1 -->
|
||||
<g id="edge3" class="edge"><title>h0->h1</title>
|
||||
<path fill="none" stroke="black" d="M60,-94.1686C60,-101.869 60,-111.026 60,-119.583"/>
|
||||
<polygon fill="black" stroke="black" points="56.5001,-119.587 60,-129.587 63.5001,-119.587 56.5001,-119.587"/>
|
||||
</g>
|
||||
<!-- h100 -->
|
||||
<g id="node4" class="node"><title>h100</title>
|
||||
<polygon fill="none" stroke="black" points="102,-238 18,-238 18,-202 102,-202 102,-238"/>
|
||||
<text text-anchor="middle" x="60" y="-215.9" font-family="Sans" font-size="14.00">Block 100</text>
|
||||
</g>
|
||||
<!-- h1->h100 -->
|
||||
<g id="edge5" class="edge"><title>h1->h100</title>
|
||||
<path fill="none" stroke="black" stroke-dasharray="1,5" d="M60,-166.169C60,-173.869 60,-183.026 60,-191.583"/>
|
||||
<polygon fill="black" stroke="black" points="56.5001,-191.587 60,-201.587 63.5001,-191.587 56.5001,-191.587"/>
|
||||
</g>
|
||||
<!-- h101 -->
|
||||
<g id="node5" class="node"><title>h101</title>
|
||||
<polygon fill="none" stroke="black" points="102,-310 18,-310 18,-274 102,-274 102,-310"/>
|
||||
<text text-anchor="middle" x="60" y="-287.9" font-family="Sans" font-size="14.00">Block 101</text>
|
||||
</g>
|
||||
<!-- h100->h101 -->
|
||||
<g id="edge7" class="edge"><title>h100->h101</title>
|
||||
<path fill="none" stroke="black" d="M60,-238.169C60,-245.869 60,-255.026 60,-263.583"/>
|
||||
<polygon fill="black" stroke="black" points="56.5001,-263.587 60,-273.587 63.5001,-263.587 56.5001,-263.587"/>
|
||||
</g>
|
||||
<!-- h102 -->
|
||||
<g id="node6" class="node"><title>h102</title>
|
||||
<polygon fill="none" stroke="black" points="102,-382 18,-382 18,-346 102,-346 102,-382"/>
|
||||
<text text-anchor="middle" x="60" y="-359.9" font-family="Sans" font-size="14.00">Block 102</text>
|
||||
</g>
|
||||
<!-- h101->h102 -->
|
||||
<g id="edge8" class="edge"><title>h101->h102</title>
|
||||
<path fill="none" stroke="black" d="M60,-310.169C60,-317.869 60,-327.026 60,-335.583"/>
|
||||
<polygon fill="black" stroke="black" points="56.5001,-335.587 60,-345.587 63.5001,-335.587 56.5001,-335.587"/>
|
||||
</g>
|
||||
<!-- d0 -->
|
||||
<g id="node11" class="node"><title>d0</title>
|
||||
<polygon fill="none" stroke="black" points="218,-94 128,-94 128,-58 218,-58 218,-94"/>
|
||||
<text text-anchor="middle" x="173" y="-71.9" font-family="Sans" font-size="14.00">Depth 101</text>
|
||||
</g>
|
||||
<!-- d1 -->
|
||||
<g id="node12" class="node"><title>d1</title>
|
||||
<polygon fill="none" stroke="black" points="218,-166 128,-166 128,-130 218,-130 218,-166"/>
|
||||
<text text-anchor="middle" x="173" y="-143.9" font-family="Sans" font-size="14.00">Depth 100</text>
|
||||
</g>
|
||||
<!-- d0->d1 -->
|
||||
<g id="edge11" class="edge"><title>d0->d1</title>
|
||||
<path fill="none" stroke="black" d="M173,-104.427C173,-112.892 173,-121.941 173,-129.587"/>
|
||||
<polygon fill="black" stroke="black" points="176.5,-104.169 173,-94.1686 169.5,-104.169 176.5,-104.169"/>
|
||||
</g>
|
||||
<!-- d100 -->
|
||||
<g id="node13" class="node"><title>d100</title>
|
||||
<polygon fill="none" stroke="black" points="209,-238 137,-238 137,-202 209,-202 209,-238"/>
|
||||
<text text-anchor="middle" x="173" y="-215.9" font-family="Sans" font-size="14.00">Depth 3</text>
|
||||
</g>
|
||||
<!-- d1->d100 -->
|
||||
<g id="edge13" class="edge"><title>d1->d100</title>
|
||||
<path fill="none" stroke="black" stroke-dasharray="1,5" d="M173,-176.427C173,-184.892 173,-193.941 173,-201.587"/>
|
||||
<polygon fill="black" stroke="black" points="176.5,-176.169 173,-166.169 169.5,-176.169 176.5,-176.169"/>
|
||||
</g>
|
||||
<!-- d101 -->
|
||||
<g id="node14" class="node"><title>d101</title>
|
||||
<polygon fill="none" stroke="black" points="209,-310 137,-310 137,-274 209,-274 209,-310"/>
|
||||
<text text-anchor="middle" x="173" y="-287.9" font-family="Sans" font-size="14.00">Depth 2</text>
|
||||
</g>
|
||||
<!-- d100->d101 -->
|
||||
<g id="edge15" class="edge"><title>d100->d101</title>
|
||||
<path fill="none" stroke="black" d="M173,-248.427C173,-256.892 173,-265.941 173,-273.587"/>
|
||||
<polygon fill="black" stroke="black" points="176.5,-248.169 173,-238.169 169.5,-248.169 176.5,-248.169"/>
|
||||
</g>
|
||||
<!-- d102 -->
|
||||
<g id="node15" class="node"><title>d102</title>
|
||||
<polygon fill="none" stroke="black" points="209,-382 137,-382 137,-346 209,-346 209,-382"/>
|
||||
<text text-anchor="middle" x="173" y="-359.9" font-family="Sans" font-size="14.00">Depth 1</text>
|
||||
</g>
|
||||
<!-- d101->d102 -->
|
||||
<g id="edge16" class="edge"><title>d101->d102</title>
|
||||
<path fill="none" stroke="black" d="M173,-320.427C173,-328.892 173,-337.941 173,-345.587"/>
|
||||
<polygon fill="black" stroke="black" points="176.5,-320.169 173,-310.169 169.5,-320.169 176.5,-320.169"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.1 KiB |
55
img/dev/en-blockchain-fork.dot
Normal file
|
@ -0,0 +1,55 @@
|
|||
digraph blockchain {
|
||||
|
||||
size=6.66;
|
||||
|
||||
//splines = "ortho";
|
||||
rankdir=LR;
|
||||
ranksep=0.1;
|
||||
|
||||
subgraph cluster_extended {
|
||||
block00 [ label = block0 ];
|
||||
block01 [ label = block1 ];
|
||||
block02 [ label = block2 ];
|
||||
block03 [ label = block3 ];
|
||||
block04 [ label = block4 ];
|
||||
block05 [ label = block5 ];
|
||||
block06 [ label = block6 ];
|
||||
|
||||
block02x [ label = block2 ];
|
||||
block03x [ label = block3 ];
|
||||
block04x [ label = block4 ];
|
||||
block05x [ label = block5 ];
|
||||
|
||||
block01 -> block02x;
|
||||
block02x -> block03x;
|
||||
block03x -> block04x;
|
||||
block04x -> block05x;
|
||||
|
||||
|
||||
block00 -> block01 [label = "Header Hash"];
|
||||
block01 -> block02;
|
||||
block02 -> block03;
|
||||
block03 -> block04;
|
||||
block04 -> block05
|
||||
block05 -> block06;
|
||||
|
||||
label = "Rare Extended Forking";
|
||||
}
|
||||
|
||||
subgraph cluster_normal {
|
||||
block2x [ label = block2 ];
|
||||
block5x [ label = block5 ];
|
||||
|
||||
block1 -> block2x;
|
||||
block4 -> block5x;
|
||||
|
||||
block0 -> block1 [label = "Header Hash"];
|
||||
block1 -> block2 [weight = 100];
|
||||
block2 -> block3;
|
||||
block3 -> block4;
|
||||
block4 -> block5 [weight = 100];
|
||||
block5 -> block6;
|
||||
|
||||
label = "Normal Occasional Forking";
|
||||
}
|
||||
}
|
BIN
img/dev/en-blockchain-fork.png
Normal file
After Width: | Height: | Size: 12 KiB |
213
img/dev/en-blockchain-fork.svg
Normal file
|
@ -0,0 +1,213 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: blockchain Pages: 1 -->
|
||||
<svg width="480pt" height="168pt"
|
||||
viewBox="0.00 0.00 480.00 168.40" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.572792 0.572792) rotate(0) translate(4 290)">
|
||||
<title>blockchain</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-290 835,-290 835,5 -4,5"/>
|
||||
<g id="graph2" class="cluster"><title>cluster_extended</title>
|
||||
<polygon fill="none" stroke="black" points="8,-8 8,-139 822,-139 822,-8 8,-8"/>
|
||||
<text text-anchor="middle" x="415" y="-122.4" font-family="Sans" font-size="14.00">Rare Extended Forking</text>
|
||||
</g>
|
||||
<g id="graph3" class="cluster"><title>cluster_normal</title>
|
||||
<polygon fill="none" stroke="black" points="8,-147 8,-278 822,-278 822,-147 8,-147"/>
|
||||
<text text-anchor="middle" x="415" y="-261.4" font-family="Sans" font-size="14.00">Normal Occasional Forking</text>
|
||||
</g>
|
||||
<!-- block00 -->
|
||||
<g id="node2" class="node"><title>block00</title>
|
||||
<ellipse fill="none" stroke="black" cx="59" cy="-61" rx="41.8891" ry="18"/>
|
||||
<text text-anchor="middle" x="59" y="-56.9" font-family="Sans" font-size="14.00">block0</text>
|
||||
</g>
|
||||
<!-- block01 -->
|
||||
<g id="node3" class="node"><title>block01</title>
|
||||
<ellipse fill="none" stroke="black" cx="251" cy="-61" rx="41.8891" ry="18"/>
|
||||
<text text-anchor="middle" x="251" y="-56.9" font-family="Sans" font-size="14.00">block1</text>
|
||||
</g>
|
||||
<!-- block00->block01 -->
|
||||
<g id="edge11" class="edge"><title>block00->block01</title>
|
||||
<path fill="none" stroke="black" d="M101.611,-61C130.098,-61 167.781,-61 198.173,-61"/>
|
||||
<polygon fill="black" stroke="black" points="198.177,-64.5001 208.177,-61 198.177,-57.5001 198.177,-64.5001"/>
|
||||
<text text-anchor="middle" x="155" y="-65.4" font-family="Sans" font-size="14.00">Header Hash</text>
|
||||
</g>
|
||||
<!-- block02 -->
|
||||
<g id="node4" class="node"><title>block02</title>
|
||||
<ellipse fill="none" stroke="black" cx="355" cy="-34" rx="41.8891" ry="18"/>
|
||||
<text text-anchor="middle" x="355" y="-29.9" font-family="Sans" font-size="14.00">block2</text>
|
||||
</g>
|
||||
<!-- block01->block02 -->
|
||||
<g id="edge13" class="edge"><title>block01->block02</title>
|
||||
<path fill="none" stroke="black" d="M287.374,-51.5567C294.143,-49.7993 301.302,-47.9409 308.329,-46.1165"/>
|
||||
<polygon fill="black" stroke="black" points="309.671,-49.3842 318.471,-43.4836 307.912,-42.6088 309.671,-49.3842"/>
|
||||
</g>
|
||||
<!-- block02x -->
|
||||
<g id="node9" class="node"><title>block02x</title>
|
||||
<ellipse fill="none" stroke="black" cx="355" cy="-88" rx="41.8891" ry="18"/>
|
||||
<text text-anchor="middle" x="355" y="-83.9" font-family="Sans" font-size="14.00">block2</text>
|
||||
</g>
|
||||
<!-- block01->block02x -->
|
||||
<g id="edge3" class="edge"><title>block01->block02x</title>
|
||||
<path fill="none" stroke="black" d="M287.374,-70.4433C294.143,-72.2007 301.302,-74.0591 308.329,-75.8835"/>
|
||||
<polygon fill="black" stroke="black" points="307.912,-79.3912 318.471,-78.5164 309.671,-72.6158 307.912,-79.3912"/>
|
||||
</g>
|
||||
<!-- block03 -->
|
||||
<g id="node5" class="node"><title>block03</title>
|
||||
<ellipse fill="none" stroke="black" cx="459" cy="-34" rx="41.8891" ry="18"/>
|
||||
<text text-anchor="middle" x="459" y="-29.9" font-family="Sans" font-size="14.00">block3</text>
|
||||
</g>
|
||||
<!-- block02->block03 -->
|
||||
<g id="edge15" class="edge"><title>block02->block03</title>
|
||||
<path fill="none" stroke="black" d="M397.601,-34C400.397,-34 403.23,-34 406.068,-34"/>
|
||||
<polygon fill="black" stroke="black" points="406.297,-37.5001 416.297,-34 406.297,-30.5001 406.297,-37.5001"/>
|
||||
</g>
|
||||
<!-- block04 -->
|
||||
<g id="node6" class="node"><title>block04</title>
|
||||
<ellipse fill="none" stroke="black" cx="563" cy="-34" rx="41.8891" ry="18"/>
|
||||
<text text-anchor="middle" x="563" y="-29.9" font-family="Sans" font-size="14.00">block4</text>
|
||||
</g>
|
||||
<!-- block03->block04 -->
|
||||
<g id="edge17" class="edge"><title>block03->block04</title>
|
||||
<path fill="none" stroke="black" d="M501.601,-34C504.397,-34 507.23,-34 510.068,-34"/>
|
||||
<polygon fill="black" stroke="black" points="510.297,-37.5001 520.297,-34 510.297,-30.5001 510.297,-37.5001"/>
|
||||
</g>
|
||||
<!-- block05 -->
|
||||
<g id="node7" class="node"><title>block05</title>
|
||||
<ellipse fill="none" stroke="black" cx="667" cy="-34" rx="41.8891" ry="18"/>
|
||||
<text text-anchor="middle" x="667" y="-29.9" font-family="Sans" font-size="14.00">block5</text>
|
||||
</g>
|
||||
<!-- block04->block05 -->
|
||||
<g id="edge19" class="edge"><title>block04->block05</title>
|
||||
<path fill="none" stroke="black" d="M605.601,-34C608.397,-34 611.23,-34 614.068,-34"/>
|
||||
<polygon fill="black" stroke="black" points="614.297,-37.5001 624.297,-34 614.297,-30.5001 614.297,-37.5001"/>
|
||||
</g>
|
||||
<!-- block06 -->
|
||||
<g id="node8" class="node"><title>block06</title>
|
||||
<ellipse fill="none" stroke="black" cx="771" cy="-34" rx="41.8891" ry="18"/>
|
||||
<text text-anchor="middle" x="771" y="-29.9" font-family="Sans" font-size="14.00">block6</text>
|
||||
</g>
|
||||
<!-- block05->block06 -->
|
||||
<g id="edge21" class="edge"><title>block05->block06</title>
|
||||
<path fill="none" stroke="black" d="M709.601,-34C712.397,-34 715.23,-34 718.068,-34"/>
|
||||
<polygon fill="black" stroke="black" points="718.297,-37.5001 728.297,-34 718.297,-30.5001 718.297,-37.5001"/>
|
||||
</g>
|
||||
<!-- block03x -->
|
||||
<g id="node10" class="node"><title>block03x</title>
|
||||
<ellipse fill="none" stroke="black" cx="459" cy="-88" rx="41.8891" ry="18"/>
|
||||
<text text-anchor="middle" x="459" y="-83.9" font-family="Sans" font-size="14.00">block3</text>
|
||||
</g>
|
||||
<!-- block02x->block03x -->
|
||||
<g id="edge5" class="edge"><title>block02x->block03x</title>
|
||||
<path fill="none" stroke="black" d="M397.601,-88C400.397,-88 403.23,-88 406.068,-88"/>
|
||||
<polygon fill="black" stroke="black" points="406.297,-91.5001 416.297,-88 406.297,-84.5001 406.297,-91.5001"/>
|
||||
</g>
|
||||
<!-- block04x -->
|
||||
<g id="node11" class="node"><title>block04x</title>
|
||||
<ellipse fill="none" stroke="black" cx="563" cy="-88" rx="41.8891" ry="18"/>
|
||||
<text text-anchor="middle" x="563" y="-83.9" font-family="Sans" font-size="14.00">block4</text>
|
||||
</g>
|
||||
<!-- block03x->block04x -->
|
||||
<g id="edge7" class="edge"><title>block03x->block04x</title>
|
||||
<path fill="none" stroke="black" d="M501.601,-88C504.397,-88 507.23,-88 510.068,-88"/>
|
||||
<polygon fill="black" stroke="black" points="510.297,-91.5001 520.297,-88 510.297,-84.5001 510.297,-91.5001"/>
|
||||
</g>
|
||||
<!-- block05x -->
|
||||
<g id="node12" class="node"><title>block05x</title>
|
||||
<ellipse fill="none" stroke="black" cx="667" cy="-88" rx="41.8891" ry="18"/>
|
||||
<text text-anchor="middle" x="667" y="-83.9" font-family="Sans" font-size="14.00">block5</text>
|
||||
</g>
|
||||
<!-- block04x->block05x -->
|
||||
<g id="edge9" class="edge"><title>block04x->block05x</title>
|
||||
<path fill="none" stroke="black" d="M605.601,-88C608.397,-88 611.23,-88 614.068,-88"/>
|
||||
<polygon fill="black" stroke="black" points="614.297,-91.5001 624.297,-88 614.297,-84.5001 614.297,-91.5001"/>
|
||||
</g>
|
||||
<!-- block2x -->
|
||||
<g id="node24" class="node"><title>block2x</title>
|
||||
<ellipse fill="none" stroke="black" cx="355" cy="-173" rx="41.8891" ry="18"/>
|
||||
<text text-anchor="middle" x="355" y="-168.9" font-family="Sans" font-size="14.00">block2</text>
|
||||
</g>
|
||||
<!-- block5x -->
|
||||
<g id="node25" class="node"><title>block5x</title>
|
||||
<ellipse fill="none" stroke="black" cx="667" cy="-173" rx="41.8891" ry="18"/>
|
||||
<text text-anchor="middle" x="667" y="-168.9" font-family="Sans" font-size="14.00">block5</text>
|
||||
</g>
|
||||
<!-- block1 -->
|
||||
<g id="node26" class="node"><title>block1</title>
|
||||
<ellipse fill="none" stroke="black" cx="251" cy="-227" rx="41.8891" ry="18"/>
|
||||
<text text-anchor="middle" x="251" y="-222.9" font-family="Sans" font-size="14.00">block1</text>
|
||||
</g>
|
||||
<!-- block1->block2x -->
|
||||
<g id="edge24" class="edge"><title>block1->block2x</title>
|
||||
<path fill="none" stroke="black" d="M278.053,-212.953C290.572,-206.453 305.618,-198.641 319.073,-191.655"/>
|
||||
<polygon fill="black" stroke="black" points="320.82,-194.691 328.082,-186.977 317.594,-188.479 320.82,-194.691"/>
|
||||
</g>
|
||||
<!-- block2 -->
|
||||
<g id="node33" class="node"><title>block2</title>
|
||||
<ellipse fill="none" stroke="black" cx="355" cy="-227" rx="41.8891" ry="18"/>
|
||||
<text text-anchor="middle" x="355" y="-222.9" font-family="Sans" font-size="14.00">block2</text>
|
||||
</g>
|
||||
<!-- block1->block2 -->
|
||||
<g id="edge30" class="edge"><title>block1->block2</title>
|
||||
<path fill="none" stroke="black" d="M293.601,-227C296.397,-227 299.23,-227 302.068,-227"/>
|
||||
<polygon fill="black" stroke="black" points="302.297,-230.5 312.297,-227 302.297,-223.5 302.297,-230.5"/>
|
||||
</g>
|
||||
<!-- block4 -->
|
||||
<g id="node28" class="node"><title>block4</title>
|
||||
<ellipse fill="none" stroke="black" cx="563" cy="-227" rx="41.8891" ry="18"/>
|
||||
<text text-anchor="middle" x="563" y="-222.9" font-family="Sans" font-size="14.00">block4</text>
|
||||
</g>
|
||||
<!-- block4->block5x -->
|
||||
<g id="edge26" class="edge"><title>block4->block5x</title>
|
||||
<path fill="none" stroke="black" d="M590.053,-212.953C602.572,-206.453 617.618,-198.641 631.073,-191.655"/>
|
||||
<polygon fill="black" stroke="black" points="632.82,-194.691 640.082,-186.977 629.594,-188.479 632.82,-194.691"/>
|
||||
</g>
|
||||
<!-- block5 -->
|
||||
<g id="node38" class="node"><title>block5</title>
|
||||
<ellipse fill="none" stroke="black" cx="667" cy="-227" rx="41.8891" ry="18"/>
|
||||
<text text-anchor="middle" x="667" y="-222.9" font-family="Sans" font-size="14.00">block5</text>
|
||||
</g>
|
||||
<!-- block4->block5 -->
|
||||
<g id="edge36" class="edge"><title>block4->block5</title>
|
||||
<path fill="none" stroke="black" d="M605.601,-227C608.397,-227 611.23,-227 614.068,-227"/>
|
||||
<polygon fill="black" stroke="black" points="614.297,-230.5 624.297,-227 614.297,-223.5 614.297,-230.5"/>
|
||||
</g>
|
||||
<!-- block0 -->
|
||||
<g id="node30" class="node"><title>block0</title>
|
||||
<ellipse fill="none" stroke="black" cx="59" cy="-227" rx="41.8891" ry="18"/>
|
||||
<text text-anchor="middle" x="59" y="-222.9" font-family="Sans" font-size="14.00">block0</text>
|
||||
</g>
|
||||
<!-- block0->block1 -->
|
||||
<g id="edge28" class="edge"><title>block0->block1</title>
|
||||
<path fill="none" stroke="black" d="M101.611,-227C130.098,-227 167.781,-227 198.173,-227"/>
|
||||
<polygon fill="black" stroke="black" points="198.177,-230.5 208.177,-227 198.177,-223.5 198.177,-230.5"/>
|
||||
<text text-anchor="middle" x="155" y="-231.4" font-family="Sans" font-size="14.00">Header Hash</text>
|
||||
</g>
|
||||
<!-- block3 -->
|
||||
<g id="node35" class="node"><title>block3</title>
|
||||
<ellipse fill="none" stroke="black" cx="459" cy="-227" rx="41.8891" ry="18"/>
|
||||
<text text-anchor="middle" x="459" y="-222.9" font-family="Sans" font-size="14.00">block3</text>
|
||||
</g>
|
||||
<!-- block2->block3 -->
|
||||
<g id="edge32" class="edge"><title>block2->block3</title>
|
||||
<path fill="none" stroke="black" d="M397.601,-227C400.397,-227 403.23,-227 406.068,-227"/>
|
||||
<polygon fill="black" stroke="black" points="406.297,-230.5 416.297,-227 406.297,-223.5 406.297,-230.5"/>
|
||||
</g>
|
||||
<!-- block3->block4 -->
|
||||
<g id="edge34" class="edge"><title>block3->block4</title>
|
||||
<path fill="none" stroke="black" d="M501.601,-227C504.397,-227 507.23,-227 510.068,-227"/>
|
||||
<polygon fill="black" stroke="black" points="510.297,-230.5 520.297,-227 510.297,-223.5 510.297,-230.5"/>
|
||||
</g>
|
||||
<!-- block6 -->
|
||||
<g id="node40" class="node"><title>block6</title>
|
||||
<ellipse fill="none" stroke="black" cx="771" cy="-227" rx="41.8891" ry="18"/>
|
||||
<text text-anchor="middle" x="771" y="-222.9" font-family="Sans" font-size="14.00">block6</text>
|
||||
</g>
|
||||
<!-- block5->block6 -->
|
||||
<g id="edge38" class="edge"><title>block5->block6</title>
|
||||
<path fill="none" stroke="black" d="M709.601,-227C712.397,-227 715.23,-227 718.068,-227"/>
|
||||
<polygon fill="black" stroke="black" points="718.297,-230.5 728.297,-227 718.297,-223.5 718.297,-230.5"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 12 KiB |
60
img/dev/en-blockchain-overview.dot
Normal file
|
@ -0,0 +1,60 @@
|
|||
digraph blockchain {
|
||||
|
||||
//splines = "ortho";
|
||||
rankdir=LR;
|
||||
size=6.66;
|
||||
node [ shape = "box", penwidth = 1.75 ];
|
||||
edge [ penwidth = 1.75 ];
|
||||
penwidth = 1.75;
|
||||
nodesep = 0.3;
|
||||
|
||||
_transactions0 [ label = "Block 1\nTransactions", width = 2 ];
|
||||
subgraph cluster_block0header {
|
||||
_blockHeader0 [ style = "invis", label = "", width = 0, height = 0 ];
|
||||
hashBlock9 [label = "Hash Of Previous\nBlock Header", shape = box];
|
||||
hashMerkleRoot0 [label = "Merkle Root"];
|
||||
|
||||
label = "Block 1\nHeader"
|
||||
}
|
||||
|
||||
|
||||
|
||||
_transactions1 [ label = "Block 2\nTransactions", width = 2 ];
|
||||
|
||||
subgraph cluster_block1header {
|
||||
_blockHeader1 [ style = "invis", label = "", width = 0, height = 0 ];
|
||||
hashBlock0 [label = "Hash Of Previous\nBlock Header", shape = box];
|
||||
hashMerkleRoot1 [label = "Merkle Root"];
|
||||
label = "Block 2\nHeader"
|
||||
}
|
||||
|
||||
|
||||
_transactions2 [ label = "Block 3\nTransactions", width = 2 ];
|
||||
_block2 [ style = "invis", label = "", width = 0, height = 0 ];
|
||||
subgraph cluster_block2header {
|
||||
_blockHeader2 [ style = "invis", label = "", width = 0, height = 0 ];
|
||||
hashBlock1 [label = "Hash Of Previous\nBlock Header", shape = box];
|
||||
hashMerkleRoot2 [label = "Merkle Root"];
|
||||
label = "Block 3\nHeader"
|
||||
}
|
||||
invis0 [ style = "invis", label = "", width = 0, height = 0 ];
|
||||
invis1 [ style = "invis", label = "", width = 0, height = 0 ];
|
||||
|
||||
invis0 -> hashBlock9 [ style = dotted ];
|
||||
|
||||
_blockHeader0 -> hashBlock0 [ minlen = 2 ];
|
||||
//hashBlock0 -> hashBlock1 [ style = "invis" ];
|
||||
_blockHeader1 -> hashBlock1 [ minlen = 2 ];
|
||||
|
||||
hashMerkleRoot0 -> hashMerkleRoot1 -> hashMerkleRoot2 [ style = invis, weight = 100, minlen = 2 ];
|
||||
|
||||
_transactions0 -> hashMerkleRoot0 [constraint = false, minlen = 1];
|
||||
_transactions1 -> hashMerkleRoot1 [constraint = false, minlen = 1];
|
||||
_transactions2 -> hashMerkleRoot2 [constraint = false, minlen = 1];
|
||||
|
||||
_transactions0 -> _transactions1 -> _transactions2 [ style = "invis", minlen = 2 ];
|
||||
invis1 -> _transactions0 [ style = "invis", minlen = 1 ];
|
||||
|
||||
|
||||
label = "\nSimplified Bitcoin Block Chain";
|
||||
}
|
BIN
img/dev/en-blockchain-overview.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
121
img/dev/en-blockchain-overview.svg
Normal file
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: blockchain Pages: 1 -->
|
||||
<svg width="480pt" height="220pt"
|
||||
viewBox="0.00 0.00 480.00 220.44" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.752351 0.752351) rotate(0) translate(4 289)">
|
||||
<title>blockchain</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-289 635,-289 635,5 -4,5"/>
|
||||
<text text-anchor="middle" x="315" y="-8.4" font-family="Sans" font-size="14.00">Simplified Bitcoin Block Chain</text>
|
||||
<g id="graph2" class="cluster"><title>cluster_block0header</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="34,-97 34,-277 186,-277 186,-97 34,-97"/>
|
||||
<text text-anchor="middle" x="110" y="-260.4" font-family="Sans" font-size="14.00">Block 1</text>
|
||||
<text text-anchor="middle" x="110" y="-243.4" font-family="Sans" font-size="14.00">Header</text>
|
||||
</g>
|
||||
<g id="graph3" class="cluster"><title>cluster_block1header</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="252,-97 252,-277 404,-277 404,-97 252,-97"/>
|
||||
<text text-anchor="middle" x="328" y="-260.4" font-family="Sans" font-size="14.00">Block 2</text>
|
||||
<text text-anchor="middle" x="328" y="-243.4" font-family="Sans" font-size="14.00">Header</text>
|
||||
</g>
|
||||
<g id="graph4" class="cluster"><title>cluster_block2header</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="470,-97 470,-277 622,-277 622,-97 470,-97"/>
|
||||
<text text-anchor="middle" x="546" y="-260.4" font-family="Sans" font-size="14.00">Block 3</text>
|
||||
<text text-anchor="middle" x="546" y="-243.4" font-family="Sans" font-size="14.00">Header</text>
|
||||
</g>
|
||||
<!-- _transactions0 -->
|
||||
<g id="node1" class="node"><title>_transactions0</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="182,-83 38,-83 38,-41 182,-41 182,-83"/>
|
||||
<text text-anchor="middle" x="110" y="-66.4" font-family="Sans" font-size="14.00">Block 1</text>
|
||||
<text text-anchor="middle" x="110" y="-49.4" font-family="Sans" font-size="14.00">Transactions</text>
|
||||
</g>
|
||||
<!-- hashMerkleRoot0 -->
|
||||
<g id="node5" class="node"><title>hashMerkleRoot0</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="159,-141 61,-141 61,-105 159,-105 159,-141"/>
|
||||
<text text-anchor="middle" x="110" y="-118.9" font-family="Sans" font-size="14.00">Merkle Root</text>
|
||||
</g>
|
||||
<!-- _transactions0->hashMerkleRoot0 -->
|
||||
<g id="edge14" class="edge"><title>_transactions0->hashMerkleRoot0</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M110,-83.4453C110,-87.1101 110,-90.7749 110,-94.4397"/>
|
||||
<polygon fill="black" stroke="black" points="106.5,-94.7677 110,-104.768 113.5,-94.7678 106.5,-94.7677"/>
|
||||
</g>
|
||||
<!-- _transactions1 -->
|
||||
<g id="node6" class="node"><title>_transactions1</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="400,-83 256,-83 256,-41 400,-41 400,-83"/>
|
||||
<text text-anchor="middle" x="328" y="-66.4" font-family="Sans" font-size="14.00">Block 2</text>
|
||||
<text text-anchor="middle" x="328" y="-49.4" font-family="Sans" font-size="14.00">Transactions</text>
|
||||
</g>
|
||||
<!-- _transactions0->_transactions1 -->
|
||||
<!-- _blockHeader0 -->
|
||||
<!-- hashBlock0 -->
|
||||
<g id="node9" class="node"><title>hashBlock0</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="395,-205 261,-205 261,-163 395,-163 395,-205"/>
|
||||
<text text-anchor="middle" x="328" y="-188.4" font-family="Sans" font-size="14.00">Hash Of Previous</text>
|
||||
<text text-anchor="middle" x="328" y="-171.4" font-family="Sans" font-size="14.00">Block Header</text>
|
||||
</g>
|
||||
<!-- _blockHeader0->hashBlock0 -->
|
||||
<g id="edge7" class="edge"><title>_blockHeader0->hashBlock0</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M110.753,-226.914C116.577,-226.242 155.06,-221.716 186,-216 207.024,-212.116 229.66,-207.304 250.547,-202.602"/>
|
||||
<polygon fill="black" stroke="black" points="251.35,-206.009 260.326,-200.38 249.799,-199.183 251.35,-206.009"/>
|
||||
</g>
|
||||
<!-- hashBlock9 -->
|
||||
<g id="node4" class="node"><title>hashBlock9</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="177,-205 43,-205 43,-163 177,-163 177,-205"/>
|
||||
<text text-anchor="middle" x="110" y="-188.4" font-family="Sans" font-size="14.00">Hash Of Previous</text>
|
||||
<text text-anchor="middle" x="110" y="-171.4" font-family="Sans" font-size="14.00">Block Header</text>
|
||||
</g>
|
||||
<!-- hashMerkleRoot1 -->
|
||||
<g id="node10" class="node"><title>hashMerkleRoot1</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="377,-141 279,-141 279,-105 377,-105 377,-141"/>
|
||||
<text text-anchor="middle" x="328" y="-118.9" font-family="Sans" font-size="14.00">Merkle Root</text>
|
||||
</g>
|
||||
<!-- hashMerkleRoot0->hashMerkleRoot1 -->
|
||||
<!-- _transactions1->hashMerkleRoot1 -->
|
||||
<g id="edge16" class="edge"><title>_transactions1->hashMerkleRoot1</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M328,-83.4453C328,-87.1101 328,-90.7749 328,-94.4397"/>
|
||||
<polygon fill="black" stroke="black" points="324.5,-94.7677 328,-104.768 331.5,-94.7678 324.5,-94.7677"/>
|
||||
</g>
|
||||
<!-- _transactions2 -->
|
||||
<g id="node11" class="node"><title>_transactions2</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="618,-83 474,-83 474,-41 618,-41 618,-83"/>
|
||||
<text text-anchor="middle" x="546" y="-66.4" font-family="Sans" font-size="14.00">Block 3</text>
|
||||
<text text-anchor="middle" x="546" y="-49.4" font-family="Sans" font-size="14.00">Transactions</text>
|
||||
</g>
|
||||
<!-- _transactions1->_transactions2 -->
|
||||
<!-- _blockHeader1 -->
|
||||
<!-- hashBlock1 -->
|
||||
<g id="node15" class="node"><title>hashBlock1</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="613,-205 479,-205 479,-163 613,-163 613,-205"/>
|
||||
<text text-anchor="middle" x="546" y="-188.4" font-family="Sans" font-size="14.00">Hash Of Previous</text>
|
||||
<text text-anchor="middle" x="546" y="-171.4" font-family="Sans" font-size="14.00">Block Header</text>
|
||||
</g>
|
||||
<!-- _blockHeader1->hashBlock1 -->
|
||||
<g id="edge9" class="edge"><title>_blockHeader1->hashBlock1</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M328.753,-226.914C334.577,-226.242 373.06,-221.716 404,-216 425.024,-212.116 447.66,-207.304 468.547,-202.602"/>
|
||||
<polygon fill="black" stroke="black" points="469.35,-206.009 478.326,-200.38 467.799,-199.183 469.35,-206.009"/>
|
||||
</g>
|
||||
<!-- hashMerkleRoot2 -->
|
||||
<g id="node16" class="node"><title>hashMerkleRoot2</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="595,-141 497,-141 497,-105 595,-105 595,-141"/>
|
||||
<text text-anchor="middle" x="546" y="-118.9" font-family="Sans" font-size="14.00">Merkle Root</text>
|
||||
</g>
|
||||
<!-- hashMerkleRoot1->hashMerkleRoot2 -->
|
||||
<!-- _transactions2->hashMerkleRoot2 -->
|
||||
<g id="edge18" class="edge"><title>_transactions2->hashMerkleRoot2</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M546,-83.4453C546,-87.1101 546,-90.7749 546,-94.4397"/>
|
||||
<polygon fill="black" stroke="black" points="542.5,-94.7677 546,-104.768 549.5,-94.7678 542.5,-94.7677"/>
|
||||
</g>
|
||||
<!-- _block2 -->
|
||||
<!-- _blockHeader2 -->
|
||||
<!-- invis0 -->
|
||||
<!-- invis0->hashBlock9 -->
|
||||
<g id="edge5" class="edge"><title>invis0->hashBlock9</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="1,5" d="M1.69605,-184C4.67071,-184 16.8595,-184 32.0519,-184"/>
|
||||
<polygon fill="black" stroke="black" points="32.4026,-187.5 42.4025,-184 32.4025,-180.5 32.4026,-187.5"/>
|
||||
</g>
|
||||
<!-- invis1 -->
|
||||
<!-- invis1->_transactions0 -->
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 7.5 KiB |
BIN
img/dev/en-btcc-payment-request.png
Normal file
After Width: | Height: | Size: 29 KiB |
29
img/dev/en-cert-order.dot
Normal file
|
@ -0,0 +1,29 @@
|
|||
digraph paymentchannel {
|
||||
size=6.66;
|
||||
//rankdir=LR;
|
||||
//splines = true;
|
||||
//nodesep = 0.4;
|
||||
|
||||
//edge [ minlen = 2 ];
|
||||
node [ shape = box ];
|
||||
|
||||
|
||||
subgraph cluster_signing {
|
||||
btcorg [ label = "www.bitcoin.org" ]
|
||||
rapidssl [ label = "RapidSSL CA" ]
|
||||
geotrust [ label = "GeoTrust Global CA" ]
|
||||
|
||||
geotrust -> rapidssl -> btcorg
|
||||
label = " Certificates In Signing Order \n "
|
||||
}
|
||||
|
||||
subgraph cluster_loading {
|
||||
one [ label = " x509.certificate.append(bitcoin_org-cert) " ]
|
||||
two [ label = " x509.certificate.append(rapidssl_ca-cert) " ]
|
||||
one -> two
|
||||
label = "Certificates In Loading Order\n(Root CA Certificate Is Not Loaded)"
|
||||
}
|
||||
|
||||
label = "(Certificates are loaded into X509Certificates() in reverse signing order)\n \nExample Certificate Loading Order For Payment Requests From Bitcoin.org"
|
||||
|
||||
}
|
BIN
img/dev/en-cert-order.png
Normal file
After Width: | Height: | Size: 9 KiB |
66
img/dev/en-cert-order.svg
Normal file
|
@ -0,0 +1,66 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: paymentchannel Pages: 1 -->
|
||||
<svg width="480pt" height="262pt"
|
||||
viewBox="0.00 0.00 480.00 261.60" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.814941 0.814941) rotate(0) translate(4 317)">
|
||||
<title>paymentchannel</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-317 586,-317 586,5 -4,5"/>
|
||||
<text text-anchor="middle" x="290.5" y="-42.4" font-family="Sans" font-size="14.00">(Certificates are loaded into X509Certificates() in reverse signing order)</text>
|
||||
<text text-anchor="middle" x="290.5" y="-25.4" font-family="Sans" font-size="14.00"> </text>
|
||||
<text text-anchor="middle" x="290.5" y="-8.4" font-family="Sans" font-size="14.00">Example Certificate Loading Order For Payment Requests From Bitcoin.org</text>
|
||||
<g id="graph2" class="cluster"><title>cluster_signing</title>
|
||||
<polygon fill="none" stroke="black" points="8,-67 8,-305 229,-305 229,-67 8,-67"/>
|
||||
<text text-anchor="middle" x="118.5" y="-288.4" font-family="Sans" font-size="14.00"> Certificates In Signing Order </text>
|
||||
<text text-anchor="middle" x="118.5" y="-271.4" font-family="Sans" font-size="14.00"> </text>
|
||||
</g>
|
||||
<g id="graph3" class="cluster"><title>cluster_loading</title>
|
||||
<polygon fill="none" stroke="black" points="237,-139 237,-305 573,-305 573,-139 237,-139"/>
|
||||
<text text-anchor="middle" x="405" y="-288.4" font-family="Sans" font-size="14.00">Certificates In Loading Order</text>
|
||||
<text text-anchor="middle" x="405" y="-271.4" font-family="Sans" font-size="14.00">(Root CA Certificate Is Not Loaded)</text>
|
||||
</g>
|
||||
<!-- btcorg -->
|
||||
<g id="node2" class="node"><title>btcorg</title>
|
||||
<polygon fill="none" stroke="black" points="183,-111 53,-111 53,-75 183,-75 183,-111"/>
|
||||
<text text-anchor="middle" x="118" y="-88.9" font-family="Sans" font-size="14.00">www.bitcoin.org</text>
|
||||
</g>
|
||||
<!-- rapidssl -->
|
||||
<g id="node3" class="node"><title>rapidssl</title>
|
||||
<polygon fill="none" stroke="black" points="170,-183 66,-183 66,-147 170,-147 170,-183"/>
|
||||
<text text-anchor="middle" x="118" y="-160.9" font-family="Sans" font-size="14.00">RapidSSL CA</text>
|
||||
</g>
|
||||
<!-- rapidssl->btcorg -->
|
||||
<g id="edge4" class="edge"><title>rapidssl->btcorg</title>
|
||||
<path fill="none" stroke="black" d="M118,-146.831C118,-139.131 118,-129.974 118,-121.417"/>
|
||||
<polygon fill="black" stroke="black" points="121.5,-121.413 118,-111.413 114.5,-121.413 121.5,-121.413"/>
|
||||
</g>
|
||||
<!-- geotrust -->
|
||||
<g id="node4" class="node"><title>geotrust</title>
|
||||
<polygon fill="none" stroke="black" points="194,-255 42,-255 42,-219 194,-219 194,-255"/>
|
||||
<text text-anchor="middle" x="118" y="-232.9" font-family="Sans" font-size="14.00">GeoTrust Global CA</text>
|
||||
</g>
|
||||
<!-- geotrust->rapidssl -->
|
||||
<g id="edge3" class="edge"><title>geotrust->rapidssl</title>
|
||||
<path fill="none" stroke="black" d="M118,-218.831C118,-211.131 118,-201.974 118,-193.417"/>
|
||||
<polygon fill="black" stroke="black" points="121.5,-193.413 118,-183.413 114.5,-193.413 121.5,-193.413"/>
|
||||
</g>
|
||||
<!-- one -->
|
||||
<g id="node7" class="node"><title>one</title>
|
||||
<polygon fill="none" stroke="black" points="565,-255 245,-255 245,-219 565,-219 565,-255"/>
|
||||
<text text-anchor="middle" x="405" y="-232.9" font-family="Sans" font-size="14.00">    x509.certificate.append(bitcoin_org-cert) </text>
|
||||
</g>
|
||||
<!-- two -->
|
||||
<g id="node8" class="node"><title>two</title>
|
||||
<polygon fill="none" stroke="black" points="564,-183 246,-183 246,-147 564,-147 564,-183"/>
|
||||
<text text-anchor="middle" x="405" y="-160.9" font-family="Sans" font-size="14.00">    x509.certificate.append(rapidssl_ca-cert) </text>
|
||||
</g>
|
||||
<!-- one->two -->
|
||||
<g id="edge7" class="edge"><title>one->two</title>
|
||||
<path fill="none" stroke="black" d="M405,-218.831C405,-211.131 405,-201.974 405,-193.417"/>
|
||||
<polygon fill="black" stroke="black" points="408.5,-193.413 405,-183.413 401.5,-193.413 408.5,-193.413"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4 KiB |
99
img/dev/en-coinjoin.dot
Normal file
|
@ -0,0 +1,99 @@
|
|||
digraph paymentchannel {
|
||||
size=6.66;
|
||||
rankdir=LR;
|
||||
//splines = false;
|
||||
nodesep = 0.1;
|
||||
|
||||
edge [ minlen = 1.33 ];
|
||||
node [ shape = box ];
|
||||
|
||||
|
||||
|
||||
|
||||
subgraph cluster_nemo {
|
||||
label = "Nemo's UTXOs"
|
||||
|
||||
nemo_out1 [ label = "10 mBTC" ];
|
||||
nemo_out2 [ label = "90 mBTC" ];
|
||||
}
|
||||
|
||||
|
||||
subgraph cluster_neminem {
|
||||
label = "Neminem's UTXOs"
|
||||
|
||||
neminem_out1 [ label = "100 mBTC" ];
|
||||
|
||||
}
|
||||
|
||||
subgraph cluster_alice {
|
||||
label = "AnonGirl's UTXOs"
|
||||
|
||||
alice_out1 [ label = "55 mBTC" ];
|
||||
alice_out2 [ label = "25 mBTC" ];
|
||||
alice_out3 [ label = "20 mBTC" ];
|
||||
|
||||
}
|
||||
|
||||
subgraph prevouts {
|
||||
node [ style = invis, label="", width=0, height=0 ]
|
||||
|
||||
prevout3;
|
||||
prevout4;
|
||||
prevout5;
|
||||
prevout0;
|
||||
prevout1;
|
||||
prevout2;
|
||||
|
||||
}
|
||||
|
||||
subgraph cluster_coinjoin {
|
||||
label = "CoinJoin Transaction"
|
||||
|
||||
subgraph cluster_inputs {
|
||||
label = "Inputs"
|
||||
node [ label = "" ]
|
||||
nemo_in1;
|
||||
nemo_in2;
|
||||
neminem_in1;
|
||||
alice_in1;
|
||||
alice_in2;
|
||||
alice_in3;
|
||||
}
|
||||
|
||||
subgraph cluster_outputs {
|
||||
label = "Outputs"
|
||||
node [ label = "100 mBTC" ];
|
||||
out1;
|
||||
out2;
|
||||
out3;
|
||||
}
|
||||
}
|
||||
|
||||
utxo1 [ label = "Person 1" ];
|
||||
utxo2 [ label = "Person 2" ];
|
||||
utxo3 [ label = "Person 3" ];
|
||||
|
||||
// prevouts
|
||||
|
||||
prevout0 -> alice_out1 [ style = dashed, label = "From Bob" ];
|
||||
prevout1 -> alice_out2 [ style = dashed, label = "From Charlie" ];
|
||||
prevout2 -> alice_out3 [ style = dashed ];
|
||||
prevout3 -> nemo_out1 [ style = dashed ];
|
||||
prevout4 -> nemo_out2 [ style = dashed ];
|
||||
prevout5 -> neminem_out1 [ style = dashed ];
|
||||
|
||||
alice_out1 -> alice_in1;
|
||||
alice_out2 -> alice_in2;
|
||||
alice_out3 -> alice_in3;
|
||||
nemo_out1 -> nemo_in1;
|
||||
nemo_out2 -> nemo_in2;
|
||||
neminem_out1 -> neminem_in1;
|
||||
|
||||
|
||||
out1 -> utxo1;
|
||||
out2 -> utxo2;
|
||||
out3 -> utxo3;
|
||||
|
||||
|
||||
label = "Example CoinJoin Transaction\nOnly the participants know who gets which output."
|
||||
}
|
BIN
img/dev/en-coinjoin.png
Normal file
After Width: | Height: | Size: 12 KiB |
206
img/dev/en-coinjoin.svg
Normal file
|
@ -0,0 +1,206 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: paymentchannel Pages: 1 -->
|
||||
<svg width="458pt" height="480pt"
|
||||
viewBox="0.00 0.00 457.62 480.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.829016 0.829016) rotate(0) translate(4 575)">
|
||||
<title>paymentchannel</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-575 549,-575 549,5 -4,5"/>
|
||||
<text text-anchor="middle" x="272" y="-25.4" font-family="Sans" font-size="14.00">Example CoinJoin Transaction</text>
|
||||
<text text-anchor="middle" x="272" y="-8.4" font-family="Sans" font-size="14.00">Only the participants know who gets which output.</text>
|
||||
<g id="graph2" class="cluster"><title>cluster_nemo</title>
|
||||
<polygon fill="none" stroke="black" points="130,-187 130,-307 248,-307 248,-187 130,-187"/>
|
||||
<text text-anchor="middle" x="189" y="-290.4" font-family="Sans" font-size="14.00">Nemo's UTXOs</text>
|
||||
</g>
|
||||
<g id="graph3" class="cluster"><title>cluster_neminem</title>
|
||||
<polygon fill="none" stroke="black" points="118,-486 118,-563 261,-563 261,-486 118,-486"/>
|
||||
<text text-anchor="middle" x="189.5" y="-546.4" font-family="Sans" font-size="14.00">Neminem's UTXOs</text>
|
||||
</g>
|
||||
<g id="graph4" class="cluster"><title>cluster_alice</title>
|
||||
<polygon fill="none" stroke="black" points="120,-315 120,-478 259,-478 259,-315 120,-315"/>
|
||||
<text text-anchor="middle" x="189.5" y="-461.4" font-family="Sans" font-size="14.00">AnonGirl's UTXOs</text>
|
||||
</g>
|
||||
<g id="graph6" class="cluster"><title>cluster_coinjoin</title>
|
||||
<polygon fill="none" stroke="black" points="281,-50 281,-554 438,-554 438,-50 281,-50"/>
|
||||
<text text-anchor="middle" x="359.5" y="-537.4" font-family="Sans" font-size="14.00">CoinJoin Transaction</text>
|
||||
</g>
|
||||
<g id="graph7" class="cluster"><title>cluster_inputs</title>
|
||||
<polygon fill="none" stroke="black" points="324,-229 324,-521 394,-521 394,-229 324,-229"/>
|
||||
<text text-anchor="middle" x="359" y="-504.4" font-family="Sans" font-size="14.00">Inputs</text>
|
||||
</g>
|
||||
<g id="graph8" class="cluster"><title>cluster_outputs</title>
|
||||
<polygon fill="none" stroke="black" points="306,-58 306,-221 412,-221 412,-58 306,-58"/>
|
||||
<text text-anchor="middle" x="359" y="-204.4" font-family="Sans" font-size="14.00">Outputs</text>
|
||||
</g>
|
||||
<!-- nemo_out1 -->
|
||||
<g id="node2" class="node"><title>nemo_out1</title>
|
||||
<polygon fill="none" stroke="black" points="229,-274 149,-274 149,-238 229,-238 229,-274"/>
|
||||
<text text-anchor="middle" x="189" y="-251.9" font-family="Sans" font-size="14.00">10 mBTC</text>
|
||||
</g>
|
||||
<!-- nemo_in1 -->
|
||||
<g id="node19" class="node"><title>nemo_in1</title>
|
||||
<polygon fill="none" stroke="black" points="386,-316 332,-316 332,-280 386,-280 386,-316"/>
|
||||
</g>
|
||||
<!-- nemo_out1->nemo_in1 -->
|
||||
<g id="edge27" class="edge"><title>nemo_out1->nemo_in1</title>
|
||||
<path fill="none" stroke="black" d="M229.288,-265.953C257.409,-272.901 294.659,-282.104 322.024,-288.865"/>
|
||||
<polygon fill="black" stroke="black" points="321.441,-292.326 331.988,-291.326 323.12,-285.53 321.441,-292.326"/>
|
||||
</g>
|
||||
<!-- nemo_out2 -->
|
||||
<g id="node3" class="node"><title>nemo_out2</title>
|
||||
<polygon fill="none" stroke="black" points="229,-231 149,-231 149,-195 229,-195 229,-231"/>
|
||||
<text text-anchor="middle" x="189" y="-208.9" font-family="Sans" font-size="14.00">90 mBTC</text>
|
||||
</g>
|
||||
<!-- nemo_in2 -->
|
||||
<g id="node20" class="node"><title>nemo_in2</title>
|
||||
<polygon fill="none" stroke="black" points="386,-273 332,-273 332,-237 386,-237 386,-273"/>
|
||||
</g>
|
||||
<!-- nemo_out2->nemo_in2 -->
|
||||
<g id="edge29" class="edge"><title>nemo_out2->nemo_in2</title>
|
||||
<path fill="none" stroke="black" d="M229.288,-222.953C257.409,-229.901 294.659,-239.104 322.024,-245.865"/>
|
||||
<polygon fill="black" stroke="black" points="321.441,-249.326 331.988,-248.326 323.12,-242.53 321.441,-249.326"/>
|
||||
</g>
|
||||
<!-- neminem_out1 -->
|
||||
<g id="node5" class="node"><title>neminem_out1</title>
|
||||
<polygon fill="none" stroke="black" points="233,-530 145,-530 145,-494 233,-494 233,-530"/>
|
||||
<text text-anchor="middle" x="189" y="-507.9" font-family="Sans" font-size="14.00">100 mBTC</text>
|
||||
</g>
|
||||
<!-- neminem_in1 -->
|
||||
<g id="node21" class="node"><title>neminem_in1</title>
|
||||
<polygon fill="none" stroke="black" points="386,-488 332,-488 332,-452 386,-452 386,-488"/>
|
||||
</g>
|
||||
<!-- neminem_out1->neminem_in1 -->
|
||||
<g id="edge31" class="edge"><title>neminem_out1->neminem_in1</title>
|
||||
<path fill="none" stroke="black" d="M233.665,-500.965C261.109,-494.185 295.855,-485.6 321.799,-479.191"/>
|
||||
<polygon fill="black" stroke="black" points="322.759,-482.559 331.628,-476.763 321.08,-475.763 322.759,-482.559"/>
|
||||
</g>
|
||||
<!-- alice_out1 -->
|
||||
<g id="node7" class="node"><title>alice_out1</title>
|
||||
<polygon fill="none" stroke="black" points="229,-445 149,-445 149,-409 229,-409 229,-445"/>
|
||||
<text text-anchor="middle" x="189" y="-422.9" font-family="Sans" font-size="14.00">55 mBTC</text>
|
||||
</g>
|
||||
<!-- alice_in1 -->
|
||||
<g id="node22" class="node"><title>alice_in1</title>
|
||||
<polygon fill="none" stroke="black" points="386,-445 332,-445 332,-409 386,-409 386,-445"/>
|
||||
</g>
|
||||
<!-- alice_out1->alice_in1 -->
|
||||
<g id="edge21" class="edge"><title>alice_out1->alice_in1</title>
|
||||
<path fill="none" stroke="black" d="M229.288,-427C257.285,-427 294.331,-427 321.662,-427"/>
|
||||
<polygon fill="black" stroke="black" points="321.988,-430.5 331.988,-427 321.988,-423.5 321.988,-430.5"/>
|
||||
</g>
|
||||
<!-- alice_out2 -->
|
||||
<g id="node8" class="node"><title>alice_out2</title>
|
||||
<polygon fill="none" stroke="black" points="229,-402 149,-402 149,-366 229,-366 229,-402"/>
|
||||
<text text-anchor="middle" x="189" y="-379.9" font-family="Sans" font-size="14.00">25 mBTC</text>
|
||||
</g>
|
||||
<!-- alice_in2 -->
|
||||
<g id="node23" class="node"><title>alice_in2</title>
|
||||
<polygon fill="none" stroke="black" points="386,-402 332,-402 332,-366 386,-366 386,-402"/>
|
||||
</g>
|
||||
<!-- alice_out2->alice_in2 -->
|
||||
<g id="edge23" class="edge"><title>alice_out2->alice_in2</title>
|
||||
<path fill="none" stroke="black" d="M229.288,-384C257.285,-384 294.331,-384 321.662,-384"/>
|
||||
<polygon fill="black" stroke="black" points="321.988,-387.5 331.988,-384 321.988,-380.5 321.988,-387.5"/>
|
||||
</g>
|
||||
<!-- alice_out3 -->
|
||||
<g id="node9" class="node"><title>alice_out3</title>
|
||||
<polygon fill="none" stroke="black" points="229,-359 149,-359 149,-323 229,-323 229,-359"/>
|
||||
<text text-anchor="middle" x="189" y="-336.9" font-family="Sans" font-size="14.00">20 mBTC</text>
|
||||
</g>
|
||||
<!-- alice_in3 -->
|
||||
<g id="node24" class="node"><title>alice_in3</title>
|
||||
<polygon fill="none" stroke="black" points="386,-359 332,-359 332,-323 386,-323 386,-359"/>
|
||||
</g>
|
||||
<!-- alice_out3->alice_in3 -->
|
||||
<g id="edge25" class="edge"><title>alice_out3->alice_in3</title>
|
||||
<path fill="none" stroke="black" d="M229.288,-341C257.285,-341 294.331,-341 321.662,-341"/>
|
||||
<polygon fill="black" stroke="black" points="321.988,-344.5 331.988,-341 321.988,-337.5 321.988,-344.5"/>
|
||||
</g>
|
||||
<!-- prevout3 -->
|
||||
<!-- prevout3->nemo_out1 -->
|
||||
<g id="edge15" class="edge"><title>prevout3->nemo_out1</title>
|
||||
<path fill="none" stroke="black" stroke-dasharray="5,2" d="M1.53931,-256C8.687,-256 85.331,-256 138.374,-256"/>
|
||||
<polygon fill="black" stroke="black" points="138.64,-259.5 148.64,-256 138.64,-252.5 138.64,-259.5"/>
|
||||
</g>
|
||||
<!-- prevout4 -->
|
||||
<!-- prevout4->nemo_out2 -->
|
||||
<g id="edge17" class="edge"><title>prevout4->nemo_out2</title>
|
||||
<path fill="none" stroke="black" stroke-dasharray="5,2" d="M1.53931,-213C8.687,-213 85.331,-213 138.374,-213"/>
|
||||
<polygon fill="black" stroke="black" points="138.64,-216.5 148.64,-213 138.64,-209.5 138.64,-216.5"/>
|
||||
</g>
|
||||
<!-- prevout5 -->
|
||||
<!-- prevout5->neminem_out1 -->
|
||||
<g id="edge19" class="edge"><title>prevout5->neminem_out1</title>
|
||||
<path fill="none" stroke="black" stroke-dasharray="5,2" d="M1.53931,-512C8.48509,-512 81.0563,-512 133.824,-512"/>
|
||||
<polygon fill="black" stroke="black" points="134.089,-515.5 144.089,-512 134.089,-508.5 134.089,-515.5"/>
|
||||
</g>
|
||||
<!-- prevout0 -->
|
||||
<!-- prevout0->alice_out1 -->
|
||||
<g id="edge9" class="edge"><title>prevout0->alice_out1</title>
|
||||
<path fill="none" stroke="black" stroke-dasharray="5,2" d="M1.53931,-427C8.687,-427 85.331,-427 138.374,-427"/>
|
||||
<polygon fill="black" stroke="black" points="138.64,-430.5 148.64,-427 138.64,-423.5 138.64,-430.5"/>
|
||||
<text text-anchor="middle" x="64" y="-431.4" font-family="Sans" font-size="14.00">From Bob</text>
|
||||
</g>
|
||||
<!-- prevout1 -->
|
||||
<!-- prevout1->alice_out2 -->
|
||||
<g id="edge11" class="edge"><title>prevout1->alice_out2</title>
|
||||
<path fill="none" stroke="black" stroke-dasharray="5,2" d="M1.53931,-384C8.687,-384 85.331,-384 138.374,-384"/>
|
||||
<polygon fill="black" stroke="black" points="138.64,-387.5 148.64,-384 138.64,-380.5 138.64,-387.5"/>
|
||||
<text text-anchor="middle" x="64" y="-388.4" font-family="Sans" font-size="14.00">From Charlie</text>
|
||||
</g>
|
||||
<!-- prevout2 -->
|
||||
<!-- prevout2->alice_out3 -->
|
||||
<g id="edge13" class="edge"><title>prevout2->alice_out3</title>
|
||||
<path fill="none" stroke="black" stroke-dasharray="5,2" d="M1.53931,-341C8.687,-341 85.331,-341 138.374,-341"/>
|
||||
<polygon fill="black" stroke="black" points="138.64,-344.5 148.64,-341 138.64,-337.5 138.64,-344.5"/>
|
||||
</g>
|
||||
<!-- out1 -->
|
||||
<g id="node26" class="node"><title>out1</title>
|
||||
<polygon fill="none" stroke="black" points="403,-188 315,-188 315,-152 403,-152 403,-188"/>
|
||||
<text text-anchor="middle" x="359" y="-165.9" font-family="Sans" font-size="14.00">100 mBTC</text>
|
||||
</g>
|
||||
<!-- utxo1 -->
|
||||
<g id="node29" class="node"><title>utxo1</title>
|
||||
<polygon fill="none" stroke="black" points="543,-188 467,-188 467,-152 543,-152 543,-188"/>
|
||||
<text text-anchor="middle" x="505" y="-165.9" font-family="Sans" font-size="14.00">Person 1</text>
|
||||
</g>
|
||||
<!-- out1->utxo1 -->
|
||||
<g id="edge33" class="edge"><title>out1->utxo1</title>
|
||||
<path fill="none" stroke="black" d="M403.598,-170C420.126,-170 438.956,-170 455.865,-170"/>
|
||||
<polygon fill="black" stroke="black" points="456.108,-173.5 466.108,-170 456.108,-166.5 456.108,-173.5"/>
|
||||
</g>
|
||||
<!-- out2 -->
|
||||
<g id="node27" class="node"><title>out2</title>
|
||||
<polygon fill="none" stroke="black" points="403,-145 315,-145 315,-109 403,-109 403,-145"/>
|
||||
<text text-anchor="middle" x="359" y="-122.9" font-family="Sans" font-size="14.00">100 mBTC</text>
|
||||
</g>
|
||||
<!-- utxo2 -->
|
||||
<g id="node30" class="node"><title>utxo2</title>
|
||||
<polygon fill="none" stroke="black" points="543,-145 467,-145 467,-109 543,-109 543,-145"/>
|
||||
<text text-anchor="middle" x="505" y="-122.9" font-family="Sans" font-size="14.00">Person 2</text>
|
||||
</g>
|
||||
<!-- out2->utxo2 -->
|
||||
<g id="edge35" class="edge"><title>out2->utxo2</title>
|
||||
<path fill="none" stroke="black" d="M403.598,-127C420.126,-127 438.956,-127 455.865,-127"/>
|
||||
<polygon fill="black" stroke="black" points="456.108,-130.5 466.108,-127 456.108,-123.5 456.108,-130.5"/>
|
||||
</g>
|
||||
<!-- out3 -->
|
||||
<g id="node28" class="node"><title>out3</title>
|
||||
<polygon fill="none" stroke="black" points="403,-102 315,-102 315,-66 403,-66 403,-102"/>
|
||||
<text text-anchor="middle" x="359" y="-79.9" font-family="Sans" font-size="14.00">100 mBTC</text>
|
||||
</g>
|
||||
<!-- utxo3 -->
|
||||
<g id="node31" class="node"><title>utxo3</title>
|
||||
<polygon fill="none" stroke="black" points="543,-102 467,-102 467,-66 543,-66 543,-102"/>
|
||||
<text text-anchor="middle" x="505" y="-79.9" font-family="Sans" font-size="14.00">Person 3</text>
|
||||
</g>
|
||||
<!-- out3->utxo3 -->
|
||||
<g id="edge37" class="edge"><title>out3->utxo3</title>
|
||||
<path fill="none" stroke="black" d="M403.598,-84C420.126,-84 438.956,-84 455.865,-84"/>
|
||||
<polygon fill="black" stroke="black" points="456.108,-87.5001 466.108,-84 456.108,-80.5001 456.108,-87.5001"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 12 KiB |
42
img/dev/en-creating-p2pkh-output.dot
Normal file
|
@ -0,0 +1,42 @@
|
|||
digraph blockchain {
|
||||
|
||||
size=6.25;
|
||||
|
||||
//splines = "false";
|
||||
rankdir=LR;
|
||||
//ranksep=0.1;
|
||||
//splines=ortho;
|
||||
|
||||
node [ fontname="Sans", shape = box, penwidth = 1.75 ];
|
||||
edge [ fontname="Sans", penwidth = 1.75 ];
|
||||
graph [ fontname="Sans" ];
|
||||
penwidth = 1.75;
|
||||
|
||||
subgraph cluster_bob {
|
||||
private_key [ label = "Private\nKey" ];
|
||||
full_public_key [ label = "Full\nPublic Key" ];
|
||||
pubkey_hash [ label = "Public Key\nHash" ];
|
||||
|
||||
label = "Bob's Computer"
|
||||
}
|
||||
|
||||
subgraph cluster_alice {
|
||||
spender_pubkey_hash [ label = "Copy Of\nPublic Key\nHash" ];
|
||||
|
||||
label = "Alice's Computer"
|
||||
}
|
||||
|
||||
subgraph cluster_tx1 {
|
||||
tx1_pubkey_hash [ label = "Copy Of\nPublic Key\nHash" ];
|
||||
|
||||
label = "TX 1"
|
||||
}
|
||||
|
||||
|
||||
private_key -> full_public_key -> pubkey_hash -> spender_pubkey_hash -> tx1_pubkey_hash;
|
||||
|
||||
|
||||
|
||||
|
||||
label = "Creating A P2PKH Public Key Hash To Receive Payment"
|
||||
}
|
BIN
img/dev/en-creating-p2pkh-output.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
78
img/dev/en-creating-p2pkh-output.svg
Normal file
|
@ -0,0 +1,78 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: blockchain Pages: 1 -->
|
||||
<svg width="450pt" height="107pt"
|
||||
viewBox="0.00 0.00 450.00 106.90" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.722311 0.722311) rotate(0) translate(4 144)">
|
||||
<title>blockchain</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-144 620,-144 620,5 -4,5"/>
|
||||
<text text-anchor="middle" x="307.5" y="-8.4" font-family="Sans" font-size="14.00">Creating A P2PKH Public Key Hash To Receive Payment</text>
|
||||
<g id="graph2" class="cluster"><title>cluster_bob</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="8,-41 8,-124 334,-124 334,-41 8,-41"/>
|
||||
<text text-anchor="middle" x="171" y="-107.4" font-family="Sans" font-size="14.00">Bob's Computer</text>
|
||||
</g>
|
||||
<g id="graph3" class="cluster"><title>cluster_alice</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="354,-33 354,-132 485,-132 485,-33 354,-33"/>
|
||||
<text text-anchor="middle" x="419.5" y="-115.4" font-family="Sans" font-size="14.00">Alice's Computer</text>
|
||||
</g>
|
||||
<g id="graph4" class="cluster"><title>cluster_tx1</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="505,-33 505,-132 607,-132 607,-33 505,-33"/>
|
||||
<text text-anchor="middle" x="556" y="-115.4" font-family="Sans" font-size="14.00">TX 1</text>
|
||||
</g>
|
||||
<!-- private_key -->
|
||||
<g id="node2" class="node"><title>private_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="82,-91 16,-91 16,-49 82,-49 82,-91"/>
|
||||
<text text-anchor="middle" x="49" y="-74.4" font-family="Sans" font-size="14.00">Private</text>
|
||||
<text text-anchor="middle" x="49" y="-57.4" font-family="Sans" font-size="14.00">Key</text>
|
||||
</g>
|
||||
<!-- full_public_key -->
|
||||
<g id="node3" class="node"><title>full_public_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="204,-91 118,-91 118,-49 204,-49 204,-91"/>
|
||||
<text text-anchor="middle" x="161" y="-74.4" font-family="Sans" font-size="14.00">Full</text>
|
||||
<text text-anchor="middle" x="161" y="-57.4" font-family="Sans" font-size="14.00">Public Key</text>
|
||||
</g>
|
||||
<!-- private_key->full_public_key -->
|
||||
<g id="edge5" class="edge"><title>private_key->full_public_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M82.3005,-70C90.272,-70 98.9822,-70 107.61,-70"/>
|
||||
<polygon fill="black" stroke="black" points="107.65,-73.5001 117.65,-70 107.65,-66.5001 107.65,-73.5001"/>
|
||||
</g>
|
||||
<!-- pubkey_hash -->
|
||||
<g id="node4" class="node"><title>pubkey_hash</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="326,-91 240,-91 240,-49 326,-49 326,-91"/>
|
||||
<text text-anchor="middle" x="283" y="-74.4" font-family="Sans" font-size="14.00">Public Key</text>
|
||||
<text text-anchor="middle" x="283" y="-57.4" font-family="Sans" font-size="14.00">Hash</text>
|
||||
</g>
|
||||
<!-- full_public_key->pubkey_hash -->
|
||||
<g id="edge6" class="edge"><title>full_public_key->pubkey_hash</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M204.013,-70C212.395,-70 221.275,-70 229.938,-70"/>
|
||||
<polygon fill="black" stroke="black" points="229.965,-73.5001 239.965,-70 229.965,-66.5001 229.965,-73.5001"/>
|
||||
</g>
|
||||
<!-- spender_pubkey_hash -->
|
||||
<g id="node6" class="node"><title>spender_pubkey_hash</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="462,-99.5 376,-99.5 376,-40.5 462,-40.5 462,-99.5"/>
|
||||
<text text-anchor="middle" x="419" y="-82.9" font-family="Sans" font-size="14.00">Copy Of</text>
|
||||
<text text-anchor="middle" x="419" y="-65.9" font-family="Sans" font-size="14.00">Public Key</text>
|
||||
<text text-anchor="middle" x="419" y="-48.9" font-family="Sans" font-size="14.00">Hash</text>
|
||||
</g>
|
||||
<!-- pubkey_hash->spender_pubkey_hash -->
|
||||
<g id="edge7" class="edge"><title>pubkey_hash->spender_pubkey_hash</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M326.031,-70C338.558,-70 352.397,-70 365.486,-70"/>
|
||||
<polygon fill="black" stroke="black" points="365.782,-73.5001 375.782,-70 365.782,-66.5001 365.782,-73.5001"/>
|
||||
</g>
|
||||
<!-- tx1_pubkey_hash -->
|
||||
<g id="node8" class="node"><title>tx1_pubkey_hash</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="599,-99.5 513,-99.5 513,-40.5 599,-40.5 599,-99.5"/>
|
||||
<text text-anchor="middle" x="556" y="-82.9" font-family="Sans" font-size="14.00">Copy Of</text>
|
||||
<text text-anchor="middle" x="556" y="-65.9" font-family="Sans" font-size="14.00">Public Key</text>
|
||||
<text text-anchor="middle" x="556" y="-48.9" font-family="Sans" font-size="14.00">Hash</text>
|
||||
</g>
|
||||
<!-- spender_pubkey_hash->tx1_pubkey_hash -->
|
||||
<g id="edge8" class="edge"><title>spender_pubkey_hash->tx1_pubkey_hash</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M462.348,-70C475.216,-70 489.46,-70 502.874,-70"/>
|
||||
<polygon fill="black" stroke="black" points="502.934,-73.5001 512.934,-70 502.934,-66.5001 502.934,-73.5001"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5 KiB |
42
img/dev/en-creating-p2sh-output.dot
Normal file
|
@ -0,0 +1,42 @@
|
|||
digraph blockchain {
|
||||
|
||||
size=6.25;
|
||||
|
||||
//splines = "false";
|
||||
rankdir=LR;
|
||||
ranksep=0.2;
|
||||
//splines=ortho;
|
||||
|
||||
node [ shape = box, penwidth = 1.75 ];
|
||||
edge [ penwidth = 1.75 ];
|
||||
penwidth = 1.75;
|
||||
|
||||
subgraph cluster_bob {
|
||||
private_key [ label = "Private\nKey" ];
|
||||
full_public_key [ label = "Full\nPublic Key" ];
|
||||
redeemScript [ label = "RedeemScript" ];
|
||||
script_hash [ label = "Script\nHash" ];
|
||||
|
||||
label = "Bob's Computer"
|
||||
}
|
||||
|
||||
subgraph cluster_alice {
|
||||
spender_script_hash [ label = "Copy Of\nScript\nHash" ];
|
||||
|
||||
label = "Alice's Computer"
|
||||
}
|
||||
|
||||
subgraph cluster_tx1 {
|
||||
tx1_script_hash [ label = "Copy Of\nScript\nHash" ];
|
||||
|
||||
label = "TX 1"
|
||||
}
|
||||
|
||||
|
||||
private_key -> full_public_key -> redeemScript -> script_hash -> spender_script_hash -> tx1_script_hash;
|
||||
|
||||
|
||||
|
||||
|
||||
label = "Creating A P2SH RedeemScript Hash To Receive Payment"
|
||||
}
|
BIN
img/dev/en-creating-p2sh-output.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
88
img/dev/en-creating-p2sh-output.svg
Normal file
|
@ -0,0 +1,88 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: blockchain Pages: 1 -->
|
||||
<svg width="450pt" height="105pt"
|
||||
viewBox="0.00 0.00 450.00 104.55" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.706436 0.706436) rotate(0) translate(4 144)">
|
||||
<title>blockchain</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-144 634,-144 634,5 -4,5"/>
|
||||
<text text-anchor="middle" x="314.5" y="-8.4" font-family="Sans" font-size="14.00">Creating A P2SH RedeemScript Hash To Receive Payment</text>
|
||||
<g id="graph2" class="cluster"><title>cluster_bob</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="8,-41 8,-124 386,-124 386,-41 8,-41"/>
|
||||
<text text-anchor="middle" x="197" y="-107.4" font-family="Sans" font-size="14.00">Bob's Computer</text>
|
||||
</g>
|
||||
<g id="graph3" class="cluster"><title>cluster_alice</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="394,-33 394,-132 525,-132 525,-33 394,-33"/>
|
||||
<text text-anchor="middle" x="459.5" y="-115.4" font-family="Sans" font-size="14.00">Alice's Computer</text>
|
||||
</g>
|
||||
<g id="graph4" class="cluster"><title>cluster_tx1</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="533,-33 533,-132 621,-132 621,-33 533,-33"/>
|
||||
<text text-anchor="middle" x="577" y="-115.4" font-family="Sans" font-size="14.00">TX 1</text>
|
||||
</g>
|
||||
<!-- private_key -->
|
||||
<g id="node2" class="node"><title>private_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="82,-91 16,-91 16,-49 82,-49 82,-91"/>
|
||||
<text text-anchor="middle" x="49" y="-74.4" font-family="Sans" font-size="14.00">Private</text>
|
||||
<text text-anchor="middle" x="49" y="-57.4" font-family="Sans" font-size="14.00">Key</text>
|
||||
</g>
|
||||
<!-- full_public_key -->
|
||||
<g id="node3" class="node"><title>full_public_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="182,-91 96,-91 96,-49 182,-49 182,-91"/>
|
||||
<text text-anchor="middle" x="139" y="-74.4" font-family="Sans" font-size="14.00">Full</text>
|
||||
<text text-anchor="middle" x="139" y="-57.4" font-family="Sans" font-size="14.00">Public Key</text>
|
||||
</g>
|
||||
<!-- private_key->full_public_key -->
|
||||
<g id="edge5" class="edge"><title>private_key->full_public_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M82.0016,-70C83.2715,-70 84.5551,-70 85.848,-70"/>
|
||||
<polygon fill="black" stroke="black" points="85.8679,-73.5001 95.8679,-70 85.8679,-66.5001 85.8679,-73.5001"/>
|
||||
</g>
|
||||
<!-- redeemScript -->
|
||||
<g id="node4" class="node"><title>redeemScript</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="307,-88 197,-88 197,-52 307,-52 307,-88"/>
|
||||
<text text-anchor="middle" x="252" y="-65.9" font-family="Sans" font-size="14.00">RedeemScript</text>
|
||||
</g>
|
||||
<!-- full_public_key->redeemScript -->
|
||||
<g id="edge6" class="edge"><title>full_public_key->redeemScript</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M182.043,-70C183.341,-70 184.649,-70 185.964,-70"/>
|
||||
<polygon fill="black" stroke="black" points="186.138,-73.5001 196.138,-70 186.137,-66.5001 186.138,-73.5001"/>
|
||||
</g>
|
||||
<!-- script_hash -->
|
||||
<g id="node5" class="node"><title>script_hash</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="378,-91 322,-91 322,-49 378,-49 378,-91"/>
|
||||
<text text-anchor="middle" x="350" y="-74.4" font-family="Sans" font-size="14.00">Script</text>
|
||||
<text text-anchor="middle" x="350" y="-57.4" font-family="Sans" font-size="14.00">Hash</text>
|
||||
</g>
|
||||
<!-- redeemScript->script_hash -->
|
||||
<g id="edge7" class="edge"><title>redeemScript->script_hash</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M307.586,-70C308.947,-70 310.3,-70 311.643,-70"/>
|
||||
<polygon fill="black" stroke="black" points="311.646,-73.5001 321.646,-70 311.646,-66.5001 311.646,-73.5001"/>
|
||||
</g>
|
||||
<!-- spender_script_hash -->
|
||||
<g id="node7" class="node"><title>spender_script_hash</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="494,-99.5 424,-99.5 424,-40.5 494,-40.5 494,-99.5"/>
|
||||
<text text-anchor="middle" x="459" y="-82.9" font-family="Sans" font-size="14.00">Copy Of</text>
|
||||
<text text-anchor="middle" x="459" y="-65.9" font-family="Sans" font-size="14.00">Script</text>
|
||||
<text text-anchor="middle" x="459" y="-48.9" font-family="Sans" font-size="14.00">Hash</text>
|
||||
</g>
|
||||
<!-- script_hash->spender_script_hash -->
|
||||
<g id="edge8" class="edge"><title>script_hash->spender_script_hash</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M378.07,-70C388.706,-70 401.113,-70 412.972,-70"/>
|
||||
<polygon fill="black" stroke="black" points="413.194,-73.5001 423.194,-70 413.194,-66.5001 413.194,-73.5001"/>
|
||||
</g>
|
||||
<!-- tx1_script_hash -->
|
||||
<g id="node9" class="node"><title>tx1_script_hash</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="612,-99.5 542,-99.5 542,-40.5 612,-40.5 612,-99.5"/>
|
||||
<text text-anchor="middle" x="577" y="-82.9" font-family="Sans" font-size="14.00">Copy Of</text>
|
||||
<text text-anchor="middle" x="577" y="-65.9" font-family="Sans" font-size="14.00">Script</text>
|
||||
<text text-anchor="middle" x="577" y="-48.9" font-family="Sans" font-size="14.00">Hash</text>
|
||||
</g>
|
||||
<!-- spender_script_hash->tx1_script_hash -->
|
||||
<g id="edge9" class="edge"><title>spender_script_hash->tx1_script_hash</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M494.724,-70C506.161,-70 518.988,-70 531.05,-70"/>
|
||||
<polygon fill="black" stroke="black" points="531.397,-73.5001 541.397,-70 531.397,-66.5001 531.397,-73.5001"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.6 KiB |
75
img/dev/en-hd-cross-generational-key-compromise.dot
Normal file
|
@ -0,0 +1,75 @@
|
|||
digraph extended {
|
||||
|
||||
size=6.25;
|
||||
rankdir=LR;
|
||||
penwidth=1.75;
|
||||
node [ fontname="Sans", penwidth = 1.75, shape = "box" ];
|
||||
edge [ fontname="Sans", penwidth = 1.75, style = "" ];
|
||||
graph [ fontname="Sans" ];
|
||||
nodesep=0.15;
|
||||
splines = false;
|
||||
ranksep = 0.7;
|
||||
|
||||
subgraph cluster_parent {
|
||||
parent_private_key [ label = "Private", style = "" ];
|
||||
parent_chain_code [ label = "Chain", style = "filled" ];
|
||||
parent_public_key [ label = "Public", style = "filled" ];
|
||||
|
||||
label = "Parent\n "
|
||||
}
|
||||
|
||||
subgraph cluster_child {
|
||||
child_private_key [ label = "Private" ];
|
||||
child_chain_code [ label = "Chain" ];
|
||||
child_public_key [ label = "Public" ];
|
||||
|
||||
label = "Child\n "
|
||||
}
|
||||
|
||||
subgraph cluster_grandchild {
|
||||
grandchild_private_key [ label = "Private", style = "filled" ];
|
||||
grandchild_chain_code [ label = "Chain" ];
|
||||
grandchild_public_key [ label = "Public" ];
|
||||
|
||||
label = "Grandchild\n "
|
||||
}
|
||||
|
||||
subgraph cluster_greatgrandchild {
|
||||
greatgrandchild_private_key [ label = "Private" ];
|
||||
greatgrandchild_chain_code [ label = "Chain" ];
|
||||
greatgrandchild_public_key [ label = "Public" ];
|
||||
|
||||
label = "Great-\nGrandchild"
|
||||
}
|
||||
|
||||
|
||||
parent_public_key -> child_public_key;
|
||||
parent_public_key -> child_chain_code;
|
||||
parent_chain_code -> child_chain_code [ label = "Normal Child\nKey Derivation", weight = 100 ];
|
||||
parent_chain_code -> child_public_key;
|
||||
parent_chain_code -> child_private_key [ style = "invis" ];
|
||||
parent_private_key -> child_private_key [ dir = "back", style = "", label = "Parent Key\nDerivation" ];
|
||||
|
||||
parent_chain_code -> parent_private_key [ constraint = false ];
|
||||
|
||||
child_private_key -> grandchild_private_key [ dir = "back", style = "" ];
|
||||
child_public_key -> grandchild_chain_code;
|
||||
child_public_key -> grandchild_public_key;
|
||||
child_chain_code -> grandchild_private_key [ style = "invis" ];
|
||||
child_chain_code -> grandchild_public_key;
|
||||
child_chain_code -> grandchild_chain_code [ weight = 100 ];
|
||||
|
||||
child_chain_code -> child_private_key [ constraint = false ]
|
||||
|
||||
grandchild_private_key -> greatgrandchild_private_key;
|
||||
grandchild_public_key -> greatgrandchild_chain_code;
|
||||
grandchild_public_key -> greatgrandchild_public_key;
|
||||
grandchild_chain_code -> greatgrandchild_private_key;
|
||||
grandchild_chain_code -> greatgrandchild_public_key;
|
||||
grandchild_chain_code -> greatgrandchild_chain_code [ weight = 100 ];
|
||||
|
||||
grandchild_chain_code -> grandchild_private_key [ constraint = false, style = "invis" ]
|
||||
greatgrandchild_chain_code -> greatgrandchild_private_key [ constraint = false, style = "invis" ]
|
||||
|
||||
label = "Cross-Generational Key Compromise"
|
||||
}
|
BIN
img/dev/en-hd-cross-generational-key-compromise.png
Normal file
After Width: | Height: | Size: 9.3 KiB |
192
img/dev/en-hd-cross-generational-key-compromise.svg
Normal file
|
@ -0,0 +1,192 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: extended Pages: 1 -->
|
||||
<svg width="450pt" height="192pt"
|
||||
viewBox="0.00 0.00 450.00 192.41" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.775862 0.775862) rotate(0) translate(4 244)">
|
||||
<title>extended</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-244 577,-244 577,5 -4,5"/>
|
||||
<text text-anchor="middle" x="286" y="-8.4" font-family="Sans" font-size="14.00">Cross-Generational Key Compromise</text>
|
||||
<g id="graph2" class="cluster"><title>cluster_parent</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="8,-33 8,-232 90,-232 90,-33 8,-33"/>
|
||||
<text text-anchor="middle" x="49" y="-215.4" font-family="Sans" font-size="14.00">Parent</text>
|
||||
<text text-anchor="middle" x="49" y="-198.4" font-family="Sans" font-size="14.00"> </text>
|
||||
</g>
|
||||
<g id="graph3" class="cluster"><title>cluster_child</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="228,-33 228,-232 310,-232 310,-33 228,-33"/>
|
||||
<text text-anchor="middle" x="269" y="-215.4" font-family="Sans" font-size="14.00">Child</text>
|
||||
<text text-anchor="middle" x="269" y="-198.4" font-family="Sans" font-size="14.00"> </text>
|
||||
</g>
|
||||
<g id="graph4" class="cluster"><title>cluster_grandchild</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="346,-33 346,-232 437,-232 437,-33 346,-33"/>
|
||||
<text text-anchor="middle" x="391.5" y="-215.4" font-family="Sans" font-size="14.00">Grandchild</text>
|
||||
<text text-anchor="middle" x="391.5" y="-198.4" font-family="Sans" font-size="14.00"> </text>
|
||||
</g>
|
||||
<g id="graph5" class="cluster"><title>cluster_greatgrandchild</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="473,-33 473,-232 564,-232 564,-33 473,-33"/>
|
||||
<text text-anchor="middle" x="518.5" y="-215.4" font-family="Sans" font-size="14.00">Great-</text>
|
||||
<text text-anchor="middle" x="518.5" y="-198.4" font-family="Sans" font-size="14.00">Grandchild</text>
|
||||
</g>
|
||||
<!-- parent_private_key -->
|
||||
<g id="node2" class="node"><title>parent_private_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="82,-182 16,-182 16,-146 82,-146 82,-182"/>
|
||||
<text text-anchor="middle" x="49" y="-159.9" font-family="Sans" font-size="14.00">Private</text>
|
||||
</g>
|
||||
<!-- child_private_key -->
|
||||
<g id="node6" class="node"><title>child_private_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="302,-182 236,-182 236,-146 302,-146 302,-182"/>
|
||||
<text text-anchor="middle" x="269" y="-159.9" font-family="Sans" font-size="14.00">Private</text>
|
||||
</g>
|
||||
<!-- parent_private_key->child_private_key -->
|
||||
<g id="edge16" class="edge"><title>parent_private_key->child_private_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M92.6643,-164C134.855,-164 197.827,-164 235.993,-164"/>
|
||||
<polygon fill="black" stroke="black" points="92.4133,-160.5 82.4133,-164 92.4132,-167.5 92.4133,-160.5"/>
|
||||
<text text-anchor="middle" x="159" y="-185.4" font-family="Sans" font-size="14.00">Parent Key</text>
|
||||
<text text-anchor="middle" x="159" y="-168.4" font-family="Sans" font-size="14.00">Derivation</text>
|
||||
</g>
|
||||
<!-- parent_chain_code -->
|
||||
<g id="node3" class="node"><title>parent_chain_code</title>
|
||||
<polygon fill="lightgrey" stroke="black" stroke-width="1.75" points="77,-124 21,-124 21,-88 77,-88 77,-124"/>
|
||||
<text text-anchor="middle" x="49" y="-101.9" font-family="Sans" font-size="14.00">Chain</text>
|
||||
</g>
|
||||
<!-- parent_chain_code->parent_private_key -->
|
||||
<g id="edge18" class="edge"><title>parent_chain_code->parent_private_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M49,-124.125C49,-127.987 49,-131.848 49,-135.71"/>
|
||||
<polygon fill="black" stroke="black" points="45.5001,-135.932 49,-145.932 52.5001,-135.932 45.5001,-135.932"/>
|
||||
</g>
|
||||
<!-- parent_chain_code->child_private_key -->
|
||||
<!-- child_chain_code -->
|
||||
<g id="node7" class="node"><title>child_chain_code</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="297,-124 241,-124 241,-88 297,-88 297,-124"/>
|
||||
<text text-anchor="middle" x="269" y="-101.9" font-family="Sans" font-size="14.00">Chain</text>
|
||||
</g>
|
||||
<!-- parent_chain_code->child_chain_code -->
|
||||
<g id="edge10" class="edge"><title>parent_chain_code->child_chain_code</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M77.3108,-106C116.336,-106 186.787,-106 230.55,-106"/>
|
||||
<polygon fill="black" stroke="black" points="230.798,-109.5 240.798,-106 230.798,-102.5 230.798,-109.5"/>
|
||||
<text text-anchor="middle" x="159" y="-127.4" font-family="Sans" font-size="14.00">Normal Child</text>
|
||||
<text text-anchor="middle" x="159" y="-110.4" font-family="Sans" font-size="14.00">Key Derivation</text>
|
||||
</g>
|
||||
<!-- child_public_key -->
|
||||
<g id="node8" class="node"><title>child_public_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="297,-77 241,-77 241,-41 297,-41 297,-77"/>
|
||||
<text text-anchor="middle" x="269" y="-54.9" font-family="Sans" font-size="14.00">Public</text>
|
||||
</g>
|
||||
<!-- parent_chain_code->child_public_key -->
|
||||
<g id="edge12" class="edge"><title>parent_chain_code->child_public_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M77.3108,-99.9518C116.311,-91.6199 186.697,-76.5829 230.466,-67.2323"/>
|
||||
<polygon fill="black" stroke="black" points="231.401,-70.6115 240.449,-65.0994 229.939,-63.766 231.401,-70.6115"/>
|
||||
</g>
|
||||
<!-- parent_public_key -->
|
||||
<g id="node4" class="node"><title>parent_public_key</title>
|
||||
<polygon fill="lightgrey" stroke="black" stroke-width="1.75" points="77,-77 21,-77 21,-41 77,-41 77,-77"/>
|
||||
<text text-anchor="middle" x="49" y="-54.9" font-family="Sans" font-size="14.00">Public</text>
|
||||
</g>
|
||||
<!-- parent_public_key->child_chain_code -->
|
||||
<g id="edge8" class="edge"><title>parent_public_key->child_chain_code</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M77.7612,-65.1444C117.01,-73.5295 187.437,-88.5752 230.998,-97.8815"/>
|
||||
<polygon fill="black" stroke="black" points="230.417,-101.336 240.927,-100.003 231.879,-94.4906 230.417,-101.336"/>
|
||||
</g>
|
||||
<!-- parent_public_key->child_public_key -->
|
||||
<g id="edge6" class="edge"><title>parent_public_key->child_public_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M77.7612,-59C116.712,-59 186.369,-59 230.002,-59"/>
|
||||
<polygon fill="black" stroke="black" points="230.232,-62.5001 240.232,-59 230.232,-55.5001 230.232,-62.5001"/>
|
||||
</g>
|
||||
<!-- grandchild_private_key -->
|
||||
<g id="node10" class="node"><title>grandchild_private_key</title>
|
||||
<polygon fill="lightgrey" stroke="black" stroke-width="1.75" points="424,-182 358,-182 358,-146 424,-146 424,-182"/>
|
||||
<text text-anchor="middle" x="391" y="-159.9" font-family="Sans" font-size="14.00">Private</text>
|
||||
</g>
|
||||
<!-- child_private_key->grandchild_private_key -->
|
||||
<g id="edge20" class="edge"><title>child_private_key->grandchild_private_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M312.136,-164C327.197,-164 343.851,-164 357.959,-164"/>
|
||||
<polygon fill="black" stroke="black" points="312.015,-160.5 302.015,-164 312.015,-167.5 312.015,-160.5"/>
|
||||
</g>
|
||||
<!-- child_chain_code->child_private_key -->
|
||||
<g id="edge32" class="edge"><title>child_chain_code->child_private_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M269,-124.125C269,-127.987 269,-131.848 269,-135.71"/>
|
||||
<polygon fill="black" stroke="black" points="265.5,-135.932 269,-145.932 272.5,-135.932 265.5,-135.932"/>
|
||||
</g>
|
||||
<!-- child_chain_code->grandchild_private_key -->
|
||||
<!-- grandchild_chain_code -->
|
||||
<g id="node11" class="node"><title>grandchild_chain_code</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="419,-124 363,-124 363,-88 419,-88 419,-124"/>
|
||||
<text text-anchor="middle" x="391" y="-101.9" font-family="Sans" font-size="14.00">Chain</text>
|
||||
</g>
|
||||
<!-- child_chain_code->grandchild_chain_code -->
|
||||
<g id="edge30" class="edge"><title>child_chain_code->grandchild_chain_code</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M297.296,-106C313.772,-106 334.767,-106 352.706,-106"/>
|
||||
<polygon fill="black" stroke="black" points="352.858,-109.5 362.858,-106 352.858,-102.5 352.858,-109.5"/>
|
||||
</g>
|
||||
<!-- grandchild_public_key -->
|
||||
<g id="node12" class="node"><title>grandchild_public_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="419,-77 363,-77 363,-41 419,-41 419,-77"/>
|
||||
<text text-anchor="middle" x="391" y="-54.9" font-family="Sans" font-size="14.00">Public</text>
|
||||
</g>
|
||||
<!-- child_chain_code->grandchild_public_key -->
|
||||
<g id="edge28" class="edge"><title>child_chain_code->grandchild_public_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M297.296,-95.0991C313.807,-88.7383 334.856,-80.6291 352.821,-73.7084"/>
|
||||
<polygon fill="black" stroke="black" points="354.362,-76.8656 362.435,-70.0046 351.845,-70.3335 354.362,-76.8656"/>
|
||||
</g>
|
||||
<!-- child_public_key->grandchild_chain_code -->
|
||||
<g id="edge22" class="edge"><title>child_public_key->grandchild_chain_code</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M297.604,-70.0194C314.242,-76.4294 335.411,-84.5847 353.387,-91.5099"/>
|
||||
<polygon fill="black" stroke="black" points="352.407,-94.8828 362.996,-95.2117 354.923,-88.3507 352.407,-94.8828"/>
|
||||
</g>
|
||||
<!-- child_public_key->grandchild_public_key -->
|
||||
<g id="edge24" class="edge"><title>child_public_key->grandchild_public_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M297.604,-59C313.853,-59 334.423,-59 352.12,-59"/>
|
||||
<polygon fill="black" stroke="black" points="352.153,-62.5001 362.153,-59 352.153,-55.5001 352.153,-62.5001"/>
|
||||
</g>
|
||||
<!-- greatgrandchild_private_key -->
|
||||
<g id="node14" class="node"><title>greatgrandchild_private_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="551,-182 485,-182 485,-146 551,-146 551,-182"/>
|
||||
<text text-anchor="middle" x="518" y="-159.9" font-family="Sans" font-size="14.00">Private</text>
|
||||
</g>
|
||||
<!-- grandchild_private_key->greatgrandchild_private_key -->
|
||||
<g id="edge34" class="edge"><title>grandchild_private_key->greatgrandchild_private_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M424.036,-164C439.495,-164 458.112,-164 474.682,-164"/>
|
||||
<polygon fill="black" stroke="black" points="474.688,-167.5 484.688,-164 474.688,-160.5 474.688,-167.5"/>
|
||||
</g>
|
||||
<!-- grandchild_chain_code->grandchild_private_key -->
|
||||
<!-- grandchild_chain_code->greatgrandchild_private_key -->
|
||||
<g id="edge40" class="edge"><title>grandchild_chain_code->greatgrandchild_private_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M419.185,-118.872C435.814,-126.466 457.181,-136.224 475.789,-144.723"/>
|
||||
<polygon fill="black" stroke="black" points="474.398,-147.935 484.948,-148.906 477.306,-141.568 474.398,-147.935"/>
|
||||
</g>
|
||||
<!-- greatgrandchild_chain_code -->
|
||||
<g id="node15" class="node"><title>greatgrandchild_chain_code</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="546,-124 490,-124 490,-88 546,-88 546,-124"/>
|
||||
<text text-anchor="middle" x="518" y="-101.9" font-family="Sans" font-size="14.00">Chain</text>
|
||||
</g>
|
||||
<!-- grandchild_chain_code->greatgrandchild_chain_code -->
|
||||
<g id="edge44" class="edge"><title>grandchild_chain_code->greatgrandchild_chain_code</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M419.185,-106C437.025,-106 460.318,-106 479.807,-106"/>
|
||||
<polygon fill="black" stroke="black" points="479.893,-109.5 489.893,-106 479.893,-102.5 479.893,-109.5"/>
|
||||
</g>
|
||||
<!-- greatgrandchild_public_key -->
|
||||
<g id="node16" class="node"><title>greatgrandchild_public_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="546,-77 490,-77 490,-41 546,-41 546,-77"/>
|
||||
<text text-anchor="middle" x="518" y="-54.9" font-family="Sans" font-size="14.00">Public</text>
|
||||
</g>
|
||||
<!-- grandchild_chain_code->greatgrandchild_public_key -->
|
||||
<g id="edge42" class="edge"><title>grandchild_chain_code->greatgrandchild_public_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M419.185,-95.5692C437.065,-88.9525 460.421,-80.3089 479.936,-73.0865"/>
|
||||
<polygon fill="black" stroke="black" points="481.291,-76.3174 489.454,-69.5642 478.861,-69.7526 481.291,-76.3174"/>
|
||||
</g>
|
||||
<!-- grandchild_public_key->greatgrandchild_chain_code -->
|
||||
<g id="edge36" class="edge"><title>grandchild_public_key->greatgrandchild_chain_code</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M419.501,-69.5477C437.394,-76.1695 460.679,-84.7866 480.116,-91.9799"/>
|
||||
<polygon fill="black" stroke="black" points="479.001,-95.2991 489.594,-95.4875 481.43,-88.7342 479.001,-95.2991"/>
|
||||
</g>
|
||||
<!-- grandchild_public_key->greatgrandchild_public_key -->
|
||||
<g id="edge38" class="edge"><title>grandchild_public_key->greatgrandchild_public_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M419.501,-59C437.026,-59 459.722,-59 478.91,-59"/>
|
||||
<polygon fill="black" stroke="black" points="479.154,-62.5001 489.154,-59 479.154,-55.5001 479.154,-62.5001"/>
|
||||
</g>
|
||||
<!-- greatgrandchild_chain_code->greatgrandchild_private_key -->
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 13 KiB |
55
img/dev/en-hd-overview.dot
Normal file
|
@ -0,0 +1,55 @@
|
|||
digraph extended {
|
||||
|
||||
size=6.25;
|
||||
rankdir=LR;
|
||||
penwidth=1.75;
|
||||
node [ fontname="Sans", penwidth = 1.75, shape = "box" ];
|
||||
edge [ fontname="Sans", penwidth = 1.75 ];
|
||||
graph [ fontname="Sans" ]
|
||||
nodesep=0.15;
|
||||
//splines = ortho;
|
||||
ranksep = 0.3;
|
||||
|
||||
subgraph cluster_parent {
|
||||
style = "invis";
|
||||
parent_private_key [ label = "Parent Private Key" ];
|
||||
parent_chain_code [ label = "Parent Chain Code" ];
|
||||
parent_public_key [ label = "Parent Public Key" ];
|
||||
}
|
||||
|
||||
child_private_key [ label = "Child Private Key" ];
|
||||
child_chain_code [ label = "Child Chain Code" ];
|
||||
child_public_key [ label = "Child Public Key" ];
|
||||
|
||||
i_norm [ label = "Index Number" ];
|
||||
hmac [ label = "One-Way Hash", style = "diagonals" ];
|
||||
|
||||
rel1 [ label = "Mathematical\nRelationship", shape = "none" ]
|
||||
rel2 [ label = "Derived\nMathematical\nRelationship", shape = "none" ]
|
||||
|
||||
rel1 -> parent_private_key [ weight = "", dir = "back" ];
|
||||
rel1 -> parent_chain_code [ weight = "", style = "invis" ];
|
||||
rel1 -> parent_public_key [ weight = "" ];
|
||||
|
||||
child_private_key -> rel2 [ ];
|
||||
child_chain_code -> rel2 [ style = "invis" ];
|
||||
child_public_key -> rel2 [ dir = "back" ];
|
||||
|
||||
|
||||
//parent_private_key -> parent_public_key [constraint = false, label = "Math Rel" ];
|
||||
//child_private_key -> child_public_key [constraint = false, minlen = 2];
|
||||
|
||||
parent_private_key -> child_private_key;
|
||||
parent_public_key -> child_public_key;
|
||||
|
||||
parent_public_key -> hmac;
|
||||
parent_chain_code -> hmac;
|
||||
parent_private_key -> hmac [ style = "invis" ];
|
||||
i_norm -> hmac;
|
||||
|
||||
hmac -> child_public_key;
|
||||
hmac -> child_private_key;
|
||||
hmac -> child_chain_code;
|
||||
|
||||
label = " \nNormal Hierarchical Deterministic (HD) Key Derivation (BIP32)"
|
||||
}
|
BIN
img/dev/en-hd-overview.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
135
img/dev/en-hd-overview.svg
Normal file
|
@ -0,0 +1,135 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: extended Pages: 1 -->
|
||||
<svg width="450pt" height="156pt"
|
||||
viewBox="0.00 0.00 450.00 155.87" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.628492 0.628492) rotate(0) translate(4 244)">
|
||||
<title>extended</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-244 713,-244 713,5 -4,5"/>
|
||||
<text text-anchor="middle" x="354" y="-25.4" font-family="Sans" font-size="14.00"> </text>
|
||||
<text text-anchor="middle" x="354" y="-8.4" font-family="Sans" font-size="14.00">Normal Hierarchical Deterministic (HD) Key Derivation (BIP32)</text>
|
||||
<g id="graph2" class="cluster"><title>cluster_parent</title>
|
||||
</g>
|
||||
<!-- parent_private_key -->
|
||||
<g id="node2" class="node"><title>parent_private_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="278,-224 132,-224 132,-188 278,-188 278,-224"/>
|
||||
<text text-anchor="middle" x="205" y="-201.9" font-family="Sans" font-size="14.00">Parent Private Key</text>
|
||||
</g>
|
||||
<!-- child_private_key -->
|
||||
<g id="node5" class="node"><title>child_private_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="576,-224 442,-224 442,-188 576,-188 576,-224"/>
|
||||
<text text-anchor="middle" x="509" y="-201.9" font-family="Sans" font-size="14.00">Child Private Key</text>
|
||||
</g>
|
||||
<!-- parent_private_key->child_private_key -->
|
||||
<g id="edge15" class="edge"><title>parent_private_key->child_private_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M278.202,-206C324.606,-206 384.552,-206 431.72,-206"/>
|
||||
<polygon fill="black" stroke="black" points="431.886,-209.5 441.886,-206 431.886,-202.5 431.886,-209.5"/>
|
||||
</g>
|
||||
<!-- hmac -->
|
||||
<g id="node9" class="node"><title>hmac</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="419,-177 301,-177 301,-141 419,-141 419,-177"/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="313,-177 301,-165 "/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="301,-153 313,-141 "/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="407,-141 419,-153 "/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="419,-165 407,-177 "/>
|
||||
<text text-anchor="middle" x="360" y="-154.9" font-family="Sans" font-size="14.00">One-Way Hash</text>
|
||||
</g>
|
||||
<!-- parent_private_key->hmac -->
|
||||
<!-- parent_chain_code -->
|
||||
<g id="node3" class="node"><title>parent_chain_code</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="278,-177 132,-177 132,-141 278,-141 278,-177"/>
|
||||
<text text-anchor="middle" x="205" y="-154.9" font-family="Sans" font-size="14.00">Parent Chain Code</text>
|
||||
</g>
|
||||
<!-- parent_chain_code->hmac -->
|
||||
<g id="edge21" class="edge"><title>parent_chain_code->hmac</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M278.415,-159C282.322,-159 286.244,-159 290.139,-159"/>
|
||||
<polygon fill="black" stroke="black" points="290.362,-162.5 300.362,-159 290.362,-155.5 290.362,-162.5"/>
|
||||
</g>
|
||||
<!-- parent_public_key -->
|
||||
<g id="node4" class="node"><title>parent_public_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="273,-130 137,-130 137,-94 273,-94 273,-130"/>
|
||||
<text text-anchor="middle" x="205" y="-107.9" font-family="Sans" font-size="14.00">Parent Public Key</text>
|
||||
</g>
|
||||
<!-- child_public_key -->
|
||||
<g id="node7" class="node"><title>child_public_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="571,-130 447,-130 447,-94 571,-94 571,-130"/>
|
||||
<text text-anchor="middle" x="509" y="-107.9" font-family="Sans" font-size="14.00">Child Public Key</text>
|
||||
</g>
|
||||
<!-- parent_public_key->child_public_key -->
|
||||
<g id="edge17" class="edge"><title>parent_public_key->child_public_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M273.603,-112C321.996,-112 386.725,-112 436.057,-112"/>
|
||||
<polygon fill="black" stroke="black" points="436.339,-115.5 446.339,-112 436.339,-108.5 436.339,-115.5"/>
|
||||
</g>
|
||||
<!-- parent_public_key->hmac -->
|
||||
<g id="edge19" class="edge"><title>parent_public_key->hmac</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M269.613,-130.115C275.163,-131.741 280.685,-133.384 286,-135 289.101,-135.943 292.271,-136.92 295.47,-137.916"/>
|
||||
<polygon fill="black" stroke="black" points="294.524,-141.288 305.113,-140.949 296.624,-134.61 294.524,-141.288"/>
|
||||
</g>
|
||||
<!-- rel2 -->
|
||||
<g id="node11" class="node"><title>rel2</title>
|
||||
<text text-anchor="middle" x="653" y="-171.9" font-family="Sans" font-size="14.00">Derived</text>
|
||||
<text text-anchor="middle" x="653" y="-154.9" font-family="Sans" font-size="14.00">Mathematical</text>
|
||||
<text text-anchor="middle" x="653" y="-137.9" font-family="Sans" font-size="14.00">Relationship</text>
|
||||
</g>
|
||||
<!-- child_private_key->rel2 -->
|
||||
<g id="edge9" class="edge"><title>child_private_key->rel2</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M564.262,-187.963C572.044,-185.423 580.101,-182.793 588.044,-180.201"/>
|
||||
<polygon fill="black" stroke="black" points="589.227,-183.497 597.648,-177.066 587.055,-176.842 589.227,-183.497"/>
|
||||
</g>
|
||||
<!-- child_chain_code -->
|
||||
<g id="node6" class="node"><title>child_chain_code</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="576,-177 442,-177 442,-141 576,-141 576,-177"/>
|
||||
<text text-anchor="middle" x="509" y="-154.9" font-family="Sans" font-size="14.00">Child Chain Code</text>
|
||||
</g>
|
||||
<!-- child_chain_code->rel2 -->
|
||||
<!-- child_public_key->rel2 -->
|
||||
<g id="edge13" class="edge"><title>child_public_key->rel2</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M573.865,-133.171C581.806,-135.763 589.864,-138.393 597.648,-140.934"/>
|
||||
<polygon fill="black" stroke="black" points="574.855,-129.813 564.262,-130.037 572.683,-136.467 574.855,-129.813"/>
|
||||
</g>
|
||||
<!-- i_norm -->
|
||||
<g id="node8" class="node"><title>i_norm</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="262,-78 148,-78 148,-42 262,-42 262,-78"/>
|
||||
<text text-anchor="middle" x="205" y="-55.9" font-family="Sans" font-size="14.00">Index Number</text>
|
||||
</g>
|
||||
<!-- i_norm->hmac -->
|
||||
<g id="edge25" class="edge"><title>i_norm->hmac</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M262.317,-73.0124C270.556,-76.0017 278.704,-79.6258 286,-84 307.108,-96.6552 326.469,-116.725 340.089,-132.92"/>
|
||||
<polygon fill="black" stroke="black" points="337.631,-135.444 346.667,-140.976 343.053,-131.016 337.631,-135.444"/>
|
||||
</g>
|
||||
<!-- hmac->child_private_key -->
|
||||
<g id="edge29" class="edge"><title>hmac->child_private_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M417.181,-177.037C425.321,-179.605 433.753,-182.265 442.059,-184.884"/>
|
||||
<polygon fill="black" stroke="black" points="441.136,-188.263 451.726,-187.934 443.242,-181.587 441.136,-188.263"/>
|
||||
</g>
|
||||
<!-- hmac->child_chain_code -->
|
||||
<g id="edge31" class="edge"><title>hmac->child_chain_code</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M419.745,-159C423.73,-159 427.774,-159 431.828,-159"/>
|
||||
<polygon fill="black" stroke="black" points="431.9,-162.5 441.9,-159 431.9,-155.5 431.9,-162.5"/>
|
||||
</g>
|
||||
<!-- hmac->child_public_key -->
|
||||
<g id="edge27" class="edge"><title>hmac->child_public_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M417.181,-140.963C425.321,-138.395 433.753,-135.735 442.059,-133.116"/>
|
||||
<polygon fill="black" stroke="black" points="443.242,-136.413 451.726,-130.066 441.136,-129.737 443.242,-136.413"/>
|
||||
</g>
|
||||
<!-- rel1 -->
|
||||
<g id="node10" class="node"><title>rel1</title>
|
||||
<text text-anchor="middle" x="55" y="-163.4" font-family="Sans" font-size="14.00">Mathematical</text>
|
||||
<text text-anchor="middle" x="55" y="-146.4" font-family="Sans" font-size="14.00">Relationship</text>
|
||||
</g>
|
||||
<!-- rel1->parent_private_key -->
|
||||
<g id="edge3" class="edge"><title>rel1->parent_private_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M120.192,-181.787C121.471,-182.198 122.741,-182.603 124,-183 129.158,-184.628 134.517,-186.266 139.911,-187.876"/>
|
||||
<polygon fill="black" stroke="black" points="120.86,-178.324 110.267,-178.54 118.683,-184.976 120.86,-178.324"/>
|
||||
</g>
|
||||
<!-- rel1->parent_chain_code -->
|
||||
<!-- rel1->parent_public_key -->
|
||||
<g id="edge7" class="edge"><title>rel1->parent_public_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M110.267,-139.46C114.902,-137.918 119.525,-136.412 124,-135 125.934,-134.39 127.897,-133.778 129.879,-133.166"/>
|
||||
<polygon fill="black" stroke="black" points="131.358,-136.375 139.911,-130.124 129.326,-129.677 131.358,-136.375"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 8.7 KiB |
65
img/dev/en-hd-private-parent-to-private-child.dot
Normal file
|
@ -0,0 +1,65 @@
|
|||
digraph extended {
|
||||
|
||||
size=6.25;
|
||||
rankdir=LR;
|
||||
penwidth=1.75;
|
||||
node [ fontname="Sans", penwidth = 1.75, shape = "box" ];
|
||||
edge [ fontname="Sans", penwidth = 1.75 ];
|
||||
graph [ fontname="Sans" ];
|
||||
nodesep=0.05;
|
||||
//splines = ortho;
|
||||
ranksep = 1.0;
|
||||
subgraph cluster_hard {
|
||||
style = "invis";
|
||||
|
||||
subgraph cluster_h_parent_extended_key {
|
||||
h_parent_private_key [ label = "Parent Private Key" ];
|
||||
h_parent_chain_code [ label = "Parent Chain Code" ];
|
||||
}
|
||||
|
||||
subgraph cluster_child_extended_key_else {
|
||||
child_private_key_hard [ label = "Child Private Key" ];
|
||||
child_chain_code_hard [ label = "Child Chain Code" ];
|
||||
}
|
||||
|
||||
hmac_hard [ style = "diagonals", label = "One-Way\nHash" ];
|
||||
i_hard [ label = "Index ≥0x80000000" ];
|
||||
|
||||
h_parent_chain_code -> hmac_hard;
|
||||
h_parent_private_key -> hmac_hard;
|
||||
|
||||
i_hard -> hmac_hard;
|
||||
|
||||
hmac_hard -> child_private_key_hard;
|
||||
hmac_hard -> child_chain_code_hard;
|
||||
h_parent_private_key -> child_private_key_hard;
|
||||
}
|
||||
|
||||
|
||||
subgraph cluster_norm {
|
||||
style = "invis"
|
||||
|
||||
subgraph cluster_n_parent_extended_key {
|
||||
n_parent_private_key [ label = "Parent Private Key" ];
|
||||
n_parent_chain_code [ label = "Parent Chain Code" ];
|
||||
n_parent_public_key [ label = "Parent Public Key" ];
|
||||
}
|
||||
|
||||
subgraph cluster_child_extended_key_norm {
|
||||
child_private_key_norm [ label = "Child Private Key" ];
|
||||
child_chain_code_norm [ label = "Child Chain Code" ];
|
||||
}
|
||||
hmac_norm [ style = "diagonals", label = "One-Way\nHash" ];
|
||||
i_norm [ label = "Index <0x80000000" ];
|
||||
|
||||
n_parent_chain_code -> hmac_norm;
|
||||
n_parent_public_key -> hmac_norm;
|
||||
i_norm -> hmac_norm;
|
||||
hmac_norm -> child_private_key_norm;
|
||||
hmac_norm -> child_chain_code_norm;
|
||||
n_parent_private_key -> child_private_key_norm [weight = 5];
|
||||
}
|
||||
|
||||
label = "Normal (Top) And Hardened (Bottom) Child Private Key Derivation";
|
||||
|
||||
}
|
BIN
img/dev/en-hd-private-parent-to-private-child.png
Normal file
After Width: | Height: | Size: 11 KiB |
161
img/dev/en-hd-private-parent-to-private-child.svg
Normal file
|
@ -0,0 +1,161 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: extended Pages: 1 -->
|
||||
<svg width="450pt" height="318pt"
|
||||
viewBox="0.00 0.00 450.00 317.69" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.792254 0.792254) rotate(0) translate(4 397)">
|
||||
<title>extended</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-397 565,-397 565,5 -4,5"/>
|
||||
<text text-anchor="middle" x="280" y="-8.4" font-family="Sans" font-size="14.00">Normal (Top) And Hardened (Bottom) Child Private Key Derivation</text>
|
||||
<g id="graph2" class="cluster"><title>cluster_hard</title>
|
||||
</g>
|
||||
<g id="graph3" class="cluster"><title>cluster_h_parent_extended_key</title>
|
||||
</g>
|
||||
<g id="graph4" class="cluster"><title>cluster_child_extended_key_else</title>
|
||||
</g>
|
||||
<g id="graph5" class="cluster"><title>cluster_norm</title>
|
||||
</g>
|
||||
<g id="graph6" class="cluster"><title>cluster_n_parent_extended_key</title>
|
||||
</g>
|
||||
<g id="graph7" class="cluster"><title>cluster_child_extended_key_norm</title>
|
||||
</g>
|
||||
<!-- h_parent_private_key -->
|
||||
<g id="node3" class="node"><title>h_parent_private_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="170,-169 24,-169 24,-133 170,-133 170,-169"/>
|
||||
<text text-anchor="middle" x="97" y="-146.9" font-family="Sans" font-size="14.00">Parent Private Key</text>
|
||||
</g>
|
||||
<!-- child_private_key_hard -->
|
||||
<g id="node6" class="node"><title>child_private_key_hard</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="536,-169 402,-169 402,-133 536,-133 536,-169"/>
|
||||
<text text-anchor="middle" x="469" y="-146.9" font-family="Sans" font-size="14.00">Child Private Key</text>
|
||||
</g>
|
||||
<!-- h_parent_private_key->child_private_key_hard -->
|
||||
<g id="edge15" class="edge"><title>h_parent_private_key->child_private_key_hard</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M170.051,-151C233.921,-151 326.389,-151 391.534,-151"/>
|
||||
<polygon fill="black" stroke="black" points="391.746,-154.5 401.746,-151 391.746,-147.5 391.746,-154.5"/>
|
||||
</g>
|
||||
<!-- hmac_hard -->
|
||||
<g id="node8" class="node"><title>hmac_hard</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="330,-132 250,-132 250,-90 330,-90 330,-132"/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="262,-132 250,-120 "/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="250,-102 262,-90 "/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="318,-90 330,-102 "/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="330,-120 318,-132 "/>
|
||||
<text text-anchor="middle" x="290" y="-115.4" font-family="Sans" font-size="14.00">One-Way</text>
|
||||
<text text-anchor="middle" x="290" y="-98.4" font-family="Sans" font-size="14.00">Hash</text>
|
||||
</g>
|
||||
<!-- h_parent_private_key->hmac_hard -->
|
||||
<g id="edge7" class="edge"><title>h_parent_private_key->hmac_hard</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M170.24,-135.821C193.425,-131.015 218.516,-125.815 239.712,-121.422"/>
|
||||
<polygon fill="black" stroke="black" points="240.697,-124.793 249.779,-119.336 239.277,-117.938 240.697,-124.793"/>
|
||||
</g>
|
||||
<!-- h_parent_chain_code -->
|
||||
<g id="node4" class="node"><title>h_parent_chain_code</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="170,-129 24,-129 24,-93 170,-93 170,-129"/>
|
||||
<text text-anchor="middle" x="97" y="-106.9" font-family="Sans" font-size="14.00">Parent Chain Code</text>
|
||||
</g>
|
||||
<!-- h_parent_chain_code->hmac_hard -->
|
||||
<g id="edge5" class="edge"><title>h_parent_chain_code->hmac_hard</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M170.24,-111C193.425,-111 218.516,-111 239.712,-111"/>
|
||||
<polygon fill="black" stroke="black" points="239.779,-114.5 249.779,-111 239.779,-107.5 239.779,-114.5"/>
|
||||
</g>
|
||||
<!-- child_chain_code_hard -->
|
||||
<g id="node7" class="node"><title>child_chain_code_hard</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="536,-129 402,-129 402,-93 536,-93 536,-129"/>
|
||||
<text text-anchor="middle" x="469" y="-106.9" font-family="Sans" font-size="14.00">Child Chain Code</text>
|
||||
</g>
|
||||
<!-- hmac_hard->child_private_key_hard -->
|
||||
<g id="edge11" class="edge"><title>hmac_hard->child_private_key_hard</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M330.171,-119.977C348.413,-124.053 370.63,-129.018 391.896,-133.77"/>
|
||||
<polygon fill="black" stroke="black" points="391.386,-137.242 401.908,-136.007 392.912,-130.411 391.386,-137.242"/>
|
||||
</g>
|
||||
<!-- hmac_hard->child_chain_code_hard -->
|
||||
<g id="edge13" class="edge"><title>hmac_hard->child_chain_code_hard</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M330.171,-111C348.413,-111 370.63,-111 391.896,-111"/>
|
||||
<polygon fill="black" stroke="black" points="391.908,-114.5 401.908,-111 391.908,-107.5 391.908,-114.5"/>
|
||||
</g>
|
||||
<!-- i_hard -->
|
||||
<g id="node9" class="node"><title>i_hard</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="177,-77 17,-77 17,-41 177,-41 177,-77"/>
|
||||
<text text-anchor="middle" x="97" y="-54.9" font-family="Sans" font-size="14.00">Index ≥0x80000000</text>
|
||||
</g>
|
||||
<!-- i_hard->hmac_hard -->
|
||||
<g id="edge9" class="edge"><title>i_hard->hmac_hard</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M163.96,-77.0411C188.903,-83.7614 216.759,-91.2668 239.928,-97.5091"/>
|
||||
<polygon fill="black" stroke="black" points="239.315,-100.969 249.881,-100.191 241.136,-94.2097 239.315,-100.969"/>
|
||||
</g>
|
||||
<!-- n_parent_private_key -->
|
||||
<g id="node18" class="node"><title>n_parent_private_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="170,-369 24,-369 24,-333 170,-333 170,-369"/>
|
||||
<text text-anchor="middle" x="97" y="-346.9" font-family="Sans" font-size="14.00">Parent Private Key</text>
|
||||
</g>
|
||||
<!-- child_private_key_norm -->
|
||||
<g id="node22" class="node"><title>child_private_key_norm</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="536,-369 402,-369 402,-333 536,-333 536,-369"/>
|
||||
<text text-anchor="middle" x="469" y="-346.9" font-family="Sans" font-size="14.00">Child Private Key</text>
|
||||
</g>
|
||||
<!-- n_parent_private_key->child_private_key_norm -->
|
||||
<g id="edge30" class="edge"><title>n_parent_private_key->child_private_key_norm</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M170.051,-351C233.921,-351 326.389,-351 391.534,-351"/>
|
||||
<polygon fill="black" stroke="black" points="391.746,-354.5 401.746,-351 391.746,-347.5 391.746,-354.5"/>
|
||||
</g>
|
||||
<!-- n_parent_chain_code -->
|
||||
<g id="node19" class="node"><title>n_parent_chain_code</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="170,-329 24,-329 24,-293 170,-293 170,-329"/>
|
||||
<text text-anchor="middle" x="97" y="-306.9" font-family="Sans" font-size="14.00">Parent Chain Code</text>
|
||||
</g>
|
||||
<!-- hmac_norm -->
|
||||
<g id="node24" class="node"><title>hmac_norm</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="330,-332 250,-332 250,-290 330,-290 330,-332"/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="262,-332 250,-320 "/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="250,-302 262,-290 "/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="318,-290 330,-302 "/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="330,-320 318,-332 "/>
|
||||
<text text-anchor="middle" x="290" y="-315.4" font-family="Sans" font-size="14.00">One-Way</text>
|
||||
<text text-anchor="middle" x="290" y="-298.4" font-family="Sans" font-size="14.00">Hash</text>
|
||||
</g>
|
||||
<!-- n_parent_chain_code->hmac_norm -->
|
||||
<g id="edge20" class="edge"><title>n_parent_chain_code->hmac_norm</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M170.24,-311C193.425,-311 218.516,-311 239.712,-311"/>
|
||||
<polygon fill="black" stroke="black" points="239.779,-314.5 249.779,-311 239.779,-307.5 239.779,-314.5"/>
|
||||
</g>
|
||||
<!-- n_parent_public_key -->
|
||||
<g id="node20" class="node"><title>n_parent_public_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="165,-289 29,-289 29,-253 165,-253 165,-289"/>
|
||||
<text text-anchor="middle" x="97" y="-266.9" font-family="Sans" font-size="14.00">Parent Public Key</text>
|
||||
</g>
|
||||
<!-- n_parent_public_key->hmac_norm -->
|
||||
<g id="edge22" class="edge"><title>n_parent_public_key->hmac_norm</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M165.588,-285.215C190.017,-290.278 217.057,-295.882 239.671,-300.569"/>
|
||||
<polygon fill="black" stroke="black" points="239.222,-304.05 249.724,-302.653 240.643,-297.196 239.222,-304.05"/>
|
||||
</g>
|
||||
<!-- child_chain_code_norm -->
|
||||
<g id="node23" class="node"><title>child_chain_code_norm</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="536,-329 402,-329 402,-293 536,-293 536,-329"/>
|
||||
<text text-anchor="middle" x="469" y="-306.9" font-family="Sans" font-size="14.00">Child Chain Code</text>
|
||||
</g>
|
||||
<!-- hmac_norm->child_private_key_norm -->
|
||||
<g id="edge26" class="edge"><title>hmac_norm->child_private_key_norm</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M330.171,-319.977C348.413,-324.053 370.63,-329.018 391.896,-333.77"/>
|
||||
<polygon fill="black" stroke="black" points="391.386,-337.242 401.908,-336.007 392.912,-330.411 391.386,-337.242"/>
|
||||
</g>
|
||||
<!-- hmac_norm->child_chain_code_norm -->
|
||||
<g id="edge28" class="edge"><title>hmac_norm->child_chain_code_norm</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M330.171,-311C348.413,-311 370.63,-311 391.896,-311"/>
|
||||
<polygon fill="black" stroke="black" points="391.908,-314.5 401.908,-311 391.908,-307.5 391.908,-314.5"/>
|
||||
</g>
|
||||
<!-- i_norm -->
|
||||
<g id="node25" class="node"><title>i_norm</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="177,-237 17,-237 17,-201 177,-201 177,-237"/>
|
||||
<text text-anchor="middle" x="97" y="-214.9" font-family="Sans" font-size="14.00">Index <0x80000000</text>
|
||||
</g>
|
||||
<!-- i_norm->hmac_norm -->
|
||||
<g id="edge24" class="edge"><title>i_norm->hmac_norm</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M160.77,-237.084C166.665,-239.233 172.489,-241.544 178,-244 203.171,-255.218 229.705,-270.9 250.626,-284.272"/>
|
||||
<polygon fill="black" stroke="black" points="248.931,-287.344 259.228,-289.841 252.736,-281.468 248.931,-287.344"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 10 KiB |
78
img/dev/en-hd-public-child-from-public-or-private-parent.dot
Normal file
|
@ -0,0 +1,78 @@
|
|||
digraph extended {
|
||||
|
||||
size=6.25;
|
||||
rankdir=LR;
|
||||
penwidth=1.75;
|
||||
node [ penwidth = 1.75, shape = "box" ];
|
||||
edge [ penwidth = 1.75 ];
|
||||
nodesep=0.05;
|
||||
splines = ortho;
|
||||
ranksep = 0.30;
|
||||
|
||||
subgraph cluster_from_private {
|
||||
//style = "invis"
|
||||
//label = "Creation Of Normal Child Extended Keys (Key + Chain Code)\nFrom Parent Extended Keys"
|
||||
|
||||
subgraph cluster_fp_n_parent_extended_key {
|
||||
fp_n_parent_private_key [ label = "Parent Private Key" ];
|
||||
fp_n_parent_chain_code [ label = "Parent Chain Code" ];
|
||||
}
|
||||
|
||||
subgraph cluster_fp_child_extended_key_norm {
|
||||
fp_child_private_key_norm [ label = "Child Private Key" ];
|
||||
fp_child_chain_code_norm [ label = "Child Chain Code" ];
|
||||
}
|
||||
subgraph cluster_fp_child_extended_key_pub {
|
||||
fp_n_child_public_key_norm [ label = "Child Public Key" ];
|
||||
fp_child_chain_code_norm1 [ label = "Child Chain Code" ];
|
||||
}
|
||||
|
||||
fp_hmac_norm [ style = "diagonals", label = "One-Way\nHash" ];
|
||||
fp_i_norm [ label = "i (Normal)" ];
|
||||
|
||||
fp_n_parent_chain_code -> fp_hmac_norm;
|
||||
fp_i_norm -> fp_hmac_norm;
|
||||
fp_hmac_norm -> fp_child_private_key_norm;
|
||||
fp_hmac_norm -> fp_child_chain_code_norm;
|
||||
fp_n_parent_private_key -> fp_child_private_key_norm;
|
||||
|
||||
fp_child_private_key_norm -> fp_n_child_public_key_norm;
|
||||
fp_child_chain_code_norm -> fp_child_chain_code_norm1;
|
||||
|
||||
label = "From Parent Extended Private Key"
|
||||
}
|
||||
|
||||
equiv [ label = "Equivalent For\nCorresponding\nExtended Keys\nAnd Same\nValue Of i", shape = "none" ];
|
||||
equiv -> fp_n_child_public_key_norm [ constraint = false, style = "dashed", dir = "back" ];
|
||||
child_public_key_hard -> equiv [ style = "dashed" ];
|
||||
|
||||
subgraph cluster_from_public {
|
||||
|
||||
subgraph cluster_h_parent_extended_key {
|
||||
h_parent_public_key [ label = "Parent Public Key" ];
|
||||
h_parent_chain_code [ label = "Parent Chain Code" ];
|
||||
}
|
||||
|
||||
subgraph cluster_child_extended_key_else {
|
||||
child_public_key_hard [ label = "Child Public Key" ];
|
||||
child_chain_code_hard [ label = "Child Chain Code" ];
|
||||
}
|
||||
|
||||
hmac_hard [ style = "diagonals", label = "One-Way\nHash" ];
|
||||
i_hard [ label = "i (Normal)" ];
|
||||
|
||||
h_parent_chain_code -> hmac_hard;
|
||||
|
||||
i_hard -> hmac_hard;
|
||||
|
||||
hmac_hard -> child_public_key_hard;
|
||||
hmac_hard -> child_chain_code_hard;
|
||||
h_parent_public_key -> child_public_key_hard;
|
||||
|
||||
label = "From Parent Extended Public Key"
|
||||
}
|
||||
|
||||
|
||||
label = "Creation Of Equivalent Child Extended Public Keys From\nEither Private Or Public Parent Keys"
|
||||
|
||||
}
|
BIN
img/dev/en-hd-public-child-from-public-or-private-parent.png
Normal file
After Width: | Height: | Size: 11 KiB |
196
img/dev/en-hd-public-child-from-public-or-private-parent.svg
Normal file
|
@ -0,0 +1,196 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: extended Pages: 1 -->
|
||||
<svg width="450pt" height="308pt"
|
||||
viewBox="0.00 0.00 450.00 307.67" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.71885 0.71885) rotate(0) translate(4 424)">
|
||||
<title>extended</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-424 623,-424 623,5 -4,5"/>
|
||||
<text text-anchor="middle" x="309" y="-25.4" font-family="Sans" font-size="14.00">Creation Of Equivalent Child Extended Public Keys From</text>
|
||||
<text text-anchor="middle" x="309" y="-8.4" font-family="Sans" font-size="14.00">Either Private Or Public Parent Keys</text>
|
||||
<g id="graph2" class="cluster"><title>cluster_from_private</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="8,-50 8,-227 610,-227 610,-50 8,-50"/>
|
||||
<text text-anchor="middle" x="309" y="-210.4" font-family="Sans" font-size="14.00">From Parent Extended Private Key</text>
|
||||
</g>
|
||||
<g id="graph3" class="cluster"><title>cluster_fp_n_parent_extended_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="16,-102 16,-194 178,-194 178,-102 16,-102"/>
|
||||
</g>
|
||||
<g id="graph4" class="cluster"><title>cluster_fp_child_extended_key_norm</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="286,-102 286,-194 436,-194 436,-102 286,-102"/>
|
||||
</g>
|
||||
<g id="graph5" class="cluster"><title>cluster_fp_child_extended_key_pub</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="452,-102 452,-194 602,-194 602,-102 452,-102"/>
|
||||
</g>
|
||||
<g id="graph6" class="cluster"><title>cluster_from_public</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="8,-235 8,-412 444,-412 444,-235 8,-235"/>
|
||||
<text text-anchor="middle" x="226" y="-395.4" font-family="Sans" font-size="14.00">From Parent Extended Public Key</text>
|
||||
</g>
|
||||
<g id="graph7" class="cluster"><title>cluster_h_parent_extended_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="16,-287 16,-379 178,-379 178,-287 16,-287"/>
|
||||
</g>
|
||||
<g id="graph8" class="cluster"><title>cluster_child_extended_key_else</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="286,-287 286,-379 436,-379 436,-287 286,-287"/>
|
||||
</g>
|
||||
<!-- fp_n_parent_private_key -->
|
||||
<g id="node3" class="node"><title>fp_n_parent_private_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="170,-186 24,-186 24,-150 170,-150 170,-186"/>
|
||||
<text text-anchor="middle" x="97" y="-163.9" font-family="Sans" font-size="14.00">Parent Private Key</text>
|
||||
</g>
|
||||
<!-- fp_child_private_key_norm -->
|
||||
<g id="node6" class="node"><title>fp_child_private_key_norm</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="428,-186 294,-186 294,-150 428,-150 428,-186"/>
|
||||
<text text-anchor="middle" x="361" y="-163.9" font-family="Sans" font-size="14.00">Child Private Key</text>
|
||||
</g>
|
||||
<!-- fp_n_parent_private_key->fp_child_private_key_norm -->
|
||||
<g id="edge14" class="edge"><title>fp_n_parent_private_key->fp_child_private_key_norm</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M170.188,-168C205.326,-168 247.454,-168 283.176,-168"/>
|
||||
<polygon fill="black" stroke="black" points="283.555,-171.5 293.555,-168 283.555,-164.5 283.555,-171.5"/>
|
||||
</g>
|
||||
<!-- fp_n_parent_chain_code -->
|
||||
<g id="node4" class="node"><title>fp_n_parent_chain_code</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="170,-146 24,-146 24,-110 170,-110 170,-146"/>
|
||||
<text text-anchor="middle" x="97" y="-123.9" font-family="Sans" font-size="14.00">Parent Chain Code</text>
|
||||
</g>
|
||||
<!-- fp_hmac_norm -->
|
||||
<g id="node11" class="node"><title>fp_hmac_norm</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="272,-149 192,-149 192,-107 272,-107 272,-149"/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="204,-149 192,-137 "/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="192,-119 204,-107 "/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="260,-107 272,-119 "/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="272,-137 260,-149 "/>
|
||||
<text text-anchor="middle" x="232" y="-132.4" font-family="Sans" font-size="14.00">One-Way</text>
|
||||
<text text-anchor="middle" x="232" y="-115.4" font-family="Sans" font-size="14.00">Hash</text>
|
||||
</g>
|
||||
<!-- fp_n_parent_chain_code->fp_hmac_norm -->
|
||||
<g id="edge6" class="edge"><title>fp_n_parent_chain_code->fp_hmac_norm</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M170.032,-128C173.876,-128 177.696,-128 181.441,-128"/>
|
||||
<polygon fill="black" stroke="black" points="181.758,-131.5 191.758,-128 181.758,-124.5 181.758,-131.5"/>
|
||||
</g>
|
||||
<!-- fp_n_child_public_key_norm -->
|
||||
<g id="node9" class="node"><title>fp_n_child_public_key_norm</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="589,-186 465,-186 465,-150 589,-150 589,-186"/>
|
||||
<text text-anchor="middle" x="527" y="-163.9" font-family="Sans" font-size="14.00">Child Public Key</text>
|
||||
</g>
|
||||
<!-- fp_child_private_key_norm->fp_n_child_public_key_norm -->
|
||||
<g id="edge16" class="edge"><title>fp_child_private_key_norm->fp_n_child_public_key_norm</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M428.04,-168C436.642,-168 445.481,-168 454.17,-168"/>
|
||||
<polygon fill="black" stroke="black" points="454.277,-171.5 464.277,-168 454.277,-164.5 454.277,-171.5"/>
|
||||
</g>
|
||||
<!-- fp_child_chain_code_norm -->
|
||||
<g id="node7" class="node"><title>fp_child_chain_code_norm</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="428,-146 294,-146 294,-110 428,-110 428,-146"/>
|
||||
<text text-anchor="middle" x="361" y="-123.9" font-family="Sans" font-size="14.00">Child Chain Code</text>
|
||||
</g>
|
||||
<!-- fp_child_chain_code_norm1 -->
|
||||
<g id="node10" class="node"><title>fp_child_chain_code_norm1</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="594,-146 460,-146 460,-110 594,-110 594,-146"/>
|
||||
<text text-anchor="middle" x="527" y="-123.9" font-family="Sans" font-size="14.00">Child Chain Code</text>
|
||||
</g>
|
||||
<!-- fp_child_chain_code_norm->fp_child_chain_code_norm1 -->
|
||||
<g id="edge18" class="edge"><title>fp_child_chain_code_norm->fp_child_chain_code_norm1</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M428.04,-128C435.196,-128 442.516,-128 449.777,-128"/>
|
||||
<polygon fill="black" stroke="black" points="449.98,-131.5 459.98,-128 449.98,-124.5 449.98,-131.5"/>
|
||||
</g>
|
||||
<!-- fp_hmac_norm->fp_child_private_key_norm -->
|
||||
<g id="edge10" class="edge"><title>fp_hmac_norm->fp_child_private_key_norm</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M272.094,-141.365C280.047,-144.016 286,-146 286,-146 286,-146 287.362,-146.4 289.719,-147.091"/>
|
||||
<polygon fill="black" stroke="black" points="288.828,-150.477 299.408,-149.933 290.798,-143.76 288.828,-150.477"/>
|
||||
</g>
|
||||
<!-- fp_hmac_norm->fp_child_chain_code_norm -->
|
||||
<g id="edge12" class="edge"><title>fp_hmac_norm->fp_child_chain_code_norm</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M272.109,-128C275.911,-128 279.846,-128 283.848,-128"/>
|
||||
<polygon fill="black" stroke="black" points="283.899,-131.5 293.899,-128 283.899,-124.5 283.899,-131.5"/>
|
||||
</g>
|
||||
<!-- fp_i_norm -->
|
||||
<g id="node12" class="node"><title>fp_i_norm</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="139,-94 55,-94 55,-58 139,-58 139,-94"/>
|
||||
<text text-anchor="middle" x="97" y="-71.9" font-family="Sans" font-size="14.00">i (Normal)</text>
|
||||
</g>
|
||||
<!-- fp_i_norm->fp_hmac_norm -->
|
||||
<g id="edge8" class="edge"><title>fp_i_norm->fp_hmac_norm</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M139.872,-89.232C159.301,-95.2287 178,-101 178,-101 178,-101 179.884,-101.942 182.947,-103.474"/>
|
||||
<polygon fill="black" stroke="black" points="181.397,-106.611 191.906,-107.953 184.527,-100.35 181.397,-106.611"/>
|
||||
</g>
|
||||
<!-- equiv -->
|
||||
<g id="node20" class="node"><title>equiv</title>
|
||||
<text text-anchor="middle" x="527" y="-382.9" font-family="Sans" font-size="14.00">Equivalent For</text>
|
||||
<text text-anchor="middle" x="527" y="-365.9" font-family="Sans" font-size="14.00">Corresponding</text>
|
||||
<text text-anchor="middle" x="527" y="-348.9" font-family="Sans" font-size="14.00">Extended Keys</text>
|
||||
<text text-anchor="middle" x="527" y="-331.9" font-family="Sans" font-size="14.00">And Same</text>
|
||||
<text text-anchor="middle" x="527" y="-314.9" font-family="Sans" font-size="14.00">Value Of i</text>
|
||||
</g>
|
||||
<!-- equiv->fp_n_child_public_key_norm -->
|
||||
<g id="edge20" class="edge"><title>equiv->fp_n_child_public_key_norm</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="5,2" d="M527,-296.86C527,-293.434 527,-291.333 527,-291.333 527,-291.333 527,-229.667 527,-229.667 527,-229.667 527,-204.359 527,-186.169"/>
|
||||
<polygon fill="black" stroke="black" points="523.5,-296.894 527,-306.894 530.5,-296.894 523.5,-296.894"/>
|
||||
</g>
|
||||
<!-- child_public_key_hard -->
|
||||
<g id="node22" class="node"><title>child_public_key_hard</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="423,-371 299,-371 299,-335 423,-335 423,-371"/>
|
||||
<text text-anchor="middle" x="361" y="-348.9" font-family="Sans" font-size="14.00">Child Public Key</text>
|
||||
</g>
|
||||
<!-- child_public_key_hard->equiv -->
|
||||
<g id="edge22" class="edge"><title>child_public_key_hard->equiv</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="5,2" d="M423.757,-353C434.864,-353 446.486,-353 457.759,-353"/>
|
||||
<polygon fill="black" stroke="black" points="457.989,-356.5 467.989,-353 457.989,-349.5 457.989,-356.5"/>
|
||||
</g>
|
||||
<!-- h_parent_public_key -->
|
||||
<g id="node26" class="node"><title>h_parent_public_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="165,-371 29,-371 29,-335 165,-335 165,-371"/>
|
||||
<text text-anchor="middle" x="97" y="-348.9" font-family="Sans" font-size="14.00">Parent Public Key</text>
|
||||
</g>
|
||||
<!-- h_parent_public_key->child_public_key_hard -->
|
||||
<g id="edge35" class="edge"><title>h_parent_public_key->child_public_key_hard</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M165.674,-353C203.259,-353 249.822,-353 288.057,-353"/>
|
||||
<polygon fill="black" stroke="black" points="288.096,-356.5 298.096,-353 288.096,-349.5 288.096,-356.5"/>
|
||||
</g>
|
||||
<!-- h_parent_chain_code -->
|
||||
<g id="node27" class="node"><title>h_parent_chain_code</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="170,-331 24,-331 24,-295 170,-295 170,-331"/>
|
||||
<text text-anchor="middle" x="97" y="-308.9" font-family="Sans" font-size="14.00">Parent Chain Code</text>
|
||||
</g>
|
||||
<!-- hmac_hard -->
|
||||
<g id="node30" class="node"><title>hmac_hard</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="272,-334 192,-334 192,-292 272,-292 272,-334"/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="204,-334 192,-322 "/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="192,-304 204,-292 "/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="260,-292 272,-304 "/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="272,-322 260,-334 "/>
|
||||
<text text-anchor="middle" x="232" y="-317.4" font-family="Sans" font-size="14.00">One-Way</text>
|
||||
<text text-anchor="middle" x="232" y="-300.4" font-family="Sans" font-size="14.00">Hash</text>
|
||||
</g>
|
||||
<!-- h_parent_chain_code->hmac_hard -->
|
||||
<g id="edge27" class="edge"><title>h_parent_chain_code->hmac_hard</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M170.032,-313C173.876,-313 177.696,-313 181.441,-313"/>
|
||||
<polygon fill="black" stroke="black" points="181.758,-316.5 191.758,-313 181.758,-309.5 181.758,-316.5"/>
|
||||
</g>
|
||||
<!-- child_chain_code_hard -->
|
||||
<g id="node29" class="node"><title>child_chain_code_hard</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="428,-331 294,-331 294,-295 428,-295 428,-331"/>
|
||||
<text text-anchor="middle" x="361" y="-308.9" font-family="Sans" font-size="14.00">Child Chain Code</text>
|
||||
</g>
|
||||
<!-- hmac_hard->child_public_key_hard -->
|
||||
<g id="edge31" class="edge"><title>hmac_hard->child_public_key_hard</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M272.094,-326.365C280.047,-329.016 286,-331 286,-331 286,-331 287.362,-331.4 289.719,-332.091"/>
|
||||
<polygon fill="black" stroke="black" points="288.828,-335.477 299.408,-334.933 290.798,-328.76 288.828,-335.477"/>
|
||||
</g>
|
||||
<!-- hmac_hard->child_chain_code_hard -->
|
||||
<g id="edge33" class="edge"><title>hmac_hard->child_chain_code_hard</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M272.109,-313C275.911,-313 279.846,-313 283.848,-313"/>
|
||||
<polygon fill="black" stroke="black" points="283.899,-316.5 293.899,-313 283.899,-309.5 283.899,-316.5"/>
|
||||
</g>
|
||||
<!-- i_hard -->
|
||||
<g id="node31" class="node"><title>i_hard</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="139,-279 55,-279 55,-243 139,-243 139,-279"/>
|
||||
<text text-anchor="middle" x="97" y="-256.9" font-family="Sans" font-size="14.00">i (Normal)</text>
|
||||
</g>
|
||||
<!-- i_hard->hmac_hard -->
|
||||
<g id="edge29" class="edge"><title>i_hard->hmac_hard</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M139.872,-274.232C159.301,-280.229 178,-286 178,-286 178,-286 179.884,-286.942 182.947,-288.474"/>
|
||||
<polygon fill="black" stroke="black" points="181.397,-291.611 191.906,-292.953 184.527,-285.35 181.397,-291.611"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 13 KiB |
39
img/dev/en-hd-public-child-from-public-parent.dot
Normal file
|
@ -0,0 +1,39 @@
|
|||
digraph extended {
|
||||
|
||||
size=6.25;
|
||||
rankdir=LR;
|
||||
penwidth=1.75;
|
||||
node [ penwidth = 1.75, shape = "box" ];
|
||||
edge [ penwidth = 1.75 ];
|
||||
nodesep=0.05;
|
||||
splines = ortho;
|
||||
ranksep = 1.0;
|
||||
|
||||
subgraph cluster_norm {
|
||||
//style = "invis"
|
||||
//label = "Creation Of Normal Child Extended Keys (Key + Chain Code)\nFrom Parent Extended Keys"
|
||||
|
||||
subgraph cluster_n_public_extended_key {
|
||||
n_parent_public_key [ label = "Parent Public Key" ];
|
||||
n_parent_chain_code [ label = "Parent Chain Code" ];
|
||||
}
|
||||
|
||||
subgraph cluster_child_extended_key_norm {
|
||||
child_public_key_norm [ label = "Child Public Key" ];
|
||||
child_chain_code_norm [ label = "Child Chain Code" ];
|
||||
}
|
||||
hmac_norm [ style = "diagonals", label = "One-Way\nHash" ];
|
||||
i_norm [ label = "i (Normal)" ];
|
||||
|
||||
n_parent_chain_code -> hmac_norm;
|
||||
i_norm -> hmac_norm;
|
||||
hmac_norm -> child_public_key_norm;
|
||||
hmac_norm -> child_chain_code_norm;
|
||||
n_parent_public_key -> child_public_key_norm;
|
||||
|
||||
label = "Normal Public"
|
||||
}
|
||||
|
||||
label = "Creation Of Child Extended Public Keys (Key, Chain Code)\n(Hardened Child Public Keys Cannot Be Created From A Parent Public Key)"
|
||||
|
||||
}
|
BIN
img/dev/en-hd-public-child-from-public-parent.png
Normal file
After Width: | Height: | Size: 7 KiB |
85
img/dev/en-hd-public-child-from-public-parent.svg
Normal file
|
@ -0,0 +1,85 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: extended Pages: 1 -->
|
||||
<svg width="450pt" height="195pt"
|
||||
viewBox="0.00 0.00 450.00 195.27" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.803571 0.803571) rotate(0) translate(4 239)">
|
||||
<title>extended</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-239 557,-239 557,5 -4,5"/>
|
||||
<text text-anchor="middle" x="276" y="-25.4" font-family="Sans" font-size="14.00">Creation Of Child Extended Public Keys (Key, Chain Code)</text>
|
||||
<text text-anchor="middle" x="276" y="-8.4" font-family="Sans" font-size="14.00">(Hardened Child Public Keys Cannot Be Created From A Parent Public Key)</text>
|
||||
<g id="graph2" class="cluster"><title>cluster_norm</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="8,-50 8,-227 544,-227 544,-50 8,-50"/>
|
||||
<text text-anchor="middle" x="276" y="-210.4" font-family="Sans" font-size="14.00">Normal Public</text>
|
||||
</g>
|
||||
<g id="graph3" class="cluster"><title>cluster_n_public_extended_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="16,-102 16,-194 178,-194 178,-102 16,-102"/>
|
||||
</g>
|
||||
<g id="graph4" class="cluster"><title>cluster_child_extended_key_norm</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="386,-102 386,-194 536,-194 536,-102 386,-102"/>
|
||||
</g>
|
||||
<!-- n_parent_public_key -->
|
||||
<g id="node3" class="node"><title>n_parent_public_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="165,-186 29,-186 29,-150 165,-150 165,-186"/>
|
||||
<text text-anchor="middle" x="97" y="-163.9" font-family="Sans" font-size="14.00">Parent Public Key</text>
|
||||
</g>
|
||||
<!-- child_public_key_norm -->
|
||||
<g id="node6" class="node"><title>child_public_key_norm</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="523,-186 399,-186 399,-150 523,-150 523,-186"/>
|
||||
<text text-anchor="middle" x="461" y="-163.9" font-family="Sans" font-size="14.00">Child Public Key</text>
|
||||
</g>
|
||||
<!-- n_parent_public_key->child_public_key_norm -->
|
||||
<g id="edge13" class="edge"><title>n_parent_public_key->child_public_key_norm</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M165.894,-168C229.477,-168 323.575,-168 388.332,-168"/>
|
||||
<polygon fill="black" stroke="black" points="388.464,-171.5 398.464,-168 388.464,-164.5 388.464,-171.5"/>
|
||||
</g>
|
||||
<!-- n_parent_chain_code -->
|
||||
<g id="node4" class="node"><title>n_parent_chain_code</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="170,-146 24,-146 24,-110 170,-110 170,-146"/>
|
||||
<text text-anchor="middle" x="97" y="-123.9" font-family="Sans" font-size="14.00">Parent Chain Code</text>
|
||||
</g>
|
||||
<!-- hmac_norm -->
|
||||
<g id="node8" class="node"><title>hmac_norm</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="322,-149 242,-149 242,-107 322,-107 322,-149"/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="254,-149 242,-137 "/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="242,-119 254,-107 "/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="310,-107 322,-119 "/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="322,-137 310,-149 "/>
|
||||
<text text-anchor="middle" x="282" y="-132.4" font-family="Sans" font-size="14.00">One-Way</text>
|
||||
<text text-anchor="middle" x="282" y="-115.4" font-family="Sans" font-size="14.00">Hash</text>
|
||||
</g>
|
||||
<!-- n_parent_chain_code->hmac_norm -->
|
||||
<g id="edge5" class="edge"><title>n_parent_chain_code->hmac_norm</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M170.117,-128C190.739,-128 212.708,-128 231.668,-128"/>
|
||||
<polygon fill="black" stroke="black" points="231.865,-131.5 241.865,-128 231.865,-124.5 231.865,-131.5"/>
|
||||
</g>
|
||||
<!-- child_chain_code_norm -->
|
||||
<g id="node7" class="node"><title>child_chain_code_norm</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="528,-146 394,-146 394,-110 528,-110 528,-146"/>
|
||||
<text text-anchor="middle" x="461" y="-123.9" font-family="Sans" font-size="14.00">Child Chain Code</text>
|
||||
</g>
|
||||
<!-- hmac_norm->child_public_key_norm -->
|
||||
<g id="edge9" class="edge"><title>hmac_norm->child_public_key_norm</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M322.171,-136.977C341.745,-141.351 365.897,-146.748 388.538,-151.807"/>
|
||||
<polygon fill="black" stroke="black" points="387.948,-155.262 398.471,-154.027 389.475,-148.43 387.948,-155.262"/>
|
||||
</g>
|
||||
<!-- hmac_norm->child_chain_code_norm -->
|
||||
<g id="edge11" class="edge"><title>hmac_norm->child_chain_code_norm</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M322.171,-128C340.413,-128 362.63,-128 383.896,-128"/>
|
||||
<polygon fill="black" stroke="black" points="383.908,-131.5 393.908,-128 383.908,-124.5 383.908,-131.5"/>
|
||||
</g>
|
||||
<!-- i_norm -->
|
||||
<g id="node9" class="node"><title>i_norm</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="139,-94 55,-94 55,-58 139,-58 139,-94"/>
|
||||
<text text-anchor="middle" x="97" y="-71.9" font-family="Sans" font-size="14.00">i (Normal)</text>
|
||||
</g>
|
||||
<!-- i_norm->hmac_norm -->
|
||||
<g id="edge7" class="edge"><title>i_norm->hmac_norm</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M139.908,-88.0605C167.407,-95.79 203.208,-105.853 231.993,-113.944"/>
|
||||
<polygon fill="black" stroke="black" points="231.284,-117.38 241.858,-116.717 233.178,-110.641 231.284,-117.38"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.5 KiB |
42
img/dev/en-hd-root-keys.dot
Normal file
|
@ -0,0 +1,42 @@
|
|||
digraph extended {
|
||||
|
||||
size=6.25;
|
||||
rankdir=LR;
|
||||
penwidth=1.75;
|
||||
node [ penwidth = 1.75, shape = "box" ];
|
||||
edge [ penwidth = 1.75 ];
|
||||
nodesep=0.2;
|
||||
ranksep=0.2;
|
||||
splines = ortho;
|
||||
|
||||
entropy [ label = "128, 256,\nOr 512 Bits\nOf Entropy\n(The Seed)" ];
|
||||
hmac [ label = "512-Bit\nOne-Way\nHash", style = "diagonals" ];
|
||||
|
||||
entropy -> hmac;
|
||||
hmac -> private_key [label = "256 Bits" ];
|
||||
hmac -> chain_code [label = "256 Bits" ];
|
||||
|
||||
|
||||
subgraph cluster_y {
|
||||
style = "invis"
|
||||
public_key [ label = "Master\nPublic Key" ];
|
||||
private_key [ label = "Master\nPrivate Key" ];
|
||||
chain_code [ label = "Master\nChain Code" ];
|
||||
}
|
||||
|
||||
style = "invis"
|
||||
|
||||
subgraph cluster_x {
|
||||
extended_private_key [ label = "Master\nExtended\nPrivate Key" ];
|
||||
extended_public_key [ label = "Master\nExtended\nPublic Key" ];
|
||||
}
|
||||
|
||||
private_key -> public_key [ style = "dashed", constraint = 1 ];
|
||||
chain_code -> extended_private_key;
|
||||
chain_code -> extended_public_key;
|
||||
private_key -> extended_private_key;
|
||||
public_key -> extended_public_key;
|
||||
|
||||
label = "Creation Of The Master Keys"
|
||||
|
||||
}
|
BIN
img/dev/en-hd-root-keys.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
111
img/dev/en-hd-root-keys.svg
Normal file
|
@ -0,0 +1,111 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: extended Pages: 1 -->
|
||||
<svg width="450pt" height="148pt"
|
||||
viewBox="0.00 0.00 450.00 147.86" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.714286 0.714286) rotate(0) translate(4 203)">
|
||||
<title>extended</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-203 627,-203 627,5 -4,5"/>
|
||||
<text text-anchor="middle" x="311" y="-8.4" font-family="Sans" font-size="14.00">Creation Of The Master Keys</text>
|
||||
<g id="graph2" class="cluster"><title>cluster_y</title>
|
||||
</g>
|
||||
<g id="graph3" class="cluster"><title>cluster_x</title>
|
||||
</g>
|
||||
<!-- entropy -->
|
||||
<g id="node1" class="node"><title>entropy</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="96,-174 3.55271e-14,-174 0,-98 96,-98 96,-174"/>
|
||||
<text text-anchor="middle" x="48" y="-157.4" font-family="Sans" font-size="14.00">128, 256,</text>
|
||||
<text text-anchor="middle" x="48" y="-140.4" font-family="Sans" font-size="14.00">Or 512 Bits</text>
|
||||
<text text-anchor="middle" x="48" y="-123.4" font-family="Sans" font-size="14.00">Of Entropy</text>
|
||||
<text text-anchor="middle" x="48" y="-106.4" font-family="Sans" font-size="14.00">(The Seed)</text>
|
||||
</g>
|
||||
<!-- hmac -->
|
||||
<g id="node2" class="node"><title>hmac</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="194,-165.5 114,-165.5 114,-106.5 194,-106.5 194,-165.5"/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="126,-165.5 114,-153.5 "/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="114,-118.5 126,-106.5 "/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="182,-106.5 194,-118.5 "/>
|
||||
<polyline fill="none" stroke="black" stroke-width="1.75" points="194,-153.5 182,-165.5 "/>
|
||||
<text text-anchor="middle" x="154" y="-148.9" font-family="Sans" font-size="14.00">512-Bit</text>
|
||||
<text text-anchor="middle" x="154" y="-131.9" font-family="Sans" font-size="14.00">One-Way</text>
|
||||
<text text-anchor="middle" x="154" y="-114.9" font-family="Sans" font-size="14.00">Hash</text>
|
||||
</g>
|
||||
<!-- entropy->hmac -->
|
||||
<g id="edge2" class="edge"><title>entropy->hmac</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M96.0377,-136C98.5335,-136 101.044,-136 103.547,-136"/>
|
||||
<polygon fill="black" stroke="black" points="103.737,-139.5 113.737,-136 103.737,-132.5 103.737,-139.5"/>
|
||||
</g>
|
||||
<!-- private_key -->
|
||||
<g id="node5" class="node"><title>private_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="371,-183 277,-183 277,-141 371,-141 371,-183"/>
|
||||
<text text-anchor="middle" x="324" y="-166.4" font-family="Sans" font-size="14.00">Master</text>
|
||||
<text text-anchor="middle" x="324" y="-149.4" font-family="Sans" font-size="14.00">Private Key</text>
|
||||
</g>
|
||||
<!-- hmac->private_key -->
|
||||
<g id="edge4" class="edge"><title>hmac->private_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M194.288,-142.162C215.852,-145.46 242.783,-149.579 266.509,-153.207"/>
|
||||
<polygon fill="black" stroke="black" points="266.042,-156.677 276.457,-154.729 267.101,-149.757 266.042,-156.677"/>
|
||||
<text text-anchor="middle" x="231" y="-156.4" font-family="Sans" font-size="14.00">256 Bits</text>
|
||||
</g>
|
||||
<!-- chain_code -->
|
||||
<g id="node7" class="node"><title>chain_code</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="371,-127 277,-127 277,-85 371,-85 371,-127"/>
|
||||
<text text-anchor="middle" x="324" y="-110.4" font-family="Sans" font-size="14.00">Master</text>
|
||||
<text text-anchor="middle" x="324" y="-93.4" font-family="Sans" font-size="14.00">Chain Code</text>
|
||||
</g>
|
||||
<!-- hmac->chain_code -->
|
||||
<g id="edge6" class="edge"><title>hmac->chain_code</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M194.074,-125.147C198.81,-123.864 202,-123 202,-123 202,-123 234.754,-118.436 266.319,-114.038"/>
|
||||
<polygon fill="black" stroke="black" points="267.061,-117.468 276.482,-112.621 266.095,-110.535 267.061,-117.468"/>
|
||||
<text text-anchor="middle" x="231" y="-127.4" font-family="Sans" font-size="14.00">256 Bits</text>
|
||||
</g>
|
||||
<!-- public_key -->
|
||||
<g id="node9" class="node"><title>public_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="476,-183 390,-183 390,-141 476,-141 476,-183"/>
|
||||
<text text-anchor="middle" x="433" y="-166.4" font-family="Sans" font-size="14.00">Master</text>
|
||||
<text text-anchor="middle" x="433" y="-149.4" font-family="Sans" font-size="14.00">Public Key</text>
|
||||
</g>
|
||||
<!-- private_key->public_key -->
|
||||
<g id="edge10" class="edge"><title>private_key->public_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="5,2" d="M371.809,-162C374.412,-162 377.035,-162 379.655,-162"/>
|
||||
<polygon fill="black" stroke="black" points="379.69,-165.5 389.69,-162 379.69,-158.5 379.69,-165.5"/>
|
||||
</g>
|
||||
<!-- extended_private_key -->
|
||||
<g id="node11" class="node"><title>extended_private_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="605,-99.5 511,-99.5 511,-40.5 605,-40.5 605,-99.5"/>
|
||||
<text text-anchor="middle" x="558" y="-82.9" font-family="Sans" font-size="14.00">Master</text>
|
||||
<text text-anchor="middle" x="558" y="-65.9" font-family="Sans" font-size="14.00">Extended</text>
|
||||
<text text-anchor="middle" x="558" y="-48.9" font-family="Sans" font-size="14.00">Private Key</text>
|
||||
</g>
|
||||
<!-- private_key->extended_private_key -->
|
||||
<g id="edge16" class="edge"><title>private_key->extended_private_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M371.615,-141.8C382.023,-137.384 390,-134 390,-134 390,-134 452.085,-110.348 500.771,-91.8015"/>
|
||||
<polygon fill="black" stroke="black" points="502.208,-94.9994 510.307,-88.1686 499.716,-88.4579 502.208,-94.9994"/>
|
||||
</g>
|
||||
<!-- chain_code->extended_private_key -->
|
||||
<g id="edge12" class="edge"><title>chain_code->extended_private_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M366.157,-84.9214C374.113,-80.9433 380,-78 380,-78 380,-78 492,-71 492,-71 492,-71 495.274,-70.9504 500.363,-70.8733"/>
|
||||
<polygon fill="black" stroke="black" points="500.439,-74.3726 510.385,-70.7214 500.333,-67.3734 500.439,-74.3726"/>
|
||||
</g>
|
||||
<!-- extended_public_key -->
|
||||
<g id="node12" class="node"><title>extended_public_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="601,-171.5 515,-171.5 515,-112.5 601,-112.5 601,-171.5"/>
|
||||
<text text-anchor="middle" x="558" y="-154.9" font-family="Sans" font-size="14.00">Master</text>
|
||||
<text text-anchor="middle" x="558" y="-137.9" font-family="Sans" font-size="14.00">Extended</text>
|
||||
<text text-anchor="middle" x="558" y="-120.9" font-family="Sans" font-size="14.00">Public Key</text>
|
||||
</g>
|
||||
<!-- chain_code->extended_public_key -->
|
||||
<g id="edge14" class="edge"><title>chain_code->extended_public_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M371.635,-113.329C410.235,-119.267 464.599,-127.631 504.654,-133.793"/>
|
||||
<polygon fill="black" stroke="black" points="504.353,-137.288 514.769,-135.349 505.417,-130.369 504.353,-137.288"/>
|
||||
</g>
|
||||
<!-- public_key->extended_public_key -->
|
||||
<g id="edge18" class="edge"><title>public_key->extended_public_key</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M476.018,-155.117C485.348,-153.624 495.321,-152.029 504.984,-150.482"/>
|
||||
<polygon fill="black" stroke="black" points="505.581,-153.932 514.903,-148.896 504.475,-147.019 505.581,-153.932"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 7.5 KiB |
66
img/dev/en-hd-tree.dot
Normal file
|
@ -0,0 +1,66 @@
|
|||
digraph extended {
|
||||
|
||||
size=6.25;
|
||||
rankdir=LR;
|
||||
penwidth=1.75;
|
||||
node [ penwidth = 1.75, shape = "box" ];
|
||||
edge [ penwidth = 1.75, style = "dashed" ];
|
||||
nodesep=0.15;
|
||||
splines = ortho;
|
||||
ranksep = 0.70;
|
||||
|
||||
|
||||
subgraph cluster_0p {
|
||||
m0p [ label = "m/0'" ];
|
||||
M0p [ label = "M/0'" ];
|
||||
m0p -> M0p [ constraint = false ];
|
||||
|
||||
label = "Hardened"
|
||||
}
|
||||
|
||||
|
||||
// DEPTH 1
|
||||
subgraph cluster_0p_0 {
|
||||
m0p_0 [ label = "m/0'/0" ];
|
||||
M0p_0 [ label = "M/0'/0" ];
|
||||
m0p_0 -> M0p_0 [ constraint = false ];
|
||||
|
||||
label = "Normal"
|
||||
}
|
||||
|
||||
subgraph cluster_0p_1p {
|
||||
m0p_1p [ label = "m/0'/1'" ];
|
||||
M0p_1p [ label = "M/0'/1'" ];
|
||||
m0p_1p -> M0p_1p [ constraint = false ];
|
||||
|
||||
label = "Hardened";
|
||||
}
|
||||
|
||||
subgraph cluster_0p_0_0 {
|
||||
m0p_0_0 [ label = "m/0'/0/0" ];
|
||||
M0p_0_0 [ label = "M/0'/0/0" ];
|
||||
m0p_0_0 -> M0p_0_0 [ constraint = false ];
|
||||
|
||||
label = "Normal"
|
||||
}
|
||||
|
||||
subgraph cluster_0p_1p_0 {
|
||||
m0p_1p_0 [ label = "m/0'/1'/0" ];
|
||||
M0p_1p_0 [ label = "M/0'/1'/0" ];
|
||||
m0p_1p_0 -> M0p_1p_0 [ constraint = false ];
|
||||
|
||||
label = "Normal"
|
||||
}
|
||||
|
||||
|
||||
m0p -> m0p_0;
|
||||
m0p -> m0p_1p;
|
||||
|
||||
m0p_0 -> m0p_0_0;
|
||||
M0p_0 -> M0p_0_0 [ label = "Normal extended\npublic keys\ncan derive child\npublic keys" ];
|
||||
m0p_1p -> m0p_1p_0 [ label = "Only derivation from\nextended private keys\nis possible for\nhardened keys" ];
|
||||
|
||||
|
||||
label = "Hierarchical Deterministic Key Derivation"
|
||||
|
||||
}
|
BIN
img/dev/en-hd-tree.png
Normal file
After Width: | Height: | Size: 11 KiB |
142
img/dev/en-hd-tree.svg
Normal file
|
@ -0,0 +1,142 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: extended Pages: 1 -->
|
||||
<svg width="450pt" height="300pt"
|
||||
viewBox="0.00 0.00 450.00 299.70" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.889328 0.889328) rotate(0) translate(4 333)">
|
||||
<title>extended</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-333 503,-333 503,5 -4,5"/>
|
||||
<text text-anchor="middle" x="249" y="-8.4" font-family="Sans" font-size="14.00">Hierarchical Deterministic Key Derivation</text>
|
||||
<g id="graph2" class="cluster"><title>cluster_0p</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="8,-72 8,-207 91,-207 91,-72 8,-72"/>
|
||||
<text text-anchor="middle" x="49.5" y="-190.4" font-family="Sans" font-size="14.00">Hardened</text>
|
||||
</g>
|
||||
<g id="graph3" class="cluster"><title>cluster_0p_0</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="130,-176 130,-311 206,-311 206,-176 130,-176"/>
|
||||
<text text-anchor="middle" x="168" y="-294.4" font-family="Sans" font-size="14.00">Normal</text>
|
||||
</g>
|
||||
<g id="graph4" class="cluster"><title>cluster_0p_1p</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="127,-33 127,-168 210,-168 210,-33 127,-33"/>
|
||||
<text text-anchor="middle" x="168.5" y="-151.4" font-family="Sans" font-size="14.00">Hardened</text>
|
||||
</g>
|
||||
<g id="graph5" class="cluster"><title>cluster_0p_0_0</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="399,-186 399,-321 489,-321 489,-186 399,-186"/>
|
||||
<text text-anchor="middle" x="444" y="-304.4" font-family="Sans" font-size="14.00">Normal</text>
|
||||
</g>
|
||||
<g id="graph6" class="cluster"><title>cluster_0p_1p_0</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="398,-33 398,-168 490,-168 490,-33 398,-33"/>
|
||||
<text text-anchor="middle" x="444" y="-151.4" font-family="Sans" font-size="14.00">Normal</text>
|
||||
</g>
|
||||
<!-- m0p -->
|
||||
<g id="node2" class="node"><title>m0p</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="76,-174 22,-174 22,-138 76,-138 76,-174"/>
|
||||
<text text-anchor="middle" x="49" y="-151.9" font-family="Sans" font-size="14.00">m/0'</text>
|
||||
</g>
|
||||
<!-- M0p -->
|
||||
<g id="node3" class="node"><title>M0p</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="76,-116 22,-116 22,-80 76,-80 76,-116"/>
|
||||
<text text-anchor="middle" x="49" y="-93.9" font-family="Sans" font-size="14.00">M/0'</text>
|
||||
</g>
|
||||
<!-- m0p->M0p -->
|
||||
<g id="edge3" class="edge"><title>m0p->M0p</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="5,2" d="M49,-137.935C49,-137.139 49,-136.667 49,-136.667 49,-136.667 49,-131.527 49,-126.373"/>
|
||||
<polygon fill="black" stroke="black" points="52.5001,-126.065 49,-116.065 45.5001,-126.065 52.5001,-126.065"/>
|
||||
</g>
|
||||
<!-- m0p_0 -->
|
||||
<g id="node6" class="node"><title>m0p_0</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="197,-278 139,-278 139,-242 197,-242 197,-278"/>
|
||||
<text text-anchor="middle" x="168" y="-255.9" font-family="Sans" font-size="14.00">m/0'/0</text>
|
||||
</g>
|
||||
<!-- m0p->m0p_0 -->
|
||||
<g id="edge17" class="edge"><title>m0p->m0p_0</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="5,2" d="M69.4936,-174.129C92.6036,-194.572 127,-225 127,-225 127,-225 132.188,-229.429 138.873,-235.135"/>
|
||||
<polygon fill="black" stroke="black" points="136.661,-237.849 146.539,-241.68 141.206,-232.525 136.661,-237.849"/>
|
||||
</g>
|
||||
<!-- m0p_1p -->
|
||||
<g id="node10" class="node"><title>m0p_1p</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="199,-135 137,-135 137,-99 199,-99 199,-135"/>
|
||||
<text text-anchor="middle" x="168" y="-112.9" font-family="Sans" font-size="14.00">m/0'/1'</text>
|
||||
</g>
|
||||
<!-- m0p->m0p_1p -->
|
||||
<g id="edge19" class="edge"><title>m0p->m0p_1p</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="5,2" d="M76.0029,-147.15C91.1364,-142.191 110.316,-135.905 127.242,-130.358"/>
|
||||
<polygon fill="black" stroke="black" points="128.487,-133.633 136.899,-127.193 126.307,-126.981 128.487,-133.633"/>
|
||||
</g>
|
||||
<!-- M0p_0 -->
|
||||
<g id="node7" class="node"><title>M0p_0</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="197,-220 139,-220 139,-184 197,-184 197,-220"/>
|
||||
<text text-anchor="middle" x="168" y="-197.9" font-family="Sans" font-size="14.00">M/0'/0</text>
|
||||
</g>
|
||||
<!-- m0p_0->M0p_0 -->
|
||||
<g id="edge6" class="edge"><title>m0p_0->M0p_0</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="5,2" d="M168,-241.935C168,-241.139 168,-240.667 168,-240.667 168,-240.667 168,-235.527 168,-230.373"/>
|
||||
<polygon fill="black" stroke="black" points="171.5,-230.065 168,-220.065 164.5,-230.065 171.5,-230.065"/>
|
||||
</g>
|
||||
<!-- m0p_0_0 -->
|
||||
<g id="node14" class="node"><title>m0p_0_0</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="480,-288 408,-288 408,-252 480,-252 480,-288"/>
|
||||
<text text-anchor="middle" x="444" y="-265.9" font-family="Sans" font-size="14.00">m/0'/0/0</text>
|
||||
</g>
|
||||
<!-- m0p_0->m0p_0_0 -->
|
||||
<g id="edge21" class="edge"><title>m0p_0->m0p_0_0</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="5,2" d="M197.846,-265.059C212.48,-267.539 227,-270 227,-270 227,-270 333.132,-270 396.95,-270"/>
|
||||
<polygon fill="black" stroke="black" points="397.189,-273.5 407.189,-270 397.189,-266.5 397.189,-273.5"/>
|
||||
</g>
|
||||
<!-- M0p_0_0 -->
|
||||
<g id="node15" class="node"><title>M0p_0_0</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="480,-230 408,-230 408,-194 480,-194 480,-230"/>
|
||||
<text text-anchor="middle" x="444" y="-207.9" font-family="Sans" font-size="14.00">M/0'/0/0</text>
|
||||
</g>
|
||||
<!-- M0p_0->M0p_0_0 -->
|
||||
<g id="edge23" class="edge"><title>M0p_0->M0p_0_0</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="5,2" d="M197.846,-200.988C212.48,-200.492 227,-200 227,-200 227,-200 381,-200 381,-200 381,-200 388.151,-201.362 397.635,-203.169"/>
|
||||
<polygon fill="black" stroke="black" points="397.239,-206.656 407.718,-205.089 398.549,-199.78 397.239,-206.656"/>
|
||||
<text text-anchor="middle" x="304" y="-255.4" font-family="Sans" font-size="14.00">Normal extended</text>
|
||||
<text text-anchor="middle" x="304" y="-238.4" font-family="Sans" font-size="14.00">public keys</text>
|
||||
<text text-anchor="middle" x="304" y="-221.4" font-family="Sans" font-size="14.00">can derive child</text>
|
||||
<text text-anchor="middle" x="304" y="-204.4" font-family="Sans" font-size="14.00">public keys</text>
|
||||
</g>
|
||||
<!-- M0p_1p -->
|
||||
<g id="node11" class="node"><title>M0p_1p</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="199,-77 137,-77 137,-41 199,-41 199,-77"/>
|
||||
<text text-anchor="middle" x="168" y="-54.9" font-family="Sans" font-size="14.00">M/0'/1'</text>
|
||||
</g>
|
||||
<!-- m0p_1p->M0p_1p -->
|
||||
<g id="edge9" class="edge"><title>m0p_1p->M0p_1p</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="5,2" d="M168,-98.9352C168,-98.1387 168,-97.6667 168,-97.6667 168,-97.6667 168,-92.5265 168,-87.3731"/>
|
||||
<polygon fill="black" stroke="black" points="171.5,-87.0648 168,-77.0648 164.5,-87.0649 171.5,-87.0648"/>
|
||||
</g>
|
||||
<!-- m0p_1p_0 -->
|
||||
<g id="node18" class="node"><title>m0p_1p_0</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="482,-135 406,-135 406,-99 482,-99 482,-135"/>
|
||||
<text text-anchor="middle" x="444" y="-112.9" font-family="Sans" font-size="14.00">m/0'/1'/0</text>
|
||||
</g>
|
||||
<!-- m0p_1p->m0p_1p_0 -->
|
||||
<g id="edge25" class="edge"><title>m0p_1p->m0p_1p_0</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="5,2" d="M199.124,-117C247.035,-117 339.231,-117 395.814,-117"/>
|
||||
<polygon fill="black" stroke="black" points="395.946,-120.5 405.946,-117 395.946,-113.5 395.946,-120.5"/>
|
||||
<text text-anchor="middle" x="304" y="-172.4" font-family="Sans" font-size="14.00">Only derivation from</text>
|
||||
<text text-anchor="middle" x="304" y="-155.4" font-family="Sans" font-size="14.00">extended private keys</text>
|
||||
<text text-anchor="middle" x="304" y="-138.4" font-family="Sans" font-size="14.00">is possible for</text>
|
||||
<text text-anchor="middle" x="304" y="-121.4" font-family="Sans" font-size="14.00">hardened keys</text>
|
||||
</g>
|
||||
<!-- m0p_0_0->M0p_0_0 -->
|
||||
<g id="edge12" class="edge"><title>m0p_0_0->M0p_0_0</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="5,2" d="M444,-251.935C444,-251.139 444,-250.667 444,-250.667 444,-250.667 444,-245.527 444,-240.373"/>
|
||||
<polygon fill="black" stroke="black" points="447.5,-240.065 444,-230.065 440.5,-240.065 447.5,-240.065"/>
|
||||
</g>
|
||||
<!-- M0p_1p_0 -->
|
||||
<g id="node19" class="node"><title>M0p_1p_0</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="481,-77 407,-77 407,-41 481,-41 481,-77"/>
|
||||
<text text-anchor="middle" x="444" y="-54.9" font-family="Sans" font-size="14.00">M/0'/1'/0</text>
|
||||
</g>
|
||||
<!-- m0p_1p_0->M0p_1p_0 -->
|
||||
<g id="edge15" class="edge"><title>m0p_1p_0->M0p_1p_0</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="5,2" d="M444,-98.9352C444,-98.1387 444,-97.6667 444,-97.6667 444,-97.6667 444,-92.5265 444,-87.3731"/>
|
||||
<polygon fill="black" stroke="black" points="447.5,-87.0648 444,-77.0648 440.5,-87.0649 447.5,-87.0648"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 9.3 KiB |
54
img/dev/en-micropayment-channel.dot
Normal file
|
@ -0,0 +1,54 @@
|
|||
digraph paymentchannel {
|
||||
size=6.66;
|
||||
rankdir=LR;
|
||||
//splines = false;
|
||||
nodesep = 0.1;
|
||||
|
||||
edge [ fontname="Sans", minlen = 4 ];
|
||||
node [ fontname="Sans", style = invis, shape = box ];
|
||||
graph [ fontname="Sans" ]
|
||||
|
||||
|
||||
|
||||
subgraph cluster_alice {
|
||||
label = "Alice's Computer\n(Server)"
|
||||
rank = same;
|
||||
//atx2v1;
|
||||
atx2v1s;
|
||||
atx1v2 [ label = "Bond\n(2-of-2\nmultisig)", style = unfilled, bgcolor = grey ];
|
||||
|
||||
//atx2v2;
|
||||
atx2v3 [ label = " \n \n "];
|
||||
atx2v4;
|
||||
atx2v5 [ label = "Refund v45\nBob: 66\n Alice: 44\n(No Lock)", style = unfilled, bgcolor = grey ];
|
||||
|
||||
}
|
||||
|
||||
subgraph cluster_bob {
|
||||
label = "Bob's Computer\n(Client)"
|
||||
rank = same;
|
||||
btx2v1 [ label = "Refund v1\nBob: 100\nAlice: 0\n(Locktime)", style = unfilled, bgcolor = grey ];
|
||||
//btx2v1s;
|
||||
btx1v2 [label = " \n \n \n "];
|
||||
|
||||
btx2v2s;
|
||||
btx2v3;
|
||||
btx2v4 [ label = " \n \n \n "];
|
||||
btx2v5;
|
||||
}
|
||||
|
||||
btx2v1 -> atx2v1s [ label = "B: Please sign refund version 1,\nwhich is a full refund of the bond\nthat can't be spent for 24 hours" ];
|
||||
atx2v1s -> btx1v2 [ style = dashed, label = "A: Signed; please send me the bond to\nprove you funded the account" ];
|
||||
btx1v2 -> atx1v2 [ label = "B: Here's the bond; please start working" ];
|
||||
atx1v2 -> btx2v2s [ style = dashed, label = "A: Some work done; please sign refund v2\nreducing your refund by 1 mBTC" ];
|
||||
btx2v2s -> atx2v3 [ label = "B: Signed; refund now pays Bob: 99; Alice: 1" ];
|
||||
atx2v3 -> btx2v3 [ style = dashed, label = "A: More work done; please sign v3\nreducing your refund by another 1 mBTC" ];
|
||||
btx2v3 -> atx2v4 [ label = "B: Signed; refund now pays Bob: 98; Alice: 2" ];
|
||||
atx2v4 -> btx2v4 [ style = dashed, label = "A: [...]" ];
|
||||
btx2v4 -> atx2v5 [ label = "B: [...]" ];
|
||||
|
||||
atx2v5 -> btx2v5 [ style = dashed, label = "A: I'm done for the day. I'm\ngoing to broadcast refund v45" ];
|
||||
|
||||
|
||||
label = " \n \nAlice broadcasts the bond to the Bitcoin network immediately.\nShe broadcasts the final version of the refund when she finishes work\nor before the locktime. If she fails to broadcast before refund v1's time lock\nexpires, Bob can broadcast refund v1 to get a full refund.\n \nBitcoin Micropayment Channels (As Implemented In Bitcoinj)"
|
||||
}
|
BIN
img/dev/en-micropayment-channel.png
Normal file
After Width: | Height: | Size: 20 KiB |
128
img/dev/en-micropayment-channel.svg
Normal file
|
@ -0,0 +1,128 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: paymentchannel Pages: 1 -->
|
||||
<svg width="480pt" height="394pt"
|
||||
viewBox="0.00 0.00 480.00 393.63" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.659341 0.659341) rotate(0) translate(4 593)">
|
||||
<title>paymentchannel</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-593 725,-593 725,5 -4,5"/>
|
||||
<text text-anchor="middle" x="360" y="-127.4" font-family="Sans" font-size="14.00"> </text>
|
||||
<text text-anchor="middle" x="360" y="-110.4" font-family="Sans" font-size="14.00"> </text>
|
||||
<text text-anchor="middle" x="360" y="-93.4" font-family="Sans" font-size="14.00">Alice broadcasts the bond to the Bitcoin network immediately.</text>
|
||||
<text text-anchor="middle" x="360" y="-76.4" font-family="Sans" font-size="14.00">She broadcasts the final version of the refund when she finishes work</text>
|
||||
<text text-anchor="middle" x="360" y="-59.4" font-family="Sans" font-size="14.00">or before the locktime.  If she fails to broadcast before refund v1's time lock</text>
|
||||
<text text-anchor="middle" x="360" y="-42.4" font-family="Sans" font-size="14.00">expires, Bob can broadcast refund v1 to get a full refund.</text>
|
||||
<text text-anchor="middle" x="360" y="-25.4" font-family="Sans" font-size="14.00"> </text>
|
||||
<text text-anchor="middle" x="360" y="-8.4" font-family="Sans" font-size="14.00">Bitcoin Micropayment Channels (As Implemented In Bitcoinj)</text>
|
||||
<g id="graph2" class="cluster"><title>cluster_alice</title>
|
||||
<polygon fill="none" stroke="black" points="8,-161 8,-511 139,-511 139,-161 8,-161"/>
|
||||
<text text-anchor="middle" x="73.5" y="-494.4" font-family="Sans" font-size="14.00">Alice's Computer</text>
|
||||
<text text-anchor="middle" x="73.5" y="-477.4" font-family="Sans" font-size="14.00">(Server)</text>
|
||||
</g>
|
||||
<g id="graph3" class="cluster"><title>cluster_bob</title>
|
||||
<polygon fill="none" stroke="black" points="587,-152 587,-581 712,-581 712,-152 587,-152"/>
|
||||
<text text-anchor="middle" x="649.5" y="-564.4" font-family="Sans" font-size="14.00">Bob's Computer</text>
|
||||
<text text-anchor="middle" x="649.5" y="-547.4" font-family="Sans" font-size="14.00">(Client)</text>
|
||||
</g>
|
||||
<!-- atx2v1s -->
|
||||
<!-- btx1v2 -->
|
||||
<!-- atx2v1s->btx1v2 -->
|
||||
<g id="edge6" class="edge"><title>atx2v1s->btx1v2</title>
|
||||
<path fill="none" stroke="black" stroke-dasharray="5,2" d="M109.156,-451.842C127.301,-455.543 149.689,-459 170,-459 170,-459 170,-459 556,-459 568.056,-459 592.44,-445.948 613.216,-433.316"/>
|
||||
<polygon fill="black" stroke="black" points="615.193,-436.208 621.852,-427.968 611.508,-430.257 615.193,-436.208"/>
|
||||
<text text-anchor="middle" x="363" y="-480.4" font-family="Sans" font-size="14.00">A: Signed; please send me the bond to</text>
|
||||
<text text-anchor="middle" x="363" y="-463.4" font-family="Sans" font-size="14.00">prove you funded the account</text>
|
||||
</g>
|
||||
<!-- atx1v2 -->
|
||||
<g id="node3" class="node"><title>atx1v2</title>
|
||||
<polygon fill="none" stroke="black" points="111,-418.5 35,-418.5 35,-359.5 111,-359.5 111,-418.5"/>
|
||||
<text text-anchor="middle" x="73" y="-401.9" font-family="Sans" font-size="14.00">Bond</text>
|
||||
<text text-anchor="middle" x="73" y="-384.9" font-family="Sans" font-size="14.00">(2-of-2</text>
|
||||
<text text-anchor="middle" x="73" y="-367.9" font-family="Sans" font-size="14.00">multisig)</text>
|
||||
</g>
|
||||
<!-- btx2v2s -->
|
||||
<!-- atx1v2->btx2v2s -->
|
||||
<g id="edge10" class="edge"><title>atx1v2->btx2v2s</title>
|
||||
<path fill="none" stroke="black" stroke-dasharray="5,2" d="M111.163,-383.817C129.001,-381.816 150.55,-380 170,-380 170,-380 170,-380 556,-380 556,-380 579.688,-371.595 603.153,-363.268"/>
|
||||
<polygon fill="black" stroke="black" points="604.524,-366.496 612.777,-359.853 602.183,-359.899 604.524,-366.496"/>
|
||||
<text text-anchor="middle" x="363" y="-401.4" font-family="Sans" font-size="14.00">A: Some work done; please sign refund v2</text>
|
||||
<text text-anchor="middle" x="363" y="-384.4" font-family="Sans" font-size="14.00">reducing your refund by 1 mBTC</text>
|
||||
</g>
|
||||
<!-- atx2v3 -->
|
||||
<!-- btx2v3 -->
|
||||
<!-- atx2v3->btx2v3 -->
|
||||
<g id="edge14" class="edge"><title>atx2v3->btx2v3</title>
|
||||
<path fill="none" stroke="black" stroke-dasharray="5,2" d="M100.189,-313.979C119.413,-307.781 145.943,-301 170,-301 170,-301 170,-301 556,-301 572.432,-301 590.488,-301.474 606.284,-302.045"/>
|
||||
<polygon fill="black" stroke="black" points="606.171,-305.543 616.298,-302.43 606.44,-298.548 606.171,-305.543"/>
|
||||
<text text-anchor="middle" x="363" y="-322.4" font-family="Sans" font-size="14.00">A: More work done; please sign v3</text>
|
||||
<text text-anchor="middle" x="363" y="-305.4" font-family="Sans" font-size="14.00">reducing your refund by another 1 mBTC</text>
|
||||
</g>
|
||||
<!-- atx2v4 -->
|
||||
<!-- btx2v4 -->
|
||||
<!-- atx2v4->btx2v4 -->
|
||||
<g id="edge18" class="edge"><title>atx2v4->btx2v4</title>
|
||||
<path fill="none" stroke="black" stroke-dasharray="5,2" d="M105.567,-259.071C132.409,-250.145 166.608,-239 170,-239 170,-239 170,-239 556,-239 574.322,-239 594.67,-239.393 611.65,-239.83"/>
|
||||
<polygon fill="black" stroke="black" points="611.647,-243.331 621.738,-240.105 611.838,-236.334 611.647,-243.331"/>
|
||||
<text text-anchor="middle" x="363" y="-243.4" font-family="Sans" font-size="14.00">A: [...]</text>
|
||||
</g>
|
||||
<!-- atx2v5 -->
|
||||
<g id="node6" class="node"><title>atx2v5</title>
|
||||
<polygon fill="none" stroke="black" points="120,-245 26,-245 26,-169 120,-169 120,-245"/>
|
||||
<text text-anchor="middle" x="73" y="-228.4" font-family="Sans" font-size="14.00">Refund v45</text>
|
||||
<text text-anchor="middle" x="73" y="-211.4" font-family="Sans" font-size="14.00">Bob: 66</text>
|
||||
<text text-anchor="middle" x="73" y="-194.4" font-family="Sans" font-size="14.00"> Alice: 44</text>
|
||||
<text text-anchor="middle" x="73" y="-177.4" font-family="Sans" font-size="14.00">(No Lock)</text>
|
||||
</g>
|
||||
<!-- btx2v5 -->
|
||||
<!-- atx2v5->btx2v5 -->
|
||||
<g id="edge22" class="edge"><title>atx2v5->btx2v5</title>
|
||||
<path fill="none" stroke="black" stroke-dasharray="5,2" d="M120.721,-173.594C135.792,-165.939 152.971,-160 170,-160 170,-160 170,-160 556,-160 572.593,-160 590.553,-162.796 606.225,-166.184"/>
|
||||
<polygon fill="black" stroke="black" points="605.626,-169.638 616.156,-168.473 607.198,-162.817 605.626,-169.638"/>
|
||||
<text text-anchor="middle" x="363" y="-181.4" font-family="Sans" font-size="14.00">A: I'm done for the day.  I'm</text>
|
||||
<text text-anchor="middle" x="363" y="-164.4" font-family="Sans" font-size="14.00">going to broadcast refund v45</text>
|
||||
</g>
|
||||
<!-- btx2v1 -->
|
||||
<g id="node8" class="node"><title>btx2v1</title>
|
||||
<polygon fill="none" stroke="black" points="693,-531 605,-531 605,-455 693,-455 693,-531"/>
|
||||
<text text-anchor="middle" x="649" y="-514.4" font-family="Sans" font-size="14.00">Refund v1</text>
|
||||
<text text-anchor="middle" x="649" y="-497.4" font-family="Sans" font-size="14.00">Bob: 100</text>
|
||||
<text text-anchor="middle" x="649" y="-480.4" font-family="Sans" font-size="14.00">Alice: 0</text>
|
||||
<text text-anchor="middle" x="649" y="-463.4" font-family="Sans" font-size="14.00">(Locktime)</text>
|
||||
</g>
|
||||
<!-- btx2v1->atx2v1s -->
|
||||
<g id="edge4" class="edge"><title>btx2v1->atx2v1s</title>
|
||||
<path fill="none" stroke="black" d="M604.266,-502.493C589.026,-504.99 571.838,-507 556,-507 170,-507 170,-507 170,-507 140.695,-507 113.418,-486.397 95.3012,-468.57"/>
|
||||
<polygon fill="black" stroke="black" points="97.5945,-465.908 88.1186,-461.169 92.5709,-470.783 97.5945,-465.908"/>
|
||||
<text text-anchor="middle" x="363" y="-545.4" font-family="Sans" font-size="14.00">B: Please sign refund version 1,</text>
|
||||
<text text-anchor="middle" x="363" y="-528.4" font-family="Sans" font-size="14.00">which is a full refund of the bond</text>
|
||||
<text text-anchor="middle" x="363" y="-511.4" font-family="Sans" font-size="14.00">that can't be spent for 24 hours</text>
|
||||
</g>
|
||||
<!-- btx1v2->atx1v2 -->
|
||||
<g id="edge8" class="edge"><title>btx1v2->atx1v2</title>
|
||||
<path fill="none" stroke="black" d="M621.597,-418.157C603.215,-422.92 578.366,-428 556,-428 170,-428 170,-428 170,-428 159.783,-428 139.794,-420.458 120.603,-412.007"/>
|
||||
<polygon fill="black" stroke="black" points="121.847,-408.729 111.292,-407.815 118.973,-415.112 121.847,-408.729"/>
|
||||
<text text-anchor="middle" x="363" y="-432.4" font-family="Sans" font-size="14.00">B: Here's the bond; please start working</text>
|
||||
</g>
|
||||
<!-- btx2v2s->atx2v3 -->
|
||||
<g id="edge12" class="edge"><title>btx2v2s->atx2v3</title>
|
||||
<path fill="none" stroke="black" d="M612.788,-348.14C595.585,-348.589 574.733,-349 556,-349 170,-349 170,-349 170,-349 149.604,-349 127.537,-343.753 109.612,-338.066"/>
|
||||
<polygon fill="black" stroke="black" points="110.71,-334.743 100.116,-334.893 108.491,-341.382 110.71,-334.743"/>
|
||||
<text text-anchor="middle" x="363" y="-353.4" font-family="Sans" font-size="14.00">B: Signed; refund now pays Bob: 99; Alice: 1</text>
|
||||
</g>
|
||||
<!-- btx2v3->atx2v4 -->
|
||||
<g id="edge16" class="edge"><title>btx2v3->atx2v4</title>
|
||||
<path fill="none" stroke="black" d="M616.438,-292.641C606.928,-289.271 596.531,-285.535 587,-282 573.148,-276.863 570.774,-270 556,-270 170,-270 170,-270 170,-270 152.289,-270 132.758,-270 115.893,-270"/>
|
||||
<polygon fill="black" stroke="black" points="115.776,-266.5 105.776,-270 115.776,-273.5 115.776,-266.5"/>
|
||||
<text text-anchor="middle" x="363" y="-274.4" font-family="Sans" font-size="14.00">B: Signed; refund now pays Bob: 98; Alice: 2</text>
|
||||
</g>
|
||||
<!-- btx2v4->atx2v5 -->
|
||||
<g id="edge20" class="edge"><title>btx2v4->atx2v5</title>
|
||||
<path fill="none" stroke="black" d="M621.812,-225.852C603.726,-217.177 579.128,-208 556,-208 170,-208 170,-208 170,-208 157.376,-208 143.828,-207.914 130.979,-207.793"/>
|
||||
<polygon fill="black" stroke="black" points="130.892,-204.292 120.856,-207.689 130.82,-211.292 130.892,-204.292"/>
|
||||
<text text-anchor="middle" x="363" y="-212.4" font-family="Sans" font-size="14.00">B: [...]</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 9.9 KiB |
146
img/dev/en-p2pkh-stack.dot
Normal file
|
@ -0,0 +1,146 @@
|
|||
digraph blockchain {
|
||||
|
||||
size=6.25;
|
||||
splines = "false";
|
||||
//rankdir=LR;
|
||||
//ranksep=0.1;
|
||||
//splines=ortho;
|
||||
|
||||
node [ fontname="Sans", shape = box ];
|
||||
edge [ fontname="Sans", style = invis, minlen = 1 ];
|
||||
graph [ fontname="Sans" ];
|
||||
//fixedsize
|
||||
nodesep = 0.05;
|
||||
//concentrate = true;
|
||||
|
||||
subgraph cluster_alice {
|
||||
bgcolor = grey;
|
||||
alice_opchecksig [ label = "CHECKSIG" ];
|
||||
alice_opequalverify [ label = "OP_EQUALVERIFY" ];
|
||||
alice_pubkeyhash [ label = "Pk Hash", shape = "" ];
|
||||
alice_ophash [ label = "OP_HASH160" ];
|
||||
alice_opdup [ label = "OP_DUP" ];
|
||||
alice_pubkey [style = invis, label="PubKey", shape = "" ];
|
||||
alice_sig [style = invis, label="Sig", shape = "" ];
|
||||
|
||||
label = "Instructions And Data Provided By Alice In Transaction #1's Output Script"
|
||||
/* label = "Data Provided By Spender 1 To Spend Output" */
|
||||
}
|
||||
|
||||
subgraph cluster_bob {
|
||||
bgcolor = grey;
|
||||
bob_opchecksig [ label = "CHECKSIG", style = invis ];
|
||||
bob_opequalverify [ label = "OP_EQUALVERIFY", style = invis ];
|
||||
bob_pubkeyhash [ label = "Pk Hash", style = invis, shape = "" ];
|
||||
bob_ophash [ label = "OP_HASH160", style = invis ];
|
||||
bob_opdup [ label = "OP_DUP", style = invis ];
|
||||
bob_pubkey [style = unfilled, label="PubKey", shape = "" ];
|
||||
bob_sig [style = unfilled, label="Sig", shape = "" ];
|
||||
|
||||
label = "Data Provided By Bob In Transaction #2's Input ScriptSig"
|
||||
}
|
||||
|
||||
alice_sig -> bob_sig;
|
||||
alice_pubkey -> bob_pubkey;
|
||||
alice_opdup -> bob_opdup;
|
||||
alice_ophash -> bob_ophash;
|
||||
alice_pubkeyhash -> bob_pubkeyhash;
|
||||
alice_opequalverify -> bob_opequalverify;
|
||||
alice_opchecksig -> bob_opchecksig;
|
||||
|
||||
subgraph invis {
|
||||
node [ style = invis, label="", width=0, height=0 ];
|
||||
invis0_0;
|
||||
invis0_1;
|
||||
invis0_2;
|
||||
invis0_3;
|
||||
|
||||
invis1_0;
|
||||
invis1_1;
|
||||
invis1_2;
|
||||
|
||||
invis2_0;
|
||||
invis2_1;
|
||||
|
||||
invis3_0;
|
||||
|
||||
invis4_0;
|
||||
|
||||
invis5_0;
|
||||
invis5_1;
|
||||
|
||||
invis6_0;
|
||||
invis6_1;
|
||||
invis6_2;
|
||||
invis6_3;
|
||||
invis6_4;
|
||||
invis6_5;
|
||||
invis6_6;
|
||||
}
|
||||
stack7_opchecksig [style = filled, label="OP_CHECKSIG" ];
|
||||
stack7_pubkey [style = filled, label="PubKey", shape = "" ];
|
||||
stack7_sig [style = filled, label="Sig", shape = "" ];
|
||||
|
||||
stack6_opequalverify [style = filled, label="OP_EQUALVERIFY" ];
|
||||
stack6_pubkeyhash [style = filled, label="Pk Hash", shape = "" ];
|
||||
stack6_ophash [style = filled, label="Pk Hash" ];
|
||||
stack6_pubkey [style = unfilled, label="PubKey", shape = "" ];
|
||||
stack6_sig [style = unfilled, label="Sig", shape = "" ];
|
||||
|
||||
stack5_pubkeyhash [style = unfilled, label="Pk Hash", shape = "" ];
|
||||
stack5_ophash [style = unfilled, label="Pk Hash" ];
|
||||
stack5_pubkey [style = unfilled, label="PubKey", shape = "" ];
|
||||
stack5_sig [style = unfilled, label="Sig", shape = "" ];
|
||||
|
||||
stack4_ophash [style = filled, label="OP_HASH160" ];
|
||||
stack4_opdup [style = filled, label="PubKey" ];
|
||||
stack4_pubkey [style = unfilled, label="PubKey", shape = "" ];
|
||||
stack4_sig [style = unfilled, label="Sig", shape = "" ];
|
||||
|
||||
stack3_opdup [style = filled, label="OP_DUP" ];
|
||||
stack3_pubkey [style = filled, label="PubKey", shape = "" ];
|
||||
stack3_sig [style = unfilled, label="Sig", shape = "" ];
|
||||
|
||||
stack2_pubkey [style = unfilled, label="PubKey", shape = "" ];
|
||||
stack2_sig [style = unfilled, label="Sig", shape = "" ];
|
||||
stack1_sig [style = unfilled, label="Sig", shape = "" ];
|
||||
|
||||
bob_sig -> invis0_0 -> invis0_1 -> invis0_2 -> invis0_3 -> stack1_sig;
|
||||
bob_sig -> invis0_1 [ style = "dotted" ];
|
||||
|
||||
bob_pubkey -> invis1_0 -> invis1_1 -> invis1_2 -> stack2_pubkey;
|
||||
bob_pubkey -> stack2_pubkey; stack2_pubkey -> stack2_sig;
|
||||
|
||||
|
||||
bob_opdup -> invis2_0 -> invis2_1 -> stack3_opdup;
|
||||
alice_opdup -> invis2_1 [ constraint = false, style = "dotted" ]; stack3_opdup -> stack3_pubkey -> stack3_sig;
|
||||
|
||||
bob_ophash -> invis3_0 -> stack4_ophash;
|
||||
bob_ophash -> stack4_ophash; stack4_ophash -> stack4_opdup -> stack4_pubkey -> stack4_sig;
|
||||
|
||||
bob_pubkeyhash -> invis4_0 -> stack5_pubkeyhash;
|
||||
bob_pubkeyhash -> stack5_pubkeyhash; stack5_pubkeyhash -> stack5_ophash -> stack5_pubkey -> stack5_sig;
|
||||
|
||||
bob_opequalverify -> stack6_opequalverify; stack6_opequalverify -> stack6_pubkeyhash -> stack6_ophash -> stack6_pubkey -> stack6_sig
|
||||
|
||||
bob_opchecksig -> invis5_0 -> invis5_1 -> stack7_opchecksig;
|
||||
bob_opchecksig -> stack7_opchecksig; stack7_opchecksig -> stack7_pubkey -> stack7_sig
|
||||
|
||||
invis6_0 -> invis6_1 -> invis6_2 -> invis6_3 -> invis6_4 -> invis6_5 -> TRUE;
|
||||
stack7_opchecksig -> TRUE [ style = "", minlen = 2 ];
|
||||
|
||||
|
||||
stack3_opdup -> stack4_opdup [ constraint = false, style = "" ];
|
||||
stack3_pubkey -> stack3_opdup [ style = "" ];
|
||||
|
||||
stack4_ophash -> stack5_ophash [ constraint = false, style = "" ];
|
||||
stack4_opdup -> stack4_ophash [ style = "" ];
|
||||
|
||||
stack6_pubkeyhash -> stack6_opequalverify [ style = "" ];
|
||||
stack6_ophash -> stack6_pubkeyhash [ style = "" ];
|
||||
|
||||
stack7_pubkey -> stack7_opchecksig [ style = "" ];
|
||||
stack7_sig -> stack7_pubkey [ style = "" ];
|
||||
|
||||
label = "Evaluation Stack Over Time During Succesful P2PKH Script Validation"
|
||||
}
|
BIN
img/dev/en-p2pkh-stack.png
Normal file
After Width: | Height: | Size: 18 KiB |
306
img/dev/en-p2pkh-stack.svg
Normal file
|
@ -0,0 +1,306 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: blockchain Pages: 1 -->
|
||||
<svg width="450pt" height="329pt"
|
||||
viewBox="0.00 0.00 450.00 328.62" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.592105 0.592105) rotate(0) translate(4 551)">
|
||||
<title>blockchain</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-551 757,-551 757,5 -4,5"/>
|
||||
<text text-anchor="middle" x="376" y="-8.4" font-family="Sans" font-size="14.00">Evaluation Stack Over Time During Succesful P2PKH Script Validation</text>
|
||||
<g id="graph2" class="cluster"><title>cluster_alice</title>
|
||||
<polygon fill="grey" stroke="black" points="8,-462 8,-539 710,-539 710,-462 8,-462"/>
|
||||
<text text-anchor="middle" x="359" y="-522.4" font-family="Sans" font-size="14.00">Instructions And Data Provided By Alice In Transaction #1's Output Script</text>
|
||||
</g>
|
||||
<g id="graph3" class="cluster"><title>cluster_bob</title>
|
||||
<polygon fill="grey" stroke="black" points="8,-377 8,-454 710,-454 710,-377 8,-377"/>
|
||||
<text text-anchor="middle" x="359" y="-437.4" font-family="Sans" font-size="14.00">Data Provided By Bob In Transaction #2's Input ScriptSig</text>
|
||||
</g>
|
||||
<!-- alice_opchecksig -->
|
||||
<g id="node2" class="node"><title>alice_opchecksig</title>
|
||||
<polygon fill="none" stroke="black" points="702,-506 614,-506 614,-470 702,-470 702,-506"/>
|
||||
<text text-anchor="middle" x="658" y="-483.9" font-family="Sans" font-size="14.00">CHECKSIG</text>
|
||||
</g>
|
||||
<!-- bob_opchecksig -->
|
||||
<!-- alice_opchecksig->bob_opchecksig -->
|
||||
<!-- alice_opequalverify -->
|
||||
<g id="node3" class="node"><title>alice_opequalverify</title>
|
||||
<polygon fill="none" stroke="black" points="610,-506 468,-506 468,-470 610,-470 610,-506"/>
|
||||
<text text-anchor="middle" x="539" y="-483.9" font-family="Sans" font-size="14.00">OP_EQUALVERIFY</text>
|
||||
</g>
|
||||
<!-- bob_opequalverify -->
|
||||
<!-- alice_opequalverify->bob_opequalverify -->
|
||||
<!-- alice_pubkeyhash -->
|
||||
<g id="node4" class="node"><title>alice_pubkeyhash</title>
|
||||
<ellipse fill="none" stroke="black" cx="414" cy="-488" rx="50.2242" ry="18"/>
|
||||
<text text-anchor="middle" x="414" y="-483.9" font-family="Sans" font-size="14.00">Pk Hash</text>
|
||||
</g>
|
||||
<!-- bob_pubkeyhash -->
|
||||
<!-- alice_pubkeyhash->bob_pubkeyhash -->
|
||||
<!-- alice_ophash -->
|
||||
<g id="node5" class="node"><title>alice_ophash</title>
|
||||
<polygon fill="none" stroke="black" points="360,-506 250,-506 250,-470 360,-470 360,-506"/>
|
||||
<text text-anchor="middle" x="305" y="-483.9" font-family="Sans" font-size="14.00">OP_HASH160</text>
|
||||
</g>
|
||||
<!-- bob_ophash -->
|
||||
<!-- alice_ophash->bob_ophash -->
|
||||
<!-- alice_opdup -->
|
||||
<g id="node6" class="node"><title>alice_opdup</title>
|
||||
<polygon fill="none" stroke="black" points="246,-506 172,-506 172,-470 246,-470 246,-506"/>
|
||||
<text text-anchor="middle" x="209" y="-483.9" font-family="Sans" font-size="14.00">OP_DUP</text>
|
||||
</g>
|
||||
<!-- bob_opdup -->
|
||||
<!-- alice_opdup->bob_opdup -->
|
||||
<!-- invis2_1 -->
|
||||
<!-- alice_opdup->invis2_1 -->
|
||||
<g id="edge40" class="edge"><title>alice_opdup->invis2_1</title>
|
||||
<path fill="none" stroke="black" stroke-dasharray="1,5" d="M209.16,-469.647C209.559,-423.956 210.588,-306.178 210.905,-269.84"/>
|
||||
<polygon fill="black" stroke="black" points="214.406,-269.73 210.994,-259.7 207.407,-269.669 214.406,-269.73"/>
|
||||
</g>
|
||||
<!-- alice_pubkey -->
|
||||
<!-- bob_pubkey -->
|
||||
<g id="node15" class="node"><title>bob_pubkey</title>
|
||||
<ellipse fill="none" stroke="black" cx="121" cy="-403" rx="46.7546" ry="18"/>
|
||||
<text text-anchor="middle" x="121" y="-398.9" font-family="Sans" font-size="14.00">PubKey</text>
|
||||
</g>
|
||||
<!-- alice_pubkey->bob_pubkey -->
|
||||
<!-- alice_sig -->
|
||||
<!-- bob_sig -->
|
||||
<g id="node16" class="node"><title>bob_sig</title>
|
||||
<ellipse fill="none" stroke="black" cx="43" cy="-403" rx="27" ry="18"/>
|
||||
<text text-anchor="middle" x="43" y="-398.9" font-family="Sans" font-size="14.00">Sig</text>
|
||||
</g>
|
||||
<!-- alice_sig->bob_sig -->
|
||||
<!-- invis5_0 -->
|
||||
<!-- bob_opchecksig->invis5_0 -->
|
||||
<!-- stack7_opchecksig -->
|
||||
<g id="node45" class="node"><title>stack7_opchecksig</title>
|
||||
<polygon fill="lightgrey" stroke="black" points="723,-205 607,-205 607,-169 723,-169 723,-205"/>
|
||||
<text text-anchor="middle" x="665" y="-182.9" font-family="Sans" font-size="14.00">OP_CHECKSIG</text>
|
||||
</g>
|
||||
<!-- bob_opchecksig->stack7_opchecksig -->
|
||||
<!-- stack6_opequalverify -->
|
||||
<g id="node48" class="node"><title>stack6_opequalverify</title>
|
||||
<polygon fill="lightgrey" stroke="black" points="610,-349 468,-349 468,-313 610,-313 610,-349"/>
|
||||
<text text-anchor="middle" x="539" y="-326.9" font-family="Sans" font-size="14.00">OP_EQUALVERIFY</text>
|
||||
</g>
|
||||
<!-- bob_opequalverify->stack6_opequalverify -->
|
||||
<!-- invis4_0 -->
|
||||
<!-- bob_pubkeyhash->invis4_0 -->
|
||||
<!-- stack5_pubkeyhash -->
|
||||
<g id="node53" class="node"><title>stack5_pubkeyhash</title>
|
||||
<ellipse fill="none" stroke="black" cx="420" cy="-259" rx="50.2242" ry="18"/>
|
||||
<text text-anchor="middle" x="420" y="-254.9" font-family="Sans" font-size="14.00">Pk Hash</text>
|
||||
</g>
|
||||
<!-- bob_pubkeyhash->stack5_pubkeyhash -->
|
||||
<!-- invis3_0 -->
|
||||
<!-- bob_ophash->invis3_0 -->
|
||||
<!-- stack4_ophash -->
|
||||
<g id="node57" class="node"><title>stack4_ophash</title>
|
||||
<polygon fill="lightgrey" stroke="black" points="365,-277 255,-277 255,-241 365,-241 365,-277"/>
|
||||
<text text-anchor="middle" x="310" y="-254.9" font-family="Sans" font-size="14.00">OP_HASH160</text>
|
||||
</g>
|
||||
<!-- bob_ophash->stack4_ophash -->
|
||||
<!-- invis2_0 -->
|
||||
<!-- bob_opdup->invis2_0 -->
|
||||
<!-- invis1_0 -->
|
||||
<!-- bob_pubkey->invis1_0 -->
|
||||
<!-- stack2_pubkey -->
|
||||
<g id="node64" class="node"><title>stack2_pubkey</title>
|
||||
<ellipse fill="none" stroke="black" cx="114" cy="-115" rx="46.7546" ry="18"/>
|
||||
<text text-anchor="middle" x="114" y="-110.9" font-family="Sans" font-size="14.00">PubKey</text>
|
||||
</g>
|
||||
<!-- bob_pubkey->stack2_pubkey -->
|
||||
<!-- invis0_0 -->
|
||||
<!-- bob_sig->invis0_0 -->
|
||||
<!-- invis0_1 -->
|
||||
<!-- bob_sig->invis0_1 -->
|
||||
<g id="edge25" class="edge"><title>bob_sig->invis0_1</title>
|
||||
<path fill="none" stroke="black" stroke-dasharray="1,5" d="M43.1267,-384.762C43.338,-354.322 43.7563,-294.095 43.9259,-269.668"/>
|
||||
<polygon fill="black" stroke="black" points="47.4265,-269.584 43.9961,-259.56 40.4267,-269.535 47.4265,-269.584"/>
|
||||
</g>
|
||||
<!-- invis0_0->invis0_1 -->
|
||||
<!-- invis0_2 -->
|
||||
<!-- invis0_1->invis0_2 -->
|
||||
<!-- invis0_3 -->
|
||||
<!-- invis0_2->invis0_3 -->
|
||||
<!-- stack1_sig -->
|
||||
<g id="node66" class="node"><title>stack1_sig</title>
|
||||
<ellipse fill="none" stroke="black" cx="44" cy="-43" rx="27" ry="18"/>
|
||||
<text text-anchor="middle" x="44" y="-38.9" font-family="Sans" font-size="14.00">Sig</text>
|
||||
</g>
|
||||
<!-- invis0_3->stack1_sig -->
|
||||
<!-- invis1_1 -->
|
||||
<!-- invis1_0->invis1_1 -->
|
||||
<!-- invis1_2 -->
|
||||
<!-- invis1_1->invis1_2 -->
|
||||
<!-- invis1_2->stack2_pubkey -->
|
||||
<!-- invis2_0->invis2_1 -->
|
||||
<!-- stack3_opdup -->
|
||||
<g id="node61" class="node"><title>stack3_opdup</title>
|
||||
<polygon fill="lightgrey" stroke="black" points="249,-205 175,-205 175,-169 249,-169 249,-205"/>
|
||||
<text text-anchor="middle" x="212" y="-182.9" font-family="Sans" font-size="14.00">OP_DUP</text>
|
||||
</g>
|
||||
<!-- invis2_1->stack3_opdup -->
|
||||
<!-- invis3_0->stack4_ophash -->
|
||||
<!-- invis4_0->stack5_pubkeyhash -->
|
||||
<!-- invis5_1 -->
|
||||
<!-- invis5_0->invis5_1 -->
|
||||
<!-- invis5_1->stack7_opchecksig -->
|
||||
<!-- invis6_0 -->
|
||||
<!-- invis6_1 -->
|
||||
<!-- invis6_0->invis6_1 -->
|
||||
<!-- invis6_2 -->
|
||||
<!-- invis6_1->invis6_2 -->
|
||||
<!-- invis6_3 -->
|
||||
<!-- invis6_2->invis6_3 -->
|
||||
<!-- invis6_4 -->
|
||||
<!-- invis6_3->invis6_4 -->
|
||||
<!-- invis6_5 -->
|
||||
<!-- invis6_4->invis6_5 -->
|
||||
<!-- TRUE -->
|
||||
<g id="node87" class="node"><title>TRUE</title>
|
||||
<polygon fill="none" stroke="black" points="752,-61 698,-61 698,-25 752,-25 752,-61"/>
|
||||
<text text-anchor="middle" x="725" y="-38.9" font-family="Sans" font-size="14.00">TRUE</text>
|
||||
</g>
|
||||
<!-- invis6_5->TRUE -->
|
||||
<!-- invis6_6 -->
|
||||
<!-- stack7_pubkey -->
|
||||
<g id="node46" class="node"><title>stack7_pubkey</title>
|
||||
<ellipse fill="lightgrey" stroke="black" cx="665" cy="-115" rx="46.7546" ry="18"/>
|
||||
<text text-anchor="middle" x="665" y="-110.9" font-family="Sans" font-size="14.00">PubKey</text>
|
||||
</g>
|
||||
<!-- stack7_opchecksig->stack7_pubkey -->
|
||||
<!-- stack7_opchecksig->TRUE -->
|
||||
<g id="edge86" class="edge"><title>stack7_opchecksig->TRUE</title>
|
||||
<path fill="none" stroke="black" d="M672.599,-168.762C682.923,-143.985 701.47,-99.4714 713.503,-70.5939"/>
|
||||
<polygon fill="black" stroke="black" points="716.847,-71.6666 717.463,-61.0896 710.386,-68.9742 716.847,-71.6666"/>
|
||||
</g>
|
||||
<!-- stack7_pubkey->stack7_opchecksig -->
|
||||
<g id="edge100" class="edge"><title>stack7_pubkey->stack7_opchecksig</title>
|
||||
<path fill="none" stroke="black" d="M666.328,-133.413C666.49,-141.059 666.538,-150.108 666.47,-158.573"/>
|
||||
<polygon fill="black" stroke="black" points="662.967,-158.782 666.323,-168.831 669.966,-158.883 662.967,-158.782"/>
|
||||
</g>
|
||||
<!-- stack7_sig -->
|
||||
<g id="node47" class="node"><title>stack7_sig</title>
|
||||
<ellipse fill="lightgrey" stroke="black" cx="665" cy="-43" rx="27" ry="18"/>
|
||||
<text text-anchor="middle" x="665" y="-38.9" font-family="Sans" font-size="14.00">Sig</text>
|
||||
</g>
|
||||
<!-- stack7_pubkey->stack7_sig -->
|
||||
<!-- stack7_sig->stack7_pubkey -->
|
||||
<g id="edge102" class="edge"><title>stack7_sig->stack7_pubkey</title>
|
||||
<path fill="none" stroke="black" d="M666.328,-61.4133C666.49,-69.0593 666.538,-78.1084 666.47,-86.5726"/>
|
||||
<polygon fill="black" stroke="black" points="662.967,-86.7821 666.323,-96.8314 669.966,-86.8827 662.967,-86.7821"/>
|
||||
</g>
|
||||
<!-- stack6_pubkeyhash -->
|
||||
<g id="node49" class="node"><title>stack6_pubkeyhash</title>
|
||||
<ellipse fill="lightgrey" stroke="black" cx="539" cy="-259" rx="50.2242" ry="18"/>
|
||||
<text text-anchor="middle" x="539" y="-254.9" font-family="Sans" font-size="14.00">Pk Hash</text>
|
||||
</g>
|
||||
<!-- stack6_opequalverify->stack6_pubkeyhash -->
|
||||
<!-- stack6_pubkeyhash->stack6_opequalverify -->
|
||||
<g id="edge96" class="edge"><title>stack6_pubkeyhash->stack6_opequalverify</title>
|
||||
<path fill="none" stroke="black" d="M540.328,-277.413C540.49,-285.059 540.538,-294.108 540.47,-302.573"/>
|
||||
<polygon fill="black" stroke="black" points="536.967,-302.782 540.323,-312.831 543.966,-302.883 536.967,-302.782"/>
|
||||
</g>
|
||||
<!-- stack6_ophash -->
|
||||
<g id="node50" class="node"><title>stack6_ophash</title>
|
||||
<polygon fill="lightgrey" stroke="black" points="575,-205 503,-205 503,-169 575,-169 575,-205"/>
|
||||
<text text-anchor="middle" x="539" y="-182.9" font-family="Sans" font-size="14.00">Pk Hash</text>
|
||||
</g>
|
||||
<!-- stack6_pubkeyhash->stack6_ophash -->
|
||||
<!-- stack6_ophash->stack6_pubkeyhash -->
|
||||
<g id="edge98" class="edge"><title>stack6_ophash->stack6_pubkeyhash</title>
|
||||
<path fill="none" stroke="black" d="M540.328,-205.413C540.49,-213.059 540.538,-222.108 540.47,-230.573"/>
|
||||
<polygon fill="black" stroke="black" points="536.967,-230.782 540.323,-240.831 543.966,-230.883 536.967,-230.782"/>
|
||||
</g>
|
||||
<!-- stack6_pubkey -->
|
||||
<g id="node51" class="node"><title>stack6_pubkey</title>
|
||||
<ellipse fill="none" stroke="black" cx="539" cy="-115" rx="46.7546" ry="18"/>
|
||||
<text text-anchor="middle" x="539" y="-110.9" font-family="Sans" font-size="14.00">PubKey</text>
|
||||
</g>
|
||||
<!-- stack6_ophash->stack6_pubkey -->
|
||||
<!-- stack6_sig -->
|
||||
<g id="node52" class="node"><title>stack6_sig</title>
|
||||
<ellipse fill="none" stroke="black" cx="539" cy="-43" rx="27" ry="18"/>
|
||||
<text text-anchor="middle" x="539" y="-38.9" font-family="Sans" font-size="14.00">Sig</text>
|
||||
</g>
|
||||
<!-- stack6_pubkey->stack6_sig -->
|
||||
<!-- stack5_ophash -->
|
||||
<g id="node54" class="node"><title>stack5_ophash</title>
|
||||
<polygon fill="none" stroke="black" points="456,-205 384,-205 384,-169 456,-169 456,-205"/>
|
||||
<text text-anchor="middle" x="420" y="-182.9" font-family="Sans" font-size="14.00">Pk Hash</text>
|
||||
</g>
|
||||
<!-- stack5_pubkeyhash->stack5_ophash -->
|
||||
<!-- stack5_pubkey -->
|
||||
<g id="node55" class="node"><title>stack5_pubkey</title>
|
||||
<ellipse fill="none" stroke="black" cx="420" cy="-115" rx="46.7546" ry="18"/>
|
||||
<text text-anchor="middle" x="420" y="-110.9" font-family="Sans" font-size="14.00">PubKey</text>
|
||||
</g>
|
||||
<!-- stack5_ophash->stack5_pubkey -->
|
||||
<!-- stack5_sig -->
|
||||
<g id="node56" class="node"><title>stack5_sig</title>
|
||||
<ellipse fill="none" stroke="black" cx="420" cy="-43" rx="27" ry="18"/>
|
||||
<text text-anchor="middle" x="420" y="-38.9" font-family="Sans" font-size="14.00">Sig</text>
|
||||
</g>
|
||||
<!-- stack5_pubkey->stack5_sig -->
|
||||
<!-- stack4_ophash->stack5_ophash -->
|
||||
<g id="edge92" class="edge"><title>stack4_ophash->stack5_ophash</title>
|
||||
<path fill="none" stroke="black" d="M337.758,-240.831C351.697,-231.707 368.76,-220.539 383.723,-210.745"/>
|
||||
<polygon fill="black" stroke="black" points="385.801,-213.568 392.251,-205.163 381.967,-207.711 385.801,-213.568"/>
|
||||
</g>
|
||||
<!-- stack4_opdup -->
|
||||
<g id="node58" class="node"><title>stack4_opdup</title>
|
||||
<polygon fill="lightgrey" stroke="black" points="344,-205 276,-205 276,-169 344,-169 344,-205"/>
|
||||
<text text-anchor="middle" x="310" y="-182.9" font-family="Sans" font-size="14.00">PubKey</text>
|
||||
</g>
|
||||
<!-- stack4_ophash->stack4_opdup -->
|
||||
<!-- stack4_opdup->stack4_ophash -->
|
||||
<g id="edge94" class="edge"><title>stack4_opdup->stack4_ophash</title>
|
||||
<path fill="none" stroke="black" d="M311.328,-205.413C311.49,-213.059 311.538,-222.108 311.47,-230.573"/>
|
||||
<polygon fill="black" stroke="black" points="307.967,-230.782 311.323,-240.831 314.966,-230.883 307.967,-230.782"/>
|
||||
</g>
|
||||
<!-- stack4_pubkey -->
|
||||
<g id="node59" class="node"><title>stack4_pubkey</title>
|
||||
<ellipse fill="none" stroke="black" cx="310" cy="-115" rx="46.7546" ry="18"/>
|
||||
<text text-anchor="middle" x="310" y="-110.9" font-family="Sans" font-size="14.00">PubKey</text>
|
||||
</g>
|
||||
<!-- stack4_opdup->stack4_pubkey -->
|
||||
<!-- stack4_sig -->
|
||||
<g id="node60" class="node"><title>stack4_sig</title>
|
||||
<ellipse fill="none" stroke="black" cx="310" cy="-43" rx="27" ry="18"/>
|
||||
<text text-anchor="middle" x="310" y="-38.9" font-family="Sans" font-size="14.00">Sig</text>
|
||||
</g>
|
||||
<!-- stack4_pubkey->stack4_sig -->
|
||||
<!-- stack3_opdup->stack4_opdup -->
|
||||
<g id="edge88" class="edge"><title>stack3_opdup->stack4_opdup</title>
|
||||
<path fill="none" stroke="black" d="M249.133,-187C254.542,-187 259.951,-187 265.36,-187"/>
|
||||
<polygon fill="black" stroke="black" points="265.762,-190.5 275.762,-187 265.762,-183.5 265.762,-190.5"/>
|
||||
</g>
|
||||
<!-- stack3_pubkey -->
|
||||
<g id="node62" class="node"><title>stack3_pubkey</title>
|
||||
<ellipse fill="lightgrey" stroke="black" cx="212" cy="-115" rx="46.7546" ry="18"/>
|
||||
<text text-anchor="middle" x="212" y="-110.9" font-family="Sans" font-size="14.00">PubKey</text>
|
||||
</g>
|
||||
<!-- stack3_opdup->stack3_pubkey -->
|
||||
<!-- stack3_pubkey->stack3_opdup -->
|
||||
<g id="edge90" class="edge"><title>stack3_pubkey->stack3_opdup</title>
|
||||
<path fill="none" stroke="black" d="M213.328,-133.413C213.49,-141.059 213.538,-150.108 213.47,-158.573"/>
|
||||
<polygon fill="black" stroke="black" points="209.967,-158.782 213.323,-168.831 216.966,-158.883 209.967,-158.782"/>
|
||||
</g>
|
||||
<!-- stack3_sig -->
|
||||
<g id="node63" class="node"><title>stack3_sig</title>
|
||||
<ellipse fill="none" stroke="black" cx="212" cy="-43" rx="27" ry="18"/>
|
||||
<text text-anchor="middle" x="212" y="-38.9" font-family="Sans" font-size="14.00">Sig</text>
|
||||
</g>
|
||||
<!-- stack3_pubkey->stack3_sig -->
|
||||
<!-- stack2_sig -->
|
||||
<g id="node65" class="node"><title>stack2_sig</title>
|
||||
<ellipse fill="none" stroke="black" cx="114" cy="-43" rx="27" ry="18"/>
|
||||
<text text-anchor="middle" x="114" y="-38.9" font-family="Sans" font-size="14.00">Sig</text>
|
||||
</g>
|
||||
<!-- stack2_pubkey->stack2_sig -->
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 16 KiB |
29
img/dev/en-payment-processing.dot
Normal file
|
@ -0,0 +1,29 @@
|
|||
graph unique {
|
||||
size="6.66";
|
||||
rankdir=LR;
|
||||
//ratio=fill;
|
||||
splines=ortho;
|
||||
|
||||
overlap = false;
|
||||
|
||||
edge [ dir = forward, penwidth=1.75 ];
|
||||
node [ shape = box, penwidth=1.75 ];
|
||||
|
||||
submit_order [ style = invis, width=0, height=0, label = "", ];
|
||||
calc_total [ label = "Price\nOrder\nIn\nBTC" ]
|
||||
request_payment [ label = "Request\nPayment" ]
|
||||
verify_payment [ label = "Verify\nPayment\n& Fulfill\nOrder" ]
|
||||
issue_refund [ label = "Issue\nRefund\n(Sometimes)" ]
|
||||
pay_expenses [ label = "Disburse\nIncome\n(Optional)" ]
|
||||
rebill_recurring [ label = "Rebill\nRecurring\n(Optional)" ]
|
||||
|
||||
|
||||
submit_order -- calc_total [ label = "New\nOrder", minlen = 1 ]
|
||||
|
||||
calc_total -- request_payment -- verify_payment [ weight = 100 ]
|
||||
verify_payment -- issue_refund -- pay_expenses -- rebill_recurring [ style = dashed, weight = 100 ]
|
||||
rebill_recurring -- calc_total [ style = dashed ]
|
||||
|
||||
label = " \nPayment Processing With Bitcoin (From A Receiver's Perspective)"
|
||||
}
|
||||
|
BIN
img/dev/en-payment-processing.png
Normal file
After Width: | Height: | Size: 6 KiB |
96
img/dev/en-payment-processing.svg
Normal file
|
@ -0,0 +1,96 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: unique Pages: 1 -->
|
||||
<svg width="480pt" height="97pt"
|
||||
viewBox="0.00 0.00 480.00 96.75" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.628272 0.628272) rotate(0) translate(4 150)">
|
||||
<title>unique</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-150 761,-150 761,5 -4,5"/>
|
||||
<text text-anchor="middle" x="378" y="-25.4" font-family="Sans" font-size="14.00"> </text>
|
||||
<text text-anchor="middle" x="378" y="-8.4" font-family="Sans" font-size="14.00">Payment Processing With Bitcoin (From A Receiver's Perspective)</text>
|
||||
<!-- submit_order -->
|
||||
<!-- calc_total -->
|
||||
<g id="node2" class="node"><title>calc_total</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="134,-146 78,-146 78,-70 134,-70 134,-146"/>
|
||||
<text text-anchor="middle" x="106" y="-129.4" font-family="Sans" font-size="14.00">Price</text>
|
||||
<text text-anchor="middle" x="106" y="-112.4" font-family="Sans" font-size="14.00">Order</text>
|
||||
<text text-anchor="middle" x="106" y="-95.4" font-family="Sans" font-size="14.00">In</text>
|
||||
<text text-anchor="middle" x="106" y="-78.4" font-family="Sans" font-size="14.00">BTC</text>
|
||||
</g>
|
||||
<!-- submit_order--calc_total -->
|
||||
<g id="edge2" class="edge"><title>submit_order--calc_total</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M1.67051,-108C6.76584,-108 39.9259,-108 67.5146,-108"/>
|
||||
<polygon fill="black" stroke="black" points="67.7454,-111.5 77.7454,-108 67.7454,-104.5 67.7454,-111.5"/>
|
||||
<text text-anchor="middle" x="40" y="-129.4" font-family="Sans" font-size="14.00">New</text>
|
||||
<text text-anchor="middle" x="40" y="-112.4" font-family="Sans" font-size="14.00">Order</text>
|
||||
</g>
|
||||
<!-- request_payment -->
|
||||
<g id="node3" class="node"><title>request_payment</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="249,-129 173,-129 173,-87 249,-87 249,-129"/>
|
||||
<text text-anchor="middle" x="211" y="-112.4" font-family="Sans" font-size="14.00">Request</text>
|
||||
<text text-anchor="middle" x="211" y="-95.4" font-family="Sans" font-size="14.00">Payment</text>
|
||||
</g>
|
||||
<!-- calc_total--request_payment -->
|
||||
<g id="edge4" class="edge"><title>calc_total--request_payment</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M134.138,-108C142.703,-108 152.38,-108 161.907,-108"/>
|
||||
<polygon fill="black" stroke="black" points="162.126,-111.5 172.126,-108 162.126,-104.5 162.126,-111.5"/>
|
||||
</g>
|
||||
<!-- verify_payment -->
|
||||
<g id="node4" class="node"><title>verify_payment</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="365,-146 289,-146 289,-70 365,-70 365,-146"/>
|
||||
<text text-anchor="middle" x="327" y="-129.4" font-family="Sans" font-size="14.00">Verify</text>
|
||||
<text text-anchor="middle" x="327" y="-112.4" font-family="Sans" font-size="14.00">Payment</text>
|
||||
<text text-anchor="middle" x="327" y="-95.4" font-family="Sans" font-size="14.00">& Fulfill</text>
|
||||
<text text-anchor="middle" x="327" y="-78.4" font-family="Sans" font-size="14.00">Order</text>
|
||||
</g>
|
||||
<!-- request_payment--verify_payment -->
|
||||
<g id="edge5" class="edge"><title>request_payment--verify_payment</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M249.626,-108C258.726,-108 268.544,-108 278.031,-108"/>
|
||||
<polygon fill="black" stroke="black" points="278.147,-111.5 288.147,-108 278.147,-104.5 278.147,-111.5"/>
|
||||
</g>
|
||||
<!-- issue_refund -->
|
||||
<g id="node5" class="node"><title>issue_refund</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="507,-137.5 405,-137.5 405,-78.5 507,-78.5 507,-137.5"/>
|
||||
<text text-anchor="middle" x="456" y="-120.9" font-family="Sans" font-size="14.00">Issue</text>
|
||||
<text text-anchor="middle" x="456" y="-103.9" font-family="Sans" font-size="14.00">Refund</text>
|
||||
<text text-anchor="middle" x="456" y="-86.9" font-family="Sans" font-size="14.00">(Sometimes)</text>
|
||||
</g>
|
||||
<!-- verify_payment--issue_refund -->
|
||||
<g id="edge7" class="edge"><title>verify_payment--issue_refund</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="5,2" d="M365.704,-108C374.738,-108 384.579,-108 394.334,-108"/>
|
||||
<polygon fill="black" stroke="black" points="394.431,-111.5 404.431,-108 394.431,-104.5 394.431,-111.5"/>
|
||||
</g>
|
||||
<!-- pay_expenses -->
|
||||
<g id="node6" class="node"><title>pay_expenses</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="632,-137.5 546,-137.5 546,-78.5 632,-78.5 632,-137.5"/>
|
||||
<text text-anchor="middle" x="589" y="-120.9" font-family="Sans" font-size="14.00">Disburse</text>
|
||||
<text text-anchor="middle" x="589" y="-103.9" font-family="Sans" font-size="14.00">Income</text>
|
||||
<text text-anchor="middle" x="589" y="-86.9" font-family="Sans" font-size="14.00">(Optional)</text>
|
||||
</g>
|
||||
<!-- issue_refund--pay_expenses -->
|
||||
<g id="edge8" class="edge"><title>issue_refund--pay_expenses</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="5,2" d="M507.802,-108C516.917,-108 526.42,-108 535.578,-108"/>
|
||||
<polygon fill="black" stroke="black" points="535.733,-111.5 545.733,-108 535.733,-104.5 535.733,-111.5"/>
|
||||
</g>
|
||||
<!-- rebill_recurring -->
|
||||
<g id="node7" class="node"><title>rebill_recurring</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="756,-137.5 670,-137.5 670,-78.5 756,-78.5 756,-137.5"/>
|
||||
<text text-anchor="middle" x="713" y="-120.9" font-family="Sans" font-size="14.00">Rebill</text>
|
||||
<text text-anchor="middle" x="713" y="-103.9" font-family="Sans" font-size="14.00">Recurring</text>
|
||||
<text text-anchor="middle" x="713" y="-86.9" font-family="Sans" font-size="14.00">(Optional)</text>
|
||||
</g>
|
||||
<!-- pay_expenses--rebill_recurring -->
|
||||
<g id="edge9" class="edge"><title>pay_expenses--rebill_recurring</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="5,2" d="M632.021,-108C640.864,-108 650.278,-108 659.44,-108"/>
|
||||
<polygon fill="black" stroke="black" points="659.635,-111.5 669.635,-108 659.635,-104.5 659.635,-111.5"/>
|
||||
</g>
|
||||
<!-- rebill_recurring--calc_total -->
|
||||
<g id="edge11" class="edge"><title>rebill_recurring--calc_total</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="5,2" d="M669.979,-85.1016C634.165,-66.0393 589,-42 589,-42 211,-42 211,-42 211,-42 211,-42 173.093,-65.827 142.832,-84.8483"/>
|
||||
<polygon fill="black" stroke="black" points="140.742,-82.0282 134.138,-90.3132 144.467,-87.9547 140.742,-82.0282"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.5 KiB |
56
img/dev/en-payment-protocol.dot
Normal file
|
@ -0,0 +1,56 @@
|
|||
digraph paymentchannel {
|
||||
size=6.66;
|
||||
rankdir=LR;
|
||||
splines = true;
|
||||
nodesep = 0.4;
|
||||
|
||||
//edge [ minlen = 2 ];
|
||||
node [ style = invis, shape = box ];
|
||||
|
||||
subgraph cluster_client {
|
||||
c0;
|
||||
c2 [ style = "", label = "Pay 10 mBTC\nTo example.com\n(VERIFIED)\nExp. In 10 Min.\nMemo: [...]" ];
|
||||
c3 [ label = " \n \n \n \n \n \n " ];
|
||||
|
||||
label = "Spender"
|
||||
|
||||
}
|
||||
|
||||
subgraph cluster_wallet {
|
||||
w0;
|
||||
w1;
|
||||
w2 [ style = "", label = <<FONT FACE="Courier-Bold">Payment</FONT><BR/> <BR/>TX1<BR/>[TX...]<BR/>Memo<BR/>Refund<BR/>address(es)> ];
|
||||
w3;
|
||||
|
||||
label = "Spender's\nWallet"
|
||||
}
|
||||
subgraph cluster_merchant {
|
||||
subgraph cluster_payment_request {
|
||||
label = <<FONT FACE="Courier-Bold">Payment<BR/>Request</FONT>>
|
||||
m1 [ style = "", label = <<FONT FACE="Courier-Bold">Payment<BR/>Details</FONT><BR/> <BR/><FONT FACE="Courier-Bold">Outputs</FONT><BR/>Exp. Time<BR/>Memo<BR/>Pay URL<BR/>Ref #>];
|
||||
sig [ style = "", label = "X.509 Sig" ];
|
||||
}
|
||||
m3 [ style = "", label = "TX1\n[TX...]\nMemo" ];
|
||||
|
||||
label = "Receiver"
|
||||
}
|
||||
|
||||
uri [ style = "", label = "Pay Now\nLink/QR Code" ]
|
||||
|
||||
uri -> c0 [constraint = false, label = "bitcoin:\n ?r=http://example.com/pay/123\n \n \n \n"];
|
||||
c0 -> w0 [ label = "I clicked a\nbitcoin: URI", weight = 100 ];
|
||||
w0 -> m1 [ label = "Send the\ninvoice from\n[...]/pay/123", weight = 100 ];
|
||||
|
||||
m1 -> w1 [ label = "Here's the invoice" ];
|
||||
w1 -> c2 [ label = "Do you agree to\nthe invoice terms?" ];
|
||||
|
||||
p2p [ style = "invis", label="", width=0, height=0 ];
|
||||
c2 -> w2 [ label = "Yes.\nPay the invoice" ];
|
||||
w2 -> m3 [ label = "TX(es) attached\nwith refund\naddresses and\na memo" ];
|
||||
m3 -> p2p [ label = "", style = dashed ]
|
||||
|
||||
m3 -> w3 [ label = <<FONT FACE="Courier-Bold">PaymentACK</FONT><BR/>Thanks!<BR/>payment accepted<BR/>for processing> ];
|
||||
w3 -> c3 [ label = "Payment accepted;\nyou can go do\nsomething else" ];
|
||||
|
||||
label = "\nThe Bitcoin Payment Protocol As Described In BIP70"
|
||||
}
|
BIN
img/dev/en-payment-protocol.png
Normal file
After Width: | Height: | Size: 17 KiB |
164
img/dev/en-payment-protocol.svg
Normal file
|
@ -0,0 +1,164 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: paymentchannel Pages: 1 -->
|
||||
<svg width="480pt" height="362pt"
|
||||
viewBox="0.00 0.00 480.00 362.34" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.668524 0.668524) rotate(0) translate(4 538)">
|
||||
<title>paymentchannel</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-538 715,-538 715,5 -4,5"/>
|
||||
<text text-anchor="middle" x="355" y="-8.4" font-family="Sans" font-size="14.00">The Bitcoin Payment Protocol As Described In BIP70</text>
|
||||
<g id="graph2" class="cluster"><title>cluster_client</title>
|
||||
<polygon fill="none" stroke="black" points="8,-58 8,-411 152,-411 152,-58 8,-58"/>
|
||||
<text text-anchor="middle" x="80" y="-394.4" font-family="Sans" font-size="14.00">Spender</text>
|
||||
</g>
|
||||
<g id="graph3" class="cluster"><title>cluster_wallet</title>
|
||||
<polygon fill="none" stroke="black" points="304,-49 304,-428 416,-428 416,-49 304,-49"/>
|
||||
<text text-anchor="middle" x="360" y="-411.4" font-family="Sans" font-size="14.00">Spender's</text>
|
||||
<text text-anchor="middle" x="360" y="-394.4" font-family="Sans" font-size="14.00">Wallet</text>
|
||||
</g>
|
||||
<g id="graph4" class="cluster"><title>cluster_merchant</title>
|
||||
<polygon fill="none" stroke="black" points="562,-129 562,-514 680,-514 680,-129 562,-129"/>
|
||||
<text text-anchor="middle" x="621" y="-497.4" font-family="Sans" font-size="14.00">Receiver</text>
|
||||
</g>
|
||||
<g id="graph5" class="cluster"><title>cluster_payment_request</title>
|
||||
<polygon fill="none" stroke="black" points="570,-216 570,-481 672,-481 672,-216 570,-216"/>
|
||||
<text text-anchor="start" x="592" y="-466.733" font-family="Courier,monospace" font-weight="bold" font-size="14.00">Payment</text>
|
||||
<text text-anchor="start" x="592" y="-449.933" font-family="Courier,monospace" font-weight="bold" font-size="14.00">Request</text>
|
||||
</g>
|
||||
<!-- c0 -->
|
||||
<!-- w0 -->
|
||||
<!-- c0->w0 -->
|
||||
<g id="edge8" class="edge"><title>c0->w0</title>
|
||||
<path fill="none" stroke="black" d="M107.102,-360C157.491,-360 265.657,-360 322.827,-360"/>
|
||||
<polygon fill="black" stroke="black" points="322.883,-363.5 332.883,-360 322.883,-356.5 322.883,-363.5"/>
|
||||
<text text-anchor="middle" x="228" y="-381.4" font-family="Sans" font-size="14.00">I clicked a</text>
|
||||
<text text-anchor="middle" x="228" y="-364.4" font-family="Sans" font-size="14.00">bitcoin: URI</text>
|
||||
</g>
|
||||
<!-- c2 -->
|
||||
<g id="node3" class="node"><title>c2</title>
|
||||
<polygon fill="none" stroke="black" points="143,-313.5 17,-313.5 17,-220.5 143,-220.5 143,-313.5"/>
|
||||
<text text-anchor="middle" x="80" y="-296.9" font-family="Sans" font-size="14.00">Pay 10 mBTC</text>
|
||||
<text text-anchor="middle" x="80" y="-279.9" font-family="Sans" font-size="14.00">To example.com</text>
|
||||
<text text-anchor="middle" x="80" y="-262.9" font-family="Sans" font-size="14.00">(VERIFIED)</text>
|
||||
<text text-anchor="middle" x="80" y="-245.9" font-family="Sans" font-size="14.00">Exp. In 10 Min.</text>
|
||||
<text text-anchor="middle" x="80" y="-228.9" font-family="Sans" font-size="14.00">Memo: [...]</text>
|
||||
</g>
|
||||
<!-- w2 -->
|
||||
<g id="node8" class="node"><title>w2</title>
|
||||
<polygon fill="none" stroke="black" points="408,-248 312,-248 312,-122 408,-122 408,-248"/>
|
||||
<text text-anchor="start" x="331" y="-233.733" font-family="Courier,monospace" font-weight="bold" font-size="14.00">Payment</text>
|
||||
<text text-anchor="start" x="357.5" y="-216.933" font-family="Sans" font-size="14.00"> </text>
|
||||
<text text-anchor="start" x="345.5" y="-200.133" font-family="Sans" font-size="14.00">TX1</text>
|
||||
<text text-anchor="start" x="338" y="-183.333" font-family="Sans" font-size="14.00">[TX...]</text>
|
||||
<text text-anchor="start" x="339" y="-166.533" font-family="Sans" font-size="14.00">Memo</text>
|
||||
<text text-anchor="start" x="335.5" y="-149.733" font-family="Sans" font-size="14.00">Refund</text>
|
||||
<text text-anchor="start" x="320.5" y="-132.933" font-family="Sans" font-size="14.00">address(es)</text>
|
||||
</g>
|
||||
<!-- c2->w2 -->
|
||||
<g id="edge16" class="edge"><title>c2->w2</title>
|
||||
<path fill="none" stroke="black" d="M143.737,-241.24C149.873,-239.028 156.033,-236.91 162,-235 208.538,-220.107 262.354,-206.758 302.124,-197.607"/>
|
||||
<polygon fill="black" stroke="black" points="302.948,-201.009 311.919,-195.373 301.391,-194.185 302.948,-201.009"/>
|
||||
<text text-anchor="middle" x="228" y="-256.4" font-family="Sans" font-size="14.00">Yes.</text>
|
||||
<text text-anchor="middle" x="228" y="-239.4" font-family="Sans" font-size="14.00">Pay the invoice</text>
|
||||
</g>
|
||||
<!-- c3 -->
|
||||
<!-- m1 -->
|
||||
<g id="node12" class="node"><title>m1</title>
|
||||
<polygon fill="none" stroke="black" points="664,-431.5 578,-431.5 578,-288.5 664,-288.5 664,-431.5"/>
|
||||
<text text-anchor="start" x="592" y="-417.233" font-family="Courier,monospace" font-weight="bold" font-size="14.00">Payment</text>
|
||||
<text text-anchor="start" x="592" y="-400.433" font-family="Courier,monospace" font-weight="bold" font-size="14.00">Details</text>
|
||||
<text text-anchor="start" x="618.5" y="-383.633" font-family="Sans" font-size="14.00"> </text>
|
||||
<text text-anchor="start" x="592" y="-366.833" font-family="Courier,monospace" font-weight="bold" font-size="14.00">Outputs</text>
|
||||
<text text-anchor="start" x="586.5" y="-350.033" font-family="Sans" font-size="14.00">Exp. Time</text>
|
||||
<text text-anchor="start" x="600" y="-333.233" font-family="Sans" font-size="14.00">Memo</text>
|
||||
<text text-anchor="start" x="592" y="-316.433" font-family="Sans" font-size="14.00">Pay URL</text>
|
||||
<text text-anchor="start" x="601.5" y="-299.633" font-family="Sans" font-size="14.00">Ref #</text>
|
||||
</g>
|
||||
<!-- w0->m1 -->
|
||||
<g id="edge10" class="edge"><title>w0->m1</title>
|
||||
<path fill="none" stroke="black" d="M387.438,-360C429.981,-360 512.644,-360 567.338,-360"/>
|
||||
<polygon fill="black" stroke="black" points="567.546,-363.5 577.546,-360 567.546,-356.5 567.546,-363.5"/>
|
||||
<text text-anchor="middle" x="490" y="-398.4" font-family="Sans" font-size="14.00">Send the</text>
|
||||
<text text-anchor="middle" x="490" y="-381.4" font-family="Sans" font-size="14.00">invoice from</text>
|
||||
<text text-anchor="middle" x="490" y="-364.4" font-family="Sans" font-size="14.00">[...]/pay/123</text>
|
||||
</g>
|
||||
<!-- w1 -->
|
||||
<!-- w1->c2 -->
|
||||
<g id="edge14" class="edge"><title>w1->c2</title>
|
||||
<path fill="none" stroke="black" d="M332.709,-292.271C291.606,-288.161 212.37,-280.237 153.532,-274.353"/>
|
||||
<polygon fill="black" stroke="black" points="153.835,-270.866 143.536,-273.354 153.138,-277.831 153.835,-270.866"/>
|
||||
<text text-anchor="middle" x="228" y="-310.4" font-family="Sans" font-size="14.00">Do you agree to</text>
|
||||
<text text-anchor="middle" x="228" y="-293.4" font-family="Sans" font-size="14.00">the invoice terms?</text>
|
||||
</g>
|
||||
<!-- m3 -->
|
||||
<g id="node14" class="node"><title>m3</title>
|
||||
<polygon fill="none" stroke="black" points="651,-195.5 591,-195.5 591,-136.5 651,-136.5 651,-195.5"/>
|
||||
<text text-anchor="middle" x="621" y="-178.9" font-family="Sans" font-size="14.00">TX1</text>
|
||||
<text text-anchor="middle" x="621" y="-161.9" font-family="Sans" font-size="14.00">[TX...]</text>
|
||||
<text text-anchor="middle" x="621" y="-144.9" font-family="Sans" font-size="14.00">Memo</text>
|
||||
</g>
|
||||
<!-- w2->m3 -->
|
||||
<g id="edge18" class="edge"><title>w2->m3</title>
|
||||
<path fill="none" stroke="black" d="M408.176,-181.493C457.747,-177.884 534.104,-172.326 580.616,-168.94"/>
|
||||
<polygon fill="black" stroke="black" points="580.913,-172.428 590.632,-168.211 580.404,-165.446 580.913,-172.428"/>
|
||||
<text text-anchor="middle" x="490" y="-235.4" font-family="Sans" font-size="14.00">TX(es) attached</text>
|
||||
<text text-anchor="middle" x="490" y="-218.4" font-family="Sans" font-size="14.00">with refund</text>
|
||||
<text text-anchor="middle" x="490" y="-201.4" font-family="Sans" font-size="14.00">addresses and</text>
|
||||
<text text-anchor="middle" x="490" y="-184.4" font-family="Sans" font-size="14.00">a memo</text>
|
||||
</g>
|
||||
<!-- w3 -->
|
||||
<!-- w3->c3 -->
|
||||
<g id="edge24" class="edge"><title>w3->c3</title>
|
||||
<path fill="none" stroke="black" d="M332.717,-79.6384C294.478,-86.2128 222.805,-98.8028 162,-111 147.281,-113.953 131.132,-117.443 117.086,-120.561"/>
|
||||
<polygon fill="black" stroke="black" points="116.277,-117.155 107.281,-122.752 117.804,-123.987 116.277,-117.155"/>
|
||||
<text text-anchor="middle" x="228" y="-149.4" font-family="Sans" font-size="14.00">Payment accepted;</text>
|
||||
<text text-anchor="middle" x="228" y="-132.4" font-family="Sans" font-size="14.00">you can go do</text>
|
||||
<text text-anchor="middle" x="228" y="-115.4" font-family="Sans" font-size="14.00">something else</text>
|
||||
</g>
|
||||
<!-- m1->w1 -->
|
||||
<g id="edge12" class="edge"><title>m1->w1</title>
|
||||
<path fill="none" stroke="black" d="M577.669,-343.512C569.849,-340.814 561.727,-338.19 554,-336 500.186,-320.751 436.533,-308.343 397.209,-301.312"/>
|
||||
<polygon fill="black" stroke="black" points="397.73,-297.85 387.273,-299.558 396.513,-304.743 397.73,-297.85"/>
|
||||
<text text-anchor="middle" x="490" y="-340.4" font-family="Sans" font-size="14.00">Here's the invoice</text>
|
||||
</g>
|
||||
<!-- sig -->
|
||||
<g id="node13" class="node"><title>sig</title>
|
||||
<polygon fill="none" stroke="black" points="663,-260 579,-260 579,-224 663,-224 663,-260"/>
|
||||
<text text-anchor="middle" x="621" y="-237.9" font-family="Sans" font-size="14.00">X.509 Sig</text>
|
||||
</g>
|
||||
<!-- m3->w3 -->
|
||||
<g id="edge22" class="edge"><title>m3->w3</title>
|
||||
<path fill="none" stroke="black" d="M600.465,-136.81C588.622,-122.336 572.435,-106.053 554,-97 503.9,-72.3953 437.986,-70.3411 397.33,-72.0072"/>
|
||||
<polygon fill="black" stroke="black" points="397.124,-68.513 387.314,-72.5144 397.478,-75.5041 397.124,-68.513"/>
|
||||
<text text-anchor="start" x="448.5" y="-154.733" font-family="Courier,monospace" font-weight="bold" font-size="14.00">PaymentACK</text>
|
||||
<text text-anchor="start" x="461.5" y="-137.933" font-family="Sans" font-size="14.00">Thanks!</text>
|
||||
<text text-anchor="start" x="426.5" y="-121.133" font-family="Sans" font-size="14.00">payment accepted</text>
|
||||
<text text-anchor="start" x="442" y="-104.333" font-family="Sans" font-size="14.00">for processing</text>
|
||||
</g>
|
||||
<!-- p2p -->
|
||||
<!-- m3->p2p -->
|
||||
<g id="edge20" class="edge"><title>m3->p2p</title>
|
||||
<path fill="none" stroke="black" stroke-dasharray="5,2" d="M651.285,-166C667.505,-166 686.488,-166 698.127,-166"/>
|
||||
<polygon fill="black" stroke="black" points="698.182,-169.5 708.182,-166 698.182,-162.5 698.182,-169.5"/>
|
||||
</g>
|
||||
<!-- uri -->
|
||||
<g id="node15" class="node"><title>uri</title>
|
||||
<polygon fill="none" stroke="black" points="135,-534 25,-534 25,-492 135,-492 135,-534"/>
|
||||
<text text-anchor="middle" x="80" y="-517.4" font-family="Sans" font-size="14.00">Pay Now</text>
|
||||
<text text-anchor="middle" x="80" y="-500.4" font-family="Sans" font-size="14.00">Link/QR Code</text>
|
||||
</g>
|
||||
<!-- uri->c0 -->
|
||||
<g id="edge6" class="edge"><title>uri->c0</title>
|
||||
<path fill="none" stroke="black" d="M80,-388.443C80,-418.379 80,-464.815 80,-491.726"/>
|
||||
<polygon fill="black" stroke="black" points="83.5,-388.228 80,-378.228 76.5,-388.228 83.5,-388.228"/>
|
||||
<text text-anchor="middle" x="194.5" y="-464.9" font-family="Sans" font-size="14.00">bitcoin:</text>
|
||||
<text text-anchor="middle" x="194.5" y="-447.9" font-family="Sans" font-size="14.00">  ?r=http://example.com/pay/123</text>
|
||||
<text text-anchor="middle" x="194.5" y="-430.9" font-family="Sans" font-size="14.00"> </text>
|
||||
<text text-anchor="middle" x="194.5" y="-413.9" font-family="Sans" font-size="14.00"> </text>
|
||||
<text text-anchor="middle" x="194.5" y="-396.9" font-family="Sans" font-size="14.00"> </text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 11 KiB |
25
img/dev/en-pooled-mining-overview.dot
Normal file
|
@ -0,0 +1,25 @@
|
|||
digraph {
|
||||
|
||||
size=6.25;
|
||||
rankdir=LR
|
||||
node [ shape = "box" ]
|
||||
splines = ortho;
|
||||
//ranksep = 10;
|
||||
nodesep = 0.5;
|
||||
|
||||
p2pnetwork [ label = "P2P\nNetwork" ]
|
||||
asic0 [ label = "ASIC" ];
|
||||
software [ label = "Mining\nSoftware" ]
|
||||
pool0 [ label = "Mining\nPool" ];
|
||||
|
||||
pool0 -> software [ label = "Prototype\nBlock→" ];
|
||||
p2pnetwork -> pool0 [ label = "TXes→" ];
|
||||
pool0 -> p2pnetwork [ label = "←Blocks" ];
|
||||
|
||||
software -> asic0 [ label = "Block\nHeaders &\nTargets→" ];
|
||||
asic0 -> software [ label = "←Headers\nBelow\nTarget" ];
|
||||
|
||||
software -> pool0 [ constraint = false, label = "←Shares" ];
|
||||
|
||||
label = "Pool-Based Bitcoin Mining Workflow"
|
||||
}
|
BIN
img/dev/en-pooled-mining-overview.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
78
img/dev/en-pooled-mining-overview.svg
Normal file
|
@ -0,0 +1,78 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: _anonymous_0 Pages: 1 -->
|
||||
<svg width="450pt" height="110pt"
|
||||
viewBox="0.00 0.00 450.00 110.20" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.765306 0.765306) rotate(0) translate(4 140)">
|
||||
<title>_anonymous_0</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-140 585,-140 585,5 -4,5"/>
|
||||
<text text-anchor="middle" x="290" y="-8.4" font-family="Sans" font-size="14.00">Pool-Based Bitcoin Mining Workflow</text>
|
||||
<!-- p2pnetwork -->
|
||||
<g id="node1" class="node"><title>p2pnetwork</title>
|
||||
<polygon fill="none" stroke="black" points="77,-100 1,-100 1,-58 77,-58 77,-100"/>
|
||||
<text text-anchor="middle" x="39" y="-83.4" font-family="Sans" font-size="14.00">P2P</text>
|
||||
<text text-anchor="middle" x="39" y="-66.4" font-family="Sans" font-size="14.00">Network</text>
|
||||
</g>
|
||||
<!-- pool0 -->
|
||||
<g id="node4" class="node"><title>pool0</title>
|
||||
<polygon fill="none" stroke="black" points="232,-100 170,-100 170,-58 232,-58 232,-100"/>
|
||||
<text text-anchor="middle" x="201" y="-83.4" font-family="Sans" font-size="14.00">Mining</text>
|
||||
<text text-anchor="middle" x="201" y="-66.4" font-family="Sans" font-size="14.00">Pool</text>
|
||||
</g>
|
||||
<!-- p2pnetwork->pool0 -->
|
||||
<g id="edge4" class="edge"><title>p2pnetwork->pool0</title>
|
||||
<path fill="none" stroke="black" d="M77.803,-79C102.457,-79 134.346,-79 159.503,-79"/>
|
||||
<polygon fill="black" stroke="black" points="159.831,-82.5001 169.831,-79 159.831,-75.5001 159.831,-82.5001"/>
|
||||
<text text-anchor="middle" x="124" y="-83.4" font-family="Sans" font-size="14.00">TXes→</text>
|
||||
</g>
|
||||
<!-- asic0 -->
|
||||
<g id="node2" class="node"><title>asic0</title>
|
||||
<polygon fill="none" stroke="black" points="580,-97 526,-97 526,-61 580,-61 580,-97"/>
|
||||
<text text-anchor="middle" x="553" y="-74.9" font-family="Sans" font-size="14.00">ASIC</text>
|
||||
</g>
|
||||
<!-- software -->
|
||||
<g id="node3" class="node"><title>software</title>
|
||||
<polygon fill="none" stroke="black" points="418,-100 338,-100 338,-58 418,-58 418,-100"/>
|
||||
<text text-anchor="middle" x="378" y="-83.4" font-family="Sans" font-size="14.00">Mining</text>
|
||||
<text text-anchor="middle" x="378" y="-66.4" font-family="Sans" font-size="14.00">Software</text>
|
||||
</g>
|
||||
<!-- asic0->software -->
|
||||
<g id="edge10" class="edge"><title>asic0->software</title>
|
||||
<path fill="none" stroke="black" d="M537.765,-60.7181C524.71,-45.0522 508,-25 508,-25 508,-25 436,-25 436,-25 436,-25 422.132,-37.9116 407.958,-51.1078"/>
|
||||
<polygon fill="black" stroke="black" points="405.524,-48.5917 400.59,-57.9676 410.294,-53.715 405.524,-48.5917"/>
|
||||
<text text-anchor="middle" x="472" y="-63.4" font-family="Sans" font-size="14.00">←Headers</text>
|
||||
<text text-anchor="middle" x="472" y="-46.4" font-family="Sans" font-size="14.00">Below</text>
|
||||
<text text-anchor="middle" x="472" y="-29.4" font-family="Sans" font-size="14.00">Target</text>
|
||||
</g>
|
||||
<!-- software->asic0 -->
|
||||
<g id="edge8" class="edge"><title>software->asic0</title>
|
||||
<path fill="none" stroke="black" d="M418.283,-83.1672C428.18,-84.191 436,-85 436,-85 436,-85 508,-85 508,-85 508,-85 511.085,-84.5886 515.64,-83.9813"/>
|
||||
<polygon fill="black" stroke="black" points="516.336,-87.4197 525.785,-82.6286 515.41,-80.4811 516.336,-87.4197"/>
|
||||
<text text-anchor="middle" x="472" y="-123.4" font-family="Sans" font-size="14.00">Block</text>
|
||||
<text text-anchor="middle" x="472" y="-106.4" font-family="Sans" font-size="14.00">Headers &</text>
|
||||
<text text-anchor="middle" x="472" y="-89.4" font-family="Sans" font-size="14.00">Targets→</text>
|
||||
</g>
|
||||
<!-- software->pool0 -->
|
||||
<g id="edge12" class="edge"><title>software->pool0</title>
|
||||
<path fill="none" stroke="black" d="M337.717,-60.9421C327.82,-56.5055 320,-53 320,-53 320,-53 250,-53 250,-53 250,-53 246.279,-54.9745 240.888,-57.8352"/>
|
||||
<polygon fill="black" stroke="black" points="239.225,-54.7549 232.032,-62.5338 242.506,-60.9383 239.225,-54.7549"/>
|
||||
<text text-anchor="middle" x="285" y="-57.4" font-family="Sans" font-size="14.00">←Shares</text>
|
||||
</g>
|
||||
<!-- pool0->p2pnetwork -->
|
||||
<g id="edge6" class="edge"><title>pool0->p2pnetwork</title>
|
||||
<path fill="none" stroke="black" d="M169.968,-62.5338C160.243,-57.3739 152,-53 152,-53 152,-53 96,-53 96,-53 96,-53 92.3058,-54.6851 86.7984,-57.1972"/>
|
||||
<polygon fill="black" stroke="black" points="85.2967,-54.0352 77.6511,-61.3697 88.2018,-60.4039 85.2967,-54.0352"/>
|
||||
<text text-anchor="middle" x="124" y="-57.4" font-family="Sans" font-size="14.00">←Blocks</text>
|
||||
</g>
|
||||
<!-- pool0->software -->
|
||||
<g id="edge2" class="edge"><title>pool0->software</title>
|
||||
<path fill="none" stroke="black" d="M232.237,-79C258.629,-79 296.93,-79 327.648,-79"/>
|
||||
<polygon fill="black" stroke="black" points="327.746,-82.5001 337.746,-79 327.746,-75.5001 327.746,-82.5001"/>
|
||||
<text text-anchor="middle" x="285" y="-100.4" font-family="Sans" font-size="14.00">Prototype</text>
|
||||
<text text-anchor="middle" x="285" y="-83.4" font-family="Sans" font-size="14.00">Block→</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.1 KiB |
BIN
img/dev/en-qr-code.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
225
img/dev/en-qr-code.svg
Normal file
|
@ -0,0 +1,225 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="507.98975"
|
||||
height="180.34579"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.3.1 r9886"
|
||||
sodipodi:docname="qr-code.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="1"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.98994949"
|
||||
inkscape:cx="299.12153"
|
||||
inkscape:cy="67.832358"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1278"
|
||||
inkscape:window-height="762"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
fit-margin-top="1"
|
||||
fit-margin-right="1"
|
||||
fit-margin-bottom="1"
|
||||
fit-margin-left="1"
|
||||
units="mm" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-181.68411,-447.73083)">
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
||||
id="rect3324"
|
||||
width="519.21838"
|
||||
height="186.87822"
|
||||
x="-4.0406103"
|
||||
y="-2.491816"
|
||||
transform="translate(181.68411,447.73083)" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
|
||||
x="237.82751"
|
||||
y="622.03723"
|
||||
id="text3050"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3052"
|
||||
x="237.82751"
|
||||
y="622.03723">bitcoin:mjSk1Ny9spzU2fouzYgLqGUD8U41iR35QN?amount=.1</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
|
||||
x="230.32329"
|
||||
y="496.75681"
|
||||
id="text3113"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3115"
|
||||
x="230.32329"
|
||||
y="496.75681">Low</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
|
||||
x="333.35886"
|
||||
y="484.63495"
|
||||
id="text3117"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3119"
|
||||
x="333.35886"
|
||||
y="484.63495">Medium</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
|
||||
x="456.59744"
|
||||
y="471.50299"
|
||||
id="text3121"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3123"
|
||||
x="456.59744"
|
||||
y="471.50299">Quartile</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
|
||||
x="603.06958"
|
||||
y="460.39133"
|
||||
id="text3125"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3127"
|
||||
x="603.06958"
|
||||
y="460.39133">High</tspan></text>
|
||||
<image
|
||||
y="499.90402"
|
||||
x="185.22742"
|
||||
id="image3047"
|
||||
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAG8AAABvCAIAAABtpwk3AAAAA3NCSVQICAjb4U/gAAACqklEQVR4
|
||||
nO2cQW4EIQwEM1H+/+XNjQuSZZtas1pVHROGTFpuBozheb1ePwLxe/sFvgrVJFFNEtUkUU0S1SRR
|
||||
TRLVJFFNEtUkUU2Sv0yj53lO/kaQCgh6Xk/tbYJflfopkUloGJskqkmScvqilL7bnfU+X5de7PC/
|
||||
CDA2SVSTpOb0Rc90lGfX43vjYKAI+um9xo6xSaKaJE2n9wgcGjQudXh309DYJFFNklGnZz6ve5t9
|
||||
JlD6TE9639gkUU2SptN79tmtmvnJ+14MHwSMTRLVJKk5/TB93aM3PpTW8hTGJolqkjxXFraHxuyt
|
||||
AgYwNklUk4TfTz9MsGcW7EHj0m4dvogwNklUk+Q0I3forKDDHpm5QS/FZ+XMNKpJgmXkMs7K9BM8
|
||||
HowPmcalkcf99PuoJslp5Uxgn8MamMzjvUlCqbbH2fs1VJOEr4alTFfy2uGcn9rjMzZJVJOklnsf
|
||||
qGLFf7W/Ye9cjOv0aVST5HSXrZeWL/Vc2onrlc+5Tv9EVJMk5fSMEXqVKpSLg8YDBl8YmySqScKf
|
||||
ZdvbvK9wfXJi7+x9GtUkOd1lo06m7E8teqfadwZKeY1NEtUkqc3eqftbFodrB2qSQNXQGpskqkky
|
||||
USO3sxr3PvcDG3C9JbyxSaKaJBM1cpnHS86iLrLYOzzM0RmbJKpJMnqWrVeGerh2KE3se/0sjE0S
|
||||
1SS5fDdsb/rdMy+ePNwxNklUk2T0btje+bJe2m1noKrW2CRRTZLRu2GpjH1pDOltwFkNex/VJBm9
|
||||
MXKx+6j0Ke8NJlQ1YICxSaKaJHecfngrO1X3ftjhjrFJopoko3fDBmSOt1PFcpm/3uvH2CRRTZLL
|
||||
d8MGzsI/05mezb1/EKpJcudu2G/F2CRRTRLVJFFNEtUkUU0S1SRRTRLVJFFNEtUk+QcaXTfA4mJ7
|
||||
PwAAAABJRU5ErkJggg==
|
||||
"
|
||||
height="111"
|
||||
width="111" />
|
||||
<image
|
||||
y="487.90402"
|
||||
x="291.19513"
|
||||
id="image3191"
|
||||
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHsAAAB7CAIAAADbpWgoAAAAA3NCSVQICAjb4U/gAAADQklEQVR4
|
||||
nO2dS47jMAwFx4O5/5UzO28EEPy5nEZXLbstS3lgXiiJsq/P5/NHQP6+PYBfh4rTqDiNitOoOI2K
|
||||
06g4jYrTqDiNitOoOM2/zEXXdU36KC3d3H3drYLeg2vOTs87B733yHxSY5xGxWlSrnLT84dhF6d1
|
||||
BH/JDCNjQc99UmOcRsVpaq5yk8kfhnfOmEmmeZC0lMZz0vukxjiNitM0XWVIaVKzZS+ZFAXAGKdR
|
||||
cZp3XCX4pq8bTsmLAIxxGhWnabpK71c+mJ6UbKFkSsNlmfV8xhinUXGamqus/8r3pjnDyVFpYOsY
|
||||
4zQqTnO9W7GfyRZKzTNuUMpV1jHGaVScJuUqwbevtChaqioJmvcKTjKtAMMxxmlUnKbmKic9Mwko
|
||||
Gdewvi645hzP0O5ujHEaFaeZ5irBxSeZr2Gvr+Gdn7PEE2OcRsVpUqu1pblDb3pS+sqXyCz23mRs
|
||||
YZgyGeM0Kk7T3ANaX2AJ6G0ED+cypYGVMMZpVJymtge0vob53GLv+gyolLAFGOM0Kk4zdZWtH/dX
|
||||
/Ooc2Nb56ABjnEbFaab1Kr2f8q0Z0PBY9Hpzc5VvRMVpas9X2XoEQc8oenX1vUnWc4UrxjiNitPs
|
||||
z4CG+7brxSRB85MtdwowxmlUnGYtVymdPr7pPdOgd8Pn6v1KGOM0Kk5Tq1dZXw8pJTYnpUlWQGna
|
||||
NayoMcZpVJym+dzanj+czYO/nPfZMophGjNMWoxxGhWnWTuz/Mrp45PhwcNhia/rKt+IitNMTxee
|
||||
PHfEeHg8cIvhPpExTqPiNM11leGaSTAD2tqPXt9myjTPYIzTqDjN2pnl4c7IsNStV7U7HHOm9xNj
|
||||
nEbFadBnwa2nDcHFJ89NqZwBfTUqToO+u7BX3FIqU8nQq43ZSnWMcRoVp0HfXfjcskymi5utc4I9
|
||||
jHEaFadB312YWaRdr7bNsJWMZTDGaVScBn3LWGkPqHcYsHcCsWdl7iz/DFScBnUVoMKttENd2uDe
|
||||
OsVsjNOoOA367sLgPsMTPcMHKWQMp7SQG2CM06g4DfruwszWz/rDDUrjOf+V2cDSVb4aFad5+d2F
|
||||
vxBjnEbFaVScRsVpVJxGxWlUnEbFaVScRsVpVJzmP8M8ChN/iw3mAAAAAElFTkSuQmCC
|
||||
"
|
||||
height="123"
|
||||
width="123" />
|
||||
<image
|
||||
y="475.90402"
|
||||
x="409.16284"
|
||||
id="image3256"
|
||||
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIcAAACHCAIAAACzhd1dAAAAA3NCSVQICAjb4U/gAAAEAklEQVR4
|
||||
nO2dwY7jMAxDt4v9/1+evfnigSBSSocdvHdsnDgtIcKWZff19fX1B8L4+9MvAN+AKomgSiKokgiq
|
||||
JIIqiaBKIqiSCKokgiqJoEoi/zqNXq/XpI871XYeeC7dXRSXijadtF7n6xTPWf81boiVRFAlkZaD
|
||||
HaS0/x3phXFJLtexl+Kuoi+J4a9RQKwkgiqJaA526IyLiksdc5NczqMY+A2fM3wgsZIIqiRiOphH
|
||||
x4sKN5Cmk55JhkCsJIIqibzVwW6GE0OpTdHYy6c9B7GSCKokYjqYF+CFUXhWVrTp9F60kTpdtzti
|
||||
JRFUSURzsK28k2dl0l1bn3S+zjrESiKokkjLwdbHGNKk777rxstodaysuOs5iJVEUCWRl1cSIDnG
|
||||
0F4679Ppq7OUKc1PpWI26XcmVhJBlUS0itbhbEtqLNmLVxnbWcGU+tqCWEkEVRJZW4uUVgwlvBS6
|
||||
N0PsPMcbVkl3ESuJoEoi2izym/uXJmtemw7Dvta3F+FgnwqqJLK2L/Kd2xiHfQ3T9d5OKAliJRFU
|
||||
SWQ6i/RyU4f13L5X0dq51Oliq2aMWEkEVRIxZ5FvqMg6PFfQVXyvG2lW63njgVhJBFUS2c+DHYa5
|
||||
9K1ireFZOhJbfREriaBKImZNflEwXzQepr63yiFuvGN/7tcoYBb58aBKImY92EHK/HgDpOfK7LcM
|
||||
8H7ggUz+7wFVEmnNIr0ByXrB53p9xdAbO228BB2xkgiqJKI52GG9IGH93AnPbJ+rg70vFRAriaBK
|
||||
ImunTHtLdVLNw9aeJqm6Y2vTN3mwjwdVEpmeMj2M2WH5VtGms6fJ25HtrahKECuJoEoi0xMOhyWp
|
||||
604ovaHnn8UnW4dUECuJoEoia//0IeWvvCp9yS2Hqa2OO63X0x6IlURQJZG1Mdh6vf2QzqjsuWXT
|
||||
A9UUvwdUSWRaTdFpIy1lrnvacLjorXJ2+iogVhJBlUQerKaQWN9w5H0vqS8J8mAfD6okYlZTbM0Q
|
||||
i0no3aZgK+sl8dzck1hJBFUS2V+L7NQzFCVenU6l9+ncLvnncHGzA7GSCKokMj2bQuvssWy/l+zy
|
||||
EmLeAyWIlURQJZG1M1oL7hFXp/Hde+eStEfb2/IzrLAlD/apoEoia7uKbqQaeOl2ycreubGxU8nf
|
||||
gVhJBFUSWatoPQw3E3Vi31tDLNp0nuxl6rwJJrGSCKoksvZvaxLDvdXe1KxjL1v706UB5A2xkgiq
|
||||
JPJWBxvm5D3D8ZZNC95QyU+sJIIqiUyrKSS8lceiU28MJhWhrS8fdCBWEkGVRMxz8j2GZ+lISbNh
|
||||
2qrzPsVzbqSfjlhJBFUSeWs9GDQhVhJBlURQJRFUSQRVEkGVRFAlEVRJBFUSQZVEUCWR/0GKvmDV
|
||||
ZtCGAAAAAElFTkSuQmCC
|
||||
"
|
||||
height="135"
|
||||
width="135" />
|
||||
<image
|
||||
y="463.90402"
|
||||
x="539.13055"
|
||||
id="image3321"
|
||||
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJMAAACTCAIAAAAFh7xCAAAAA3NCSVQICAjb4U/gAAAEmElEQVR4
|
||||
nO2dwbLbMAhFm877/19ONx1tmKFwwU5vfM7WtqTkDgQBcl7v9/sXGPL70wsAEZRzBeVcQTlXUM4V
|
||||
lHMF5VxBOVdQzhWUcwXlXPmp3PR6vSZznNRoHCdeSvKorWVURq6sJ16qsPWNJWBzrqCcKyVveVj3
|
||||
GPGe5KnEAbac7bknPp7MXvG68dJ1PhabcwXlXOl5y0PFp1UuVfxDEu8lC6u4qVasq33kZK7W4xFs
|
||||
zhWUc0X0lhqV6K4S77V22a08QMtJJnPdADbnCsq5cqu3rLCVMGxFicMt+Ud6VrE5V1DOFdFbbvmH
|
||||
lm9c37YnacZK1NoKKdc9KjbnCsq50vOWw1JvQquC06ryfGTkw3XfGDbnCsq58vrILnLLh7Qq4K06
|
||||
i5bAJG8J/wblXJnmLYd9Nev1kcqAraVql+I9yTK0VC025wrKuTLtTh9GZVrkVnEv62WaSkE/oXVz
|
||||
BWzOFZRzpeQtNUsflqfjONp6tDLNek5yfSOPzbmCcq6U8pZbJxa1zezw5oPm869LaQ6zENicKyjn
|
||||
Sq/Ko4WLCcOTMluzV9j67NrPSgSbcwXlXNl/q8bwWI02qTbFcK7I0P2yE38EKOfKWmzZYugb198m
|
||||
tJUQGDZwEls+ApRzRXwH0fB84kF745BGxcdedyZ9y0kesDlXUM6V/diydUnrb0y47uTOMHxdB5tz
|
||||
BeVcEc/yDKvA8Z5hF+KwSSlZYWXSyuPsxOEvKOeKeE684p20iEvLHGoN8MOu+8o4lZE1sDlXUM4V
|
||||
sd/ysF4Wqcyu3dzKDAw31+sJigg25wrKuSLmLQ/rbZZbKcQt76S5zfVCfASbcwXlXJn2W2qBn7ar
|
||||
rbiX4SHNBK2rfMu1RrA5V1DOlek7iFpZwSS32Uppak+1Lh2SNGyFliekg+gRoJwr03ent8orW41D
|
||||
W/nPZM2tS8kyWvFwC2zOFZRz5Y7YcqtnW+vPGeZaW65MG5nu9GeBcq6svQ040vJgrdSoRpJUTKLf
|
||||
9XL5Yfi5sDlXUM6V6cnHrZ3vdU6psh5tm6w1XlY6VKnyfDMo58r0f3m0TF1rnMOw2akyznpmVesZ
|
||||
wFt+MyjnithB1Eozap6ntU2OCxueqYxzXVd/11aIzbmCcq7c+p+Pw9PlrW17MrLmnSqz31lawuZc
|
||||
QTlXeicfh5vQeE8yV4WtXa22jK1jUPEevOU3g3Ku9P7F7HBDUea6kQ+VjXxyc7y0FVtWwOZcQTlX
|
||||
xNjyuo7xG2pDw/B1y93FKYgtHwHKufL/5i1vcErD2bV+qlb+MwGbcwXlXJm+sa3CMFxsLUPLiGpe
|
||||
LhlH25tzlucRoJwrYnd6haGPrbzY57qS0HU/ENo50Ag25wrKuSKefNTitOTxpE9S8yrDe7RI8s4g
|
||||
HJtzBeVcmZ4Tb6EdDEweb8WEWkVJa4jSlkFs+QhQzpVbveXwmPlWmUbzTq1j3TdU0rE5V1DOlen7
|
||||
LYePD3vID1rANjyeM5w9Ps5O/BGgnCvifz4Oae2pW4evK9nOyuMJWq/+1u/CAZtzBeVcubXfEhbB
|
||||
5lxBOVdQzhWUcwXlXEE5V1DOFZRzBeVcQTlXUM6VP7Dln2u1jDhDAAAAAElFTkSuQmCC
|
||||
"
|
||||
height="147"
|
||||
width="147" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 11 KiB |
87
img/dev/en-signing-output-to-spend.dot
Normal file
|
@ -0,0 +1,87 @@
|
|||
digraph blockchain {
|
||||
|
||||
size="6.25";
|
||||
|
||||
//splines = "false";
|
||||
rankdir=TB;
|
||||
ranksep=-0.1;
|
||||
//splines=ortho;
|
||||
overlap = true;
|
||||
nodesep = 0.1;
|
||||
|
||||
node [ shape = box, penwidth = 1.75 ];
|
||||
edge [ penwidth = 1.75, minlen = 2 ];
|
||||
penwidth = 1.75;
|
||||
|
||||
subgraph cluster_tx1 {
|
||||
tx1_txid [ label = "TXID" ];
|
||||
tx1_vout [ label = "Output Index Number" ];
|
||||
tx1_script [ label = "Script" ];
|
||||
|
||||
label = "Transaction 1 (TX 1)"
|
||||
}
|
||||
|
||||
|
||||
|
||||
subgraph cluster_sig {
|
||||
node [ style = "invis", label = "", height=0 ];
|
||||
|
||||
sig_tx1_txid [ width = 0.7 ];
|
||||
sig_tx1_vout [ width = 2.3 ];
|
||||
sig_tx1_script [ width = 1.6 ];
|
||||
//nil_pubkey [ width = 1.3 ];
|
||||
sig_tx2t_script [ width = 0.75 ];
|
||||
sig_tx2t_amount [ width = 0.95 ];
|
||||
signature [ width = 1.25 ];
|
||||
|
||||
|
||||
label = "Signed Data"
|
||||
}
|
||||
|
||||
subgraph cluster_tx2 {
|
||||
tx2_tx1_txid [ label = "TXID" ];
|
||||
tx2_tx1_vout [ label = "Output Index Number" ];
|
||||
tx2_script [ label = "Script" ];
|
||||
public_key [ label = "Full Public Key" ];
|
||||
tx2_amount [ label = "Amount" ];
|
||||
tx2_signature [ label = "Signature" ];
|
||||
|
||||
label = "Transaction 2"
|
||||
}
|
||||
|
||||
subgraph cluster_bob {
|
||||
private_key [ label = "Private Key" ];
|
||||
|
||||
label = "Bob's Computer"
|
||||
subgraph cluster_tx2t {
|
||||
tx2t_script [ label = "Script" ];
|
||||
tx2t_amount [ label = "Amount" ];
|
||||
|
||||
label = "TX2 Template"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
edge [ arrowhead = "dot" ];
|
||||
tx1_script -> sig_tx1_script;
|
||||
tx1_txid -> sig_tx1_txid;
|
||||
tx1_vout -> sig_tx1_vout;
|
||||
tx2t_script -> sig_tx2t_script;
|
||||
tx2t_amount -> sig_tx2t_amount;
|
||||
private_key -> signature [ style = "dotted" ];
|
||||
}
|
||||
|
||||
|
||||
sig_tx1_txid -> tx2_tx1_txid;
|
||||
sig_tx1_vout -> tx2_tx1_vout;
|
||||
sig_tx2t_script -> tx2_script;
|
||||
sig_tx2t_amount -> tx2_amount;
|
||||
signature -> tx2_signature;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
label = "Some Of The Data Signed By Default"
|
||||
}
|
BIN
img/dev/en-signing-output-to-spend.png
Normal file
After Width: | Height: | Size: 8.8 KiB |
155
img/dev/en-signing-output-to-spend.svg
Normal file
|
@ -0,0 +1,155 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: blockchain Pages: 1 -->
|
||||
<svg width="450pt" height="230pt"
|
||||
viewBox="0.00 0.00 450.00 230.35" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.713154 0.713154) rotate(0) translate(4 319)">
|
||||
<title>blockchain</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-319 628,-319 628,5 -4,5"/>
|
||||
<text text-anchor="middle" x="311.5" y="-8.4" font-family="Sans" font-size="14.00">Some Of The Data Signed By Default</text>
|
||||
<g id="graph2" class="cluster"><title>cluster_tx1</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="9,-197 9,-274 317,-274 317,-197 9,-197"/>
|
||||
<text text-anchor="middle" x="163" y="-257.4" font-family="Sans" font-size="14.00">Transaction 1 (TX 1)</text>
|
||||
</g>
|
||||
<g id="graph3" class="cluster"><title>cluster_sig</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="11,-128 11,-171 604,-171 604,-128 11,-128"/>
|
||||
<text text-anchor="middle" x="307.5" y="-154.4" font-family="Sans" font-size="14.00">Signed Data</text>
|
||||
</g>
|
||||
<g id="graph4" class="cluster"><title>cluster_tx2</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="8,-33 8,-110 605,-110 605,-33 8,-33"/>
|
||||
<text text-anchor="middle" x="306.5" y="-93.4" font-family="Sans" font-size="14.00">Transaction 2</text>
|
||||
</g>
|
||||
<g id="graph5" class="cluster"><title>cluster_bob</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="348,-189 348,-307 615,-307 615,-189 348,-189"/>
|
||||
<text text-anchor="middle" x="481.5" y="-290.4" font-family="Sans" font-size="14.00">Bob's Computer</text>
|
||||
</g>
|
||||
<g id="graph6" class="cluster"><title>cluster_tx2t</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="458,-197 458,-274 607,-274 607,-197 458,-197"/>
|
||||
<text text-anchor="middle" x="532.5" y="-257.4" font-family="Sans" font-size="14.00">TX2 Template</text>
|
||||
</g>
|
||||
<!-- tx1_txid -->
|
||||
<g id="node2" class="node"><title>tx1_txid</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="71,-241 17,-241 17,-205 71,-205 71,-241"/>
|
||||
<text text-anchor="middle" x="44" y="-218.9" font-family="Sans" font-size="14.00">TXID</text>
|
||||
</g>
|
||||
<!-- sig_tx1_txid -->
|
||||
<!-- tx1_txid->sig_tx1_txid -->
|
||||
<g id="edge10" class="edge"><title>tx1_txid->sig_tx1_txid</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M44,-204.762C44,-186.762 44,-159.981 44,-146.092"/>
|
||||
<ellipse fill="black" stroke="black" cx="44" cy="-141.75" rx="4" ry="4"/>
|
||||
</g>
|
||||
<!-- tx1_vout -->
|
||||
<g id="node3" class="node"><title>tx1_vout</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="246,-241 78,-241 78,-205 246,-205 246,-241"/>
|
||||
<text text-anchor="middle" x="162" y="-218.9" font-family="Sans" font-size="14.00">Output Index Number</text>
|
||||
</g>
|
||||
<!-- sig_tx1_vout -->
|
||||
<!-- tx1_vout->sig_tx1_vout -->
|
||||
<g id="edge12" class="edge"><title>tx1_vout->sig_tx1_vout</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M161.364,-204.762C160.736,-186.762 159.802,-159.981 159.317,-146.092"/>
|
||||
<ellipse fill="black" stroke="black" cx="159.166" cy="-141.748" rx="4" ry="4"/>
|
||||
</g>
|
||||
<!-- tx1_script -->
|
||||
<g id="node4" class="node"><title>tx1_script</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="309,-241 253,-241 253,-205 309,-205 309,-241"/>
|
||||
<text text-anchor="middle" x="281" y="-218.9" font-family="Sans" font-size="14.00">Script</text>
|
||||
</g>
|
||||
<!-- sig_tx1_script -->
|
||||
<!-- tx1_script->sig_tx1_script -->
|
||||
<g id="edge8" class="edge"><title>tx1_script->sig_tx1_script</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M286.302,-204.762C291.587,-186.58 299.477,-159.439 303.478,-145.675"/>
|
||||
<ellipse fill="black" stroke="black" cx="304.665" cy="-141.591" rx="4.00001" ry="4.00001"/>
|
||||
</g>
|
||||
<!-- tx2_tx1_txid -->
|
||||
<g id="node13" class="node"><title>tx2_tx1_txid</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="70,-77 16,-77 16,-41 70,-41 70,-77"/>
|
||||
<text text-anchor="middle" x="43" y="-54.9" font-family="Sans" font-size="14.00">TXID</text>
|
||||
</g>
|
||||
<!-- sig_tx1_txid->tx2_tx1_txid -->
|
||||
<g id="edge20" class="edge"><title>sig_tx1_txid->tx2_tx1_txid</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M43.9888,-136.124C43.9269,-131.3 43.6214,-107.47 43.3661,-87.5593"/>
|
||||
<polygon fill="black" stroke="black" points="46.8631,-87.2911 43.2351,-77.3368 39.8637,-87.3809 46.8631,-87.2911"/>
|
||||
</g>
|
||||
<!-- tx2_tx1_vout -->
|
||||
<g id="node14" class="node"><title>tx2_tx1_vout</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="245,-77 77,-77 77,-41 245,-41 245,-77"/>
|
||||
<text text-anchor="middle" x="161" y="-54.9" font-family="Sans" font-size="14.00">Output Index Number</text>
|
||||
</g>
|
||||
<!-- sig_tx1_vout->tx2_tx1_vout -->
|
||||
<g id="edge22" class="edge"><title>sig_tx1_vout->tx2_tx1_vout</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M159.022,-136.124C159.146,-131.3 159.757,-107.47 160.268,-87.5593"/>
|
||||
<polygon fill="black" stroke="black" points="163.772,-87.4233 160.53,-77.3368 156.775,-87.2438 163.772,-87.4233"/>
|
||||
</g>
|
||||
<!-- sig_tx2t_script -->
|
||||
<!-- tx2_script -->
|
||||
<g id="node15" class="node"><title>tx2_script</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="520,-77 464,-77 464,-41 520,-41 520,-77"/>
|
||||
<text text-anchor="middle" x="492" y="-54.9" font-family="Sans" font-size="14.00">Script</text>
|
||||
</g>
|
||||
<!-- sig_tx2t_script->tx2_script -->
|
||||
<g id="edge24" class="edge"><title>sig_tx2t_script->tx2_script</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M493.978,-136.124C493.854,-131.3 493.243,-107.47 492.732,-87.5593"/>
|
||||
<polygon fill="black" stroke="black" points="496.225,-87.2438 492.47,-77.3368 489.228,-87.4233 496.225,-87.2438"/>
|
||||
</g>
|
||||
<!-- sig_tx2t_amount -->
|
||||
<!-- tx2_amount -->
|
||||
<g id="node17" class="node"><title>tx2_amount</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="597,-77 527,-77 527,-41 597,-41 597,-77"/>
|
||||
<text text-anchor="middle" x="562" y="-54.9" font-family="Sans" font-size="14.00">Amount</text>
|
||||
</g>
|
||||
<!-- sig_tx2t_amount->tx2_amount -->
|
||||
<g id="edge26" class="edge"><title>sig_tx2t_amount->tx2_amount</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M562,-136.124C562,-131.3 562,-107.47 562,-87.5593"/>
|
||||
<polygon fill="black" stroke="black" points="565.5,-87.3368 562,-77.3368 558.5,-87.3369 565.5,-87.3368"/>
|
||||
</g>
|
||||
<!-- signature -->
|
||||
<!-- tx2_signature -->
|
||||
<g id="node18" class="node"><title>tx2_signature</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="457,-77 373,-77 373,-41 457,-41 457,-77"/>
|
||||
<text text-anchor="middle" x="415" y="-54.9" font-family="Sans" font-size="14.00">Signature</text>
|
||||
</g>
|
||||
<!-- signature->tx2_signature -->
|
||||
<g id="edge28" class="edge"><title>signature->tx2_signature</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M415,-136.124C415,-131.3 415,-107.47 415,-87.5593"/>
|
||||
<polygon fill="black" stroke="black" points="418.5,-87.3368 415,-77.3368 411.5,-87.3369 418.5,-87.3368"/>
|
||||
</g>
|
||||
<!-- public_key -->
|
||||
<g id="node16" class="node"><title>public_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="366,-77 252,-77 252,-41 366,-41 366,-77"/>
|
||||
<text text-anchor="middle" x="309" y="-54.9" font-family="Sans" font-size="14.00">Full Public Key</text>
|
||||
</g>
|
||||
<!-- private_key -->
|
||||
<g id="node20" class="node"><title>private_key</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="450,-241 356,-241 356,-205 450,-205 450,-241"/>
|
||||
<text text-anchor="middle" x="403" y="-218.9" font-family="Sans" font-size="14.00">Private Key</text>
|
||||
</g>
|
||||
<!-- private_key->signature -->
|
||||
<g id="edge18" class="edge"><title>private_key->signature</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="1,5" d="M405.545,-204.762C408.082,-186.58 411.869,-159.439 413.79,-145.675"/>
|
||||
<ellipse fill="black" stroke="black" cx="414.343" cy="-141.712" rx="4.00001" ry="4.00001"/>
|
||||
</g>
|
||||
<!-- tx2t_script -->
|
||||
<g id="node22" class="node"><title>tx2t_script</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="522,-241 466,-241 466,-205 522,-205 522,-241"/>
|
||||
<text text-anchor="middle" x="494" y="-218.9" font-family="Sans" font-size="14.00">Script</text>
|
||||
</g>
|
||||
<!-- tx2t_script->sig_tx2t_script -->
|
||||
<g id="edge14" class="edge"><title>tx2t_script->sig_tx2t_script</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M494,-204.762C494,-186.762 494,-159.981 494,-146.092"/>
|
||||
<ellipse fill="black" stroke="black" cx="494" cy="-141.75" rx="4" ry="4"/>
|
||||
</g>
|
||||
<!-- tx2t_amount -->
|
||||
<g id="node23" class="node"><title>tx2t_amount</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="599,-241 529,-241 529,-205 599,-205 599,-241"/>
|
||||
<text text-anchor="middle" x="564" y="-218.9" font-family="Sans" font-size="14.00">Amount</text>
|
||||
</g>
|
||||
<!-- tx2t_amount->sig_tx2t_amount -->
|
||||
<g id="edge16" class="edge"><title>tx2t_amount->sig_tx2t_amount</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M563.576,-204.762C563.157,-186.762 562.534,-159.981 562.211,-146.092"/>
|
||||
<ellipse fill="black" stroke="black" cx="562.11" cy="-141.749" rx="4" ry="4"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 9.3 KiB |
25
img/dev/en-solo-mining-overview.dot
Normal file
|
@ -0,0 +1,25 @@
|
|||
digraph {
|
||||
|
||||
size=6.25;
|
||||
rankdir=LR
|
||||
node [ shape = "box" ]
|
||||
splines = ortho;
|
||||
//ranksep = 10;
|
||||
nodesep = 0.5;
|
||||
|
||||
p2pnetwork [ label = "P2P\nNetwork" ]
|
||||
asic0 [ label = "ASIC" ];
|
||||
software [ label = "Mining\nSoftware" ]
|
||||
pool0 [ label = "bitcoind" ];
|
||||
|
||||
pool0 -> software [ label = "Block\nTemplate→" ];
|
||||
p2pnetwork -> pool0 [ label = "TXes→" ];
|
||||
pool0 -> p2pnetwork [ label = "←Blocks" ];
|
||||
|
||||
software -> asic0 [ label = "Block\nHeaders &\nTargets→" ];
|
||||
asic0 -> software [ label = "←Headers\nBelow\nTarget" ];
|
||||
|
||||
software -> pool0 [ constraint = false, label = "←Blocks" ];
|
||||
|
||||
label = "Solo Bitcoin Mining Workflow"
|
||||
}
|
BIN
img/dev/en-solo-mining-overview.png
Normal file
After Width: | Height: | Size: 5.1 KiB |
77
img/dev/en-solo-mining-overview.svg
Normal file
|
@ -0,0 +1,77 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: _anonymous_0 Pages: 1 -->
|
||||
<svg width="450pt" height="107pt"
|
||||
viewBox="0.00 0.00 450.00 107.28" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.745033 0.745033) rotate(0) translate(4 140)">
|
||||
<title>_anonymous_0</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-140 601,-140 601,5 -4,5"/>
|
||||
<text text-anchor="middle" x="298" y="-8.4" font-family="Sans" font-size="14.00">Solo Bitcoin Mining Workflow</text>
|
||||
<!-- p2pnetwork -->
|
||||
<g id="node1" class="node"><title>p2pnetwork</title>
|
||||
<polygon fill="none" stroke="black" points="77,-100 1,-100 1,-58 77,-58 77,-100"/>
|
||||
<text text-anchor="middle" x="39" y="-83.4" font-family="Sans" font-size="14.00">P2P</text>
|
||||
<text text-anchor="middle" x="39" y="-66.4" font-family="Sans" font-size="14.00">Network</text>
|
||||
</g>
|
||||
<!-- pool0 -->
|
||||
<g id="node4" class="node"><title>pool0</title>
|
||||
<polygon fill="none" stroke="black" points="241,-97 171,-97 171,-61 241,-61 241,-97"/>
|
||||
<text text-anchor="middle" x="206" y="-74.9" font-family="Sans" font-size="14.00">bitcoind</text>
|
||||
</g>
|
||||
<!-- p2pnetwork->pool0 -->
|
||||
<g id="edge4" class="edge"><title>p2pnetwork->pool0</title>
|
||||
<path fill="none" stroke="black" d="M77.7329,-79C102.292,-79 134.187,-79 160.027,-79"/>
|
||||
<polygon fill="black" stroke="black" points="160.328,-82.5001 170.328,-79 160.328,-75.5001 160.328,-82.5001"/>
|
||||
<text text-anchor="middle" x="124" y="-83.4" font-family="Sans" font-size="14.00">TXes→</text>
|
||||
</g>
|
||||
<!-- asic0 -->
|
||||
<g id="node2" class="node"><title>asic0</title>
|
||||
<polygon fill="none" stroke="black" points="596,-97 542,-97 542,-61 596,-61 596,-97"/>
|
||||
<text text-anchor="middle" x="569" y="-74.9" font-family="Sans" font-size="14.00">ASIC</text>
|
||||
</g>
|
||||
<!-- software -->
|
||||
<g id="node3" class="node"><title>software</title>
|
||||
<polygon fill="none" stroke="black" points="434,-100 354,-100 354,-58 434,-58 434,-100"/>
|
||||
<text text-anchor="middle" x="394" y="-83.4" font-family="Sans" font-size="14.00">Mining</text>
|
||||
<text text-anchor="middle" x="394" y="-66.4" font-family="Sans" font-size="14.00">Software</text>
|
||||
</g>
|
||||
<!-- asic0->software -->
|
||||
<g id="edge10" class="edge"><title>asic0->software</title>
|
||||
<path fill="none" stroke="black" d="M553.765,-60.7181C540.71,-45.0522 524,-25 524,-25 524,-25 452,-25 452,-25 452,-25 438.132,-37.9116 423.958,-51.1078"/>
|
||||
<polygon fill="black" stroke="black" points="421.524,-48.5917 416.59,-57.9676 426.294,-53.715 421.524,-48.5917"/>
|
||||
<text text-anchor="middle" x="488" y="-63.4" font-family="Sans" font-size="14.00">←Headers</text>
|
||||
<text text-anchor="middle" x="488" y="-46.4" font-family="Sans" font-size="14.00">Below</text>
|
||||
<text text-anchor="middle" x="488" y="-29.4" font-family="Sans" font-size="14.00">Target</text>
|
||||
</g>
|
||||
<!-- software->asic0 -->
|
||||
<g id="edge8" class="edge"><title>software->asic0</title>
|
||||
<path fill="none" stroke="black" d="M434.283,-83.1672C444.18,-84.191 452,-85 452,-85 452,-85 524,-85 524,-85 524,-85 527.085,-84.5886 531.64,-83.9813"/>
|
||||
<polygon fill="black" stroke="black" points="532.336,-87.4197 541.785,-82.6286 531.41,-80.4811 532.336,-87.4197"/>
|
||||
<text text-anchor="middle" x="488" y="-123.4" font-family="Sans" font-size="14.00">Block</text>
|
||||
<text text-anchor="middle" x="488" y="-106.4" font-family="Sans" font-size="14.00">Headers &</text>
|
||||
<text text-anchor="middle" x="488" y="-89.4" font-family="Sans" font-size="14.00">Targets→</text>
|
||||
</g>
|
||||
<!-- software->pool0 -->
|
||||
<g id="edge12" class="edge"><title>software->pool0</title>
|
||||
<path fill="none" stroke="black" d="M353.717,-60.9421C343.82,-56.5055 336,-53 336,-53 336,-53 260,-53 260,-53 260,-53 256.28,-54.7909 250.794,-57.4326"/>
|
||||
<polygon fill="black" stroke="black" points="249.21,-54.3107 241.718,-61.8024 252.246,-60.6177 249.21,-54.3107"/>
|
||||
<text text-anchor="middle" x="298" y="-57.4" font-family="Sans" font-size="14.00">←Blocks</text>
|
||||
</g>
|
||||
<!-- pool0->p2pnetwork -->
|
||||
<g id="edge6" class="edge"><title>pool0->p2pnetwork</title>
|
||||
<path fill="none" stroke="black" d="M170.282,-61.8024C160.24,-56.9673 152,-53 152,-53 152,-53 96,-53 96,-53 96,-53 92.3058,-54.6851 86.7984,-57.1972"/>
|
||||
<polygon fill="black" stroke="black" points="85.2967,-54.0352 77.6511,-61.3697 88.2018,-60.4039 85.2967,-54.0352"/>
|
||||
<text text-anchor="middle" x="124" y="-57.4" font-family="Sans" font-size="14.00">←Blocks</text>
|
||||
</g>
|
||||
<!-- pool0->software -->
|
||||
<g id="edge2" class="edge"><title>pool0->software</title>
|
||||
<path fill="none" stroke="black" d="M241.804,-79C270.644,-79 311.532,-79 343.667,-79"/>
|
||||
<polygon fill="black" stroke="black" points="343.767,-82.5001 353.767,-79 343.767,-75.5001 343.767,-82.5001"/>
|
||||
<text text-anchor="middle" x="298" y="-100.4" font-family="Sans" font-size="14.00">Block</text>
|
||||
<text text-anchor="middle" x="298" y="-83.4" font-family="Sans" font-size="14.00">Template→</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5 KiB |
86
img/dev/en-transaction-propagation.dot
Normal file
|
@ -0,0 +1,86 @@
|
|||
digraph blockchain {
|
||||
|
||||
//splines = "ortho";
|
||||
rankdir=LR;
|
||||
ranksep=0.1;
|
||||
size=6.25;
|
||||
|
||||
node [ shape = box ]
|
||||
|
||||
subgraph cluster_tx0 {
|
||||
label = "Transaction 0\n(TX 0)"
|
||||
|
||||
tx0_input0 [ label = "input0" ]
|
||||
|
||||
tx0_output0 [ label = "output0" ]
|
||||
tx0_output1 [ label = "output1" ]
|
||||
}
|
||||
|
||||
subgraph cluster_tx1 {
|
||||
label = "TX 1"
|
||||
|
||||
tx1_input0 [ label = "input0" ]
|
||||
|
||||
tx1_output0 [ label = "output0" ]
|
||||
}
|
||||
|
||||
subgraph cluster_tx2 {
|
||||
label = "TX 2"
|
||||
|
||||
tx2_input0 [ label = "input0" ]
|
||||
|
||||
tx2_output0 [ label = "output0" ]
|
||||
tx2_output1 [ label = "output1" ]
|
||||
}
|
||||
|
||||
subgraph cluster_tx3 {
|
||||
label = "TX 3"
|
||||
|
||||
tx3_input0 [ label = "input0" ]
|
||||
|
||||
tx3_output0 [ label = "output0" ]
|
||||
}
|
||||
|
||||
subgraph cluster_tx4 {
|
||||
label = "TX 4"
|
||||
|
||||
tx4_input0 [ label = "input0" ]
|
||||
|
||||
tx4_output0 [ label = "output0" ]
|
||||
}
|
||||
|
||||
subgraph cluster_tx5 {
|
||||
label = "TX 5"
|
||||
|
||||
tx5_input0 [ label = "input0" ]
|
||||
|
||||
tx5_output0 [ label = "output0" ]
|
||||
}
|
||||
|
||||
subgraph cluster_tx6 {
|
||||
label = "TX 6"
|
||||
|
||||
tx6_input0 [ label = "input0" ]
|
||||
tx6_input1 [ label = "input1" ]
|
||||
|
||||
tx6_output0 [ label = "output0" ]
|
||||
}
|
||||
txold [ style = "invis", label = "", width = 0, height = 0 ];
|
||||
utxo0 [ style = "invis", label = "", width = 0, height = 0 ];
|
||||
//spacer0 [ style = "invis", label = "", width = 0, height = 0 ];
|
||||
//tx3_output0 -> spacer0 -> utxo0 [ style = invis ];
|
||||
//tx6_input0 -> utxo0 [style = invis];
|
||||
utxo1 [ style = "invis", label = "", width = 0, height = 0 ];
|
||||
|
||||
txold -> tx0_input0 [ label = "100,000\n(100k)\nsatoshis", style = dotted ]
|
||||
tx0_output0 -> tx1_input0 [ label = "40k" ]
|
||||
tx0_output1 -> tx2_input0 [ label = "50k" ]
|
||||
tx1_output0 -> tx3_input0 [ label = "30k" ]
|
||||
tx2_output0 -> tx4_input0 [ label = "20k" ]
|
||||
tx2_output1 -> tx5_input0 [ label = "20k"]
|
||||
tx4_output0 -> tx6_input0 [ label = "10k" ]
|
||||
tx5_output0 -> tx6_input1 [ label = "10k" ]
|
||||
tx3_output0 -> utxo0 [ style=dashed, labelfloat = true, minlen = 2, label = "20k Unspent TX\nOutput (UTXO)" ]
|
||||
tx6_output0 -> utxo1 [ style=dashed, label = "10k\nUTXO" ]
|
||||
label = "Triple-Entry Bookkeeping (Transaction-To-Transaction Payments) As Used By Bitcoin"
|
||||
}
|
BIN
img/dev/en-transaction-propagation.png
Normal file
After Width: | Height: | Size: 10 KiB |
195
img/dev/en-transaction-propagation.svg
Normal file
|
@ -0,0 +1,195 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: blockchain Pages: 1 -->
|
||||
<svg width="450pt" height="353pt"
|
||||
viewBox="0.00 0.00 450.00 353.37" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.690184 0.690184) rotate(0) translate(4 508)">
|
||||
<title>blockchain</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-508 649,-508 649,5 -4,5"/>
|
||||
<text text-anchor="middle" x="322" y="-8.4" font-family="Sans" font-size="14.00">Triple-Entry Bookkeeping (Transaction-To-Transaction Payments) As Used By Bitcoin</text>
|
||||
<g id="graph2" class="cluster"><title>cluster_tx0</title>
|
||||
<polygon fill="none" stroke="black" points="78,-290 78,-492 188,-492 188,-290 78,-290"/>
|
||||
<text text-anchor="middle" x="133" y="-475.4" font-family="Sans" font-size="14.00">Transaction 0</text>
|
||||
<text text-anchor="middle" x="133" y="-458.4" font-family="Sans" font-size="14.00">(TX 0)</text>
|
||||
</g>
|
||||
<g id="graph3" class="cluster"><title>cluster_tx1</title>
|
||||
<polygon fill="none" stroke="black" points="232,-365 232,-496 320,-496 320,-365 232,-365"/>
|
||||
<text text-anchor="middle" x="276" y="-479.4" font-family="Sans" font-size="14.00">TX 1</text>
|
||||
</g>
|
||||
<g id="graph4" class="cluster"><title>cluster_tx2</title>
|
||||
<polygon fill="none" stroke="black" points="232,-172 232,-357 320,-357 320,-172 232,-172"/>
|
||||
<text text-anchor="middle" x="276" y="-340.4" font-family="Sans" font-size="14.00">TX 2</text>
|
||||
</g>
|
||||
<g id="graph5" class="cluster"><title>cluster_tx3</title>
|
||||
<polygon fill="none" stroke="black" points="364,-311 364,-442 452,-442 452,-311 364,-311"/>
|
||||
<text text-anchor="middle" x="408" y="-425.4" font-family="Sans" font-size="14.00">TX 3</text>
|
||||
</g>
|
||||
<g id="graph6" class="cluster"><title>cluster_tx4</title>
|
||||
<polygon fill="none" stroke="black" points="364,-172 364,-303 452,-303 452,-172 364,-172"/>
|
||||
<text text-anchor="middle" x="408" y="-286.4" font-family="Sans" font-size="14.00">TX 4</text>
|
||||
</g>
|
||||
<g id="graph7" class="cluster"><title>cluster_tx5</title>
|
||||
<polygon fill="none" stroke="black" points="364,-33 364,-164 452,-164 452,-33 364,-33"/>
|
||||
<text text-anchor="middle" x="408" y="-147.4" font-family="Sans" font-size="14.00">TX 5</text>
|
||||
</g>
|
||||
<g id="graph8" class="cluster"><title>cluster_tx6</title>
|
||||
<polygon fill="none" stroke="black" points="496,-41 496,-226 584,-226 584,-41 496,-41"/>
|
||||
<text text-anchor="middle" x="540" y="-209.4" font-family="Sans" font-size="14.00">TX 6</text>
|
||||
</g>
|
||||
<!-- tx0_input0 -->
|
||||
<g id="node2" class="node"><title>tx0_input0</title>
|
||||
<polygon fill="none" stroke="black" points="164,-442 102,-442 102,-406 164,-406 164,-442"/>
|
||||
<text text-anchor="middle" x="133" y="-419.9" font-family="Sans" font-size="14.00">input0</text>
|
||||
</g>
|
||||
<!-- tx0_output0 -->
|
||||
<g id="node3" class="node"><title>tx0_output0</title>
|
||||
<polygon fill="none" stroke="black" points="169,-388 97,-388 97,-352 169,-352 169,-388"/>
|
||||
<text text-anchor="middle" x="133" y="-365.9" font-family="Sans" font-size="14.00">output0</text>
|
||||
</g>
|
||||
<!-- tx1_input0 -->
|
||||
<g id="node6" class="node"><title>tx1_input0</title>
|
||||
<polygon fill="none" stroke="black" points="307,-463 245,-463 245,-427 307,-427 307,-463"/>
|
||||
<text text-anchor="middle" x="276" y="-440.9" font-family="Sans" font-size="14.00">input0</text>
|
||||
</g>
|
||||
<!-- tx0_output0->tx1_input0 -->
|
||||
<g id="edge11" class="edge"><title>tx0_output0->tx1_input0</title>
|
||||
<path fill="none" stroke="black" d="M169.205,-387.498C175.495,-390.616 181.955,-393.869 188,-397 203.741,-405.152 220.887,-414.416 235.828,-422.616"/>
|
||||
<polygon fill="black" stroke="black" points="234.367,-425.807 244.814,-427.565 237.744,-419.675 234.367,-425.807"/>
|
||||
<text text-anchor="middle" x="210" y="-419.4" font-family="Sans" font-size="14.00">40k</text>
|
||||
</g>
|
||||
<!-- tx0_output1 -->
|
||||
<g id="node4" class="node"><title>tx0_output1</title>
|
||||
<polygon fill="none" stroke="black" points="169,-334 97,-334 97,-298 169,-298 169,-334"/>
|
||||
<text text-anchor="middle" x="133" y="-311.9" font-family="Sans" font-size="14.00">output1</text>
|
||||
</g>
|
||||
<!-- tx2_input0 -->
|
||||
<g id="node9" class="node"><title>tx2_input0</title>
|
||||
<polygon fill="none" stroke="black" points="307,-324 245,-324 245,-288 307,-288 307,-324"/>
|
||||
<text text-anchor="middle" x="276" y="-301.9" font-family="Sans" font-size="14.00">input0</text>
|
||||
</g>
|
||||
<!-- tx0_output1->tx2_input0 -->
|
||||
<g id="edge13" class="edge"><title>tx0_output1->tx2_input0</title>
|
||||
<path fill="none" stroke="black" d="M169.085,-313.477C189.045,-312.081 213.932,-310.34 234.671,-308.89"/>
|
||||
<polygon fill="black" stroke="black" points="235.052,-312.372 244.784,-308.183 234.564,-305.389 235.052,-312.372"/>
|
||||
<text text-anchor="middle" x="210" y="-315.4" font-family="Sans" font-size="14.00">50k</text>
|
||||
</g>
|
||||
<!-- tx1_output0 -->
|
||||
<g id="node7" class="node"><title>tx1_output0</title>
|
||||
<polygon fill="none" stroke="black" points="312,-409 240,-409 240,-373 312,-373 312,-409"/>
|
||||
<text text-anchor="middle" x="276" y="-386.9" font-family="Sans" font-size="14.00">output0</text>
|
||||
</g>
|
||||
<!-- tx3_input0 -->
|
||||
<g id="node13" class="node"><title>tx3_input0</title>
|
||||
<polygon fill="none" stroke="black" points="439,-409 377,-409 377,-373 439,-373 439,-409"/>
|
||||
<text text-anchor="middle" x="408" y="-386.9" font-family="Sans" font-size="14.00">input0</text>
|
||||
</g>
|
||||
<!-- tx1_output0->tx3_input0 -->
|
||||
<g id="edge15" class="edge"><title>tx1_output0->tx3_input0</title>
|
||||
<path fill="none" stroke="black" d="M312.07,-391C328.884,-391 348.988,-391 366.437,-391"/>
|
||||
<polygon fill="black" stroke="black" points="366.906,-394.5 376.906,-391 366.906,-387.5 366.906,-394.5"/>
|
||||
<text text-anchor="middle" x="342" y="-395.4" font-family="Sans" font-size="14.00">30k</text>
|
||||
</g>
|
||||
<!-- tx2_output0 -->
|
||||
<g id="node10" class="node"><title>tx2_output0</title>
|
||||
<polygon fill="none" stroke="black" points="312,-270 240,-270 240,-234 312,-234 312,-270"/>
|
||||
<text text-anchor="middle" x="276" y="-247.9" font-family="Sans" font-size="14.00">output0</text>
|
||||
</g>
|
||||
<!-- tx4_input0 -->
|
||||
<g id="node16" class="node"><title>tx4_input0</title>
|
||||
<polygon fill="none" stroke="black" points="439,-270 377,-270 377,-234 439,-234 439,-270"/>
|
||||
<text text-anchor="middle" x="408" y="-247.9" font-family="Sans" font-size="14.00">input0</text>
|
||||
</g>
|
||||
<!-- tx2_output0->tx4_input0 -->
|
||||
<g id="edge17" class="edge"><title>tx2_output0->tx4_input0</title>
|
||||
<path fill="none" stroke="black" d="M312.07,-252C328.884,-252 348.988,-252 366.437,-252"/>
|
||||
<polygon fill="black" stroke="black" points="366.906,-255.5 376.906,-252 366.906,-248.5 366.906,-255.5"/>
|
||||
<text text-anchor="middle" x="342" y="-256.4" font-family="Sans" font-size="14.00">20k</text>
|
||||
</g>
|
||||
<!-- tx2_output1 -->
|
||||
<g id="node11" class="node"><title>tx2_output1</title>
|
||||
<polygon fill="none" stroke="black" points="312,-216 240,-216 240,-180 312,-180 312,-216"/>
|
||||
<text text-anchor="middle" x="276" y="-193.9" font-family="Sans" font-size="14.00">output1</text>
|
||||
</g>
|
||||
<!-- tx5_input0 -->
|
||||
<g id="node19" class="node"><title>tx5_input0</title>
|
||||
<polygon fill="none" stroke="black" points="439,-131 377,-131 377,-95 439,-95 439,-131"/>
|
||||
<text text-anchor="middle" x="408" y="-108.9" font-family="Sans" font-size="14.00">input0</text>
|
||||
</g>
|
||||
<!-- tx2_output1->tx5_input0 -->
|
||||
<g id="edge19" class="edge"><title>tx2_output1->tx5_input0</title>
|
||||
<path fill="none" stroke="black" d="M303.994,-179.974C323.682,-167.296 350.215,-150.21 371.554,-136.469"/>
|
||||
<polygon fill="black" stroke="black" points="373.534,-139.357 380.047,-131 369.744,-133.472 373.534,-139.357"/>
|
||||
<text text-anchor="middle" x="342" y="-168.4" font-family="Sans" font-size="14.00">20k</text>
|
||||
</g>
|
||||
<!-- tx3_output0 -->
|
||||
<g id="node14" class="node"><title>tx3_output0</title>
|
||||
<polygon fill="none" stroke="black" points="444,-355 372,-355 372,-319 444,-319 444,-355"/>
|
||||
<text text-anchor="middle" x="408" y="-332.9" font-family="Sans" font-size="14.00">output0</text>
|
||||
</g>
|
||||
<!-- utxo0 -->
|
||||
<!-- tx3_output0->utxo0 -->
|
||||
<g id="edge25" class="edge"><title>tx3_output0->utxo0</title>
|
||||
<path fill="none" stroke="black" stroke-dasharray="5,2" d="M444.204,-337C498.689,-337 598.917,-337 632.049,-337"/>
|
||||
<polygon fill="black" stroke="black" points="632.145,-340.5 642.145,-337 632.145,-333.5 632.145,-340.5"/>
|
||||
<text text-anchor="middle" x="540" y="-358.4" font-family="Sans" font-size="14.00">20k Unspent TX</text>
|
||||
<text text-anchor="middle" x="540" y="-341.4" font-family="Sans" font-size="14.00">Output (UTXO)</text>
|
||||
</g>
|
||||
<!-- tx4_output0 -->
|
||||
<g id="node17" class="node"><title>tx4_output0</title>
|
||||
<polygon fill="none" stroke="black" points="444,-216 372,-216 372,-180 444,-180 444,-216"/>
|
||||
<text text-anchor="middle" x="408" y="-193.9" font-family="Sans" font-size="14.00">output0</text>
|
||||
</g>
|
||||
<!-- tx6_input0 -->
|
||||
<g id="node22" class="node"><title>tx6_input0</title>
|
||||
<polygon fill="none" stroke="black" points="571,-193 509,-193 509,-157 571,-157 571,-193"/>
|
||||
<text text-anchor="middle" x="540" y="-170.9" font-family="Sans" font-size="14.00">input0</text>
|
||||
</g>
|
||||
<!-- tx4_output0->tx6_input0 -->
|
||||
<g id="edge21" class="edge"><title>tx4_output0->tx6_input0</title>
|
||||
<path fill="none" stroke="black" d="M444.163,-186.661C449.439,-185.273 454.833,-183.995 460,-183 472.421,-180.608 486.074,-178.907 498.529,-177.707"/>
|
||||
<polygon fill="black" stroke="black" points="499.003,-181.179 508.657,-176.814 498.388,-174.206 499.003,-181.179"/>
|
||||
<text text-anchor="middle" x="474" y="-187.4" font-family="Sans" font-size="14.00">10k</text>
|
||||
</g>
|
||||
<!-- tx5_output0 -->
|
||||
<g id="node20" class="node"><title>tx5_output0</title>
|
||||
<polygon fill="none" stroke="black" points="444,-77 372,-77 372,-41 444,-41 444,-77"/>
|
||||
<text text-anchor="middle" x="408" y="-54.9" font-family="Sans" font-size="14.00">output0</text>
|
||||
</g>
|
||||
<!-- tx6_input1 -->
|
||||
<g id="node23" class="node"><title>tx6_input1</title>
|
||||
<polygon fill="none" stroke="black" points="571,-139 509,-139 509,-103 571,-103 571,-139"/>
|
||||
<text text-anchor="middle" x="540" y="-116.9" font-family="Sans" font-size="14.00">input1</text>
|
||||
</g>
|
||||
<!-- tx5_output0->tx6_input1 -->
|
||||
<g id="edge23" class="edge"><title>tx5_output0->tx6_input1</title>
|
||||
<path fill="none" stroke="black" d="M444.07,-75.9418C461.202,-83.9887 481.747,-93.6389 499.422,-101.941"/>
|
||||
<polygon fill="black" stroke="black" points="498.367,-105.312 508.906,-106.395 501.343,-98.9758 498.367,-105.312"/>
|
||||
<text text-anchor="middle" x="474" y="-100.4" font-family="Sans" font-size="14.00">10k</text>
|
||||
</g>
|
||||
<!-- tx6_output0 -->
|
||||
<g id="node24" class="node"><title>tx6_output0</title>
|
||||
<polygon fill="none" stroke="black" points="576,-85 504,-85 504,-49 576,-49 576,-85"/>
|
||||
<text text-anchor="middle" x="540" y="-62.9" font-family="Sans" font-size="14.00">output0</text>
|
||||
</g>
|
||||
<!-- utxo1 -->
|
||||
<!-- tx6_output0->utxo1 -->
|
||||
<g id="edge27" class="edge"><title>tx6_output0->utxo1</title>
|
||||
<path fill="none" stroke="black" stroke-dasharray="5,2" d="M576.024,-67C595.705,-67 618.71,-67 631.993,-67"/>
|
||||
<polygon fill="black" stroke="black" points="632.339,-70.5001 642.339,-67 632.339,-63.5001 632.339,-70.5001"/>
|
||||
<text text-anchor="middle" x="613" y="-88.4" font-family="Sans" font-size="14.00">10k</text>
|
||||
<text text-anchor="middle" x="613" y="-71.4" font-family="Sans" font-size="14.00">UTXO</text>
|
||||
</g>
|
||||
<!-- txold -->
|
||||
<!-- txold->tx0_input0 -->
|
||||
<g id="edge9" class="edge"><title>txold->tx0_input0</title>
|
||||
<path fill="none" stroke="black" stroke-dasharray="1,5" d="M1.84293,-424C8.67759,-424 55.6789,-424 91.4816,-424"/>
|
||||
<polygon fill="black" stroke="black" points="91.7074,-427.5 101.707,-424 91.7074,-420.5 91.7074,-427.5"/>
|
||||
<text text-anchor="middle" x="40" y="-462.4" font-family="Sans" font-size="14.00">100,000</text>
|
||||
<text text-anchor="middle" x="40" y="-445.4" font-family="Sans" font-size="14.00">(100k)</text>
|
||||
<text text-anchor="middle" x="40" y="-428.4" font-family="Sans" font-size="14.00">satoshis</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 12 KiB |
84
img/dev/en-tx-overview.dot
Normal file
|
@ -0,0 +1,84 @@
|
|||
digraph blockchain {
|
||||
|
||||
size=6.25;
|
||||
splines = "false";
|
||||
rankdir=LR;
|
||||
ranksep=0.1;
|
||||
//splines=ortho;
|
||||
|
||||
node [ penwidth=1.75, fontname="Sans", shape = box ];
|
||||
edge [ penwidth=1.75, fontname="Sans" ];
|
||||
graph [ penwidth=1.75, fontname="Sans" ];
|
||||
|
||||
//edge [ style = invis, minlen = 1 ];
|
||||
//fixedsize
|
||||
nodesep = 0.25;
|
||||
//concentrate = true;
|
||||
|
||||
tophelp0 [style = invis, label="", width=0, height=0 ];
|
||||
prevout [style = invis, label="", width=0, height=0 ];
|
||||
nextout [style = invis, label="", width=0, height=0 ];
|
||||
|
||||
subgraph cluster_tx {
|
||||
version;
|
||||
subgraph cluster_input {
|
||||
sequence;
|
||||
vout [label="output index"];
|
||||
txid;
|
||||
input [style = invis, label="", width=0, height=0 ];
|
||||
|
||||
subgraph cluster_scriptsig {
|
||||
label = "scriptSig"
|
||||
subgraph cluster_signature {
|
||||
hashtype;
|
||||
signature [style = invis, label="", width=0, height=0 ];
|
||||
label = "signature"
|
||||
}
|
||||
scriptsig [style = invis, label="", width=0, height=0 ];
|
||||
}
|
||||
label = "Input"
|
||||
}
|
||||
|
||||
left0 [style = invis ];
|
||||
left1 [style = invis ];
|
||||
left2 [style = invis ];
|
||||
middle1 [style = invis, label="", width=0, height=0 ];
|
||||
middle2 [style = invis, label="", width=0, height=0 ];
|
||||
middle3 [style = invis, label="", width=0, height=1.05 ];
|
||||
middle4 [style = invis, label="", width=0, height=0 ];
|
||||
middle5 [style = invis, label="", width=0, height=0 ];
|
||||
middle6 [style = invis, label="", width=0, height=0 ];
|
||||
middle7 [style = invis, label="", width=0, height=0 ];
|
||||
middle0 [style = invis, label="", width=0, height=0 ];
|
||||
|
||||
subgraph cluster_output {
|
||||
output [style = invis, label="", width=0, height=0 ];
|
||||
amount;
|
||||
script;
|
||||
label = "Output"
|
||||
}
|
||||
|
||||
locktime;
|
||||
label = "A Basic Transaction With One Input & One Output"
|
||||
}
|
||||
|
||||
prevout -> input [ style = "dashed", label = "Each input\nspends\nsatoshis\nfrom a\nprevious\noutput\n(prevout)" ];
|
||||
output -> nextout [style="dashed", label = "Each output\nwaits as an\nUnspent\nTx Output\n(UTXO)\nuntil a\nlater input\nspends it"];
|
||||
tophelp0 -> version [ style = invis ];
|
||||
|
||||
txid -> middle1 [ dir = none, label = "Select a previous tx with an\noutput to spend" ];
|
||||
vout -> middle2 [ dir = none, label = "Select an output from previous tx" ];
|
||||
sequence -> middle3 [ dir = none, label = "Allow override of locktime" ];
|
||||
scriptsig -> middle4 [ dir = none, label = "Satisfy prevout script conditions" ];
|
||||
signature -> middle5 [ dir = none, label = "Protect tx against modification\nby unauthorized parties" ];
|
||||
hashtype -> middle6 [ dir = none, label = "Authorize others to modify tx;\nselect what they can modify" ];
|
||||
|
||||
version -> middle7 [ dir = none, label = "Indicate what rules this tx follows" ];
|
||||
left2 -> locktime [ dir = none, label = "Prevent tx from being added to the\nblock chain before a particular time" ];
|
||||
|
||||
left0 -> amount [ dir = none, label = "Set amount to spend & pay in fees" ];
|
||||
left1 -> script [ dir = none, label = "Describe conditions necessary\nto spend this output" ];
|
||||
|
||||
|
||||
label = "(Metadata not shown: number of inputs/outputs, length in bytes of each script/scriptSig)\n \nThe Parts Of A Transaction"
|
||||
}
|
BIN
img/dev/en-tx-overview.png
Normal file
After Width: | Height: | Size: 16 KiB |
175
img/dev/en-tx-overview.svg
Normal file
|
@ -0,0 +1,175 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||
-->
|
||||
<!-- Title: blockchain Pages: 1 -->
|
||||
<svg width="450pt" height="444pt"
|
||||
viewBox="0.00 0.00 450.00 444.16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(0.648415 0.648415) rotate(0) translate(4 681)">
|
||||
<title>blockchain</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-681 691,-681 691,5 -4,5"/>
|
||||
<text text-anchor="middle" x="343" y="-42.4" font-family="Sans" font-size="14.00">(Metadata not shown: number of inputs/outputs, length in bytes of each script/scriptSig)</text>
|
||||
<text text-anchor="middle" x="343" y="-25.4" font-family="Sans" font-size="14.00"> </text>
|
||||
<text text-anchor="middle" x="343" y="-8.4" font-family="Sans" font-size="14.00">The Parts Of A Transaction</text>
|
||||
<g id="graph2" class="cluster"><title>cluster_tx</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="92,-67 92,-669 582,-669 582,-67 92,-67"/>
|
||||
<text text-anchor="middle" x="337" y="-652.4" font-family="Sans" font-size="14.00">A Basic Transaction With One Input & One Output</text>
|
||||
</g>
|
||||
<g id="graph3" class="cluster"><title>cluster_input</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="100,-247 100,-592 228,-592 228,-247 100,-247"/>
|
||||
<text text-anchor="middle" x="164" y="-575.4" font-family="Sans" font-size="14.00">Input</text>
|
||||
</g>
|
||||
<g id="graph4" class="cluster"><title>cluster_scriptsig</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="108,-263 108,-407 220,-407 220,-263 108,-263"/>
|
||||
<text text-anchor="middle" x="164" y="-390.4" font-family="Sans" font-size="14.00">scriptSig</text>
|
||||
</g>
|
||||
<g id="graph5" class="cluster"><title>cluster_signature</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="116,-271 116,-366 212,-366 212,-271 116,-271"/>
|
||||
<text text-anchor="middle" x="164" y="-349.4" font-family="Sans" font-size="14.00">signature</text>
|
||||
</g>
|
||||
<g id="graph6" class="cluster"><title>cluster_output</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="488,-138 488,-287 574,-287 574,-138 488,-138"/>
|
||||
<text text-anchor="middle" x="531" y="-270.4" font-family="Sans" font-size="14.00">Output</text>
|
||||
</g>
|
||||
<!-- tophelp0 -->
|
||||
<!-- version -->
|
||||
<g id="node5" class="node"><title>version</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="197,-636 131,-636 131,-600 197,-600 197,-636"/>
|
||||
<text text-anchor="middle" x="164" y="-613.9" font-family="Sans" font-size="14.00">version</text>
|
||||
</g>
|
||||
<!-- tophelp0->version -->
|
||||
<!-- prevout -->
|
||||
<!-- input -->
|
||||
<!-- prevout->input -->
|
||||
<g id="edge7" class="edge"><title>prevout->input</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="5,2" d="M1.72672,-255C11.5697,-255 118.636,-255 153.264,-255"/>
|
||||
<polygon fill="black" stroke="black" points="153.328,-258.5 163.328,-255 153.328,-251.5 153.328,-258.5"/>
|
||||
<text text-anchor="middle" x="47" y="-361.4" font-family="Sans" font-size="14.00">Each input</text>
|
||||
<text text-anchor="middle" x="47" y="-344.4" font-family="Sans" font-size="14.00">spends</text>
|
||||
<text text-anchor="middle" x="47" y="-327.4" font-family="Sans" font-size="14.00">satoshis</text>
|
||||
<text text-anchor="middle" x="47" y="-310.4" font-family="Sans" font-size="14.00">from a</text>
|
||||
<text text-anchor="middle" x="47" y="-293.4" font-family="Sans" font-size="14.00">previous</text>
|
||||
<text text-anchor="middle" x="47" y="-276.4" font-family="Sans" font-size="14.00">output</text>
|
||||
<text text-anchor="middle" x="47" y="-259.4" font-family="Sans" font-size="14.00">(prevout)</text>
|
||||
</g>
|
||||
<!-- nextout -->
|
||||
<!-- middle7 -->
|
||||
<!-- version->middle7 -->
|
||||
<g id="edge25" class="edge"><title>version->middle7</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M197.542,-618C285.309,-618 515.97,-618 530.301,-618"/>
|
||||
<text text-anchor="middle" x="358" y="-622.4" font-family="Sans" font-size="14.00">Indicate what rules this tx follows</text>
|
||||
</g>
|
||||
<!-- sequence -->
|
||||
<g id="node7" class="node"><title>sequence</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="204,-451 124,-451 124,-415 204,-415 204,-451"/>
|
||||
<text text-anchor="middle" x="164" y="-428.9" font-family="Sans" font-size="14.00">sequence</text>
|
||||
</g>
|
||||
<!-- middle3 -->
|
||||
<!-- sequence->middle3 -->
|
||||
<g id="edge17" class="edge"><title>sequence->middle3</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M204.678,-433C297.245,-433 516.709,-433 530.335,-433"/>
|
||||
<text text-anchor="middle" x="358" y="-437.4" font-family="Sans" font-size="14.00">Allow override of locktime</text>
|
||||
</g>
|
||||
<!-- vout -->
|
||||
<g id="node8" class="node"><title>vout</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="216,-505 112,-505 112,-469 216,-469 216,-505"/>
|
||||
<text text-anchor="middle" x="164" y="-482.9" font-family="Sans" font-size="14.00">output index</text>
|
||||
</g>
|
||||
<!-- middle2 -->
|
||||
<!-- vout->middle2 -->
|
||||
<g id="edge15" class="edge"><title>vout->middle2</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M216.582,-487.287C314.89,-487.822 517.8,-488.928 530.386,-488.997"/>
|
||||
<text text-anchor="middle" x="358" y="-493.4" font-family="Sans" font-size="14.00">Select an output from previous tx</text>
|
||||
</g>
|
||||
<!-- txid -->
|
||||
<g id="node9" class="node"><title>txid</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="191,-559 137,-559 137,-523 191,-523 191,-559"/>
|
||||
<text text-anchor="middle" x="164" y="-536.9" font-family="Sans" font-size="14.00">txid</text>
|
||||
</g>
|
||||
<!-- middle1 -->
|
||||
<!-- txid->middle1 -->
|
||||
<g id="edge13" class="edge"><title>txid->middle1</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M191.285,-541C273.68,-541 515.249,-541 530.267,-541"/>
|
||||
<text text-anchor="middle" x="358" y="-562.4" font-family="Sans" font-size="14.00">Select a previous tx with an</text>
|
||||
<text text-anchor="middle" x="358" y="-545.4" font-family="Sans" font-size="14.00">output to spend</text>
|
||||
</g>
|
||||
<!-- hashtype -->
|
||||
<g id="node13" class="node"><title>hashtype</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="204,-315 124,-315 124,-279 204,-279 204,-315"/>
|
||||
<text text-anchor="middle" x="164" y="-292.9" font-family="Sans" font-size="14.00">hashtype</text>
|
||||
</g>
|
||||
<!-- middle6 -->
|
||||
<!-- hashtype->middle6 -->
|
||||
<g id="edge23" class="edge"><title>hashtype->middle6</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M204.325,-296.78C296.683,-296.277 516.674,-295.078 530.333,-295.004"/>
|
||||
<text text-anchor="middle" x="358" y="-316.4" font-family="Sans" font-size="14.00">Authorize others to modify tx;</text>
|
||||
<text text-anchor="middle" x="358" y="-299.4" font-family="Sans" font-size="14.00">select what they can modify</text>
|
||||
</g>
|
||||
<!-- signature -->
|
||||
<!-- middle5 -->
|
||||
<!-- signature->middle5 -->
|
||||
<g id="edge21" class="edge"><title>signature->middle5</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M164.595,-333C180.617,-333 514.777,-333 530.432,-333"/>
|
||||
<text text-anchor="middle" x="358" y="-354.4" font-family="Sans" font-size="14.00">Protect tx against modification</text>
|
||||
<text text-anchor="middle" x="358" y="-337.4" font-family="Sans" font-size="14.00">by unauthorized parties</text>
|
||||
</g>
|
||||
<!-- scriptsig -->
|
||||
<!-- middle4 -->
|
||||
<!-- scriptsig->middle4 -->
|
||||
<g id="edge19" class="edge"><title>scriptsig->middle4</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M164.595,-374.005C180.617,-374.136 514.777,-376.867 530.432,-376.995"/>
|
||||
<text text-anchor="middle" x="358" y="-381.4" font-family="Sans" font-size="14.00">Satisfy prevout script conditions</text>
|
||||
</g>
|
||||
<!-- left0 -->
|
||||
<!-- amount -->
|
||||
<g id="node29" class="node"><title>amount</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="566,-236 496,-236 496,-200 566,-200 566,-236"/>
|
||||
<text text-anchor="middle" x="531" y="-213.9" font-family="Sans" font-size="14.00">amount</text>
|
||||
</g>
|
||||
<!-- left0->amount -->
|
||||
<g id="edge29" class="edge"><title>left0->amount</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M191.285,-218.926C256.819,-218.747 423.047,-218.294 495.891,-218.096"/>
|
||||
<text text-anchor="middle" x="358" y="-223.4" font-family="Sans" font-size="14.00">Set amount to spend & pay in fees</text>
|
||||
</g>
|
||||
<!-- left1 -->
|
||||
<!-- script -->
|
||||
<g id="node30" class="node"><title>script</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="558,-182 504,-182 504,-146 558,-146 558,-182"/>
|
||||
<text text-anchor="middle" x="531" y="-159.9" font-family="Sans" font-size="14.00">script</text>
|
||||
</g>
|
||||
<!-- left1->script -->
|
||||
<g id="edge31" class="edge"><title>left1->script</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M191.285,-164.926C259.228,-164.741 435.402,-164.26 503.536,-164.075"/>
|
||||
<text text-anchor="middle" x="358" y="-186.4" font-family="Sans" font-size="14.00">Describe conditions necessary</text>
|
||||
<text text-anchor="middle" x="358" y="-169.4" font-family="Sans" font-size="14.00">to spend this output</text>
|
||||
</g>
|
||||
<!-- left2 -->
|
||||
<!-- locktime -->
|
||||
<g id="node31" class="node"><title>locktime</title>
|
||||
<polygon fill="none" stroke="black" stroke-width="1.75" points="568,-125 494,-125 494,-89 568,-89 568,-125"/>
|
||||
<text text-anchor="middle" x="531" y="-102.9" font-family="Sans" font-size="14.00">locktime</text>
|
||||
</g>
|
||||
<!-- left2->locktime -->
|
||||
<g id="edge27" class="edge"><title>left2->locktime</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" d="M191.285,-110.703C256.238,-109.995 420.105,-108.209 493.931,-107.404"/>
|
||||
<text text-anchor="middle" x="358" y="-132.4" font-family="Sans" font-size="14.00">Prevent tx from being added to the</text>
|
||||
<text text-anchor="middle" x="358" y="-115.4" font-family="Sans" font-size="14.00">block chain before a particular time</text>
|
||||
</g>
|
||||
<!-- middle0 -->
|
||||
<!-- output -->
|
||||
<!-- output->nextout -->
|
||||
<g id="edge9" class="edge"><title>output->nextout</title>
|
||||
<path fill="none" stroke="black" stroke-width="1.75" stroke-dasharray="5,2" d="M531.687,-254C540.903,-254 640.334,-254 673.96,-254"/>
|
||||
<polygon fill="black" stroke="black" points="674.365,-257.5 684.365,-254 674.365,-250.5 674.365,-257.5"/>
|
||||
<text text-anchor="middle" x="633" y="-377.4" font-family="Sans" font-size="14.00">Each output</text>
|
||||
<text text-anchor="middle" x="633" y="-360.4" font-family="Sans" font-size="14.00">waits as an</text>
|
||||
<text text-anchor="middle" x="633" y="-343.4" font-family="Sans" font-size="14.00">Unspent</text>
|
||||
<text text-anchor="middle" x="633" y="-326.4" font-family="Sans" font-size="14.00">Tx Output</text>
|
||||
<text text-anchor="middle" x="633" y="-309.4" font-family="Sans" font-size="14.00">(UTXO)</text>
|
||||
<text text-anchor="middle" x="633" y="-292.4" font-family="Sans" font-size="14.00">until a</text>
|
||||
<text text-anchor="middle" x="633" y="-275.4" font-family="Sans" font-size="14.00">later input</text>
|
||||
<text text-anchor="middle" x="633" y="-258.4" font-family="Sans" font-size="14.00">spends it</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 11 KiB |