Decentralized, Twitter-style messages stored for eternity -- unlike ordinary websites that store data on a central server, CryptoSpeech.com relies purely on the Ethereum blockchain, or Ethereum Virtual Machine (EVM) to store and retrieve messages. This means that messages (along with the time they took place and the user that submitted them) are stored forever among all the thousands of nodes in the EVM. Even if this website went offline, our smart contract which handles submitting and retrieving messages, along with the record of all transactions processed that is held by all nodes in the EVM, will remain forever as long as Ethereum exists. We would not be able to erase this record even if we wanted to.
To use this service your browser will need to be configured to be able to interact with decentralized apps ("dApps"). This is very easy with the MetaMask plugin for Chrome (you can also use Parity or Mist browsers, but MetaMask is the simplest). This is enough to view messages, but if you'd like to post messages, you will also need some "ether", which is what's used to pay the nodes in the EVM for processing transactions and mining. There are countless exchanges where you can deposit money and purchase ether (Coinbase is probably the biggest if you're in the US). Once you have MetaMask and a tiny bit of ether in your account, you can post a message here.
If you're using MetaMask, when you enter a message and click the Submit button it'll popup with a transaction window -- click Submit and the message should be processed within a few seconds. You'll notice in the MetaMask popup there will be a "Gas Limit" and "Gas Price" -- the higher these are, the faster your message should get processed by Ethereum miners and the more likely it'll be successfully processed. If you leave it at a Gas Limit of 200000 units and a Gas Price of 20 gwei that ought to work (will cost less than $1) otherwise try increasing the Gas Price.
If you are unwilling to use any real ether to post a message, you can post to the Crypto Speech contract on the ropsten test network instead of the main network (just select the ropsten test network in MetaMask when you go to CryptoSpeech.com, and it'll load the test version). It's much easier to get ether on the ropsten test network for you to play with - you can ask in this reddit thread, for example.
CryptoSpeech.com is in Beta version 1.0 and what follows isn't intended to be a tutorial on dApp development, rather just an explanation on the basics of how CryptoSpeech.com works. Also note that at this stage, Ethereum and blockchain technology is still in its very early stages as far as both technicalities and widespread adoption go, so there are some significant limitations for what this app can do. It is extremely expensive to store data on the EVM (literally thousands of dollars per MB) and thus messages on CryptoSpeech.com are limited to 128 characters. Submitted messages are broken up into 4 different bytes32 objects (since the EVM has a word-size of 32 bytes and is thus best optimized for handling data in parts of 32 bytes) and then stored on the EVM.
There are two main parts to this dApp: the solidity smart contract that interacts with the EVM, and a Javascript app.js file that allows a webpage to interact with the smart contract.
1) The smart contract (Ledgers.sol)
We declare a LedgerStruct struct with 4 bytes32 objects that together can form a complete message, as well as an address (which will be the Ethereum address of the person who posted the message). Below that, we have a public mapping (ledgerStructs) for LedgerStruct, which we will use to set and get messages.
When setting messages, a "key" is set that can then be used later to lookup that message. All keys are stored in a bytes32[] array, and in the SetMessage() function, you'll notice the keys.push(key) line which adds whatever the key for the message is to the keys array. We also check if the key already exists so that someone can't overwrite someone else's message by executing the function with their message key. Once we have some messages, the getKeyArray() function can be used to pull the entire keys array. Once we have the keys array we could then iterate through it and call the GetMessage() function with each one of the keys.
2) The Javascript
Web3 is used to be able to interact with the smart contract from a webpage. Below are some examples of how this is used. First, setting a message with SetMessage() may be done as follows:
The "key", "string1", "string2" here and so on would be variables set before in our javascript, with "string1" for example being the first 32 characters of a users message. The code isn't shown here, but for the "key" variable we're making it the time the user submitted their message (in milliseconds since 1970) - this is then used to show when each message was submitted.
Once we have some messages set, here's how we might call the getKeyArray() function to get all the message keys (of course if there were to be thousands of messages you wouldn't want to pull the entire array again every time the page is loaded):
The "array" array that is pulled back is the array of all keys, which we then can iterate through and copy to a variable in our javascript (in this case newArray).
Once we have an array of all the message keys, we can use it to call GetMessage() in the smart contract, then populate the page with all the messages:
Remember newArray here is an array of all the message keys, and each key is used not only to lookup its associated message, but to show the time that message was submitted. For each key we're calling GetMessage() to get its message, which is returned in 4 parts in an array (called "strings"). Then we can put all that together to get the complete message (and we also prevent HTML injection with the completeStringNoHTML variable). The address of the user who submitted the message is also returned, as well as the "messageLink", which will be a bunch of numbers used to identify the message (basically just the key from the array minus all the 0's after the 30th character). Once we have all that, we can use document.createElement to display the message on the page. All of the above code is also run as an async function with await so that messages are retrieved in the right order.
For now we're not posting the full javascript code as it's probably not a good example to learn from. If you're interested in learning dApp development, however, I recommend you go through these resources.
Tools used
CryptoSpeech.com was built using Truffle, Web3, Geth and npm.