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" ) type NodeConf struct { Url string EnableTls bool TlsHostName string } 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, err := base64.StdEncoding.DecodeString(userCert) if err != nil { return nil, fmt.Errorf("failed to base64 decode userCert,err: %v", err) } orgId, err := GetOrgId(cert) if err != nil { return nil, fmt.Errorf("failed to gert org id from cert,err: %v", err) } 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 } func CreateSDKClient(nodeConfs []NodeConf, chainId, chainMode, userKey, userCert, hashMethod string) (*chainmaker_sdk_go.ChainClient, error) { return createSDKClient(nodeConfs, chainId, chainMode, userKey, userCert, hashMethod) } func CreateSDKClientWithoutKey(nodeConfs []NodeConf, chainId, chainMode, hashMethod string) (*chainmaker_sdk_go.ChainClient, error) { return createSDKClient(nodeConfs, chainId, chainMode, "", "", hashMethod) } 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 }