[Ethereum] Make data from smartcontracts / events only visible for certain address/users

contract-designdapp-developmentencryptionjavascriptsolidity

I Have an use case where i need :

1- My data not to be visible to the public.

2- To be able to revoke my clients/users rights to view said data from my smart contract.

As anyone done that before ?

I was thinking of encrypting / decrypting my data client side so that the data is never visible on the blockchain in clear and that seems solid enough.(client would hold the private key)

But then i'm failing to see how to prevent my users from watching the events for that contract using something like

contractInstance.EventName({x: y}, {fromBlock: 0, toBlock: 'latest'});

or by calling getters directly form their local node when i want to revoke their right to see it.

I was thinking of re-encrypting the data On blockchain a second time and have my contract decrypt it for address in some kind of list , but that would require my contract to hold the private key and that would effectively make everything useless.

Are there any solution other / better solution to this issue?

Edit :

A bit more on my usecase it a kind of registry. I'm hosting data on the blockchain , i give the right to add/edit data to my users with basics rights (i'm owner of the contract and there is a list of authorized user that can use add/edit functions).Also,User can edit his own data only but can see the whole set, if subscribed.

I want that same list of user ONLY to be able to read the data ( subscription based system ) so that once the subscription runs out they can't event read the data anymore.

I'm having a hard time picturing the proper design as encrypting the data and sending it to the blockchain while having the private key stored in my privately distributed client is fine,but that would still mean the client hold the key to decrypt the data forever. Or i would have to re encrypt the whole set of data each time a client unsub which is not realistic.

Best Answer

You cannot prevent anyone with access to the blockchain from reading state and executing code in any way they wish. You can encrypt data, but that doesn't prevent people from seeing it, just interpreting it.

Assuming you're happy with people who have stopped subscribing being able to access the data that was already available to them - something you fundamentally can't prevent anyway - there are a couple of ways you could achieve this.

One is to use standard multi-recipient public key encryption: Encrypt each message with a randomly generated key, then encrypt that key with the public key of each user who should be able to access it. When a user ceases their subscription, remove them from the set of active keys. When a new user subscribes, add them to the set, and encrypt the secrets of any past messages they should be able to access.

A slight variation may permit easier key management: Use one key for each 'epoch'. An epoch ends each time a user ends their subscription. Whenever you insert a message, encrypt it using the current epoch key (make sure to use an IV too, to prevent dictionary and known-plaintext attacks). Provide a keystore that lets users access the epoch keys for every epoch they're subscribed to; either off-chain, or by encrypting those keys with the public key of each user who's permitted to use them.

Related Topic