Merge pull request #393 from bitcoin/devel-docs

Add Developer Guide To Bitcoin.org
This commit is contained in:
saivann 2014-05-24 11:01:45 -04:00
commit 2f17ee4dae
121 changed files with 16160 additions and 12 deletions

294
_autocrossref.yaml Normal file
View 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

View 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 %}
![Block Chain Overview](/img/dev/en-blockchain-overview.svg)
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.
![Transaction Propagation](/img/dev/en-transaction-propagation.svg)
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.
![Common And Uncommon Block Chain Forks](/img/dev/en-blockchain-fork.svg)
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 %}

View 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.
![Micropayment Channel Example](/img/dev/en-micropayment-channel.svg)
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.
![Example CoinJoin Transaction](/img/dev/en-coinjoin.svg)
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
View 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
View 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.
![Solo Bitcoin Mining](/img/dev/en-solo-mining-overview.svg)
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.
![Pooled Bitcoin Mining](/img/dev/en-pooled-mining-overview.svg)
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 %}

View 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 clients 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.
![Block Height Compared To Block Depth](/img/dev/en-block-height-vs-depth.svg)
{% 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 %}

View 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 %}

File diff suppressed because it is too large Load diff

View 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 Parts Of A Transaction](/img/dev/en-tx-overview.svg)
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.
![Creating A P2PKH Public Key Hash To Receive Payment](/img/dev/en-creating-p2pkh-output.svg)
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.
![Unlocking A P2PKH Output For Spending](/img/dev/en-unlocking-p2pkh-output.svg)
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.
![Some Things Signed When Spending An Output](/img/dev/en-signing-output-to-spend.svg)
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.
![P2PKH Stack Evaluation](/img/dev/en-p2pkh-stack.svg)
* 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.
![Creating A P2SH RedeemScript And Hash](/img/dev/en-creating-p2sh-output.svg)
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.
![Unlocking A P2SH Output For Spending](/img/dev/en-unlocking-p2sh-output.svg)
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 its 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 arent as
secure as P2PKH, so they generally
arent 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
View 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.
![Overview Of Hierarchical Deterministic Key Derivation](/img/dev/en-hd-overview.svg)
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.
![Creating A Root Extended Key Pair](/img/dev/en-hd-root-keys.svg)
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.
![Cross-Generational Key Compromise](/img/dev/en-hd-cross-generational-key-compromise.svg)
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.
![Creating Child Public Keys From An Extended Private Key](/img/dev/en-hd-private-parent-to-private-child.svg)
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.
![Example HD Wallet Tree Using Prime Notation](/img/dev/en-hd-tree.svg)
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 ones 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 %}

View 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 %}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View 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" }'
~~~

View 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.)

View 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
View 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 %}
![Overview Of Hierarchical Deterministic Key Derivation](/img/dev/en-hd-overview.svg)
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
View 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

View file

@ -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;

View file

@ -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
View 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)

View file

@ -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 %}

View file

@ -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>

View file

@ -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."

View 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
View 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
View 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
View 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.

View 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"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View 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&#45;&gt;h1 -->
<g id="edge3" class="edge"><title>h0&#45;&gt;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&#45;&gt;h100 -->
<g id="edge5" class="edge"><title>h1&#45;&gt;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&#45;&gt;h101 -->
<g id="edge7" class="edge"><title>h100&#45;&gt;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&#45;&gt;h102 -->
<g id="edge8" class="edge"><title>h101&#45;&gt;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&#45;&gt;d1 -->
<g id="edge11" class="edge"><title>d0&#45;&gt;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&#45;&gt;d100 -->
<g id="edge13" class="edge"><title>d1&#45;&gt;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&#45;&gt;d101 -->
<g id="edge15" class="edge"><title>d100&#45;&gt;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&#45;&gt;d102 -->
<g id="edge16" class="edge"><title>d101&#45;&gt;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

View 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";
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View 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&#45;&gt;block01 -->
<g id="edge11" class="edge"><title>block00&#45;&gt;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&#45;&gt;block02 -->
<g id="edge13" class="edge"><title>block01&#45;&gt;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&#45;&gt;block02x -->
<g id="edge3" class="edge"><title>block01&#45;&gt;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&#45;&gt;block03 -->
<g id="edge15" class="edge"><title>block02&#45;&gt;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&#45;&gt;block04 -->
<g id="edge17" class="edge"><title>block03&#45;&gt;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&#45;&gt;block05 -->
<g id="edge19" class="edge"><title>block04&#45;&gt;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&#45;&gt;block06 -->
<g id="edge21" class="edge"><title>block05&#45;&gt;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&#45;&gt;block03x -->
<g id="edge5" class="edge"><title>block02x&#45;&gt;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&#45;&gt;block04x -->
<g id="edge7" class="edge"><title>block03x&#45;&gt;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&#45;&gt;block05x -->
<g id="edge9" class="edge"><title>block04x&#45;&gt;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&#45;&gt;block2x -->
<g id="edge24" class="edge"><title>block1&#45;&gt;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&#45;&gt;block2 -->
<g id="edge30" class="edge"><title>block1&#45;&gt;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&#45;&gt;block5x -->
<g id="edge26" class="edge"><title>block4&#45;&gt;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&#45;&gt;block5 -->
<g id="edge36" class="edge"><title>block4&#45;&gt;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&#45;&gt;block1 -->
<g id="edge28" class="edge"><title>block0&#45;&gt;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&#45;&gt;block3 -->
<g id="edge32" class="edge"><title>block2&#45;&gt;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&#45;&gt;block4 -->
<g id="edge34" class="edge"><title>block3&#45;&gt;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&#45;&gt;block6 -->
<g id="edge38" class="edge"><title>block5&#45;&gt;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

View 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";
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

View 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&#45;&gt;hashMerkleRoot0 -->
<g id="edge14" class="edge"><title>_transactions0&#45;&gt;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&#45;&gt;_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&#45;&gt;hashBlock0 -->
<g id="edge7" class="edge"><title>_blockHeader0&#45;&gt;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&#45;&gt;hashMerkleRoot1 -->
<!-- _transactions1&#45;&gt;hashMerkleRoot1 -->
<g id="edge16" class="edge"><title>_transactions1&#45;&gt;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&#45;&gt;_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&#45;&gt;hashBlock1 -->
<g id="edge9" class="edge"><title>_blockHeader1&#45;&gt;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&#45;&gt;hashMerkleRoot2 -->
<!-- _transactions2&#45;&gt;hashMerkleRoot2 -->
<g id="edge18" class="edge"><title>_transactions2&#45;&gt;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&#45;&gt;hashBlock9 -->
<g id="edge5" class="edge"><title>invis0&#45;&gt;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&#45;&gt;_transactions0 -->
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

29
img/dev/en-cert-order.dot Normal file
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 9 KiB

66
img/dev/en-cert-order.svg Normal file
View 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&#45;&gt;btcorg -->
<g id="edge4" class="edge"><title>rapidssl&#45;&gt;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&#45;&gt;rapidssl -->
<g id="edge3" class="edge"><title>geotrust&#45;&gt;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"> &#160;&#160;&#160;x509.certificate.append(bitcoin_org&#45;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"> &#160;&#160;&#160;x509.certificate.append(rapidssl_ca&#45;cert) </text>
</g>
<!-- one&#45;&gt;two -->
<g id="edge7" class="edge"><title>one&#45;&gt;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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

206
img/dev/en-coinjoin.svg Normal file
View 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&#39;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&#39;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&#39;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&#45;&gt;nemo_in1 -->
<g id="edge27" class="edge"><title>nemo_out1&#45;&gt;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&#45;&gt;nemo_in2 -->
<g id="edge29" class="edge"><title>nemo_out2&#45;&gt;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&#45;&gt;neminem_in1 -->
<g id="edge31" class="edge"><title>neminem_out1&#45;&gt;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&#45;&gt;alice_in1 -->
<g id="edge21" class="edge"><title>alice_out1&#45;&gt;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&#45;&gt;alice_in2 -->
<g id="edge23" class="edge"><title>alice_out2&#45;&gt;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&#45;&gt;alice_in3 -->
<g id="edge25" class="edge"><title>alice_out3&#45;&gt;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&#45;&gt;nemo_out1 -->
<g id="edge15" class="edge"><title>prevout3&#45;&gt;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&#45;&gt;nemo_out2 -->
<g id="edge17" class="edge"><title>prevout4&#45;&gt;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&#45;&gt;neminem_out1 -->
<g id="edge19" class="edge"><title>prevout5&#45;&gt;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&#45;&gt;alice_out1 -->
<g id="edge9" class="edge"><title>prevout0&#45;&gt;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&#45;&gt;alice_out2 -->
<g id="edge11" class="edge"><title>prevout1&#45;&gt;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&#45;&gt;alice_out3 -->
<g id="edge13" class="edge"><title>prevout2&#45;&gt;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&#45;&gt;utxo1 -->
<g id="edge33" class="edge"><title>out1&#45;&gt;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&#45;&gt;utxo2 -->
<g id="edge35" class="edge"><title>out2&#45;&gt;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&#45;&gt;utxo3 -->
<g id="edge37" class="edge"><title>out3&#45;&gt;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

View 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"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View 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&#39;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&#39;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&#45;&gt;full_public_key -->
<g id="edge5" class="edge"><title>private_key&#45;&gt;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&#45;&gt;pubkey_hash -->
<g id="edge6" class="edge"><title>full_public_key&#45;&gt;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&#45;&gt;spender_pubkey_hash -->
<g id="edge7" class="edge"><title>pubkey_hash&#45;&gt;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&#45;&gt;tx1_pubkey_hash -->
<g id="edge8" class="edge"><title>spender_pubkey_hash&#45;&gt;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

View 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"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View 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&#39;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&#39;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&#45;&gt;full_public_key -->
<g id="edge5" class="edge"><title>private_key&#45;&gt;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&#45;&gt;redeemScript -->
<g id="edge6" class="edge"><title>full_public_key&#45;&gt;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&#45;&gt;script_hash -->
<g id="edge7" class="edge"><title>redeemScript&#45;&gt;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&#45;&gt;spender_script_hash -->
<g id="edge8" class="edge"><title>script_hash&#45;&gt;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&#45;&gt;tx1_script_hash -->
<g id="edge9" class="edge"><title>spender_script_hash&#45;&gt;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

View 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"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

View 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&#45;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&#45;</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&#45;&gt;child_private_key -->
<g id="edge16" class="edge"><title>parent_private_key&#45;&gt;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&#45;&gt;parent_private_key -->
<g id="edge18" class="edge"><title>parent_chain_code&#45;&gt;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&#45;&gt;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&#45;&gt;child_chain_code -->
<g id="edge10" class="edge"><title>parent_chain_code&#45;&gt;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&#45;&gt;child_public_key -->
<g id="edge12" class="edge"><title>parent_chain_code&#45;&gt;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&#45;&gt;child_chain_code -->
<g id="edge8" class="edge"><title>parent_public_key&#45;&gt;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&#45;&gt;child_public_key -->
<g id="edge6" class="edge"><title>parent_public_key&#45;&gt;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&#45;&gt;grandchild_private_key -->
<g id="edge20" class="edge"><title>child_private_key&#45;&gt;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&#45;&gt;child_private_key -->
<g id="edge32" class="edge"><title>child_chain_code&#45;&gt;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&#45;&gt;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&#45;&gt;grandchild_chain_code -->
<g id="edge30" class="edge"><title>child_chain_code&#45;&gt;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&#45;&gt;grandchild_public_key -->
<g id="edge28" class="edge"><title>child_chain_code&#45;&gt;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&#45;&gt;grandchild_chain_code -->
<g id="edge22" class="edge"><title>child_public_key&#45;&gt;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&#45;&gt;grandchild_public_key -->
<g id="edge24" class="edge"><title>child_public_key&#45;&gt;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&#45;&gt;greatgrandchild_private_key -->
<g id="edge34" class="edge"><title>grandchild_private_key&#45;&gt;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&#45;&gt;grandchild_private_key -->
<!-- grandchild_chain_code&#45;&gt;greatgrandchild_private_key -->
<g id="edge40" class="edge"><title>grandchild_chain_code&#45;&gt;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&#45;&gt;greatgrandchild_chain_code -->
<g id="edge44" class="edge"><title>grandchild_chain_code&#45;&gt;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&#45;&gt;greatgrandchild_public_key -->
<g id="edge42" class="edge"><title>grandchild_chain_code&#45;&gt;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&#45;&gt;greatgrandchild_chain_code -->
<g id="edge36" class="edge"><title>grandchild_public_key&#45;&gt;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&#45;&gt;greatgrandchild_public_key -->
<g id="edge38" class="edge"><title>grandchild_public_key&#45;&gt;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&#45;&gt;greatgrandchild_private_key -->
</g>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

135
img/dev/en-hd-overview.svg Normal file
View 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&#45;&gt;child_private_key -->
<g id="edge15" class="edge"><title>parent_private_key&#45;&gt;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&#45;Way Hash</text>
</g>
<!-- parent_private_key&#45;&gt;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&#45;&gt;hmac -->
<g id="edge21" class="edge"><title>parent_chain_code&#45;&gt;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&#45;&gt;child_public_key -->
<g id="edge17" class="edge"><title>parent_public_key&#45;&gt;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&#45;&gt;hmac -->
<g id="edge19" class="edge"><title>parent_public_key&#45;&gt;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&#45;&gt;rel2 -->
<g id="edge9" class="edge"><title>child_private_key&#45;&gt;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&#45;&gt;rel2 -->
<!-- child_public_key&#45;&gt;rel2 -->
<g id="edge13" class="edge"><title>child_public_key&#45;&gt;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&#45;&gt;hmac -->
<g id="edge25" class="edge"><title>i_norm&#45;&gt;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&#45;&gt;child_private_key -->
<g id="edge29" class="edge"><title>hmac&#45;&gt;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&#45;&gt;child_chain_code -->
<g id="edge31" class="edge"><title>hmac&#45;&gt;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&#45;&gt;child_public_key -->
<g id="edge27" class="edge"><title>hmac&#45;&gt;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&#45;&gt;parent_private_key -->
<g id="edge3" class="edge"><title>rel1&#45;&gt;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&#45;&gt;parent_chain_code -->
<!-- rel1&#45;&gt;parent_public_key -->
<g id="edge7" class="edge"><title>rel1&#45;&gt;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

View 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";
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View 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&#45;&gt;child_private_key_hard -->
<g id="edge15" class="edge"><title>h_parent_private_key&#45;&gt;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&#45;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&#45;&gt;hmac_hard -->
<g id="edge7" class="edge"><title>h_parent_private_key&#45;&gt;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&#45;&gt;hmac_hard -->
<g id="edge5" class="edge"><title>h_parent_chain_code&#45;&gt;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&#45;&gt;child_private_key_hard -->
<g id="edge11" class="edge"><title>hmac_hard&#45;&gt;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&#45;&gt;child_chain_code_hard -->
<g id="edge13" class="edge"><title>hmac_hard&#45;&gt;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&#45;&gt;hmac_hard -->
<g id="edge9" class="edge"><title>i_hard&#45;&gt;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&#45;&gt;child_private_key_norm -->
<g id="edge30" class="edge"><title>n_parent_private_key&#45;&gt;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&#45;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&#45;&gt;hmac_norm -->
<g id="edge20" class="edge"><title>n_parent_chain_code&#45;&gt;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&#45;&gt;hmac_norm -->
<g id="edge22" class="edge"><title>n_parent_public_key&#45;&gt;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&#45;&gt;child_private_key_norm -->
<g id="edge26" class="edge"><title>hmac_norm&#45;&gt;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&#45;&gt;child_chain_code_norm -->
<g id="edge28" class="edge"><title>hmac_norm&#45;&gt;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 &lt;0x80000000</text>
</g>
<!-- i_norm&#45;&gt;hmac_norm -->
<g id="edge24" class="edge"><title>i_norm&#45;&gt;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

View 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"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View 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&#45;&gt;fp_child_private_key_norm -->
<g id="edge14" class="edge"><title>fp_n_parent_private_key&#45;&gt;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&#45;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&#45;&gt;fp_hmac_norm -->
<g id="edge6" class="edge"><title>fp_n_parent_chain_code&#45;&gt;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&#45;&gt;fp_n_child_public_key_norm -->
<g id="edge16" class="edge"><title>fp_child_private_key_norm&#45;&gt;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&#45;&gt;fp_child_chain_code_norm1 -->
<g id="edge18" class="edge"><title>fp_child_chain_code_norm&#45;&gt;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&#45;&gt;fp_child_private_key_norm -->
<g id="edge10" class="edge"><title>fp_hmac_norm&#45;&gt;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&#45;&gt;fp_child_chain_code_norm -->
<g id="edge12" class="edge"><title>fp_hmac_norm&#45;&gt;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&#45;&gt;fp_hmac_norm -->
<g id="edge8" class="edge"><title>fp_i_norm&#45;&gt;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&#45;&gt;fp_n_child_public_key_norm -->
<g id="edge20" class="edge"><title>equiv&#45;&gt;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&#45;&gt;equiv -->
<g id="edge22" class="edge"><title>child_public_key_hard&#45;&gt;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&#45;&gt;child_public_key_hard -->
<g id="edge35" class="edge"><title>h_parent_public_key&#45;&gt;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&#45;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&#45;&gt;hmac_hard -->
<g id="edge27" class="edge"><title>h_parent_chain_code&#45;&gt;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&#45;&gt;child_public_key_hard -->
<g id="edge31" class="edge"><title>hmac_hard&#45;&gt;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&#45;&gt;child_chain_code_hard -->
<g id="edge33" class="edge"><title>hmac_hard&#45;&gt;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&#45;&gt;hmac_hard -->
<g id="edge29" class="edge"><title>i_hard&#45;&gt;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

View 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)"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

View 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&#45;&gt;child_public_key_norm -->
<g id="edge13" class="edge"><title>n_parent_public_key&#45;&gt;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&#45;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&#45;&gt;hmac_norm -->
<g id="edge5" class="edge"><title>n_parent_chain_code&#45;&gt;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&#45;&gt;child_public_key_norm -->
<g id="edge9" class="edge"><title>hmac_norm&#45;&gt;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&#45;&gt;child_chain_code_norm -->
<g id="edge11" class="edge"><title>hmac_norm&#45;&gt;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&#45;&gt;hmac_norm -->
<g id="edge7" class="edge"><title>i_norm&#45;&gt;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

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

111
img/dev/en-hd-root-keys.svg Normal file
View 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&#45;Bit</text>
<text text-anchor="middle" x="154" y="-131.9" font-family="Sans" font-size="14.00">One&#45;Way</text>
<text text-anchor="middle" x="154" y="-114.9" font-family="Sans" font-size="14.00">Hash</text>
</g>
<!-- entropy&#45;&gt;hmac -->
<g id="edge2" class="edge"><title>entropy&#45;&gt;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&#45;&gt;private_key -->
<g id="edge4" class="edge"><title>hmac&#45;&gt;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&#45;&gt;chain_code -->
<g id="edge6" class="edge"><title>hmac&#45;&gt;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&#45;&gt;public_key -->
<g id="edge10" class="edge"><title>private_key&#45;&gt;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&#45;&gt;extended_private_key -->
<g id="edge16" class="edge"><title>private_key&#45;&gt;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&#45;&gt;extended_private_key -->
<g id="edge12" class="edge"><title>chain_code&#45;&gt;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&#45;&gt;extended_public_key -->
<g id="edge14" class="edge"><title>chain_code&#45;&gt;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&#45;&gt;extended_public_key -->
<g id="edge18" class="edge"><title>public_key&#45;&gt;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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

142
img/dev/en-hd-tree.svg Normal file
View 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&#39;</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&#39;</text>
</g>
<!-- m0p&#45;&gt;M0p -->
<g id="edge3" class="edge"><title>m0p&#45;&gt;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&#39;/0</text>
</g>
<!-- m0p&#45;&gt;m0p_0 -->
<g id="edge17" class="edge"><title>m0p&#45;&gt;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&#39;/1&#39;</text>
</g>
<!-- m0p&#45;&gt;m0p_1p -->
<g id="edge19" class="edge"><title>m0p&#45;&gt;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&#39;/0</text>
</g>
<!-- m0p_0&#45;&gt;M0p_0 -->
<g id="edge6" class="edge"><title>m0p_0&#45;&gt;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&#39;/0/0</text>
</g>
<!-- m0p_0&#45;&gt;m0p_0_0 -->
<g id="edge21" class="edge"><title>m0p_0&#45;&gt;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&#39;/0/0</text>
</g>
<!-- M0p_0&#45;&gt;M0p_0_0 -->
<g id="edge23" class="edge"><title>M0p_0&#45;&gt;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&#39;/1&#39;</text>
</g>
<!-- m0p_1p&#45;&gt;M0p_1p -->
<g id="edge9" class="edge"><title>m0p_1p&#45;&gt;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&#39;/1&#39;/0</text>
</g>
<!-- m0p_1p&#45;&gt;m0p_1p_0 -->
<g id="edge25" class="edge"><title>m0p_1p&#45;&gt;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&#45;&gt;M0p_0_0 -->
<g id="edge12" class="edge"><title>m0p_0_0&#45;&gt;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&#39;/1&#39;/0</text>
</g>
<!-- m0p_1p_0&#45;&gt;M0p_1p_0 -->
<g id="edge15" class="edge"><title>m0p_1p_0&#45;&gt;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

View 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)"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View 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. &#160;If she fails to broadcast before refund v1&#39;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&#39;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&#39;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&#45;&gt;btx1v2 -->
<g id="edge6" class="edge"><title>atx2v1s&#45;&gt;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&#45;of&#45;2</text>
<text text-anchor="middle" x="73" y="-367.9" font-family="Sans" font-size="14.00">multisig)</text>
</g>
<!-- btx2v2s -->
<!-- atx1v2&#45;&gt;btx2v2s -->
<g id="edge10" class="edge"><title>atx1v2&#45;&gt;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&#45;&gt;btx2v3 -->
<g id="edge14" class="edge"><title>atx2v3&#45;&gt;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&#45;&gt;btx2v4 -->
<g id="edge18" class="edge"><title>atx2v4&#45;&gt;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&#45;&gt;btx2v5 -->
<g id="edge22" class="edge"><title>atx2v5&#45;&gt;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&#39;m done for the day. &#160;I&#39;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&#45;&gt;atx2v1s -->
<g id="edge4" class="edge"><title>btx2v1&#45;&gt;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&#39;t be spent for 24 hours</text>
</g>
<!-- btx1v2&#45;&gt;atx1v2 -->
<g id="edge8" class="edge"><title>btx1v2&#45;&gt;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&#39;s the bond; please start working</text>
</g>
<!-- btx2v2s&#45;&gt;atx2v3 -->
<g id="edge12" class="edge"><title>btx2v2s&#45;&gt;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&#45;&gt;atx2v4 -->
<g id="edge16" class="edge"><title>btx2v3&#45;&gt;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&#45;&gt;atx2v5 -->
<g id="edge20" class="edge"><title>btx2v4&#45;&gt;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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

306
img/dev/en-p2pkh-stack.svg Normal file
View 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&#39;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&#39;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&#45;&gt;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&#45;&gt;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&#45;&gt;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&#45;&gt;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&#45;&gt;bob_opdup -->
<!-- invis2_1 -->
<!-- alice_opdup&#45;&gt;invis2_1 -->
<g id="edge40" class="edge"><title>alice_opdup&#45;&gt;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&#45;&gt;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&#45;&gt;bob_sig -->
<!-- invis5_0 -->
<!-- bob_opchecksig&#45;&gt;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&#45;&gt;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&#45;&gt;stack6_opequalverify -->
<!-- invis4_0 -->
<!-- bob_pubkeyhash&#45;&gt;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&#45;&gt;stack5_pubkeyhash -->
<!-- invis3_0 -->
<!-- bob_ophash&#45;&gt;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&#45;&gt;stack4_ophash -->
<!-- invis2_0 -->
<!-- bob_opdup&#45;&gt;invis2_0 -->
<!-- invis1_0 -->
<!-- bob_pubkey&#45;&gt;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&#45;&gt;stack2_pubkey -->
<!-- invis0_0 -->
<!-- bob_sig&#45;&gt;invis0_0 -->
<!-- invis0_1 -->
<!-- bob_sig&#45;&gt;invis0_1 -->
<g id="edge25" class="edge"><title>bob_sig&#45;&gt;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&#45;&gt;invis0_1 -->
<!-- invis0_2 -->
<!-- invis0_1&#45;&gt;invis0_2 -->
<!-- invis0_3 -->
<!-- invis0_2&#45;&gt;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&#45;&gt;stack1_sig -->
<!-- invis1_1 -->
<!-- invis1_0&#45;&gt;invis1_1 -->
<!-- invis1_2 -->
<!-- invis1_1&#45;&gt;invis1_2 -->
<!-- invis1_2&#45;&gt;stack2_pubkey -->
<!-- invis2_0&#45;&gt;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&#45;&gt;stack3_opdup -->
<!-- invis3_0&#45;&gt;stack4_ophash -->
<!-- invis4_0&#45;&gt;stack5_pubkeyhash -->
<!-- invis5_1 -->
<!-- invis5_0&#45;&gt;invis5_1 -->
<!-- invis5_1&#45;&gt;stack7_opchecksig -->
<!-- invis6_0 -->
<!-- invis6_1 -->
<!-- invis6_0&#45;&gt;invis6_1 -->
<!-- invis6_2 -->
<!-- invis6_1&#45;&gt;invis6_2 -->
<!-- invis6_3 -->
<!-- invis6_2&#45;&gt;invis6_3 -->
<!-- invis6_4 -->
<!-- invis6_3&#45;&gt;invis6_4 -->
<!-- invis6_5 -->
<!-- invis6_4&#45;&gt;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&#45;&gt;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&#45;&gt;stack7_pubkey -->
<!-- stack7_opchecksig&#45;&gt;TRUE -->
<g id="edge86" class="edge"><title>stack7_opchecksig&#45;&gt;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&#45;&gt;stack7_opchecksig -->
<g id="edge100" class="edge"><title>stack7_pubkey&#45;&gt;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&#45;&gt;stack7_sig -->
<!-- stack7_sig&#45;&gt;stack7_pubkey -->
<g id="edge102" class="edge"><title>stack7_sig&#45;&gt;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&#45;&gt;stack6_pubkeyhash -->
<!-- stack6_pubkeyhash&#45;&gt;stack6_opequalverify -->
<g id="edge96" class="edge"><title>stack6_pubkeyhash&#45;&gt;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&#45;&gt;stack6_ophash -->
<!-- stack6_ophash&#45;&gt;stack6_pubkeyhash -->
<g id="edge98" class="edge"><title>stack6_ophash&#45;&gt;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&#45;&gt;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&#45;&gt;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&#45;&gt;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&#45;&gt;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&#45;&gt;stack5_sig -->
<!-- stack4_ophash&#45;&gt;stack5_ophash -->
<g id="edge92" class="edge"><title>stack4_ophash&#45;&gt;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&#45;&gt;stack4_opdup -->
<!-- stack4_opdup&#45;&gt;stack4_ophash -->
<g id="edge94" class="edge"><title>stack4_opdup&#45;&gt;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&#45;&gt;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&#45;&gt;stack4_sig -->
<!-- stack3_opdup&#45;&gt;stack4_opdup -->
<g id="edge88" class="edge"><title>stack3_opdup&#45;&gt;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&#45;&gt;stack3_pubkey -->
<!-- stack3_pubkey&#45;&gt;stack3_opdup -->
<g id="edge90" class="edge"><title>stack3_pubkey&#45;&gt;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&#45;&gt;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&#45;&gt;stack2_sig -->
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

View 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)"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 KiB

View 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&#39;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&#45;&#45;calc_total -->
<g id="edge2" class="edge"><title>submit_order&#45;&#45;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&#45;&#45;request_payment -->
<g id="edge4" class="edge"><title>calc_total&#45;&#45;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">&amp; Fulfill</text>
<text text-anchor="middle" x="327" y="-78.4" font-family="Sans" font-size="14.00">Order</text>
</g>
<!-- request_payment&#45;&#45;verify_payment -->
<g id="edge5" class="edge"><title>request_payment&#45;&#45;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&#45;&#45;issue_refund -->
<g id="edge7" class="edge"><title>verify_payment&#45;&#45;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&#45;&#45;pay_expenses -->
<g id="edge8" class="edge"><title>issue_refund&#45;&#45;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&#45;&#45;rebill_recurring -->
<g id="edge9" class="edge"><title>pay_expenses&#45;&#45;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&#45;&#45;calc_total -->
<g id="edge11" class="edge"><title>rebill_recurring&#45;&#45;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

View 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"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View 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&#39;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&#45;&gt;w0 -->
<g id="edge8" class="edge"><title>c0&#45;&gt;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&#45;&gt;w2 -->
<g id="edge16" class="edge"><title>c2&#45;&gt;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&#45;&gt;m1 -->
<g id="edge10" class="edge"><title>w0&#45;&gt;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&#45;&gt;c2 -->
<g id="edge14" class="edge"><title>w1&#45;&gt;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&#45;&gt;m3 -->
<g id="edge18" class="edge"><title>w2&#45;&gt;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&#45;&gt;c3 -->
<g id="edge24" class="edge"><title>w3&#45;&gt;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&#45;&gt;w1 -->
<g id="edge12" class="edge"><title>m1&#45;&gt;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&#39;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&#45;&gt;w3 -->
<g id="edge22" class="edge"><title>m3&#45;&gt;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&#45;&gt;p2p -->
<g id="edge20" class="edge"><title>m3&#45;&gt;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&#45;&gt;c0 -->
<g id="edge6" class="edge"><title>uri&#45;&gt;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"> &#160;?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

View 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"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

View 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&#45;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&#45;&gt;pool0 -->
<g id="edge4" class="edge"><title>p2pnetwork&#45;&gt;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&#45;&gt;software -->
<g id="edge10" class="edge"><title>asic0&#45;&gt;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&#45;&gt;asic0 -->
<g id="edge8" class="edge"><title>software&#45;&gt;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 &amp;</text>
<text text-anchor="middle" x="472" y="-89.4" font-family="Sans" font-size="14.00">Targets→</text>
</g>
<!-- software&#45;&gt;pool0 -->
<g id="edge12" class="edge"><title>software&#45;&gt;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&#45;&gt;p2pnetwork -->
<g id="edge6" class="edge"><title>pool0&#45;&gt;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&#45;&gt;software -->
<g id="edge2" class="edge"><title>pool0&#45;&gt;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

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

225
img/dev/en-qr-code.svg Normal file
View 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

View 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"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

View 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&#39;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&#45;&gt;sig_tx1_txid -->
<g id="edge10" class="edge"><title>tx1_txid&#45;&gt;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&#45;&gt;sig_tx1_vout -->
<g id="edge12" class="edge"><title>tx1_vout&#45;&gt;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&#45;&gt;sig_tx1_script -->
<g id="edge8" class="edge"><title>tx1_script&#45;&gt;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&#45;&gt;tx2_tx1_txid -->
<g id="edge20" class="edge"><title>sig_tx1_txid&#45;&gt;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&#45;&gt;tx2_tx1_vout -->
<g id="edge22" class="edge"><title>sig_tx1_vout&#45;&gt;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&#45;&gt;tx2_script -->
<g id="edge24" class="edge"><title>sig_tx2t_script&#45;&gt;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&#45;&gt;tx2_amount -->
<g id="edge26" class="edge"><title>sig_tx2t_amount&#45;&gt;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&#45;&gt;tx2_signature -->
<g id="edge28" class="edge"><title>signature&#45;&gt;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&#45;&gt;signature -->
<g id="edge18" class="edge"><title>private_key&#45;&gt;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&#45;&gt;sig_tx2t_script -->
<g id="edge14" class="edge"><title>tx2t_script&#45;&gt;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&#45;&gt;sig_tx2t_amount -->
<g id="edge16" class="edge"><title>tx2t_amount&#45;&gt;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

View 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"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View 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&#45;&gt;pool0 -->
<g id="edge4" class="edge"><title>p2pnetwork&#45;&gt;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&#45;&gt;software -->
<g id="edge10" class="edge"><title>asic0&#45;&gt;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&#45;&gt;asic0 -->
<g id="edge8" class="edge"><title>software&#45;&gt;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 &amp;</text>
<text text-anchor="middle" x="488" y="-89.4" font-family="Sans" font-size="14.00">Targets→</text>
</g>
<!-- software&#45;&gt;pool0 -->
<g id="edge12" class="edge"><title>software&#45;&gt;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&#45;&gt;p2pnetwork -->
<g id="edge6" class="edge"><title>pool0&#45;&gt;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&#45;&gt;software -->
<g id="edge2" class="edge"><title>pool0&#45;&gt;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

View 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"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View 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&#45;Entry Bookkeeping (Transaction&#45;To&#45;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&#45;&gt;tx1_input0 -->
<g id="edge11" class="edge"><title>tx0_output0&#45;&gt;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&#45;&gt;tx2_input0 -->
<g id="edge13" class="edge"><title>tx0_output1&#45;&gt;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&#45;&gt;tx3_input0 -->
<g id="edge15" class="edge"><title>tx1_output0&#45;&gt;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&#45;&gt;tx4_input0 -->
<g id="edge17" class="edge"><title>tx2_output0&#45;&gt;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&#45;&gt;tx5_input0 -->
<g id="edge19" class="edge"><title>tx2_output1&#45;&gt;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&#45;&gt;utxo0 -->
<g id="edge25" class="edge"><title>tx3_output0&#45;&gt;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&#45;&gt;tx6_input0 -->
<g id="edge21" class="edge"><title>tx4_output0&#45;&gt;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&#45;&gt;tx6_input1 -->
<g id="edge23" class="edge"><title>tx5_output0&#45;&gt;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&#45;&gt;utxo1 -->
<g id="edge27" class="edge"><title>tx6_output0&#45;&gt;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&#45;&gt;tx0_input0 -->
<g id="edge9" class="edge"><title>txold&#45;&gt;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

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

175
img/dev/en-tx-overview.svg Normal file
View 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 &amp; 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&#45;&gt;version -->
<!-- prevout -->
<!-- input -->
<!-- prevout&#45;&gt;input -->
<g id="edge7" class="edge"><title>prevout&#45;&gt;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&#45;&gt;middle7 -->
<g id="edge25" class="edge"><title>version&#45;&gt;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&#45;&gt;middle3 -->
<g id="edge17" class="edge"><title>sequence&#45;&gt;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&#45;&gt;middle2 -->
<g id="edge15" class="edge"><title>vout&#45;&gt;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&#45;&gt;middle1 -->
<g id="edge13" class="edge"><title>txid&#45;&gt;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&#45;&gt;middle6 -->
<g id="edge23" class="edge"><title>hashtype&#45;&gt;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&#45;&gt;middle5 -->
<g id="edge21" class="edge"><title>signature&#45;&gt;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&#45;&gt;middle4 -->
<g id="edge19" class="edge"><title>scriptsig&#45;&gt;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&#45;&gt;amount -->
<g id="edge29" class="edge"><title>left0&#45;&gt;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 &amp; 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&#45;&gt;script -->
<g id="edge31" class="edge"><title>left1&#45;&gt;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&#45;&gt;locktime -->
<g id="edge27" class="edge"><title>left2&#45;&gt;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&#45;&gt;nextout -->
<g id="edge9" class="edge"><title>output&#45;&gt;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

Some files were not shown because too many files have changed in this diff Show more