@@ -373,6 +373,8 @@ This solution has the major drawback that it introduces extra complexity, latenc
373373The best solution is to decouple the move from the execution without increasing the latency or the cost.
374374This way, the side-channel attacks are no longer possible because the move is not executed immediately.
375375To avoid increasing the latency, the move must be executed at the end of the block.
376+ Note that contracts can define the handleRefund function, which will be called with value equal to what is left from the gas processing paid for.
377+ This is called with enough gas to save locally how much should be refunded to whoever paid for the callback.
376378
377379See below a simple implementation of the coin flip game using the TEN platform:
378380
@@ -385,11 +387,19 @@ interface TenCallbacks {
385387 function register(bytes calldata) external payable returns (uint256);
386388}
387389
390+ interface Refunds {
391+ function handleRefund(uint256 callbackId) external payable;
392+ }
393+
388394contract CoinFlip {
389395 // Event to emit the result of the coin flip
390396 event CoinFlipResult(address indexed player, bool didWin, uint256 randomNumber);
391397
392398 private TenCallbacks tenCallbacks;
399+ mapping(uint256 callbackId => address player) public callbackToPlayer;
400+ mapping(address player => uint256 refundAmount) public playerToRefundAmount;
401+
402+
393403
394404 modifier onlyTenSystemCall() {
395405 require(msg.sender == address(tenCallbacks));
@@ -436,5 +446,19 @@ contract CoinFlip {
436446 function getRandomNumber() internal view returns (uint256) {
437447 return block.prevrandao;
438448 }
449+
450+ function handleRefund(uint256 callbackId) external payable {
451+ address player = callbackToPlayer[callbackId];
452+ playerToRefundAmount[player] += msg.value;
453+ }
454+
455+ function claimRefund() external {
456+ uint256 refundAmount = playerToRefundAmount[msg.sender];
457+ require(refundAmount > 0, "No refunds to claim");
458+ playerToRefundAmount[msg.sender] = 0;
459+ (bool success, ) = payable(msg.sender).call{value: refundAmount}("");
460+ require(success, "Transfer failed");
461+ }
462+
439463}
440464```
0 commit comments