diff --git a/user/id.go b/user/id.go
index 8535b01c..31ff9b65 100644
--- a/user/id.go
+++ b/user/id.go
@@ -72,6 +72,11 @@ func (x *ID) SetScriptHash(scriptHash util.Uint160) {
 	copy(x.w[21:], hash.Checksum(x.w[:21]))
 }
 
+// ScriptHash calculates and returns script hash of ID.
+func (x *ID) ScriptHash() (util.Uint160, error) {
+	return util.Uint160DecodeBytesBE(x.w[1:21])
+}
+
 // WalletBytes returns FrostFS user ID as Neo3 wallet address in a binary format.
 //
 // Return value MUST NOT be mutated: to do this, first make a copy.
diff --git a/user/id_test.go b/user/id_test.go
index 6b1d0f89..00b08840 100644
--- a/user/id_test.go
+++ b/user/id_test.go
@@ -8,6 +8,7 @@ import (
 	. "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
 	usertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user/test"
 	"github.com/mr-tron/base58"
+	"github.com/nspcc-dev/neo-go/pkg/encoding/address"
 	"github.com/nspcc-dev/neo-go/pkg/util"
 	"github.com/nspcc-dev/neo-go/pkg/util/slice"
 	"github.com/stretchr/testify/require"
@@ -47,6 +48,19 @@ func TestID_SetScriptHash(t *testing.T) {
 	require.True(t, id2.Equals(id))
 }
 
+func TestID_ScriptHash(t *testing.T) {
+	userID := usertest.ID()
+
+	scriptHash, err := userID.ScriptHash()
+	require.NoError(t, err)
+
+	ownerAddress := userID.EncodeToString()
+	decodedScriptHash, err := address.StringToUint160(ownerAddress)
+	require.NoError(t, err)
+
+	require.True(t, scriptHash.Equals(decodedScriptHash))
+}
+
 func TestV2_ID(t *testing.T) {
 	id := usertest.ID()
 	var m refs.OwnerID