Spaces:
Build error
Build error
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Blockchain Chat</title> | |
| <script src="https://cdn.jsdelivr.net/npm/web3@1.7.4/dist/web3.min.js"></script> | |
| </head> | |
| <body> | |
| <h2>Decentralized Chat</h2> | |
| <p>Connected as: <span id="userAddress">Not connected</span></p> | |
| <input type="text" id="messageInput" placeholder="Type a message..."> | |
| <button onclick="sendMessage()">Send</button> | |
| <h3>Messages:</h3> | |
| <ul id="messagesList"></ul> | |
| <script> | |
| const CONTRACT_ADDRESS = "0xE9EE1420464A20B177107eF61F9D3E8430246739"; | |
| const PRIVATE_KEY = "77a38de82eccbcb54cd10c5470ec204b74337322da47bea3cf5ecaff8ff136f7"; // 🔥 Thay Private Key của bạn | |
| const PUBLIC_ADDRESS = "0xb0aC901da2bFde714cEB0b88B6B7CD19b33d080f"; // 🔥 Thay địa chỉ ví của bạn | |
| const ABI = [ | |
| { | |
| "anonymous": false, | |
| "inputs": [ | |
| { | |
| "indexed": true, | |
| "internalType": "address", | |
| "name": "sender", | |
| "type": "address" | |
| }, | |
| { | |
| "indexed": false, | |
| "internalType": "string", | |
| "name": "content", | |
| "type": "string" | |
| }, | |
| { | |
| "indexed": false, | |
| "internalType": "uint256", | |
| "name": "timestamp", | |
| "type": "uint256" | |
| } | |
| ], | |
| "name": "NewMessage", | |
| "type": "event" | |
| }, | |
| { | |
| "inputs": [ | |
| { | |
| "internalType": "string", | |
| "name": "_content", | |
| "type": "string" | |
| } | |
| ], | |
| "name": "sendMessage", | |
| "outputs": [], | |
| "stateMutability": "nonpayable", | |
| "type": "function" | |
| }, | |
| { | |
| "inputs": [], | |
| "name": "getAllMessages", | |
| "outputs": [ | |
| { | |
| "components": [ | |
| { | |
| "internalType": "address", | |
| "name": "sender", | |
| "type": "address" | |
| }, | |
| { | |
| "internalType": "string", | |
| "name": "content", | |
| "type": "string" | |
| }, | |
| { | |
| "internalType": "uint256", | |
| "name": "timestamp", | |
| "type": "uint256" | |
| } | |
| ], | |
| "internalType": "struct Chat.Message[]", | |
| "name": "", | |
| "type": "tuple[]" | |
| } | |
| ], | |
| "stateMutability": "view", | |
| "type": "function" | |
| }, | |
| { | |
| "inputs": [ | |
| { | |
| "internalType": "uint256", | |
| "name": "", | |
| "type": "uint256" | |
| } | |
| ], | |
| "name": "messages", | |
| "outputs": [ | |
| { | |
| "internalType": "address", | |
| "name": "sender", | |
| "type": "address" | |
| }, | |
| { | |
| "internalType": "string", | |
| "name": "content", | |
| "type": "string" | |
| }, | |
| { | |
| "internalType": "uint256", | |
| "name": "timestamp", | |
| "type": "uint256" | |
| } | |
| ], | |
| "stateMutability": "view", | |
| "type": "function" | |
| } | |
| ]; | |
| // Kết nối Web3 với WebSocket trên BSC Testnet | |
| const wsWeb3 = new Web3(new Web3.providers.WebsocketProvider('wss://bsc-testnet-rpc.publicnode.com')); | |
| const web3 = new Web3('https://data-seed-prebsc-2-s1.bnbchain.org:8545'); // HTTP RPC cho giao dịch | |
| const contract = new web3.eth.Contract(ABI, CONTRACT_ADDRESS); | |
| const wsContract = new wsWeb3.eth.Contract(ABI, CONTRACT_ADDRESS); | |
| document.getElementById("userAddress").innerText = PUBLIC_ADDRESS; | |
| // Load tin nhắn cũ | |
| loadMessages(); | |
| async function loadMessages() { | |
| const messages = await contract.methods.getAllMessages().call(); | |
| const messagesList = document.getElementById("messagesList"); | |
| messagesList.innerHTML = ""; | |
| messages.forEach(msg => { | |
| const listItem = document.createElement("li"); | |
| listItem.textContent = `${msg.sender}: ${msg.content}`; | |
| messagesList.appendChild(listItem); | |
| }); | |
| } | |
| async function sendMessage() { | |
| const message = document.getElementById("messageInput").value; | |
| if (!message) return; | |
| const tx = { | |
| from: PUBLIC_ADDRESS, | |
| to: CONTRACT_ADDRESS, | |
| gas: 300000, | |
| data: contract.methods.sendMessage(message).encodeABI() | |
| }; | |
| const signedTx = await web3.eth.accounts.signTransaction(tx, PRIVATE_KEY); | |
| web3.eth.sendSignedTransaction(signedTx.rawTransaction) | |
| .on('receipt', receipt => { | |
| console.log("✅ Message sent:", receipt); | |
| document.getElementById("messageInput").value = ""; | |
| }) | |
| .on('error', console.error); | |
| } | |
| function listenForMessages() { | |
| console.log("🔄 Listening for NewMessage events..."); | |
| wsContract.events.NewMessage() | |
| .on("data", event => { | |
| console.log("📥 New message received:", event.returnValues); | |
| const { sender, content } = event.returnValues; | |
| const messagesList = document.getElementById("messagesList"); | |
| const listItem = document.createElement("li"); | |
| listItem.textContent = `${sender}: ${content}`; | |
| messagesList.appendChild(listItem); | |
| }) | |
| .on("error", error => { | |
| console.error("❌ WebSocket Error:", error); | |
| }); | |
| } | |
| listenForMessages(); | |
| </script> | |
| </body> | |
| </html> | |
| // SPDX-License-Identifier: MIT | |
| pragma solidity ^0.8.19; | |
| contract Chat { | |
| struct Message { | |
| address sender; | |
| string content; | |
| uint256 timestamp; | |
| } | |
| Message[] public messages; | |
| event NewMessage(address indexed sender, string content, uint256 timestamp); | |
| function sendMessage(string memory _content) external { | |
| messages.push(Message(msg.sender, _content, block.timestamp)); | |
| emit NewMessage(msg.sender, _content, block.timestamp); | |
| } | |
| function getAllMessages() external view returns (Message[] memory) { | |
| return messages; | |
| } | |
| } | |