A full inclusion proof is the ordered list of siblings from a leaf all the way up to the root. Today you generate one by walking the tree upward.
Generate the full ordered list of sibling steps from a leaf to the root.
Generating a proof is a walk from a leaf to the root. At each level you record the
current node’s sibling and its side, then move up to the parent by halving the index
(node idx has parent idx/2). Repeat until you reach the level just below the root.
For leaf 0 in a four-leaf tree that is two steps: its leaf sibling on the right, then
the whole right subtree’s hash on the right.
The proof is small - about log2(n) hashes for n leaves - which is the entire
appeal. To prove one transaction is in a block of thousands, you ship a handful of
hashes, not the block. An out-of-range index has no path, so return an empty proof
rather than reaching past the tree. (The promoted-node case, where a level contributes
no step, gets its own lesson shortly.)
func (t *Tree) Prove(index int) []ProofStep {var proof []ProofStepidx := indexfor level := 0; level < len(t.Levels)-1; level++ {row := t.Levels[level]if idx%2 == 0 && idx+1 < len(row) {proof = append(proof, ProofStep{row[idx+1], true})} else if idx%2 == 1 {proof = append(proof, ProofStep{row[idx-1], false})} // else: promoted, no step this levelidx /= 2}return proof}