Error handling
Challenges in error handling
Recommended approach: Error logging with a handler
Example implementation
struct LastError {
euint8 error; // Encrypted error code
uint timestamp; // Timestamp of the error
}
// Define error codes
euint8 internal NO_ERROR;
euint8 internal NOT_ENOUGH_FUNDS;
constructor() {
NO_ERROR = FHE.asEuint8(0); // Code 0: No error
NOT_ENOUGH_FUNDS = FHE.asEuint8(1); // Code 1: Insufficient funds
}
// Store the last error for each address
mapping(address => LastError) private _lastErrors;
// Event to notify about an error state change
event ErrorChanged(address indexed user);
/**
* @dev Set the last error for a specific address.
* @param error Encrypted error code.
* @param addr Address of the user.
*/
function setLastError(euint8 error, address addr) private {
_lastErrors[addr] = LastError(error, block.timestamp);
emit ErrorChanged(addr);
}
/**
* @dev Internal transfer function with error handling.
* @param from Sender's address.
* @param to Recipient's address.
* @param amount Encrypted transfer amount.
*/
function _transfer(address from, address to, euint32 amount) internal {
// Check if the sender has enough balance to transfer
ebool canTransfer = FHE.le(amount, balances[from]);
// Log the error state: NO_ERROR or NOT_ENOUGH_FUNDS
setLastError(FHE.select(canTransfer, NO_ERROR, NOT_ENOUGH_FUNDS), msg.sender);
// Perform the transfer operation conditionally
balances[to] = FHE.add(balances[to], FHE.select(canTransfer, amount, FHE.asEuint32(0)));
FHE.allowThis(balances[to]);
FHE.allow(balances[to], to);
balances[from] = FHE.sub(balances[from], FHE.select(canTransfer, amount, FHE.asEuint32(0)));
FHE.allowThis(balances[from]);
FHE.allow(balances[from], from);
}How It Works
Example error query
Benefits of this approach
Last updated