func CreateAddress(id ID, owner []byte) (swarm.Address, error) {
	sum, err := hash(id, owner)
	if err != nil {
		return swarm.ZeroAddress, err
	}
	return swarm.NewAddress(sum), nil
}
CreateAddress creates a new SOC address from the id and
the ethereum address of the owner.
package soc
import (
	"bytes"
	"errors"
	"github.com/ethsana/sana/pkg/cac"
	"github.com/ethsana/sana/pkg/crypto"
	"github.com/ethsana/sana/pkg/swarm"
)
const (
	IdSize        = 32
	SignatureSize = 65
	minChunkSize  = IdSize + SignatureSize + swarm.SpanSize
)
var (
	errInvalidAddress = errors.New("soc: invalid address")
	errWrongChunkSize = errors.New("soc: chunk length is less than minimum")
)
type ID []byte
type SOC struct {
	id        ID
	owner     []byte  
	signature []byte
	chunk     swarm.Chunk  
}
func New(id ID, ch swarm.Chunk) *SOC {
	return &SOC{
		id:    id,
		chunk: ch,
	}
}
func NewSigned(id ID, ch swarm.Chunk, owner, sig []byte) (*SOC, error) {
	s := New(id, ch)
	if len(owner) != crypto.AddressSize {
		return nil, errInvalidAddress
	}
	s.owner = owner
	s.signature = sig
	return s, nil
}
func (s *SOC) address() (swarm.Address, error) {
	if len(s.owner) != crypto.AddressSize {
		return swarm.ZeroAddress, errInvalidAddress
	}
	return CreateAddress(s.id, s.owner)
}
func (s *SOC) WrappedChunk() swarm.Chunk {
	return s.chunk
}
func (s *SOC) Chunk() (swarm.Chunk, error) {
	socAddress, err := s.address()
	if err != nil {
		return nil, err
	}
	return swarm.NewChunk(socAddress, s.toBytes()), nil
}
func (s *SOC) toBytes() []byte {
	buf := bytes.NewBuffer(nil)
	buf.Write(s.id)
	buf.Write(s.signature)
	buf.Write(s.chunk.Data())
	return buf.Bytes()
}
func (s *SOC) Sign(signer crypto.Signer) (swarm.Chunk, error) {
	publicKey, err := signer.PublicKey()
	if err != nil {
		return nil, err
	}
	ownerAddressBytes, err := crypto.NewEthereumAddress(*publicKey)
	if err != nil {
		return nil, err
	}
	if len(ownerAddressBytes) != crypto.AddressSize {
		return nil, errInvalidAddress
	}
	s.owner = ownerAddressBytes
	toSignBytes, err := hash(s.id, s.chunk.Address().Bytes())
	if err != nil {
		return nil, err
	}
	signature, err := signer.Sign(toSignBytes)
	if err != nil {
		return nil, err
	}
	s.signature = signature
	return s.Chunk()
}
func FromChunk(sch swarm.Chunk) (*SOC, error) {
	chunkData := sch.Data()
	if len(chunkData) < minChunkSize {
		return nil, errWrongChunkSize
	}
	s := &SOC{}
	cursor := 0
	s.id = chunkData[cursor:IdSize]
	cursor += IdSize
	s.signature = chunkData[cursor : cursor+SignatureSize]
	cursor += SignatureSize
	ch, err := cac.NewWithDataSpan(chunkData[cursor:])
	if err != nil {
		return nil, err
	}
	toSignBytes, err := hash(s.id, ch.Address().Bytes())
	if err != nil {
		return nil, err
	}
	recoveredOwnerAddress, err := recoverAddress(s.signature, toSignBytes)
	if err != nil {
		return nil, err
	}
	if len(recoveredOwnerAddress) != crypto.AddressSize {
		return nil, errInvalidAddress
	}
	s.owner = recoveredOwnerAddress
	s.chunk = ch
	return s, nil
}