How to handle private data in tx request?

When a client app sends a transaction request to tendermint, is it possible to mark some data as private, and so the private data in the request is passed to the abci app, but is not written on the public chain? The abci app instance may process the private data, and store it in its private datastore, but only a hash of the private data can be broadcasted and written on the public chain. If this is not possible, what can I do to hide private data in a transaction request? I could send the data as encrypted, but it may not be safe to store on the public chain forever.

This question can be compared with the private data collections supported by Hyperledger Fabric, where client app can send private data in a transaction request, but the private data will be processed by only the peer node that is connected to the client app, and only a hash of the private data is broadcasted and stored on the public chain. Does tendermint support something similar?

So this is not natively possible when you send a tx, but it could be effectively simulated by using abci queries. You can send an /abci_query which will only go to the local app, and it can do whatever it wants with it, including splitting it into “private” and “public” parts, storing the private part in some local store, and broadcasting the public part back to tendermint as a transaction. Or the client could send both the query (with the private part) and the tx (with the public part), and the app would just hold on to the query part until the tx got committed. So there’s enough flexibility to pull this off already, but you have to write the abci app to handle it by getting the private data through the ABCI query.

And of course note, any data coming through the ABCI query can’t change the consensus state, since it’s local to only that note, so you just need to be careful to separate local app state from the global/consensus app state.

Thanks for the clever use of query, Ethan. I like the option that client sends both public and private data via query, and the app creates a public transaction that including public data and a hash of the private data, and also store the private data somewhere locally. This would keep the private data only to the app itself.

Here comes the second question regarding the management of private data: Assuming that it is a supply-chain app, and the app runs on multiple nodes, and so the “private data” would need to be shared between 2 trading partners. I guess that I can create a private off-chain messaging layer to sync the private data between partners, but wonder if it may make sense for Tendermint to support such private communication between targeted nodes that host the app.

Yes it would be good for Tendermint to support this kind of thing down the road, but since this is more an enterprise use case, it hasn’t been prioritized as most of the focus recently has been on supporting the public networks.