github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/imocc/application/main.go (about) 1 package main 2 3 import ( 4 "fmt" 5 6 "context" 7 "time" 8 9 "net/http" 10 11 "bytes" 12 13 "github.com/gin-gonic/gin" 14 "github.com/hyperledger/fabric-sdk-go/pkg/client/channel" 15 "github.com/hyperledger/fabric-sdk-go/pkg/client/event" 16 "github.com/hyperledger/fabric-sdk-go/pkg/client/ledger" 17 "github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt" 18 "github.com/hyperledger/fabric-sdk-go/pkg/core/config" 19 "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" 20 ) 21 22 func main() { 23 router := gin.Default() 24 25 // 定义路由 26 { 27 router.POST("/users", userRegister) 28 router.GET("/users/:id", queryUser) 29 router.DELETE("/users/:id", deleteUser) 30 router.GET("/assets/get/:id", queryAsset) 31 router.POST("/assets/enroll", assetsEnroll) 32 router.POST("/assets/exchange", assetsExchange) 33 router.GET("/assets/exchange/history", assetsExchangeHistory) 34 } 35 36 router.Run() // listen and serve on 0.0.0.0:8080 37 } 38 39 type UserRegisterRequest struct { 40 Id string `form:"id" binding:"required"` 41 Name string `form:"name" binding:"required"` 42 } 43 44 // 用户开户 45 func userRegister(ctx *gin.Context) { 46 // 参数处理 47 req := new(UserRegisterRequest) 48 if err := ctx.ShouldBind(req); err != nil { 49 ctx.AbortWithError(400, err) 50 return 51 } 52 53 // 区块链交互 54 resp, err := channelExecute("userRegister", [][]byte{ 55 []byte(req.Name), 56 []byte(req.Id), 57 }) 58 59 if err != nil { 60 ctx.String(http.StatusOK, err.Error()) 61 return 62 } 63 64 ctx.JSON(http.StatusOK, resp) 65 } 66 67 // 查询用户 68 func queryUser(ctx *gin.Context) { 69 userId := ctx.Param("id") 70 71 resp, err := channelQuery("queryUser", [][]byte{ 72 []byte(userId), 73 }) 74 75 if err != nil { 76 ctx.String(http.StatusOK, err.Error()) 77 return 78 } 79 80 //ctx.JSON(http.StatusOK, resp) 81 ctx.String(http.StatusOK, bytes.NewBuffer(resp.Payload).String()) 82 } 83 84 // 用户销户 85 func deleteUser(ctx *gin.Context) { 86 userId := ctx.Param("id") 87 88 resp, err := channelExecute("userDestroy", [][]byte{ 89 []byte(userId), 90 }) 91 92 if err != nil { 93 ctx.String(http.StatusOK, err.Error()) 94 return 95 } 96 97 ctx.JSON(http.StatusOK, resp) 98 } 99 100 // 资产查询 101 func queryAsset(ctx *gin.Context) { 102 assetId := ctx.Param("id") 103 104 resp, err := channelQuery("queryAsset", [][]byte{ 105 []byte(assetId), 106 }) 107 108 if err != nil { 109 ctx.String(http.StatusOK, err.Error()) 110 return 111 } 112 113 //ctx.JSON(http.StatusOK, resp) 114 ctx.String(http.StatusOK, bytes.NewBuffer(resp.Payload).String()) 115 } 116 117 type AssetsEnrollRequest struct { 118 AssetId string `form:"assetsid" binding:"required"` 119 AssetName string `form:"assetname" binding:"required"` 120 Metadata string `form:"metadata" binding:"required"` 121 OwnerId string `form:"ownerid" binding:"required"` 122 } 123 124 // 资产登记 125 func assetsEnroll(ctx *gin.Context) { 126 req := new(AssetsEnrollRequest) 127 if err := ctx.ShouldBind(req); err != nil { 128 ctx.AbortWithError(400, err) 129 return 130 } 131 132 resp, err := channelExecute("assetEnroll", [][]byte{ 133 []byte(req.AssetName), 134 []byte(req.AssetId), 135 []byte(req.Metadata), 136 []byte(req.OwnerId), 137 }) 138 139 if err != nil { 140 ctx.String(http.StatusOK, err.Error()) 141 return 142 } 143 144 ctx.JSON(http.StatusOK, resp) 145 } 146 147 type AssetsExchangeRequest struct { 148 AssetId string `form:"assetsid" binding:"required"` 149 OriginOwnerId string `form:"originownerid" binding:"required"` 150 CurrentOwnerId string `form:"currentownerid" binding:"required"` 151 } 152 153 // 资产转让 154 func assetsExchange(ctx *gin.Context) { 155 req := new(AssetsExchangeRequest) 156 if err := ctx.ShouldBind(req); err != nil { 157 ctx.AbortWithError(400, err) 158 return 159 } 160 161 resp, err := channelExecute("assetExchange", [][]byte{ 162 []byte(req.OriginOwnerId), 163 []byte(req.AssetId), 164 []byte(req.CurrentOwnerId), 165 }) 166 167 if err != nil { 168 ctx.String(http.StatusOK, err.Error()) 169 return 170 } 171 172 ctx.JSON(http.StatusOK, resp) 173 } 174 175 // 资产历史变更记录 176 func assetsExchangeHistory(ctx *gin.Context) { 177 assetId := ctx.Query("assetid") 178 queryType := ctx.Query("querytype") 179 180 resp, err := channelQuery("queryAssetHistory", [][]byte{ 181 []byte(assetId), 182 []byte(queryType), 183 }) 184 185 if err != nil { 186 ctx.String(http.StatusOK, err.Error()) 187 return 188 } 189 190 //ctx.JSON(http.StatusOK, resp) 191 ctx.String(http.StatusOK, bytes.NewBuffer(resp.Payload).String()) 192 } 193 194 var ( 195 sdk *fabsdk.FabricSDK 196 channelName = "assetschannel" 197 chaincodeName = "assets" 198 org = "org1" 199 user = "Admin" 200 //configPath = "$GOPATH/src/github.com/hyperledger/fabric/imocc/application/config.yaml" 201 configPath = "./config.yaml" 202 ) 203 204 func init() { 205 var err error 206 sdk, err = fabsdk.New(config.FromFile(configPath)) 207 if err != nil { 208 panic(err) 209 } 210 } 211 212 // 区块链管理 213 func manageBlockchain() { 214 // 表明身份 215 ctx := sdk.Context(fabsdk.WithOrg(org), fabsdk.WithUser(user)) 216 217 cli, err := resmgmt.New(ctx) 218 if err != nil { 219 panic(err) 220 } 221 222 // 具体操作 223 cli.SaveChannel(resmgmt.SaveChannelRequest{}, resmgmt.WithOrdererEndpoint("orderer.imocc.com"), resmgmt.WithTargetEndpoints()) 224 } 225 226 // 区块链数据查询 账本的查询 227 func queryBlockchain() { 228 ctx := sdk.ChannelContext(channelName, fabsdk.WithOrg(org), fabsdk.WithUser(user)) 229 230 cli, err := ledger.New(ctx) 231 if err != nil { 232 panic(err) 233 } 234 235 resp, err := cli.QueryInfo(ledger.WithTargetEndpoints("peer0.org1.imocc.com")) 236 if err != nil { 237 panic(err) 238 } 239 240 fmt.Println(resp) 241 242 // 1 243 cli.QueryBlockByHash(resp.BCI.CurrentBlockHash) 244 245 // 2 246 for i := uint64(0); i <= resp.BCI.Height; i++ { 247 cli.QueryBlock(i) 248 } 249 } 250 251 // 区块链交互 252 func channelExecute(fcn string, args [][]byte) (channel.Response, error) { 253 ctx := sdk.ChannelContext(channelName, fabsdk.WithOrg(org), fabsdk.WithUser(user)) 254 255 cli, err := channel.New(ctx) 256 if err != nil { 257 return channel.Response{}, err 258 } 259 260 // 状态更新,insert/update/delete 261 resp, err := cli.Execute(channel.Request{ 262 ChaincodeID: chaincodeName, 263 Fcn: fcn, 264 Args: args, 265 }, channel.WithTargetEndpoints("peer0.org1.imocc.com")) 266 if err != nil { 267 return channel.Response{}, err 268 } 269 270 // 链码事件监听 271 go func() { 272 // channel 273 reg, ccevt, err := cli.RegisterChaincodeEvent(chaincodeName, "eventname") 274 if err != nil { 275 return 276 } 277 defer cli.UnregisterChaincodeEvent(reg) 278 279 timeoutctx, cancel := context.WithTimeout(context.Background(), time.Minute) 280 defer cancel() 281 282 for { 283 select { 284 case evt := <-ccevt: 285 fmt.Printf("received event of tx %s: %+v", resp.TransactionID, evt) 286 case <-timeoutctx.Done(): 287 fmt.Println("event timeout, exit!") 288 return 289 } 290 } 291 292 // event 293 //eventcli, err := event.New(ctx) 294 //if err != nil { 295 // return 296 //} 297 298 //eventcli.RegisterChaincodeEvent(chaincodeName, "eventname") 299 }() 300 301 // 交易状态事件监听 302 go func() { 303 eventcli, err := event.New(ctx) 304 if err != nil { 305 return 306 } 307 308 reg, status, err := eventcli.RegisterTxStatusEvent(string(resp.TransactionID)) 309 defer eventcli.Unregister(reg) // 注册必有注销 310 311 timeoutctx, cancel := context.WithTimeout(context.Background(), time.Minute) 312 defer cancel() 313 314 for { 315 select { 316 case evt := <-status: 317 fmt.Printf("received event of tx %s: %+v", resp.TransactionID, evt) 318 case <-timeoutctx.Done(): 319 fmt.Println("event timeout, exit!") 320 return 321 } 322 } 323 }() 324 325 return resp, nil 326 } 327 328 func channelQuery(fcn string, args [][]byte) (channel.Response, error) { 329 ctx := sdk.ChannelContext(channelName, fabsdk.WithOrg(org), fabsdk.WithUser(user)) 330 331 cli, err := channel.New(ctx) 332 if err != nil { 333 return channel.Response{}, err 334 } 335 336 // 状态的查询,select 337 return cli.Query(channel.Request{ 338 ChaincodeID: chaincodeName, 339 Fcn: fcn, 340 Args: args, 341 }, channel.WithTargetEndpoints("peer0.org1.imocc.com")) 342 } 343 344 // 事件监听 345 func eventHandle() { 346 ctx := sdk.ChannelContext(channelName, fabsdk.WithOrg(org), fabsdk.WithUser(user)) 347 348 cli, err := event.New(ctx) 349 if err != nil { 350 panic(err) 351 } 352 353 // 交易状态事件 354 // 链码事件 业务事件 355 // 区块事件 356 reg, blkevent, err := cli.RegisterBlockEvent() 357 if err != nil { 358 panic(err) 359 } 360 defer cli.Unregister(reg) 361 362 timeoutctx, cancel := context.WithTimeout(context.Background(), time.Minute) 363 defer cancel() 364 365 for { 366 select { 367 case evt := <-blkevent: 368 fmt.Printf("received a block", evt) 369 case <-timeoutctx.Done(): 370 fmt.Println("event timeout, exit!") 371 return 372 } 373 } 374 }