I've been thinking about this situation for quite a while and I wonder if there is a way to solve this on the public Ethereum blockchain.

User A stores some data on the blockchain, encrypted in some way. (with A's private key, for instance). This data is thus only readable by A. Now, A wants to "transfer" the ownership of this data to B, again in an encrypted way, all while guaranteeing that the data isn't being tampered with during the process. This means that the encryption can't happen off-chain: first of all, B can't send his private key to A for obvious reasons, but more than that, if A would re-encrypt the data with B's key offchain, there would be no way to verify if the data is still the same.

I know there is no straightforward way to implement this logic with a smartcontract. The obvious issue here is that smartcontracts "can't" encrypt, because you need to provide them with the key to do so, thus rendering the encryption useless from the start.

That being said, is there a way to achieve this exact process with other tools, while preserving maximal security?

  • When you say "transfer", do you mean a process such that A no longer has access after transferring to B? If so, that's not possible (though you could potentially create something through which A gets no future versions of the data). If you mean let B also have access, A can encrypt the data using B's public keys with a public key system. Now, it can be posted publicly (including on a blockchain, but that seems a bit over-kill for large data).
    – lungj
    Commented Nov 22, 2017 at 21:53
  • @lungj yes I mean such that A no longer has access to future versions of the data -- older versions could still be accessed by them. What would a way round be for this then? Thanks a bunch!
    – el-flor
    Commented Nov 22, 2017 at 22:30
  • 1
    The least complicated way is probably for there to be a decryption key that A sends to B, encrypted using B's public key so that only B can read the message. The encrypted data can be transferred to B via a channel, trusted or otherwise. B re-keys the data. Without modifying the data, A knows what the data is (because A has a decryption key for the version shared with B). But, if the data is modified, A can't determine its contents (assuming an appropriate encryption scheme is selected).
    – lungj
    Commented Nov 23, 2017 at 5:55
  • I had the same type of question: ethereum.stackexchange.com/questions/48540/… no better answer found
    – tomsoft
    Commented Nov 1, 2018 at 13:58

3 Answers 3


First of all, information is encrypted using public key and decrypted using private key, not the other way around (that is signing and verifying).

First time A stores data, A will generate new keypair (private and public key) from hash or that data itself.

After that A will first encrypt data using newly generated public key and after that encrypt newly generated private key using her own public key. When transferring A will decrypt newly generated private key and encrypt it using B's public key.

Then B can decrypt that private key using his own private key and then decrypt data using that private key and confirm that it is indeed same data (since he can decrypt it, and if A put wrong data on blockchain than she would not be able to decrypt it).

Now you can decide if you are going to generate keypair everytime data is changed or you are going to use keypair from first data entry on blockchain. And if B wants to restrict access to A when B next time changes data, B just has to generate new keypair from altered data.

Contract will need one event with string encryptedPrivateKey and string encryptedData.

When transferring you will just put B's address alongside private key encrypted with B's public key in another event.

In dapp you will notice B if his address is in transfer event and try to decrypt data and if it works transfer is legit.

  • you can encrypt with public or private and decrypt with the other depending on the need. (We had to do this in school 25 years ago)
    – RW.
    Commented Sep 16, 2021 at 3:46
  • There's a research paper called SmartDHX that implements this as you described it.
    – jdbertron
    Commented Jun 10, 2022 at 13:39

Smart Contracts shouldn't encrypt sensible data using private keys for two reasons:

1.- To encrypt any data they need to know the data, and that implies it being public on the blockchain transaction data field.

2.- The Smart Contract using someone's private key means the private key is passed as an argument to a given function of the contract, and it would be recorded on the ledger as a transaction data field too. Never expose private keys.

So, it should be the DApp or wallet responsible to encrypt (offchain) the data using public key of recipient, and then send it to the contract just as a storage service.

In order to transfer the asset, the encryption should be performed offchain as well, by the DApp/wallet sending the new ciphered data to the contract.

  • 1
    Thanks for your answer. I definitely understand the 2 points, as I hoped to make it clear in my post, and I had already ruled out the straightforward approach of having the smart contract do the encryption. How can I ensure off-chain that the data being decrypted and the new encrypted data stored is the same data? And how one user both do the decryption and the encryption with the other user's private key?
    – el-flor
    Commented Nov 22, 2017 at 17:41
  • 1
    The off-chain DApp or wallet that performs encryption should know the data, the first public key and the second public key. This way it may perform encryption for two different users of the same data and verify that first result matches previous version. Commented Nov 23, 2017 at 7:31
  • Does this mean that if the wallet/dApp, used for off-chain encryption, is abandoned by its devs, e.g. will not support a future hardfork, then the "dApp" will stop working? Thus it is not a real dApp?
    – shelll
    Commented Nov 13, 2018 at 8:52

I had a similar use case (How to store a private data in ethereum) . The best that I've found is the following:

while A is owner of the data, he store this data on the blockchain using his public key. So A is the only one who can decode it.

When A transfer the ownership to B, he read the data and decode it off chain, then re-encoding it using B public key, then store it on the chain.....

If you really want to prove that it was A who've done it, you can easily do it through a smart contract, for instance by making sure that's A who have stored B data.

For instance, if ownership is stored in a smart contract, only current owner can modify ownership (or related data), so only A can modify data and assign them to B.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.