4.8 C
New York
Monday, November 25, 2024

Understanding bitcoin merkle tree building at code stage

Share To Your Friends

[ad_1]

I’ve a excessive stage understanding of how merkle bushes are constructed for a Bitcoin block, however I’m inquisitive about constructing somewhat CLI device in golang that really takes an inventory of transactions for a block and reconstructs the merkle tree. I’m doing this only for my very own academic functions. As I’m going by means of this course of I’m realizing some particulars concerning the merkle tree building which I don’t perceive.

I’ve the next code to assemble the merkle tree from an inventory of transaction hashes

func buildTree(leafHashes []string, comboFn CombineHashFn) (*node, error) {
    if len(leafHashes) == 0 {
        return nil, errors.New("empty listing of leaf node hashes offered, can not assemble tree")
    }
    currentLayer := make([]*node, len(leafHashes), len(leafHashes))
    for i := 0; i < len(leafHashes); i++ {
        currentLayer[i] = &node{
            hash:      leafHashes[i],
            left:      nil,
            proper:     nil,
            duplicate: false,
        }
    }

    for len(currentLayer) > 1 {
        if len(currentLayer)%2 == 1 {
            lastNode := currentLayer[len(currentLayer)-1]
            duplicateNode := &node{
                hash:      lastNode.hash,
                left:      nil,
                proper:     nil,
                duplicate: true,
            }
            currentLayer = append(currentLayer, duplicateNode)
        }

        nextLayerLen := len(currentLayer) / 2
        nextLayer := make([]*node, nextLayerLen, nextLayerLen)
        for i := 0; i < len(currentLayer); i += 2 {
            nextLayer[i/2] = &node{
                hash:      comboFn(currentLayer[i].hash, currentLayer[i+1].hash),
                left:      currentLayer[i],
                proper:     currentLayer[i+1],
                duplicate: false,
            }
        }
        currentLayer = nextLayer
    }

    return currentLayer[0], nil
}

I’m passing in a perform to mix to node’s hashes that appears like

func Sha256CombineHashFn(left string, proper string) string {
    return fmt.Sprintf("%x", sha256.Sum256([]byte(left+proper)))
}

I think my merkle tree logic is appropriate however my methodology for combining node’s hashes is mistaken. Primarily based on some Googling I think the next issues are mistaken

  1. I believe I shouldn’t be representing the hashes as hex encoded strings, however as an alternative needs to be utilizing byte arrays.
  2. I imagine I needs to be doing a “double” hash.

As a substitute of guessing and checking if I used to be combining nodes appropriately I as an alternative simply tried to learn the Bitcoin merkle tree code. I discovered this code. I hoped studying the code would unblock me, however I’m simply extra confused for just a few causes.

  1. It seems like two hashes should not being taken however as an alternative some variety of hashes are being taken which are proportional to the variety of leaf nodes (reference code)
  2. Understanding this line and this methodology implementation goes over my head. I anticipated this logic to be quite simple, from my understanding all that must be performed is take two node’s hash values, mix them some how after which hash the end result. As a substitute it seems like a number of hashes are being taken, it seems just like the 0th index is used twice, and I don’t see the place hashes are mixed.

If I wished to write down a easy perform in go along with the next perform header

func Sha256CombineHashFn(left string, proper string) string
// OR
func Sha256CombineHashFn(left []byte, proper []byte) []byte

How would possibly I do that to match the Bitcoin logic?

[ad_2]


Share To Your Friends

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles