Luisnguyen1 commited on
Commit
5c12778
·
1 Parent(s): fb2d702
Files changed (4) hide show
  1. Meeting.sol +5 -2
  2. callSM.go +533 -0
  3. luonghoatdong.md +18 -0
  4. main.go +49 -83
Meeting.sol CHANGED
@@ -52,7 +52,7 @@ contract Meeting {
52
  address private owner;
53
 
54
  // Events
55
- event RoomCreated(string roomId, string name, address owner);
56
  event JoinedRoom(string roomId, address user);
57
  event LeftRoom(string roomId, address user);
58
  event TrackPublished(string roomId, address participant, string trackName);
@@ -139,9 +139,11 @@ contract Meeting {
139
  rooms[roomId].isActive = true;
140
 
141
  roomIds.push(roomId);
142
- emit RoomCreated(roomId, name, msg.sender);
 
143
  }
144
 
 
145
  function setRoomStatus(string memory roomId, bool isActive) public roomMustExist(roomId) {
146
  require(rooms[roomId].owner == msg.sender || users[msg.sender].isModerator, "Not authorized");
147
 
@@ -193,6 +195,7 @@ contract Meeting {
193
  return bytes(rooms[roomId].name).length > 0;
194
  }
195
 
 
196
  // Participant management
197
  function joinRoom(string memory roomId) public roomMustExist(roomId) {
198
  require(rooms[roomId].participants[msg.sender].user == address(0), "Already joined");
 
52
  address private owner;
53
 
54
  // Events
55
+ event RoomCreated(string roomId, string name, string metadata ,address owner ,uint256 timestamp, bool isActive);
56
  event JoinedRoom(string roomId, address user);
57
  event LeftRoom(string roomId, address user);
58
  event TrackPublished(string roomId, address participant, string trackName);
 
139
  rooms[roomId].isActive = true;
140
 
141
  roomIds.push(roomId);
142
+
143
+ emit RoomCreated(roomId, name, metadata , msg.sender, rooms[roomId].createdAt , true);
144
  }
145
 
146
+
147
  function setRoomStatus(string memory roomId, bool isActive) public roomMustExist(roomId) {
148
  require(rooms[roomId].owner == msg.sender || users[msg.sender].isModerator, "Not authorized");
149
 
 
195
  return bytes(rooms[roomId].name).length > 0;
196
  }
197
 
198
+
199
  // Participant management
200
  function joinRoom(string memory roomId) public roomMustExist(roomId) {
201
  require(rooms[roomId].participants[msg.sender].user == address(0), "Already joined");
callSM.go ADDED
@@ -0,0 +1,533 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // package main
2
+
3
+ // import (
4
+ // "context"
5
+ // "crypto/ecdsa"
6
+ // "fmt"
7
+ // "log"
8
+ // "math/big"
9
+ // "os"
10
+ // "strings"
11
+
12
+ // "github.com/ethereum/go-ethereum"
13
+ // "github.com/ethereum/go-ethereum/accounts/abi"
14
+ // "github.com/ethereum/go-ethereum/common"
15
+ // "github.com/ethereum/go-ethereum/core/types"
16
+ // "github.com/ethereum/go-ethereum/crypto"
17
+ // "github.com/ethereum/go-ethereum/ethclient"
18
+ // "github.com/joho/godotenv"
19
+ // )
20
+
21
+ // // Global variables
22
+ // var (
23
+ // client *ethclient.Client
24
+ // contractAddress common.Address
25
+ // parsedABI abi.ABI
26
+ // privateKey *ecdsa.PrivateKey
27
+ // fromAddress common.Address
28
+ // chainID *big.Int
29
+ // )
30
+
31
+ // func init() {
32
+ // // Load environment variables
33
+ // if err := godotenv.Load(); err != nil {
34
+ // log.Fatal("Error loading .env file")
35
+ // }
36
+
37
+ // // Connect to the blockchain
38
+ // var err error
39
+ // client, err = ethclient.Dial("https://bsc-testnet.publicnode.com") // BSC Testnet
40
+ // if err != nil {
41
+ // log.Fatalf("Failed to connect to the blockchain: %v", err)
42
+ // }
43
+
44
+ // // Load contract information
45
+ // contractAddress = common.HexToAddress(os.Getenv("CONTRACT_ADDRESS"))
46
+ // parsedABI, err = abi.JSON(strings.NewReader(os.Getenv("ABI_JSON")))
47
+ // if err != nil {
48
+ // log.Fatalf("Failed to parse ABI: %v", err)
49
+ // }
50
+
51
+ // // Load private key
52
+ // privateKey, err = crypto.HexToECDSA(os.Getenv("PRIVATE_KEY"))
53
+ // if err != nil {
54
+ // log.Fatalf("Failed to parse private key: %v", err)
55
+ // }
56
+
57
+ // // Get public key and address
58
+ // publicKey := privateKey.Public()
59
+ // publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
60
+ // if !ok {
61
+ // log.Fatal("Error converting public key")
62
+ // }
63
+ // fromAddress = crypto.PubkeyToAddress(*publicKeyECDSA)
64
+
65
+ // // Set chain ID for BSC Testnet
66
+ // chainID = big.NewInt(97)
67
+
68
+ // fmt.Printf("Connected to blockchain with address: %s\n", fromAddress.Hex())
69
+ // }
70
+
71
+ // // Read function example - getAllRooms
72
+ // func getAllRooms() {
73
+ // callData, err := parsedABI.Pack("getAllRooms")
74
+ // if err != nil {
75
+ // log.Fatalf("Failed to pack call data: %v", err)
76
+ // }
77
+
78
+ // result, err := client.CallContract(context.Background(), ethereum.CallMsg{
79
+ // To: &contractAddress,
80
+ // Data: callData,
81
+ // }, nil)
82
+ // if err != nil {
83
+ // log.Fatalf("Failed to call getAllRooms: %v", err)
84
+ // }
85
+
86
+ // var roomIds []string
87
+ // err = parsedABI.UnpackIntoInterface(&roomIds, "getAllRooms", result)
88
+ // if err != nil {
89
+ // log.Fatalf("Failed to unpack result: %v", err)
90
+ // }
91
+
92
+ // fmt.Println("All Room IDs:")
93
+ // for i, roomId := range roomIds {
94
+ // fmt.Printf("%d. %s\n", i+1, roomId)
95
+ // }
96
+ // }
97
+
98
+ // // Read function - getRoomDetails
99
+ // func getRoomDetails(roomId string) {
100
+ // callData, err := parsedABI.Pack("getRoomDetails", roomId)
101
+ // if err != nil {
102
+ // log.Fatalf("Failed to pack call data: %v", err)
103
+ // }
104
+
105
+ // result, err := client.CallContract(context.Background(), ethereum.CallMsg{
106
+ // To: &contractAddress,
107
+ // Data: callData,
108
+ // }, nil)
109
+ // if err != nil {
110
+ // log.Fatalf("Failed to call getRoomDetails: %v", err)
111
+ // }
112
+
113
+ // // Unpack result
114
+ // output, err := parsedABI.Unpack("getRoomDetails", result)
115
+ // if err != nil {
116
+ // log.Fatalf("Failed to unpack result: %v", err)
117
+ // }
118
+
119
+ // // Process output
120
+ // if len(output) == 6 {
121
+ // fmt.Println("Room Details:")
122
+ // fmt.Printf("ID: %s\n", output[0].(string))
123
+ // fmt.Printf("Name: %s\n", output[1].(string))
124
+ // fmt.Printf("Metadata: %s\n", output[2].(string))
125
+ // fmt.Printf("Owner: %s\n", output[3].(common.Address).Hex())
126
+ // fmt.Printf("Created At: %s\n", output[4].(*big.Int).String())
127
+ // fmt.Printf("Is Active: %t\n", output[5].(bool))
128
+ // } else {
129
+ // fmt.Println("Unexpected output format")
130
+ // }
131
+ // }
132
+
133
+ // // Read function - getRoomParticipants
134
+ // func getRoomParticipants(roomId string) {
135
+ // callData, err := parsedABI.Pack("getRoomParticipants", roomId)
136
+ // if err != nil {
137
+ // log.Fatalf("Failed to pack call data: %v", err)
138
+ // }
139
+
140
+ // result, err := client.CallContract(context.Background(), ethereum.CallMsg{
141
+ // To: &contractAddress,
142
+ // Data: callData,
143
+ // }, nil)
144
+ // if err != nil {
145
+ // log.Fatalf("Failed to call getRoomParticipants: %v", err)
146
+ // }
147
+
148
+ // var participants []common.Address
149
+ // err = parsedABI.UnpackIntoInterface(&participants, "getRoomParticipants", result)
150
+ // if err != nil {
151
+ // log.Fatalf("Failed to unpack result: %v", err)
152
+ // }
153
+
154
+ // fmt.Printf("Participants in room %s:\n", roomId)
155
+ // for i, address := range participants {
156
+ // fmt.Printf("%d. %s\n", i+1, address.Hex())
157
+ // }
158
+ // }
159
+
160
+ // // Read function - getIceServers
161
+ // func getIceServers() {
162
+ // callData, err := parsedABI.Pack("getIceServers")
163
+ // if err != nil {
164
+ // log.Fatalf("Failed to pack call data: %v", err)
165
+ // }
166
+
167
+ // result, err := client.CallContract(context.Background(), ethereum.CallMsg{
168
+ // To: &contractAddress,
169
+ // Data: callData,
170
+ // }, nil)
171
+ // if err != nil {
172
+ // log.Fatalf("Failed to call getIceServers: %v", err)
173
+ // }
174
+
175
+ // // This is a bit trickier due to struct array return type
176
+ // // Just showing raw result for now
177
+ // fmt.Printf("ICE Servers Raw Result: %x\n", result)
178
+ // }
179
+
180
+ // // Write function - createRoom
181
+ // func createRoom(roomId, name, metadata string) {
182
+ // nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
183
+ // if err != nil {
184
+ // log.Fatalf("Failed to get nonce: %v", err)
185
+ // }
186
+
187
+ // gasPrice, err := client.SuggestGasPrice(context.Background())
188
+ // if err != nil {
189
+ // log.Fatalf("Failed to get gas price: %v", err)
190
+ // }
191
+
192
+ // // Pack the data for the function call
193
+ // data, err := parsedABI.Pack("createRoom", roomId, name, metadata)
194
+ // if err != nil {
195
+ // log.Fatalf("Failed to pack transaction data: %v", err)
196
+ // }
197
+
198
+ // // Estimate gas
199
+ // gasLimit := uint64(500000) // Default high value
200
+ // estimatedGas, err := client.EstimateGas(context.Background(), ethereum.CallMsg{
201
+ // From: fromAddress,
202
+ // To: &contractAddress,
203
+ // Value: big.NewInt(0),
204
+ // Data: data,
205
+ // })
206
+
207
+ // if err == nil {
208
+ // // Add 20% buffer to estimated gas
209
+ // gasLimit = uint64(float64(estimatedGas) * 1.2)
210
+ // fmt.Printf("Gas estimate: %d, using: %d\n", estimatedGas, gasLimit)
211
+ // } else {
212
+ // fmt.Printf("Gas estimation failed: %v. Using default: %d\n", err, gasLimit)
213
+ // }
214
+
215
+ // // Create the transaction
216
+ // tx := types.NewTransaction(nonce, contractAddress, big.NewInt(0), gasLimit, gasPrice, data)
217
+
218
+ // // Sign the transaction
219
+ // signedTx, err := types.SignTx(tx, types.NewLondonSigner(chainID), privateKey)
220
+ // if err != nil {
221
+ // log.Fatalf("Failed to sign transaction: %v", err)
222
+ // }
223
+
224
+ // // Send the transaction
225
+ // err = client.SendTransaction(context.Background(), signedTx)
226
+ // if err != nil {
227
+ // log.Fatalf("Failed to send transaction: %v", err)
228
+ // }
229
+
230
+ // fmt.Printf("Transaction sent! Hash: %s\n", signedTx.Hash().Hex())
231
+ // fmt.Println("Room creation initiated. Wait for the transaction to be mined.")
232
+ // }
233
+
234
+ // // Write function - joinRoom
235
+ // func joinRoom(roomId string) {
236
+ // nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
237
+ // if err != nil {
238
+ // log.Fatalf("Failed to get nonce: %v", err)
239
+ // }
240
+
241
+ // gasPrice, err := client.SuggestGasPrice(context.Background())
242
+ // if err != nil {
243
+ // log.Fatalf("Failed to get gas price: %v", err)
244
+ // }
245
+
246
+ // // Pack the data for the function call
247
+ // data, err := parsedABI.Pack("joinRoom", roomId)
248
+ // if err != nil {
249
+ // log.Fatalf("Failed to pack transaction data: %v", err)
250
+ // }
251
+
252
+ // gasLimit := uint64(300000)
253
+
254
+ // // Create the transaction
255
+ // tx := types.NewTransaction(nonce, contractAddress, big.NewInt(0), gasLimit, gasPrice, data)
256
+
257
+ // // Sign the transaction
258
+ // signedTx, err := types.SignTx(tx, types.NewLondonSigner(chainID), privateKey)
259
+ // if err != nil {
260
+ // log.Fatalf("Failed to sign transaction: %v", err)
261
+ // }
262
+
263
+ // // Send the transaction
264
+ // err = client.SendTransaction(context.Background(), signedTx)
265
+ // if err != nil {
266
+ // log.Fatalf("Failed to send transaction: %v", err)
267
+ // }
268
+
269
+ // fmt.Printf("Transaction sent! Hash: %s\n", signedTx.Hash().Hex())
270
+ // fmt.Println("Room join initiated. Wait for the transaction to be mined.")
271
+ // }
272
+
273
+ // // Write function - leaveRoom
274
+ // func leaveRoom(roomId string) {
275
+ // nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
276
+ // if err != nil {
277
+ // log.Fatalf("Failed to get nonce: %v", err)
278
+ // }
279
+
280
+ // gasPrice, err := client.SuggestGasPrice(context.Background())
281
+ // if err != nil {
282
+ // log.Fatalf("Failed to get gas price: %v", err)
283
+ // }
284
+
285
+ // // Pack the data for the function call
286
+ // data, err := parsedABI.Pack("leaveRoom", roomId)
287
+ // if err != nil {
288
+ // log.Fatalf("Failed to pack transaction data: %v", err)
289
+ // }
290
+
291
+ // gasLimit := uint64(300000)
292
+
293
+ // // Create the transaction
294
+ // tx := types.NewTransaction(nonce, contractAddress, big.NewInt(0), gasLimit, gasPrice, data)
295
+
296
+ // // Sign the transaction
297
+ // signedTx, err := types.SignTx(tx, types.NewLondonSigner(chainID), privateKey)
298
+ // if err != nil {
299
+ // log.Fatalf("Failed to sign transaction: %v", err)
300
+ // }
301
+
302
+ // // Send the transaction
303
+ // err = client.SendTransaction(context.Background(), signedTx)
304
+ // if err != nil {
305
+ // log.Fatalf("Failed to send transaction: %v", err)
306
+ // }
307
+
308
+ // fmt.Printf("Transaction sent! Hash: %s\n", signedTx.Hash().Hex())
309
+ // fmt.Println("Room leave initiated. Wait for the transaction to be mined.")
310
+ // }
311
+
312
+ // // Write function - saveSessionID
313
+ // func saveSessionID(roomId, sessionID string) {
314
+ // nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
315
+ // if err != nil {
316
+ // log.Fatalf("Failed to get nonce: %v", err)
317
+ // }
318
+
319
+ // gasPrice, err := client.SuggestGasPrice(context.Background())
320
+ // if err != nil {
321
+ // log.Fatalf("Failed to get gas price: %v", err)
322
+ // }
323
+
324
+ // // Pack the data for the function call
325
+ // data, err := parsedABI.Pack("saveSessionID", roomId, sessionID)
326
+ // if err != nil {
327
+ // log.Fatalf("Failed to pack transaction data: %v", err)
328
+ // }
329
+
330
+ // gasLimit := uint64(300000)
331
+
332
+ // // Create the transaction
333
+ // tx := types.NewTransaction(nonce, contractAddress, big.NewInt(0), gasLimit, gasPrice, data)
334
+
335
+ // // Sign the transaction
336
+ // signedTx, err := types.SignTx(tx, types.NewLondonSigner(chainID), privateKey)
337
+ // if err != nil {
338
+ // log.Fatalf("Failed to sign transaction: %v", err)
339
+ // }
340
+
341
+ // // Send the transaction
342
+ // err = client.SendTransaction(context.Background(), signedTx)
343
+ // if err != nil {
344
+ // log.Fatalf("Failed to send transaction: %v", err)
345
+ // }
346
+
347
+ // fmt.Printf("Transaction sent! Hash: %s\n", signedTx.Hash().Hex())
348
+ // fmt.Println("Session ID save initiated. Wait for the transaction to be mined.")
349
+ // }
350
+
351
+ // // Write function - updateRoomMetadata
352
+ // func updateRoomMetadata(roomId, key, value string) {
353
+ // nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
354
+ // if err != nil {
355
+ // log.Fatalf("Failed to get nonce: %v", err)
356
+ // }
357
+
358
+ // gasPrice, err := client.SuggestGasPrice(context.Background())
359
+ // if err != nil {
360
+ // log.Fatalf("Failed to get gas price: %v", err)
361
+ // }
362
+
363
+ // // Pack the data for the function call
364
+ // data, err := parsedABI.Pack("updateRoomMetadata", roomId, key, value)
365
+ // if err != nil {
366
+ // log.Fatalf("Failed to pack transaction data: %v", err)
367
+ // }
368
+
369
+ // gasLimit := uint64(300000)
370
+
371
+ // // Create the transaction
372
+ // tx := types.NewTransaction(nonce, contractAddress, big.NewInt(0), gasLimit, gasPrice, data)
373
+
374
+ // // Sign the transaction
375
+ // signedTx, err := types.SignTx(tx, types.NewLondonSigner(chainID), privateKey)
376
+ // if err != nil {
377
+ // log.Fatalf("Failed to sign transaction: %v", err)
378
+ // }
379
+
380
+ // // Send the transaction
381
+ // err = client.SendTransaction(context.Background(), signedTx)
382
+ // if err != nil {
383
+ // log.Fatalf("Failed to send transaction: %v", err)
384
+ // }
385
+
386
+ // fmt.Printf("Transaction sent! Hash: %s\n", signedTx.Hash().Hex())
387
+ // fmt.Println("Metadata update initiated. Wait for the transaction to be mined.")
388
+ // }
389
+
390
+ // // Write function - setRoomStatus
391
+ // func setRoomStatus(roomId string, isActive bool) {
392
+ // nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
393
+ // if err != nil {
394
+ // log.Fatalf("Failed to get nonce: %v", err)
395
+ // }
396
+
397
+ // gasPrice, err := client.SuggestGasPrice(context.Background())
398
+ // if err != nil {
399
+ // log.Fatalf("Failed to get gas price: %v", err)
400
+ // }
401
+
402
+ // // Pack the data for the function call
403
+ // data, err := parsedABI.Pack("setRoomStatus", roomId, isActive)
404
+ // if err != nil {
405
+ // log.Fatalf("Failed to pack transaction data: %v", err)
406
+ // }
407
+
408
+ // gasLimit := uint64(300000)
409
+
410
+ // // Create the transaction
411
+ // tx := types.NewTransaction(nonce, contractAddress, big.NewInt(0), gasLimit, gasPrice, data)
412
+
413
+ // // Sign the transaction
414
+ // signedTx, err := types.SignTx(tx, types.NewLondonSigner(chainID), privateKey)
415
+ // if err != nil {
416
+ // log.Fatalf("Failed to sign transaction: %v", err)
417
+ // }
418
+
419
+ // // Send the transaction
420
+ // err = client.SendTransaction(context.Background(), signedTx)
421
+ // if err != nil {
422
+ // log.Fatalf("Failed to send transaction: %v", err)
423
+ // }
424
+
425
+ // fmt.Printf("Transaction sent! Hash: %s\n", signedTx.Hash().Hex())
426
+ // fmt.Println("Room status update initiated. Wait for the transaction to be mined.")
427
+ // }
428
+
429
+ // func main() {
430
+ // fmt.Println("Smart Contract Testing Tool")
431
+ // fmt.Println("===========================")
432
+
433
+ // for {
434
+ // fmt.Println("\nSelect an operation:")
435
+ // fmt.Println("Read Operations:")
436
+ // fmt.Println("1. Get All Rooms")
437
+ // fmt.Println("2. Get Room Details")
438
+ // fmt.Println("3. Get Room Participants")
439
+ // fmt.Println("4. Get ICE Servers")
440
+ // fmt.Println("\nWrite Operations:")
441
+ // fmt.Println("5. Create Room")
442
+ // fmt.Println("6. Join Room")
443
+ // fmt.Println("7. Leave Room")
444
+ // fmt.Println("8. Save Session ID")
445
+ // fmt.Println("9. Update Room Metadata")
446
+ // fmt.Println("10. Set Room Status")
447
+ // fmt.Println("\n0. Exit")
448
+
449
+ // var choice int
450
+ // fmt.Print("\nEnter your choice: ")
451
+ // fmt.Scan(&choice)
452
+
453
+ // switch choice {
454
+ // case 0:
455
+ // fmt.Println("Exiting...")
456
+ // return
457
+
458
+ // case 1: // Get All Rooms
459
+ // getAllRooms()
460
+
461
+ // case 2: // Get Room Details
462
+ // var roomId string
463
+ // fmt.Print("Enter Room ID: ")
464
+ // fmt.Scan(&roomId)
465
+ // getRoomDetails(roomId)
466
+
467
+ // case 3: // Get Room Participants
468
+ // var roomId string
469
+ // fmt.Print("Enter Room ID: ")
470
+ // fmt.Scan(&roomId)
471
+ // getRoomParticipants(roomId)
472
+
473
+ // case 4: // Get ICE Servers
474
+ // getIceServers()
475
+
476
+ // case 5: // Create Room
477
+ // var roomId, name, metadata string
478
+ // fmt.Print("Enter Room ID: ")
479
+ // fmt.Scan(&roomId)
480
+ // fmt.Print("Enter Room Name: ")
481
+ // fmt.Scan(&name)
482
+ // fmt.Print("Enter Metadata (JSON string): ")
483
+ // fmt.Scan(&metadata)
484
+ // createRoom(roomId, name, metadata)
485
+
486
+ // case 6: // Join Room
487
+ // var roomId string
488
+ // fmt.Print("Enter Room ID: ")
489
+ // fmt.Scan(&roomId)
490
+ // joinRoom(roomId)
491
+
492
+ // case 7: // Leave Room
493
+ // var roomId string
494
+ // fmt.Print("Enter Room ID: ")
495
+ // fmt.Scan(&roomId)
496
+ // leaveRoom(roomId)
497
+
498
+ // case 8: // Save Session ID
499
+ // var roomId, sessionID string
500
+ // fmt.Print("Enter Room ID: ")
501
+ // fmt.Scan(&roomId)
502
+ // fmt.Print("Enter Session ID: ")
503
+ // fmt.Scan(&sessionID)
504
+ // saveSessionID(roomId, sessionID)
505
+
506
+ // case 9: // Update Room Metadata
507
+ // var roomId, key, value string
508
+ // fmt.Print("Enter Room ID: ")
509
+ // fmt.Scan(&roomId)
510
+ // fmt.Print("Enter Metadata Key: ")
511
+ // fmt.Scan(&key)
512
+ // fmt.Print("Enter Metadata Value: ")
513
+ // fmt.Scan(&value)
514
+ // updateRoomMetadata(roomId, key, value)
515
+
516
+ // case 10: // Set Room Status
517
+ // var roomId string
518
+ // var status int
519
+ // fmt.Print("Enter Room ID: ")
520
+ // fmt.Scan(&roomId)
521
+ // fmt.Print("Enter Status (1 for active, 0 for inactive): ")
522
+ // fmt.Scan(&status)
523
+ // isActive := status == 1
524
+ // setRoomStatus(roomId, isActive)
525
+
526
+ // default:
527
+ // fmt.Println("Invalid choice. Please try again.")
528
+ // }
529
+
530
+ // fmt.Println("\nPress Enter to continue...")
531
+ // fmt.Scanln() // Wait for Enter
532
+ // }
533
+ // }
luonghoatdong.md ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ graph LR
2
+ A[Client (Frontend)] --> B(Backend Server - Go package main)
3
+ B --> C[Cloudflare Calls API]
4
+ B <--> D[WebSocket Connections]
5
+ B --> E[Data Storage (In-memory)]
6
+
7
+ subgraph "Backend Server (Go)"
8
+ B -- Gin HTTP Routes --> B1[Route Handlers]
9
+ B -- WebSocket Endpoint --> B2[WebSocket Handler]
10
+ B1 --> B3[Cloudflare API Functions]
11
+ B2 --> B4[Broadcast Functions]
12
+ B1 & B2 --> E
13
+ end
14
+
15
+ style B fill:#f9f,stroke:#333,stroke-width:2px
16
+ style C fill:#ccf,stroke:#333,stroke-width:1px
17
+ style D fill:#ccf,stroke:#333,stroke-width:1px
18
+ style E fill:#eee,stroke:#333,stroke-width:1px
main.go CHANGED
@@ -3,7 +3,6 @@ package main
3
  import (
4
  "bytes"
5
  "context"
6
- "crypto/ecdsa"
7
  "crypto/hmac"
8
  "crypto/sha256"
9
  "encoding/base64"
@@ -11,7 +10,6 @@ import (
11
  "fmt"
12
  "io"
13
  "log"
14
- "math/big"
15
  "net/http"
16
  "os"
17
  "strconv"
@@ -19,10 +17,10 @@ import (
19
  "sync"
20
  "time"
21
 
 
22
  "github.com/ethereum/go-ethereum/accounts/abi"
23
  "github.com/ethereum/go-ethereum/common"
24
  "github.com/ethereum/go-ethereum/core/types"
25
- "github.com/ethereum/go-ethereum/crypto"
26
  "github.com/ethereum/go-ethereum/ethclient"
27
  "github.com/gin-gonic/gin"
28
  "github.com/golang-jwt/jwt/v5"
@@ -614,22 +612,12 @@ func serializeRoom(roomId string, room *Room) gin.H {
614
 
615
  // --- Route Handlers ---
616
 
617
- func createRoom(c *gin.Context) {
618
- roomId := uuid.NewString()
619
- var req struct {
620
- Name string `json:"name"`
621
- Metadata map[string]interface{} `json:"metadata"`
622
- }
623
-
624
- if err := c.ShouldBindJSON(&req); err != nil {
625
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
626
- return
627
- }
628
 
629
  room := &Room{
630
  RoomId: roomId, // Thêm trường này
631
- Name: req.Name,
632
- Metadata: req.Metadata,
633
  Participants: []*Participant{},
634
  CreatedAt: time.Now().Unix(),
635
  }
@@ -638,13 +626,6 @@ func createRoom(c *gin.Context) {
638
  rooms.m[roomId] = room
639
  rooms.Unlock()
640
 
641
- // Update data on the smart contract
642
- err := updateRoomOnContract(roomId, req.Name, req.Metadata)
643
- if err != nil {
644
- c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update smart contract", "details": err.Error()})
645
- return
646
- }
647
-
648
  log.Printf("Room metadata: %s", room.Metadata)
649
 
650
  // Trả về format giống Express
@@ -655,66 +636,7 @@ func createRoom(c *gin.Context) {
655
  "participantCount": len(room.Participants),
656
  "createdAt": room.CreatedAt,
657
  })
658
- }
659
-
660
- func updateRoomOnContract(roomId string, name string, metadata map[string]interface{}) error {
661
- client, err := ethclient.Dial(RPC_URL)
662
- if err != nil {
663
- return fmt.Errorf("failed to connect to blockchain: %v", err)
664
- }
665
- defer client.Close()
666
-
667
- contractAddress := common.HexToAddress(CONTRACT_ADDRESS)
668
- parsedABI, err := abi.JSON(strings.NewReader(ABI_JSON))
669
- if err != nil {
670
- return fmt.Errorf("failed to parse ABI: %v", err)
671
- }
672
-
673
- privateKey, err := crypto.HexToECDSA(PRIVATE_KEY)
674
- if err != nil {
675
- return fmt.Errorf("failed to parse private key: %v", err)
676
- }
677
- publicKey := privateKey.Public()
678
- publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
679
- if !ok {
680
- return fmt.Errorf("error converting public key")
681
- }
682
- fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
683
-
684
- nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
685
- if err != nil {
686
- return fmt.Errorf("failed to get nonce: %v", err)
687
- }
688
- gasLimit := uint64(300000)
689
- gasPrice, err := client.SuggestGasPrice(context.Background())
690
- if err != nil {
691
- return fmt.Errorf("failed to get gas price: %v", err)
692
- }
693
-
694
- metadataJSON, err := json.Marshal(metadata)
695
- if err != nil {
696
- return fmt.Errorf("failed to marshal metadata: %v", err)
697
- }
698
-
699
- data, err := parsedABI.Pack("createRoom", roomId, name, string(metadataJSON))
700
- if err != nil {
701
- return fmt.Errorf("failed to pack transaction data: %v", err)
702
- }
703
 
704
- tx := types.NewTransaction(nonce, contractAddress, big.NewInt(0), gasLimit, gasPrice, data)
705
- chainID := big.NewInt(97) // BSC Testnet chain ID
706
- signedTx, err := types.SignTx(tx, types.NewLondonSigner(chainID), privateKey)
707
- if err != nil {
708
- return fmt.Errorf("failed to sign transaction: %v", err)
709
- }
710
-
711
- err = client.SendTransaction(context.Background(), signedTx)
712
- if err != nil {
713
- return fmt.Errorf("failed to send transaction: %v", err)
714
- }
715
-
716
- log.Printf("Transaction sent! Hash: %s", signedTx.Hash().Hex())
717
- return nil
718
  }
719
 
720
  func inspectRooms(c *gin.Context) {
@@ -1859,7 +1781,7 @@ func main() {
1859
  api := r.Group("/api", verifyToken)
1860
  {
1861
  // Match Express routes
1862
- api.POST("/rooms", createRoom)
1863
  api.GET("/rooms", getRooms)
1864
  api.GET("/inspect-rooms", inspectRooms)
1865
  api.POST("/rooms/:roomId/join", joinRoom)
@@ -1887,4 +1809,48 @@ func main() {
1887
  if err := r.Run(":" + port); err != nil {
1888
  log.Fatal("Failed to start server:", err)
1889
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1890
  }
 
3
  import (
4
  "bytes"
5
  "context"
 
6
  "crypto/hmac"
7
  "crypto/sha256"
8
  "encoding/base64"
 
10
  "fmt"
11
  "io"
12
  "log"
 
13
  "net/http"
14
  "os"
15
  "strconv"
 
17
  "sync"
18
  "time"
19
 
20
+ "github.com/ethereum/go-ethereum"
21
  "github.com/ethereum/go-ethereum/accounts/abi"
22
  "github.com/ethereum/go-ethereum/common"
23
  "github.com/ethereum/go-ethereum/core/types"
 
24
  "github.com/ethereum/go-ethereum/ethclient"
25
  "github.com/gin-gonic/gin"
26
  "github.com/golang-jwt/jwt/v5"
 
612
 
613
  // --- Route Handlers ---
614
 
615
+ func createRoom(c *gin.Context, roomId string, name string, metadata map[string]interface{}) {
 
 
 
 
 
 
 
 
 
 
616
 
617
  room := &Room{
618
  RoomId: roomId, // Thêm trường này
619
+ Name: name,
620
+ Metadata: metadata,
621
  Participants: []*Participant{},
622
  CreatedAt: time.Now().Unix(),
623
  }
 
626
  rooms.m[roomId] = room
627
  rooms.Unlock()
628
 
 
 
 
 
 
 
 
629
  log.Printf("Room metadata: %s", room.Metadata)
630
 
631
  // Trả về format giống Express
 
636
  "participantCount": len(room.Participants),
637
  "createdAt": room.CreatedAt,
638
  })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
639
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
640
  }
641
 
642
  func inspectRooms(c *gin.Context) {
 
1781
  api := r.Group("/api", verifyToken)
1782
  {
1783
  // Match Express routes
1784
+ // api.POST("/rooms", createRoom)
1785
  api.GET("/rooms", getRooms)
1786
  api.GET("/inspect-rooms", inspectRooms)
1787
  api.POST("/rooms/:roomId/join", joinRoom)
 
1809
  if err := r.Run(":" + port); err != nil {
1810
  log.Fatal("Failed to start server:", err)
1811
  }
1812
+
1813
+ // Tạo Phòng và lắng nghe smrtract
1814
+ client, err := ethclient.Dial(RPC_URL)
1815
+ if err != nil {
1816
+ log.Fatalf("Không thể kết nối đến BSC Testnet: %v", err)
1817
+ }
1818
+ fmt.Println("Đã kết nối đến BSC Testnet!")
1819
+
1820
+ contractAddress := common.HexToAddress(CONTRACT_ADDRESS)
1821
+ query := ethereum.FilterQuery{
1822
+ Addresses: []common.Address{contractAddress},
1823
+ }
1824
+
1825
+ contractAbi, err := abi.JSON(strings.NewReader(ABI_JSON))
1826
+ if err != nil {
1827
+ log.Fatalf("Không thể phân tích ABI: %v", err)
1828
+ }
1829
+
1830
+ logs := make(chan types.Log)
1831
+ sub, err := client.SubscribeFilterLogs(context.Background(), query, logs)
1832
+ fmt.Println("Đã kết nối đến BSC Testnet!", sub)
1833
+ if err != nil {
1834
+ log.Fatalf("Không thể đăng ký lắng nghe sự kiện: %v", err)
1835
+ }
1836
+ fmt.Println("Đang lắng nghe sự kiện RoomCreated...")
1837
+
1838
+ type RoomCreatedEvent struct {
1839
+ RoomId string `abi:"roomId"`
1840
+ Name string `abi:"name"`
1841
+ Metadata string `abi:"metadata"`
1842
+ Owner common.Address `abi:"owner"`
1843
+ Timestamp int64 `abi:"timestamp"`
1844
+ IsActive bool `abi:"isActive"`
1845
+ }
1846
+ go func() {
1847
+ for eventLog := range logs {
1848
+ event := new(RoomCreatedEvent)
1849
+ if err := contractAbi.UnpackIntoInterface(event, "RoomCreated", eventLog.Data); err != nil {
1850
+ log.Printf("Lỗi giải mã sự kiện: %v", err)
1851
+ continue
1852
+ }
1853
+ fmt.Printf("Sự kiện RoomCreated: RoomId=%s, Name=%s, Owner=%s\n", event.RoomId, event.Name, event.Owner.Hex())
1854
+ }
1855
+ }()
1856
  }