Solidity

Solidity Function Calls

Solidity Function Calls Main Tips

  • In Solidity you can call functions either internally or externally.
  • Only the same contract’s functions of the same contract may be called internally, whereas external function calls refer to other contracts

Solidity Function Calls Internal

The current contract’s functions are possible to call directly, to which we also refer to as calling functions internally, as well as recursively, as shown in this example: 

Example

pragma solidity ^0.4.0;

contract cont {
    function func1(uint x) returns (uint returnValue) { return func2(); }
    function func2() returns (uint returValue) { return func1(7) + func2(); }
}

 

Try on Remix Try live on Hosting

Those function calls get translated to simple jumps in the EVM. The effect of this is the current memory not being cleared, for example, passing references of memory to internally-called functions is extermely efficient. You can only call functions that are in the same contract internally though.


Solidity Functions Calls External

The expressions this.func2(8); and cont.func2(2); (the cont being an instance of a contract) are valid function calls too, however, in this case, the function is going to be called “externally”, through a message call instead of being called directly via jumps. Keep in mind that function calls in this are not usable inside the constructor, since the contract itself has not been created yet.

Other contracts’ functions must be called externally. To create an external call, eacg function argument has to be copied into memory.

When functions of other contracts are called, the number of Wei sent along with the call, so the gas may be specified using special options .gas() and .value(), respectively:

Example

pragma solidity ^0.4.0;

contract DataFeed {
    function data() payable returns (uint dataReturn) { return 42; }
}

contract DataConsumer {
    InfoFeed feed;
    function feedSet(address addr) { feed = DataFeed(addr); }
    function feedCall() { feed.data.value(10).gas(800)(); }
}

 

Try on Remix Try live on Hosting 

The modifier called payable must be used for data, as otherwise, the option .value() will not be available.

Notice how the expression DataFeed(addr) will perform an explicit conversion of type stating that “we know that the type of the contract at the given address is DataFeed” which does not execute a constructor. Explicit type conversions must be handled with extra cautiously. A function on a contract in which you are not sure about the type it has should never be called.

We could have used function feedSet( DataFeed _feed ) { feed = _feed; } directly as well. Be cautious about the fact that feed.data.value(10).gas(800) sets the value only locally and amount of gas that is sent with the function call, so only the parentheses at the end would perform the call itself.

Function calls will cause exceptions in the scenario that the called contract does not exist at all (the account iself contains no code) or when the called contract itself has thrown an exception or runs out of gas.

Warning: Any kind of interaction with another contract poses a potential danger, even more so, when the contract’s source code is not known in advance. The current contract would then hand over control to the called contract that was called, at which point there is no telling what the other contract is going to do. Even in the cases that the called contract would inherit from a known parent contract, the contract that is inheriting is only required for having a correct interface. The contract’s implementation, however, may be completely arbitrary, posing a potential danger. Additionally, you should prepare for the case that it would call into other contracts in your system or even right back into the contract that is calling before the first call is returned. This would mean that the called contract is capable of changing state variables that belong to the calling contract using its functions. Your functions should be written in a way that, for example, would call to external functions when any changes to state variables inside your contract are made, so your contract would not be vulnerable to a reentrancy exploit.


Solidity Function Calls Named Calls And Anonymous Parameters

Arguments of a function call can also be assigned by name, in any order, so long they are enclosed in { } like in the following example. The list of arguments must coincide by name with the parameter list from the declaration of the functions, however, it can be in an arbitrary order.

Example

pragma solidity ^0.4.0;

contract cont {
    function func1(uint value, uint key) {
        // ...
    }

    function func2() {
        // arguments are named
        func1({key: 3, value: 2});
    }
}

 

Try on Remix Try live on Hosting


Solidity Function Calls Omit Function Parameter Names

Unused parameter names (even mor so return parameters) may be omitted. These parameters are still going to be present on the stack, however, they will be inaccessible.

Example

pragma solidity ^0.4.0;

contract cont {
    // omitted name for parameter
    function func1(uint var1, uint) returns(uint) {
        return var1;
    }
}

 

Try on Remix Try live on Hosting

Read previous post:
Solidity Control Structures

Solidity Control Structures Main Tips In Solidity, much like in JavaScript, functions can take input in the form of parameters....

Close