Hi @filipaze,
The function is first making sure that _toContract is actually a contract (an account with code in it). Then in general lines it calls _toContract method _method with parameters _args, _fromContractAddr and _fromChainId. In particular the _method parameters is a string (encoded in bytes) with the name of the function to be called.
If _method has, for example, the value “doSomething”, the code above would be executing:
_toContract.doSomething(_args, _fromContractAddr, _fromChainId)
The way it does this call is by first calculating the function selector for the _method parameters. This is done by hashing the signature of the method “doSomething(bytes,bytes,uint64)” and getting the first 4 bytes. This is what the first part of the last line is doing. It first concatenates the _method name to the rest of the signature:
abi.encodePacked(_method, "(bytes,bytes,uint64)")
Then it hashes it:
keccak256(abi.encodePacked(_method, "(bytes,bytes,uint64)"))
And finally gets the first 4 bytes:
bytes4(keccak256(abi.encodePacked(_method, "(bytes,bytes,uint64)")))
That will yield a 4 bytes value with the function selector for the function name in _method. Let’s call this value _selector.
Finally it appends to this selector the required parameters in order to call that function in the other contract:
abi.encodePacked(_selector, abi.encode(_args, _fromContractAddr, _fromChainId))
This yields a sequence of bytes that encode a call to _selector with the rest of the parameters as arguments. Let’s call this sequence of bytes _calldata. Notice that _args, _fromContractAddr and _fromChaind parameters follow the signature used to calculate the selector (bytes,bytes,uint64).
Then it goes into calling that function in _toContract:
_toContract.call(_calldata)
Hope this helps!