Skip to main content
1 of 3
BonisTech
  • 672
  • 5
  • 17

If you're purely trying to use the call() instruction, this will not work. However, it is actually possible to call a private function from within a contract.

Since you're playing around with Yul, what I like to do is write a simple contract in Solidity and compile it using the IR optimizer and look at the output to understand it more. Here's an example:

  1. Write a contract Foo.sol:
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;

contract Foo {
    function privateFunction() private pure returns(uint256) {
        return 42;
    }

    function someFunction() external pure returns(uint256) {
        return privateFunction();
    }

    function anotherFunction() external pure returns(uint256) {
        return privateFunction();
    }
}
  1. Compile it using the following command:

solc --optimize --ir-optimized -o out ./Foo.sol --overwrite

  1. Look at the output file in ./out/Foo_opt.sol. The output should look like this:
/// @use-src 0:"src/Foo.sol"
object "Foo_28" {
    code {
        {
           /// here goes the constructor code
        }
    }
    /// @use-src 0:"src/Foo.sol"
    object "Foo_28_deployed" {
        code {
            {
                /// @src 0:65:376  "contract Foo {..."
                mstore(64, memoryguard(0x80))
                if iszero(lt(calldatasize(), 4))
                {
                    switch shr(224, calldataload(0))
                    case 0x0714c622 { // function signature of anotherFunction()
                        external_fun_anotherFunction() // call to private function
                    }
                    case 0x35b09a6e { // function signature of someFunction()
                        external_fun_anotherFunction() // call to private function
                    }
                }
                revert(0, 0)
            }
            function external_fun_anotherFunction() // the function privateFunction() 
            {
                if callvalue() { revert(0, 0) }
                if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }
                let memPos := mload(64)
                mstore(memPos, /** @src 0:158:160  "42" */ 0x2a)
                /// @src 0:65:376  "contract Foo {..."
                return(memPos, 32)
            }
        }
        data // here goes the meta data
    }
}

Explanation: The compiler writes an internal/private external_fun_anotherFunction function, which is called by the other two functions. You can go through the code line by line, and hopefully learn a bit more :)

BonisTech
  • 672
  • 5
  • 17