func hasher(data []byte) func([]byte) ([]byte, error) {
	return func(span []byte) ([]byte, error) {
		hasher := bmtpool.Get()
		defer bmtpool.Put(hasher)
		hasher.SetHeader(span)
		if _, err := hasher.Write(data); err != nil {
			return nil, err
		}
		return hasher.Hash(nil)
	}
}
hasher is a helper function to hash a given data based on the given span.
package cac
import (
	"bytes"
	"encoding/binary"
	"errors"
	"github.com/ethsana/sana/pkg/bmtpool"
	"github.com/ethsana/sana/pkg/swarm"
)
var (
	errTooShortChunkData = errors.New("short chunk data")
	errTooLargeChunkData = errors.New("data too large")
)
func New(data []byte) (swarm.Chunk, error) {
	dataLength := len(data)
	if dataLength > swarm.ChunkSize {
		return nil, errTooLargeChunkData
	}
	if dataLength == 0 {
		return nil, errTooShortChunkData
	}
	span := make([]byte, swarm.SpanSize)
	binary.LittleEndian.PutUint64(span, uint64(dataLength))
	return newWithSpan(data, span)
}
func NewWithDataSpan(data []byte) (swarm.Chunk, error) {
	dataLength := len(data)
	if dataLength > swarm.ChunkSize+swarm.SpanSize {
		return nil, errTooLargeChunkData
	}
	if dataLength < swarm.SpanSize {
		return nil, errTooShortChunkData
	}
	return newWithSpan(data[swarm.SpanSize:], data[:swarm.SpanSize])
}
func newWithSpan(data, span []byte) (swarm.Chunk, error) {
	h := hasher(data)
	hash, err := h(span)
	if err != nil {
		return nil, err
	}
	cdata := make([]byte, len(data)+len(span))
	copy(cdata[:swarm.SpanSize], span)
	copy(cdata[swarm.SpanSize:], data)
	return swarm.NewChunk(swarm.NewAddress(hash), cdata), nil
}