Migration pattern for on chain data (Discovery)


I was wondering how data stored on chain could be migrated securely when a contract version is updated in Discovery. I’m assuming that there’s no off-chain storage in Discovery from Victor’s reply here.

Let’s say a secret contract implements getter methods for its persistent on-chain state. Would it be possible to return the encrypted version of that state (encrypted with the enclave’s private key) to the next version of the contract?

Actually, it’s worth clarifying Victor’s reply, as it’s been a few months since.

There is an encrypted state storage that is shared on the Enigma network level. So technically, that could be considered off-chain (or stored on the 2nd layer), as opposed to on the first layer. In Ethereum, we only store hashes as proofs that the data should exist.

Migration is likely going to be challenging in Discovery, because we intentionally don’t support composition of secret contracts (we do allow composing a secret contract with an Ethereum smart contract, but it’s fairly specific). This allows us to scale better, which is a key component.

As to migrating the data itself - the state key is symmetric, so you won’t be able to re-encrypt the data on one contract, and have a getter function that returns the state encrypted with the second contract’s key. Currently, you would have to have a getter designated to a specific party that can get (and see) the state. I’d need to think about it a bit more to see if there’s a way to distribute this trust (e.g., by secret sharing this key, or by having another secret contract that manages it). This doesn’t seem trivial to me from a quick glance.

Regardless, thanks for this great question! This might be a good feature for us to consider more directly in future releases.


Thank you for the thorough reply, Guy!

Just to make sure I understand: by “composition of secret contracts”, do you mean being able to call secret contracts (e.g. a contract meant for storing and providing data) from other secret contracts (e.g. a contract with business logic)?

Currently, you would have to have a getter designated to a specific party that can get (and see) the state.

So for example, would a workaround be to have each user fetch their data to store locally from the first contract, and then send it to the second contract with another transaction?

Correct - I was referring to calling a contract from a contract.

That sounds like a plausible (though difficult to coordinate), workaround.