5

We have this application scenario and try to see if Ethereum, or blockchain in general, is a good solution for this.

The basic idea is the user controls a small amount of private sensitive data (e.g., individual profile change history, transaction history). The user can control who has access to that data. When user A toggles on the access for another user B, B can see the whole transaction history. Obviously other users without access shouldn't see A's data.

We are thinking of storing user's encrypted data in the public blockchain. Ethereum is one of the options we are considering. The advantages of doing so is:

  • De-centralized, or zero downtime

  • Any user with access see the un-alterable transaction trail (good for auditing purpose)

Questions:

  • How would you implement the role based access control to the content encryption key?

Obviously we can't encrypt the content with the user's own private key, otherwise when user wants to share data, he/she would have to give away the private key in order to decrypt the content.

So each unit of private data should have a unique encryption key. And we have to change the encryption key and re-encrypt the content every time the user revokes someone else's access.

So that leads to another question:

  • Where should we store these encryption keys?

Should we store them in a privately owned database? A more general question is, since blockchain achieves tracking the ownership in a public shared ledger, can it implement role-based access control completely with everything (except user's private keys) in public chain as well?

UPDATES

Thanks for the answer of Rob Hitchens. I read Vitalik's blog post and found that it's difficult to implement obfuscated computing on chain. So it's impossible to store everything on the public chain while keeping user's data privacy.

That mandates we need some kind of private storage to realize the privacy. One idea is to use the public chain for permissions record keeping only. e.g., we declare

mapping (address => bool) permissions;

And only sender can assign set any account's permission to true or false. Our private authentication server respects this permission mapping (stored in public chain) and only allows an authenticated user (i.e., the user that owns the private key to an authorized account) to access the content encryption key.

If we use the above design, to authenticate herself, the account owner needs to use the private key to compute a signature, and the auth server needs to verify that. That seems to similar to the way how identity is verified in ethereum transactions.

Will the above approach work? or more importantly, is there a better design?

5

Agree with Sanchit about using modifiers to control access to functions.

However, the example implementation is misleading. I would flag that for a redesign.

A couple of things to consider.

As far a data storage is concerned, you might want to consider off-chain serialization with encryption. This, to reduce the overall storage cost without compromising the distributed nature of the app.

For privacy, I see you're aware that information in Ethereum is visible to all parties. Consider using multi-party encryption with a smart contract to help distribute the "secret" to multiple authorized parties.

For scalability, @Sanchit's modifier needs to eliminate the unbounded for loop. Put simply, for(i=0;i<n;i++) is an anti-pattern. At a certain n the cost of execution will exceed the block gasLimit meaning it will fail in all cases. In other words, implemented that way guarantees a successful application will eventually fail, possibly in a way that can't be repaired.

What's shown is perfectly logical in a server-centric world. In Ethereum, all functions need an (approximately) fixed gas cost at any scale. A solution is to refactor with 1-step lookups using mapping.

Just mentioning this because this error exists in a lot of contracts and I hope the answer (I generally agree) doesn't lead coders to replicate that sort of defect.

Hope it helps.

  • Thanks for the answer. I read Vitalik's blog post (blog.ethereum.org/2016/01/15/privacy-on-the-blockchain) and find that it's difficult to implement obfuscated computing on chain. So it's impossible to store everything on the public chain while keeping user's data privacy. Am I interpreting that right? – user10375 Jun 15 '17 at 22:15
  • I guess to protect privacy we have to rely on a private data storage, and use the public chain for permissions record keeping only. The authentication server respects the permission matrix (stored in public chain) and only allows an authenticated user (i.e., the user that owns the private key to an authorized account) to access the encryption key. – user10375 Jun 15 '17 at 22:23
  • Thanks @Rob for pointing out issues, I'll refactor my code and update the answer. – Sanchit Jun 15 '17 at 22:51
  • @user10375 Just rephrasing in case it helps. The contract can guarantee that a function only executes if the signer is on an access control list, or even if a hash of the signer's address is on an ACL (more private), but it can't stop an interested party from exploring the data. It's futile given that all miners/verifiers must see the data to work with (at this time). They don't need permission from a function to do read-only exploration. – Rob Hitchens - B9lab Jun 16 '17 at 5:14
  • @RobHitchens To prevent the miners from reading the private data, it seems like the best solution is to move the data off the chain. Alternatively, we can upload the encrypted data, but that would cause too much computing and storage burn for the ehtereum nodes. Agree? – user10375 Jun 16 '17 at 13:36
4

You can implement access control on your smart contract functions with the help of modifiers. Let's say you don't want some function to be called by everyone using your contract, in that case, you can create a modifier and restrict the function usage. In a similar way you can have multiple modifiers for different roles as per your case.

A sample modifier, which I'm using in one of my project - "Only Member"

modifier onlyMember {
    var index = DataStore(memberStore).getAddressIndex('account', msg.sender);
    var state = DataStore(memberStore).getIntValue(index, 'state');
    if (index != 0 && state == 0) {
        _;
    } else {
        Status(100);
    }
}

//modifier usage    
    function getMyBooks() constant onlyMember returns (string bookString, uint8 count) {
        return getBooks(true);
    }

Hope this helps.

  • Thanks. This definitely helps, and solves the role based access control implementation question. My next question is what should that smart contract function do? Can a smart contract function somehow trigger something off-chain? – user10375 Jun 15 '17 at 22:24
  • 1
    Smart contract function would contain your business logic definition, whatever functionality you want to have inside it. Like in my example, i'm getting the list of books associated with the owner using another function called getBooks(). Also, I think yes smart contract function can trigger something off-chain as well. I haven't tried this but you should take a look at oraclize.it – Sanchit Jun 15 '17 at 22:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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