New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ERC: address-to-address messaging system protocol #802

Open
Dexaran opened this Issue Dec 19, 2017 · 11 comments

Comments

Projects
None yet
5 participants
@Dexaran

Dexaran commented Dec 19, 2017

ERC: <to be assigned>
Title: Address-to-Address messaging system protocol
Author: Dexaran, dexaran@ethereumclassic.org
Status: Draft
Type: ERC
Created: 19-12.2017
Resolution: https://github.com/EthereumCommonwealth/Address-to-Address-messaging

Abstract

The following describes the details of the smart-contract based messaging system which aims to allow Ethereum users to directly contact the address owner without having to know who hi (she) is.

Motivation

Ethereum lacks a central messaging system that will allow to contact an address owner directly. You can send him a transaction with ASCII message attached as data but it is likely that address owner will not even try to recognize it as a text message. As the result there is no viable way to deliver a message to address owner directly.

This service is necessary in some circumstances, for example:

  1. You sent someone a token, the existence of which this person does not know. It is likely that a person will spot an incoming ETH transaction, but there is no way that a person will spot an incoming token transaction or the fact that his balance of this token increases. You need to contact the owner of this address and ask to send your tokens back.

  2. You sent ETC into someone's ETH address. The same situation as with tokens. It is likely that a person will not recognize an incoming transaction of an alternative currency. But he definitely can access it and send it back (or just go and sell it).

  3. You spotted that someone have deployed a contract that is proven to be vulnerable. If you're a good guy then you want to contact an owner of the "vulnerable contract" and warn him that he is going to use a contract that contains vulnerability and his funds are at risk in this case.

  4. You spotted that someone has hacked something. You would like to contact a hacker and kindly ask him to send everything back but the hacker likely will not respond if you will try to contact him via forums. I suppose that it is the most important case. On-chain methods of communication are the only way to securely contact a hacker or to respond if you are the hacker.

Specification

Basic address-to-address messaging smart-contract.

This is a simple smart-contract that stores messages mapped to addresses by id and a mapping that represents the last message id for each address. Last message id increases for the receiver address when this address receives a new message (there is no message at last_message_id in fact... this represents a numeric id that will be filled with the next incoming message in fact). If the last_message_id is equal to 0 then there are no messages for this address. If last_message_id is equal to 2 then there are 2 messages at positions 0 and 1 for this address.

There is no possibility to edit, change, delete messages. This contract is not a messenger or a chat. This contract is an emergency way to contact an owner of a certain address when there is no possibility to contact him off-chain. As the result, editing and deleting messages has no reason because it will still be available via history of transactions.

Basically, there is no way to encrypt message on-chain because there is no way to hide an input call data. As a result, there is an additional field for attaching a public asymmetric encryption key. If the owner of a certain address has a desire to allow someone to contact him privately, then he can publish his public key at this contract and describe what type of key he has published at the "Key type" variable (for example PGP public key or RSA 2048 bit public key). Anyone else is allowed to look at the public key in the contract, encrypt the message outside the network and send an encrypted message on this contract.

Methods

sendMessage

    function sendMessage(address _to, string _text)

Delivers a string message to _to address owner.

lastIndex

    function lastIndex(address _owner) constant returns (uint256)

Returns an index of the last message for the _owner address.

NOTE: This means that there are messages at 0 to lastIndex - 1 positions. There is no message at lastIndex position actually. This will be filled with the next message for this address. If the lastIndex is equal to 0 then there is no messages for this address.

getLastMessage

    function getLastMessage(address _who) constant returns (address _from, string _text)

Returns the last message for the _who address and the sender of this message.

NOTE: Message is actually at lastIndex(_who) - 1 position.

getMessageByIndex

    function getMessageByIndex(address _who, uint256 _index) constant returns (address, string)

Returns the message for _who address at _index position and the sender of this message.

getPublicKey

    function getPublicKey(address _who) constant returns (string _key, string _key_type)

Returns a public key of the _who address and a type of this key.

setPublicKey

    function setPublicKey(string _key, string _type)

Sets a public key and a description of key type for the sender address.

Events

NewMessage

event Message(address indexed _sender, address indexed _receiver, uint256 _time, string message)

Triggered when a new message is sent. This event logs timestamp of the message in UNIX seconds.

PublicKeyUpdated

event PublicKeyUpdated(address indexed _sender, string _key, string _keytype)

Triggered when a customer updates a public key of an address or sets it first time. This event logs a new public key and key type to make it easier to recognize which encryption algorithm should be used with this key.

Resolution

Obviously, this contract can not guarantee that an owner of the address will receive a message. It requires to be supported by UIs. It is likely that an owner of a certain address will see a message if MyEtherWallet, MetaMask or Mist will display messages somehow (for example a certain number of last messages).

Also, it makes sense to standardize possible public key types. Ideally, UI should have a button "Send message to address" and "Send encrypted message to address" and distinguish public key, key type and then encrypt message automatically.

@pabloruiz55

This comment has been minimized.

Show comment
Hide comment
@pabloruiz55

pabloruiz55 Dec 20, 2017

Looks very useful. Just the other day I was thinking about something similar, given how many issues I've seen of people mistakenly sending tokens, or even the case you mention of a contract being hacked and having no way to communicate with the perp.

Have you thought about firing an Event when a message is sent? It would make it easier to read all messages for a particular contract and even filter them by date or sender.

pabloruiz55 commented Dec 20, 2017

Looks very useful. Just the other day I was thinking about something similar, given how many issues I've seen of people mistakenly sending tokens, or even the case you mention of a contract being hacked and having no way to communicate with the perp.

Have you thought about firing an Event when a message is sent? It would make it easier to read all messages for a particular contract and even filter them by date or sender.

@Dexaran

This comment has been minimized.

Show comment
Hide comment
@Dexaran

Dexaran Dec 20, 2017

@pabloruiz55 Thanks for the useful idea. I'll update the code with events to make it easier to watch events of the contract for third party services.

Dexaran commented Dec 20, 2017

@pabloruiz55 Thanks for the useful idea. I'll update the code with events to make it easier to watch events of the contract for third party services.

@Dexaran

This comment has been minimized.

Show comment
Hide comment
@RorschachRev

This comment has been minimized.

Show comment
Hide comment
@RorschachRev

RorschachRev Dec 22, 2017

We could possibly enhance this a little. If someone sends a transaction it exposes their public key. A blockchain explorer could act as an oracle in this case.
If we add a "MSG!" Token and send them to people, this may get noticed by wallets and block chain explorers. With a "watch this address" that some explorers already have, the user would get an actual email. We could potentially include the decrypted contents by wallet, but that's a stretch. (Using block chain public key, wallet would have the private key, but symmetric key and decoding method would be required.)

RorschachRev commented Dec 22, 2017

We could possibly enhance this a little. If someone sends a transaction it exposes their public key. A blockchain explorer could act as an oracle in this case.
If we add a "MSG!" Token and send them to people, this may get noticed by wallets and block chain explorers. With a "watch this address" that some explorers already have, the user would get an actual email. We could potentially include the decrypted contents by wallet, but that's a stretch. (Using block chain public key, wallet would have the private key, but symmetric key and decoding method would be required.)

@3esmit

This comment has been minimized.

Show comment
Hide comment
@3esmit

3esmit Dec 24, 2017

That's would be a very expansive way of sending messages.

3esmit commented Dec 24, 2017

That's would be a very expansive way of sending messages.

@shrugs

This comment has been minimized.

Show comment
Hide comment
@shrugs

shrugs Dec 24, 2017

@3esmit the expense doesn't really matter here; use public key cryptography to organize conversation off-chain. This serves the (particularly useful) purpose of a central location to check for messages that you want to send to an address, without having to know anything about someone besides their address.

@Dexaran I would also include that this is also useful for contacting owners of ENS domains.

I like this and could contribute time towards building a canonical interface for this contract.

shrugs commented Dec 24, 2017

@3esmit the expense doesn't really matter here; use public key cryptography to organize conversation off-chain. This serves the (particularly useful) purpose of a central location to check for messages that you want to send to an address, without having to know anything about someone besides their address.

@Dexaran I would also include that this is also useful for contacting owners of ENS domains.

I like this and could contribute time towards building a canonical interface for this contract.

@Dexaran

This comment has been minimized.

Show comment
Hide comment
@Dexaran

Dexaran Dec 25, 2017

@RorschachRev it is an interesting idea to use Ethereum's private and public keys of an address to encrypt/decrypt messages, but it's not related to the logic of the smart-contract in any case. Encryption/decryption process should be off-chain.

Dexaran commented Dec 25, 2017

@RorschachRev it is an interesting idea to use Ethereum's private and public keys of an address to encrypt/decrypt messages, but it's not related to the logic of the smart-contract in any case. Encryption/decryption process should be off-chain.

@Dexaran

This comment has been minimized.

Show comment
Hide comment
@Dexaran

Dexaran Dec 25, 2017

@shrugs

@Dexaran I would also include that this is also useful for contacting owners of ENS domains.

I suppose that it is up to UI and this should not be part of messagin contract as well.

Dexaran commented Dec 25, 2017

@shrugs

@Dexaran I would also include that this is also useful for contacting owners of ENS domains.

I suppose that it is up to UI and this should not be part of messagin contract as well.

@shrugs

This comment has been minimized.

Show comment
Hide comment
@shrugs

shrugs Dec 25, 2017

@Dexaran Of course, I mean this is a good usecase for entering negotiations with squatters (for example, we've been trying to obtain truebit.eth for ages, including with ascii transactions, but without progress).

shrugs commented Dec 25, 2017

@Dexaran Of course, I mean this is a good usecase for entering negotiations with squatters (for example, we've been trying to obtain truebit.eth for ages, including with ascii transactions, but without progress).

@Dexaran

This comment has been minimized.

Show comment
Hide comment
@Dexaran

Dexaran Dec 26, 2017

There is one concern that I'd like to discuss: crosschain interoperability.

Request for comment: cross chain interoperability

The whole Ethereum ecosystem lacks an address to address central messaging system. It is not a local problem of Ethereum, it is a bit more global. Currently, there are some "Ethereum-compatible" chains: ETC, PIRL, UBQ, EXP, MusiCoin (and probably RootStock) and they all need to solve the same problem.

NOTE: I've said Ethereum-compatible chains since they all utilize the same address schemes. The owner of 0x1111111111111111 address can use this address on any of the mentioned chains. One private key can unlock exactly the same addresses on any of this chains. As the result, if you sent UBQ into EXP address, then the owner of this address can access your UBQ.

To be honest, I don't see any reason to deploy exactly the same service on each chain separately. This is not to benefit of anyone. I think that the best idea is to deploy the service on one chain and then consider it a core part of the overall messaging system.

A UI that have access to multiple nodes (for example MyEtherWallet) can connect to the core-node (node of the network that will be used to deploy this service contract) and look for messages. If the message for the address is found at the core-network, then the UI should display it to the user. It doesn't matter if the user is currently on the core-network or any of the alternative Ethereum-compatible chains.

This approach has some advantages:

  1. Deploying one contract on multiple chains is just irrational. Now we have many copies of the ENS in each network. As practice has shown, it is not needed for anyone.

  2. If there is only one core network, then the user can send a message from an "address" to an "address" regardless of whether he uses his address in the same chain with the owner of the message recipient or not. You can inform a ETH user that you have sent him a token that is deployed on UBQ, for example, and he will receive your message.

  3. It is cheaper for ETH users to utilize the powers of some else network.

I'd like to receive more feedback and any thoughts about this.

Dexaran commented Dec 26, 2017

There is one concern that I'd like to discuss: crosschain interoperability.

Request for comment: cross chain interoperability

The whole Ethereum ecosystem lacks an address to address central messaging system. It is not a local problem of Ethereum, it is a bit more global. Currently, there are some "Ethereum-compatible" chains: ETC, PIRL, UBQ, EXP, MusiCoin (and probably RootStock) and they all need to solve the same problem.

NOTE: I've said Ethereum-compatible chains since they all utilize the same address schemes. The owner of 0x1111111111111111 address can use this address on any of the mentioned chains. One private key can unlock exactly the same addresses on any of this chains. As the result, if you sent UBQ into EXP address, then the owner of this address can access your UBQ.

To be honest, I don't see any reason to deploy exactly the same service on each chain separately. This is not to benefit of anyone. I think that the best idea is to deploy the service on one chain and then consider it a core part of the overall messaging system.

A UI that have access to multiple nodes (for example MyEtherWallet) can connect to the core-node (node of the network that will be used to deploy this service contract) and look for messages. If the message for the address is found at the core-network, then the UI should display it to the user. It doesn't matter if the user is currently on the core-network or any of the alternative Ethereum-compatible chains.

This approach has some advantages:

  1. Deploying one contract on multiple chains is just irrational. Now we have many copies of the ENS in each network. As practice has shown, it is not needed for anyone.

  2. If there is only one core network, then the user can send a message from an "address" to an "address" regardless of whether he uses his address in the same chain with the owner of the message recipient or not. You can inform a ETH user that you have sent him a token that is deployed on UBQ, for example, and he will receive your message.

  3. It is cheaper for ETH users to utilize the powers of some else network.

I'd like to receive more feedback and any thoughts about this.

@Dexaran

This comment has been minimized.

Show comment
Hide comment
@Dexaran

Dexaran Mar 22, 2018

Message system in use: ethereumproject/ECIPs#85 (comment)

General info

Here is a reference implementation of the described Message System at CLassicEtherWallet.

https://ethereumproject.github.io/etherwallet/#messages

Interchain Address-To-Address messaging contract is currently deployed on Ethereum CLassic chain at 0x6A77417FFeef35ae6fe2E9d6562992bABA47a676 address.

It is an open-source contract and it is licensed under GPLv3. Source codes could be found here: https://github.com/EthereumCommonwealth/Address-to-Address-messaging

Functionality

The described messaging system allows:

  • send messages
  • retrieve messages
  • display messages to a user when he/she unlocks a wallet to send a transaction

Howto

Sending a message.

  1. Open ClassicEtherWallet and go to messages tab. Make sure that you are at ETC network. It is necessary to use ETC network in order to send a message https://ethereumproject.github.io/etherwallet/#messages

  2. Unlock your wallet.

  3. Click a New Message section.
    newmsg

  4. Type the address and the message.
    newmsg2

  5. Click SEND button and wait for transaction info to appear. NOTE: It may take longer to calculate the transaction info if your network speed is low.
    newmsg3

  6. Check the transaction hash to make sure that your message was successfully sent.
    newmsg4

Watching your messages.

  1. Open ClassicEtherWallet and go to messages tab. It doesn't matter what network you are currently at to display your messages. You can retrieve ETC messages being on UBQ network. https://ethereumproject.github.io/etherwallet/#messages

  2. Unlock your wallet. Wait for messages to load. It may take a minute or something like this because it requires a number of contract calls. NOTE: You can view messages with address only but you will not be able to respond if you are using this method of message checking.
    viewmessage1

  3. You can also reply to a message if you want. However, it requires gas.
    viewmessage2

NOTE: This is an emergency message system! Not an on-chain chatroom.

Every symbol that you broadcast to the network will cost you gas. This is not an on-chain chat! This is only an emergency system that allows you to contact an owner of a certain address if there is no way to contact him off-chain. For example if you accidentally sent a number of funds into someone elses address or if you want to interview TheDAO hacker.

Dexaran commented Mar 22, 2018

Message system in use: ethereumproject/ECIPs#85 (comment)

General info

Here is a reference implementation of the described Message System at CLassicEtherWallet.

https://ethereumproject.github.io/etherwallet/#messages

Interchain Address-To-Address messaging contract is currently deployed on Ethereum CLassic chain at 0x6A77417FFeef35ae6fe2E9d6562992bABA47a676 address.

It is an open-source contract and it is licensed under GPLv3. Source codes could be found here: https://github.com/EthereumCommonwealth/Address-to-Address-messaging

Functionality

The described messaging system allows:

  • send messages
  • retrieve messages
  • display messages to a user when he/she unlocks a wallet to send a transaction

Howto

Sending a message.

  1. Open ClassicEtherWallet and go to messages tab. Make sure that you are at ETC network. It is necessary to use ETC network in order to send a message https://ethereumproject.github.io/etherwallet/#messages

  2. Unlock your wallet.

  3. Click a New Message section.
    newmsg

  4. Type the address and the message.
    newmsg2

  5. Click SEND button and wait for transaction info to appear. NOTE: It may take longer to calculate the transaction info if your network speed is low.
    newmsg3

  6. Check the transaction hash to make sure that your message was successfully sent.
    newmsg4

Watching your messages.

  1. Open ClassicEtherWallet and go to messages tab. It doesn't matter what network you are currently at to display your messages. You can retrieve ETC messages being on UBQ network. https://ethereumproject.github.io/etherwallet/#messages

  2. Unlock your wallet. Wait for messages to load. It may take a minute or something like this because it requires a number of contract calls. NOTE: You can view messages with address only but you will not be able to respond if you are using this method of message checking.
    viewmessage1

  3. You can also reply to a message if you want. However, it requires gas.
    viewmessage2

NOTE: This is an emergency message system! Not an on-chain chatroom.

Every symbol that you broadcast to the network will cost you gas. This is not an on-chain chat! This is only an emergency system that allows you to contact an owner of a certain address if there is no way to contact him off-chain. For example if you accidentally sent a number of funds into someone elses address or if you want to interview TheDAO hacker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment