4. 公共服务

4.1. 公共服务介绍

公共服务是数据要素流通平台的重要组成,采用微服务设计搭建,主要负责api管理、用户管理、区块链配置管理、合约配置管理、平台配置管理、链账户管理、上链交互、多链多合约事件订阅等功能。

公共服务包括以下子服务模块:

  • 网关:包含用户管理、接口(API)管理、路由分发等主要功能

  • 链交互服务: 给应用层提供区块链配置管理、合约配置管理、平台配置管理、合约调用、链上事件订阅推送等相关功能的微服务组件

  • 密钥管理服务: 应用层提供链账户配置、私钥/证书导入保存、链上交易签名、多类型加解密等相关功能的微服务组件

4.2. 网关

网关(gateway)是整个平台请求的入口,集成了用户管理、接口(API)管理、路由分发等主要功能模块。gateway 是基于流行的 go-zero 框架开发的 http 服务,保障了整体业务的高可用、高性能支撑。

主要的模块如下所述:

  • 用户中心:完成用户信息的管理

    • 用户添加、登录、信息修改

    • 用户权限管理

    • 用户角色管理

    • 用户登录态管理,包括登录态生成、校验、销毁, 采用redis存储

  • 接口(API)管理

    • 接口Path、Method、参数校验

    • 接口访问权限校验

  • 路由分发

    • 接口访问参数校验

    • 对特定服务采用不同转发策略

      • 用户相关:不转发,本地处理

      • Mira业务相关:Http转发

      • Tdh业务相关:Http转发

      • 资产登记服务:Grpc转发

      • 资产认证服务:Grpc转发

      • 密钥管理服务:Grpc转发

      • 链服务:Grpc转发

以下是它的整体架构:

网关整体架构.png

架构上分为 4 层:

  • go-zero框架层,搭建 http 服务基础框架,提供参数校验、请求处理、服务高可用控制等功能

  • logic层,核心逻辑层,主要封装了对 user-center、registration-service、certification-service、chain-service、key-service 等模块访问的 api 逻辑

  • storage层,提供对用户数据存储和查询

  • config层,服务启动参数配置,包含了 go-zero 框架自带的配置和服务自定义配置项

以下是它和各个模块的关联关系:

网关各模块关系.png

gateway 启动配置文件样例 gateway.yaml 如下:

# ------ go-zero 自带配置 ------ 
Name: gateway
Host: 0.0.0.0
Port: 8080

# 当前服务请求超时时间是 30s
Timeout: 30000

# 最大连接数 10000,根据实际部署环境设置
MaxConns: 10000

# 请求体最大允许字节数 50MB,根据实际情况设置
MaxBytes: 52428800

Log:
  # 服务名称
  ServiceName: gateway
  # 日志输出到文件
  Mode: file
  # 日志输出文件路径
  Path: logs
  # 日志级别
  Level: info
  # 是否压缩日志
  Compress: true
  # 日志保留天数,只有在文件模式才会生效
  KeepDays: 3
  # 按天切割日志
  Rotation: daily

# 基于 OpenTelemetry 的日志收集链路追踪
Telemetry:
  # 链路追踪开关,不配置默认是开启
  Disabled: true
  # 链路追踪服务名称,跟服务名称保持一致即可
  Name: chain.rpc
  # 链路追踪服务端地址
  Endpoint: http://jaeger:14268/api/traces
  # 采样率,不配置默认是 1.0
  Sampler: 1.0
  # 支持 jaeger|zipkin|otlpgrpc|otlphttp 这些链路追踪工具,不配置默认 jaeger
  Batcher: jaeger

# 监控,默认都是开启,主要调整端口和监控访问路由
DevServer:
  # 监控指标和健康检查的总开关,不配置是默认开启
  Enable: true
  # 监控指标和健康检查的端口
  Port: 6060
  # 健康检查路由,不配置是默认 /healthz
  HealthPath: "/healthz"
  # 健康检查返回,不配置默认是 OK
  HealthResponse: "OK"
  # 监控指标路由,不配置是默认 /metrics
  MetricsPath: "/metrics"
GrpcConf:
  ServerCertFile: ""
  ServerKeyFile: ""
  #  ServerCertFile: ./cert/gateway/server.pem
  #  ServerKeyFile: ./cert/gateway/server.key

  # 接收、发送消息大小设置为 50 mb,根据服务实际场景调整
  MaxRecvMsgSize: 52428800
  MaxSendMsgSize: 52428800

# 数据库配置
DBConf:
  # 数据库类型,支持:mysql、kingbase_mysql、kingbase_pgsql、postgres
  Type: "mysql"
  # 数据库连接字符串
  DNS: root:root123456@tcp(127.0.0.1:3306)/user_management?charset=utf8&parseTime=true&loc=Asia%2FShanghai


# redis 缓存配置,主要指定访问地址,其他配置项默认即可
Cache:
  - Host: 127.0.0.1:6379
    Pass: "123456"

# 注册用户默认密码
UserCenterConf:
  DefaultPassword: "ChainMaker123."

# 隐私计算配置
MiraConf:
  Endpoint: http://127.0.0.1:31008

# 存证中心配置
TdhConf:
  Endpoint: http://127.0.0.1:8090
  # 存证中心是否去中心化
  TdhDecentration: true

GrpcConfs:
  chain-service:
    #    ClientCertFile: ./cert/chain-service/client.pem
    #    ClientKeyFile: ./cert/chain-service/client.key
    #    CaCertFile: ./cert/ca/ca.pem
    ClientCertFile: ""
    ClientKeyFile: ""
    CaCertFile: ""
    DNS: localhost
    Endpoint: 127.0.0.1:8081
  registration-service:
    #    ClientCertFile: ./cert/registration-service/client.pem
    #    ClientKeyFile: ./cert/registration-service/client.key
    #    CaCertFile: ./cert/ca/ca.pem
    ClientCertFile: ""
    ClientKeyFile: ""
    CaCertFile: ""
    DNS: localhost
    Endpoint: 127.0.0.1:8082
  #    Endpoint: 127.0.0.1:8082
  key-service:
    #    ClientCertFile: ./cert/key-service/client.pem
    #    ClientKeyFile: ./cert/key-service/client.key
    #    CaCertFile: ./cert/ca/ca.pem
    ClientCertFile: ""
    ClientKeyFile: ""
    CaCertFile: ""
    DNS: localhost
    Endpoint: 127.0.0.1:8083
  certification-service:
    #    ClientCertFile: ./cert/certification-service/client.pem
    #    ClientKeyFile: ./cert/certification-service/client.key
    #    CaCertFile: ./cert/ca/ca.pem
    ClientCertFile: ""
    ClientKeyFile: ""
    CaCertFile: ""
    DNS: localhost
    Endpoint: 127.0.0.1:8084

# 三方登录配置
Oauth2Config:
  oss:
    # 对应app
    ClientId: privacy
    # 对应Key
    ClientSecret: xxxxxxxxxxxxxxxxxxxxxx
    # 对应OpenServicesGetUserBaseUrl
    RedirectUri: http://127.0.0.1:8090/RedirectUri

4.3. 链交互服务

链交互服务(chain-service)专门对接长安链底层协议,给应用层提供区块链配置管理、合约配置管理、平台配置管理、合约调用、链上事件订阅推送等相关功能的微服务组件。chain-service 是基于流行的 go-zero 框架开发的 grpc 服务,保障了整体业务的高可用、高性能支撑。

以下是它的整体架构:

chain-service-architecture

架构上分为 4 层:

  • go-zero框架层,搭建 grpc 服务基础框架,提供参数校验、监控指标采集、请求处理、链路追踪、服务高可用控制等功能

  • logic层,核心逻辑层,提供了区块链配置管理、合约配置管理、平台配置管理、节点检测、合约调用、链上事件同步等功能

  • storage层,提供对区块链配置、合约配置、平台配置等数据存储和查询

  • config层,服务启动参数配置,包含了 go-zero 框架自带的配置和服务自定义配置项

4.3.1. 区块链配置信息查看

chain-service-list-chain

区块链配置信息查看流程如下:

  • 用户点击前端页面 “配置中心-区块链配置” 菜单,请求到网关

  • 网关对当前请求鉴权,通过后转发到链服务(chain-service)

  • 链服务从本地数据库获取到区块链配置信息列表,返回给网关,再返回给前端页面

4.3.2. 修改区块链配置信息

chain-service-save-chain

修改区块链配置信息流程如下:

  • 用户点击前端页面 “配置中心-区块链配置” 菜单,点击中区块链信息列表 “配置” 按钮,输入或者修改相关信息,完成提交,请求到网关

  • 网关对当前请求鉴权,通过后转发到链服务(chain-service)

  • 链服务检测提交的各节点是否可用,如果节点都可用,则更新到本地数据库,返回成功或者失败给网关,再返回给前端页面

4.3.3. 合约调用

call-contract

合约调用流程如下:

  • 上链业务通过调用 chain-service 的合约调用接口来统一上链

  • chain-service 组装对应的 tx payload,交给 key-service 签名

  • chain-service 拿到签名数据后,组装完整的 tx request,发送到链节点

  • chain-service 检查节点返回的交易结果,返回给上链业务端最终结果

4.3.4. 链上事件处理

chain-service-event

链上事件处理流程如下:

  • chain-service 启动时,单独开启一个协程,从 redis 获取上次监听的块高开始,轮训监听链上合约事件

  • 一旦收到新的链上事件,推送到 redis,并更新 redis 最新块高

  • 如果期间处理异常,则不会更新 redis 最新块高

chain-service 启动配置文件样例 chain-service.yaml 如下:

# ------ go-zero 自带配置 ------ 
# 服务名称
Name: chain.rpc
# 服务监听端口
ListenOn: 0.0.0.0:8081
# 当前服务请求超时时间,单位 ms
Timeout: 30000
# 服务运行环境:dev、test、pre、prod
Mode: dev
# go-zero 日志配置
Log:
  # 服务名称,用于日志打印
  ServiceName: chain-service
  # 日志输出到文件
  Mode: file
  # 日志输出文件路径
  Path: logs
  # 日志级别
  Level: debug
  # 是否压缩日志
  Compress: true
  # 日志保留天数,只有在文件模式才会生效
  KeepDays: 30
  # 按天切割日志
  Rotation: daily
# 基于 OpenTelemetry 的日志收集链路追踪
Telemetry:
  # 链路追踪开关,不配置默认是开启
  Disabled: true
  # 链路追踪服务名称,跟服务名称保持一致即可
  Name: chain.rpc
  # 链路追踪服务端地址
  Endpoint: http://jaeger:14268/api/traces
  # 采样率,不配置默认是 1.0
  Sampler: 1.0
  # 支持 jaeger|zipkin|otlpgrpc|otlphttp 这些链路追踪工具,不配置默认 jaeger
  Batcher: jaeger
# 监控,默认都是开启,主要调整端口和监控访问路由
DevServer:
  # 监控指标和健康检查的总开关,不配置是默认开启
  Enable: true
  # 监控指标和健康检查的端口
  Port: 6061
  # 健康检查路由,不配置是默认 /healthz
  HealthPath: "/healthz"
  # 健康检查返回,不配置默认是 OK
  HealthResponse: "OK"
  # 监控指标路由,不配置是默认 /metrics
  MetricsPath: "/metrics"
# ------ go-zero 自带配置 ------ 


# ------ 自定义配置 ------ 
# 服务端 tls 证书私钥配置,如果不开启 tls,则需要配置空字符串
GrpcConf:
  #CaCertFile: ./cert/ca/ca.pem
  #ServerCertFile: ./cert/chain-service/server.pem
  #ServerKeyFile: ./cert/chain-service/server.key
  CaCertFile: ""
  ServerCertFile: ""
  ServerKeyFile: ""
  # 接收、发送消息大小设置为 20 mb,根据服务实际场景调整
  MaxRecvMsgSize: 20971520
  MaxSendMsgSize: 20971520
# 与 key-service 通信的 tls 证书私钥配置,如果不开启 tls,则需要配置空字符串
KeyServiceConf:
  #ClientCertFile: ./cert/key-service/client.pem
  #ClientKeyFile: ./cert/key-service/client.key
  #CaCertFile: ./cert/ca/ca.pem
  ClientCertFile: ""
  ClientKeyFile: ""
  CaCertFile: ""
  # 如果指定 tls 证书配置,同时需要指定证书中 DNS 名称
  DNS: localhost
  # 服务端地址
  Endpoint: 192.168.1.134:8083
# 数据库配置
DBConf:
  # 数据库类型,支持:mysql、kingbase_mysql、kingbase_pgsql、postgres
  Type: "mysql"
  # 数据库连接字符串
  DNS: root:root123456@tcp(192.168.1.135:3306)/chainservice?charset=utf8&parseTime=true&loc=Asia%2FShanghai
# 链上事件订阅推送配置
SubscribeConf:
	# Redis 地址
  RedisAddr: 192.168.1.135:6379
  # Redis 用户名,没有则置为空字符串
  RedisUserName:
  # Redis 密码
  RedisPassword: "123456"
# 交易查询次数    
QueryTxConf:
  # 最多查询 20 次,如果还未成功上链,则报错
  RetryLimit: 20
  # 每次间隔 500ms
  RetryInterval: 500
# ftp 传输配置
FtpConfig:
  # 是否启动 ftp 传输 tx
  Enable: false
  # ftp 客户端配置文件路径
  ConfFilePath: ./etc/ftp_config.yml
# 发送交易超时时间,单位 s
SendTxTimeout: 120
# ------ 自定义配置 ------ 

ftp_config.yml 配置样例如下:

ftp_tx_file_config:
  # 请求方式: RPC | FTP (client端为FTP, chain端为RPC)
  request_mod: "FTP"
  # 请求文件存储目录
  request_file_dir: "./tx_request"
  # 返回文件存储目录
  response_file_dir: "./tx_response"
  # 交易文件分类方式 direct | date(year/month/week/day/hour)
  file_classify_mod: "month"
  # 交易文件写入方式: single | batch
  file_write_mod: "single"
  # 交易序列化方式: json(default) | pb
  file_serialize_mod: "json"
  # 交易容量(default 50)
  tx_buffer_size: 50
  # 事件容量(default 50)
  event_buffer_size: 50
  # 请求超时,单位:s
  get_request_timeout: 30

4.4. 密钥管理服务

密钥管理服务(key-service)给应用层提供链账户配置、私钥/证书导入保存、链上交易签名、多类型加解密等相关功能的微服务组件。key-service 是基于流行的 go-zero 框架开发的 grpc 服务,保障了整体业务的高可用、高性能支撑。

以下是它的整体架构:

key-service-architecture

架构上分为 4 层:

  • go-zero框架层,搭建 grpc 服务基础框架,提供参数校验、监控指标采集、请求处理、链路追踪、服务高可用控制等功能

  • logic层,核心逻辑层,提供链账户信息管理、私钥数据加解密、链账户身份注册、交易签、多类型加解密等功能

  • storage层,提供对链账户信息存储和查询

  • config层,服务启动参数配置,包含了 go-zero 框架自带的配置和服务自定义配置项

4.4.1. 导入私钥/证书

key-service-import-key

导入私钥/证书流程如下:

  • 用户点击前端页面 “配置中心-链账户绑定” 菜单,点击页面 “导入” 按钮,选择对应的链和上传相关文件,完成提交,请求到网关

  • 网关对当前请求鉴权,通过后转发到 key-service

  • key-service 对收到的私钥/证书加密存储到本地 db

  • key-service 返回成功或者失败给网关,再返回给前端页面

4.4.2. 链账户信息查看

key-service-list-account

链账户信息查看流程如下:

  • 用户点击前端页面 “配置中心-链账户绑定” 菜单,请求到网关

  • 网关对当前请求鉴权,通过后转发到 key-service

  • key-service 从本地 db 查询链账户信息列表,返回给网关,再返回给前端页面

4.4.3. 交易签名

key-service-sign-tx

交易签名流程如下:

  • 上链业务通过调用 chain-service 的合约调用接口来统一上链

  • chain-service 组装对应的 tx payload,交给 key-service 签名,返回签名数据给 chain-service

  • chain-service 拿到签名数据后,组装完整的 tx request,发送到链上

4.4.4. 链账户身份注册

key-service-account-config

链账户身份注册流程如下:

  • 用户点击前端页面 “配置中心-链账户绑定” 菜单,点击列表中 “配置” 按钮,输入相关信息,完成提交,请求到网关

  • 网关对当前请求鉴权,通过后转发到 key-service

  • key-service 请求 chain-service 发起合约调用

  • chain-service 组装对应的 tx payload,发给 key-service 签名,拿到签名数据组装完整 tx request,发送到链上

  • chain-service 检查节点返回的交易结果,返回给 key-service 上链结果

  • key-service 检查上链结果,如果成功,同时存储账户相关信息到本地 db,并返回给网关,再返回给前端页面

key-service 启动配置文件样例 key-service.yaml 如下:

# ------ go-zero 自带配置 ------ 
# 服务名称
Name: key.rpc
# 服务监听端口
ListenOn: 0.0.0.0:8083
# 当前服务请求超时时间,单位 ms
Timeout: 30000
# 服务运行环境:dev、test、pre、prod
Mode: dev
# go-zero 日志配置
Log:
  # 服务名称,用于日志打印
  ServiceName: key-service
  # 日志输出到文件
  Mode: file
  # 日志输出文件路径
  Path: logs
  # 日志级别
  Level: debug
  # 是否压缩日志
  Compress: true
  # 日志保留天数,只有在文件模式才会生效
  KeepDays: 30
  # 按天切割日志
  Rotation: daily
# 基于 OpenTelemetry 的日志收集链路追踪
Telemetry:
  # 链路追踪开关,不配置默认是开启
  Disabled: true
  # 链路追踪服务名称,跟服务名称保持一致即可
  Name: key.rpc
  # 链路追踪服务端地址
  Endpoint: http://jaeger:14268/api/traces
  # 采样率,不配置默认是 1.0
  Sampler: 1.0
  # 支持 jaeger|zipkin|otlpgrpc|otlphttp 这些链路追踪工具,不配置默认 jaeger
  Batcher: jaeger
# 监控,默认都是开启,主要调整端口和监控访问路由
DevServer:
  # 监控指标和健康检查的总开关,不配置是默认开启
  Enable: true
  # 监控指标和健康检查的端口
  Port: 6063
  # 健康检查路由,不配置是默认 /healthz
  HealthPath: "/healthz"
  # 健康检查返回,不配置默认是 OK
  HealthResponse: "OK"
  # 监控指标路由,不配置是默认 /metrics
  MetricsPath: "/metrics"
# ------ go-zero 自带配置 ------ 


# ------ 自定义配置 ------ 
# 服务端 tls 证书私钥配置,如果不开启 tls,则需要配置空字符串
GrpcConf:
  #CaCertFile: ./cert/ca/ca.pem
  #ServerCertFile: ./cert/key-service/server.pem
  #ServerKeyFile: ./cert/key-service/server.key
  CaCertFile: ""
  ServerCertFile: ""
  ServerKeyFile: ""
  # 接收、发送消息大小设置为 20 mb,根据服务实际场景调整
  MaxRecvMsgSize: 20971520
  MaxSendMsgSize: 20971520
# 与 chain-service 通信的 tls 证书私钥配置,如果不开启 tls,则需要配置空字符串
ChainServiceConf:
  #ClientCertFile: ./cert/chain-service/client.pem
  #ClientKeyFile: ./cert/chain-service/client.key
  #CaCertFile: ./cert/ca/ca.pem
  ClientCertFile: ""
  ClientKeyFile: ""
  CaCertFile: ""
  # 如果指定 tls 证书配置,同时需要指定证书中 DNS 名称
  DNS: localhost
  # 服务端地址
  Endpoint: 192.168.1.134:8081
# 数据库配置
DBConf:
  # 数据库类型,支持:mysql、kingbase_mysql、kingbase_pgsql、postgres
  Type: "mysql"
  # 数据库连接字符串
  DNS: root:root123456@tcp(192.168.1.135:3306)/keyservice?charset=utf8&parseTime=true&loc=Asia%2FShanghai
# 私钥证书等加密配置
SymmetricEncryptConf:
  # 1.0.0 版本使用的 AES 算法,2.0.0 改为使用 SM4
  Algo: SM4
  Key: GVQDSaJW5YKJHGDF
# 地址格式
AddressType: ethereum
# CryptoConfig 配置硬件或软件算法
CryptoConfig:
  Soft: true
  HSM: ""  # 支持 sdf 或者 pkcs11
# sdf 配置
SDFConf:
  # lib 库文件路径
  LibPath: "/lib/libswsds.so" # SDF Lib Path
  # 会话channel数量:
  SessionCacheSize: 10 # size of HSM session cache, default to 10
# pkcs11 配置
Pkcs11Conf:
  Enabled: false # pkcs11 is not used by default
  Type: pkcs11 # only support pkcs11 or sdf
  Label: HSM # label for the slot to be used
  Library: /usr/lib/softhsm/libsofthsm2.so # path to the .so file of pkcs11 interface
  Password: "11111111" # password to logon the HSM(Hardware security module)
  SessionCacheSize: 10 # size of HSM session cache, default to 10
  Hash: "SHA256" # hash algorithm used to compute SKI
# 外接 kms 配置
KmsConf:
  Enabled: false # kms is not used by default
  DefaultUrl: kms-adapter.public:8180  # default kms adapter url
# ------ 自定义配置 ------