9

Looking around I found Solidity functions - private visibility but not an answer to my specific question. Basically my question is: is the private keyword enforced at the Solidity language level or EVM level? My intuition says it is a Solidity feature but I wanted to double check here.

I am just getting started with Ethereum so pardon any beginner mistakes. Consider the following Solidity code:

contract Silly {
  function unsafePrivateWithdraw(address addr, uint amount) private {
    addr.transfer(amount);
  }
  function safeWithdraw(address addr, uint amount) {
    if (!checkWithdrawConditions) throw; // pseudocode
    unsafePrivateWithdraw(addr, amount);
  }
}

I know that using Solidity one wouldn't be able to call unsafePrivateWithdraw directly. But could somebody write in LLL or EVM opcodes a direct call to the address of the unsafePrivateWithdraw function?

Charles Cooper
  • 316
  • 2
  • 4

1 Answers1

15

No.

A private or internal function can only be called by the contract itself. Further, private functions cannot be called by derived contracts--so internal is more common. Here is Solidity's own documentation on the subject.

How does the EVM enforce this? Simple. On the EVM level, there are no function calls. Rather, Solidity generates a dispatcher for each contract, and sending a transaction just activates said dispatcher. On a theoretical level, making a function private is just a matter of not putting it in the dispatcher.

Matthew Schmidt
  • 7,290
  • 1
  • 24
  • 35
  • 1
    Thanks! That helps some, I see now that a private function (https://github.com/ethereum/solidity/blob/v0.4.11/libsolidity/codegen/ExpressionCompiler.cpp#L532) uses a JUMP instruction but a non-private function would use a CALL-series instruction (https://github.com/ethereum/solidity/blob/v0.4.11/libsolidity/codegen/ExpressionCompiler.cpp#L1718).

    I am still lacking a bit of clarity though. What does it mean to add a function to a dispatcher? Does that involve calling JUMPDEST?

    – Charles Cooper May 30 '17 at 21:33
  • Is it possible to call a private/internal function from the web3js frontend? – Ruham Sep 23 '18 at 12:47
  • 1
    @Ruham: No. There's no way to call a private/internal function in any way except from the contract itself. The web3js frontend only sends transactions, or simulates them being called. – Matthew Schmidt Sep 24 '18 at 13:06