函式是一個最小可被呼叫的元素
語法
function name([argument, ...]) [visibility] [view|pure]
[payable] [modifier, ...] [returns([argument, ...])];
可見度 (visibility) 有四種 public, private, internal, external,細節會在可見度的篇幅做進一步解釋。
範例
function setName(string name) public { ... };
function getName() view public returns(string name) { ... };
function compute() private returns(int num1, int num2) { ... };
當函式不修改任何狀態時,可以在函式宣告時標記 view 關鍵字。
以下的情境會修改狀態:
selfdestruct
view 或 pure 的函式pragma solidity ^0.4.16;
contract C {
function f(uint a, uint b) public view returns (uint) {
return a * (b + 42) + now;
}
}
constant是view的別名
當函式不讀取或不修改狀態時,可以在函式宣告時標記 pure 關鍵字。
除了上面列表的情況之外,還要考慮以下情況:
this.balance 或 <address>.balance.
block, tx, msg 物件裡的屬性 (除了 msg.sig 和 msg.data 是例外)pure 的函式pragma solidity ^0.4.16;
contract C {
function f(uint a, uint b) public pure returns (uint) {
return a * (b + 42);
}
}
讓函式可以接收以太幣
function fund(string _name) public payable {
// ...
}
合約可以有唯一個沒有函式名稱的函式,此函式不沒有參數,也不能返回值。如果在呼叫合約時,呼叫的函式名稱沒有比對到任何具名函式,這個函式就會被觸發。
除此之外,如果有人對於合約地址進行一般的轉帳作業,也會執行此函式。但為了要接收 Ether,函式必須要標記 payable,否則會無法接收 Ether。
通常呼叫 fallback 函式,只會消耗掉少量的 gas (例如 2300 gas),所以要盡量降低呼叫 fallback 函式的費用是非常重要的。
特別是以下操作,將消耗更多的 gas:
在部署你的合約之前,請測試你的 fallback 函式,確保它執行費用低於 2300 gas。
雖然
fallback函式規定不能有參數,但是你還是可以透過msg.data來取得資料。
如果你沒有宣告fallback函式,當有EOA帳戶轉錢給智能合約地址時,會直接直接拋出異常,並退回 Ether。
情境一
這個合約會自動收下所有 Ether 不會返回
contract Sink {
function() public payable { }
}
情境二
因為 Test 合約的 fallback 函式沒有標記 payable,所以合約會直接拋出異常,並退回 Ether。
pragma solidity ^0.4.0;
contract Test {
function() public { x = 1; }
uint x;
}
contract Caller {
function callTest(Test test) public {
test.call(0xabcdef01);
}
}
情境三
這個情境編譯會失敗,即使 Caller 合約送 Ether 到 Test 合約,因為 Test 合約沒有 payable,所以交易會失敗。

pragma solidity ^0.4.0;
contract Test {
function() public { x = 1; }
uint x;
}
contract Caller {
function callTest(Test test) public {
test.send(2 ether);
}
}
只要參數數量不同,合約可以有多個同名函式。
情境一
pragma solidity ^0.4.16;
contract A {
function f(uint _in) public pure returns (uint out) {
out = 1;
}
function f(uint _in, bytes32 _key) public pure returns (uint out) {
out = 2;
}
}
情境二
下面的範例,即使參數的型別不同,但參數的數量相同,還是無法編譯。

pragma solidity ^0.4.16;
contract A {
function f(B _in) public pure returns (B out) {
out = _in;
}
function f(address _in) public pure returns (address out) {
out = _in;
}
}
contract B {}