0

Functional Background:

Contracts for upgradable design pattern: ProofDB.sol : contract to store the data. Proof.sol : contract that contains the business logic. Registry.sol: contract that contains the latest version of Proof.sol

Flow: Frontend application first calls the Registry.sol contract to get the latest veresion of Proof.sol(logic contract). After receiving the latest version it makes calls to respective function. Proof.sol contracts executes the call and sotres the state in ProofDB.sol.

**Migrations script:**

Sequence of deployment:
deployer.deploy(Mortal).then(() => {
return deployer.deploy(ProofDB)
}).then(() => {
return deployer.deploy(Proof, ProofDB.address);
}).then(() => {
return deployer.deploy(Registry, Proof.address);
})



**Code from ProofDB.sol**     
Contract ProofDB.sol {

        constructor() public {
            owner = message.sender;
        }

        modifier onlyAllowedContractOrOwner {
            require (allowedContracts[msg.sender] != true && msg.sender != owner,"Should be a owner");
            _;
        }

        function addAllowedContractOrOwner(address _addr)
        public
        onlyOwner 
        returns(bool) {
            if( allowedContracts[_addr] == false ) {
                allowedContracts[_addr] = true;
                allowedContractsKeys.push(_addr);
                return true;
            }
            return false;
        }

    }

Problem statement:

To ensure the contracts are not vulnarabel to the attack. I want to restrict the access to ProofDB.sol only to selected contracts and owners. How can I do during deployment.How can I invoke ProofDB.sol contract during deployment to pass the list of allowed users and contracts that can access it.

Issue:

  1. I cannot pass constructor arguments because ProofDB.sol sould be deployed first in the sequence. At that point I do not know the address of Proof.sol.
  2. Is there a way to pass the allowed contracts and owners to ProofDB.sol during deployment with out doing it manually ?
0

Here's a sketch.

pragma solidity 0.4.24;

contract DB {

  address public owner;
  mapping(address => bool) public allowedContracts;

  modifier onlyAllowedContracts() {
      require(allowedContracts[msg.sender]);
      _;
  }

  modifier onlyOwner {
      require(msg.sender == owner);
      _;
  }

  constructor() public {
      owner = msg.sender;
  }

  function isAllowedContract(address check) public view returns(bool isIndeed) {
      return allowedContracts[check];
  }

  function addAllowedContract(address newContract) public onlyOwner returns(bool success) {
      require(!isAllowedContract(newContract));
      allowedContracts[newContract] = true;
      return true;
  }

  function removeAllowedContract(address newContract) public returns(bool success) {
      require(isAllowedContract(msg.sender));
      allowedContracts[newContract] = false;
      return true;
  }

  function insertNewDataRecords() public onlyAllowedContracts returns(bool success) {
      // do something
      return true;
  }
}

I separated contract writers from the owner. You don't need the added complexity of an either/or modifier because the owner can always add itself to the allowed writers list.

Hope it helps.

  • I get your point that the owner can always add or remove allowed contracts. But when doing deployment using truffle it can get really tough to take the addresses of the latest contract manually and add it to the storage contract. I want to know if there is any way where addAllowedContractOrOwner() function can be triggered with the latest logic contract version ? – Santosh Kumar Aug 23 '18 at 19:30

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.