概述
SDK说明
华为链目前提供Java、Golang两种语言SDK,区块链服务启动时会启动一系列grpc接口,监听客户端发送的消息,与客户端交互完成各种请求。在开发客户端时,如果从底层grpc接口开始,进行各种消息封装、消息发送、返回值解析等工作,不仅会导致开发量过大,并且造成重复劳动。SDK则是将区块链服务提供的各种grpc接口进行封装,同时封装各接口所需类型的消息。在开发客户端时,只需要关注自己的业务逻辑,调用相应接口封装并发送消息即可,不需要关注底层消息发送接收的具体过程。
SDK逻辑结构
SDK主要提供消息封装、发送模块及相应的配套组件。配套组件主要包含异常处理、配置文件解析、节点获取等功能接口。
- 消息封装
由于消息类型较多,因此按类型进行了分类封装。消息封装相关接口均在build这个包下面,包含了ContractRawMessage、QueryRawMessage这几种消息构造的封装类。
- ContractRawMessage:包含交易背书、落盘两阶段消息的构建。
- QueryRawMessage:包含所有查询相关接口的消息构建,目前支持交易详情查询、链状态查询、区块查询、合约信息查询等接口。
- 消息发送
同消息封装类接口,按类型进行了分类封装。消息发送相关接口均包含在action这个包下面,包含了ContractAction、QueryAction、EventAction这几种消息发送的封装类。
- ContractAction:对应ContractRawMessage封装的消息的发送。
- QueryAction:对应QueryRawMessage中封装的消息的发送。
- EventAction:主要用于监听消息的最终状态,因为参数仅包含交易ID,消息封装的方法直接内置。同时所有的消息发送接口均提供同步和异步两种接口。
同步接口入参均为需要发送的消息,返回值为一个ListenableFuture对象,用于监听消息发送结果。
异步接口则传入需要发送消息的同时,还需要传入一个StreamObserver对象,用于异步获取消息发送结果。
基于SDK开发流程
基于SDK开发客户端需要进行以下步骤。
- 初始化
- 构造消息
由于消息类型较多,所以根据消息类型进行封装,在构造消息之前,必须先获取消息类型对象,然后再基于获取对象中对应的方法封装消息。
- 获取节点
- 发送消息
所有的发送接口都封装在节点类中,发送消息时,先获取节点,再调用节点的消息发送对象获取方法。不同的消息对应不同的构建接口,同理,消息发送接口也根据接口类型进行了分装,在发送消息前,必须先获取接口类型对象,然后再基于获取对象中对应的方法发送消息。
- 结果解析
服务端返回的消息中,均包含交易最后执行结果的标志位,以此判断交易是否执行成功。若结果为不成功,则返回错误原因,用于分析定位。
- 结果监听
对于业务交易和投票类型等需要落盘的交易,即使消息发送成功,后续落盘时还可能产生各种校验失败,导致交易无效。因此还需要监听交易是否最终落盘成功。
接口说明
由于实现各种不同的交易发送,需要多个接口互相配合,因此接口说明按照实现功能进行归类介绍,而不是逐个接口类介绍。
所有消息发送方法,都提供同步和异步两种接口,异步接口多一个StreamObserver监听对象,无返回值。
另外SDK还提供其他扩展能力,有需要的用户可以参考。如Java接口:
public SdkClient(String configPath, Function<byte[], byte[]> func)
public SdkClient()
public void setIdentity(String type, byte[] key, byte[] cert)
public void setTls(byte[] key, byte[] cert, byte[][] roots)
public void addWienerChainNode(String name, String host, int port)
public String getTxId(Transaction tx)
public ChainRawMessage getChainRawMessage()
public Block buildGenesisBlock(String chainId, String path)
public Block buildGenesisBlock(String chainId, String path, Function<byte[], byte[]> func)
public Block buildGenesisBlock(String chainId, ChainConfig chainConfig)
public static GenesisConfig createGenesisConfig(String path)
public void addOrganization(String name, byte[] admin, byte[] root, byte[] tls)
public void addConsenter(String name, String org, String host, long port, byte[] cert, byte[] tee)
public ChainConfig getChainConfig(String chainId)
public Block buildGenesisBlock(String chainId, ChainConfig chainConfig)
public void addChainNode(String name, String hostOverride, String host, int port)
public RawMessage buildJoinChainRawMessage(Block genesisBlock)
public RawMessage buildJoinChainRawMessage(ByteString genesisBlock, Entrypoint entrypoint)
public RawMessage buildJoinChainRawMessage(ByteString genesisBlock, ConfigInfo config, Entrypoint entrypoint)
public static Entrypoint readEntrypointFile(String path) throws ConfigException
public ListenableFuture<RawMessage> joinChain(RawMessage rawMessage)
public void joinChain(RawMessage rawMessage, StreamObserver<RawMessage>)
public RawMessage buildQuitChainRawMessage(String chainId)
public ListenableFuture<RawMessage> quitChain(RawMessage rawMessage)
public void quitChain(RawMessage rawMessage, StreamObserver<RawMessage> responseObserver)
public RawMessage buildQueryChainRawMessage()
public ListenableFuture<RawMessage> queryAllChains(RawMessage rawMessage)
public void queryAllChains(RawMessage rawMessage, StreamObserver<RawMessage> responseObserver)
public RawMessage buildQueryChainRawMessage(String chainId)
public ListenableFuture<RawMessage> queryChain(RawMessage rawMessage)
public void queryChain(RawMessage rawMessage, StreamObserver<RawMessage>
public Builder.TxRawMsg buildUpdateChainRawMessage(String chainId, String path)
public Builder.TxRawMsg buildUpdateChainRawMessage(String chainId, ChainConfig chainConfig)
public Builder.TxRawMsg buildUpdateChainRawMessage(String chainId, String path, Function<byte[], byte[]> func)
public TxRawMsg buildUpdateConfPolicyRawMessage(String chainId, String policy)
public TxRawMsg buildUpdateOrgRawMessage(String chainId, String path, Function<byte[], byte[]> func)
public TxRawMsg buildUpdateOrgRawMessage(String chainId, List<ConfigSet.OrgUpdate> orgUpdates)
public RawMessage buildQueryChainUpdateVote(String chainId)
public ListenableFuture<RawMessage> queryVote(RawMessage rawMsg)
public void queryVote(RawMessage rawMsg, StreamObserver<RawMessage> responseObserver)
public RawMessage buildImportRawMessage(Contract contract, String path, String sandbox, String language)
public ListenableFuture<RawMessage> contractImport(RawMessage rawMessage)
public void contractImport(RawMessage rawMessage, StreamObserver<RawMessage> responseObserver)
public Builder.TxRawMsg buildManageRawMessage(String chain, String contract, String option)
public RawMessage buildQueryStateRawMessage(String chain, String contract)
public ListenableFuture<RawMessage> queryState(RawMessage rawMessage)
public Builder.TxRawMsg buildVoteRawMessage(Contract contract, String description, String policy, boolean historySupport)
public Builder.TxRawMsg buildSQLVoteRawMessage(Contract contract, String description, String policy, String schema, boolean isHistorySupport)
public ListenableFuture<RawMessage> transaction(RawMessage rawMessage)
public void transaction(RawMessage rawMessage, StreamObserver<RawMessage> responseObserver)
public RawMessage buildQueryLifecycleVote(String chainId, String contract)
public static ContractInvocation buildContractInvocation(String name, String function, String[] args)
public RawMessage buildContractRawMessage(String chainId, String contract)
public ListenableFuture<RawMessage> queryContractInfo(RawMessage rawMsg)
public void queryContractInfo(RawMessage rawMsg, StreamObserver<RawMessage> responseObserver)
如Go接口:
func NewGatewayClient(configPath string, decrypts ...func(bytes []byte) ([]byte, error)) (*GatewayClient, error)
func GenerateTimestamp() uint64
func (msg *ChainRawMessage) BuildGenesisBlock(chainID string, genesisConfigPath string, decrypts ...func(bytes []byte) (*common.Block, error)
func (msg *ChainRawMessage) BuildJoinChainRawMessage(genesisBlockBytes []byte) (*common.RawMessage, error)
func (msg *ChainRawMessage) BuildJoinMsgWithLatestConf(genesisBlockBytes []byte, latestConf *common.ConfigInfo) (*common.RawMessage, error)
func (msg *ChainRawMessage) BuildJoinMsgWithEntrypoint(genesisBlockBytes []byte, latestConf *common.ConfigInfo, entrypoint *common.Entrypoint) (*common.RawMessage, error)
func (action *ChainAction) JoinChain(rawMsg *common.RawMessage) (*common.RawMessage, error)
func (msg *ChainRawMessage) BuildQuitChainRawMessage(chainID string) (*common.RawMessage, error)
func (action *ChainAction) QuitChain(rawMsg *common.RawMessage) (*common.RawMessage, error)
func (msg *ChainRawMessage) BuildQueryAllChainRawMessage() (*common.RawMessage, error)
func (action *ChainAction) QueryAllChains(rawMsg *common.RawMessage) (*common.RawMessage, error)
func (msg *ChainRawMessage) BuildQueryChainRawMessage(chainID string) (*common.RawMessage, error)
func (action *ChainAction) QueryChain(rawMsg *common.RawMessage) (*common.RawMessage, error)
func (u *UpdateConfig) BuildUpdateConfPolicyRawMessage(chainID string, policy string) (*TxRawMsg, error)
func (u *UpdateConfig) BuildUpdateLifecycleRawMessage(chainID string, policy string) (*TxRawMsg, error)
func (u *UpdateConfig) BuildUpdateOrgRawMessageWithYaml(chainID string, path string, decrypt config.DecryptFunc) (*TxRawMsg, error)
func (u *UpdateConfig) BuildUpdateOrgRawMessage(chainID string, orgUpdates *common.ConfigSet_OrgUpdates) (*TxRawMsg, error)
func (msg *QueryRawMessage) BuildQueryChainUpdateVoteRawMessage(chainID string) (*common.RawMessage, error)
func (action *QueryAction) GetVote(rawMsg *common.RawMessage) (*common.RawMessage, error)
func (msg *LifecycleRawMessage) BuildImportRawMessage(c *Contract, path string, sandbox string, language string) (*common.RawMessage, error)
func (action *ContractAction) ContractImport(rawMsg *common.RawMessage) (*common.RawMessage, error)
func (msg *LifecycleRawMessage) BuildManageRawMessage(chain string, contract string, option string) (*TxRawMsg, error)
func (msg *LifecycleRawMessage) BuildVoteRawMessage(c *Contract, desc string, policy string, historySupport bool) (*TxRawMsg, error)
func (action *ContractAction) Transaction(rawMsg *common.RawMessage) (*common.RawMessage, error)
func (msg *QueryRawMessage) BuildQueryLifecycleVoteRawMessage(chainID string, contract string) (*common.RawMessage, error)
func BuildTxHeader(chainID string, []string domains) *common.TxHeader
func (msg *QueryRawMessage) BuildContractRawMessage(chainID string, contract string) (*common.RawMessage, error)
func (action *QueryAction) GetContractInfo(rawMsg *common.RawMessage) (*common.RawMessage, error)