Which transfer function do you call?
Each transfer comes in two forms. Pick by who holds the amount:
Both encrypted types are
bytes32 in the ABI, so ethers cannot pick the overload by argument types. Index the contract with the full signature, as in the table.
The AndCall versions of both functions also notify the recipient. See transfer callbacks.
How do you send from a wallet?
Encrypt the amount with the SDK. Name the token as the consuming contract, and encrypt with the client of the account that sends the transaction:InvalidSigner. That includes encrypting as one account and submitting from another, so an operator encrypts with its own client. See encrypting inputs for client setup.
How do you send from a contract?
A contract that already holds an encrypted amount shares it with the token, then reads back what moved:sharedEuint64 overloads accept only a share that the direct caller created for the token. An account that passes a bare handle gets NotShared, so a wallet cannot use them. Call a token from your contract walks through a full example.
What happens when the balance is too low?
The transfer succeeds and moves zero. The token cannot revert on an encrypted comparison without revealing its result. Instead it moves the requested amount if the balance covers it, and zero otherwise. Every transfer function returns that amount as asharedEuint64 directed at the caller. A contract caller reads it with FHE.receiveEuint64FromCall and should act on it, not on the amount it requested. A wallet can find the same handle in the ConfidentialTransfer event.
The token grants persistent access to the moved amount to the sender, the recipient, and the token itself. Either party can decrypt it with decryptForView.
The one case that does revert is a sender that has never held the token. Its balance handle does not exist, so the transfer fails with FHERC20ZeroBalance.
What does a transfer emit?
Mints emit both events with
from set to the zero address, and burns with to set to the zero address.
All transfer functions are nonReentrant. A callback that tries to start a second transfer on the same token in the same call reverts.
Errors
How do you make an amount public?
Disclosure publishes a decrypted amount onchain together with a proof that it is correct. Use it when an amount has to become public, such as a payment that a third party must verify.1
Request disclosure
Call
requestDiscloseEncryptedAmount(handle) from an account that has access to the handle, such as the holder of a balance. The token makes the handle publicly decryptable and emits AmountDiscloseRequested. A caller without access gets FHERC20UnauthorizedUseOfEncryptedAmount.2
Decrypt it
Anyone can now decrypt the handle with
decryptForTx, without an ACP:3
Publish the result
Call
discloseEncryptedAmount(handle, decryptedValue, signature). The token verifies the signature and emits AmountDisclosed(handle, amount). A value that does not match the handle reverts with InvalidSigner.discloseEncryptedAmount checks only the proof. It does not need a prior request, so you can publish any handle you hold a valid decryption proof for.
Disclosing a balance handle reveals that balance at that moment and cannot be undone. Later balance changes create new handles, which stay private.