/* Copyright (C) THL A29 Limited, a Tencent company. All rights reserved. SPDX-License-Identifier: Apache-2.0 */ package chain import ( "encoding/base64" "encoding/pem" "errors" "fmt" "chainmaker.org/chainmaker/common/v2/crypto/x509" chainmaker_sdk_go "chainmaker.org/chainmaker/sdk-go/v2" ) // NodeConf add next time // @Description: type NodeConf struct { Url string EnableTls bool TlsHostName string } // createSDKClient 创建 sdk client // // @Description: // @param nodeConfs // @param chainId // @param chainMode // @param userKey // @param userCert // @param hashMethod // @return *chainmaker_sdk_go.ChainClient // @return error func createSDKClient(nodeConfs []NodeConf, chainId, chainMode, userKey, userCert, hashMethod string) (*chainmaker_sdk_go.ChainClient, error) { rpcConf := chainmaker_sdk_go.NewRPCClientConfig( chainmaker_sdk_go.WithRPCClientGetTxTimeout(60), chainmaker_sdk_go.WithRPCClientSendTxTimeout(60), chainmaker_sdk_go.WithRPCClientMaxReceiveMessageSize(100), chainmaker_sdk_go.WithRPCClientMaxSendMessageSize(100), ) cryptoConf := chainmaker_sdk_go.NewCryptoConfig( chainmaker_sdk_go.WithHashAlgo(hashMethod), ) sdkClientOpts := []chainmaker_sdk_go.ChainClientOption{ chainmaker_sdk_go.WithChainClientChainId(chainId), chainmaker_sdk_go.WithCryptoConfig(cryptoConf), chainmaker_sdk_go.WithRetryInterval(500), chainmaker_sdk_go.WithRetryLimit(20), chainmaker_sdk_go.WithEnableNormalKey(false), chainmaker_sdk_go.WithRPCClientConfig(rpcConf), } // 添加多个 node 配置 for _, n := range nodeConfs { nodeConf := chainmaker_sdk_go.NewNodeConfig( chainmaker_sdk_go.WithNodeAddr(n.Url), chainmaker_sdk_go.WithNodeConnCnt(10), chainmaker_sdk_go.WithNodeUseTLS(n.EnableTls), chainmaker_sdk_go.WithNodeTLSHostName(n.TlsHostName), ) sdkClientOpts = append(sdkClientOpts, chainmaker_sdk_go.AddChainClientNodeConfig(nodeConf)) } key, err := base64.StdEncoding.DecodeString(userKey) if err != nil { return nil, fmt.Errorf("failed to base64 decode userKey,err: %v", err) } switch chainMode { case KEY_MODE_PK: sdkClientOpts = append(sdkClientOpts, chainmaker_sdk_go.WithAuthType("public"), chainmaker_sdk_go.WithUserSignKeyBytes(key), ) case KEY_MODE_CERT: cert, err1 := base64.StdEncoding.DecodeString(userCert) if err1 != nil { return nil, fmt.Errorf("failed to base64 decode userCert,err: %v", err1) } orgId, err2 := GetOrgId(cert) if err2 != nil { return nil, fmt.Errorf("failed to gert org id from cert,err: %v", err2) } sdkClientOpts = append(sdkClientOpts, chainmaker_sdk_go.WithAuthType("permissionedWithKey"), chainmaker_sdk_go.WithChainClientOrgId(orgId), chainmaker_sdk_go.WithUserKeyBytes(key), chainmaker_sdk_go.WithUserCrtBytes(cert), ) } var sdkClient *chainmaker_sdk_go.ChainClient if userKey != "" { sdkClient, err = chainmaker_sdk_go.NewChainClient(sdkClientOpts...) if err != nil { return nil, fmt.Errorf("failed to new sdk client,err: %v", err) } } else { sdkClient, err = chainmaker_sdk_go.NewChainClientWithoutKey(sdkClientOpts...) if err != nil { return nil, fmt.Errorf("failed to new sdk client,err: %v", err) } } return sdkClient, nil } // CreateSDKClient 创建 sdk client // // @Description: // @param nodeConfs // @param chainId // @param chainMode // @param userKey // @param userCert // @param hashMethod // @return *chainmaker_sdk_go.ChainClient // @return error func CreateSDKClient(nodeConfs []NodeConf, chainId, chainMode, userKey, userCert, hashMethod string) (*chainmaker_sdk_go.ChainClient, error) { return createSDKClient(nodeConfs, chainId, chainMode, userKey, userCert, hashMethod) } // CreateSDKClientWithoutKey 创建 sdk client // // @Description: // @param nodeConfs // @param chainId // @param chainMode // @param hashMethod // @return *chainmaker_sdk_go.ChainClient // @return error func CreateSDKClientWithoutKey(nodeConfs []NodeConf, chainId, chainMode, hashMethod string) (*chainmaker_sdk_go.ChainClient, error) { return createSDKClient(nodeConfs, chainId, chainMode, "", "", hashMethod) } // GetOrgId 获取证书中的 org id // // @Description: // @param cert // @return string // @return error func GetOrgId(cert []byte) (string, error) { pemBlock, _ := pem.Decode(cert) if pemBlock == nil { return "", errors.New("invalid pem format cert") } c, err := x509.ParseCertificate(pemBlock.Bytes) if err != nil { return "", fmt.Errorf("failed to x509 parse cert,err: %v", err) } orgId := "" if len(c.Issuer.Organization) > 0 { orgId = c.Issuer.Organization[0] } return orgId, nil }