diff --git a/pkg/morph/client/netmap/client.go b/pkg/morph/client/netmap/client.go
index dd89985f6..0c54f4bb4 100644
--- a/pkg/morph/client/netmap/client.go
+++ b/pkg/morph/client/netmap/client.go
@@ -35,6 +35,7 @@ type cfg struct {
 	newEpochMethod, // new epoch method name for invocation
 	netMapMethod, // get network map method name
 	snapshotMethod, // get network map snapshot method name
+	epochSnapshotMethod, // get network map snapshot by epoch method name
 	updateStateMethod, // update state method name for invocation
 	innerRingListMethod, // IR list method name for invocation
 	epochMethod, // get epoch number method name
@@ -50,6 +51,8 @@ const (
 	defaultInnerRIngListMethod = "innerRingList" // default IR list method name
 	defaultEpochMethod         = "epoch"         // default get epoch number method name
 	defaultConfigMethod        = "config"        // default get config value method name
+
+	defaultEpochSnapshotMethod = "snapshotByEpoch" // default get network map snapshot by epoch method name
 )
 
 func defaultConfig() *cfg {
@@ -58,6 +61,7 @@ func defaultConfig() *cfg {
 		newEpochMethod:      defaultNewEpochMethod,
 		netMapMethod:        defaultNetMapMethod,
 		snapshotMethod:      defaultSnapshotMethod,
+		epochSnapshotMethod: defaultEpochSnapshotMethod,
 		updateStateMethod:   defaultUpdateStateMethod,
 		innerRingListMethod: defaultInnerRIngListMethod,
 		epochMethod:         defaultEpochMethod,
@@ -194,3 +198,17 @@ func WithConfigMethod(n string) Option {
 		}
 	}
 }
+
+// WithEpochSnapshotMethod returns a client constructor option that
+// specifies the method name of snapshot by value receiving operation.
+//
+// Ignores empty value.
+//
+// If option not provided, "snapshotByValue" is used.
+func WithEpochSnapshotMethod(n string) Option {
+	return func(c *cfg) {
+		if n != "" {
+			c.epochSnapshotMethod = n
+		}
+	}
+}
diff --git a/pkg/morph/client/netmap/netmap.go b/pkg/morph/client/netmap/netmap.go
index 86f86c2ad..043e33dd1 100644
--- a/pkg/morph/client/netmap/netmap.go
+++ b/pkg/morph/client/netmap/netmap.go
@@ -23,6 +23,18 @@ type GetNetMapValues struct {
 	peers [][]byte
 }
 
+// EpochSnapshotArgs groups the arguments
+// of snapshot by epoch test invoke call.
+type EpochSnapshotArgs struct {
+	epoch uint64
+}
+
+// EpochSnapshotValues groups the stack parameters
+// returned by snapshot by epoch test invoke.
+type EpochSnapshotValues struct {
+	*GetNetMapValues
+}
+
 const nodeInfoFixedPrmNumber = 1
 
 // SetDiff sets argument for snapshot method of
@@ -31,6 +43,11 @@ func (g *GetSnapshotArgs) SetDiff(d uint64) {
 	g.diff = d
 }
 
+// SetEpoch sets epoch number to get snapshot.
+func (a *EpochSnapshotArgs) SetEpoch(d uint64) {
+	a.epoch = d
+}
+
 // Peers return the list of peers from
 // network map in a binary format.
 func (g GetNetMapValues) Peers() [][]byte {
@@ -69,6 +86,29 @@ func (c *Client) Snapshot(a GetSnapshotArgs) (*GetNetMapValues, error) {
 	return peersFromStackItems(prms, c.snapshotMethod)
 }
 
+// EpochSnapshot performs the test invoke of get snapshot of network map by epoch
+// from NeoFS Netmap contract.
+func (c *Client) EpochSnapshot(args EpochSnapshotArgs) (*EpochSnapshotValues, error) {
+	prms, err := c.client.TestInvoke(
+		c.epochSnapshotMethod,
+		int64(args.epoch),
+	)
+	if err != nil {
+		return nil, errors.Wrapf(err,
+			"could not perform test invocation (%s)",
+			c.epochSnapshotMethod)
+	}
+
+	nmVals, err := peersFromStackItems(prms, c.epochSnapshotMethod)
+	if err != nil {
+		return nil, err
+	}
+
+	return &EpochSnapshotValues{
+		GetNetMapValues: nmVals,
+	}, nil
+}
+
 func peersFromStackItems(stack []stackitem.Item, method string) (*GetNetMapValues, error) {
 	if ln := len(stack); ln != 1 {
 		return nil, errors.Errorf("unexpected stack item count (%s): %d",
diff --git a/pkg/morph/client/netmap/wrapper/netmap.go b/pkg/morph/client/netmap/wrapper/netmap.go
index 9d3a06a6a..fb96a64ae 100644
--- a/pkg/morph/client/netmap/wrapper/netmap.go
+++ b/pkg/morph/client/netmap/wrapper/netmap.go
@@ -14,12 +14,30 @@ func (w Wrapper) GetNetMap(diff uint64) (*netmap.Netmap, error) {
 	args := client.GetSnapshotArgs{}
 	args.SetDiff(diff)
 
-	peers, err := w.client.Snapshot(args)
+	vals, err := w.client.Snapshot(args)
 	if err != nil {
 		return nil, err
 	}
 
-	rawPeers := peers.Peers() // slice of serialized node infos
+	return unmarshalNetmap(vals.Peers())
+}
+
+// GetNetMapByEpoch receives information list about storage nodes
+// through the Netmap contract call, composes network map
+// from them and returns it. Returns snapshot of the specified epoch number.
+func (w Wrapper) GetNetMapByEpoch(epoch uint64) (*netmap.Netmap, error) {
+	args := client.EpochSnapshotArgs{}
+	args.SetEpoch(epoch)
+
+	vals, err := w.client.EpochSnapshot(args)
+	if err != nil {
+		return nil, err
+	}
+
+	return unmarshalNetmap(vals.Peers())
+}
+
+func unmarshalNetmap(rawPeers [][]byte) (*netmap.Netmap, error) {
 	infos := make([]netmap.NodeInfo, 0, len(rawPeers))
 
 	for _, peer := range rawPeers {