func (b *blockchain) verifyTransaction(m message.NamecoinTransaction) bool { blck, ok := b.Direct[m.BlockId] if !ok { fmt.Println(m.BlockId, "not in blockchain.") return false } var hashes []wire.ShaHash for _, v := range m.VerificationHashes { temp, err := wire.NewShaHash(v) if err != nil { fmt.Println("Unable to create Verification Sha hash", err) return false } hashes = append(hashes, *temp) } txHash, err := wire.NewShaHashFromStr(m.TxId) if err != nil { fmt.Println("Cannot make TX Sha Hash", err) return false } _, err = VerifyMerkleBranch(wire.MerkleBranch{ BranchSideMask: m.Branch, BranchHash: hashes, }, &blck.MerkleRoot, txHash) if err != nil { fmt.Println("Error verifying Merkle Branch", err) } return err == nil }
// constructMerkleTree will create a wire.MerkleBranch object that places the // transaction in the block Merkle Tree. func constructMerkleTree(transactions []string, root string, transaction string) (wire.MerkleBranch, error) { workingRow := make([]*wire.ShaHash, len(transactions)) // Used to build the Merkle Branch var ( currentTransaction int verificationHashes []wire.ShaHash height uint32 merkleBitmask int32 ) var err error for i, v := range transactions { if v == transaction { currentTransaction = i } if workingRow[i], err = wire.NewShaHashFromStr(v); err != nil { return wire.MerkleBranch{}, err } } for { // We double the last entry if the row has an odd number of if len(workingRow)%2 == 1 { workingRow = append(workingRow, workingRow[len(workingRow)-1]) } // Hash into the Next Row var nextRow []*wire.ShaHash for i := 0; i < len(workingRow); i += 2 { left := workingRow[i] right := workingRow[i+1] if currentTransaction == i { // We need to add the right hash to the merkle branch. verificationHashes = append(verificationHashes, *right) currentTransaction = len(nextRow) merkleBitmask = merkleBitmask | (0 << height) } else if currentTransaction == i+1 { // We need to add the left hash to the merkle branch. verificationHashes = append(verificationHashes, *left) currentTransaction = len(nextRow) merkleBitmask = merkleBitmask | (1 << height) } hash, err := wire.NewShaHash(wire.DoubleSha256( append(left.Bytes(), right.Bytes()...), )) if err != nil { return wire.MerkleBranch{}, err } nextRow = append(nextRow, hash) } if len(nextRow) == 1 { if nextRow[0].String() != root { return wire.MerkleBranch{}, errors.New("Cannot validate MerkleTree.") } break } workingRow = nextRow height++ } return wire.MerkleBranch{ BranchHash: verificationHashes, BranchSideMask: merkleBitmask, }, nil }