@@ -2,6 +2,7 @@ package client
import (
"bytes"
"crypto"
"crypto/rand"
"encoding/hex"
"encoding/json"
@@ -10,10 +11,12 @@ import (
"log"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"github.com/tjfoc/gmsm/sm2"
"golang.org/x/sync/errgroup"
"go.fusiongalaxy.cn/bdware/bdcontract-client/sm2util"
)
@@ -56,19 +59,32 @@ func NewClient(
} , nil
}
// RequestWithSignature
// @Description 发送带有签名的请求
// @Param path 请求路径
// @Param http 请求方法(GET | POST)
// @Param result 接收请求返回结果的结构体指针
// @Param body 请求体( 尽在method为POST时使用)
// @Param priv 请求私钥
// @Param pub 请求公钥
func ( c * Client ) RequestWithSignature (
path string ,
method string ,
result any ,
body map [ string ] interface { } ,
priv * sm2 . PrivateKey ,
pub * sm2 . PublicKey ,
) ( statusCode int , respBody io . ReadCloser , err error ) {
) ( response HttpResponse [ any ] , err error ) {
response = HttpResponse [ any ] {
Status : 0 ,
}
var pubHex string
if priv != nil {
var err error
pubHex , err = sm2util . CheckSm2KeyPair ( priv , pub )
if err != nil {
return 0 , nil , err
return response , err
}
} else {
priv = c . priv
@@ -87,30 +103,70 @@ func (c *Client) RequestWithSignature(
pubHex ,
)
var resp * http . Response
switch strings . ToUpper ( method ) {
case "POST" :
body[ "sign" ] = c . Sign ( u [ strings . Index ( u , "?" ) + 1 : ] , priv )
if body = = nil {
body = make ( map [ string ] interface { } )
}
body [ "sign" ] = c . Sign ( u [ strings . Index ( u , "?" ) + 1 : ] , priv , nil )
bodyJson , err := json . Marshal ( body )
if err != nil {
return 0 , nil , err
return response , err
}
resp , err : = c . httpc . Post ( rawUrl , "application/json" , bytes . NewBuffer ( bodyJson ) )
resp , err = c . httpc . Post ( rawUrl , "application/json" , bytes . NewBuffer ( bodyJson ) )
if err != nil {
return 0 , nil , err
return response , err
}
respBody = resp . Body
case "GET" :
params := url . Values {
"sign" : { c . Sign ( u [ strings . Index ( u , "?" ) + 1 : ] , priv , nil ) } ,
"pubKey" : { pubHex } ,
}
return statusCode , respBody , nil
if strings . Contains ( rawUrl , "?" ) {
rawUrl = rawUrl + "&" + params . Encode ( )
} else {
rawUrl = rawUrl + "?" + params . Encode ( )
}
func ( c * Client ) Sign ( data string , priv * sm2 . PrivateKey ) string {
resp , err = c . httpc . Get ( rawUrl )
if err != nil {
return response , err
}
default :
return response , fmt . Errorf ( "unsupported method: %s" , method )
}
defer resp . Body . Close ( )
// 读取所有数据直到 EOF
bodyBytes , err := io . ReadAll ( resp . Body )
// 如果bodyBytes不能被json解析直接将信息保存到ErrData
if err != nil || ! json . Valid ( bodyBytes ) {
response . ErrData = string ( bodyBytes )
return response , nil
}
err = json . Unmarshal ( bodyBytes , result )
// 如果bodyBytes解析失败直接将信息保存到ErrData
if err != nil {
response . ErrData = string ( bodyBytes )
return response , nil
}
response . Status = resp . StatusCode
return response , nil
}
func ( c * Client ) Sign ( data string , priv * sm2 . PrivateKey , signer crypto . SignerOpts ) string {
if priv == nil {
priv = c . priv
}
sig , err := priv . Sign ( rand . Reader , [ ] byte ( data ) , nil )
sig , err := priv . Sign ( rand . Reader , [ ] byte ( data ) , signer )
if err != nil {
log . Fatal ( err )
}
@@ -125,68 +181,820 @@ func genUrlParamsFromObject(obj map[string]interface{}) string {
return strings . Join ( params , "&" )
}
func retry [ T any ] ( fn func ( ) ( int , T , error ) ) (int , T , error ) {
func retry [ T any ] ( fn func ( ) ( T , error ) ) ( T , error ) {
var lastErr error
for attempt := 0 ; attempt < 3 ; attempt ++ {
resp , statusCode , err := fn ( )
resp , err := fn ( )
if err == nil {
return resp , statusCode , nil
return resp , nil
}
lastErr = err
time . Sleep ( 100 * time . Millisecond * time . Duration ( attempt + 1 ) )
}
var zero T
return 0 , zero , lastErr
return zero , lastErr
}
func ( c * Client ) Ping ( ) ( statusCode int , resp * Ping Response, err error ) {
return retry ( func ( ) ( statusCode int , resp * PingResponse , err error ) {
statusCode , respBody , err := c . RequestWithSignature (
func genHttpResponse [ D any ] ( data D , response * Http Response[ any ] , err error ) ( * HttpResponse [ D ] , error ) {
return & HttpResponse [ D ] {
Data : data ,
Status : response . Status ,
ErrData : response . ErrData ,
} , err
}
// Ping https://public.internetapi.cn/docs/bdcontract/doc/ContractAPI.html#id15
func ( c * Client ) Ping ( ) ( * HttpResponse [ PingResponse ] , error ) {
return retry ( func ( ) ( * HttpResponse [ PingResponse ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
"/SCManager?action=ping" ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
if err != nil {
return 0 , nil , err
}
defer respBody . Close ( )
decoder := json . NewDecoder ( respBody )
if err := decoder . Decode ( & resp ) ; err != nil {
return 0 , nil , err
}
return statusCode , resp , nil
return genHttpResponse [ PingResponse ] ( result , & resp , err )
} )
}
func ( c * Client ) StartContract ( code string ) ( statusCode int , resp string , err error ) {
// StartContract TODO 未跑通
// StartContract 启动合约
// https://public.internetapi.cn/docs/bdcontract/doc/ContractAPI.html#id60
func ( c * Client ) StartContract ( code string ) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : { "startContract" } ,
"script" : { code } ,
}
path := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( int , string , error ) {
statusCode , respBody , err := c . RequestWithSignature (
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
path ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
if err != nil {
return 0 , "" , err
}
var resp string
defer respBody . Close ( )
buf := new ( strings . Builder )
if _ , err := io . Copy ( buf , respBody ) ; err != nil {
return 0 , "" , err
}
return statusCode , resp , nil
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// StartContractByYPK TODO 待测试
// StartContractByYPK 启动合约
// https://public.internetapi.cn/docs/bdcontract/doc/ContractAPI.html#id13
func ( c * Client ) StartContractByYPK ( isPrivate bool , path string , script string ) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : [ ] string { "startContractByYPK" } ,
"script" : [ ] string { script } ,
"isPrivate" : [ ] string { strconv . FormatBool ( isPrivate ) } ,
"path" : [ ] string { path } ,
"owner" : [ ] string { c . pubHex } ,
"aim" : [ ] string { "onStartContract" } ,
"signature" : [ ] string { c . Sign ( "Fixed|" + path + "|" + c . pubHex , nil , nil ) } ,
}
httpPath := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
httpPath ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// ExecuteContract 调用合约
// https://public.internetapi.cn/docs/bdcontract/doc/ContractAPI.html#id69
func ( c * Client ) ExecuteContract (
contractID string ,
operation string ,
arg string ,
withDynamicAnalysis bool ,
withSignature bool ,
) ( * HttpResponse [ ExecuteContractResponse [ any ] ] , error ) {
body := map [ string ] any {
"action" : "executeContract" ,
"contractID" : contractID ,
"operation" : operation ,
"withDynamicAnalysis" : withDynamicAnalysis ,
"arg" : arg ,
}
if withSignature {
body [ "signature" ] = c . Sign ( contractID + "|" + operation + "|" + arg + "|" + c . pubHex , nil , nil )
body [ "pubkey" ] = c . pubHex
}
return retry ( func ( ) ( * HttpResponse [ ExecuteContractResponse [ any ] ] , error ) {
result := ExecuteContractResponse [ any ] { }
resp , err := c . RequestWithSignature (
"/SCManager" ,
"POST" ,
& result ,
body ,
nil ,
nil ,
)
return genHttpResponse [ ExecuteContractResponse [ any ] ] ( result , & resp , err )
} )
}
// KillContractProcess TODO 待测试
// KillContractProcess 停止合约
// https://public.internetapi.cn/docs/bdcontract/doc/ContractAPI.html#id122
func ( c * Client ) KillContractProcess ( contractID string , requestID string ) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : [ ] string { "killContractProcess" } ,
"id" : [ ] string { contractID } ,
}
if requestID != "" {
params [ "requestID" ] = [ ] string { requestID }
}
httpPath := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
httpPath ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// KillAllContract TODO 待测试
// KillAllContract 停止所有合约
// https://public.internetapi.cn/docs/bdcontract/doc/ContractAPI.html#id131
func ( c * Client ) KillAllContract ( ) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : [ ] string { "killAllContract" } ,
}
httpPath := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
httpPath ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// ApplyNodeRole TODO 待测试
// ApplyNodeRole 申请角色
// https://public.internetapi.cn/docs/bdcontract/doc/ContractAPI.html
func ( c * Client ) ApplyNodeRole ( role string ) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : [ ] string { "applyNodeRole" } ,
"role" : [ ] string { role } ,
}
httpPath := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
httpPath ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// AuthNodeRole TODO 待测试
// AuthNodeRole 授权角色
// https://public.internetapi.cn/docs/bdcontract/doc/ContractAPI.html
func ( c * Client ) AuthNodeRole (
isAccept bool ,
authorizedPubKey string ,
priv * sm2 . PrivateKey ,
pub * sm2 . PublicKey ,
) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : [ ] string { "authNodeRole" } ,
"isAccept" : [ ] string { strconv . FormatBool ( isAccept ) } ,
"authorizedPubKey" : [ ] string { authorizedPubKey } ,
}
httpPath := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
httpPath ,
"GET" ,
& result ,
nil ,
priv ,
pub ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// DistributeContract TODO 待测试, 用sse获取问题未解决! ! !
// 分发合约项目
// https://public.internetapi.cn/docs/bdcontract/doc/ContractAPI.html
//func (c *Client) DistributeContract(
// nodeIDs string,
// projectName string,
// isPrivate bool,
//) (*HttpResponse[any], error) {
// params := url.Values{
// "action": []string{"distributeContract"},
// "isPrivate": []string{strconv.FormatBool(isPrivate)},
// "nodeIDs": []string{nodeIDs},
// "projectName": []string{projectName},
// }
//
// httpPath := fmt.Sprintf("/SCManager?%s", params.Encode())
//
// return retry(func() (*HttpResponse[any], error) {
// result := PingResponse{}
// resp, err := c.RequestWithSignature(
// httpPath,
// "GET",
// &result,
// nil,
// nil,
// nil,
// )
//
// return genHttpResponse[any](result, &resp, err)
// })
//}
// SaveFile TODO 待测试
func ( c * Client ) SaveFile (
content string ,
isAppend bool ,
isPrivate bool ,
path string ,
) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : [ ] string { "saveFile" } ,
"isAppend" : [ ] string { strconv . FormatBool ( isAppend ) } ,
"isPrivate" : [ ] string { strconv . FormatBool ( isPrivate ) } ,
"content" : [ ] string { content } ,
"path" : [ ] string { path } ,
}
httpPath := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
httpPath ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// ListProjectPermission TODO 待测试
func ( c * Client ) ListProjectPermission (
isPrivate bool ,
path string ,
) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : [ ] string { "listProjectPermission" } ,
"isPrivate" : [ ] string { strconv . FormatBool ( isPrivate ) } ,
"path" : [ ] string { path } ,
}
httpPath := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
httpPath ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// StartContractMultiPoint TODO 待测试
func ( c * Client ) StartContractMultiPoint (
peersID string ,
contractType int ,
selectUnitNum int ,
projectName string ,
isPrivate bool ,
sponsorPeerID string ,
) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : [ ] string { "startContractMultiPoint" } ,
"peersID" : [ ] string { peersID } ,
"projectName" : [ ] string { projectName } ,
"sponsorPeerID" : [ ] string { sponsorPeerID } ,
"isPrivate" : [ ] string { strconv . FormatBool ( isPrivate ) } ,
"contractType" : [ ] string { strconv . Itoa ( contractType ) } ,
"selectUnitNum" : [ ] string { strconv . Itoa ( selectUnitNum ) } ,
}
httpPath := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
httpPath ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// LoadNodeConfig TODO 待测试
// 获取节点配置信息
// https://public.internetapi.cn/docs/bdcontract/doc/ContractAPI.html#id497
func ( c * Client ) LoadNodeConfig ( ) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : [ ] string { "loadNodeConfig" } ,
}
httpPath := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
httpPath ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// UpdateConfig TODO 待测试
// 修改节点配置
// https://public.internetapi.cn/docs/bdcontract/doc/ContractAPI.html#id504
// @Param key {licence, projectDir, yjsPath, dataChain, doipConfig, nodeCenter, nodeName, masterAddress, resetNodeCenterWS}
func ( c * Client ) UpdateConfig ( key string , val string ) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : [ ] string { "updateConfig" } ,
"key" : [ ] string { key } ,
"val" : [ ] string { val } ,
}
httpPath := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
httpPath ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// ResetNodeManager TODO 待测试
// 设置pubkey为node manager
func ( c * Client ) ResetNodeManager ( ) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : [ ] string { "resetNodeManager" } ,
}
httpPath := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
httpPath ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// LockEdit TODO 待测试
// 锁定某个用户的的私有目录编辑功能
func ( c * Client ) LockEdit ( ) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : [ ] string { "lockEdit" } ,
}
httpPath := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
httpPath ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// UnlockEdit TODO 待测试
// 解锁某个用户的的私有目录编辑功能
func ( c * Client ) UnlockEdit ( ) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : [ ] string { "unlockEdit" } ,
}
httpPath := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
httpPath ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// AddNode TODO 待测试
func ( c * Client ) AddNode ( nodePubKey string ) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : [ ] string { "addNode" } ,
"nodePubKey" : [ ] string { nodePubKey } ,
}
httpPath := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
httpPath ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// ApplyRole TODO 待测试
// 申请角色
func ( c * Client ) ApplyRole ( role string ) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : [ ] string { "applyRole" } ,
"role" : [ ] string { role } ,
}
httpPath := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
httpPath ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// AuthNodeManager TODO 待测试
func ( c * Client ) AuthNodeManager ( isAccept bool , authorizedPubKey string ) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : [ ] string { "authNodeManager" } ,
"isAccept" : [ ] string { strconv . FormatBool ( isAccept ) } ,
"authorizedPubKey" : [ ] string { authorizedPubKey } ,
}
httpPath := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
httpPath ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// ListAllUsers TODO 待测试
func ( c * Client ) ListAllUsers ( ) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : [ ] string { "listAllUsers" } ,
}
httpPath := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
httpPath ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// ListNodes TODO 待测试
func ( c * Client ) ListNodes ( ) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : [ ] string { "listNodes" } ,
}
httpPath := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
httpPath ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// CreateTrustUnit TODO 待测试
// 建立可信执行集群
// https://public.internetapi.cn/docs/bdcontract/doc/ContractAPI.html#id664
func ( c * Client ) CreateTrustUnit (
data [ ] struct {
nodeName string
pubkey string
} ,
msg string ,
) ( * HttpResponse [ any ] , error ) {
body := map [ string ] any {
"action" : "createTrustUnit" ,
"data" : data ,
"msg" : msg ,
"pubKey" : c . pubHex ,
"sign" : c . Sign ( "action=createTrustUnit&data=" + fmt . Sprintf ( "%v" , data ) + "&msg=" + msg + "&pubKey=" + c . pubHex , nil , nil ) ,
}
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
"/SCManager" ,
"POST" ,
& result ,
body ,
nil ,
nil ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// ListTrustUnits TODO 待测试
// 查看可信执行集群列表
// https://public.internetapi.cn/docs/bdcontract/doc/ContractAPI.html#id657
func ( c * Client ) ListTrustUnits ( ) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : [ ] string { "listTrustUnits" } ,
}
httpPath := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
httpPath ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// ListContractProcess TODO 待测试
// 查询合约进程
// https://public.internetapi.cn/docs/bdcontract/doc/ContractAPI.html#id444
func ( c * Client ) ListContractProcess ( ) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : [ ] string { "listContractProcess" } ,
}
httpPath := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
httpPath ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// DownloadContract TODO 待测试
// 下载合约项目
// https://public.internetapi.cn/docs/bdcontract/doc/ContractAPI.html#id25
func ( c * Client ) DownloadContract ( projectName string , isPrivate bool , timestamp int ) ( * HttpResponse [ any ] , error ) {
params := url . Values {
"action" : [ ] string { "downloadContract" } ,
"projectName" : [ ] string { projectName } ,
"isPrivate" : [ ] string { strconv . FormatBool ( isPrivate ) } ,
"timestamp" : [ ] string { strconv . Itoa ( timestamp ) } ,
}
httpPath := fmt . Sprintf ( "/SCManager?%s" , params . Encode ( ) )
return retry ( func ( ) ( * HttpResponse [ any ] , error ) {
result := PingResponse { }
resp , err := c . RequestWithSignature (
httpPath ,
"GET" ,
& result ,
nil ,
nil ,
nil ,
)
return genHttpResponse [ any ] ( result , & resp , err )
} )
}
// ConfigNode TODO 待测试
// 配置合约引擎节点, 若节点没有设置过node manager, 将当前key设置为node manager
// struct arg {
// nodeName string
// dataChain string
// masterAddress string
// nodeCenter string
// // 配置中心节点时使用
// LHSProxyAddress string
// }
func ( c * Client ) ConfigNode ( arg map [ string ] string ) bool {
res , err := c . ResetNodeManager ( )
if err != nil || res . Status == 0 {
return false
}
eg := errgroup . Group { }
for key , value := range arg {
eg . Go ( func ( ) error {
res , err = c . UpdateConfig ( key , value )
if err != nil {
return err
}
if res . Status == 0 {
return fmt . Errorf ( res . ErrData )
}
return nil
} )
}
for _ , value := range [ ] string { "ContractProvider" , "ContractUser" , "ContractInstanceManager" } {
eg . Go ( func ( ) error {
res , err = c . ApplyNodeRole ( value )
if err != nil {
return err
}
if res . Status == 0 {
return fmt . Errorf ( res . ErrData )
}
return nil
} )
}
eg . Go ( func ( ) error {
res , err = c . AuthNodeRole ( true , c . pubHex , nil , nil )
if err != nil {
return err
}
if res . Status == 0 {
return fmt . Errorf ( res . ErrData )
}
return nil
} )
err = eg . Wait ( )
if err != nil {
return false
}
res , err = c . LoadNodeConfig ( )
if err != nil || res . Status == 0 {
return false
}
for k , v := range arg {
if arg [ remapNodeConfigKey ( k ) ] != v {
return false
}
}
return true
}
func remapNodeConfigKey ( k string ) string {
switch k {
case "dataChain" :
return "bdledger"
default :
return k
}
}