0

For example, given the following structure, I want some fields to be visible only for the contract owner

struct Participant{
    address participantAddress; // can be seen by anyone
    string team; // can be seen by anyone
    string personalDescription; // can be seen by anyone
    string secret // can be seen only by contract owner    
}
// Mapping each participant to an uint id
mapping(address=>Participant) public participantsMapping;

In other words, someone inspecting the participantsMapping can see all the fields EXCEPT the secret one (which can only be seen by owner)

From what I know, the "private" keyword doesn't hide any data, it's only a code-level specifier.

There are modifiers for function, but do they work for fields in a structure too? If not, how can it be achieved?

modifier onlyOwner() {
    require(msg.sender==ownerAddress,
    "Visible only by owner");
    _;
}
1
  • 1
    All data in EVM blockchain are public. If you want to hide some data on chain, you need to cipher it offchain. Apr 19, 2022 at 14:37

1 Answer 1

0

You can use getter function to retrieve and in the same time restricted access with other user that they aren't smart contract owner. I wrote a smart contract for your use case, see this:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

contract TestContract {
    address ownerAddress;

    constructor() {
        ownerAddress = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == ownerAddress,"Visible only by owner");
        _;
    }

    struct Participant {
        address participantAddress;
        string team;
        string personalDescription;
        string secret;    
    }

    // I removed 'public' and I set 'private'
    mapping(address => Participant) private participantsMapping;

    function fillMapping(Participant memory _partecipant) public {
        participantsMapping[msg.sender] = _partecipant;
    }

    // Anyone call this function, he'll retrieve all data without secret value.
    function getFields(address _address) external view returns(address participantAddress, string memory team, string memory personalDescription) {
        return (participantsMapping[_address].participantAddress, participantsMapping[_address].team, participantsMapping[_address].personalDescription);
    }

    // Restrict access only Owner to access a secret about a specific address in a mapping
    function getSecret(address _address) onlyOwner external view returns(string memory secret) {
        return (participantsMapping[_address].secret);
    }

}
5
  • Thank you, I will test this in the very near future. However, I have a question. Deleting the "public" modifier for the mapping defaults it to "internal" (similar to "protected" in other programming languages). Does this really stop someone who is not the contract owner from seeing the content? For example, if I do something like instance.participantsMapping("0xc0CDB2Dd5Db92eC92cf98a41370f28E1899fCbE6") directly, without calling the getFields() function, won't that still show all the fields (including secret)? Apr 19, 2022 at 15:10
  • Yes, I forgot to set private when set partecipantsMapping. I updated the answer. Apr 19, 2022 at 15:22
  • The fields are still accessible by a direct storage read though. Nothing is really private, anyone can read the content, it's just harder to do but certainly not impossible.
    – hroussille
    Apr 19, 2022 at 17:03
  • @hroussille That was my concern too. According to this article, private variables can be relatively easily read. medium.com/coinmonks/… Maybe encrypting them first (in addition to doing what Kerry99 suggested) would be a good idea? How would one would proceed in this case? Apr 19, 2022 at 19:43
  • Yes, I guess you could encrypt the data before sending it on chain, but the algorithm / level of encryption is entirely up to you. It's just a little preprocessing on the client side anyway your solidity code could be left relatively unchanged.
    – hroussille
    Apr 20, 2022 at 11:57

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.