SC-Client supports the full contract API
diff --git a/pkg/client/sc/apis.go b/pkg/client/sc/apis.go
index aa5d951..47bf631 100644
--- a/pkg/client/sc/apis.go
+++ b/pkg/client/sc/apis.go
@@ -16,29 +16,23 @@
 package sc
 
 import (
+	"context"
 	"encoding/json"
-	"fmt"
+	"io/ioutil"
+	"net/http"
+
 	"github.com/apache/servicecomb-service-center/pkg/util"
 	"github.com/apache/servicecomb-service-center/server/admin/model"
-	"github.com/apache/servicecomb-service-center/server/core"
-	pb "github.com/apache/servicecomb-service-center/server/core/proto"
 	scerr "github.com/apache/servicecomb-service-center/server/error"
 	"github.com/apache/servicecomb-service-center/server/plugin/pkg/registry"
 	"github.com/apache/servicecomb-service-center/version"
-	"golang.org/x/net/context"
-	"io/ioutil"
-	"net/http"
 )
 
 const (
-	apiVersionURL   = "/version"
-	apiDumpURL      = "/v4/default/admin/dump"
-	apiClustersURL  = "/v4/default/admin/clusters"
-	apiHealthURL    = "/v4/default/registry/health"
-	apiSchemasURL   = "/v4/%s/registry/microservices/%s/schemas"
-	apiSchemaURL    = "/v4/%s/registry/microservices/%s/schemas/%s"
-	apiInstancesURL = "/v4/%s/registry/microservices/%s/instances"
-	apiInstanceURL  = "/v4/%s/registry/microservices/%s/instances/%s"
+	apiVersionURL  = "/version"
+	apiDumpURL     = "/v4/default/admin/dump"
+	apiClustersURL = "/v4/default/admin/clusters"
+	apiHealthURL   = "/v4/default/registry/health"
 
 	QueryGlobal = "global"
 )
@@ -115,70 +109,6 @@
 	return dump.Cache, nil
 }
 
-func (c *SCClient) GetSchemasByServiceId(ctx context.Context, domainProject, serviceId string) ([]*pb.Schema, *scerr.Error) {
-	domain, project := core.FromDomainProject(domainProject)
-	headers := c.CommonHeaders(ctx)
-	headers.Set("X-Domain-Name", domain)
-	resp, err := c.RestDoWithContext(ctx, http.MethodGet,
-		fmt.Sprintf(apiSchemasURL, project, serviceId)+"?withSchema=1&"+c.parseQuery(ctx),
-		headers, nil)
-	if err != nil {
-		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
-	}
-	defer resp.Body.Close()
-
-	body, err := ioutil.ReadAll(resp.Body)
-	if err != nil {
-		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
-	}
-
-	if resp.StatusCode != http.StatusOK {
-		return nil, c.toError(body)
-	}
-
-	schemas := &pb.GetAllSchemaResponse{}
-	err = json.Unmarshal(body, schemas)
-	if err != nil {
-		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
-	}
-
-	return schemas.Schemas, nil
-}
-
-func (c *SCClient) GetSchemaBySchemaId(ctx context.Context, domainProject, serviceId, schemaId string) (*pb.Schema, *scerr.Error) {
-	domain, project := core.FromDomainProject(domainProject)
-	headers := c.CommonHeaders(ctx)
-	headers.Set("X-Domain-Name", domain)
-	resp, err := c.RestDoWithContext(ctx, http.MethodGet,
-		fmt.Sprintf(apiSchemaURL, project, serviceId, schemaId)+"?"+c.parseQuery(ctx),
-		headers, nil)
-	if err != nil {
-		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
-	}
-	defer resp.Body.Close()
-
-	body, err := ioutil.ReadAll(resp.Body)
-	if err != nil {
-		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
-	}
-
-	if resp.StatusCode != http.StatusOK {
-		return nil, c.toError(body)
-	}
-
-	schema := &pb.GetSchemaResponse{}
-	err = json.Unmarshal(body, schema)
-	if err != nil {
-		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
-	}
-
-	return &pb.Schema{
-		SchemaId: schemaId,
-		Schema:   schema.Schema,
-		Summary:  schema.SchemaSummary,
-	}, nil
-}
-
 func (c *SCClient) GetClusters(ctx context.Context) (registry.Clusters, *scerr.Error) {
 	headers := c.CommonHeaders(ctx)
 	// only default domain has admin permission
@@ -227,65 +157,3 @@
 	}
 	return nil
 }
-
-func (c *SCClient) GetInstancesByServiceId(ctx context.Context, domainProject, providerId, consumerId string) ([]*pb.MicroServiceInstance, *scerr.Error) {
-	domain, project := core.FromDomainProject(domainProject)
-	headers := c.CommonHeaders(ctx)
-	headers.Set("X-Domain-Name", domain)
-	headers.Set("X-ConsumerId", consumerId)
-	resp, err := c.RestDoWithContext(ctx, http.MethodGet,
-		fmt.Sprintf(apiInstancesURL, project, providerId)+"?"+c.parseQuery(ctx),
-		headers, nil)
-	if err != nil {
-		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
-	}
-	defer resp.Body.Close()
-
-	body, err := ioutil.ReadAll(resp.Body)
-	if err != nil {
-		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
-	}
-
-	if resp.StatusCode != http.StatusOK {
-		return nil, c.toError(body)
-	}
-
-	instancesResp := &pb.GetInstancesResponse{}
-	err = json.Unmarshal(body, instancesResp)
-	if err != nil {
-		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
-	}
-
-	return instancesResp.Instances, nil
-}
-
-func (c *SCClient) GetInstanceByInstanceId(ctx context.Context, domainProject, providerId, instanceId, consumerId string) (*pb.MicroServiceInstance, *scerr.Error) {
-	domain, project := core.FromDomainProject(domainProject)
-	headers := c.CommonHeaders(ctx)
-	headers.Set("X-Domain-Name", domain)
-	headers.Set("X-ConsumerId", consumerId)
-	resp, err := c.RestDoWithContext(ctx, http.MethodGet,
-		fmt.Sprintf(apiInstanceURL, project, providerId, instanceId)+"?"+c.parseQuery(ctx),
-		headers, nil)
-	if err != nil {
-		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
-	}
-	defer resp.Body.Close()
-
-	body, err := ioutil.ReadAll(resp.Body)
-	if err != nil {
-		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
-	}
-
-	if resp.StatusCode != http.StatusOK {
-		return nil, c.toError(body)
-	}
-
-	instanceResp := &pb.GetOneInstanceResponse{}
-	err = json.Unmarshal(body, instanceResp)
-	if err != nil {
-		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
-	}
-
-	return instanceResp.Instance, nil
-}
diff --git a/pkg/client/sc/instance.go b/pkg/client/sc/instance.go
index d6ab277..5189b5e 100644
--- a/pkg/client/sc/instance.go
+++ b/pkg/client/sc/instance.go
@@ -31,6 +31,8 @@
 const (
 	apiDiscoveryInstancesURL = "/v4/%s/registry/instances"
 	apiHeartbeatSetURL       = "/v4/%s/registry/heartbeats"
+	apiInstancesURL          = "/v4/%s/registry/microservices/%s/instances"
+	apiInstanceURL           = "/v4/%s/registry/microservices/%s/instances/%s"
 	apiInstanceHeartbeatURL  = "/v4/%s/registry/microservices/%s/instances/%s/heartbeat"
 )
 
@@ -191,3 +193,65 @@
 
 	return instancesResp.Instances, nil
 }
+
+func (c *SCClient) GetInstancesByServiceId(ctx context.Context, domainProject, providerId, consumerId string) ([]*pb.MicroServiceInstance, *scerr.Error) {
+	domain, project := core.FromDomainProject(domainProject)
+	headers := c.CommonHeaders(ctx)
+	headers.Set("X-Domain-Name", domain)
+	headers.Set("X-ConsumerId", consumerId)
+	resp, err := c.RestDoWithContext(ctx, http.MethodGet,
+		fmt.Sprintf(apiInstancesURL, project, providerId)+"?"+c.parseQuery(ctx),
+		headers, nil)
+	if err != nil {
+		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
+	}
+	defer resp.Body.Close()
+
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
+	}
+
+	if resp.StatusCode != http.StatusOK {
+		return nil, c.toError(body)
+	}
+
+	instancesResp := &pb.GetInstancesResponse{}
+	err = json.Unmarshal(body, instancesResp)
+	if err != nil {
+		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
+	}
+
+	return instancesResp.Instances, nil
+}
+
+func (c *SCClient) GetInstanceByInstanceId(ctx context.Context, domainProject, providerId, instanceId, consumerId string) (*pb.MicroServiceInstance, *scerr.Error) {
+	domain, project := core.FromDomainProject(domainProject)
+	headers := c.CommonHeaders(ctx)
+	headers.Set("X-Domain-Name", domain)
+	headers.Set("X-ConsumerId", consumerId)
+	resp, err := c.RestDoWithContext(ctx, http.MethodGet,
+		fmt.Sprintf(apiInstanceURL, project, providerId, instanceId)+"?"+c.parseQuery(ctx),
+		headers, nil)
+	if err != nil {
+		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
+	}
+	defer resp.Body.Close()
+
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
+	}
+
+	if resp.StatusCode != http.StatusOK {
+		return nil, c.toError(body)
+	}
+
+	instanceResp := &pb.GetOneInstanceResponse{}
+	err = json.Unmarshal(body, instanceResp)
+	if err != nil {
+		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
+	}
+
+	return instanceResp.Instance, nil
+}
diff --git a/pkg/client/sc/schema.go b/pkg/client/sc/schema.go
new file mode 100644
index 0000000..f76c707
--- /dev/null
+++ b/pkg/client/sc/schema.go
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package sc
+
+import (
+	"context"
+	"crypto/sha256"
+	"encoding/json"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+
+	"github.com/apache/servicecomb-service-center/server/core"
+	pb "github.com/apache/servicecomb-service-center/server/core/proto"
+	scerr "github.com/apache/servicecomb-service-center/server/error"
+)
+
+const (
+	apiSchemasURL = "/v4/%s/registry/microservices/%s/schemas"
+	apiSchemaURL  = "/v4/%s/registry/microservices/%s/schemas/%s"
+)
+
+func (c *SCClient) CreateSchemas(ctx context.Context, domainProject, serviceId string, schemas []*pb.Schema) *scerr.Error {
+	domain, project := core.FromDomainProject(domainProject)
+	headers := c.CommonHeaders(ctx)
+	headers.Set("X-Domain-Name", domain)
+
+	for index, val := range schemas {
+		if len(val.Schema) > 0 {
+			schemas[index].Summary = schemaSummary(val.Schema)
+		}
+	}
+
+	reqBody, err := json.Marshal(&pb.ModifySchemasRequest{ServiceId: serviceId, Schemas: schemas})
+	if err != nil {
+		return scerr.NewError(scerr.ErrInternal, err.Error())
+	}
+
+	resp, err := c.RestDoWithContext(ctx, http.MethodPost,
+		fmt.Sprintf(apiSchemasURL, project, serviceId),
+		headers, reqBody)
+	if err != nil {
+		return scerr.NewError(scerr.ErrInternal, err.Error())
+	}
+	defer resp.Body.Close()
+
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return scerr.NewError(scerr.ErrInternal, err.Error())
+	}
+
+	if resp.StatusCode != http.StatusOK {
+		return c.toError(body)
+	}
+	return nil
+}
+
+func (c *SCClient) UpdateSchema(ctx context.Context, domainProject, serviceId string, schemaId string, schema string) *scerr.Error {
+	domain, project := core.FromDomainProject(domainProject)
+	headers := c.CommonHeaders(ctx)
+	headers.Set("X-Domain-Name", domain)
+
+	reqBody, err := json.Marshal(&pb.ModifySchemaRequest{
+		ServiceId: serviceId,
+		SchemaId:  schemaId,
+		Schema:    schema,
+		Summary:   schemaSummary(schema),
+	})
+	if err != nil {
+		return scerr.NewError(scerr.ErrInternal, err.Error())
+	}
+
+	resp, err := c.RestDoWithContext(ctx, http.MethodPut,
+		fmt.Sprintf(apiSchemaURL, project, serviceId, schemaId),
+		headers, reqBody)
+	if err != nil {
+		return scerr.NewError(scerr.ErrInternal, err.Error())
+	}
+	defer resp.Body.Close()
+
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return scerr.NewError(scerr.ErrInternal, err.Error())
+	}
+
+	if resp.StatusCode != http.StatusOK {
+		return c.toError(body)
+	}
+	return nil
+}
+
+func (c *SCClient) DeleteSchema(ctx context.Context, domainProject, serviceId string, schemaId string) *scerr.Error {
+	domain, project := core.FromDomainProject(domainProject)
+	headers := c.CommonHeaders(ctx)
+	headers.Set("X-Domain-Name", domain)
+
+	reqBody, err := json.Marshal(&pb.DeleteSchemaRequest{ServiceId: serviceId, SchemaId: schemaId})
+	if err != nil {
+		return scerr.NewError(scerr.ErrInternal, err.Error())
+	}
+
+	resp, err := c.RestDoWithContext(ctx, http.MethodDelete,
+		fmt.Sprintf(apiSchemaURL, project, serviceId, schemaId),
+		headers, reqBody)
+	if err != nil {
+		return scerr.NewError(scerr.ErrInternal, err.Error())
+	}
+	defer resp.Body.Close()
+
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return scerr.NewError(scerr.ErrInternal, err.Error())
+	}
+
+	if resp.StatusCode != http.StatusOK {
+		return c.toError(body)
+	}
+	return nil
+}
+
+func (c *SCClient) GetSchemasByServiceId(ctx context.Context, domainProject, serviceId string) ([]*pb.Schema, *scerr.Error) {
+	domain, project := core.FromDomainProject(domainProject)
+	headers := c.CommonHeaders(ctx)
+	headers.Set("X-Domain-Name", domain)
+	resp, err := c.RestDoWithContext(ctx, http.MethodGet,
+		fmt.Sprintf(apiSchemasURL, project, serviceId)+"?withSchema=1&"+c.parseQuery(ctx),
+		headers, nil)
+	if err != nil {
+		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
+	}
+	defer resp.Body.Close()
+
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
+	}
+
+	if resp.StatusCode != http.StatusOK {
+		return nil, c.toError(body)
+	}
+
+	schemas := &pb.GetAllSchemaResponse{}
+	err = json.Unmarshal(body, schemas)
+	if err != nil {
+		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
+	}
+
+	return schemas.Schemas, nil
+}
+
+func (c *SCClient) GetSchemaBySchemaId(ctx context.Context, domainProject, serviceId, schemaId string) (*pb.Schema, *scerr.Error) {
+	domain, project := core.FromDomainProject(domainProject)
+	headers := c.CommonHeaders(ctx)
+	headers.Set("X-Domain-Name", domain)
+	resp, err := c.RestDoWithContext(ctx, http.MethodGet,
+		fmt.Sprintf(apiSchemaURL, project, serviceId, schemaId)+"?"+c.parseQuery(ctx),
+		headers, nil)
+	if err != nil {
+		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
+	}
+	defer resp.Body.Close()
+
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
+	}
+
+	if resp.StatusCode != http.StatusOK {
+		return nil, c.toError(body)
+	}
+
+	schema := &pb.GetSchemaResponse{}
+	err = json.Unmarshal(body, schema)
+	if err != nil {
+		return nil, scerr.NewError(scerr.ErrInternal, err.Error())
+	}
+
+	return &pb.Schema{
+		SchemaId: schemaId,
+		Schema:   schema.Schema,
+		Summary:  schema.SchemaSummary,
+	}, nil
+}
+
+func schemaSummary(context string) string {
+	return fmt.Sprintf("%x", sha256.Sum256([]byte(context)))
+}