8

Assume I have two contracts as follows

contract FirstContract{

function anyFunction(){}

}

contract SecondContract{

  FirstContract x = new FirstContract();

function anotherFunction(){
  x.anyFunction(); ///////
}

}

How can I restrict anyFunction() so that only SecondContract can call it and nothing else?

ninesalt
  • 488
  • 1
  • 5
  • 14

2 Answers2

8

Use modifiers to restrict access to a function by other contracts/users.

Example:

contract FirstContract {

    address creator; // This will be the address of SecondContract.

    function FirstContract() {
        creator = msg.sender; // Which we set here.
    }

    modifier onlyCreator() {
        require(msg.sender == creator); // If it is incorrect here, it reverts.
        _;                              // Otherwise, it continues.
    } 

    function anyFunction() onlyCreator {} // This can now only be accessed by SecondContract

}

If this is what you are looking for, you may also be interested in researching the more common owned pattern, which works similarly.

Matthew Schmidt
  • 7,290
  • 1
  • 24
  • 35
  • Cool, this answers my question. Is there any way I could limit which contracts can instantiate another contract? I tried putting the modifier on the constructor but it didn't work. – ninesalt Aug 12 '17 at 12:16
  • In theory, you could put that same code in the constructor without a modifier. In practice, there's no way to stop a sufficiently determined individual from creating an instance of a contract. If nothing else, he can just modify the code to allow it. – Matthew Schmidt Aug 12 '17 at 21:35
  • This doesn't work and it's a huge security risk, this shouldn't be the accepted answer, msg.sender is the original tx sender not the direct caller. In the call "user -> contract1 -> contract2" msg.sender is user not contract1 – Enrique Alcazar Mar 13 '21 at 17:01
  • No. You are confusing tx.origin and msg.sender – Undead8 Feb 02 '22 at 19:51
0

Don't have enough rep to add comment. But just confirming the selected answer is correct and Enrique's comment is incorrect. User -> Contract1 ->Contract2, msg.sender IS contract 1 for contract2.

See here: Who is msg.sender when calling a contract from a contract

tx.origin is the EOA, msg.sender works for contract. enter image description here

Carlos M.
  • 101
  • 1