Decentralized Discord
Let's build Trustless Discord, a decentralized, unstoppable, and open messaging application.
create a new server
join an existing server
create a channel on an existing server
post a message to the created channel
get all messages posted to a channel
Write the Trustless Discord smart contract
It turns out that writing the Trustless Discord smart contract is very simple. Here is a basic contract to provide a decentralized social application.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract Discord {
struct Server {
address creator;
string serverName;
}
struct Channel {
address creator;
string serverName;
string channelName;
}
struct Message {
address sender;
string message;
}
mapping(string => Server) public servers;
mapping(address => mapping(string => uint8)) public joinInfo;
mapping(string => Channel) public channels;
mapping(string => mapping(string => Message[])) public messages;
function createServer(string memory _sname) public {
require(keccak256(abi.encodePacked(servers[_sname].serverName)) == keccak256(abi.encodePacked("")), "The server name is existed already");
servers[_sname] = Server(
msg.sender,
_sname
);
}
function joinServer(string memory _sname) public {
require(keccak256(abi.encodePacked(_sname)) != keccak256(abi.encodePacked("")), "Server name must be not empty");
require(keccak256(abi.encodePacked(servers[_sname].serverName)) != keccak256(abi.encodePacked("")), "The server name is not existed yet");
require(joinInfo[msg.sender][_sname] == 0, "You have joined the server already");
joinInfo[msg.sender][_sname] = 1;
}
function createChannel(string memory _sname, string memory _cname) public {
require(keccak256(abi.encodePacked(_sname)) != keccak256(abi.encodePacked("")), "Server name must be not empty");
require(keccak256(abi.encodePacked(_cname)) != keccak256(abi.encodePacked("")), "Channel name must be not empty");
require(keccak256(abi.encodePacked(servers[_sname].serverName)) != keccak256(abi.encodePacked("")), "The server name is not existed yet");
channels[_cname] = Channel(
msg.sender,
servers[_sname].serverName,
_cname
);
}
function postMessage(string memory _sname, string memory _cname, string memory _message) public {
require(joinInfo[msg.sender][_sname] != 0, "You have not joined the server");
require(keccak256(abi.encodePacked(channels[_cname].channelName)) != keccak256(abi.encodePacked("")), "The channel is not existed yet");
Message memory newMsg = Message(
msg.sender,
_message
);
messages[_sname][_cname].push(newMsg);
}
function getMessages(string memory _sname, string memory _cname) public view returns (string memory, string memory, Message[] memory) {
return (_sname, _cname, messages[_sname][_cname]);
}
}Clone the smart contract examples
We've prepared a few different examples for you to get started. The Messenger example is located at smart-contract-examples/contracts/Discord.sol.
Compile the contracts
To compile your contracts, use the built-in hardhat compile task.
Deploy the contracts
Review config file hardhat.config.ts. The network configs should look like this.
We'll deploy Trustless Discord on Layer 2, because it needs low latency.
Run the deploy scripts using hardhat-deploy.
Make sure the accounts in hardhat.config.ts have some $BVM.
Interact with the contracts
Once the contracts are deployed, you can interact with them. We've prepared a few hardhat tasks to make it easy for you to interact with the contracts.
Last updated