Solidity - 回退函数
如果没有其他函数与函数标识符匹配,或者函数调用没有提供数据,则执行 Solidity 回退函数。只能将一个未命名的函数分配给合约,并且只要合约收到没有任何数据的纯以太币,就会执行该函数。要接收 Ether 并将其添加到合约的总余额中,必须将回退函数标记为应付。如果没有这样的函数,合约就不能通过常规交易接收 Ether,并会抛出异常。
回退函数的属性:
- 没有名称或参数。
- 如果它没有被标记为payable ,合约将在收到没有数据的普通以太币时抛出异常。
- 不能返回任何东西。
- 每个合约可以定义一次。
- 如果调用者打算调用一个不可用的函数,它也会被执行
- 必须将其标记为外部。
- 当被另一个函数调用时,它被限制为 2300 gas。这是为了使这个函数调用尽可能便宜。
示例:在下面的示例中,创建合约以演示不同回退函数的不同条件。
Solidity
pragma solidity ^0.4.0;
// Creating a contract
contract GeeksForGeeks
{
// Declaring the state variable
uint x;
// Mapping of addresses to their balances
mapping(address => uint) balance;
// Creating a constructor
constructor() public
{
// Set x to default
// value of 10
x=10;
}
// Creating a function
function SetX(uint _x) public returns(bool)
{
// Set x to the
// value sent
x=_x;
return true;
}
// This fallback function
// will keep all the Ether
function() public payable
{
balance[msg.sender] += msg.value;
}
}
// Creating the sender contract
contract Sender
{
function transfer() public payable
{
// Address of GeeksForGeeks contract
address _receiver =
0xbcc0185441de06F0452D45AEd6Ad8b98017796fb;
// Transfers 100 Eth to above contract
_receiver.transfer(100);
}
}
输出:
解释:
1.Contract GeeksForGeeks:它有一个变量x,它在constructor()中被设置为默认值10。该合约有一个名为SetX(uint _x)的函数,它将函数值设置为函数调用期间发送的所需参数。下面的声明创建了称为 balance 的地址到值映射,该映射将地址映射到它们的余额。
mapping(address => uint) balance;
2. 合约发送方:这是一个完全独立且不相关的合约。它将以太币值发送到合约 GeeksForGeeks。合约不知道 GeeksForGeeks 合约的机制。发送没有任何消息且只有 Ether 的交易会导致错误。
下面的语句声明了一个地址类型的变量_receiver 。它明确存储合约 GeeksForGeeks 的地址。然后它使用address.transfer(value)将 Ether 转移到合约。
address _receiver = 0xbcc0185441de06F0452D45AEd6Ad8b98017796fb; //Address of GeeksForGeeks contract
_receiver.transfer(100);
3.函数()公开应付:
下面的函数是一个回退函数。它被宣布为应付,允许它接受转移价值。它在两种情况下被调用
- 合约只接收以太币,不接收数据。
- 即使帐户收到数据,也没有匹配的函数调用。
这有助于我们保护函数免于抛出错误。在这个程序中,合约 GeeksForGeeks 只接收 Ether,回退函数使用接收到的值添加到与发送地址相关的余额中。
function() public payable
{
balance[msg.sender] += msg.value;
}