Fee delegation¶
Generally the user who sends a transaction needs to pay the transaction execution fee. The fee delegation is a feature that allows the contract to pay the execution, so the user does not need to pay for it.
In order to use this feature, the contract needs to support fee delegation and the transaction must use the FeeDelegation type. The contract also needs to have sufficient balance to pay the execution.
Registering the functions¶
The functions to be executed using fee delegation must be specified with abi.fee_delegation()
Example:
abi.fee_delegation(function1, function2)
check_delegation function¶
The check_delegation
is a special function used to check whether the transaction can be processed using fee delegation.
In another words: if the contract will pay for this specific transaction execution or not.
It is called by the engine when a transaction with fee delegation type arrives (a transaction asking to be paid by the contract). The arguments to this function are:
- the name of the function that the transaction wants to call/execute
- the arguments to that function
You can use any logic to determine if the transaction will be paid by the contract.
It is common to check who is sending the transaction with system.getOrigin()
or system.getSender()
.
This function should return a boolean (true
=accept or false
=reject) and it is read-only (it should not write to the state).
Differing from normal calls¶
Notice that the function marked to be called using fee delegation can also be called with transactions that pay themselves for the execution.
You can check whether the transaction is using fee delegation with the system.isFeeDelegation()
function.
Transfering coins to the smart contract¶
Currently the existing method is by using a transaction with type CALL and setting the desired amount.
The smart contract must have a function registered with abi.payable()
, generally the default
function.
In this case no payload is required, otherwise the transaction must specify the name of the function that will receive the transfer.
Contract example¶
Here is a very basic example of a contract that implements fee delegation:
state.var{
whitelist = state.map(),
item = state.value()
}
function reg(user)
if (k == nil) then
whitelist[system.getSender()] = true
else
whitelist[user] = true
end
end
function work(arg0)
if (system.isFeeDelegation() == true) then
whitelist[system.getSender()] = false
end
item:set(arg0)
end
function check_delegation(fname, arg0)
if (fname == "work") then
return whitelist[system.getSender()]
end
return false
end
function default()
end
abi.register(reg, work)
abi.payable(default)
abi.fee_delegation(work)
aergocli example¶
aergocli contract call --delegation AmPbWrQbtQrCaJqLWdMtfk2KiN83m2HFpBbQQSTxqqchVv58o82i Amh6aHxfoMrCmXd2GrV3Yem1zmcqgAiPaJAhsux3wedpEVUCGowx work
1 : HtyNZdJzJNYkeCQCrz8xozPvGLn1xhde9ExNEEiEKPy4 TX_OK
Receipt¶
aergocli receipt get HtyNZdJzJNYkeCQCrz8xozPvGLn1xhde9ExNEEiEKPy4
{
"BlokNo": 9673,
"BlockHash": "Az8pJvDso44nP9Lq5Wj7QoU6n9yZcFkCcmJaiRKyq9Qz",
"contractAddress": "Amh6aHxfoMrCmXd2GrV3Yem1zmcqgAiPaJAhsux3wedpEVUCGowx",
"status": "SUCCESS",
"ret": "",
"txHash": "HtyNZdJzJNYkeCQCrz8xozPvGLn1xhde9ExNEEiEKPy4",
"txIndex": 0,
"from": "AmPbWrQbtQrCaJqLWdMtfk2KiN83m2HFpBbQQSTxqqchVv58o82i",
"to": "Amh6aHxfoMrCmXd2GrV3Yem1zmcqgAiPaJAhsux3wedpEVUCGowx",
"usedFee": 2000000000000000,
"feeDelegation": true,
"events": []
}