All: update images for reviewer feedback
Special thanks to Murchandamus who provided most of the feedback
@ -806,7 +806,6 @@ key can produce a public key expressed in two different formats
|
|||||||
addresses. However, the private key is identical for both Bitcoin
|
addresses. However, the private key is identical for both Bitcoin
|
||||||
addresses.
|
addresses.
|
||||||
|
|
||||||
//FIXME:misaligned text, see Murch CH04 feedback
|
|
||||||
[[pubkey_compression]]
|
[[pubkey_compression]]
|
||||||
[role="smallerseventy"]
|
[role="smallerseventy"]
|
||||||
.Public key compression
|
.Public key compression
|
||||||
|
@ -366,7 +366,6 @@ header and summarizes all the data in all four transactions.
|
|||||||
<<simple_merkle>> shows how the root is calculated by pair-wise hashes
|
<<simple_merkle>> shows how the root is calculated by pair-wise hashes
|
||||||
of the nodes.
|
of the nodes.
|
||||||
|
|
||||||
//FIXME: s/+/||/
|
|
||||||
[[simple_merkle]]
|
[[simple_merkle]]
|
||||||
.Calculating the nodes in a merkle tree
|
.Calculating the nodes in a merkle tree
|
||||||
image::images/mbc2_0902.png["merkle_tree"]
|
image::images/mbc2_0902.png["merkle_tree"]
|
||||||
@ -379,7 +378,6 @@ shown in <<merkle_tree_odd>>, where transaction C is duplicated.
|
|||||||
Similarly, if there are an odd number of hashes to process at any level,
|
Similarly, if there are an odd number of hashes to process at any level,
|
||||||
the last hash is duplicated.
|
the last hash is duplicated.
|
||||||
|
|
||||||
//FIXME: s/+/||/
|
|
||||||
[[merkle_tree_odd]]
|
[[merkle_tree_odd]]
|
||||||
.Duplicating one data element achieves an even number of data elements
|
.Duplicating one data element achieves an even number of data elements
|
||||||
image::images/mbc2_0903.png["merkle_tree_odd"]
|
image::images/mbc2_0903.png["merkle_tree_odd"]
|
||||||
@ -403,18 +401,11 @@ is unusual in Merkle trees). This results in certain sequences of
|
|||||||
transactions leading to the same merkle root. For example, these two
|
transactions leading to the same merkle root. For example, these two
|
||||||
trees:
|
trees:
|
||||||
|
|
||||||
//FIXME:replace with image to fix italics in code text
|
[[cve_tree]]
|
||||||
----
|
.Two Bitcoin-style merkle tree with the same root but a different number of leaves
|
||||||
A A
|
image::images/cve-2012-2459.dot.png["Two Bitcoin-style merkle tree with the same root but a different number of leaves"]
|
||||||
/ \ / \
|
|
||||||
B C B C
|
|
||||||
/ \ | / \ / \
|
|
||||||
D E F D E F F
|
|
||||||
/ \ / \ / \ / \ / \ / \ / \
|
|
||||||
1 2 3 4 5 6 1 2 3 4 5 6 5 6
|
|
||||||
----
|
|
||||||
|
|
||||||
for transaction lists [1,2,3,4,5,6] and [1,2,3,4,5,6,5,6] (where 5 and
|
For transaction lists [1,2,3,4,5,6] and [1,2,3,4,5,6,5,6] (where 5 and
|
||||||
6 are repeated) result in the same root hash A (because the hash of both
|
6 are repeated) result in the same root hash A (because the hash of both
|
||||||
of (F) and (F,F) is C).
|
of (F) and (F,F) is C).
|
||||||
|
|
||||||
@ -475,28 +466,12 @@ diagram).
|
|||||||
image::images/mbc2_0905.png["merkle_tree_path"]
|
image::images/mbc2_0905.png["merkle_tree_path"]
|
||||||
|
|
||||||
The efficiency of merkle trees becomes obvious as the scale increases.
|
The efficiency of merkle trees becomes obvious as the scale increases.
|
||||||
<<block_structure2>> shows the amount of data that needs to be exchanged
|
The largest possible block can hold almost 16,000 transactions in 4,000,000
|
||||||
as a merkle path to prove that a transaction is part of a block.
|
bytes, but proving any particular one of those sixteen thousand transactions
|
||||||
|
is a part of that block only requires a copy of the transaction, a copy
|
||||||
//FIXME: replace with a plot of size per txes: plot [0:16000] ceil(log2(x))
|
of the 80-byte block header, and 448 bytes for the merkle proof. That
|
||||||
[[block_structure2]]
|
makes the largest possible proof almost 10,000 times smaller than the
|
||||||
.Merkle tree efficiency
|
largest possible Bitcoin block.
|
||||||
[options="header"]
|
|
||||||
|=======
|
|
||||||
|Number of transactions| Approx. size of block | Path size (hashes) | Path size (bytes)
|
|
||||||
| 16 transactions | 4 kilobytes | 4 hashes | 128 bytes
|
|
||||||
| 512 transactions | 128 kilobytes | 9 hashes | 288 bytes
|
|
||||||
| 2048 transactions | 512 kilobytes | 11 hashes | 352 bytes
|
|
||||||
| 65,535 transactions | 16 megabytes | 16 hashes | 512 bytes
|
|
||||||
|=======
|
|
||||||
|
|
||||||
With merkle trees, a node can download just the block headers (80
|
|
||||||
bytes per block) and still be able to identify a transaction's inclusion
|
|
||||||
in a block by retrieving a small merkle path from a full node, without
|
|
||||||
storing or transmitting the vast majority of the blockchain.
|
|
||||||
Clients that do not fully validate transactions, called lightweight
|
|
||||||
clients, use merkle paths to verify transactions without downloading
|
|
||||||
full blocks.
|
|
||||||
|
|
||||||
=== Merkle Trees and Lightweight Clients
|
=== Merkle Trees and Lightweight Clients
|
||||||
|
|
||||||
|
148
ch10.asciidoc
@ -1205,11 +1205,11 @@ selection of the chain with the most Proof-of-Work.
|
|||||||
A _best blockchain_ is whichever valid chain of blocks has
|
A _best blockchain_ is whichever valid chain of blocks has
|
||||||
the most cumulative Proof-of-Work associated with it.
|
the most cumulative Proof-of-Work associated with it.
|
||||||
The
|
The
|
||||||
best chain will also have branches with blocks that are "siblings" to
|
best chain may also have branches with blocks that are "siblings" to
|
||||||
the blocks on the best chain. These blocks are valid but not part of the
|
the blocks on the best chain. These blocks are valid but not part of the
|
||||||
best chain. They are kept for future reference, in case one of those
|
best chain. They are kept for future reference, in case one of those
|
||||||
chains is extended and becomes the new best chain. In the next section
|
many secondary chains later becomes primary. When sibling blocks occur,
|
||||||
(<<forks>>), we will see how secondary chains occur as a result of an
|
they're usually the result of an
|
||||||
almost simultaneous mining of blocks at the same height.
|
almost simultaneous mining of blocks at the same height.
|
||||||
|
|
||||||
When a new block is received, a node will try to add it onto the
|
When a new block is received, a node will try to add it onto the
|
||||||
@ -1219,7 +1219,7 @@ node will attempt to find that parent in the existing blockchain. Most
|
|||||||
of the time, the parent will be the "tip" of the best chain, meaning
|
of the time, the parent will be the "tip" of the best chain, meaning
|
||||||
this new block extends the best chain.
|
this new block extends the best chain.
|
||||||
|
|
||||||
Sometimes, as we will see in <<forks>>, the new block does not extend
|
Sometimes the new block does not extend
|
||||||
the best chain. In that case, the node will attach the new block to a
|
the best chain. In that case, the node will attach the new block to a
|
||||||
secondary chain and then compare the work of the secondary chain to the
|
secondary chain and then compare the work of the secondary chain to the
|
||||||
previous best chain. If the secondary chain is now the best chain, the
|
previous best chain. If the secondary chain is now the best chain, the
|
||||||
@ -1239,138 +1239,8 @@ result of transmission delays in the global network. We will also look
|
|||||||
at deliberately induced forks later in this chapter.
|
at deliberately induced forks later in this chapter.
|
||||||
====
|
====
|
||||||
|
|
||||||
In the next few diagrams, we follow the progress of a "fork" event
|
Forks are almost always resolved within one block.
|
||||||
across the network. The diagram is a simplified representation of the
|
It is possible for an accidental fork to extend to two blocks if both
|
||||||
Bitcoin network. For illustration purposes, different blocks are shown
|
|
||||||
as different shapes (star, triangle, upside-down triangle, rhombus),
|
|
||||||
spreading across the network. Each node in the network is represented as
|
|
||||||
a circle.
|
|
||||||
|
|
||||||
For
|
|
||||||
illustration purposes, each node contains a shape that represents the
|
|
||||||
block that it believes is currently the tip of the best chain. So, if
|
|
||||||
you see a star shape in the node, that means that the star block is the
|
|
||||||
tip of the best chain, as far as that node is concerned.
|
|
||||||
|
|
||||||
In the first diagram (<<fork1>>), the network has a unified perspective
|
|
||||||
of the blockchain, with the star block as the tip of the best chain.
|
|
||||||
|
|
||||||
[[fork1]]
|
|
||||||
[role="smallereighty"]
|
|
||||||
.Before the fork—all nodes have the same perspective
|
|
||||||
image::images/mbc2_1002.png["Before the fork - all nodes have the same perspective"]
|
|
||||||
|
|
||||||
In <<fork2>>, we see two miners (Node X and Node Y) who mine two
|
|
||||||
different blocks almost simultaneously. Both of these blocks are
|
|
||||||
children of the star block, and extend the chain by building on top of
|
|
||||||
the star block. To help us track it, one is visualized as a triangle
|
|
||||||
block originating from Node X, and the other is shown as an upside-down
|
|
||||||
triangle block originating from Node Y.
|
|
||||||
|
|
||||||
[[fork2]]
|
|
||||||
[role="smallersixty"]
|
|
||||||
.Visualization of a blockchain fork event: two blocks found simultaneously
|
|
||||||
image::images/mbc2_1003.png["Visualization of a blockchain fork event: two blocks found simultaneously"]
|
|
||||||
|
|
||||||
Let's assume, for example, that a miner Node X finds a Proof-of-Work
|
|
||||||
solution for a block "triangle" that extends the blockchain, building on
|
|
||||||
top of the parent block "star." Almost simultaneously, the miner Node Y
|
|
||||||
who was also extending the chain from block "star" finds a solution for
|
|
||||||
block "upside-down triangle," his candidate block. Now, there are two
|
|
||||||
possible blocks; one we call "triangle," originating in Node X; and one
|
|
||||||
we call "upside-down triangle," originating in Node Y. Both blocks are
|
|
||||||
valid, both blocks contain a valid solution to the Proof-of-Work, and
|
|
||||||
both blocks extend the same parent (block "star"). Both blocks likely
|
|
||||||
contain most of the same transactions, with only perhaps a few
|
|
||||||
differences in the order of transactions.
|
|
||||||
|
|
||||||
As the two blocks propagate, some nodes receive block "triangle" first
|
|
||||||
and some receive block "upside-down triangle" first. As shown in
|
|
||||||
<<fork3>>, the network splits into two different perspectives of the
|
|
||||||
blockchain; one side topped with a triangle block, the other with the
|
|
||||||
upside-down-triangle block.
|
|
||||||
|
|
||||||
//FIXME:node X won't receive upside down triangle because it's not
|
|
||||||
//connected to a peer with that block. Same problem for Node Y
|
|
||||||
[[fork3]]
|
|
||||||
[role="smallersixty"]
|
|
||||||
.Visualization of a blockchain fork event: two blocks propagate, splitting the network
|
|
||||||
image::images/mbc2_1004.png["Visualization of a blockchain fork event: two blocks propagate, splitting the network"]
|
|
||||||
|
|
||||||
In the diagram, a randomly chosen "Node X" received the triangle block
|
|
||||||
first and extended the star chain with it. Node X selected the chain
|
|
||||||
with "triangle" block as the best chain. Later, Node X also received the
|
|
||||||
"upside-down triangle" block. Since it was received second, it is
|
|
||||||
assumed to have "lost" the race. Yet, the "upside-down triangle" block
|
|
||||||
is not discarded. It is linked to the "star" block parent and forms a
|
|
||||||
secondary chain. While Node X assumes it has correctly selected the
|
|
||||||
winning chain, it keeps the "losing" chain so that it has the
|
|
||||||
information needed to reorganize if the "losing" chain ends up
|
|
||||||
"winning."
|
|
||||||
|
|
||||||
On the other side of the network, Node Y constructs a blockchain based
|
|
||||||
on its own perspective of the sequence of events. It received
|
|
||||||
"upside-down triangle" first and elected that chain as the "winner."
|
|
||||||
When it later received "triangle" block, it connected it to the "star"
|
|
||||||
block parent as a secondary chain.
|
|
||||||
|
|
||||||
Neither side is "correct," or "incorrect." Both are valid perspectives
|
|
||||||
of the blockchain. Only in hindsight will one prevail, based on how
|
|
||||||
these two competing chains are extended by additional work.
|
|
||||||
|
|
||||||
Mining nodes whose perspective resembles Node X will immediately begin
|
|
||||||
mining a candidate block that extends the chain with "triangle" as its
|
|
||||||
tip. By linking "triangle" as the parent of their candidate block, they
|
|
||||||
are using their hashing power to build on that chain.
|
|
||||||
|
|
||||||
Any mining node whose perspective resembles Node Y will start building a
|
|
||||||
candidate node with "upside-down triangle" as its parent, extending the
|
|
||||||
chain that they believe is the best chain. And so, the race begins
|
|
||||||
again.
|
|
||||||
|
|
||||||
Forks are almost always resolved within one block. While part of the
|
|
||||||
network's hashing power is dedicated to building on top of "triangle" as
|
|
||||||
the parent, another part of the hashing power is focused on building on
|
|
||||||
top of "upside-down triangle." Even if the hashing power is almost
|
|
||||||
evenly split, it is likely that one set of miners will find a solution
|
|
||||||
and propagate it before the other set of miners have found any
|
|
||||||
solutions. Let's say, for example, that the miners building on top of
|
|
||||||
"triangle" find a new block "rhombus" that extends the chain (e.g.,
|
|
||||||
star-triangle-rhombus). They immediately propagate this new block and
|
|
||||||
the entire network sees it as a valid solution as shown in <<fork4>>.
|
|
||||||
|
|
||||||
[[fork4]]
|
|
||||||
[role="smallereighty"]
|
|
||||||
.Visualization of a blockchain fork event: a new block extends one fork, reorganizing the network
|
|
||||||
image::images/mbc2_1005.png["Visualization of a blockchain fork event: a new block extends one fork"]
|
|
||||||
|
|
||||||
All nodes that had chosen "triangle" as the winner in the previous round
|
|
||||||
will simply extend the chain one more block. The nodes that chose
|
|
||||||
"upside-down triangle" as the winner, however, will now see two chains:
|
|
||||||
star-triangle-rhombus and star-upside-down-triangle. The chain
|
|
||||||
star-triangle-rhombus now has more cumulative work than the
|
|
||||||
other chain. As a result, those nodes will set the chain
|
|
||||||
star-triangle-rhombus as the best chain and change the
|
|
||||||
star-upside-down-triangle chain to a secondary chain, as shown in
|
|
||||||
<<fork5>>. This is a chain reorganization, because those nodes are forced
|
|
||||||
to revise their view of the blockchain to incorporate the new evidence
|
|
||||||
of a longer chain. Any miners working on extending the chain
|
|
||||||
star-upside-down-triangle will now stop that work because their
|
|
||||||
block is "stale," as its parent "upside-down-triangle" is
|
|
||||||
no longer on the best chain. The transactions within
|
|
||||||
"upside-down-triangle" that are not within "triangle" are re-inserted in
|
|
||||||
the mempool for inclusion in the next block to become a part of the best
|
|
||||||
chain. The entire network converges on a single blockchain
|
|
||||||
star-triangle-rhombus, with "rhombus" as the last block in the chain.
|
|
||||||
All miners immediately start working on candidate blocks that reference
|
|
||||||
"rhombus" as their parent to extend the star-triangle-rhombus chain.
|
|
||||||
|
|
||||||
[[fork5]]
|
|
||||||
[role="smallereighty"]
|
|
||||||
.Visualization of a blockchain fork event: the network reorganizes on a new longest chain
|
|
||||||
image::images/mbc2_1006.png["Visualization of a blockchain fork event: the network reorganizes on a new longest chain"]
|
|
||||||
|
|
||||||
It is possible for a fork to extend to two blocks, if two
|
|
||||||
blocks are found almost simultaneously by miners on opposite "sides" of
|
blocks are found almost simultaneously by miners on opposite "sides" of
|
||||||
a previous fork. However, the chance of that happening is low.
|
a previous fork. However, the chance of that happening is low.
|
||||||
|
|
||||||
@ -1856,13 +1726,9 @@ height 4, a one-block fork occurs. This is the type of spontaneous fork
|
|||||||
we saw in <<forks>>. With the mining of block 5, the network converges
|
we saw in <<forks>>. With the mining of block 5, the network converges
|
||||||
on one chain and the fork is resolved.
|
on one chain and the fork is resolved.
|
||||||
|
|
||||||
//FIXME:"The blocks following the new rules should have a unique color. I would have expected the "b-fork" to follow the old rules based on the colors."
|
|
||||||
// I was looking here where the other block was created, because I assumed that the enumeration would start with a) and then progress to b).
|
|
||||||
//
|
|
||||||
// Perhaps call this chain "7F–11F" to indicate the new Foocoin rules?
|
|
||||||
[[blockchainwithforks]]
|
[[blockchainwithforks]]
|
||||||
.A blockchain with forks
|
.A blockchain with forks
|
||||||
image::images/mbc2_1009.png[A blockchain with forks]
|
image::images/fork.dot.png[A blockchain with forks]
|
||||||
|
|
||||||
Later, however, at block height 6,
|
Later, however, at block height 6,
|
||||||
a new implementation of the client is released with a change in the
|
a new implementation of the client is released with a change in the
|
||||||
|
@ -634,7 +634,6 @@ blocks before commitment transaction #1 becomes valid.
|
|||||||
shorter timelock, allowing it to be spent before the previous
|
shorter timelock, allowing it to be spent before the previous
|
||||||
commitments become valid.
|
commitments become valid.
|
||||||
|
|
||||||
//FIXME: s/3720/3721/
|
|
||||||
[[timelocked_commitments]]
|
[[timelocked_commitments]]
|
||||||
.Each commitment sets a shorter timelock, allowing it to be spent before the previous commitments become valid
|
.Each commitment sets a shorter timelock, allowing it to be spent before the previous commitments become valid
|
||||||
image::images/mbc2_1207.png["Each commitment sets a shorter timelock, allowing it to be spent before the previous commitments become valid"]
|
image::images/mbc2_1207.png["Each commitment sets a shorter timelock, allowing it to be spent before the previous commitments become valid"]
|
||||||
|
@ -132,7 +132,6 @@ payment to a public key hash), showing the combined script resulting
|
|||||||
from the concatenation of the scripts prior to
|
from the concatenation of the scripts prior to
|
||||||
validation.
|
validation.
|
||||||
|
|
||||||
//FIXME: revise to use "output script" and "input script" from chap 6
|
|
||||||
[[input_and_output_scripts_legacy]]
|
[[input_and_output_scripts_legacy]]
|
||||||
.Combining input and output scripts to evaluate a transaction script
|
.Combining input and output scripts to evaluate a transaction script
|
||||||
image::../images/mbc2_0603.png["input_and_output_scripts"]
|
image::../images/mbc2_0603.png["input_and_output_scripts"]
|
||||||
@ -1710,7 +1709,6 @@ his partners to spend their money frequently; the time delayed
|
|||||||
conditions only exist in case something goes wrong. We can re-structure
|
conditions only exist in case something goes wrong. We can re-structure
|
||||||
our tree with this knowledge in <<diagram_mast3>>.
|
our tree with this knowledge in <<diagram_mast3>>.
|
||||||
|
|
||||||
//FIXME: keep leaves in the same order, see Murch feedback chapter 7
|
|
||||||
[[diagram_mast3]]
|
[[diagram_mast3]]
|
||||||
.A MAST with the most-expected script in the best position
|
.A MAST with the most-expected script in the best position
|
||||||
image::../images/mast3.dot.png["A MAST with the most-expected script in the best position"]
|
image::../images/mast3.dot.png["A MAST with the most-expected script in the best position"]
|
||||||
|
72
images/cve-2012-2459.dot
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// A A
|
||||||
|
// / \ / \
|
||||||
|
// B C B C
|
||||||
|
// / \ | / \ / \
|
||||||
|
// D E F D E F F
|
||||||
|
// / \ / \ / \ / \ / \ / \ / \
|
||||||
|
// 1 2 3 4 5 6 1 2 3 4 5 6 5 6
|
||||||
|
|
||||||
|
digraph MerkleTrees {
|
||||||
|
// General settings
|
||||||
|
rankdir=TB;
|
||||||
|
//node [shape=none, style=filled, color=lightblue];
|
||||||
|
node [shape=box, width=0, height=0];
|
||||||
|
ranksep=0.3;
|
||||||
|
nodesep=0.1
|
||||||
|
|
||||||
|
subgraph cluster_x {
|
||||||
|
// Merkle Tree 1
|
||||||
|
A1 [label="A"];
|
||||||
|
B1 [label="B"];
|
||||||
|
C1 [label="C"];
|
||||||
|
D1 [label="D"];
|
||||||
|
E1 [label="E"];
|
||||||
|
F1 [label="F"];
|
||||||
|
x1 [label="1"];
|
||||||
|
x2 [label="2"];
|
||||||
|
x3 [label="3"];
|
||||||
|
x4 [label="4"];
|
||||||
|
x5 [label="5"];
|
||||||
|
x6 [label="6"];
|
||||||
|
|
||||||
|
A1 -> B1;
|
||||||
|
A1 -> C1;
|
||||||
|
B1 -> D1;
|
||||||
|
B1 -> E1;
|
||||||
|
C1 -> F1;
|
||||||
|
D1 -> {x1, x2};
|
||||||
|
E1 -> {x3, x4};
|
||||||
|
F1 -> {x5, x6};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
subgraph cluster_y {
|
||||||
|
// Merkle Tree 2
|
||||||
|
A2 [label="A"];
|
||||||
|
B2 [label="B"];
|
||||||
|
C2 [label="C"];
|
||||||
|
D2 [label="D"];
|
||||||
|
E2 [label="E"];
|
||||||
|
F2 [label="F"];
|
||||||
|
F2_dup [label = "F" ];
|
||||||
|
y1 [label="1"];
|
||||||
|
y2 [label="2"];
|
||||||
|
y3 [label="3"];
|
||||||
|
y4 [label="4"];
|
||||||
|
y5 [label="5"];
|
||||||
|
y6 [label="6"];
|
||||||
|
y5_dup [label="5"];
|
||||||
|
y6_dup [label="6"];
|
||||||
|
|
||||||
|
A2 -> B2;
|
||||||
|
A2 -> C2;
|
||||||
|
B2 -> D2;
|
||||||
|
B2 -> E2;
|
||||||
|
C2 -> {F2, F2_dup};
|
||||||
|
D2 -> {y1, y2};
|
||||||
|
E2 -> {y3, y4};
|
||||||
|
F2 -> {y5, y6};
|
||||||
|
F2_dup -> {y5_dup, y6_dup};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
BIN
images/cve-2012-2459.dot.png
Normal file
After Width: | Height: | Size: 9.1 KiB |
38
images/fork.dot
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
digraph G {
|
||||||
|
rankdir=LR; // Left to Right direction
|
||||||
|
node [shape=box];
|
||||||
|
|
||||||
|
block1 [label="1"];
|
||||||
|
block2 [label="2"];
|
||||||
|
block3 [label="3"];
|
||||||
|
block4a [label="4a"];
|
||||||
|
block4b [label="4b"];
|
||||||
|
block5 [label="5"];
|
||||||
|
block6 [label="7"];
|
||||||
|
block7a [label="7a"];
|
||||||
|
block8a [label="8a"];
|
||||||
|
|
||||||
|
subgraph cluster_foocoin {
|
||||||
|
block7b [label="7b"];
|
||||||
|
block8b [label="8b"];
|
||||||
|
block9 [label="9"];
|
||||||
|
block10 [label="10"];
|
||||||
|
block11 [label="11"];
|
||||||
|
|
||||||
|
labelloc = "t"
|
||||||
|
label = "Using new rules"
|
||||||
|
}
|
||||||
|
|
||||||
|
block1 -> block2 [dir=back];
|
||||||
|
block2 -> block3 [dir=back];
|
||||||
|
block3 -> {block4a,block4b} [dir=back];
|
||||||
|
block4a -> block5 [dir=back];
|
||||||
|
block5 -> block6 [dir=back];
|
||||||
|
block6 -> {block7a,block7b} [dir=back];
|
||||||
|
block7a -> block8a [dir=back];
|
||||||
|
block7b -> block8b [dir=back];
|
||||||
|
block8b -> block9 [dir=back];
|
||||||
|
block9 -> block10 [dir=back];
|
||||||
|
block10 -> block11 [dir=back];
|
||||||
|
}
|
||||||
|
|
BIN
images/fork.dot.png
Normal file
After Width: | Height: | Size: 6.0 KiB |
@ -2,20 +2,20 @@ digraph merkle_tree {
|
|||||||
splines=ortho;
|
splines=ortho;
|
||||||
node [shape=box, style="filled", color="black", fontcolor="black", fillcolor="white"];
|
node [shape=box, style="filled", color="black", fontcolor="black", fillcolor="white"];
|
||||||
|
|
||||||
"Merkle Root" -> "Hash AB";
|
"Merkle Root" -> "Hash A";
|
||||||
"Merkle Root" -> "Hash C";
|
"Merkle Root" -> "Hash BC";
|
||||||
"Hash AB" -> "Hash A";
|
"Hash BC" -> "Hash B";
|
||||||
"Hash AB" -> "Hash B";
|
"Hash BC" -> "Hash C";
|
||||||
"Hash A" -> "A";
|
"Hash A" -> "A" [minlen = 2];
|
||||||
"Hash B" -> "B";
|
"Hash B" -> "B";
|
||||||
"Hash C" -> "C" [minlen = 2];
|
"Hash C" -> "C";
|
||||||
|
|
||||||
"Merkle Root" [label="Merkle Root"];
|
"Merkle Root" [label="Merkle Root"];
|
||||||
"Hash AB" [label="Hash AB"];
|
"Hash BC" [label="Hash BC"];
|
||||||
"Hash A" [label="Hash A"];
|
"Hash A" [label="Hash A"];
|
||||||
"Hash B" [label="Hash B"];
|
"Hash B" [label="Hash B"];
|
||||||
"Hash C" [label="Hash C"];
|
"Hash C" [label="Hash C"];
|
||||||
"C" [label="2 <M> <S> <Z> 3 OP_CHECKMULTISIG", style="filled", fillcolor="silver"];
|
"A" [label="2 <M> <S> <Z> 3 OP_CHECKMULTISIG", style="filled", fillcolor="silver"];
|
||||||
"B" [label="<30 days> OP_CSV OP_DROP\n<Lawyer> OP_CHECKSIGVERIFY\n1 <M> <S> <Z> 3 OP_CHECKMULTISIG"];
|
"B" [label="<30 days> OP_CSV OP_DROP\n<Lawyer> OP_CHECKSIGVERIFY\n1 <M> <S> <Z> 3 OP_CHECKMULTISIG"];
|
||||||
"A" [label="<90 days> OP_CSV OP_DROP\n<Lawyer> OP_CHECKSIG"];
|
"C" [label="<90 days> OP_CSV OP_DROP\n<Lawyer> OP_CHECKSIG"];
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 118 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 59 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 97 KiB |