Repository: kaspanet/kaspad
Pull request #1281 (2020-12-24 12:06:30)

Remove the limit to the returned headers from buildMsgBlockHeaders
This limit truncated the amount of headers returned to around 130k.
The limit was in place for historical reasons, when we didn't send headers in batches, and is no longer relevant.


Patch:
diff --git a/app/appmessage/common.go b/app/appmessage/common.go
index 66b5ca53..c772b1ac 100644
--- a/app/appmessage/common.go
+++ b/app/appmessage/common.go
@@ -5,19 +5,9 @@
 package appmessage
 
 import (
-	"fmt"
-	"io"
-
-	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
-	"github.com/kaspanet/kaspad/infrastructure/network/netadapter/id"
-	"github.com/kaspanet/kaspad/util/binaryserializer"
-	"github.com/kaspanet/kaspad/util/mstime"
 	"github.com/pkg/errors"
 )
 
-// MaxVarIntPayload is the maximum payload size for a variable length integer.
-const MaxVarIntPayload = 9
-
 // MaxInvPerMsg is the maximum number of inventory vectors that can be in any type of kaspa inv message.
 const MaxInvPerMsg = 1 << 17
 
@@ -28,333 +18,3 @@ var errNonCanonicalVarInt = "non-canonical varint %x - discriminant %x must " +
 
 // errNoEncodingForType signifies that there's no encoding for the given type.
 var errNoEncodingForType = errors.New("there's no encoding for this type")
-
-// int64Time represents a unix timestamp with milliseconds precision encoded with
-// an int64. It is used as a way to signal the readElement function how to decode
-// a timestamp into a Go mstime.Time since it is otherwise ambiguous.
-type int64Time mstime.Time
-
-// ReadElement reads the next sequence of bytes from r using little endian
-// depending on the concrete type of element pointed to.
-func ReadElement(r io.Reader, element interface{}) error {
-	// Attempt to read the element based on the concrete type via fast
-	// type assertions first.
-	switch e := element.(type) {
-	case *int32:
-		rv, err := binaryserializer.Uint32(r)
-		if err != nil {
-			return err
-		}
-		*e = int32(rv)
-		return nil
-
-	case *uint32:
-		rv, err := binaryserializer.Uint32(r)
-		if err != nil {
-			return err
-		}
-		*e = rv
-		return nil
-
-	case *int64:
-		rv, err := binaryserializer.Uint64(r)
-		if err != nil {
-			return err
-		}
-		*e = int64(rv)
-		return nil
-
-	case *uint64:
-		rv, err := binaryserializer.Uint64(r)
-		if err != nil {
-			return err
-		}
-		*e = rv
-		return nil
-
-	case *uint8:
-		rv, err := binaryserializer.Uint8(r)
-		if err != nil {
-			return err
-		}
-		*e = rv
-		return nil
-
-	case *bool:
-		rv, err := binaryserializer.Uint8(r)
-		if err != nil {
-			return err
-		}
-		if rv == 0x00 {
-			*e = false
-		} else {
-			*e = true
-		}
-		return nil
-
-	// Unix timestamp encoded as an int64.
-	case *int64Time:
-		rv, err := binaryserializer.Uint64(r)
-		if err != nil {
-			return err
-		}
-		*e = int64Time(mstime.UnixMilliseconds(int64(rv)))
-		return nil
-
-	// Message header checksum.
-	case *[4]byte:
-		_, err := io.ReadFull(r, e[:])
-		if err != nil {
-			return err
-		}
-		return nil
-
-	// Message header command.
-	case *MessageCommand:
-		rv, err := binaryserializer.Uint32(r)
-		if err != nil {
-			return err
-		}
-		*e = MessageCommand(rv)
-		return nil
-
-	// IP address.
-	case *[16]byte:
-		_, err := io.ReadFull(r, e[:])
-		if err != nil {
-			return err
-		}
-		return nil
-
-	case *externalapi.DomainHash:
-		_, err := io.ReadFull(r, e[:])
-		if err != nil {
-			return err
-		}
-		return nil
-
-	case *id.ID:
-		return e.Deserialize(r)
-
-	case *externalapi.DomainSubnetworkID:
-		_, err := io.ReadFull(r, e[:])
-		if err != nil {
-			return err
-		}
-		return nil
-
-	case *ServiceFlag:
-		rv, err := binaryserializer.Uint64(r)
-		if err != nil {
-			return err
-		}
-		*e = ServiceFlag(rv)
-		return nil
-
-	case *KaspaNet:
-		rv, err := binaryserializer.Uint32(r)
-		if err != nil {
-			return err
-		}
-		*e = KaspaNet(rv)
-		return nil
-	}
-
-	return errors.Wrapf(errNoEncodingForType, "couldn't find a way to read type %T", element)
-}
-
-// readElements reads multiple items from r. It is equivalent to multiple
-// calls to readElement.
-func readElements(r io.Reader, elements ...interface{}) error {
-	for _, element := range elements {
-		err := ReadElement(r, element)
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-// WriteElement writes the little endian representation of element to w.
-func WriteElement(w io.Writer, element interface{}) error {
-	// Attempt to write the element based on the concrete type via fast
-	// type assertions first.
-	switch e := element.(type) {
-	case int32:
-		err := binaryserializer.PutUint32(w, uint32(e))
-		if err != nil {
-			return err
-		}
-		return nil
-
-	case uint32:
-		err := binaryserializer.PutUint32(w, e)
-		if err != nil {
-			return err
-		}
-		return nil
-
-	case int64:
-		err := binaryserializer.PutUint64(w, uint64(e))
-		if err != nil {
-			return err
-		}
-		return nil
-
-	case uint64:
-		err := binaryserializer.PutUint64(w, e)
-		if err != nil {
-			return err
-		}
-		return nil
-
-	case uint8:
-		err := binaryserializer.PutUint8(w, e)
-		if err != nil {
-			return err
-		}
-		return nil
-
-	case bool:
-		var err error
-		if e {
-			err = binaryserializer.PutUint8(w, 0x01)
-		} else {
-			err = binaryserializer.PutUint8(w, 0x00)
-		}
-		if err != nil {
-			return err
-		}
-		return nil
-
-	// Message header checksum.
-	case [4]byte:
-		_, err := w.Write(e[:])
-		if err != nil {
-			return err
-		}
-		return nil
-
-	// Message header command.
-	case MessageCommand:
-		err := binaryserializer.PutUint32(w, uint32(e))
-		if err != nil {
-			return err
-		}
-		return nil
-
-	// IP address.
-	case [16]byte:
-		_, err := w.Write(e[:])
-		if err != nil {
-			return err
-		}
-		return nil
-
-	case *externalapi.DomainHash:
-		_, err := w.Write(e[:])
-		if err != nil {
-			return err
-		}
-		return nil
-
-	case *id.ID:
-		return e.Serialize(w)
-
-	case *externalapi.DomainSubnetworkID:
-		_, err := w.Write(e[:])
-		if err != nil {
-			return err
-		}
-		return nil
-
-	case ServiceFlag:
-		err := binaryserializer.PutUint64(w, uint64(e))
-		if err != nil {
-			return err
-		}
-		return nil
-
-	case KaspaNet:
-		err := binaryserializer.PutUint32(w, uint32(e))
-		if err != nil {
-			return err
-		}
-		return nil
-	}
-
-	return errors.Wrapf(errNoEncodingForType, "couldn't find a way to write type %T", element)
-}
-
-// writeElements writes multiple items to w. It is equivalent to multiple
-// calls to writeElement.
-func writeElements(w io.Writer, elements ...interface{}) error {
-	for _, element := range elements {
-		err := WriteElement(w, element)
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-// ReadVarInt reads a variable length integer from r and returns it as a uint64.
-func ReadVarInt(r io.Reader) (uint64, error) {
-	discriminant, err := binaryserializer.Uint8(r)
-	if err != nil {
-		return 0, err
-	}
-
-	var rv uint64
-	switch discriminant {
-	case 0xff:
-		sv, err := binaryserializer.Uint64(r)
-		if err != nil {
-			return 0, err
-		}
-		rv = sv
-
-		// The encoding is not canonical if the value could have been
-		// encoded using fewer bytes.
-		min := uint64(0x100000000)
-		if rv < min {
-			return 0, messageError("readVarInt", fmt.Sprintf(
-				errNonCanonicalVarInt, rv, discriminant, min))
-		}
-
-	case 0xfe:
-		sv, err := binaryserializer.Uint32(r)
-		if err != nil {
-			return 0, err
-		}
-		rv = uint64(sv)
-
-		// The encoding is not canonical if the value could have been
-		// encoded using fewer bytes.
-		min := uint64(0x10000)
-		if rv < min {
-			return 0, messageError("readVarInt", fmt.Sprintf(
-				errNonCanonicalVarInt, rv, discriminant, min))
-		}
-
-	case 0xfd:
-		sv, err := binaryserializer.Uint16(r)
-		if err != nil {
-			return 0, err
-		}
-		rv = uint64(sv)
-
-		// The encoding is not canonical if the value could have been
-		// encoded using fewer bytes.
-		min := uint64(0xfd)
-		if rv < min {
-			return 0, messageError("readVarInt", fmt.Sprintf(
-				errNonCanonicalVarInt, rv, discriminant, min))
-		}
-
-	default:
-		rv = uint64(discriminant)
-	}
-
-	return rv, nil
-}
diff --git a/app/appmessage/domainconverters.go b/app/appmessage/domainconverters.go
index 21733ff8..46f52f9a 100644
--- a/app/appmessage/domainconverters.go
+++ b/app/appmessage/domainconverters.go
@@ -2,8 +2,8 @@ package appmessage
 
 import (
 	"encoding/hex"
+
 	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
-	"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
 	"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
 	"github.com/kaspanet/kaspad/domain/consensus/utils/transactionid"
 	"github.com/kaspanet/kaspad/util/mstime"
@@ -208,7 +208,7 @@ func RPCTransactionToDomainTransaction(rpcTransaction *RPCTransaction) (*externa
 	if err != nil {
 		return nil, err
 	}
-	payloadHash, err := hashes.FromBytes(payloadHashBytes)
+	payloadHash, err := externalapi.NewDomainHashFromByteSlice(payloadHashBytes)
 	if err != nil {
 		return nil, err
 	}
@@ -233,7 +233,7 @@ func RPCTransactionToDomainTransaction(rpcTransaction *RPCTransaction) (*externa
 func DomainTransactionToRPCTransaction(transaction *externalapi.DomainTransaction) *RPCTransaction {
 	inputs := make([]*RPCTransactionInput, len(transaction.Inputs))
 	for i, input := range transaction.Inputs {
-		transactionID := hex.EncodeToString(input.PreviousOutpoint.TransactionID[:])
+		transactionID := input.PreviousOutpoint.TransactionID.String()
 		previousOutpoint := &RPCOutpoint{
 			TransactionID: transactionID,
 			Index:         input.PreviousOutpoint.Index,
@@ -254,7 +254,7 @@ func DomainTransactionToRPCTransaction(transaction *externalapi.DomainTransactio
 		}
 	}
 	subnetworkID := hex.EncodeToString(transaction.SubnetworkID[:])
-	payloadHash := hex.EncodeToString(transaction.PayloadHash[:])
+	payloadHash := transaction.PayloadHash.String()
 	payload := hex.EncodeToString(transaction.Payload)
 	return &RPCTransaction{
 		Version:      transaction.Version,
diff --git a/app/protocol/flows/blockrelay/handle_request_headers.go b/app/protocol/flows/blockrelay/handle_request_headers.go
index 6600461d..a512369b 100644
--- a/app/protocol/flows/blockrelay/handle_request_headers.go
+++ b/app/protocol/flows/blockrelay/handle_request_headers.go
@@ -10,7 +10,6 @@ import (
 )
 
 const ibdBatchSize = router.DefaultMaxMessages
-const maxHeaders = appmessage.MaxInvPerMsg
 
 // RequestIBDBlocksContext is the interface for the context needed for the HandleRequestHeaders flow.
 type RequestIBDBlocksContext interface {
@@ -39,26 +38,35 @@ func (flow *handleRequestBlocksFlow) start() error {
 			return err
 		}
 
-		msgHeaders, err := flow.buildMsgBlockHeaders(lowHash, highHash)
+		blockHashes, err := flow.Domain().Consensus().GetHashesBetween(lowHash, highHash)
 		if err != nil {
 			return err
 		}
 
-		for offset := 0; offset < len(msgHeaders); offset += ibdBatchSize {
+		for offset := 0; offset < len(blockHashes); offset += ibdBatchSize {
 			end := offset + ibdBatchSize
-			if end > len(msgHeaders) {
-				end = len(msgHeaders)
+			if end > len(blockHashes) {
+				end = len(blockHashes)
 			}
 
-			blocksToSend := msgHeaders[offset:end]
-			err = flow.sendHeaders(blocksToSend)
+			blocksHashesToSend := blockHashes[offset:end]
+
+			msgBlockHeadersToSend := make([]*appmessage.MsgBlockHeader, len(blocksHashesToSend))
+			for i, blockHash := range blocksHashesToSend {
+				header, err := flow.Domain().Consensus().GetBlockHeader(blockHash)
+				if err != nil {
+					return err
+				}
+				msgBlockHeadersToSend[i] = appmessage.DomainBlockHeaderToBlockHeader(header)
+			}
+			err = flow.sendHeaders(msgBlockHeadersToSend)
 			if err != nil {
 				return nil
 			}
 
 			// Exit the loop and don't wait for the GetNextIBDBlocks message if the last batch was
 			// less than ibdBatchSize.
-			if len(blocksToSend) < ibdBatchSize {
+			if len(blocksHashesToSend) < ibdBatchSize {
 				break
 			}
 
@@ -91,30 +99,6 @@ func receiveRequestHeaders(incomingRoute *router.Route) (lowHash *externalapi.Do
 	return msgRequestIBDBlocks.LowHash, msgRequestIBDBlocks.HighHash, nil
 }
 
-func (flow *handleRequestBlocksFlow) buildMsgBlockHeaders(lowHash *externalapi.DomainHash,
-	highHash *externalapi.DomainHash) ([]*appmessage.MsgBlockHeader, error) {
-
-	blockHashes, err := flow.Domain().Consensus().GetHashesBetween(lowHash, highHash)
-	if err != nil {
-		return nil, err
-	}
-
-	if len(blockHashes) > maxHeaders {
-		blockHashes = blockHashes[:maxHeaders]
-	}
-
-	msgBlockHeaders := make([]*appmessage.MsgBlockHeader, len(blockHashes))
-	for i, blockHash := range blockHashes {
-		header, err := flow.Domain().Consensus().GetBlockHeader(blockHash)
-		if err != nil {
-			return nil, err
-		}
-		msgBlockHeaders[i] = appmessage.DomainBlockHeaderToBlockHeader(header)
-	}
-
-	return msgBlockHeaders, nil
-}
-
 func (flow *handleRequestBlocksFlow) sendHeaders(headers []*appmessage.MsgBlockHeader) error {
 	for _, msgBlockHeader := range headers {
 		err := flow.outgoingRoute.Enqueue(msgBlockHeader)
diff --git a/app/rpc/rpccontext/chain_changed.go b/app/rpc/rpccontext/chain_changed.go
index d3f0dd6b..2375e3ce 100644
--- a/app/rpc/rpccontext/chain_changed.go
+++ b/app/rpc/rpccontext/chain_changed.go
@@ -1,7 +1,6 @@
 package rpccontext
 
 import (
-	"encoding/hex"
 	"github.com/kaspanet/kaspad/app/appmessage"
 	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
 	"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
@@ -14,7 +13,7 @@ func (ctx *Context) ConvertVirtualSelectedParentChainChangesToChainChangedNotifi
 
 	removedChainBlockHashes := make([]string, len(selectedParentChainChanges.Removed))
 	for i, removed := range selectedParentChainChanges.Removed {
-		removedChainBlockHashes[i] = hex.EncodeToString(removed[:])
+		removedChainBlockHashes[i] = removed.String()
 	}
 
 	addedChainBlocks := make([]*appmessage.ChainBlock, len(selectedParentChainChanges.Added))
@@ -28,16 +27,16 @@ func (ctx *Context) ConvertVirtualSelectedParentChainChangesToChainChangedNotifi
 			acceptedTransactionIDs := make([]string, len(acceptedBlock.TransactionAcceptanceData))
 			for k, transaction := range acceptedBlock.TransactionAcceptanceData {
 				transactionID := consensushashing.TransactionID(transaction.Transaction)
-				acceptedTransactionIDs[k] = hex.EncodeToString(transactionID[:])
+				acceptedTransactionIDs[k] = transactionID.String()
 			}
 			acceptedBlocks[j] = &appmessage.AcceptedBlock{
-				Hash:                   hex.EncodeToString(acceptedBlock.BlockHash[:]),
+				Hash:                   acceptedBlock.BlockHash.String(),
 				AcceptedTransactionIDs: acceptedTransactionIDs,
 			}
 		}
 
 		addedChainBlocks[i] = &appmessage.ChainBlock{
-			Hash:           hex.EncodeToString(added[:]),
+			Hash:           added.String(),
 			AcceptedBlocks: acceptedBlocks,
 		}
 	}
diff --git a/app/rpc/rpccontext/notificationmanager.go b/app/rpc/rpccontext/notificationmanager.go
index 5fc44ac6..284e5e4d 100644
--- a/app/rpc/rpccontext/notificationmanager.go
+++ b/app/rpc/rpccontext/notificationmanager.go
@@ -1,12 +1,12 @@
 package rpccontext
 
 import (
-	"encoding/hex"
+	"sync"
+
 	"github.com/kaspanet/kaspad/app/appmessage"
 	"github.com/kaspanet/kaspad/domain/utxoindex"
 	routerpkg "github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
 	"github.com/pkg/errors"
-	"sync"
 )
 
 // NotificationManager manages notifications for the RPC
@@ -236,7 +236,7 @@ func (nl *NotificationListener) convertUTXOChangesToUTXOsChangedNotification(
 				notification.Removed = append(notification.Removed, &appmessage.UTXOsByAddressesEntry{
 					Address: listenerAddress.Address,
 					Outpoint: &appmessage.RPCOutpoint{
-						TransactionID: hex.EncodeToString(outpoint.TransactionID[:]),
+						TransactionID: outpoint.TransactionID.String(),
 						Index:         outpoint.Index,
 					},
 				})
diff --git a/app/rpc/rpccontext/utxos_by_addresses.go b/app/rpc/rpccontext/utxos_by_addresses.go
index b4ead0d7..7fd2458e 100644
--- a/app/rpc/rpccontext/utxos_by_addresses.go
+++ b/app/rpc/rpccontext/utxos_by_addresses.go
@@ -2,6 +2,7 @@ package rpccontext
 
 import (
 	"encoding/hex"
+
 	"github.com/kaspanet/kaspad/app/appmessage"
 	"github.com/kaspanet/kaspad/domain/utxoindex"
 )
@@ -14,7 +15,7 @@ func ConvertUTXOOutpointEntryPairsToUTXOsByAddressesEntries(address string, pair
 		utxosByAddressesEntries = append(utxosByAddressesEntries, &appmessage.UTXOsByAddressesEntry{
 			Address: address,
 			Outpoint: &appmessage.RPCOutpoint{
-				TransactionID: hex.EncodeToString(outpoint.TransactionID[:]),
+				TransactionID: outpoint.TransactionID.String(),
 				Index:         outpoint.Index,
 			},
 			UTXOEntry: &appmessage.RPCUTXOEntry{
diff --git a/app/rpc/rpccontext/verbosedata.go b/app/rpc/rpccontext/verbosedata.go
index 88b46407..1828dbf6 100644
--- a/app/rpc/rpccontext/verbosedata.go
+++ b/app/rpc/rpccontext/verbosedata.go
@@ -7,6 +7,8 @@ import (
 	"math/big"
 	"strconv"
 
+	"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
+
 	"github.com/kaspanet/kaspad/domain/consensus/utils/estimatedsize"
 	"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
 
@@ -37,7 +39,7 @@ func (ctx *Context) BuildBlockVerboseData(block *externalapi.DomainBlock, includ
 		HashMerkleRoot:       blockHeader.HashMerkleRoot.String(),
 		AcceptedIDMerkleRoot: blockHeader.AcceptedIDMerkleRoot.String(),
 		UTXOCommitment:       blockHeader.UTXOCommitment.String(),
-		ParentHashes:         externalapi.DomainHashesToStrings(blockHeader.ParentHashes),
+		ParentHashes:         hashes.ToStrings(blockHeader.ParentHashes),
 		Nonce:                blockHeader.Nonce,
 		Time:                 blockHeader.TimeInMilliseconds,
 		Bits:                 strconv.FormatInt(int64(blockHeader.Bits), 16),
diff --git a/app/rpc/rpchandlers/get_block.go b/app/rpc/rpchandlers/get_block.go
index dce3caf6..c2de8b10 100644
--- a/app/rpc/rpchandlers/get_block.go
+++ b/app/rpc/rpchandlers/get_block.go
@@ -3,7 +3,7 @@ package rpchandlers
 import (
 	"github.com/kaspanet/kaspad/app/appmessage"
 	"github.com/kaspanet/kaspad/app/rpc/rpccontext"
-	"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
+	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
 	"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
 )
 
@@ -12,7 +12,7 @@ func HandleGetBlock(context *rpccontext.Context, _ *router.Router, request appme
 	getBlockRequest := request.(*appmessage.GetBlockRequestMessage)
 
 	// Load the raw block bytes from the database.
-	hash, err := hashes.FromString(getBlockRequest.Hash)
+	hash, err := externalapi.NewDomainHashFromString(getBlockRequest.Hash)
 	if err != nil {
 		errorMessage := &appmessage.GetBlockResponseMessage{}
 		errorMessage.Error = appmessage.RPCErrorf("Hash could not be parsed: %s", err)
diff --git a/app/rpc/rpchandlers/get_virtual_selected_parent_chain_from_block.go b/app/rpc/rpchandlers/get_virtual_selected_parent_chain_from_block.go
index c0a5789d..c3430c19 100644
--- a/app/rpc/rpchandlers/get_virtual_selected_parent_chain_from_block.go
+++ b/app/rpc/rpchandlers/get_virtual_selected_parent_chain_from_block.go
@@ -1,10 +1,9 @@
 package rpchandlers
 
 import (
-	"encoding/hex"
 	"github.com/kaspanet/kaspad/app/appmessage"
 	"github.com/kaspanet/kaspad/app/rpc/rpccontext"
-	"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
+	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
 	"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
 )
 
@@ -12,13 +11,7 @@ import (
 func HandleGetVirtualSelectedParentChainFromBlock(context *rpccontext.Context, _ *router.Router, request appmessage.Message) (appmessage.Message, error) {
 	getVirtualSelectedParentChainFromBlockRequest := request.(*appmessage.GetVirtualSelectedParentChainFromBlockRequestMessage)
 
-	startHashBytes, err := hex.DecodeString(getVirtualSelectedParentChainFromBlockRequest.StartHash)
-	if err != nil {
-		errorMessage := &appmessage.GetVirtualSelectedParentChainFromBlockResponseMessage{}
-		errorMessage.Error = appmessage.RPCErrorf("Could not parse startHash: %s", err)
-		return errorMessage, nil
-	}
-	startHash, err := hashes.FromBytes(startHashBytes)
+	startHash, err := externalapi.NewDomainHashFromString(getVirtualSelectedParentChainFromBlockRequest.StartHash)
 	if err != nil {
 		errorMessage := &appmessage.GetVirtualSelectedParentChainFromBlockResponseMessage{}
 		errorMessage.Error = appmessage.RPCErrorf("Could not parse startHash: %s", err)
diff --git a/domain/consensus/database/serialization/hash.go b/domain/consensus/database/serialization/hash.go
index f09bc290..6e4f7d5c 100644
--- a/domain/consensus/database/serialization/hash.go
+++ b/domain/consensus/database/serialization/hash.go
@@ -2,17 +2,16 @@ package serialization
 
 import (
 	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
-	"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
 )
 
 // DbHashToDomainHash converts a DbHash to a DomainHash
 func DbHashToDomainHash(dbHash *DbHash) (*externalapi.DomainHash, error) {
-	return hashes.FromBytes(dbHash.Hash)
+	return externalapi.NewDomainHashFromByteSlice(dbHash.Hash)
 }
 
 // DomainHashToDbHash converts a DomainHash to a DbHash
 func DomainHashToDbHash(domainHash *externalapi.DomainHash) *DbHash {
-	return &DbHash{Hash: domainHash[:]}
+	return &DbHash{Hash: domainHash.ByteSlice()}
 }
 
 // DomainHashesToDbHashes converts a slice of DomainHash to a slice of DbHash
diff --git a/domain/consensus/database/serialization/transactionid.go b/domain/consensus/database/serialization/transactionid.go
index dab925b7..24c1c066 100644
--- a/domain/consensus/database/serialization/transactionid.go
+++ b/domain/consensus/database/serialization/transactionid.go
@@ -12,5 +12,5 @@ func DbTransactionIDToDomainTransactionID(dbTransactionID *DbTransactionId) (*ex
 
 // DomainTransactionIDToDbTransactionID converts DomainTransactionID to DbTransactionId
 func DomainTransactionIDToDbTransactionID(domainTransactionID *externalapi.DomainTransactionID) *DbTransactionId {
-	return &DbTransactionId{TransactionId: domainTransactionID[:]}
+	return &DbTransactionId{TransactionId: domainTransactionID.ByteSlice()}
 }
diff --git a/domain/consensus/datastructures/acceptancedatastore/acceptancedatastore.go b/domain/consensus/datastructures/acceptancedatastore/acceptancedatastore.go
index ce824e21..2cbb76ac 100644
--- a/domain/consensus/datastructures/acceptancedatastore/acceptancedatastore.go
+++ b/domain/consensus/datastructures/acceptancedatastore/acceptancedatastore.go
@@ -113,5 +113,5 @@ func (ads *acceptanceDataStore) deserializeAcceptanceData(acceptanceDataBytes []
 }
 
 func (ads *acceptanceDataStore) hashAsKey(hash *externalapi.DomainHash) model.DBKey {
-	return bucket.Key(hash[:])
+	return bucket.Key(hash.ByteSlice())
 }
diff --git a/domain/consensus/datastructures/blockheaderstore/blockheaderstore.go b/domain/consensus/datastructures/blockheaderstore/blockheaderstore.go
index 81934893..ce80f707 100644
--- a/domain/consensus/datastructures/blockheaderstore/blockheaderstore.go
+++ b/domain/consensus/datastructures/blockheaderstore/blockheaderstore.go
@@ -164,7 +164,7 @@ func (bhs *blockHeaderStore) Delete(blockHash *externalapi.DomainHash) {
 }
 
 func (bhs *blockHeaderStore) hashAsKey(hash *externalapi.DomainHash) model.DBKey {
-	return bucket.Key(hash[:])
+	return bucket.Key(hash.ByteSlice())
 }
 
 func (bhs *blockHeaderStore) serializeHeader(header *externalapi.DomainBlockHeader) ([]byte, error) {
diff --git a/domain/consensus/datastructures/blockrelationstore/blockrelationstore.go b/domain/consensus/datastructures/blockrelationstore/blockrelationstore.go
index 64b69e5c..d1c6a75c 100644
--- a/domain/consensus/datastructures/blockrelationstore/blockrelationstore.go
+++ b/domain/consensus/datastructures/blockrelationstore/blockrelationstore.go
@@ -89,7 +89,7 @@ func (brs *blockRelationStore) Has(dbContext model.DBReader, blockHash *external
 }
 
 func (brs *blockRelationStore) hashAsKey(hash *externalapi.DomainHash) model.DBKey {
-	return bucket.Key(hash[:])
+	return bucket.Key(hash.ByteSlice())
 }
 
 func (brs *blockRelationStore) serializeBlockRelations(blockRelations *model.BlockRelations) ([]byte, error) {
diff --git a/domain/consensus/datastructures/blockstatusstore/blockstatusstore.go b/domain/consensus/datastructures/blockstatusstore/blockstatusstore.go
index 943d3ad5..40c97433 100644
--- a/domain/consensus/datastructures/blockstatusstore/blockstatusstore.go
+++ b/domain/consensus/datastructures/blockstatusstore/blockstatusstore.go
@@ -111,5 +111,5 @@ func (bss *blockStatusStore) deserializeBlockStatus(statusBytes []byte) (externa
 }
 
 func (bss *blockStatusStore) hashAsKey(hash *externalapi.DomainHash) model.DBKey {
-	return bucket.Key(hash[:])
+	return bucket.Key(hash.ByteSlice())
 }
diff --git a/domain/consensus/datastructures/blockstore/blockstore.go b/domain/consensus/datastructures/blockstore/blockstore.go
index 20c51efb..a688d085 100644
--- a/domain/consensus/datastructures/blockstore/blockstore.go
+++ b/domain/consensus/datastructures/blockstore/blockstore.go
@@ -178,7 +178,7 @@ func (bs *blockStore) deserializeBlock(blockBytes []byte) (*externalapi.DomainBl
 }
 
 func (bs *blockStore) hashAsKey(hash *externalapi.DomainHash) model.DBKey {
-	return bucket.Key(hash[:])
+	return bucket.Key(hash.ByteSlice())
 }
 
 func (bs *blockStore) Count() uint64 {
diff --git a/domain/consensus/datastructures/finalitystore/finality_store.go b/domain/consensus/datastructures/finalitystore/finality_store.go
index 4cd34e35..002f1d30 100644
--- a/domain/consensus/datastructures/finalitystore/finality_store.go
+++ b/domain/consensus/datastructures/finalitystore/finality_store.go
@@ -4,7 +4,6 @@ import (
 	"github.com/kaspanet/kaspad/domain/consensus/model"
 	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
 	"github.com/kaspanet/kaspad/domain/consensus/utils/dbkeys"
-	"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
 	"github.com/kaspanet/kaspad/domain/consensus/utils/lrucache"
 )
 
@@ -43,7 +42,7 @@ func (fs *finalityStore) FinalityPoint(
 	if err != nil {
 		return nil, err
 	}
-	finalityPointHash, err := hashes.FromBytes(finalityPointHashBytes)
+	finalityPointHash, err := externalapi.NewDomainHashFromByteSlice(finalityPointHashBytes)
 	if err != nil {
 		return nil, err
 	}
@@ -58,7 +57,7 @@ func (fs *finalityStore) Discard() {
 
 func (fs *finalityStore) Commit(dbTx model.DBTransaction) error {
 	for hash, finalityPointHash := range fs.staging {
-		err := dbTx.Put(fs.hashAsKey(&hash), finalityPointHash[:])
+		err := dbTx.Put(fs.hashAsKey(&hash), finalityPointHash.ByteSlice())
 		if err != nil {
 			return err
 		}
@@ -74,5 +73,5 @@ func (fs *finalityStore) IsStaged() bool {
 }
 
 func (fs *finalityStore) hashAsKey(hash *externalapi.DomainHash) model.DBKey {
-	return bucket.Key(hash[:])
+	return bucket.Key(hash.ByteSlice())
 }
diff --git a/domain/consensus/datastructures/ghostdagdatastore/ghostdagdatastore.go b/domain/consensus/datastructures/ghostdagdatastore/ghostdagdatastore.go
index c42a0140..c8b1a7c0 100644
--- a/domain/consensus/datastructures/ghostdagdatastore/ghostdagdatastore.go
+++ b/domain/consensus/datastructures/ghostdagdatastore/ghostdagdatastore.go
@@ -79,7 +79,7 @@ func (gds *ghostdagDataStore) Get(dbContext model.DBReader, blockHash *externala
 }
 
 func (gds *ghostdagDataStore) hashAsKey(hash *externalapi.DomainHash) model.DBKey {
-	return bucket.Key(hash[:])
+	return bucket.Key(hash.ByteSlice())
 }
 
 func (gds *ghostdagDataStore) serializeBlockGHOSTDAGData(blockGHOSTDAGData model.BlockGHOSTDAGData) ([]byte, error) {
diff --git a/domain/consensus/datastructures/headersselectedtipstore/headertipsstore.go b/domain/consensus/datastructures/headersselectedtipstore/headertipsstore.go
index 8926c1c1..f0df6910 100644
--- a/domain/consensus/datastructures/headersselectedtipstore/headertipsstore.go
+++ b/domain/consensus/datastructures/headersselectedtipstore/headertipsstore.go
@@ -56,7 +56,7 @@ func (hts *headerSelectedTipStore) Commit(dbTx model.DBTransaction) error {
 }
 
 func (hts *headerSelectedTipStore) Stage(selectedTip *externalapi.DomainHash) {
-	hts.staging = selectedTip.Clone()
+	hts.staging = selectedTip
 }
 
 func (hts *headerSelectedTipStore) IsStaged() bool {
@@ -65,11 +65,11 @@ func (hts *headerSelectedTipStore) IsStaged() bool {
 
 func (hts *headerSelectedTipStore) HeadersSelectedTip(dbContext model.DBReader) (*externalapi.DomainHash, error) {
 	if hts.staging != nil {
-		return hts.staging.Clone(), nil
+		return hts.staging, nil
 	}
 
 	if hts.cache != nil {
-		return hts.cache.Clone(), nil
+		return hts.cache, nil
 	}
 
 	selectedTipBytes, err := dbContext.Get(headerSelectedTipKey)
@@ -82,7 +82,7 @@ func (hts *headerSelectedTipStore) HeadersSelectedTip(dbContext model.DBReader)
 		return nil, err
 	}
 	hts.cache = selectedTip
-	return hts.cache.Clone(), nil
+	return hts.cache, nil
 }
 
 func (hts *headerSelectedTipStore) serializeHeadersSelectedTip(selectedTip *externalapi.DomainHash) ([]byte, error) {
diff --git a/domain/consensus/datastructures/multisetstore/multisetstore.go b/domain/consensus/datastructures/multisetstore/multisetstore.go
index 17aa680c..20beca60 100644
--- a/domain/consensus/datastructures/multisetstore/multisetstore.go
+++ b/domain/consensus/datastructures/multisetstore/multisetstore.go
@@ -99,7 +99,7 @@ func (ms *multisetStore) Delete(blockHash *externalapi.DomainHash) {
 }
 
 func (ms *multisetStore) hashAsKey(hash *externalapi.DomainHash) model.DBKey {
-	return bucket.Key(hash[:])
+	return bucket.Key(hash.ByteSlice())
 }
 
 func (ms *multisetStore) serializeMultiset(multiset model.Multiset) ([]byte, error) {
diff --git a/domain/consensus/datastructures/pruningstore/pruningstore.go b/domain/consensus/datastructures/pruningstore/pruningstore.go
index ba69a749..24a25258 100644
--- a/domain/consensus/datastructures/pruningstore/pruningstore.go
+++ b/domain/consensus/datastructures/pruningstore/pruningstore.go
@@ -22,7 +22,7 @@ type pruningStore struct {
 }
 
 func (ps *pruningStore) StagePruningPointCandidate(candidate *externalapi.DomainHash) {
-	ps.pruningPointCandidateStaging = candidate.Clone()
+	ps.pruningPointCandidateStaging = candidate
 }
 
 func (ps *pruningStore) PruningPointCandidate(dbContext model.DBReader) (*externalapi.DomainHash, error) {
@@ -66,7 +66,7 @@ func New() model.PruningStore {
 
 // Stage stages the pruning state
 func (ps *pruningStore) StagePruningPoint(pruningPointBlockHash *externalapi.DomainHash, pruningPointUTXOSetBytes []byte) {
-	ps.pruningPointStaging = pruningPointBlockHash.Clone()
+	ps.pruningPointStaging = pruningPointBlockHash
 	ps.serializedUTXOSetStaging = pruningPointUTXOSetBytes
 }
 
diff --git a/domain/consensus/datastructures/reachabilitydatastore/reachabilitydatastore.go b/domain/consensus/datastructures/reachabilitydatastore/reachabilitydatastore.go
index f466e9d9..c14f0e99 100644
--- a/domain/consensus/datastructures/reachabilitydatastore/reachabilitydatastore.go
+++ b/domain/consensus/datastructures/reachabilitydatastore/reachabilitydatastore.go
@@ -137,7 +137,7 @@ func (rds *reachabilityDataStore) ReachabilityReindexRoot(dbContext model.DBRead
 }
 
 func (rds *reachabilityDataStore) reachabilityDataBlockHashAsKey(hash *externalapi.DomainHash) model.DBKey {
-	return reachabilityDataBucket.Key(hash[:])
+	return reachabilityDataBucket.Key(hash.ByteSlice())
 }
 
 func (rds *reachabilityDataStore) serializeReachabilityData(reachabilityData *model.ReachabilityData) ([]byte, error) {
diff --git a/domain/consensus/datastructures/utxodiffstore/utxodiffstore.go b/domain/consensus/datastructures/utxodiffstore/utxodiffstore.go
index 60d5e55e..9fa0adc1 100644
--- a/domain/consensus/datastructures/utxodiffstore/utxodiffstore.go
+++ b/domain/consensus/datastructures/utxodiffstore/utxodiffstore.go
@@ -38,7 +38,7 @@ func (uds *utxoDiffStore) Stage(blockHash *externalapi.DomainHash, utxoDiff mode
 	uds.utxoDiffStaging[*blockHash] = utxoDiff
 
 	if utxoDiffChild != nil {
-		uds.utxoDiffChildStaging[*blockHash] = utxoDiffChild.Clone()
+		uds.utxoDiffChildStaging[*blockHash] = utxoDiffChild
 	}
 }
 
@@ -132,11 +132,11 @@ func (uds *utxoDiffStore) UTXODiff(dbContext model.DBReader, blockHash *external
 // UTXODiffChild gets the utxoDiff child associated with the given blockHash
 func (uds *utxoDiffStore) UTXODiffChild(dbContext model.DBReader, blockHash *externalapi.DomainHash) (*externalapi.DomainHash, error) {
 	if utxoDiffChild, ok := uds.utxoDiffChildStaging[*blockHash]; ok {
-		return utxoDiffChild.Clone(), nil
+		return utxoDiffChild, nil
 	}
 
 	if utxoDiffChild, ok := uds.utxoDiffChildCache.Get(blockHash); ok {
-		return utxoDiffChild.(*externalapi.DomainHash).Clone(), nil
+		return utxoDiffChild.(*externalapi.DomainHash), nil
 	}
 
 	utxoDiffChildBytes, err := dbContext.Get(uds.utxoDiffChildHashAsKey(blockHash))
@@ -149,7 +149,7 @@ func (uds *utxoDiffStore) UTXODiffChild(dbContext model.DBReader, blockHash *ext
 		return nil, err
 	}
 	uds.utxoDiffChildCache.Add(blockHash, utxoDiffChild)
-	return utxoDiffChild.Clone(), nil
+	return utxoDiffChild, nil
 }
 
 // HasUTXODiffChild returns true if the given blockHash has a UTXODiffChild
@@ -180,11 +180,11 @@ func (uds *utxoDiffStore) Delete(blockHash *externalapi.DomainHash) {
 }
 
 func (uds *utxoDiffStore) utxoDiffHashAsKey(hash *externalapi.DomainHash) model.DBKey {
-	return utxoDiffBucket.Key(hash[:])
+	return utxoDiffBucket.Key(hash.ByteSlice())
 }
 
 func (uds *utxoDiffStore) utxoDiffChildHashAsKey(hash *externalapi.DomainHash) model.DBKey {
-	return utxoDiffChildBucket.Key(hash[:])
+	return utxoDiffChildBucket.Key(hash.ByteSlice())
 }
 
 func (uds *utxoDiffStore) serializeUTXODiff(utxoDiff model.UTXODiff) ([]byte, error) {
diff --git a/domain/consensus/model/externalapi/block.go b/domain/consensus/model/externalapi/block.go
index 07d0d5cb..1ff82a4c 100644
--- a/domain/consensus/model/externalapi/block.go
+++ b/domain/consensus/model/externalapi/block.go
@@ -63,9 +63,9 @@ func (header *DomainBlockHeader) Clone() *DomainBlockHeader {
 	return &DomainBlockHeader{
 		Version:              header.Version,
 		ParentHashes:         CloneHashes(header.ParentHashes),
-		HashMerkleRoot:       *header.HashMerkleRoot.Clone(),
-		AcceptedIDMerkleRoot: *header.AcceptedIDMerkleRoot.Clone(),
-		UTXOCommitment:       *header.UTXOCommitment.Clone(),
+		HashMerkleRoot:       header.HashMerkleRoot,
+		AcceptedIDMerkleRoot: header.AcceptedIDMerkleRoot,
+		UTXOCommitment:       header.UTXOCommitment,
 		TimeInMilliseconds:   header.TimeInMilliseconds,
 		Bits:                 header.Bits,
 		Nonce:                header.Nonce,
diff --git a/domain/consensus/model/externalapi/hash.go b/domain/consensus/model/externalapi/hash.go
index d52feac3..02317d88 100644
--- a/domain/consensus/model/externalapi/hash.go
+++ b/domain/consensus/model/externalapi/hash.go
@@ -1,27 +1,79 @@
 package externalapi
 
-import "encoding/hex"
+import (
+	"encoding/hex"
+
+	"github.com/pkg/errors"
+)
 
 // DomainHashSize of array used to store hashes.
 const DomainHashSize = 32
 
 // DomainHash is the domain representation of a Hash
-type DomainHash [DomainHashSize]byte
+type DomainHash struct {
+	hashArray [DomainHashSize]byte
+}
+
+// NewDomainHashFromByteArray constructs a new DomainHash out of a byte array
+func NewDomainHashFromByteArray(hashBytes *[DomainHashSize]byte) *DomainHash {
+	return &DomainHash{
+		hashArray: *hashBytes,
+	}
+}
+
+// NewDomainHashFromByteSlice constructs a new DomainHash out of a byte slice.
+// Returns an error if the length of the byte slice is not exactly `DomainHashSize`
+func NewDomainHashFromByteSlice(hashBytes []byte) (*DomainHash, error) {
+	if len(hashBytes) != DomainHashSize {
+		return nil, errors.Errorf("invalid hash size. Want: %d, got: %d",
+			DomainHashSize, len(hashBytes))
+	}
+	domainHash := DomainHash{
+		hashArray: [DomainHashSize]byte{},
+	}
+	copy(domainHash.hashArray[:], hashBytes)
+	return &domainHash, nil
+}
+
+// NewDomainHashFromString constructs a new DomainHash out of a hex-encoded string.
+// Returns an error if the length of the string is not exactly `DomainHashSize * 2`
+func NewDomainHashFromString(hashString string) (*DomainHash, error) {
+	expectedLength := DomainHashSize * 2
+	// Return error if hash string is too long.
+	if len(hashString) != expectedLength {
+		return nil, errors.Errorf("hash string length is %d, while it should be be %d",
+			len(hashString), expectedLength)
+	}
+
+	hashBytes, err := hex.DecodeString(hashString)
+	if err != nil {
+		return nil, errors.WithStack(err)
+	}
+
+	return NewDomainHashFromByteSlice(hashBytes)
+}
 
 // String returns the Hash as the hexadecimal string of the hash.
 func (hash DomainHash) String() string {
-	return hex.EncodeToString(hash[:])
+	return hex.EncodeToString(hash.hashArray[:])
+}
+
+// ByteArray returns the bytes in this hash represented as a byte array.
+// The hash bytes are cloned, therefore it is safe to modify the resulting array.
+func (hash *DomainHash) ByteArray() *[DomainHashSize]byte {
+	arrayClone := hash.hashArray
+	return &arrayClone
 }
 
-// Clone clones the hash
-func (hash *DomainHash) Clone() *DomainHash {
-	hashClone := *hash
-	return &hashClone
+// ByteSlice returns the bytes in this hash represented as a byte slice.
+// The hash bytes are cloned, therefore it is safe to modify the resulting slice.
+func (hash *DomainHash) ByteSlice() []byte {
+	return hash.ByteArray()[:]
 }
 
 // If this doesn't compile, it means the type definition has been changed, so it's
 // an indication to update Equal and Clone accordingly.
-var _ DomainHash = [DomainHashSize]byte{}
+var _ DomainHash = DomainHash{hashArray: [DomainHashSize]byte{}}
 
 // Equal returns whether hash equals to other
 func (hash *DomainHash) Equal(other *DomainHash) bool {
@@ -29,7 +81,15 @@ func (hash *DomainHash) Equal(other *DomainHash) bool {
 		return hash == other
 	}
 
-	return *hash == *other
+	return hash.hashArray == other.hashArray
+}
+
+// CloneHashes returns a clone of the given hashes slice.
+// Note: since DomainHash is a read-only type, the clone is shallow
+func CloneHashes(hashes []*DomainHash) []*DomainHash {
+	clone := make([]*DomainHash, len(hashes))
+	copy(clone, hashes)
+	return clone
 }
 
 // HashesEqual returns whether the given hash slices are equal.
@@ -45,22 +105,3 @@ func HashesEqual(a, b []*DomainHash) bool {
 	}
 	return true
 }
-
-// CloneHashes returns a clone of the given hashes slice
-func CloneHashes(hashes []*DomainHash) []*DomainHash {
-	clone := make([]*DomainHash, len(hashes))
-	for i, hash := range hashes {
-		clone[i] = hash.Clone()
-	}
-	return clone
-}
-
-// DomainHashesToStrings returns a slice of strings representing the hashes in the given slice of hashes
-func DomainHashesToStrings(hashes []*DomainHash) []string {
-	strings := make([]string, len(hashes))
-	for i, hash := range hashes {
-		strings[i] = hash.String()
-	}
-
-	return strings
-}
diff --git a/domain/consensus/model/externalapi/transaction.go b/domain/consensus/model/externalapi/transaction.go
index d0410e9f..0dec46d5 100644
--- a/domain/consensus/model/externalapi/transaction.go
+++ b/domain/consensus/model/externalapi/transaction.go
@@ -3,6 +3,7 @@ package externalapi
 import (
 	"bytes"
 	"fmt"
+
 	"github.com/pkg/errors"
 )
 
@@ -52,7 +53,7 @@ func (tx *DomainTransaction) Clone() *DomainTransaction {
 		LockTime:     tx.LockTime,
 		SubnetworkID: *tx.SubnetworkID.Clone(),
 		Gas:          tx.Gas,
-		PayloadHash:  *tx.PayloadHash.Clone(),
+		PayloadHash:  tx.PayloadHash,
 		Payload:      payloadClone,
 		Fee:          tx.Fee,
 		Mass:         tx.Mass,
@@ -263,6 +264,31 @@ func (output *DomainTransactionOutput) Clone() *DomainTransactionOutput {
 // DomainTransactionID represents the ID of a Kaspa transaction
 type DomainTransactionID DomainHash
 
+// NewDomainTransactionIDFromByteArray constructs a new TransactionID out of a byte array
+func NewDomainTransactionIDFromByteArray(transactionIDBytes *[DomainHashSize]byte) *DomainTransactionID {
+	return (*DomainTransactionID)(NewDomainHashFromByteArray(transactionIDBytes))
+}
+
+// NewDomainTransactionIDFromByteSlice constructs a new TransactionID out of a byte slice
+// Returns an error if the length of the byte slice is not exactly `DomainHashSize`
+func NewDomainTransactionIDFromByteSlice(transactionIDBytes []byte) (*DomainTransactionID, error) {
+	hash, err := NewDomainHashFromByteSlice(transactionIDBytes)
+	if err != nil {
+		return nil, err
+	}
+	return (*DomainTransactionID)(hash), nil
+}
+
+// NewDomainTransactionIDFromString constructs a new TransactionID out of a string
+// Returns an error if the length of the string is not exactly `DomainHashSize * 2`
+func NewDomainTransactionIDFromString(transactionIDString string) (*DomainTransactionID, error) {
+	hash, err := NewDomainHashFromString(transactionIDString)
+	if err != nil {
+		return nil, err
+	}
+	return (*DomainTransactionID)(hash), nil
+}
+
 // String stringifies a transaction ID.
 func (id DomainTransactionID) String() string {
 	return DomainHash(id).String()
@@ -274,15 +300,19 @@ func (id *DomainTransactionID) Clone() *DomainTransactionID {
 	return &idClone
 }
 
-// If this doesn't compile, it means the type definition has been changed, so it's
-// an indication to update Equal and Clone accordingly.
-var _ DomainTransactionID = [DomainHashSize]byte{}
-
 // Equal returns whether id equals to other
 func (id *DomainTransactionID) Equal(other *DomainTransactionID) bool {
-	if id == nil || other == nil {
-		return id == other
-	}
+	return (*DomainHash)(id).Equal((*DomainHash)(other))
+}
+
+// ByteArray returns the bytes in this transactionID represented as a byte array.
+// The transactionID bytes are cloned, therefore it is safe to modify the resulting array.
+func (id *DomainTransactionID) ByteArray() *[DomainHashSize]byte {
+	return (*DomainHash)(id).ByteArray()
+}
 
-	return *id == *other
+// ByteSlice returns the bytes in this transactionID represented as a byte slice.
+// The transactionID bytes are cloned, therefore it is safe to modify the resulting slice.
+func (id *DomainTransactionID) ByteSlice() []byte {
+	return (*DomainHash)(id).ByteSlice()
 }
diff --git a/domain/consensus/model/pow/pow.go b/domain/consensus/model/pow/pow.go
index c3fe5a71..323fdb93 100644
--- a/domain/consensus/model/pow/pow.go
+++ b/domain/consensus/model/pow/pow.go
@@ -37,7 +37,7 @@ func calcPowValue(header *externalapi.DomainBlockHeader) *big.Int {
 
 	// PRE_POW_HASH || TIME || 32 zero byte padding || NONCE
 	writer := hashes.NewPoWHashWriter()
-	writer.InfallibleWrite(prePowHash[:])
+	writer.InfallibleWrite(prePowHash.ByteSlice())
 	err := serialization.WriteElement(writer, timestamp)
 	if err != nil {
 		panic(errors.Wrap(err, "this should never happen. Hash digest should never return an error"))
@@ -54,11 +54,11 @@ func calcPowValue(header *externalapi.DomainBlockHeader) *big.Int {
 // ToBig converts a externalapi.DomainHash into a big.Int treated as a little endian string.
 func toBig(hash *externalapi.DomainHash) *big.Int {
 	// We treat the Hash as little-endian for PoW purposes, but the big package wants the bytes in big-endian, so reverse them.
-	buf := hash.Clone()
+	buf := hash.ByteSlice()
 	blen := len(buf)
 	for i := 0; i < blen/2; i++ {
 		buf[i], buf[blen-1-i] = buf[blen-1-i], buf[i]
 	}
 
-	return new(big.Int).SetBytes(buf[:])
+	return new(big.Int).SetBytes(buf)
 }
diff --git a/domain/consensus/model/reachabilitydata.go b/domain/consensus/model/reachabilitydata.go
index f90c42e5..d95e5f80 100644
--- a/domain/consensus/model/reachabilitydata.go
+++ b/domain/consensus/model/reachabilitydata.go
@@ -2,6 +2,7 @@ package model
 
 import (
 	"fmt"
+
 	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
 )
 
@@ -93,15 +94,9 @@ func (rtn *ReachabilityTreeNode) Equal(other *ReachabilityTreeNode) bool {
 
 // Clone returns a clone of ReachabilityTreeNode
 func (rtn *ReachabilityTreeNode) Clone() *ReachabilityTreeNode {
-
-	var parentClone *externalapi.DomainHash
-	if rtn.Parent != nil {
-		parentClone = rtn.Parent.Clone()
-	}
-
 	return &ReachabilityTreeNode{
 		Children: externalapi.CloneHashes(rtn.Children),
-		Parent:   parentClone,
+		Parent:   rtn.Parent,
 		Interval: rtn.Interval.Clone(),
 	}
 }
diff --git a/domain/consensus/model/virtual.go b/domain/consensus/model/virtual.go
index 1162b36d..5aeab2de 100644
--- a/domain/consensus/model/virtual.go
+++ b/domain/consensus/model/virtual.go
@@ -3,9 +3,9 @@ package model
 import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
 
 // VirtualBlockHash is a marker hash for the virtual block
-var VirtualBlockHash = &externalapi.DomainHash{
+var VirtualBlockHash = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-}
+})
diff --git a/domain/consensus/processes/ghostdag2/ghostdagimpl.go b/domain/consensus/processes/ghostdag2/ghostdagimpl.go
index ec2ad1ef..05a3030f 100644
--- a/domain/consensus/processes/ghostdag2/ghostdagimpl.go
+++ b/domain/consensus/processes/ghostdag2/ghostdagimpl.go
@@ -5,10 +5,11 @@ import (
 
 	"github.com/kaspanet/kaspad/domain/consensus/processes/ghostdagmanager"
 
+	"math/big"
+
 	"github.com/kaspanet/kaspad/domain/consensus/model"
 	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
 	"github.com/kaspanet/kaspad/util"
-	"math/big"
 )
 
 type ghostdagHelper struct {
@@ -122,12 +123,14 @@ func (gh *ghostdagHelper) GHOSTDAG(blockCandidate *externalapi.DomainHash) error
 
 /* --------isMoreHash(w, selectedParent)----------------*/
 func ismoreHash(parent *externalapi.DomainHash, selectedParent *externalapi.DomainHash) bool {
+	parentByteArray := parent.ByteArray()
+	selectedParentByteArray := selectedParent.ByteArray()
 	//Check if parentHash is more then selectedParentHash
-	for i := len(parent) - 1; i >= 0; i-- {
+	for i := len(parentByteArray) - 1; i >= 0; i-- {
 		switch {
-		case parent[i] < selectedParent[i]:
+		case parentByteArray[i] < selectedParentByteArray[i]:
 			return false
-		case parent[i] > selectedParent[i]:
+		case parentByteArray[i] > selectedParentByteArray[i]:
 			return true
 		}
 	}
diff --git a/domain/consensus/utils/consensushashing/transaction.go b/domain/consensus/utils/consensushashing/transaction.go
index 79c3ad2f..a0c74660 100644
--- a/domain/consensus/utils/consensushashing/transaction.go
+++ b/domain/consensus/utils/consensushashing/transaction.go
@@ -180,7 +180,7 @@ func writeTransactionInput(w io.Writer, ti *externalapi.DomainTransactionInput,
 }
 
 func writeOutpoint(w io.Writer, outpoint *externalapi.DomainOutpoint) error {
-	_, err := w.Write(outpoint.TransactionID[:])
+	_, err := w.Write(outpoint.TransactionID.ByteSlice())
 	if err != nil {
 		return err
 	}
diff --git a/domain/consensus/utils/hashes/compare.go b/domain/consensus/utils/hashes/compare.go
index 0b644086..fdf16db1 100644
--- a/domain/consensus/utils/hashes/compare.go
+++ b/domain/consensus/utils/hashes/compare.go
@@ -11,12 +11,14 @@ import (
 //   +1 if a >  b
 //
 func cmp(a, b *externalapi.DomainHash) int {
+	aBytes := a.ByteArray()
+	bBytes := b.ByteArray()
 	// We compare the hashes backwards because Hash is stored as a little endian byte array.
 	for i := externalapi.DomainHashSize - 1; i >= 0; i-- {
 		switch {
-		case a[i] < b[i]:
+		case aBytes[i] < bBytes[i]:
 			return -1
-		case a[i] > b[i]:
+		case aBytes[i] > bBytes[i]:
 			return 1
 		}
 	}
diff --git a/domain/consensus/utils/hashes/from_bytes.go b/domain/consensus/utils/hashes/from_bytes.go
deleted file mode 100644
index 8b397ccb..00000000
--- a/domain/consensus/utils/hashes/from_bytes.go
+++ /dev/null
@@ -1,17 +0,0 @@
-package hashes
-
-import (
-	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
-	"github.com/pkg/errors"
-)
-
-// FromBytes creates a DomainHash from the given byte slice
-func FromBytes(hashBytes []byte) (*externalapi.DomainHash, error) {
-	if len(hashBytes) != externalapi.DomainHashSize {
-		return nil, errors.Errorf("invalid hash size. Want: %d, got: %d",
-			externalapi.DomainHashSize, len(hashBytes))
-	}
-	var domainHash externalapi.DomainHash
-	copy(domainHash[:], hashBytes)
-	return &domainHash, nil
-}
diff --git a/domain/consensus/utils/hashes/strings.go b/domain/consensus/utils/hashes/strings.go
index 022dd94b..91a901a6 100644
--- a/domain/consensus/utils/hashes/strings.go
+++ b/domain/consensus/utils/hashes/strings.go
@@ -1,52 +1,9 @@
 package hashes
 
 import (
-	"encoding/hex"
-
 	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
-	"github.com/pkg/errors"
 )
 
-// FromString creates a DomainHash from a hash string. The string should be
-// the hexadecimal string of a hash, but any missing characters
-// result in zero padding at the end of the Hash.
-func FromString(hash string) (*externalapi.DomainHash, error) {
-	ret := new(externalapi.DomainHash)
-	err := decode(ret, hash)
-	if err != nil {
-		return nil, err
-	}
-	return ret, nil
-}
-
-// decode decodes the hexadecimal string encoding of a Hash to a destination.
-func decode(dst *externalapi.DomainHash, src string) error {
-	expectedSrcLength := externalapi.DomainHashSize * 2
-	// Return error if hash string is too long.
-	if len(src) != expectedSrcLength {
-		return errors.Errorf("hash string length is %d, while it should be be %d",
-			len(src), expectedSrcLength)
-	}
-
-	// Hex decoder expects the hash to be a multiple of two. When not, pad
-	// with a leading zero.
-	var srcBytes []byte
-	if len(src)%2 == 0 {
-		srcBytes = []byte(src)
-	} else {
-		srcBytes = make([]byte, 1+len(src))
-		srcBytes[0] = '0'
-		copy(srcBytes[1:], src)
-	}
-
-	// Hex decode the source bytes
-	_, err := hex.Decode(dst[externalapi.DomainHashSize-hex.DecodedLen(len(srcBytes)):], srcBytes)
-	if err != nil {
-		return errors.Wrap(err, "couldn't decode hash hex")
-	}
-	return nil
-}
-
 // ToStrings converts a slice of hashes into a slice of the corresponding strings
 func ToStrings(hashes []*externalapi.DomainHash) []string {
 	strings := make([]string, len(hashes))
diff --git a/domain/consensus/utils/hashes/to_big.go b/domain/consensus/utils/hashes/to_big.go
index 25077c69..6eedafed 100644
--- a/domain/consensus/utils/hashes/to_big.go
+++ b/domain/consensus/utils/hashes/to_big.go
@@ -1,8 +1,9 @@
 package hashes
 
 import (
-	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
 	"math/big"
+
+	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
 )
 
 // ToBig converts a externalapi.DomainHash into a big.Int that can be used to
@@ -10,7 +11,7 @@ import (
 func ToBig(hash *externalapi.DomainHash) *big.Int {
 	// A Hash is in little-endian, but the big package wants the bytes in
 	// big-endian, so reverse them.
-	buf := hash.Clone()
+	buf := hash.ByteArray()
 	blen := len(buf)
 	for i := 0; i < blen/2; i++ {
 		buf[i], buf[blen-1-i] = buf[blen-1-i], buf[i]
diff --git a/domain/consensus/utils/hashes/writers.go b/domain/consensus/utils/hashes/writers.go
index 7b5958dd..51b0f4cd 100644
--- a/domain/consensus/utils/hashes/writers.go
+++ b/domain/consensus/utils/hashes/writers.go
@@ -1,9 +1,10 @@
 package hashes
 
 import (
+	"hash"
+
 	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
 	"github.com/pkg/errors"
-	"hash"
 )
 
 // HashWriter is used to incrementally hash data without concatenating all of the data to a single buffer
@@ -25,8 +26,8 @@ func (h HashWriter) InfallibleWrite(p []byte) {
 
 // Finalize returns the resulting hash
 func (h HashWriter) Finalize() *externalapi.DomainHash {
-	var sum externalapi.DomainHash
+	var sum [externalapi.DomainHashSize]byte
 	// This should prevent `Sum` for allocating an output buffer, by using the DomainHash buffer. we still copy because we don't want to rely on that.
 	copy(sum[:], h.Sum(sum[:0]))
-	return &sum
+	return externalapi.NewDomainHashFromByteArray(&sum)
 }
diff --git a/domain/consensus/utils/merkle/merkle.go b/domain/consensus/utils/merkle/merkle.go
index 9eb6686a..c53a0ef8 100644
--- a/domain/consensus/utils/merkle/merkle.go
+++ b/domain/consensus/utils/merkle/merkle.go
@@ -29,8 +29,8 @@ func hashMerkleBranches(left, right *externalapi.DomainHash) *externalapi.Domain
 	// Concatenate the left and right nodes.
 	w := hashes.NewMerkleBranchHashWriter()
 
-	w.InfallibleWrite(left[:])
-	w.InfallibleWrite(right[:])
+	w.InfallibleWrite(left.ByteSlice())
+	w.InfallibleWrite(right.ByteSlice())
 
 	return w.Finalize()
 }
diff --git a/domain/consensus/utils/multiset/multiset.go b/domain/consensus/utils/multiset/multiset.go
index efda18f9..8ba1862a 100644
--- a/domain/consensus/utils/multiset/multiset.go
+++ b/domain/consensus/utils/multiset/multiset.go
@@ -4,7 +4,6 @@ import (
 	"github.com/kaspanet/go-secp256k1"
 	"github.com/kaspanet/kaspad/domain/consensus/model"
 	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
-	"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
 	"github.com/pkg/errors"
 )
 
@@ -21,13 +20,9 @@ func (m multiset) Remove(data []byte) {
 }
 
 func (m multiset) Hash() *externalapi.DomainHash {
-	hash, err := hashes.FromBytes(m.ms.Finalize()[:])
-	if err != nil {
-		panic(errors.Errorf("this should never happen unless seckp hash size is different than %d",
-			externalapi.DomainHashSize))
-	}
-
-	return hash
+	finalizedHash := m.ms.Finalize()
+	finalizedHashAsByteArray := (*[secp256k1.HashSize]byte)(finalizedHash)
+	return externalapi.NewDomainHashFromByteArray(finalizedHashAsByteArray)
 }
 
 func (m multiset) Serialize() []byte {
diff --git a/domain/consensus/utils/serialization/common.go b/domain/consensus/utils/serialization/common.go
index c66e6a5c..9228ef9c 100644
--- a/domain/consensus/utils/serialization/common.go
+++ b/domain/consensus/utils/serialization/common.go
@@ -66,14 +66,14 @@ func WriteElement(w io.Writer, element interface{}) error {
 		return nil
 
 	case externalapi.DomainHash:
-		_, err := w.Write(e[:])
+		_, err := w.Write(e.ByteSlice())
 		if err != nil {
 			return err
 		}
 		return nil
 
 	case *externalapi.DomainHash:
-		_, err := w.Write(e[:])
+		_, err := w.Write(e.ByteSlice())
 		if err != nil {
 			return err
 		}
diff --git a/domain/consensus/utils/transactionid/compare.go b/domain/consensus/utils/transactionid/compare.go
index a9d1017d..918c5420 100644
--- a/domain/consensus/utils/transactionid/compare.go
+++ b/domain/consensus/utils/transactionid/compare.go
@@ -2,28 +2,10 @@ package transactionid
 
 import (
 	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
+	"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
 )
 
-// cmp compares two transaction IDs and returns:
-//
-//   -1 if a <  b
-//    0 if a == b
-//   +1 if a >  b
-//
-func cmp(a, b *externalapi.DomainTransactionID) int {
-	// We compare the transaction IDs backwards because Hash is stored as a little endian byte array.
-	for i := externalapi.DomainHashSize - 1; i >= 0; i-- {
-		switch {
-		case a[i] < b[i]:
-			return -1
-		case a[i] > b[i]:
-			return 1
-		}
-	}
-	return 0
-}
-
 // Less returns true iff transaction ID a is less than hash b
 func Less(a, b *externalapi.DomainTransactionID) bool {
-	return cmp(a, b) < 0
+	return hashes.Less((*externalapi.DomainHash)(a), (*externalapi.DomainHash)(b))
 }
diff --git a/domain/consensus/utils/transactionid/from_bytes.go b/domain/consensus/utils/transactionid/from_bytes.go
index d407f4b8..3a1dacd0 100644
--- a/domain/consensus/utils/transactionid/from_bytes.go
+++ b/domain/consensus/utils/transactionid/from_bytes.go
@@ -2,16 +2,13 @@ package transactionid
 
 import (
 	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
-	"github.com/pkg/errors"
 )
 
 // FromBytes creates a DomainTransactionID from the given byte slice
 func FromBytes(transactionIDBytes []byte) (*externalapi.DomainTransactionID, error) {
-	if len(transactionIDBytes) != externalapi.DomainHashSize {
-		return nil, errors.Errorf("invalid hash size. Want: %d, got: %d",
-			externalapi.DomainHashSize, len(transactionIDBytes))
+	hash, err := externalapi.NewDomainHashFromByteSlice(transactionIDBytes)
+	if err != nil {
+		return nil, err
 	}
-	var domainTransactionID externalapi.DomainTransactionID
-	copy(domainTransactionID[:], transactionIDBytes)
-	return &domainTransactionID, nil
+	return (*externalapi.DomainTransactionID)(hash), nil
 }
diff --git a/domain/consensus/utils/transactionid/from_string.go b/domain/consensus/utils/transactionid/from_string.go
index 07c1124e..e5c68d1a 100644
--- a/domain/consensus/utils/transactionid/from_string.go
+++ b/domain/consensus/utils/transactionid/from_string.go
@@ -2,11 +2,10 @@ package transactionid
 
 import (
 	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
-	"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
 )
 
 // FromString creates a new DomainTransactionID from the given string
 func FromString(str string) (*externalapi.DomainTransactionID, error) {
-	hash, err := hashes.FromString(str)
+	hash, err := externalapi.NewDomainHashFromString(str)
 	return (*externalapi.DomainTransactionID)(hash), err
 }
diff --git a/domain/consensus/utils/txscript/opcode.go b/domain/consensus/utils/txscript/opcode.go
index 3bc11528..9706dca9 100644
--- a/domain/consensus/utils/txscript/opcode.go
+++ b/domain/consensus/utils/txscript/opcode.go
@@ -10,9 +10,10 @@ import (
 	"crypto/sha256"
 	"encoding/binary"
 	"fmt"
-	"golang.org/x/crypto/blake2b"
 	"hash"
 
+	"golang.org/x/crypto/blake2b"
+
 	"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
 
 	"github.com/kaspanet/go-secp256k1"
@@ -2051,7 +2052,7 @@ func opcodeCheckSig(op *parsedOpcode, vm *Engine) error {
 	}
 
 	var valid bool
-	secpHash := secp256k1.Hash(*sigHash)
+	secpHash := secp256k1.Hash(*sigHash.ByteArray())
 	if vm.sigCache != nil {
 
 		valid = vm.sigCache.Exists(secpHash, signature, pubKey)
@@ -2245,7 +2246,7 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error {
 			return err
 		}
 
-		secpHash := secp256k1.Hash(*sigHash)
+		secpHash := secp256k1.Hash(*sigHash.ByteArray())
 		var valid bool
 		if vm.sigCache != nil {
 			valid = vm.sigCache.Exists(secpHash, parsedSig, parsedPubKey)
diff --git a/domain/consensus/utils/txscript/sign.go b/domain/consensus/utils/txscript/sign.go
index e6a45091..5b850755 100644
--- a/domain/consensus/utils/txscript/sign.go
+++ b/domain/consensus/utils/txscript/sign.go
@@ -22,7 +22,7 @@ func RawTxInSignature(tx *externalapi.DomainTransaction, idx int, script []byte,
 	if err != nil {
 		return nil, err
 	}
-	secpHash := secp256k1.Hash(*hash)
+	secpHash := secp256k1.Hash(*hash.ByteArray())
 	signature, err := key.SchnorrSign(&secpHash)
 	if err != nil {
 		return nil, errors.Errorf("cannot sign tx input: %s", err)
diff --git a/domain/consensus/utils/utxo/serialization.go b/domain/consensus/utils/utxo/serialization.go
index 19613e64..850e0f9d 100644
--- a/domain/consensus/utils/utxo/serialization.go
+++ b/domain/consensus/utils/utxo/serialization.go
@@ -44,7 +44,7 @@ func DeserializeUTXO(utxoBytes []byte) (entry externalapi.UTXOEntry, outpoint *e
 }
 
 func serializeOutpoint(w io.Writer, outpoint *externalapi.DomainOutpoint) error {
-	_, err := w.Write(outpoint.TransactionID[:])
+	_, err := w.Write(outpoint.TransactionID.ByteSlice())
 	if err != nil {
 		return err
 	}
diff --git a/domain/dagconfig/genesis.go b/domain/dagconfig/genesis.go
index 162ef8d2..22362e4e 100644
--- a/domain/dagconfig/genesis.go
+++ b/domain/dagconfig/genesis.go
@@ -27,21 +27,21 @@ var genesisCoinbaseTx = transactionhelper.NewSubnetworkTransaction(1, []*externa
 
 // genesisHash is the hash of the first block in the block DAG for the main
 // network (genesis block).
-var genesisHash = externalapi.DomainHash{
+var genesisHash = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 	0x8c, 0x74, 0x62, 0xc9, 0xb6, 0xa8, 0xb2, 0x7c,
 	0x8d, 0x03, 0xa3, 0x7e, 0x45, 0x73, 0x31, 0x77,
 	0xc7, 0xe1, 0x00, 0xa8, 0xc7, 0x75, 0xe9, 0xaa,
 	0x31, 0x02, 0xa9, 0x82, 0x9f, 0xad, 0x34, 0xc8,
-}
+})
 
 // genesisMerkleRoot is the hash of the first transaction in the genesis block
 // for the main network.
-var genesisMerkleRoot = externalapi.DomainHash{
+var genesisMerkleRoot = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 	0x32, 0xea, 0x93, 0x9a, 0x1f, 0x00, 0x50, 0xc3,
 	0x97, 0x2c, 0x3d, 0xdf, 0x28, 0xb4, 0x8f, 0x1d,
 	0x75, 0x9f, 0xb1, 0x82, 0x99, 0x79, 0x7a, 0x48,
 	0xc9, 0xf6, 0x05, 0xc6, 0xae, 0x30, 0x49, 0xf7,
-}
+})
 
 // genesisBlock defines the genesis block of the block DAG which serves as the
 // public transaction ledger for the main network.
@@ -49,7 +49,7 @@ var genesisBlock = externalapi.DomainBlock{
 	Header: &externalapi.DomainBlockHeader{
 		Version:              1,
 		ParentHashes:         []*externalapi.DomainHash{},
-		HashMerkleRoot:       genesisMerkleRoot,
+		HashMerkleRoot:       *genesisMerkleRoot,
 		AcceptedIDMerkleRoot: externalapi.DomainHash{},
 		UTXOCommitment:       externalapi.DomainHash{},
 		TimeInMilliseconds:   0x1763db5c4a9,
@@ -78,21 +78,21 @@ var devnetGenesisCoinbaseTx = transactionhelper.NewSubnetworkTransaction(1,
 
 // devGenesisHash is the hash of the first block in the block DAG for the development
 // network (genesis block).
-var devnetGenesisHash = externalapi.DomainHash{
+var devnetGenesisHash = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 	0xee, 0xce, 0x68, 0x63, 0x61, 0xb4, 0xa8, 0x09,
 	0x5d, 0xa3, 0x91, 0x6c, 0x12, 0x20, 0x27, 0xdd,
 	0xf8, 0x16, 0x74, 0x8e, 0xd8, 0x7a, 0xfe, 0x2c,
 	0xb7, 0x98, 0xe6, 0x9d, 0x47, 0x07, 0x02, 0xc5,
-}
+})
 
 // devnetGenesisMerkleRoot is the hash of the first transaction in the genesis block
 // for the devopment network.
-var devnetGenesisMerkleRoot = externalapi.DomainHash{
+var devnetGenesisMerkleRoot = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 	0xdf, 0x52, 0x65, 0x3a, 0x5a, 0xd4, 0x07, 0x4e,
 	0xad, 0xac, 0xb3, 0xd7, 0xd6, 0x9a, 0xf5, 0xd3,
 	0x68, 0x05, 0x4d, 0xef, 0xd9, 0x41, 0x28, 0x84,
 	0xa9, 0x56, 0xdd, 0x68, 0x60, 0x1b, 0x8d, 0x2c,
-}
+})
 
 // devnetGenesisBlock defines the genesis block of the block DAG which serves as the
 // public transaction ledger for the development network.
@@ -100,7 +100,7 @@ var devnetGenesisBlock = externalapi.DomainBlock{
 	Header: &externalapi.DomainBlockHeader{
 		Version:              1,
 		ParentHashes:         []*externalapi.DomainHash{},
-		HashMerkleRoot:       devnetGenesisMerkleRoot,
+		HashMerkleRoot:       *devnetGenesisMerkleRoot,
 		AcceptedIDMerkleRoot: externalapi.DomainHash{},
 		UTXOCommitment:       externalapi.DomainHash{},
 		TimeInMilliseconds:   0x1763db5c4a9,
@@ -128,21 +128,21 @@ var simnetGenesisCoinbaseTx = transactionhelper.NewSubnetworkTransaction(1,
 
 // simnetGenesisHash is the hash of the first block in the block DAG for
 // the simnet (genesis block).
-var simnetGenesisHash = externalapi.DomainHash{
+var simnetGenesisHash = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 	0xe3, 0xa4, 0x4a, 0xe5, 0xdc, 0x3d, 0x39, 0x6a,
 	0xc8, 0x5b, 0x1b, 0x95, 0x30, 0x05, 0x7d, 0xb9,
 	0xd4, 0xfa, 0x30, 0x9a, 0x20, 0x7a, 0x42, 0x54,
 	0xf8, 0x10, 0x73, 0xc0, 0x15, 0x31, 0xf5, 0x1a,
-}
+})
 
 // simnetGenesisMerkleRoot is the hash of the first transaction in the genesis block
 // for the devopment network.
-var simnetGenesisMerkleRoot = externalapi.DomainHash{
+var simnetGenesisMerkleRoot = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 	0x16, 0x07, 0x15, 0x0f, 0x1b, 0xc0, 0x26, 0x27,
 	0x42, 0xc5, 0x84, 0x77, 0xdb, 0x58, 0xf7, 0x87,
 	0xa8, 0xe9, 0x9f, 0x21, 0x73, 0xa0, 0x9d, 0x96,
 	0x6a, 0x99, 0x55, 0x46, 0x7b, 0xb2, 0x1b, 0x99,
-}
+})
 
 // simnetGenesisBlock defines the genesis block of the block DAG which serves as the
 // public transaction ledger for the development network.
@@ -150,7 +150,7 @@ var simnetGenesisBlock = externalapi.DomainBlock{
 	Header: &externalapi.DomainBlockHeader{
 		Version:              1,
 		ParentHashes:         []*externalapi.DomainHash{},
-		HashMerkleRoot:       simnetGenesisMerkleRoot,
+		HashMerkleRoot:       *simnetGenesisMerkleRoot,
 		AcceptedIDMerkleRoot: externalapi.DomainHash{},
 		UTXOCommitment:       externalapi.DomainHash{},
 		TimeInMilliseconds:   0x1763db5c4a9,
@@ -176,21 +176,21 @@ var testnetGenesisCoinbaseTx = transactionhelper.NewSubnetworkTransaction(1,
 
 // testnetGenesisHash is the hash of the first block in the block DAG for the test
 // network (genesis block).
-var testnetGenesisHash = externalapi.DomainHash{
+var testnetGenesisHash = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 	0x17, 0xb3, 0x16, 0xd3, 0x4f, 0xb5, 0x2c, 0xc1,
 	0x22, 0x53, 0x1a, 0xc9, 0xde, 0x79, 0xc3, 0x03,
 	0x53, 0xa2, 0x1a, 0x0d, 0x00, 0x40, 0x7d, 0x49,
 	0x66, 0x0c, 0x76, 0xf2, 0x61, 0xe4, 0x9a, 0x23,
-}
+})
 
 // testnetGenesisMerkleRoot is the hash of the first transaction in the genesis block
 // for testnet.
-var testnetGenesisMerkleRoot = externalapi.DomainHash{
+var testnetGenesisMerkleRoot = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 	0xd7, 0x16, 0x4a, 0x38, 0x3b, 0x8a, 0x67, 0xc2,
 	0x3b, 0x89, 0x12, 0x1c, 0xcb, 0x97, 0x89, 0xe1,
 	0x12, 0x82, 0x12, 0xc2, 0x69, 0x95, 0x7f, 0x03,
 	0x29, 0xd1, 0x4f, 0xdd, 0xf1, 0x93, 0xd8, 0x47,
-}
+})
 
 // testnetGenesisBlock defines the genesis block of the block DAG which serves as the
 // public transaction ledger for testnet.
@@ -198,7 +198,7 @@ var testnetGenesisBlock = externalapi.DomainBlock{
 	Header: &externalapi.DomainBlockHeader{
 		Version:              1,
 		ParentHashes:         []*externalapi.DomainHash{},
-		HashMerkleRoot:       testnetGenesisMerkleRoot,
+		HashMerkleRoot:       *testnetGenesisMerkleRoot,
 		AcceptedIDMerkleRoot: externalapi.DomainHash{},
 		UTXOCommitment:       externalapi.DomainHash{},
 		TimeInMilliseconds:   0x1763db5c4a9,
diff --git a/domain/dagconfig/params.go b/domain/dagconfig/params.go
index b26e4706..476582f5 100644
--- a/domain/dagconfig/params.go
+++ b/domain/dagconfig/params.go
@@ -208,7 +208,7 @@ var MainnetParams = Params{
 
 	// DAG parameters
 	GenesisBlock:                   &genesisBlock,
-	GenesisHash:                    &genesisHash,
+	GenesisHash:                    genesisHash,
 	PowMax:                         mainPowMax,
 	BlockCoinbaseMaturity:          100,
 	SubsidyReductionInterval:       210000,
@@ -265,7 +265,7 @@ var TestnetParams = Params{
 
 	// DAG parameters
 	GenesisBlock:                   &testnetGenesisBlock,
-	GenesisHash:                    &testnetGenesisHash,
+	GenesisHash:                    testnetGenesisHash,
 	PowMax:                         testnetPowMax,
 	BlockCoinbaseMaturity:          100,
 	SubsidyReductionInterval:       210000,
@@ -328,7 +328,7 @@ var SimnetParams = Params{
 
 	// DAG parameters
 	GenesisBlock:                   &simnetGenesisBlock,
-	GenesisHash:                    &simnetGenesisHash,
+	GenesisHash:                    simnetGenesisHash,
 	PowMax:                         simnetPowMax,
 	BlockCoinbaseMaturity:          100,
 	SubsidyReductionInterval:       210000,
@@ -383,7 +383,7 @@ var DevnetParams = Params{
 
 	// DAG parameters
 	GenesisBlock:                   &devnetGenesisBlock,
-	GenesisHash:                    &devnetGenesisHash,
+	GenesisHash:                    devnetGenesisHash,
 	PowMax:                         devnetPowMax,
 	BlockCoinbaseMaturity:          100,
 	SubsidyReductionInterval:       210000,
diff --git a/go.sum b/go.sum
index ef0ff054..8df988a2 100644
--- a/go.sum
+++ b/go.sum
@@ -2,6 +2,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd h1:R/opQEbFEy9JGkIguV40SvRY1uliPX8ifOvi6ICsFCw=
 github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
+github.com/btcsuite/winsvc v1.0.0 h1:J9B4L7e3oqhXOcm+2IuNApwzQec85lE+QaikUcCs+dk=
 github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
@@ -12,6 +13,7 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
@@ -32,8 +34,10 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
 github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
 github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
@@ -42,7 +46,9 @@ github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlT
 github.com/kaspanet/go-secp256k1 v0.0.3 h1:zvrKddgUm/sZ0capLUZVcn2tKoAvQaXytZYrOzLZWx4=
 github.com/kaspanet/go-secp256k1 v0.0.3/go.mod h1:cFbxhxKkxqHX5eIwUGKARkph19PehipDPJejWB+H0jM=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
 github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
 github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -78,6 +84,7 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
 golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -101,9 +108,13 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
 google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
 google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/infrastructure/network/netadapter/server/grpcserver/protowire/common.go b/infrastructure/network/netadapter/server/grpcserver/protowire/common.go
index d48dee02..94112ac7 100644
--- a/infrastructure/network/netadapter/server/grpcserver/protowire/common.go
+++ b/infrastructure/network/netadapter/server/grpcserver/protowire/common.go
@@ -1,11 +1,11 @@
 package protowire
 
 import (
+	"math"
+
 	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
-	"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
 	"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
 	"github.com/kaspanet/kaspad/domain/consensus/utils/transactionid"
-	"math"
 
 	"github.com/kaspanet/kaspad/app/appmessage"
 	"github.com/kaspanet/kaspad/util/mstime"
@@ -13,7 +13,7 @@ import (
 )
 
 func (x *Hash) toDomain() (*externalapi.DomainHash, error) {
-	return hashes.FromBytes(x.Bytes)
+	return externalapi.NewDomainHashFromByteSlice(x.Bytes)
 }
 
 func protoHashesToDomain(protoHashes []*Hash) ([]*externalapi.DomainHash, error) {
@@ -30,7 +30,7 @@ func protoHashesToDomain(protoHashes []*Hash) ([]*externalapi.DomainHash, error)
 
 func domainHashToProto(hash *externalapi.DomainHash) *Hash {
 	return &Hash{
-		Bytes: hash[:],
+		Bytes: hash.ByteSlice(),
 	}
 }
 
@@ -60,7 +60,7 @@ func protoTransactionIDsToDomain(protoIDs []*TransactionId) ([]*externalapi.Doma
 
 func domainTransactionIDToProto(id *externalapi.DomainTransactionID) *TransactionId {
 	return &TransactionId{
-		Bytes: id[:],
+		Bytes: id.ByteSlice(),
 	}
 }
 
diff --git a/infrastructure/network/netadapter/server/grpcserver/protowire/wire.go b/infrastructure/network/netadapter/server/grpcserver/protowire/wire.go
index a68f1017..a5782f99 100644
--- a/infrastructure/network/netadapter/server/grpcserver/protowire/wire.go
+++ b/infrastructure/network/netadapter/server/grpcserver/protowire/wire.go
@@ -11,7 +11,11 @@ type converter interface {
 
 // ToAppMessage converts a KaspadMessage to its appmessage.Message representation
 func (x *KaspadMessage) ToAppMessage() (appmessage.Message, error) {
-	appMessage, err := x.Payload.(converter).toAppMessage()
+	converter, ok := x.Payload.(converter)
+	if !ok {
+		return nil, errors.Errorf("received invalid message")
+	}
+	appMessage, err := converter.toAppMessage()
 	if err != nil {
 		return nil, err
 	}


Test patch:
diff --git a/app/appmessage/common_test.go b/app/appmessage/common_test.go
index 6644d4fd..2069106d 100644
--- a/app/appmessage/common_test.go
+++ b/app/appmessage/common_test.go
@@ -1,234 +1,44 @@
-// Copyright (c) 2013-2016 The btcsuite developers
-// Use of this source code is governed by an ISC
-// license that can be found in the LICENSE file.
-
 package appmessage
 
-import (
-	"bytes"
-	"io"
-	"reflect"
-	"testing"
-
-	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
-	"github.com/pkg/errors"
-
-	"github.com/davecgh/go-spew/spew"
-)
+import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
 
 // mainnetGenesisHash is the hash of the first block in the block DAG for the
 // main network (genesis block).
-var mainnetGenesisHash = &externalapi.DomainHash{
+var mainnetGenesisHash = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 	0xdc, 0x5f, 0x5b, 0x5b, 0x1d, 0xc2, 0xa7, 0x25,
 	0x49, 0xd5, 0x1d, 0x4d, 0xee, 0xd7, 0xa4, 0x8b,
 	0xaf, 0xd3, 0x14, 0x4b, 0x56, 0x78, 0x98, 0xb1,
 	0x8c, 0xfd, 0x9f, 0x69, 0xdd, 0xcf, 0xbb, 0x63,
-}
+})
 
 // simnetGenesisHash is the hash of the first block in the block DAG for the
 // simulation test network.
-var simnetGenesisHash = &externalapi.DomainHash{
+var simnetGenesisHash = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 	0x9d, 0x89, 0xb0, 0x6e, 0xb3, 0x47, 0xb5, 0x6e,
 	0xcd, 0x6c, 0x63, 0x99, 0x45, 0x91, 0xd5, 0xce,
 	0x9b, 0x43, 0x05, 0xc1, 0xa5, 0x5e, 0x2a, 0xda,
 	0x90, 0x4c, 0xf0, 0x6c, 0x4d, 0x5f, 0xd3, 0x62,
-}
+})
 
 // mainnetGenesisMerkleRoot is the hash of the first transaction in the genesis
 // block for the main network.
-var mainnetGenesisMerkleRoot = &externalapi.DomainHash{
+var mainnetGenesisMerkleRoot = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 	0x4a, 0x5e, 0x1e, 0x4b, 0xaa, 0xb8, 0x9f, 0x3a,
 	0x32, 0x51, 0x8a, 0x88, 0xc3, 0x1b, 0xc8, 0x7f,
 	0x61, 0x8f, 0x76, 0x67, 0x3e, 0x2c, 0xc7, 0x7a,
 	0xb2, 0x12, 0x7b, 0x7a, 0xfd, 0xed, 0xa3, 0x3b,
-}
+})
 
-var exampleAcceptedIDMerkleRoot = &externalapi.DomainHash{
+var exampleAcceptedIDMerkleRoot = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 	0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C,
 	0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
 	0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
 	0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
-}
+})
 
-var exampleUTXOCommitment = &externalapi.DomainHash{
+var exampleUTXOCommitment = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 	0x10, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C,
 	0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
 	0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
 	0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
-}
-
-// TestElementEncoding tests appmessage encode and decode for various element types. This
-// is mainly to test the "fast" paths in readElement and writeElement which use
-// type assertions to avoid reflection when possible.
-func TestElementEncoding(t *testing.T) {
-	tests := []struct {
-		in  interface{} // Value to encode
-		buf []byte      // Encoded value
-	}{
-		{int32(1), []byte{0x01, 0x00, 0x00, 0x00}},
-		{uint32(256), []byte{0x00, 0x01, 0x00, 0x00}},
-		{
-			int64(65536),
-			[]byte{0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00},
-		},
-		{
-			uint64(4294967296),
-			[]byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00},
-		},
-		{
-			true,
-			[]byte{0x01},
-		},
-		{
-			false,
-			[]byte{0x00},
-		},
-		{
-			[4]byte{0x01, 0x02, 0x03, 0x04},
-			[]byte{0x01, 0x02, 0x03, 0x04},
-		},
-		{
-			MessageCommand(0x10),
-			[]byte{
-				0x10, 0x00, 0x00, 0x00,
-			},
-		},
-		{
-			[16]byte{
-				0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
-				0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
-			},
-			[]byte{
-				0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
-				0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
-			},
-		},
-		{
-			(*externalapi.DomainHash)(&[externalapi.DomainHashSize]byte{
-				0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
-				0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
-				0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
-				0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
-			}),
-			[]byte{
-				0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
-				0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
-				0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
-				0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
-			},
-		},
-		{
-			ServiceFlag(SFNodeNetwork),
-			[]byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-		},
-		{
-			KaspaNet(Mainnet),
-			[]byte{0x1d, 0xf7, 0xdc, 0x3d},
-		},
-	}
-
-	t.Logf("Running %d tests", len(tests))
-	for i, test := range tests {
-		// Write to appmessage format.
-		var buf bytes.Buffer
-		err := WriteElement(&buf, test.in)
-		if err != nil {
-			t.Errorf("writeElement #%d error %v", i, err)
-			continue
-		}
-		if !bytes.Equal(buf.Bytes(), test.buf) {
-			t.Errorf("writeElement #%d\n got: %s want: %s", i,
-				spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
-			continue
-		}
-
-		// Read from appmessage format.
-		rbuf := bytes.NewReader(test.buf)
-		val := test.in
-		if reflect.ValueOf(test.in).Kind() != reflect.Ptr {
-			val = reflect.New(reflect.TypeOf(test.in)).Interface()
-		}
-		err = ReadElement(rbuf, val)
-		if err != nil {
-			t.Errorf("readElement #%d error %v", i, err)
-			continue
-		}
-		ival := val
-		if reflect.ValueOf(test.in).Kind() != reflect.Ptr {
-			ival = reflect.Indirect(reflect.ValueOf(val)).Interface()
-		}
-		if !reflect.DeepEqual(ival, test.in) {
-			t.Errorf("readElement #%d\n got: %s want: %s", i,
-				spew.Sdump(ival), spew.Sdump(test.in))
-			continue
-		}
-	}
-}
-
-// TestElementEncodingErrors performs negative tests against appmessage encode and decode
-// of various element types to confirm error paths work correctly.
-func TestElementEncodingErrors(t *testing.T) {
-	type writeElementReflect int32
-
-	tests := []struct {
-		in       interface{} // Value to encode
-		max      int         // Max size of fixed buffer to induce errors
-		writeErr error       // Expected write error
-		readErr  error       // Expected read error
-	}{
-		{int32(1), 0, io.ErrShortWrite, io.EOF},
-		{uint32(256), 0, io.ErrShortWrite, io.EOF},
-		{int64(65536), 0, io.ErrShortWrite, io.EOF},
-		{true, 0, io.ErrShortWrite, io.EOF},
-		{[4]byte{0x01, 0x02, 0x03, 0x04}, 0, io.ErrShortWrite, io.EOF},
-		{
-			MessageCommand(10),
-			0, io.ErrShortWrite, io.EOF,
-		},
-		{
-			[16]byte{
-				0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
-				0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
-			},
-			0, io.ErrShortWrite, io.EOF,
-		},
-		{
-			(*externalapi.DomainHash)(&[externalapi.DomainHashSize]byte{
-				0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
-				0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
-				0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
-				0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
-			}),
-			0, io.ErrShortWrite, io.EOF,
-		},
-		{ServiceFlag(SFNodeNetwork), 0, io.ErrShortWrite, io.EOF},
-		{KaspaNet(Mainnet), 0, io.ErrShortWrite, io.EOF},
-		// Type with no supported encoding.
-		{writeElementReflect(0), 0, errNoEncodingForType, errNoEncodingForType},
-	}
-
-	t.Logf("Running %d tests", len(tests))
-	for i, test := range tests {
-		// Encode to appmessage format.
-		w := newFixedWriter(test.max)
-		err := WriteElement(w, test.in)
-		if !errors.Is(err, test.writeErr) {
-			t.Errorf("writeElement #%d wrong error got: %v, want: %v",
-				i, err, test.writeErr)
-			continue
-		}
-
-		// Decode from appmessage format.
-		r := newFixedReader(test.max, nil)
-		val := test.in
-		if reflect.ValueOf(test.in).Kind() != reflect.Ptr {
-			val = reflect.New(reflect.TypeOf(test.in)).Interface()
-		}
-		err = ReadElement(r, val)
-		if !errors.Is(err, test.readErr) {
-			t.Errorf("readElement #%d wrong error got: %v, want: %v",
-				i, err, test.readErr)
-			continue
-		}
-	}
-}
+})
diff --git a/app/appmessage/p2p_msgblocklocator_test.go b/app/appmessage/p2p_msgblocklocator_test.go
index 1623c7a5..889fe487 100644
--- a/app/appmessage/p2p_msgblocklocator_test.go
+++ b/app/appmessage/p2p_msgblocklocator_test.go
@@ -3,8 +3,6 @@ package appmessage
 import (
 	"testing"
 
-	"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
-
 	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
 
 	"github.com/davecgh/go-spew/spew"
@@ -13,7 +11,7 @@ import (
 // TestBlockLocator tests the MsgBlockLocator API.
 func TestBlockLocator(t *testing.T) {
 	hashStr := "000000000002e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
-	locatorHash, err := hashes.FromString(hashStr)
+	locatorHash, err := externalapi.NewDomainHashFromString(hashStr)
 	if err != nil {
 		t.Errorf("NewHashFromStr: %v", err)
 	}
diff --git a/app/appmessage/p2p_msgrequestblocklocator_test.go b/app/appmessage/p2p_msgrequestblocklocator_test.go
index 925f3922..e94f6ef9 100644
--- a/app/appmessage/p2p_msgrequestblocklocator_test.go
+++ b/app/appmessage/p2p_msgrequestblocklocator_test.go
@@ -4,14 +4,12 @@ import (
 	"testing"
 
 	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
-
-	"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
 )
 
 // TestRequestBlockLocator tests the MsgRequestBlockLocator API.
 func TestRequestBlockLocator(t *testing.T) {
 	hashStr := "000000000002e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
-	highHash, err := hashes.FromString(hashStr)
+	highHash, err := externalapi.NewDomainHashFromString(hashStr)
 	if err != nil {
 		t.Errorf("NewHashFromStr: %v", err)
 	}
diff --git a/app/appmessage/p2p_msgrequestheaders_test.go b/app/appmessage/p2p_msgrequestheaders_test.go
index 9d0a60cd..ac1f7a4a 100644
--- a/app/appmessage/p2p_msgrequestheaders_test.go
+++ b/app/appmessage/p2p_msgrequestheaders_test.go
@@ -7,19 +7,19 @@ package appmessage
 import (
 	"testing"
 
-	"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
+	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
 )
 
 // TestRequstIBDBlocks tests the MsgRequestHeaders API.
 func TestRequstIBDBlocks(t *testing.T) {
 	hashStr := "000000000002e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
-	lowHash, err := hashes.FromString(hashStr)
+	lowHash, err := externalapi.NewDomainHashFromString(hashStr)
 	if err != nil {
 		t.Errorf("NewHashFromStr: %v", err)
 	}
 
 	hashStr = "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
-	highHash, err := hashes.FromString(hashStr)
+	highHash, err := externalapi.NewDomainHashFromString(hashStr)
 	if err != nil {
 		t.Errorf("NewHashFromStr: %v", err)
 	}
diff --git a/app/appmessage/p2p_msgtx_test.go b/app/appmessage/p2p_msgtx_test.go
index dd124e65..a8704e3d 100644
--- a/app/appmessage/p2p_msgtx_test.go
+++ b/app/appmessage/p2p_msgtx_test.go
@@ -7,12 +7,11 @@ package appmessage
 import (
 	"bytes"
 	"fmt"
-	"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
 	"math"
 	"reflect"
 	"testing"
 
-	"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
+	"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
 
 	"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
 	"github.com/kaspanet/kaspad/domain/consensus/utils/transactionid"
@@ -185,7 +184,7 @@ func TestTxHashAndID(t *testing.T) {
 	}
 
 	hash2Str := "0c60a073b56ff0510307e3efbb5e1881c3b1b97b4f0a69e4220042a15596766b"
-	wantHash2, err := hashes.FromString(hash2Str)
+	wantHash2, err := externalapi.NewDomainHashFromString(hash2Str)
 	if err != nil {
 		t.Errorf("NewTxIDFromStr: %v", err)
 		return
@@ -201,7 +200,7 @@ func TestTxHashAndID(t *testing.T) {
 	txIns := []*TxIn{{
 		PreviousOutpoint: Outpoint{
 			Index: 0,
-			TxID:  externalapi.DomainTransactionID{1, 2, 3},
+			TxID:  *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{1, 2, 3}),
 		},
 		SignatureScript: []byte{
 			0x49, 0x30, 0x46, 0x02, 0x21, 0x00, 0xDA, 0x0D, 0xC6, 0xAE, 0xCE, 0xFE, 0x1E, 0x06, 0xEF, 0xDF,
diff --git a/app/protocol/flows/blockrelay/handle_request_headers_test.go b/app/protocol/flows/blockrelay/handle_request_headers_test.go
deleted file mode 100644
index 704cad76..00000000
--- a/app/protocol/flows/blockrelay/handle_request_headers_test.go
+++ /dev/null
@@ -1,15 +0,0 @@
-package blockrelay
-
-import (
-	"github.com/kaspanet/kaspad/domain/consensus/utils/testutils"
-	"github.com/kaspanet/kaspad/domain/dagconfig"
-	"testing"
-)
-
-func TestMaxHeaders(t *testing.T) {
-	testutils.ForAllNets(t, false, func(t *testing.T, params *dagconfig.Params) {
-		if params.FinalityDepth() > maxHeaders {
-			t.Errorf("FinalityDepth() in %s should be lower or equal to appmessage.MaxInvPerMsg", params.Name)
-		}
-	})
-}
diff --git a/domain/consensus/model/acceptancedata_equal_clone_test.go b/domain/consensus/model/acceptancedata_equal_clone_test.go
index 73bc29c9..b3d7936f 100644
--- a/domain/consensus/model/acceptancedata_equal_clone_test.go
+++ b/domain/consensus/model/acceptancedata_equal_clone_test.go
@@ -1,10 +1,11 @@
 package model_test
 
 import (
-	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
-	"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
 	"reflect"
 	"testing"
+
+	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
+	"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
 )
 
 func initTestTransactionAcceptanceDataForClone() []*externalapi.TransactionAcceptanceData {
@@ -14,7 +15,7 @@ func initTestTransactionAcceptanceDataForClone() []*externalapi.TransactionAccep
 			&externalapi.DomainTransaction{
 				Version: 1,
 				Inputs: []*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-					externalapi.DomainTransactionID{0x01}, 0xFFFF},
+					*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 					[]byte{1, 2, 3},
 					uint64(0xFFFFFFFF),
 					utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -25,17 +26,19 @@ func initTestTransactionAcceptanceDataForClone() []*externalapi.TransactionAccep
 				LockTime:     1,
 				SubnetworkID: externalapi.DomainSubnetworkID{0x01},
 				Gas:          1,
-				PayloadHash: externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				PayloadHash: *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 				Payload: []byte{0x01},
 				Fee:     0,
 				Mass:    1,
-				ID: &externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				ID: externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 			},
 			1,
 			true,
@@ -60,7 +63,7 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
 		&externalapi.DomainTransaction{
 			Version: 1,
 			Inputs: []*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-				externalapi.DomainTransactionID{0x01}, 0xFFFF},
+				*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 				[]byte{1, 2, 3},
 				uint64(0xFFFFFFFF),
 				utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -71,17 +74,19 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
 			LockTime:     1,
 			SubnetworkID: externalapi.DomainSubnetworkID{0x01},
 			Gas:          1,
-			PayloadHash: externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			PayloadHash: *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 			Payload: []byte{0x01},
 			Fee:     0,
 			Mass:    1,
-			ID: &externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			ID: externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 		},
 		1,
 		true,
@@ -91,7 +96,7 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
 		&externalapi.DomainTransaction{
 			Version: 1,
 			Inputs: []*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-				externalapi.DomainTransactionID{0x01}, 0xFFFF},
+				*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 				[]byte{1, 2, 3},
 				uint64(0xFFFFFFFF),
 				utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -102,17 +107,18 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
 			LockTime:     1,
 			SubnetworkID: externalapi.DomainSubnetworkID{0x01},
 			Gas:          1,
-			PayloadHash: externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			PayloadHash: *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 			Payload: []byte{0x01},
 			Fee:     0,
 			Mass:    1,
-			ID: &externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			ID: externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 		},
 		1,
 		true,
@@ -122,7 +128,7 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
 		&externalapi.DomainTransaction{
 			Version: 2,
 			Inputs: []*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-				externalapi.DomainTransactionID{0x01}, 0xFFFF},
+				*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 				[]byte{1, 2, 3},
 				uint64(0xFFFFFFFF),
 				utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -133,17 +139,18 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
 			LockTime:     1,
 			SubnetworkID: externalapi.DomainSubnetworkID{0x01},
 			Gas:          1,
-			PayloadHash: externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			PayloadHash: *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 			Payload: []byte{0x01},
 			Fee:     0,
 			Mass:    1,
-			ID: &externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			ID: externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 		},
 		1,
 		true,
@@ -153,7 +160,7 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
 		&externalapi.DomainTransaction{
 			Version: 1,
 			Inputs: []*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-				externalapi.DomainTransactionID{0x01}, 0xFFFF},
+				*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 				[]byte{1, 2, 3},
 				uint64(0xFFFFFFFF),
 				utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -164,17 +171,19 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
 			LockTime:     1,
 			SubnetworkID: externalapi.DomainSubnetworkID{0x01},
 			Gas:          1,
-			PayloadHash: externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			PayloadHash: *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 			Payload: []byte{0x01},
 			Fee:     0,
 			Mass:    1,
-			ID: &externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			ID: externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 		},
 		2,
 		true,
@@ -184,7 +193,7 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
 		&externalapi.DomainTransaction{
 			Version: 1,
 			Inputs: []*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-				externalapi.DomainTransactionID{0x01}, 0xFFFF},
+				*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 				[]byte{1, 2, 3},
 				uint64(0xFFFFFFFF),
 				utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -195,17 +204,19 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
 			LockTime:     1,
 			SubnetworkID: externalapi.DomainSubnetworkID{0x01},
 			Gas:          1,
-			PayloadHash: externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			PayloadHash: *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 			Payload: []byte{0x01},
 			Fee:     0,
 			Mass:    1,
-			ID: &externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			ID: externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 		},
 		1,
 		false,
@@ -280,16 +291,18 @@ func TestTransactionAcceptanceData_Clone(t *testing.T) {
 
 func initTestBlockAcceptanceDataForClone() []*externalapi.BlockAcceptanceData {
 
-	tests := []*externalapi.BlockAcceptanceData{{&externalapi.DomainHash{1},
+	tests := []*externalapi.BlockAcceptanceData{{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 		[]*externalapi.TransactionAcceptanceData{
 			{
 				&externalapi.DomainTransaction{
 					1,
-					[]*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-						externalapi.DomainTransactionID{0x01}, 0xFFFF},
-						[]byte{1, 2, 3},
-						uint64(0xFFFFFFFF),
-						utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
+					[]*externalapi.DomainTransactionInput{
+						{externalapi.DomainOutpoint{
+							*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}),
+							0xFFFF},
+							[]byte{1, 2, 3},
+							uint64(0xFFFFFFFF),
+							utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
 					[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
 						[]byte{1, 2}},
 						{uint64(0xFFFF),
@@ -297,17 +310,19 @@ func initTestBlockAcceptanceDataForClone() []*externalapi.BlockAcceptanceData {
 					1,
 					externalapi.DomainSubnetworkID{0x01},
 					1,
-					externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 					[]byte{0x01},
 					0,
 					1,
-					&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 				},
 				1,
 				true,
@@ -329,13 +344,13 @@ type testBlockAcceptanceDataStruct struct {
 
 func iniBlockAcceptanceDataForEqual() []testBlockAcceptanceDataStruct {
 	var testBlockAcceptanceDataBase = externalapi.BlockAcceptanceData{
-		&externalapi.DomainHash{1},
+		externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 		[]*externalapi.TransactionAcceptanceData{{
 			&externalapi.DomainTransaction{
 				1,
 				[]*externalapi.DomainTransactionInput{{
 					externalapi.DomainOutpoint{
-						externalapi.DomainTransactionID{0x01}, 0xFFFF},
+						*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 					[]byte{1, 2, 3},
 					uint64(0xFFFFFFFF),
 					utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -346,30 +361,32 @@ func iniBlockAcceptanceDataForEqual() []testBlockAcceptanceDataStruct {
 				1,
 				externalapi.DomainSubnetworkID{0x01},
 				1,
-				externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 				[]byte{0x01},
 				0,
 				1,
-				&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 			},
 			1,
 			true,
 		}}}
 	//test 1: structs are equal
 	var testBlockAcceptanceData1 = externalapi.BlockAcceptanceData{
-		&externalapi.DomainHash{1},
+		externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 		[]*externalapi.TransactionAcceptanceData{{
 			&externalapi.DomainTransaction{
 				1,
 				[]*externalapi.DomainTransactionInput{{
 					externalapi.DomainOutpoint{
-						externalapi.DomainTransactionID{0x01}, 0xFFFF},
+						*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 					[]byte{1, 2, 3},
 					uint64(0xFFFFFFFF),
 					utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -380,30 +397,32 @@ func iniBlockAcceptanceDataForEqual() []testBlockAcceptanceDataStruct {
 				1,
 				externalapi.DomainSubnetworkID{0x01},
 				1,
-				externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 				[]byte{0x01},
 				0,
 				1,
-				&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 			},
 			1,
 			true,
 		}}}
 	// test 2: different size
 	var testBlockAcceptanceData2 = externalapi.BlockAcceptanceData{
-		&externalapi.DomainHash{1},
+		externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 		[]*externalapi.TransactionAcceptanceData{{
 			&externalapi.DomainTransaction{
 				1,
 				[]*externalapi.DomainTransactionInput{{
 					externalapi.DomainOutpoint{
-						externalapi.DomainTransactionID{0x01}, 0xFFFF},
+						*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 					[]byte{1, 2, 3},
 					uint64(0xFFFFFFFF),
 					utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -414,30 +433,32 @@ func iniBlockAcceptanceDataForEqual() []testBlockAcceptanceDataStruct {
 				1,
 				externalapi.DomainSubnetworkID{0x01},
 				1,
-				externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 				[]byte{0x01},
 				0,
 				1,
-				&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 			},
 			1,
 			true,
 		}, {}}}
 	//test 3: different transactions, same size
 	var testBlockAcceptanceData3 = externalapi.BlockAcceptanceData{
-		&externalapi.DomainHash{1},
+		externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 		[]*externalapi.TransactionAcceptanceData{{
 			&externalapi.DomainTransaction{
 				1,
 				[]*externalapi.DomainTransactionInput{{
 					externalapi.DomainOutpoint{
-						externalapi.DomainTransactionID{0x01}, 0xFFFF},
+						*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 					[]byte{1, 2, 3},
 					uint64(0xFFFFFFFF),
 					utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -448,17 +469,19 @@ func iniBlockAcceptanceDataForEqual() []testBlockAcceptanceDataStruct {
 				1,
 				externalapi.DomainSubnetworkID{0x01},
 				1,
-				externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 				[]byte{0x01},
 				0,
 				1,
-				&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 			},
 			1,
 			false,
@@ -466,13 +489,13 @@ func iniBlockAcceptanceDataForEqual() []testBlockAcceptanceDataStruct {
 
 	// test 4 - different block hash
 	var testBlockAcceptanceData4 = externalapi.BlockAcceptanceData{
-		&externalapi.DomainHash{2},
+		externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
 		[]*externalapi.TransactionAcceptanceData{{
 			&externalapi.DomainTransaction{
 				1,
 				[]*externalapi.DomainTransactionInput{{
 					externalapi.DomainOutpoint{
-						externalapi.DomainTransactionID{0x01}, 0xFFFF},
+						*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 					[]byte{1, 2, 3},
 					uint64(0xFFFFFFFF),
 					utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -483,17 +506,19 @@ func iniBlockAcceptanceDataForEqual() []testBlockAcceptanceDataStruct {
 				1,
 				externalapi.DomainSubnetworkID{0x01},
 				1,
-				externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 				[]byte{0x01},
 				0,
 				1,
-				&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 			},
 			1,
 			true,
@@ -571,13 +596,13 @@ func TestBlockAcceptanceData_Clone(t *testing.T) {
 func initTestAcceptanceDataForClone() []externalapi.AcceptanceData {
 
 	test1 := []*externalapi.BlockAcceptanceData{{
-		&externalapi.DomainHash{1},
+		externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 		[]*externalapi.TransactionAcceptanceData{
 			{
 				&externalapi.DomainTransaction{
 					1,
 					[]*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-						externalapi.DomainTransactionID{0x01}, 0xFFFF},
+						*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 						[]byte{1, 2, 3},
 						uint64(0xFFFFFFFF),
 						utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -588,17 +613,19 @@ func initTestAcceptanceDataForClone() []externalapi.AcceptanceData {
 					1,
 					externalapi.DomainSubnetworkID{0x01},
 					1,
-					externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 					[]byte{0x01},
 					0,
 					1,
-					&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 				},
 				1,
 				true,
@@ -622,13 +649,13 @@ type testAcceptanceDataStruct struct {
 func initAcceptanceDataForEqual() []testAcceptanceDataStruct {
 	var testAcceptanceDataBase = []*externalapi.BlockAcceptanceData{
 		{
-			&externalapi.DomainHash{1},
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 			[]*externalapi.TransactionAcceptanceData{{
 				&externalapi.DomainTransaction{
 					1,
 					[]*externalapi.DomainTransactionInput{{
 						externalapi.DomainOutpoint{
-							externalapi.DomainTransactionID{0x01}, 0xFFFF},
+							*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 						[]byte{1, 2, 3},
 						uint64(0xFFFFFFFF),
 						utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -639,30 +666,32 @@ func initAcceptanceDataForEqual() []testAcceptanceDataStruct {
 					1,
 					externalapi.DomainSubnetworkID{0x01},
 					1,
-					externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 					[]byte{0x01},
 					0,
 					1,
-					&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 				},
 				1,
 				true,
 			}}}}
 	//test 1: structs are equal
 	var testAcceptanceData1 = []*externalapi.BlockAcceptanceData{
-		{&externalapi.DomainHash{1},
+		{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 			[]*externalapi.TransactionAcceptanceData{{
 				&externalapi.DomainTransaction{
 					1,
 					[]*externalapi.DomainTransactionInput{{
 						externalapi.DomainOutpoint{
-							externalapi.DomainTransactionID{0x01}, 0xFFFF},
+							*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 						[]byte{1, 2, 3},
 						uint64(0xFFFFFFFF),
 						utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -673,30 +702,32 @@ func initAcceptanceDataForEqual() []testAcceptanceDataStruct {
 					1,
 					externalapi.DomainSubnetworkID{0x01},
 					1,
-					externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 					[]byte{0x01},
 					0,
 					1,
-					&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 				},
 				1,
 				true,
 			}}}}
 	// test 2: different size
 	var testAcceptanceData2 = []*externalapi.BlockAcceptanceData{
-		{&externalapi.DomainHash{1},
+		{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 			[]*externalapi.TransactionAcceptanceData{{
 				&externalapi.DomainTransaction{
 					1,
 					[]*externalapi.DomainTransactionInput{{
 						externalapi.DomainOutpoint{
-							externalapi.DomainTransactionID{0x01}, 0xFFFF},
+							*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 						[]byte{1, 2, 3},
 						uint64(0xFFFFFFFF),
 						utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -707,30 +738,32 @@ func initAcceptanceDataForEqual() []testAcceptanceDataStruct {
 					1,
 					externalapi.DomainSubnetworkID{0x01},
 					1,
-					externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 					[]byte{0x01},
 					0,
 					1,
-					&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 				},
 				1,
 				true,
 			}}}, {}}
 	//test 3: different transactions, same size
 	var testAcceptanceData3 = []*externalapi.BlockAcceptanceData{
-		{&externalapi.DomainHash{1},
+		{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 			[]*externalapi.TransactionAcceptanceData{{
 				&externalapi.DomainTransaction{
 					2,
 					[]*externalapi.DomainTransactionInput{{
 						externalapi.DomainOutpoint{
-							externalapi.DomainTransactionID{0x01}, 0xFFFF},
+							*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 						[]byte{1, 2, 3},
 						uint64(0xFFFFFFFF),
 						utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -741,17 +774,19 @@ func initAcceptanceDataForEqual() []testAcceptanceDataStruct {
 					1,
 					externalapi.DomainSubnetworkID{0x01},
 					1,
-					externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 					[]byte{0x01},
 					0,
 					1,
-					&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 				},
 				1,
 				true,
diff --git a/domain/consensus/model/blockrelations_equal_clone_test.go b/domain/consensus/model/blockrelations_equal_clone_test.go
index 39c05e8e..98193c22 100644
--- a/domain/consensus/model/blockrelations_equal_clone_test.go
+++ b/domain/consensus/model/blockrelations_equal_clone_test.go
@@ -1,17 +1,24 @@
 package model
 
 import (
-	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
 	"reflect"
 	"testing"
+
+	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
 )
 
 func initTestBlockRelationsForClone() []*BlockRelations {
 
 	tests := []*BlockRelations{
 		{
-			[]*externalapi.DomainHash{{1}, {2}},
-			[]*externalapi.DomainHash{{3}, {4}},
+			[]*externalapi.DomainHash{
+				externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+				externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
+			},
+			[]*externalapi.DomainHash{
+				externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
+				externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
+			},
 		},
 	}
 	return tests
@@ -30,23 +37,47 @@ type testBlockRelationsStruct struct {
 func initTestBlockRelationsForEqual() []testBlockRelationsStruct {
 
 	var testBlockRelationsBase = BlockRelations{
-		[]*externalapi.DomainHash{{1}, {2}},
-		[]*externalapi.DomainHash{{3}, {4}},
+		[]*externalapi.DomainHash{
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
+		},
+		[]*externalapi.DomainHash{
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
+		},
 	}
 	//First test: structs are equal
 	var testBlockRelations1 = BlockRelations{
-		[]*externalapi.DomainHash{{1}, {2}},
-		[]*externalapi.DomainHash{{3}, {4}},
+		[]*externalapi.DomainHash{
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
+		},
+		[]*externalapi.DomainHash{
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
+		},
 	}
 	//Second test: children changed
 	var testBlockRelations2 = BlockRelations{
-		[]*externalapi.DomainHash{{1}, {2}},
-		[]*externalapi.DomainHash{{3}, {5}},
+		[]*externalapi.DomainHash{
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
+		},
+		[]*externalapi.DomainHash{
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{5}),
+		},
 	}
 	//Third test: parents changed
 	var testBlockRelations3 = BlockRelations{
-		[]*externalapi.DomainHash{{6}, {2}},
-		[]*externalapi.DomainHash{{3}, {4}},
+		[]*externalapi.DomainHash{
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{6}),
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
+		},
+		[]*externalapi.DomainHash{
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
+		},
 	}
 
 	tests := []testBlockRelationsStruct{
diff --git a/domain/consensus/model/externalapi/block_equal_clone_test.go b/domain/consensus/model/externalapi/block_equal_clone_test.go
index 9a032d84..35dd5030 100644
--- a/domain/consensus/model/externalapi/block_equal_clone_test.go
+++ b/domain/consensus/model/externalapi/block_equal_clone_test.go
@@ -24,17 +24,19 @@ func initTestBaseTransactions() []*DomainTransaction {
 		LockTime:     1,
 		SubnetworkID: DomainSubnetworkID{0x01},
 		Gas:          1,
-		PayloadHash: DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		PayloadHash: *NewDomainHashFromByteArray(&[DomainHashSize]byte{
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 		Payload: []byte{0x01},
 		Fee:     0,
 		Mass:    1,
-		ID: &DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		ID: NewDomainTransactionIDFromByteArray(&[DomainHashSize]byte{
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 	}}
 	return testTx
 }
@@ -48,17 +50,19 @@ func initTestAnotherTransactions() []*DomainTransaction {
 		LockTime:     1,
 		SubnetworkID: DomainSubnetworkID{0x01},
 		Gas:          1,
-		PayloadHash: DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		PayloadHash: *NewDomainHashFromByteArray(&[DomainHashSize]byte{
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}),
 		Payload: []byte{0x01},
 		Fee:     0,
 		Mass:    1,
-		ID: &DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		ID: NewDomainTransactionIDFromByteArray(&[DomainHashSize]byte{
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}),
 	}}
 	return testTx
 }
@@ -72,17 +76,19 @@ func initTestTwoTransactions() []*DomainTransaction {
 		LockTime:     1,
 		SubnetworkID: DomainSubnetworkID{0x01},
 		Gas:          1,
-		PayloadHash: DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		PayloadHash: *NewDomainHashFromByteArray(&[DomainHashSize]byte{
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}),
 		Payload: []byte{0x01},
 		Fee:     0,
 		Mass:    1,
-		ID: &DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		ID: NewDomainTransactionIDFromByteArray(&[DomainHashSize]byte{
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}),
 	}, {
 		Version:      1,
 		Inputs:       []*DomainTransactionInput{},
@@ -90,17 +96,19 @@ func initTestTwoTransactions() []*DomainTransaction {
 		LockTime:     1,
 		SubnetworkID: DomainSubnetworkID{0x01},
 		Gas:          1,
-		PayloadHash: DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		PayloadHash: *NewDomainHashFromByteArray(&[DomainHashSize]byte{
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}),
 		Payload: []byte{0x01},
 		Fee:     0,
 		Mass:    1,
-		ID: &DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		ID: NewDomainTransactionIDFromByteArray(&[DomainHashSize]byte{
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}),
 	}}
 	return testTx
 }
@@ -112,10 +120,10 @@ func initTestBlockStructsForClone() []*DomainBlock {
 			&DomainBlockHeader{
 
 				0,
-				[]*DomainHash{{0}},
-				DomainHash{1},
-				DomainHash{2},
-				DomainHash{3},
+				[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{0})},
+				*NewDomainHashFromByteArray(&[DomainHashSize]byte{1}),
+				*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+				*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
 				4,
 				5,
 				6,
@@ -126,9 +134,9 @@ func initTestBlockStructsForClone() []*DomainBlock {
 
 				0,
 				[]*DomainHash{},
-				DomainHash{1},
-				DomainHash{2},
-				DomainHash{3},
+				*NewDomainHashFromByteArray(&[DomainHashSize]byte{1}),
+				*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+				*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
 				4,
 				5,
 				6,
@@ -153,10 +161,10 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
 					block: &DomainBlock{
 						&DomainBlockHeader{
 							0,
-							[]*DomainHash{{0}},
-							DomainHash{1},
-							DomainHash{2},
-							DomainHash{3},
+							[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{0})},
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{1}),
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
 							4,
 							5,
 							6,
@@ -169,10 +177,10 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
 			baseBlock: &DomainBlock{
 				&DomainBlockHeader{
 					0,
-					[]*DomainHash{{1}},
-					DomainHash{2},
-					DomainHash{3},
-					DomainHash{4},
+					[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{1})},
+					*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+					*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
+					*NewDomainHashFromByteArray(&[DomainHashSize]byte{4}),
 					5,
 					6,
 					7,
@@ -188,10 +196,10 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
 					block: &DomainBlock{
 						&DomainBlockHeader{
 							0,
-							[]*DomainHash{{1}},
-							DomainHash{2},
-							DomainHash{3},
-							DomainHash{4},
+							[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{1})},
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{4}),
 							5,
 							6,
 							7,
@@ -203,10 +211,10 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
 					block: &DomainBlock{
 						&DomainBlockHeader{
 							0,
-							[]*DomainHash{{1}},
-							DomainHash{2},
-							DomainHash{3},
-							DomainHash{4},
+							[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{1})},
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{4}),
 							5,
 							6,
 							7,
@@ -218,10 +226,13 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
 					block: &DomainBlock{
 						&DomainBlockHeader{
 							0,
-							[]*DomainHash{{1}, {2}}, // Changed
-							DomainHash{2},
-							DomainHash{3},
-							DomainHash{4},
+							[]*DomainHash{
+								NewDomainHashFromByteArray(&[DomainHashSize]byte{1}),
+								NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+							},
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{4}),
 							5,
 							6,
 							7,
@@ -233,10 +244,10 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
 					block: &DomainBlock{
 						&DomainBlockHeader{
 							0,
-							[]*DomainHash{{100}}, // Changed
-							DomainHash{2},
-							DomainHash{3},
-							DomainHash{4},
+							[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{100})}, // Changed
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{4}),
 							5,
 							6,
 							7,
@@ -248,10 +259,10 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
 					block: &DomainBlock{
 						&DomainBlockHeader{
 							0,
-							[]*DomainHash{{1}},
-							DomainHash{100}, // Changed
-							DomainHash{3},
-							DomainHash{4},
+							[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{1})},
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{100}), // Changed
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{4}),
 							5,
 							6,
 							7,
@@ -263,10 +274,10 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
 					block: &DomainBlock{
 						&DomainBlockHeader{
 							0,
-							[]*DomainHash{{1}},
-							DomainHash{2},
-							DomainHash{100}, // Changed
-							DomainHash{4},
+							[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{1})},
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{100}), // Changed
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{4}),
 							5,
 							6,
 							7,
@@ -278,10 +289,10 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
 					block: &DomainBlock{
 						&DomainBlockHeader{
 							0,
-							[]*DomainHash{{1}},
-							DomainHash{2},
-							DomainHash{3},
-							DomainHash{100}, // Changed
+							[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{1})},
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{100}), // Changed
 							5,
 							6,
 							7,
@@ -293,10 +304,10 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
 					block: &DomainBlock{
 						&DomainBlockHeader{
 							0,
-							[]*DomainHash{{1}},
-							DomainHash{2},
-							DomainHash{3},
-							DomainHash{4},
+							[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{1})},
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{4}),
 							100, // Changed
 							6,
 							7,
@@ -308,10 +319,10 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
 					block: &DomainBlock{
 						&DomainBlockHeader{
 							0,
-							[]*DomainHash{{1}},
-							DomainHash{2},
-							DomainHash{3},
-							DomainHash{4},
+							[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{1})},
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{4}),
 							5,
 							100, // Changed
 							7,
@@ -323,10 +334,10 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
 					block: &DomainBlock{
 						&DomainBlockHeader{
 							0,
-							[]*DomainHash{{1}},
-							DomainHash{2},
-							DomainHash{3},
-							DomainHash{4},
+							[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{1})},
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
+							*NewDomainHashFromByteArray(&[DomainHashSize]byte{4}),
 							5,
 							6,
 							100, // Changed
diff --git a/domain/consensus/model/externalapi/blocklocator_clone_test.go b/domain/consensus/model/externalapi/blocklocator_clone_test.go
index 149a51b2..28e90768 100644
--- a/domain/consensus/model/externalapi/blocklocator_clone_test.go
+++ b/domain/consensus/model/externalapi/blocklocator_clone_test.go
@@ -8,48 +8,57 @@ import (
 func initTestBlockLocatorForClone() []*BlockLocator {
 
 	tests := []*BlockLocator{{
-
-		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		NewDomainHashFromByteArray(&[DomainHashSize]byte{
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
-		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}),
+		NewDomainHashFromByteArray(&[DomainHashSize]byte{
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
-		{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
+		NewDomainHashFromByteArray(&[DomainHashSize]byte{
+			0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
-		{0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}),
+		NewDomainHashFromByteArray(&[DomainHashSize]byte{
+			0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04},
-		{0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04}),
+		NewDomainHashFromByteArray(&[DomainHashSize]byte{
+			0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF},
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}),
 	}, {
-		{0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		NewDomainHashFromByteArray(&[DomainHashSize]byte{
+			0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF},
-		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}),
+		NewDomainHashFromByteArray(&[DomainHashSize]byte{
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2},
-		{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2}),
+		NewDomainHashFromByteArray(&[DomainHashSize]byte{
+			0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1},
-		{0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1}),
+		NewDomainHashFromByteArray(&[DomainHashSize]byte{
+			0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1, 1},
-		{0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1, 1}),
+		NewDomainHashFromByteArray(&[DomainHashSize]byte{
+			0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2, 1},
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2, 1}),
 	},
 	}
 	return tests
diff --git a/domain/consensus/model/externalapi/equal_test.go b/domain/consensus/model/externalapi/equal_test.go
index 4ccd2450..cc4797a0 100644
--- a/domain/consensus/model/externalapi/equal_test.go
+++ b/domain/consensus/model/externalapi/equal_test.go
@@ -24,10 +24,10 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
 				{
 					header: &DomainBlockHeader{
 						0,
-						[]*DomainHash{{0}},
-						DomainHash{1},
-						DomainHash{2},
-						DomainHash{3},
+						[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{0})},
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{1}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
 						4,
 						5,
 						6,
@@ -39,10 +39,10 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
 		{
 			baseHeader: &DomainBlockHeader{
 				0,
-				[]*DomainHash{{1}},
-				DomainHash{2},
-				DomainHash{3},
-				DomainHash{4},
+				[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{1})},
+				*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+				*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
+				*NewDomainHashFromByteArray(&[DomainHashSize]byte{4}),
 				5,
 				6,
 				7,
@@ -55,10 +55,10 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
 				{
 					header: &DomainBlockHeader{
 						0,
-						[]*DomainHash{{1}},
-						DomainHash{2},
-						DomainHash{3},
-						DomainHash{4},
+						[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{1})},
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{4}),
 						5,
 						6,
 						7,
@@ -68,10 +68,10 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
 				{
 					header: &DomainBlockHeader{
 						100,
-						[]*DomainHash{{1}},
-						DomainHash{2},
-						DomainHash{3},
-						DomainHash{4},
+						[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{1})},
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{4}),
 						5,
 						6,
 						7,
@@ -81,10 +81,13 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
 				{
 					header: &DomainBlockHeader{
 						0,
-						[]*DomainHash{{1}, {2}},
-						DomainHash{2},
-						DomainHash{3},
-						DomainHash{4},
+						// []*DomainHash{{1}, {2}},
+						[]*DomainHash{
+							NewDomainHashFromByteArray(&[DomainHashSize]byte{1}),
+							NewDomainHashFromByteArray(&[DomainHashSize]byte{2})},
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{4}),
 						5,
 						6,
 						7,
@@ -94,10 +97,10 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
 				{
 					header: &DomainBlockHeader{
 						0,
-						[]*DomainHash{{100}},
-						DomainHash{2},
-						DomainHash{3},
-						DomainHash{4},
+						[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{100})},
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{4}),
 						5,
 						6,
 						7,
@@ -107,10 +110,10 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
 				{
 					header: &DomainBlockHeader{
 						0,
-						[]*DomainHash{{1}},
-						DomainHash{100},
-						DomainHash{3},
-						DomainHash{4},
+						[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{1})},
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{100}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{4}),
 						5,
 						6,
 						7,
@@ -120,10 +123,10 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
 				{
 					header: &DomainBlockHeader{
 						0,
-						[]*DomainHash{{1}},
-						DomainHash{2},
-						DomainHash{100},
-						DomainHash{4},
+						[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{1})},
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{100}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{4}),
 						5,
 						6,
 						7,
@@ -133,10 +136,10 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
 				{
 					header: &DomainBlockHeader{
 						0,
-						[]*DomainHash{{1}},
-						DomainHash{2},
-						DomainHash{3},
-						DomainHash{100},
+						[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{1})},
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{100}),
 						5,
 						6,
 						7,
@@ -146,10 +149,10 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
 				{
 					header: &DomainBlockHeader{
 						0,
-						[]*DomainHash{{1}},
-						DomainHash{2},
-						DomainHash{3},
-						DomainHash{4},
+						[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{1})},
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{4}),
 						100,
 						6,
 						7,
@@ -159,10 +162,10 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
 				{
 					header: &DomainBlockHeader{
 						0,
-						[]*DomainHash{{1}},
-						DomainHash{2},
-						DomainHash{3},
-						DomainHash{4},
+						[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{1})},
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{4}),
 						5,
 						100,
 						7,
@@ -172,10 +175,10 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
 				{
 					header: &DomainBlockHeader{
 						0,
-						[]*DomainHash{{1}},
-						DomainHash{2},
-						DomainHash{3},
-						DomainHash{4},
+						[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{1})},
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
+						*NewDomainHashFromByteArray(&[DomainHashSize]byte{4}),
 						5,
 						6,
 						100,
@@ -205,10 +208,10 @@ func TestDomainBlockHeader_Clone(t *testing.T) {
 	headers := []*DomainBlockHeader{
 		{
 			0,
-			[]*DomainHash{{0}},
-			DomainHash{1},
-			DomainHash{2},
-			DomainHash{3},
+			[]*DomainHash{NewDomainHashFromByteArray(&[DomainHashSize]byte{0})},
+			*NewDomainHashFromByteArray(&[DomainHashSize]byte{1}),
+			*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+			*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
 			4,
 			5,
 			6,
@@ -216,9 +219,9 @@ func TestDomainBlockHeader_Clone(t *testing.T) {
 		{
 			0,
 			[]*DomainHash{},
-			DomainHash{1},
-			DomainHash{2},
-			DomainHash{3},
+			*NewDomainHashFromByteArray(&[DomainHashSize]byte{1}),
+			*NewDomainHashFromByteArray(&[DomainHashSize]byte{2}),
+			*NewDomainHashFromByteArray(&[DomainHashSize]byte{3}),
 			4,
 			5,
 			6,
diff --git a/domain/consensus/model/externalapi/hash_clone_equal_test.go b/domain/consensus/model/externalapi/hash_clone_equal_test.go
index 89e2c844..7e47b035 100644
--- a/domain/consensus/model/externalapi/hash_clone_equal_test.go
+++ b/domain/consensus/model/externalapi/hash_clone_equal_test.go
@@ -1,38 +1,9 @@
 package externalapi
 
 import (
-	"reflect"
 	"testing"
 )
 
-func initTestDomainHashForClone() []*DomainHash {
-
-	tests := []*DomainHash{
-
-		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
-		{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-		{0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-		{0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF},
-	}
-	return tests
-}
-
 type testHashToCompare struct {
 	hash           *DomainHash
 	expectedResult bool
@@ -52,33 +23,37 @@ func initTestDomainHashForEqual() []*testHashStruct {
 					hash:           nil,
 					expectedResult: true,
 				}, {
-					hash: &DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					hash: NewDomainHashFromByteArray(&[DomainHashSize]byte{
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 					expectedResult: false,
 				},
 			},
 		}, {
-			baseHash: &DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			baseHash: NewDomainHashFromByteArray(&[DomainHashSize]byte{
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}),
 			hashesToCompareTo: []testHashToCompare{
 				{
 					hash:           nil,
 					expectedResult: false,
 				}, {
-					hash: &DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					hash: NewDomainHashFromByteArray(&[DomainHashSize]byte{
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 					expectedResult: false,
 				}, {
-					hash: &DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					hash: NewDomainHashFromByteArray(&[DomainHashSize]byte{
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF},
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}),
 					expectedResult: true,
 				},
 			},
@@ -88,7 +63,6 @@ func initTestDomainHashForEqual() []*testHashStruct {
 }
 
 func TestDomainHash_Equal(t *testing.T) {
-
 	hashTests := initTestDomainHashForEqual()
 	for i, test := range hashTests {
 		for j, subTest := range test.hashesToCompareTo {
@@ -103,17 +77,3 @@ func TestDomainHash_Equal(t *testing.T) {
 		}
 	}
 }
-
-func TestDomainHash_Clone(t *testing.T) {
-
-	hashes := initTestDomainHashForClone()
-	for i, hash := range hashes {
-		hashClone := hash.Clone()
-		if !hashClone.Equal(hash) {
-			t.Fatalf("Test #%d:[Equal] clone should be equal to the original", i)
-		}
-		if !reflect.DeepEqual(hash, hashClone) {
-			t.Fatalf("Test #%d:[DeepEqual] clone should be equal to the original", i)
-		}
-	}
-}
diff --git a/domain/consensus/model/externalapi/transaction_equal_clone_test.go b/domain/consensus/model/externalapi/transaction_equal_clone_test.go
index 9a6c6e7b..43f3d3d8 100644
--- a/domain/consensus/model/externalapi/transaction_equal_clone_test.go
+++ b/domain/consensus/model/externalapi/transaction_equal_clone_test.go
@@ -1,10 +1,11 @@
 package externalapi_test
 
 import (
-	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
-	"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
 	"reflect"
 	"testing"
+
+	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
+	"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
 )
 
 // Changed fields of a test struct compared to a base test struct marked as "changed" and
@@ -66,7 +67,7 @@ func initTestBaseTransaction() *externalapi.DomainTransaction {
 	testTx := &externalapi.DomainTransaction{
 		1,
 		[]*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-			externalapi.DomainTransactionID{0x01}, 0xFFFF},
+			*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 			[]byte{1, 2, 3},
 			uint64(0xFFFFFFFF),
 			utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -77,17 +78,17 @@ func initTestBaseTransaction() *externalapi.DomainTransaction {
 		1,
 		externalapi.DomainSubnetworkID{0x01},
 		1,
-		externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 		[]byte{0x01},
 		0,
 		1,
-		&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 	}
 	return testTx
 }
@@ -98,7 +99,7 @@ func initTestTransactionToCompare() []*transactionToCompare {
 		tx: &externalapi.DomainTransaction{
 			1,
 			[]*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-				externalapi.DomainTransactionID{0x01}, 0xFFFF},
+				*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 				[]byte{1, 2, 3},
 				uint64(0xFFFFFFFF),
 				utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -109,24 +110,24 @@ func initTestTransactionToCompare() []*transactionToCompare {
 			1,
 			externalapi.DomainSubnetworkID{0x01},
 			1,
-			externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, //Changed
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}), //Changed
 			[]byte{0x01},
 			0,
 			1,
-			&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 		},
 		expectedResult: false,
 	}, {
 		tx: &externalapi.DomainTransaction{
 			1,
 			[]*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-				externalapi.DomainTransactionID{0x01}, 0xFFFF},
+				*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 				[]byte{1, 2, 3},
 				uint64(0xFFFFFFFF),
 				utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -137,24 +138,24 @@ func initTestTransactionToCompare() []*transactionToCompare {
 			1,
 			externalapi.DomainSubnetworkID{0x01},
 			1,
-			externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 			[]byte{0x01},
 			0,
 			1,
-			&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 		},
 		expectedResult: false,
 	}, {
 		tx: &externalapi.DomainTransaction{
 			1,
 			[]*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-				externalapi.DomainTransactionID{0x01}, 0xFFFF},
+				*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 				[]byte{1, 2, 3},
 				uint64(0xFFFFFFFF),
 				utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -165,24 +166,24 @@ func initTestTransactionToCompare() []*transactionToCompare {
 			1,
 			externalapi.DomainSubnetworkID{0x01, 0x02}, //Changed
 			1,
-			externalapi.DomainHash{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 			[]byte{0x01},
 			0,
 			1,
-			&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 		},
 		expectedResult: false,
 	}, {
 		tx: &externalapi.DomainTransaction{
 			1,
 			[]*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-				externalapi.DomainTransactionID{0x01}, 0xFFFF},
+				*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 				[]byte{1, 2, 3},
 				uint64(0xFFFFFFFF),
 				utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -193,24 +194,24 @@ func initTestTransactionToCompare() []*transactionToCompare {
 			1,
 			externalapi.DomainSubnetworkID{0x01},
 			1,
-			externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 			[]byte{0x01, 0x02}, //Changed
 			0,
 			1,
-			&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 		},
 		expectedResult: false,
 	}, {
 		tx: &externalapi.DomainTransaction{
 			1,
 			[]*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-				externalapi.DomainTransactionID{0x01}, 0xFFFF},
+				*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 				[]byte{1, 2, 3},
 				uint64(0xFFFFFFFF),
 				utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -220,17 +221,17 @@ func initTestTransactionToCompare() []*transactionToCompare {
 			1,
 			externalapi.DomainSubnetworkID{0x01},
 			1,
-			externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 			[]byte{0x01},
 			0,
 			1,
-			&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 		},
 		expectedResult: true,
 	},
@@ -239,7 +240,7 @@ func initTestTransactionToCompare() []*transactionToCompare {
 			tx: &externalapi.DomainTransaction{
 				1,
 				[]*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-					externalapi.DomainTransactionID{0x01}, 0xFFFF},
+					*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 					[]byte{1, 2, 3},
 					uint64(0xFFFFFFFF),
 					utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -249,17 +250,17 @@ func initTestTransactionToCompare() []*transactionToCompare {
 				1,
 				externalapi.DomainSubnetworkID{0x01},
 				1,
-				externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 				[]byte{0x01},
 				0,
 				1,
-				&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}),
 			},
 			expectsPanic: true,
 		},
@@ -267,7 +268,7 @@ func initTestTransactionToCompare() []*transactionToCompare {
 			tx: &externalapi.DomainTransaction{
 				1,
 				[]*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-					externalapi.DomainTransactionID{0x01}, 0xFFFF},
+					*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 					[]byte{1, 2, 3},
 					uint64(0xFFFFFFFF),
 					utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -278,24 +279,24 @@ func initTestTransactionToCompare() []*transactionToCompare {
 				1,
 				externalapi.DomainSubnetworkID{0x01},
 				1,
-				externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 				[]byte{0x01},
 				1000000000, //Changed
 				1,
-				&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 			},
 			expectedResult: false,
 		}, {
 			tx: &externalapi.DomainTransaction{
 				2, //Changed
 				[]*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-					externalapi.DomainTransactionID{0x01}, 0xFFFF},
+					*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 					[]byte{1, 2, 3},
 					uint64(0xFFFFFFFF),
 					utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -305,24 +306,24 @@ func initTestTransactionToCompare() []*transactionToCompare {
 				1,
 				externalapi.DomainSubnetworkID{0x01},
 				1,
-				externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 				[]byte{0x01},
 				0,
 				1,
-				&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 			}, //6
 			expectedResult: false,
 		}, {
 			tx: &externalapi.DomainTransaction{
 				1,
 				[]*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-					externalapi.DomainTransactionID{0x01}, 0xFFFF},
+					*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 					[]byte{1, 2, 3},
 					uint64(0xFFFFFFFF),
 					utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -332,24 +333,24 @@ func initTestTransactionToCompare() []*transactionToCompare {
 				1,
 				externalapi.DomainSubnetworkID{0x01},
 				1,
-				externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 				[]byte{0x01},
 				0,
 				2, //Changed
-				&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}),
 			}, //7
 			expectedResult: false,
 		}, {
 			tx: &externalapi.DomainTransaction{
 				1,
 				[]*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-					externalapi.DomainTransactionID{0x01}, 0xFFFF},
+					*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 					[]byte{1, 2, 3},
 					uint64(0xFFFFFFFF),
 					utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -359,29 +360,29 @@ func initTestTransactionToCompare() []*transactionToCompare {
 				2, //Changed
 				externalapi.DomainSubnetworkID{0x01},
 				1,
-				externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 				[]byte{0x01},
 				0,
 				1,
-				&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 			},
 			expectedResult: false,
 		}, {
 			tx: &externalapi.DomainTransaction{
 				1,
 				[]*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-					externalapi.DomainTransactionID{0x01}, 0xFFFF},
+					*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 					[]byte{1, 2, 3},
 					uint64(0xFFFFFFFF),
 					utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)},
 					{externalapi.DomainOutpoint{
-						externalapi.DomainTransactionID{0x01}, 0xFFFF},
+						*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 						[]byte{1, 2, 3},
 						uint64(0xFFFFFFFF),
 						utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -391,24 +392,24 @@ func initTestTransactionToCompare() []*transactionToCompare {
 				1,
 				externalapi.DomainSubnetworkID{0x01},
 				1,
-				externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 				[]byte{0x01},
 				0,
 				1,
-				&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 			},
 			expectedResult: false,
 		}, {
 			tx: &externalapi.DomainTransaction{
 				1,
 				[]*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-					externalapi.DomainTransactionID{0x01}, 0xFFFF},
+					*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 					[]byte{1, 2, 3},
 					uint64(0xFFFFFFFF),
 					utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -419,24 +420,24 @@ func initTestTransactionToCompare() []*transactionToCompare {
 				1,
 				externalapi.DomainSubnetworkID{0x01},
 				1,
-				externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 				[]byte{0x01},
 				0,
 				1,
-				&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 			},
 			expectedResult: false,
 		}, {
 			tx: &externalapi.DomainTransaction{
 				1,
 				[]*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-					externalapi.DomainTransactionID{0x01}, 0xFFFF},
+					*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 					[]byte{1, 2, 3},
 					uint64(0xFFFFFFFF),
 					utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
@@ -446,10 +447,10 @@ func initTestTransactionToCompare() []*transactionToCompare {
 				1,
 				externalapi.DomainSubnetworkID{0x01},
 				1,
-				externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 				[]byte{0x01},
 				0,
 				1,
@@ -460,7 +461,7 @@ func initTestTransactionToCompare() []*transactionToCompare {
 			tx: &externalapi.DomainTransaction{
 				1,
 				[]*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
-					externalapi.DomainTransactionID{0x01}, 0xFFFF},
+					*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 					[]byte{1, 2, 3},
 					uint64(0xFFFFFFFF),
 					utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3, 4}, true, 2)}},
@@ -470,17 +471,17 @@ func initTestTransactionToCompare() []*transactionToCompare {
 				1,
 				externalapi.DomainSubnetworkID{0x01},
 				1,
-				externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 				[]byte{0x01},
 				0,
 				1,
-				&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 			},
 			expectedResult: false,
 		},
@@ -495,7 +496,7 @@ func initTestDomainTransactionForClone() []*externalapi.DomainTransaction {
 			Version: 1,
 			Inputs: []*externalapi.DomainTransactionInput{
 				{externalapi.DomainOutpoint{
-					externalapi.DomainTransactionID{0x01}, 0xFFFF},
+					*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 					[]byte{1, 2, 3},
 					uint64(0xFFFFFFFF),
 					utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)},
@@ -505,17 +506,17 @@ func initTestDomainTransactionForClone() []*externalapi.DomainTransaction {
 			LockTime:     1,
 			SubnetworkID: externalapi.DomainSubnetworkID{0x01},
 			Gas:          1,
-			PayloadHash: externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			PayloadHash: *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}),
 			Payload: []byte{0x01},
 			Fee:     5555555555,
 			Mass:    1,
-			ID: &externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			ID: externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 		}, {
 			Version:      1,
 			Inputs:       []*externalapi.DomainTransactionInput{},
@@ -523,14 +524,14 @@ func initTestDomainTransactionForClone() []*externalapi.DomainTransaction {
 			LockTime:     1,
 			SubnetworkID: externalapi.DomainSubnetworkID{0x01},
 			Gas:          1,
-			PayloadHash: externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			PayloadHash: *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}),
 			Payload: []byte{0x01},
 			Fee:     0,
 			Mass:    1,
-			ID:      &externalapi.DomainTransactionID{},
+			ID:      externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{}),
 		},
 	}
 	return tests
@@ -553,17 +554,17 @@ func initTestDomainTransactionForEqual() []testDomainTransactionStruct {
 					1,
 					externalapi.DomainSubnetworkID{0x01},
 					1,
-					externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 					[]byte{0x01},
 					0,
 					1,
-					&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 				},
 				expectedResult: false,
 			}, {
@@ -577,17 +578,17 @@ func initTestDomainTransactionForEqual() []testDomainTransactionStruct {
 				1,
 				externalapi.DomainSubnetworkID{0x01},
 				1,
-				externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 				[]byte{0x01},
 				0,
 				1,
-				&externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 			},
 			transactionToCompareTo: []*transactionToCompare{{
 				tx:             nil,
@@ -600,10 +601,10 @@ func initTestDomainTransactionForEqual() []testDomainTransactionStruct {
 					1,
 					externalapi.DomainSubnetworkID{0x01},
 					0,
-					externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 					[]byte{0x01},
 					0,
 					1,
@@ -618,10 +619,10 @@ func initTestDomainTransactionForEqual() []testDomainTransactionStruct {
 					1,
 					externalapi.DomainSubnetworkID{0x01},
 					1,
-					externalapi.DomainHash{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					*externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
 					[]byte{0x01},
 					0,
 					1,
@@ -636,7 +637,7 @@ func initTestDomainTransactionForEqual() []testDomainTransactionStruct {
 
 func initTestBaseDomainTransactionInput() *externalapi.DomainTransactionInput {
 	basetxInput := &externalapi.DomainTransactionInput{
-		externalapi.DomainOutpoint{externalapi.DomainTransactionID{0x01}, 0xFFFF},
+		externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 		[]byte{1, 2, 3},
 		uint64(0xFFFFFFFF),
 		utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2),
@@ -647,7 +648,7 @@ func initTestBaseDomainTransactionInput() *externalapi.DomainTransactionInput {
 func initTestDomainTxInputToCompare() []*transactionInputToCompare {
 	txInput := []*transactionInputToCompare{{
 		tx: &externalapi.DomainTransactionInput{
-			externalapi.DomainOutpoint{externalapi.DomainTransactionID{0x01}, 0xFFFF},
+			externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 			[]byte{1, 2, 3},
 			uint64(0xFFFFFFFF),
 			utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2),
@@ -655,7 +656,7 @@ func initTestDomainTxInputToCompare() []*transactionInputToCompare {
 		expectedResult: true,
 	}, {
 		tx: &externalapi.DomainTransactionInput{
-			externalapi.DomainOutpoint{externalapi.DomainTransactionID{0x01}, 0xFFFF},
+			externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 			[]byte{1, 2, 3},
 			uint64(0xFFFFFFFF),
 			utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, false, 2), // Changed
@@ -663,7 +664,7 @@ func initTestDomainTxInputToCompare() []*transactionInputToCompare {
 		expectedResult: false,
 	}, {
 		tx: &externalapi.DomainTransactionInput{
-			externalapi.DomainOutpoint{externalapi.DomainTransactionID{0x01}, 0xFFFF},
+			externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 			[]byte{1, 2, 3},
 			uint64(0xFFFFFFF0), // Changed
 			utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2),
@@ -671,7 +672,7 @@ func initTestDomainTxInputToCompare() []*transactionInputToCompare {
 		expectedResult: false,
 	}, {
 		tx: &externalapi.DomainTransactionInput{
-			externalapi.DomainOutpoint{externalapi.DomainTransactionID{0x01}, 0xFFFF},
+			externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 			[]byte{1, 2, 3, 4}, // Changed
 			uint64(0xFFFFFFFF),
 			utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2),
@@ -679,7 +680,7 @@ func initTestDomainTxInputToCompare() []*transactionInputToCompare {
 		expectedResult: false,
 	}, {
 		tx: &externalapi.DomainTransactionInput{
-			externalapi.DomainOutpoint{externalapi.DomainTransactionID{0x01, 0x02}, 0xFFFF}, // Changed
+			externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01, 0x02}), 0xFFFF}, // Changed
 			[]byte{1, 2, 3},
 			uint64(0xFFFFFFF0), // Changed
 			utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2),
@@ -687,7 +688,7 @@ func initTestDomainTxInputToCompare() []*transactionInputToCompare {
 		expectedResult: false,
 	}, {
 		tx: &externalapi.DomainTransactionInput{
-			externalapi.DomainOutpoint{externalapi.DomainTransactionID{0x01, 0x02}, 0xFFFF}, // Changed
+			externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01, 0x02}), 0xFFFF}, // Changed
 			[]byte{1, 2, 3},
 			uint64(0xFFFFFFF0), // Changed
 			utxo.NewUTXOEntry(2 /* Changed */, []byte{0, 1, 2, 3}, true, 2), // Changed
@@ -695,7 +696,7 @@ func initTestDomainTxInputToCompare() []*transactionInputToCompare {
 		expectedResult: false,
 	}, {
 		tx: &externalapi.DomainTransactionInput{
-			externalapi.DomainOutpoint{externalapi.DomainTransactionID{0x01, 0x02}, 0xFFFF}, // Changed
+			externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01, 0x02}), 0xFFFF}, // Changed
 			[]byte{1, 2, 3},
 			uint64(0xFFFFFFF0), // Changed
 			utxo.NewUTXOEntry(3 /* Changed */, []byte{0, 1, 2, 3}, true, 3), // Changed
@@ -712,19 +713,19 @@ func initTestDomainTxInputToCompare() []*transactionInputToCompare {
 func initTestDomainTransactionInputForClone() []*externalapi.DomainTransactionInput {
 	txInput := []*externalapi.DomainTransactionInput{
 		{
-			externalapi.DomainOutpoint{externalapi.DomainTransactionID{0x01}, 0xFFFF},
+			externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 			[]byte{1, 2, 3},
 			uint64(0xFFFFFFFF),
 			utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2),
 		}, {
 
-			externalapi.DomainOutpoint{externalapi.DomainTransactionID{0x01}, 0xFFFF},
+			externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 			[]byte{1, 2, 3},
 			uint64(0xFFFFFFFF),
 			utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2),
 		}, {
 
-			externalapi.DomainOutpoint{externalapi.DomainTransactionID{0x01}, 0xFFFF},
+			externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
 			[]byte{1, 2, 3},
 			uint64(0xFFFFFFF0),
 			utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2),
@@ -954,10 +955,10 @@ func TestDomainTransactionOutput_Clone(t *testing.T) {
 
 func initTestDomainOutpointForClone() []*externalapi.DomainOutpoint {
 	outpoint := []*externalapi.DomainOutpoint{{
-		externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}),
 		1},
 	}
 	return outpoint
@@ -967,43 +968,43 @@ func initTestDomainOutpointForEqual() []testDomainOutpointStruct {
 
 	var outpoint = []*domainOutpointToCompare{{
 		domainOutpoint: &externalapi.DomainOutpoint{
-			externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 			1},
 		expectedResult: true,
 	}, {
 		domainOutpoint: &externalapi.DomainOutpoint{
-			externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}),
 			1},
 		expectedResult: false,
 	}, {
 		domainOutpoint: &externalapi.DomainOutpoint{
-			externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0}),
 			2},
 		expectedResult: false,
 	}}
 	tests := []testDomainOutpointStruct{
 		{
 			baseDomainOutpoint: &externalapi.DomainOutpoint{
-				externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 				1},
 			domainOutpointToCompareTo: outpoint,
 		}, {baseDomainOutpoint: &externalapi.DomainOutpoint{
-			externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 			1},
 			domainOutpointToCompareTo: []*domainOutpointToCompare{{domainOutpoint: nil, expectedResult: false}},
 		}, {baseDomainOutpoint: nil,
@@ -1044,56 +1045,41 @@ func TestDomainOutpoint_Clone(t *testing.T) {
 	}
 }
 
-func initTestDomainTransactionIDForClone() []*externalapi.DomainTransactionID {
-	outpoint := []*externalapi.DomainTransactionID{
-		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
-		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
-	}
-
-	return outpoint
-}
-
 func initTestDomainTransactionIDForEqual() []testDomainTransactionIDStruct {
 
 	var outpoint = []*domainTransactionIDToCompare{{
-		domainTransactionID: &externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		domainTransactionID: externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 		expectedResult: true,
 	}, {
-		domainTransactionID: &externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		domainTransactionID: externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}),
 		expectedResult: false,
 	}, {
-		domainTransactionID: &externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		domainTransactionID: externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0},
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0}),
 		expectedResult: false,
 	}}
 	tests := []testDomainTransactionIDStruct{
 		{
-			baseDomainTransactionID: &externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			baseDomainTransactionID: externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
 			domainTransactionIDToCompareTo: outpoint,
 		}, {
 			baseDomainTransactionID: nil,
 			domainTransactionIDToCompareTo: []*domainTransactionIDToCompare{{
-				domainTransactionID: &externalapi.DomainTransactionID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				domainTransactionID: externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}),
 				expectedResult: false,
 			}},
 		},
@@ -1102,7 +1088,6 @@ func initTestDomainTransactionIDForEqual() []testDomainTransactionIDStruct {
 }
 
 func TestDomainTransactionID_Equal(t *testing.T) {
-
 	domainDomainTransactionIDs := initTestDomainTransactionIDForEqual()
 	for i, test := range domainDomainTransactionIDs {
 		for j, subTest := range test.domainTransactionIDToCompareTo {
@@ -1117,17 +1102,3 @@ func TestDomainTransactionID_Equal(t *testing.T) {
 		}
 	}
 }
-
-func TestDomainTransactionID_Clone(t *testing.T) {
-
-	domainDomainTransactionIDs := initTestDomainTransactionIDForClone()
-	for i, domainTransactionID := range domainDomainTransactionIDs {
-		domainTransactionIDClone := domainTransactionID.Clone()
-		if !domainTransactionIDClone.Equal(domainTransactionID) {
-			t.Fatalf("Test #%d:[Equal] clone should be equal to the original", i)
-		}
-		if !reflect.DeepEqual(domainTransactionID, domainTransactionIDClone) {
-			t.Fatalf("Test #%d:[DeepEqual] clone should be equal to the original", i)
-		}
-	}
-}
diff --git a/domain/consensus/model/reachabilitydata_equal_clone_test.go b/domain/consensus/model/reachabilitydata_equal_clone_test.go
index 408981ec..a4251ddf 100644
--- a/domain/consensus/model/reachabilitydata_equal_clone_test.go
+++ b/domain/consensus/model/reachabilitydata_equal_clone_test.go
@@ -1,9 +1,10 @@
 package model
 
 import (
-	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
 	"reflect"
 	"testing"
+
+	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
 )
 
 func TestReachabilityData_Equal(t *testing.T) {
@@ -45,7 +46,10 @@ func TestReachabilityData_Equal(t *testing.T) {
 				{
 					data: &ReachabilityData{
 						&ReachabilityTreeNode{
-							[]*externalapi.DomainHash{{1}, {2}}, // Changed
+							[]*externalapi.DomainHash{
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
+							}, // Changed
 							&externalapi.DomainHash{},
 							&ReachabilityInterval{},
 						},
@@ -57,7 +61,7 @@ func TestReachabilityData_Equal(t *testing.T) {
 					data: &ReachabilityData{
 						&ReachabilityTreeNode{
 							[]*externalapi.DomainHash{},
-							&externalapi.DomainHash{1}, // Changed
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}), // Changed
 							&ReachabilityInterval{},
 						},
 						FutureCoveringTreeNodeSet{},
@@ -93,7 +97,9 @@ func TestReachabilityData_Equal(t *testing.T) {
 							&externalapi.DomainHash{},
 							&ReachabilityInterval{},
 						},
-						FutureCoveringTreeNodeSet{{1}, {2}}, // Changed
+						FutureCoveringTreeNodeSet{
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2})}, // Changed
 					},
 					expectedResult: false,
 				},
@@ -103,29 +109,42 @@ func TestReachabilityData_Equal(t *testing.T) {
 		{
 			baseData: &ReachabilityData{
 				&ReachabilityTreeNode{
-					[]*externalapi.DomainHash{{1}, {2}, {3}},
-					&externalapi.DomainHash{1},
+					[]*externalapi.DomainHash{
+						externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+						externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
+						externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3})},
+					externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 					&ReachabilityInterval{100, 200},
 				},
-				FutureCoveringTreeNodeSet{{1}, {2}},
+				FutureCoveringTreeNodeSet{
+					externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+					externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2})},
 			},
 			dataToCompareTo: []dataToCompare{
 				{
 					data: &ReachabilityData{
 						&ReachabilityTreeNode{
-							[]*externalapi.DomainHash{{1}, {2}, {3}},
-							&externalapi.DomainHash{1},
+							[]*externalapi.DomainHash{
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3})},
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 							&ReachabilityInterval{100, 200},
 						},
-						FutureCoveringTreeNodeSet{{1}, {2}},
+						FutureCoveringTreeNodeSet{
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2})},
 					},
 					expectedResult: true,
 				},
 				{
 					data: &ReachabilityData{
 						&ReachabilityTreeNode{
-							[]*externalapi.DomainHash{{1}, {2}, {3}},
-							&externalapi.DomainHash{1},
+							[]*externalapi.DomainHash{
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3})},
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 							&ReachabilityInterval{100, 200},
 						},
 						FutureCoveringTreeNodeSet{}, // Changed
@@ -135,33 +154,48 @@ func TestReachabilityData_Equal(t *testing.T) {
 				{
 					data: &ReachabilityData{
 						&ReachabilityTreeNode{
-							[]*externalapi.DomainHash{{1}, {2}, {3}},
-							&externalapi.DomainHash{1},
+							[]*externalapi.DomainHash{
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3})},
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 							&ReachabilityInterval{200, 200}, // Changed start
 						},
-						FutureCoveringTreeNodeSet{{1}, {2}},
+						FutureCoveringTreeNodeSet{
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2})},
 					},
 					expectedResult: false,
 				},
 				{
 					data: &ReachabilityData{
 						&ReachabilityTreeNode{
-							[]*externalapi.DomainHash{{1}, {2}, {3}},
-							&externalapi.DomainHash{1},
+							[]*externalapi.DomainHash{
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3})},
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 							nil, //Changed
 						},
-						FutureCoveringTreeNodeSet{{1}, {2}},
+						FutureCoveringTreeNodeSet{
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2})},
 					},
 					expectedResult: false,
 				},
 				{
 					data: &ReachabilityData{
 						&ReachabilityTreeNode{
-							[]*externalapi.DomainHash{{1}, {2}, {3}},
-							&externalapi.DomainHash{1},
+							[]*externalapi.DomainHash{
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3})},
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 							&ReachabilityInterval{100, 100}, // Changed end
 						},
-						FutureCoveringTreeNodeSet{{1}, {2}},
+						FutureCoveringTreeNodeSet{
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2})},
 					},
 					expectedResult: false,
 				},
@@ -169,40 +203,52 @@ func TestReachabilityData_Equal(t *testing.T) {
 					data: &ReachabilityData{
 						&ReachabilityTreeNode{
 							[]*externalapi.DomainHash{}, // Changed
-							&externalapi.DomainHash{1},
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 							&ReachabilityInterval{100, 200},
 						},
-						FutureCoveringTreeNodeSet{{1}, {2}},
+						FutureCoveringTreeNodeSet{
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2})},
 					},
 					expectedResult: false,
 				},
 				{
 					data: &ReachabilityData{
 						&ReachabilityTreeNode{
-							[]*externalapi.DomainHash{{1}, {2}},
+							[]*externalapi.DomainHash{
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2})},
 							&externalapi.DomainHash{}, // Changed
 							&ReachabilityInterval{100, 200},
 						},
-						FutureCoveringTreeNodeSet{{1}, {2}},
+						FutureCoveringTreeNodeSet{
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2})},
 					},
 					expectedResult: false,
 				},
 				{
 					data: &ReachabilityData{
 						&ReachabilityTreeNode{
-							[]*externalapi.DomainHash{{1}, {2}},
-							&externalapi.DomainHash{1},
+							[]*externalapi.DomainHash{
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2})},
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 							&ReachabilityInterval{}, // Changed
 						},
-						FutureCoveringTreeNodeSet{{1}, {2}},
+						FutureCoveringTreeNodeSet{
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2})},
 					},
 					expectedResult: false,
 				},
 				{
 					data: &ReachabilityData{
 						&ReachabilityTreeNode{
-							[]*externalapi.DomainHash{{1}, {2}},
-							&externalapi.DomainHash{1},
+							[]*externalapi.DomainHash{
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+								externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2})},
+							externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 							&ReachabilityInterval{100, 200},
 						},
 						FutureCoveringTreeNodeSet{}, // Changed
@@ -251,35 +297,47 @@ func TestReachabilityData_Clone(t *testing.T) {
 		},
 		{
 			&ReachabilityTreeNode{
-				[]*externalapi.DomainHash{{1}, {2}},
-				&externalapi.DomainHash{1},
+				[]*externalapi.DomainHash{
+					externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+					externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2})},
+				externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 				&ReachabilityInterval{100, 200},
 			},
-			FutureCoveringTreeNodeSet{{1}, {2}},
+			FutureCoveringTreeNodeSet{
+				externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+				externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2})},
 		},
 		{
 			&ReachabilityTreeNode{
 				[]*externalapi.DomainHash{},
-				&externalapi.DomainHash{1},
+				externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 				&ReachabilityInterval{100, 200},
 			},
-			FutureCoveringTreeNodeSet{{1}, {2}},
+			FutureCoveringTreeNodeSet{
+				externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+				externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2})},
 		},
 		{
 			&ReachabilityTreeNode{
-				[]*externalapi.DomainHash{{1}, {2}},
-				&externalapi.DomainHash{1},
+				[]*externalapi.DomainHash{
+					externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+					externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2})},
+				externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 				&ReachabilityInterval{},
 			},
-			FutureCoveringTreeNodeSet{{1}, {2}},
+			FutureCoveringTreeNodeSet{
+				externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+				externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2})},
 		},
 		{
 			&ReachabilityTreeNode{
 				[]*externalapi.DomainHash{},
-				&externalapi.DomainHash{1},
+				externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
 				&ReachabilityInterval{100, 200},
 			},
-			FutureCoveringTreeNodeSet{{1}, {2}},
+			FutureCoveringTreeNodeSet{
+				externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
+				externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2})},
 		},
 	}
 
diff --git a/domain/consensus/processes/blockbuilder/test_block_builder.go b/domain/consensus/processes/blockbuilder/test_block_builder.go
index 3248fcfa..3e3fa750 100644
--- a/domain/consensus/processes/blockbuilder/test_block_builder.go
+++ b/domain/consensus/processes/blockbuilder/test_block_builder.go
@@ -16,8 +16,8 @@ type testBlockBuilder struct {
 	nonceCounter  uint64
 }
 
-var tempBlockHash = &externalapi.DomainHash{
-	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
+var tempBlockHash = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1})
 
 // NewTestBlockBuilder creates an instance of a TestBlockBuilder
 func NewTestBlockBuilder(baseBlockBuilder model.BlockBuilder, testConsensus testapi.TestConsensus) testapi.TestBlockBuilder {
diff --git a/domain/consensus/processes/blockvalidator/block_body_in_isolation_test.go b/domain/consensus/processes/blockvalidator/block_body_in_isolation_test.go
index a3668bfd..929312b9 100644
--- a/domain/consensus/processes/blockvalidator/block_body_in_isolation_test.go
+++ b/domain/consensus/processes/blockvalidator/block_body_in_isolation_test.go
@@ -122,37 +122,37 @@ var unOrderedParentsBlock = externalapi.DomainBlock{
 	Header: &externalapi.DomainBlockHeader{
 		Version: 0x10000000,
 		ParentHashes: []*externalapi.DomainHash{
-			{
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 				0x4b, 0xb0, 0x75, 0x35, 0xdf, 0xd5, 0x8e, 0x0b,
 				0x3c, 0xd6, 0x4f, 0xd7, 0x15, 0x52, 0x80, 0x87,
 				0x2a, 0x04, 0x71, 0xbc, 0xf8, 0x30, 0x95, 0x52,
 				0x6a, 0xce, 0x0e, 0x38, 0xc6, 0x00, 0x00, 0x00,
-			},
-			{
+			}),
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 				0x16, 0x5e, 0x38, 0xe8, 0xb3, 0x91, 0x45, 0x95,
 				0xd9, 0xc6, 0x41, 0xf3, 0xb8, 0xee, 0xc2, 0xf3,
 				0x46, 0x11, 0x89, 0x6b, 0x82, 0x1a, 0x68, 0x3b,
 				0x7a, 0x4e, 0xde, 0xfe, 0x2c, 0x00, 0x00, 0x00,
-			},
+			}),
 		},
-		HashMerkleRoot: externalapi.DomainHash{
+		HashMerkleRoot: *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 			0xf8, 0x55, 0x7b, 0xd0, 0xda, 0xf2, 0x06, 0x8b,
 			0x3b, 0xb1, 0x93, 0x5a, 0x2c, 0x52, 0x43, 0xf0,
 			0x02, 0xf2, 0xb1, 0x40, 0x81, 0x2c, 0x0c, 0x15,
 			0x8d, 0x04, 0x3d, 0xe2, 0x23, 0x54, 0x98, 0x88,
-		},
-		AcceptedIDMerkleRoot: externalapi.DomainHash{
+		}),
+		AcceptedIDMerkleRoot: *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 			0x80, 0xf7, 0x00, 0xe3, 0x16, 0x3d, 0x04, 0x95,
 			0x5b, 0x7e, 0xaf, 0x84, 0x7e, 0x1b, 0x6b, 0x06,
 			0x4e, 0x06, 0xba, 0x64, 0xd7, 0x61, 0xda, 0x25,
 			0x1a, 0x0e, 0x21, 0xd4, 0x64, 0x49, 0x02, 0xa2,
-		},
-		UTXOCommitment: externalapi.DomainHash{
+		}),
+		UTXOCommitment: *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 			0x80, 0xf7, 0x00, 0xe3, 0x16, 0x3d, 0x04, 0x95,
 			0x5b, 0x7e, 0xaf, 0x84, 0x7e, 0x1b, 0x6b, 0x06,
 			0x4e, 0x06, 0xba, 0x64, 0xd7, 0x61, 0xda, 0x25,
 			0x1a, 0x0e, 0x21, 0xd4, 0x64, 0x49, 0x02, 0xa2,
-		},
+		}),
 		TimeInMilliseconds: 0x5cd18053000,
 		Bits:               0x207fffff,
 		Nonce:              0x1,
@@ -163,7 +163,7 @@ var unOrderedParentsBlock = externalapi.DomainBlock{
 			Inputs: []*externalapi.DomainTransactionInput{
 				{
 					PreviousOutpoint: externalapi.DomainOutpoint{
-						TransactionID: externalapi.DomainTransactionID{},
+						TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{}),
 						Index:         0xffffffff,
 					},
 					SignatureScript: []byte{
@@ -185,19 +185,19 @@ var unOrderedParentsBlock = externalapi.DomainBlock{
 			LockTime:     0,
 			SubnetworkID: subnetworks.SubnetworkIDCoinbase,
 			Payload:      []byte{9, 0, 0, 0, 0, 0, 0, 0, 0},
-			PayloadHash: externalapi.DomainHash{
+			PayloadHash: *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 				0x31, 0x3d, 0xd5, 0x20, 0x4c, 0xc9, 0x89, 0x20,
 				0x46, 0x22, 0x59, 0xe0, 0x0d, 0x33, 0x27, 0xe6,
 				0x04, 0x20, 0x5f, 0x4e, 0xd5, 0xf4, 0xf9, 0x2f,
 				0x1a, 0xf0, 0x13, 0x0b, 0xe3, 0x92, 0xd8, 0xff,
-			},
+			}),
 		},
 		{
 			Version: 1,
 			Inputs: []*externalapi.DomainTransactionInput{
 				{
 					PreviousOutpoint: externalapi.DomainOutpoint{
-						TransactionID: externalapi.DomainTransactionID([32]byte{
+						TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 							0x03, 0x2e, 0x38, 0xe9, 0xc0, 0xa8, 0x4c, 0x60,
 							0x46, 0xd6, 0x87, 0xd1, 0x05, 0x56, 0xdc, 0xac,
 							0xc4, 0x1d, 0x27, 0x5e, 0xc5, 0x5f, 0xc0, 0x07,
@@ -267,7 +267,7 @@ var unOrderedParentsBlock = externalapi.DomainBlock{
 			Inputs: []*externalapi.DomainTransactionInput{
 				{
 					PreviousOutpoint: externalapi.DomainOutpoint{
-						TransactionID: externalapi.DomainTransactionID([32]byte{
+						TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 							0xc3, 0x3e, 0xbf, 0xf2, 0xa7, 0x09, 0xf1, 0x3d,
 							0x9f, 0x9a, 0x75, 0x69, 0xab, 0x16, 0xa3, 0x27,
 							0x86, 0xaf, 0x7d, 0x7e, 0x2d, 0xe0, 0x92, 0x65,
@@ -336,7 +336,7 @@ var unOrderedParentsBlock = externalapi.DomainBlock{
 			Inputs: []*externalapi.DomainTransactionInput{
 				{
 					PreviousOutpoint: externalapi.DomainOutpoint{
-						TransactionID: externalapi.DomainTransactionID([32]byte{
+						TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 							0x0b, 0x60, 0x72, 0xb3, 0x86, 0xd4, 0xa7, 0x73,
 							0x23, 0x52, 0x37, 0xf6, 0x4c, 0x11, 0x26, 0xac,
 							0x3b, 0x24, 0x0c, 0x84, 0xb9, 0x17, 0xa3, 0x90,
@@ -396,32 +396,32 @@ var exampleValidBlock = externalapi.DomainBlock{
 	Header: &externalapi.DomainBlockHeader{
 		Version: 0x10000000,
 		ParentHashes: []*externalapi.DomainHash{
-			{
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 				0x16, 0x5e, 0x38, 0xe8, 0xb3, 0x91, 0x45, 0x95,
 				0xd9, 0xc6, 0x41, 0xf3, 0xb8, 0xee, 0xc2, 0xf3,
 				0x46, 0x11, 0x89, 0x6b, 0x82, 0x1a, 0x68, 0x3b,
 				0x7a, 0x4e, 0xde, 0xfe, 0x2c, 0x00, 0x00, 0x00,
-			},
-			{
+			}),
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 				0x4b, 0xb0, 0x75, 0x35, 0xdf, 0xd5, 0x8e, 0x0b,
 				0x3c, 0xd6, 0x4f, 0xd7, 0x15, 0x52, 0x80, 0x87,
 				0x2a, 0x04, 0x71, 0xbc, 0xf8, 0x30, 0x95, 0x52,
 				0x6a, 0xce, 0x0e, 0x38, 0xc6, 0x00, 0x00, 0x00,
-			},
+			}),
 		},
-		HashMerkleRoot: externalapi.DomainHash{
+		HashMerkleRoot: *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 			0x33, 0x70, 0xa7, 0x40, 0x9f, 0x2d, 0x87, 0xe1,
 			0x26, 0xaf, 0x0f, 0x5c, 0x7e, 0xc3, 0x84, 0x5e,
 			0x4f, 0x68, 0x42, 0x0a, 0xbf, 0x90, 0xcd, 0xef,
 			0x94, 0x9b, 0xe1, 0x9a, 0xf7, 0xdd, 0xb0, 0xb5,
-		},
-		AcceptedIDMerkleRoot: externalapi.DomainHash{
+		}),
+		AcceptedIDMerkleRoot: *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 			0x8a, 0xb7, 0xd6, 0x73, 0x1b, 0xe6, 0xc5, 0xd3,
 			0x5d, 0x4e, 0x2c, 0xc9, 0x57, 0x88, 0x30, 0x65,
 			0x81, 0xb8, 0xa0, 0x68, 0x77, 0xc4, 0x02, 0x1e,
 			0x3c, 0xb1, 0x16, 0x8f, 0x5f, 0x6b, 0x45, 0x87,
-		},
-		UTXOCommitment:     [32]byte{},
+		}),
+		UTXOCommitment:     *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{}),
 		TimeInMilliseconds: 0x17305aa654a,
 		Bits:               0x207fffff,
 		Nonce:              1,
@@ -432,12 +432,12 @@ var exampleValidBlock = externalapi.DomainBlock{
 			Inputs: []*externalapi.DomainTransactionInput{
 				{
 					PreviousOutpoint: externalapi.DomainOutpoint{
-						TransactionID: externalapi.DomainTransactionID{
+						TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 							0x9b, 0x22, 0x59, 0x44, 0x66, 0xf0, 0xbe, 0x50,
 							0x7c, 0x1c, 0x8a, 0xf6, 0x06, 0x27, 0xe6, 0x33,
 							0x38, 0x7e, 0xd1, 0xd5, 0x8c, 0x42, 0x59, 0x1a,
 							0x31, 0xac, 0x9a, 0xa6, 0x2e, 0xd5, 0x2b, 0x0f,
-						},
+						}),
 						Index: 0xffffffff,
 					},
 					SignatureScript: nil,
@@ -457,36 +457,36 @@ var exampleValidBlock = externalapi.DomainBlock{
 			LockTime:     0,
 			SubnetworkID: subnetworks.SubnetworkIDCoinbase,
 			Payload:      []byte{9, 0, 0, 0, 0, 0, 0, 0, 0},
-			PayloadHash: externalapi.DomainHash{
+			PayloadHash: *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 				0x31, 0x3d, 0xd5, 0x20, 0x4c, 0xc9, 0x89, 0x20,
 				0x46, 0x22, 0x59, 0xe0, 0x0d, 0x33, 0x27, 0xe6,
 				0x04, 0x20, 0x5f, 0x4e, 0xd5, 0xf4, 0xf9, 0x2f,
 				0x1a, 0xf0, 0x13, 0x0b, 0xe3, 0x92, 0xd8, 0xff,
-			},
+			}),
 		},
 		{
 			Version: 1,
 			Inputs: []*externalapi.DomainTransactionInput{
 				{
 					PreviousOutpoint: externalapi.DomainOutpoint{
-						TransactionID: externalapi.DomainTransactionID{
+						TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 							0x16, 0x5e, 0x38, 0xe8, 0xb3, 0x91, 0x45, 0x95,
 							0xd9, 0xc6, 0x41, 0xf3, 0xb8, 0xee, 0xc2, 0xf3,
 							0x46, 0x11, 0x89, 0x6b, 0x82, 0x1a, 0x68, 0x3b,
 							0x7a, 0x4e, 0xde, 0xfe, 0x2c, 0x00, 0x00, 0x00,
-						},
+						}),
 						Index: 0xffffffff,
 					},
 					Sequence: math.MaxUint64,
 				},
 				{
 					PreviousOutpoint: externalapi.DomainOutpoint{
-						TransactionID: externalapi.DomainTransactionID{
+						TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 							0x4b, 0xb0, 0x75, 0x35, 0xdf, 0xd5, 0x8e, 0x0b,
 							0x3c, 0xd6, 0x4f, 0xd7, 0x15, 0x52, 0x80, 0x87,
 							0x2a, 0x04, 0x71, 0xbc, 0xf8, 0x30, 0x95, 0x52,
 							0x6a, 0xce, 0x0e, 0x38, 0xc6, 0x00, 0x00, 0x00,
-						},
+						}),
 						Index: 0xffffffff,
 					},
 					Sequence: math.MaxUint64,
@@ -499,7 +499,7 @@ var exampleValidBlock = externalapi.DomainBlock{
 			Inputs: []*externalapi.DomainTransactionInput{
 				{
 					PreviousOutpoint: externalapi.DomainOutpoint{
-						TransactionID: externalapi.DomainTransactionID([32]byte{
+						TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 							0x03, 0x2e, 0x38, 0xe9, 0xc0, 0xa8, 0x4c, 0x60,
 							0x46, 0xd6, 0x87, 0xd1, 0x05, 0x56, 0xdc, 0xac,
 							0xc4, 0x1d, 0x27, 0x5e, 0xc5, 0x5f, 0xc0, 0x07,
@@ -569,7 +569,7 @@ var exampleValidBlock = externalapi.DomainBlock{
 			Inputs: []*externalapi.DomainTransactionInput{
 				{
 					PreviousOutpoint: externalapi.DomainOutpoint{
-						TransactionID: externalapi.DomainTransactionID([32]byte{
+						TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 							0xc3, 0x3e, 0xbf, 0xf2, 0xa7, 0x09, 0xf1, 0x3d,
 							0x9f, 0x9a, 0x75, 0x69, 0xab, 0x16, 0xa3, 0x27,
 							0x86, 0xaf, 0x7d, 0x7e, 0x2d, 0xe0, 0x92, 0x65,
@@ -638,12 +638,12 @@ var exampleValidBlock = externalapi.DomainBlock{
 			Inputs: []*externalapi.DomainTransactionInput{
 				{
 					PreviousOutpoint: externalapi.DomainOutpoint{
-						TransactionID: externalapi.DomainTransactionID{
+						TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 							0x0b, 0x60, 0x72, 0xb3, 0x86, 0xd4, 0xa7, 0x73,
 							0x23, 0x52, 0x37, 0xf6, 0x4c, 0x11, 0x26, 0xac,
 							0x3b, 0x24, 0x0c, 0x84, 0xb9, 0x17, 0xa3, 0x90,
 							0x9b, 0xa1, 0xc4, 0x3d, 0xed, 0x5f, 0x51, 0xf4,
-						}, // f4515fed3dc4a19b90a317b9840c243bac26114cf637522373a7d486b372600b
+						}), // f4515fed3dc4a19b90a317b9840c243bac26114cf637522373a7d486b372600b
 						Index: 0,
 					},
 					SignatureScript: []byte{
@@ -698,37 +698,37 @@ var blockWithWrongTxOrder = externalapi.DomainBlock{
 	Header: &externalapi.DomainBlockHeader{
 		Version: 1,
 		ParentHashes: []*externalapi.DomainHash{
-			{
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 				0x16, 0x5e, 0x38, 0xe8, 0xb3, 0x91, 0x45, 0x95,
 				0xd9, 0xc6, 0x41, 0xf3, 0xb8, 0xee, 0xc2, 0xf3,
 				0x46, 0x11, 0x89, 0x6b, 0x82, 0x1a, 0x68, 0x3b,
 				0x7a, 0x4e, 0xde, 0xfe, 0x2c, 0x00, 0x00, 0x00,
-			},
-			{
+			}),
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 				0x4b, 0xb0, 0x75, 0x35, 0xdf, 0xd5, 0x8e, 0x0b,
 				0x3c, 0xd6, 0x4f, 0xd7, 0x15, 0x52, 0x80, 0x87,
 				0x2a, 0x04, 0x71, 0xbc, 0xf8, 0x30, 0x95, 0x52,
 				0x6a, 0xce, 0x0e, 0x38, 0xc6, 0x00, 0x00, 0x00,
-			},
+			}),
 		},
-		HashMerkleRoot: externalapi.DomainHash{
+		HashMerkleRoot: *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 			0xac, 0xa4, 0x21, 0xe1, 0xa6, 0xc3, 0xbe, 0x5d,
 			0x52, 0x66, 0xf3, 0x0b, 0x21, 0x87, 0xbc, 0xf3,
 			0xf3, 0x2d, 0xd1, 0x05, 0x64, 0xb5, 0x16, 0x76,
 			0xe4, 0x66, 0x7d, 0x51, 0x53, 0x18, 0x6d, 0xb1,
-		},
-		AcceptedIDMerkleRoot: externalapi.DomainHash{
+		}),
+		AcceptedIDMerkleRoot: *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 			0xa0, 0x69, 0x2d, 0x16, 0xb5, 0xd7, 0xe4, 0xf3,
 			0xcd, 0xc7, 0xc9, 0xaf, 0xfb, 0xd2, 0x1b, 0x85,
 			0x0b, 0x79, 0xf5, 0x29, 0x6d, 0x1c, 0xaa, 0x90,
 			0x2f, 0x01, 0xd4, 0x83, 0x9b, 0x2a, 0x04, 0x5e,
-		},
-		UTXOCommitment: externalapi.DomainHash{
+		}),
+		UTXOCommitment: *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 			0x00, 0x69, 0x2d, 0x16, 0xb5, 0xd7, 0xe4, 0xf3,
 			0xcd, 0xc7, 0xc9, 0xaf, 0xfb, 0xd2, 0x1b, 0x85,
 			0x0b, 0x79, 0xf5, 0x29, 0x6d, 0x1c, 0xaa, 0x90,
 			0x2f, 0x01, 0xd4, 0x83, 0x9b, 0x2a, 0x04, 0x5e,
-		},
+		}),
 		TimeInMilliseconds: 0x5cd16eaa000,
 		Bits:               0x207fffff,
 		Nonce:              1,
@@ -739,12 +739,12 @@ var blockWithWrongTxOrder = externalapi.DomainBlock{
 			Inputs: []*externalapi.DomainTransactionInput{
 				{
 					PreviousOutpoint: externalapi.DomainOutpoint{
-						TransactionID: externalapi.DomainTransactionID{
+						TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 							0x9b, 0x22, 0x59, 0x44, 0x66, 0xf0, 0xbe, 0x50,
 							0x7c, 0x1c, 0x8a, 0xf6, 0x06, 0x27, 0xe6, 0x33,
 							0x38, 0x7e, 0xd1, 0xd5, 0x8c, 0x42, 0x59, 0x1a,
 							0x31, 0xac, 0x9a, 0xa6, 0x2e, 0xd5, 0x2b, 0x0f,
-						},
+						}),
 						Index: 0xffffffff,
 					},
 					SignatureScript: nil,
@@ -764,36 +764,36 @@ var blockWithWrongTxOrder = externalapi.DomainBlock{
 			LockTime:     0,
 			SubnetworkID: subnetworks.SubnetworkIDCoinbase,
 			Payload:      []byte{9, 0, 0, 0, 0, 0, 0, 0, 0},
-			PayloadHash: externalapi.DomainHash{
+			PayloadHash: *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
 				0x31, 0x3d, 0xd5, 0x20, 0x4c, 0xc9, 0x89, 0x20,
 				0x46, 0x22, 0x59, 0xe0, 0x0d, 0x33, 0x27, 0xe6,
 				0x04, 0x20, 0x5f, 0x4e, 0xd5, 0xf4, 0xf9, 0x2f,
 				0x1a, 0xf0, 0x13, 0x0b, 0xe3, 0x92, 0xd8, 0xff,
-			},
+			}),
 		},
 		{
 			Version: 1,
 			Inputs: []*externalapi.DomainTransactionInput{
 				{
 					PreviousOutpoint: externalapi.DomainOutpoint{
-						TransactionID: externalapi.DomainTransactionID{
+						TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 							0x16, 0x5e, 0x38, 0xe8, 0xb3, 0x91, 0x45, 0x95,
 							0xd9, 0xc6, 0x41, 0xf3, 0xb8, 0xee, 0xc2, 0xf3,
 							0x46, 0x11, 0x89, 0x6b, 0x82, 0x1a, 0x68, 0x3b,
 							0x7a, 0x4e, 0xde, 0xfe, 0x2c, 0x00, 0x00, 0x00,
-						},
+						}),
 						Index: 0xffffffff,
 					},
 					Sequence: math.MaxUint64,
 				},
 				{
 					PreviousOutpoint: externalapi.DomainOutpoint{
-						TransactionID: externalapi.DomainTransactionID{
+						TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 							0x4b, 0xb0, 0x75, 0x35, 0xdf, 0xd5, 0x8e, 0x0b,
 							0x3c, 0xd6, 0x4f, 0xd7, 0x15, 0x52, 0x80, 0x87,
 							0x2a, 0x04, 0x71, 0xbc, 0xf8, 0x30, 0x95, 0x52,
 							0x6a, 0xce, 0x0e, 0x38, 0xc6, 0x00, 0x00, 0x00,
-						},
+						}),
 						Index: 0xffffffff,
 					},
 					Sequence: math.MaxUint64,
@@ -806,7 +806,7 @@ var blockWithWrongTxOrder = externalapi.DomainBlock{
 			Inputs: []*externalapi.DomainTransactionInput{
 				{
 					PreviousOutpoint: externalapi.DomainOutpoint{
-						TransactionID: externalapi.DomainTransactionID([32]byte{
+						TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 							0x03, 0x2e, 0x38, 0xe9, 0xc0, 0xa8, 0x4c, 0x60,
 							0x46, 0xd6, 0x87, 0xd1, 0x05, 0x56, 0xdc, 0xac,
 							0xc4, 0x1d, 0x27, 0x5e, 0xc5, 0x5f, 0xc0, 0x07,
@@ -871,14 +871,14 @@ var blockWithWrongTxOrder = externalapi.DomainBlock{
 			LockTime:     0,
 			SubnetworkID: externalapi.DomainSubnetworkID{11},
 			Payload:      []byte{},
-			PayloadHash:  [32]byte{0xFF, 0xFF},
+			PayloadHash:  *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0xFF, 0xFF}),
 		},
 		{
 			Version: 1,
 			Inputs: []*externalapi.DomainTransactionInput{
 				{
 					PreviousOutpoint: externalapi.DomainOutpoint{
-						TransactionID: externalapi.DomainTransactionID([32]byte{
+						TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 							0xc3, 0x3e, 0xbf, 0xf2, 0xa7, 0x09, 0xf1, 0x3d,
 							0x9f, 0x9a, 0x75, 0x69, 0xab, 0x16, 0xa3, 0x27,
 							0x86, 0xaf, 0x7d, 0x7e, 0x2d, 0xe0, 0x92, 0x65,
@@ -947,7 +947,7 @@ var blockWithWrongTxOrder = externalapi.DomainBlock{
 			Inputs: []*externalapi.DomainTransactionInput{
 				{
 					PreviousOutpoint: externalapi.DomainOutpoint{
-						TransactionID: externalapi.DomainTransactionID([32]byte{
+						TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 							0x0b, 0x60, 0x72, 0xb3, 0x86, 0xd4, 0xa7, 0x73,
 							0x23, 0x52, 0x37, 0xf6, 0x4c, 0x11, 0x26, 0xac,
 							0x3b, 0x24, 0x0c, 0x84, 0xb9, 0x17, 0xa3, 0x90,
diff --git a/domain/consensus/processes/ghostdagmanager/ghostdag_test.go b/domain/consensus/processes/ghostdagmanager/ghostdag_test.go
index 08f64b32..a05a6a29 100644
--- a/domain/consensus/processes/ghostdagmanager/ghostdag_test.go
+++ b/domain/consensus/processes/ghostdagmanager/ghostdag_test.go
@@ -56,7 +56,6 @@ func TestGHOSTDAG(t *testing.T) {
 		{ghostdag2.New, "Tal's impl"},
 	}
 	testutils.ForAllNets(t, true, func(t *testing.T, params *dagconfig.Params) {
-
 		dagTopology := &DAGTopologyManagerImpl{
 			parentsMap: make(map[externalapi.DomainHash][]*externalapi.DomainHash),
 		}
@@ -95,8 +94,7 @@ func TestGHOSTDAG(t *testing.T) {
 			}
 			params.K = test.K
 
-			var genesisHash externalapi.DomainHash
-			copy(genesisHash[:], test.GenesisID)
+			genesisHash := *StringToDomainHash(test.GenesisID)
 
 			dagTopology.parentsMap[genesisHash] = nil
 
@@ -108,10 +106,10 @@ func TestGHOSTDAG(t *testing.T) {
 				g := factory.function(nil, dagTopology, ghostdagDataStore, blockHeadersStore, test.K)
 				for _, testBlockData := range test.Blocks {
 
-					blockID := StringToByte(testBlockData.ID)
-					dagTopology.parentsMap[*blockID] = StringToByteArray(testBlockData.Parents)
+					blockID := StringToDomainHash(testBlockData.ID)
+					dagTopology.parentsMap[*blockID] = StringToDomainHashSlice(testBlockData.Parents)
 					blockHeadersStore.dagMap[*blockID] = &externalapi.DomainBlockHeader{
-						ParentHashes: StringToByteArray(testBlockData.Parents),
+						ParentHashes: StringToDomainHashSlice(testBlockData.Parents),
 						Bits:         genesisHeader.Bits,
 					}
 
@@ -137,17 +135,17 @@ func TestGHOSTDAG(t *testing.T) {
 							factory.implName, info.Name(), testBlockData.ID, testBlockData.Score, ghostdagData.BlueScore())
 					}
 
-					if !StringToByte(testBlockData.SelectedParent).Equal(ghostdagData.SelectedParent()) {
-						t.Fatalf("\nTEST FAILED:\n Impl: %s, FileName: %s \nBlock: %s, \nError: expected selected parent %v but got %v.",
-							factory.implName, info.Name(), testBlockData.ID, testBlockData.SelectedParent, string(ghostdagData.SelectedParent()[:]))
+					if !StringToDomainHash(testBlockData.SelectedParent).Equal(ghostdagData.SelectedParent()) {
+						t.Fatalf("\nTEST FAILED:\n Impl: %s, FileName: %s \nBlock: %s, \nError: expected selected parent %v but got %s.",
+							factory.implName, info.Name(), testBlockData.ID, testBlockData.SelectedParent, ghostdagData.SelectedParent())
 					}
 
-					if !reflect.DeepEqual(StringToByteArray(testBlockData.MergeSetBlues), ghostdagData.MergeSetBlues()) {
+					if !reflect.DeepEqual(StringToDomainHashSlice(testBlockData.MergeSetBlues), ghostdagData.MergeSetBlues()) {
 						t.Fatalf("\nTEST FAILED:\n Impl: %s, FileName: %s \nBlock: %s, \nError: expected merge set blues %v but got %v.",
 							factory.implName, info.Name(), testBlockData.ID, testBlockData.MergeSetBlues, hashesToStrings(ghostdagData.MergeSetBlues()))
 					}
 
-					if !reflect.DeepEqual(StringToByteArray(testBlockData.MergeSetReds), ghostdagData.MergeSetReds()) {
+					if !reflect.DeepEqual(StringToDomainHashSlice(testBlockData.MergeSetReds), ghostdagData.MergeSetReds()) {
 						t.Fatalf("\nTEST FAILED:\n Impl: %s, FileName: %s \nBlock: %s, \nError: expected merge set reds %v but got %v.",
 							factory.implName, info.Name(), testBlockData.ID, testBlockData.MergeSetReds, hashesToStrings(ghostdagData.MergeSetReds()))
 					}
@@ -175,21 +173,21 @@ func TestGHOSTDAG(t *testing.T) {
 func hashesToStrings(arr []*externalapi.DomainHash) []string {
 	var strArr = make([]string, len(arr))
 	for i, hash := range arr {
-		strArr[i] = string(hash[:])
+		strArr[i] = hash.String()
 	}
 	return strArr
 }
 
-func StringToByte(strID string) *externalapi.DomainHash {
-	var domainHash externalapi.DomainHash
-	copy(domainHash[:], strID)
-	return &domainHash
+func StringToDomainHash(strID string) *externalapi.DomainHash {
+	var genesisHashArray [externalapi.DomainHashSize]byte
+	copy(genesisHashArray[:], strID)
+	return externalapi.NewDomainHashFromByteArray(&genesisHashArray)
 }
 
-func StringToByteArray(stringIDArr []string) []*externalapi.DomainHash {
+func StringToDomainHashSlice(stringIDArr []string) []*externalapi.DomainHash {
 	domainHashArr := make([]*externalapi.DomainHash, len(stringIDArr))
 	for i, strID := range stringIDArr {
-		domainHashArr[i] = StringToByte(strID)
+		domainHashArr[i] = StringToDomainHash(strID)
 	}
 	return domainHashArr
 }
diff --git a/domain/consensus/processes/reachabilitymanager/reachability_test.go b/domain/consensus/processes/reachabilitymanager/reachability_test.go
index 0e7f36af..cb45f6ad 100644
--- a/domain/consensus/processes/reachabilitymanager/reachability_test.go
+++ b/domain/consensus/processes/reachabilitymanager/reachability_test.go
@@ -2,11 +2,12 @@ package reachabilitymanager
 
 import (
 	"encoding/binary"
-	"github.com/kaspanet/kaspad/domain/consensus/model"
-	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
 	"reflect"
 	"strings"
 	"testing"
+
+	"github.com/kaspanet/kaspad/domain/consensus/model"
+	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
 )
 
 type reachabilityDataStoreMock struct {
@@ -87,10 +88,10 @@ type testHelper struct {
 }
 
 func (th *testHelper) generateHash() *externalapi.DomainHash {
-	var hash externalapi.DomainHash
-	binary.LittleEndian.PutUint64(hash[:], th.hashCounter)
+	var hashArray [externalapi.DomainHashSize]byte
+	binary.LittleEndian.PutUint64(hashArray[:], th.hashCounter)
 	th.hashCounter++
-	return &hash
+	return externalapi.NewDomainHashFromByteArray(&hashArray)
 }
 
 func (th *testHelper) newNode() *externalapi.DomainHash {
diff --git a/domain/consensus/ruleerrors/rule_error_test.go b/domain/consensus/ruleerrors/rule_error_test.go
index 025f83ff..ebeeb517 100644
--- a/domain/consensus/ruleerrors/rule_error_test.go
+++ b/domain/consensus/ruleerrors/rule_error_test.go
@@ -8,7 +8,13 @@ import (
 )
 
 func TestNewErrMissingTxOut(t *testing.T) {
-	outer := NewErrMissingTxOut([]*externalapi.DomainOutpoint{{TransactionID: externalapi.DomainTransactionID{255, 255, 255}, Index: 5}})
+	outer := NewErrMissingTxOut(
+		[]*externalapi.DomainOutpoint{
+			{
+				TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{255, 255, 255}),
+				Index:         5,
+			},
+		})
 	expectedOuterErr := "ErrMissingTxOut: missing the following outpoint: [(ffffff0000000000000000000000000000000000000000000000000000000000: 5)]"
 	inner := &ErrMissingTxOut{}
 	if !errors.As(outer, inner) {
diff --git a/domain/consensus/utils/txscript/engine_test.go b/domain/consensus/utils/txscript/engine_test.go
index 5d0968d2..d79f855d 100644
--- a/domain/consensus/utils/txscript/engine_test.go
+++ b/domain/consensus/utils/txscript/engine_test.go
@@ -26,7 +26,7 @@ func TestBadPC(t *testing.T) {
 	inputs := []*externalapi.DomainTransactionInput{
 		{
 			PreviousOutpoint: externalapi.DomainOutpoint{
-				TransactionID: externalapi.DomainTransactionID([32]byte{
+				TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 					0xc9, 0x97, 0xa5, 0xe5,
 					0x6e, 0x10, 0x41, 0x02,
 					0xfa, 0x20, 0x9c, 0x6a,
@@ -95,7 +95,7 @@ func TestCheckErrorCondition(t *testing.T) {
 		func() {
 			inputs := []*externalapi.DomainTransactionInput{{
 				PreviousOutpoint: externalapi.DomainOutpoint{
-					TransactionID: externalapi.DomainTransactionID([32]byte{
+					TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 						0xc9, 0x97, 0xa5, 0xe5,
 						0x6e, 0x10, 0x41, 0x02,
 						0xfa, 0x20, 0x9c, 0x6a,
@@ -223,7 +223,7 @@ func TestDisasmPC(t *testing.T) {
 	// tx with almost empty scripts.
 	inputs := []*externalapi.DomainTransactionInput{{
 		PreviousOutpoint: externalapi.DomainOutpoint{
-			TransactionID: externalapi.DomainTransactionID([32]byte{
+			TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 				0xc9, 0x97, 0xa5, 0xe5,
 				0x6e, 0x10, 0x41, 0x02,
 				0xfa, 0x20, 0x9c, 0x6a,
@@ -287,7 +287,7 @@ func TestDisasmScript(t *testing.T) {
 	// tx with almost empty scripts.
 	inputs := []*externalapi.DomainTransactionInput{{
 		PreviousOutpoint: externalapi.DomainOutpoint{
-			TransactionID: externalapi.DomainTransactionID([32]byte{
+			TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 				0xc9, 0x97, 0xa5, 0xe5,
 				0x6e, 0x10, 0x41, 0x02,
 				0xfa, 0x20, 0x9c, 0x6a,
diff --git a/domain/consensus/utils/utxo/serialization_test.go b/domain/consensus/utils/utxo/serialization_test.go
index 928033fb..9ac8d901 100644
--- a/domain/consensus/utils/utxo/serialization_test.go
+++ b/domain/consensus/utils/utxo/serialization_test.go
@@ -15,12 +15,12 @@ func Benchmark_serializeUTXO(b *testing.B) {
 	}
 	entry := NewUTXOEntry(5000000000, scriptPublicKey, false, 1432432)
 	outpoint := &externalapi.DomainOutpoint{
-		TransactionID: externalapi.DomainTransactionID{
+		TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 			0x16, 0x5e, 0x38, 0xe8, 0xb3, 0x91, 0x45, 0x95,
 			0xd9, 0xc6, 0x41, 0xf3, 0xb8, 0xee, 0xc2, 0xf3,
 			0x46, 0x11, 0x89, 0x6b, 0x82, 0x1a, 0x68, 0x3b,
 			0x7a, 0x4e, 0xde, 0xfe, 0x2c, 0x00, 0x00, 0x00,
-		},
+		}),
 		Index: 0xffffffff,
 	}
 
@@ -39,12 +39,12 @@ func Test_serializeUTXO(t *testing.T) {
 	}
 	entry := NewUTXOEntry(5000000000, scriptPublicKey, false, 1432432)
 	outpoint := &externalapi.DomainOutpoint{
-		TransactionID: externalapi.DomainTransactionID{
+		TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
 			0x16, 0x5e, 0x38, 0xe8, 0xb3, 0x91, 0x45, 0x95,
 			0xd9, 0xc6, 0x41, 0xf3, 0xb8, 0xee, 0xc2, 0xf3,
 			0x46, 0x11, 0x89, 0x6b, 0x82, 0x1a, 0x68, 0x3b,
 			0x7a, 0x4e, 0xde, 0xfe, 0x2c, 0x00, 0x00, 0x00,
-		},
+		}),
 		Index: 0xffffffff,
 	}
 
diff --git a/domain/dagconfig/params_test.go b/domain/dagconfig/params_test.go
index 3790ed75..d3f85058 100644
--- a/domain/dagconfig/params_test.go
+++ b/domain/dagconfig/params_test.go
@@ -8,7 +8,6 @@ import (
 	"testing"
 
 	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
-	"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
 )
 
 func TestNewHashFromStr(t *testing.T) {
@@ -19,9 +18,11 @@ func TestNewHashFromStr(t *testing.T) {
 	}{
 		{"banana", nil, true},
 		{"0000000000000000000000000000000000000000000000000000000000000000",
-			&externalapi.DomainHash{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}),
+			false},
 		{"0101010101010101010101010101010101010101010101010101010101010101",
-			&externalapi.DomainHash{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, false},
+			externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}),
+			false},
 	}
 
 	for _, test := range tests {
@@ -46,7 +47,7 @@ func TestNewHashFromStr(t *testing.T) {
 // It only differs from the one available in hashes package in that it panics on an error
 // since it will only be called from tests.
 func newHashFromStr(hexStr string) *externalapi.DomainHash {
-	hash, err := hashes.FromString(hexStr)
+	hash, err := externalapi.NewDomainHashFromString(hexStr)
 	if err != nil {
 		panic(err)
 	}
diff --git a/testing/integration/selected_parent_chain_test.go b/testing/integration/selected_parent_chain_test.go
index 8b5812d7..9c3c9937 100644
--- a/testing/integration/selected_parent_chain_test.go
+++ b/testing/integration/selected_parent_chain_test.go
@@ -1,10 +1,10 @@
 package integration
 
 import (
-	"encoding/hex"
+	"testing"
+
 	"github.com/kaspanet/kaspad/app/appmessage"
 	"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
-	"testing"
 )
 
 func TestVirtualSelectedParentChain(t *testing.T) {
@@ -26,7 +26,7 @@ func TestVirtualSelectedParentChain(t *testing.T) {
 	// each chain changed notifications contains only one entry
 	// in `added` and nothing in `removed`
 	chain1TipHash := consensushashing.BlockHash(kaspad1.config.NetParams().GenesisBlock)
-	chain1TipHashHex := hex.EncodeToString(chain1TipHash[:])
+	chain1TipHashString := chain1TipHash.String()
 	const blockAmountToMine = 10
 	for i := 0; i < blockAmountToMine; i++ {
 		minedBlock := mineNextBlock(t, kaspad1)
@@ -40,12 +40,12 @@ func TestVirtualSelectedParentChain(t *testing.T) {
 		}
 
 		minedBlockHash := consensushashing.BlockHash(minedBlock)
-		minedBlockHashHex := hex.EncodeToString(minedBlockHash[:])
-		if minedBlockHashHex != notification.AddedChainBlocks[0].Hash {
+		minedBlockHashString := minedBlockHash.String()
+		if minedBlockHashString != notification.AddedChainBlocks[0].Hash {
 			t.Fatalf("Unexpected block hash in AddedChainBlocks. Want: %s, got: %s",
-				minedBlockHashHex, notification.AddedChainBlocks[0].Hash)
+				minedBlockHashString, notification.AddedChainBlocks[0].Hash)
 		}
-		chain1TipHashHex = minedBlockHashHex
+		chain1TipHashString = minedBlockHashString
 	}
 
 	// In kaspad2, mine a different chain of `blockAmountToMine`
@@ -61,7 +61,7 @@ func TestVirtualSelectedParentChain(t *testing.T) {
 	// between the two nodes
 	chain2Tip := mineNextBlock(t, kaspad2)
 	chain2TipHash := consensushashing.BlockHash(chain2Tip)
-	chain2TipHashHex := hex.EncodeToString(chain2TipHash[:])
+	chain2TipHashString := chain2TipHash.String()
 
 	// For the first `blockAmountToMine - 1` blocks we don't expect
 	// the chain to change at all
@@ -104,7 +104,7 @@ func TestVirtualSelectedParentChain(t *testing.T) {
 
 	// Get the virtual selected parent chain from the tip of
 	// the first chain
-	virtualSelectedParentChainFromChain1Tip, err := kaspad1.rpcClient.GetVirtualSelectedParentChainFromBlock(chain1TipHashHex)
+	virtualSelectedParentChainFromChain1Tip, err := kaspad1.rpcClient.GetVirtualSelectedParentChainFromBlock(chain1TipHashString)
 	if err != nil {
 		t.Fatalf("GetVirtualSelectedParentChainFromBlock failed: %s", err)
 	}
@@ -123,8 +123,8 @@ func TestVirtualSelectedParentChain(t *testing.T) {
 	// Make sure that the last block in `added` is the tip
 	// of chain2
 	lastAddedChainBlock := virtualSelectedParentChainFromChain1Tip.AddedChainBlocks[len(virtualSelectedParentChainFromChain1Tip.AddedChainBlocks)-1]
-	if lastAddedChainBlock.Hash != chain2TipHashHex {
+	if lastAddedChainBlock.Hash != chain2TipHashString {
 		t.Fatalf("Unexpected last added chain block. Want: %s, got: %s",
-			chain2TipHashHex, lastAddedChainBlock.Hash)
+			chain2TipHashString, lastAddedChainBlock.Hash)
 	}
 }