I have a citizenship persona contract which acts as a personal identity file which is under the control of the user. Personas can make other personas in the system into trustees or allies. As part of the persona contract I'd like to implement a feature called publicity, which has three settings, denoted by -1, 0, 1. publicity controls who can access the persona's general information.

-1 = only trustees can access info.

0 = trustees and allies can access info.

1 = full publicity to anyone who requests it.

There are two lines of security I'm concerned about: interacting with functions themselves and viewing the state on the blockchain.

The first issue can be solved against with modifiers, although I'm not exactly sure the following attempt works (persona is a struct containing all the relevant details about the human being which can be queried):

mapping(address => int) allies;
mapping(address => int) trustees; //

modifier Security {
    if(persona.publicity = -1) {
        if(trustees[msg.sender] = -1) { 
            _ } else throw;
    else if(persona.publicity = 0) {
        if(allies[msg.sender] = 0 || trustees[msg.sender] = -1) {
            _ } else throw;
    else _

I'm not sure if this is valid. Would appreciate if this syntax could be verified.

The second line of attack is reading state directly on the blockchain. This is a little more complicated. I know many of the state variables that hold data can be encrypted using the sha3(x,y,z) approach. But how would you implement this?

This is the struct which holds persona information:

struct Persona {
        bytes16[] name;
        bytes16[][] residency;
        bytes32 id;
        string origin;
        uint created;
        uint access;
        int birth;
        int exit;
        int publicity;
        int status;
        Sex assigned;
Persona public persona;

How could these state variables be encrypted so that they can't be read on the blockchain? What sort of scheme could you implement so that people in the trustees or allies permission group would be able to decrypt the data on their end? Apologies if this is too much for one question but I think it might be useful for others with permission group/access restriction questions.


Quick note first, for comparisons you want == rather than =.

Secondly it appears you're storing 0 for allies and -1 for trustees, e.g. this code:

if(allies[msg.sender] = 0 || trustees[msg.sender] = -1) {

The trouble is that mappings initialize to default values, and 0 is the default for ints. So that code will find that everybody is an ally. Since you have two mappings anyway, the easiest solution is probably to just store 1 if a member of the group, and leave the default 0 if not.

I wasn't sure whether it was legal to have more than one underscore, so I tested it in the online Solidity compiler and it turned out that it compiles. So I guess wherever it hits the underscore, it'll execute the entire body of the function; I haven't tested that to be sure but I don't know what else it could do.

I don't think it's really idiomatic though, and I'd argue that it's more convoluted than it could be. I would refactor into two modifiers. Each tests the condition and throws if it's false, then has the underscore afterwards. That makes the modifiers really easy to read:

modifier checkTrusteeOnly {
    if (persona.publicity == -1 && 
        trustees[msg.sender] == 0) throw;

modifier checkTrusteeAndAlliesOnly {
    if (persona.publicity == 0 && 
        allies[msg.sender] == 0 && 
        trustees[msg.sender] == 0) throw;

function blah() checkTrusteeOnly checkTrusteeAndAlliesOnly { ...  }

As for encryption, the only way you could manage it is to personally give people encryption keys. The contract itself can't keep private information that way, everything is public.

So really, for this particular application all the above is moot. You can't keep people from seeing this information unless you manage encryption keys off-chain, and if you do that then there's no point putting these access controls in the contract.

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.