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:
- 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();
}
}
- Compile it using the following command:
solc --optimize --ir-optimized -o out ./Foo.sol --overwrite
- 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 :)