---
eip: 2848
title: My Own Messages (MOM)
author: Giuseppe Bertone (@Neurone)
discussions-to: https://github.com/InternetOfPeers/EIPs/issues/1
status: Stagnant
type: Standards Track
category: ERC
created: 2020-08-02
---

## Simple Summary

My Own Messages (MOM) is a standard to create your very own public, always updated, unstoppable, verifiable, message board.

## Abstract

My Own Messages (MOM) use Ethereum as a certification layer for commands and multihash of your messages. It don't use smart contracts but simple self-send transactions with specific payload attached.

To ge more insights, you can test a [live client](http://internetofpeers.org/mom-client/), watch a [full video overview and demo](https://www.youtube.com/watch?v=z1SnoQkQYkU) and read a [brief presentation](../assets/eip-2848/presentation.pdf).

## Motivation

As a _developer_ or _pool's owner_, I'd like to send messages to my users in a decentralized way. They must be able to easily verify my role in the smart contract context (owner, user, and so on) and they must be able to do it without relying on external, insecure and hackable social media sites (Facebook, Twitter, you name it). Also, I'd like to read messages from my userbase, in the same secure and verifiable manner.

As a _user_, I want a method to easily share my thoughts and idea, publish content, send messages, receive feedback, receive tips, and so on, without dealing with any complexity: just write a message, send it and it's done. Also, I want to write to some smart contract's owner or to the sender of some transaction.

As an _explorer service_, I want to give my users an effective way to read information by smart contract owners and a place to share ideas and information without using third party services (i.e. Etherscan uses Disqus, and so on)

And in _any role_, I want a method that does not allow scams - transactions without values, no smart contract's address to remember or to fake - and it does not allow spam - it's cheap but not free, and even if you can link/refer other accounts, you cannot send them messages directly, and others must explicitly follow and listen to your transactions if they want to read your messages.

Main advantages:

- You can send messages to users of your ÐApp or Smart Contract, and they always know it is a voice reliable as the smart contract is.
- Create your Ethereum account dedicated to your personal messages, say something only once and it can be seen on every social platform (no more reply of the same post/opinion on dozens of sites like Reddit, Twitter, Facebook, Medium, Disqus, and so on...)
- Small fee to be free: pay just few cents of dollar to notarize your messages, and distribute them with IPFS, Swarm or any other storage you prefer. Because the multihash of the content is notarized, you can always check the integrity of the message you download even from centralized storage services.
- Finally, you can ask and get tips for your words directly into your wallet.

I know, My Own Messages (MOM) sounds like _mom_. And yes, pun intended :)

## Specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt) when, and only when, they appear in all capitals as shown here.

Clients following MOM standard **MUST** allow users to send and to read MOM transaction, creating an _updated message list_ for each address the users are interested in.

Reading MOM transactions, MOM clients **MUST** be able to show the current and updated message list, and they **SHOULD** be able to show also all the message history if users ask for it.

Apart from message list, MOM clients **SHOULD** be able to download the content of the messages and to show them to the user.

Clients **SHOULD** allow users to choose and set the source to download content from, and they **SHOULD** be able to use common Content Addressable Networks - i.e. IPFS or Swarm - or HTTP servers. If content is downloaded from HTTP servers, clients **MUST** check the content against the declared multihash.

As the default setting, clients **MUST** consider `text/markdown` ([RFC 7763](https://www.ietf.org/rfc/rfc7763.txt)) as the media type of the content represented by a multihash, and in particular [Markdown](https://en.wikipedia.org/wiki/Markdown) text in [UTF-8](https://en.wikipedia.org/wiki/UTF-8) without [BOM](https://en.wikipedia.org/wiki/Byte_order_mark).

Clients **MAY** let users choose to parse messages considering other content types. In this case they **SHOULD** cast a warning to users stating that a content type other than `text/markdown` is used while processing messages.

It's **RECOMMENDED** that clients inform users about the actual setting of the default content type.

### MOM transactions

Clients **MUST** assume that **invalid MOM transactions don't exist**. If a transaction does not strictly follow the MOM standard, clients **MUST** ignore it and they **MUST NOT** consider it a MOM transaction at all.

Because there can be security implications parsing data sent by users, clients **SHOULD NOT** try to keep track or interpret transactions as _invalid_ MOM transactions.

#### Valid MOM transaction's data structure

| ATTRIBUTE | VALUE |
|:--------|:------------|
| `to` | **MUST** be the same account signing the transaction. |
| `value` |  **MUST** be `0` wei. |
| `data` | **MUST** be at least `2` bytes. The first byte **MUST** be operational code and following bytes **MUST** be based on the operational codes listed below. |

#### List of supported operations and messages

Each operational code has one or more parameters, and all parameters **MUST** be considered mandatory.

Optional parameters don't exist: if parameters for the specific operational code are not all present or they don't follow the rules, clients **MUST** ignore the transaction completely.

Messages **MUST** be always referenced with the multihash of their content.

Operations are divided into two sets: **CORE** and **EXTENDED** operations. 

- Clients **MUST** support all core operations and they **SHOULD** support as much extended operations as possible.
- Clients **SHOULD** support and implement as much extended operations as possible, but they **MAY** choose to implement only some specific extended operations they are interested in.

#### Core operations

| OPERATION | CODE | PARAMETERS | MEANING | EFFECT |
|-----------|:--------:|------------|---------|--------|
| ADD | `0x00` | multihash | Add a message. The parameter **MUST** be the multihash of the message. | Clients **MUST** add the message to the message list of the sender. |
| UPDATE | `0x01` | multihash, multihash | Update a message. The first parameter **MUST** be the multihash of the message to be updated. The second parameter **MUST** be the multihash of the updated message. | Clients **MUST** update the message list to show the updated message. |
| REPLY | `0x02` | multihash, multihash | Reply to a message. The first parameter **MUST** be the multihash of the message to reply to. The second parameter **MUST** the multihash of the message. | Clients **MUST** insert a new message in the message list and they **MUST** preserve the relationship with the referenced message. |
| DELETE | `0x03` | multihash | Delete a message. The parameter **MUST** be the multihash of the message to delete. | Clients **MUST** remove the message from the message list. |
| CLOSE ACCOUNT | `0xFD` | multihash | Close an account. The parameter **MUST** be the multihash of the message with the motivations for closing the account. | Clients **MUST** add the message with motivations to the message list and they **MUST NOT** consider MOM messages sent by that address to be valid anymore, ever. In other words, MOM clients **MUST** ignore any other transaction sent by that address while creating the message list. This is useful when users want to change account, for example because the private key seems compromised. |
| RAW | `0xFF` | any | The parameter **MUST** be at least `1` byte. Content type is not disclosed and it **MUST NOT** be considered as `text/markdown`. | Clients **MUST** add the message to the message list but they **MUST NOT** try to decode the content. Clients **SHOULD** allow users to see this message only if explicitly asked for. This operation can be used for _blind_ notarization that general client can ignore. |

#### Note about `DELETE` operational code

Please note that sending a `DELETE` command users are not asking to actually delete anything from the blockchain, they are just asking clients to hide that specific message because it's not valid anymore for some reasons. You can think of it like if users say: _I changed my mind so please ÐApps don't show this anymore_. As already stated in the specifications above, clients **MUST** follow this request by the author, unless expressly asked otherwise by the user. 

Please also note that, because it's usually up to the author of a message to be sure the content is available to everyone, if a `DELETE` message was sent it's very likely the content referenced by the multihash isn't available anymore, simply because probably it's not shared by anyone.

#### Extended operations

| OPERATION | CODE | PARAMETERS | MEANING | EFFECT |
|-----------|:--------:|------------|---------|--------|
| ADD & REFER | `0x04` | multihash, address | Add a message and refer an account. The first parameter **MUST** be the multihash of the message. The second parameter **MUST** be an address referenced by the message. | Clients **MUST** add the message to the message list and they **MUST** track the reference to the specified account. This can be useful _to invite_ the owner of the referenced account to read this specific message. |
| UPDATE & REFER | `0x05` | multihash, multihash, address | Update a message. The first parameter **MUST** be the multihash of the message to be updated. The second parameter **MUST** be the multihash of the updated message. The third parameter **MUST** be an address referenced by the message.| Clients **MUST** update the message list to show the updated message and they **MUST** track the reference to the specified account. This can be useful _to invite_ the owner of the referenced account to read this specific message. |
| ENDORSE | `0x06` | multihash | Endorse a message identified by the specified multihash. The parameter **MUST** be the multihash of the message to be endorsed. | Clients **MUST** record and track the endorsement for that specific message. Think it as a _like_, a _retwitt_, etc. |
| REMOVE ENDORSEMENT | `0x07` | multihash | Remove endorsement to the message identified by the specified multihash. The parameter **MUST** be the multihash of the message. | Clients **MUST** remove the endorsement for that specific message. |
| DISAPPROVE | `0x08` | multihash | Disapprove a message identified by the specified multihash. The parameter **MUST** be the multihash of the message to disapprove. | Clients **MUST** record and track the disapproval for that specific message. Think it as a _I don't like it_. |
| REMOVE DISAPPROVAL | `0x09` | multihash | Remove disapproval of a message identified by the specified multihash. The parameter **MUST** be the multihash of the message. | Clients **MUST** remove the disapproval for that specific message. |
| ENDORSE & REPLY | `0x0A` | multihash, multihash | Endorse a message and reply to it. The first parameter **MUST** be the multihash of the message to reply to. The second parameter **MUST** be the multihash of the message. | Clients **MUST** insert a new message in the message list and they **MUST** preserve the relationship with the referenced message. Clients **MUST** also record and track the endorsement for that specific message. |
| DISAPPROVE & REPLY | `0x0B` | multihash, multihash | Disapprove a message and reply to it. The first parameter **MUST** be the multihash of the message to reply to. The second parameter **MUST** be the multihash of the message. | Clients **MUST** insert a new message in the message list and they **MUST** preserve the relationship with the referenced message. Clients **MUST** also record and track the disapproval for that specific message. |

## Rationale

Ethereum is _account based_, so it's good to be identified as a single source of information.

It is also able of doing notarization very well and to impose some restrictions on transaction's structure, so it's good for commands.

IPFS, Swarm or other CANs (Content Addressable Networks) or storage methods are good to store a lot of information. So, the union of both worlds it's a good solution to achieve the objectives of this message standard.

The objective is also to avoid in the first place any kind of scam and malicious behaviors, so MOM don't allow to send transactions to other accounts and the value of a MOM transaction is always 0.

### Why not using a smart contract?

MOM wants to be useful, easy to implement and read, error proof, fast and cheap, but:

- using a smart contract for messages can leads more easily to errors and misunderstandings:
  - address of the contract can be wrong
  - smart contract must be deployed on that specific network to send messages
- executing a smart contract costs much more than sending transactions
- executing a smart contract just to store static data is the best example of an anti-pattern (expensive and almost useless)

Without a specific smart contract to rely on, the MOM standard can be implemented and used right now in any existing networks, and even in future ones.

Finally, if you can achieve exactly the same result without a smart contract, you didn't need a smart contract at the first place.

### Why not storing messages directly on-chain?

There's no benefit to store _static_ messages on-chain, if they are not related to some smart contract's state or if they don't represent exchange of value. The cost of storing data on-chain is also very high.

### Why not storing op codes inside the message?

While cost effectiveness is a very important feature in a blockchain related standard, there's also a compromise to reach with usability and usefulness.

Storing commands inside the messages forces the client to actually download messages to understand what to do with them. This is very inefficient, bandwidth and time consuming.

Being able to see the commands before downloading the content, it allows the client to recreate the history of all messages and then, at the end, download only updated messages.

Creating a structure for the content of the messages leads to many issues and considerations in parsing the content, if it's correct, misspelled, and so on.

Finally, the **content must remain clean**. You really want to notarize the content and not to refer to a data structure, because this can lead to possible false-negative when checking if a content is the same of another.

### Why multihash?

[Multihash](https://github.com/multiformats/multihash) is flexible, future-proof and there are already tons of library supporting it. Ethereum must be easily integrable with many different platforms and architectures, so MOM standard follows that idea.

## Backwards Compatibility

You can already find few transactions over the Ethereum network that use a pattern similar to this EIP. Sometimes it's done to invalidate a previous transaction in memory pool, using the same nonce but with more gas price, so that transaction is mined cancelling the previous one still in the memory pool. This kind of transactions can be easily ignored if created before the approval of this EIP or just checking if the payload follows the correct syntax.

## Test Cases

A MOM-compliant client can be found and tested on [GitHub](https://github.com/InternetOfPeers/mom-client).

You can use the latest version of MOM client directly via [GitHub Pages](https://internetofpeers.github.io/mom-client) or via IPFS (see the [client repo](https://github.com/InternetOfPeers/mom-client) for the latest updated address).

## Implementation

You can use an already working MOM JavaScript package on [GitHub Packages](https://github.com/InternetOfPeers/mom-js/packages/323930) or [npmjs](https://www.npmjs.com/package/@internetofpeers/mom-js). The package is already used by the MOM client above, and you can use it in your ÐApps too with:

```bash
npm install @internetofpeers/mom-js
```

Transaction [`0x8e49485c56897757a6f2707b92cd5dad06126afed92261b9fe1a19b110bc34e6`](https://etherscan.io/tx/0x8e49485c56897757a6f2707b92cd5dad06126afed92261b9fe1a19b110bc34e6) is an example of a valid MOM transaction already mined on the Main net; it's an `ADD` message.

## Security Considerations

MOM is very simple and it has no real security concerns by itself. The standard already considers valid only transactions with `0` value and where `from` and `to` addresses are equals.

The only concerns can come from the payload, but it is more related to the client and not to the standard itself, so here you can find some security suggestions related to clients implementing the standard.

### Parsing commands

MOM standard involves parsing payloads generated by potentially malicious clients, so attention must be made to avoid unwanted code execution.

- Strictly follow only the standard codes
- Don't execute any commands outside of the standard ones, unless expressly acknowledged by the user
- Ignore malformed transactions (transactions that don't strictly follow the rules)

### Messages

Default content-type of a message following the MOM standard is Markdown text in UTF8 without BOM. It is highly recommended to disallow the reading of any not-text content-type, unless expressly acknowledged by the user.

Because content multihash is always stored into the chain, clients can download that content from Content Addressable Network (like IPFS or Swarm) or from central servers. In the latter case, a client should always check the integrity of the received messages, or it must warn the user if it cannot do that (feature not implemented or in error).

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).
