Skip to main content
This page covers the FHERC20 transfer functions and the disclosure flow that turns an encrypted amount into a public, verified one. It assumes you know what an FHERC20 token stores.

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:
The proof is bound to both the consuming contract and the sender. If either differs, the transaction reverts with 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:
The 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 a sharedEuint64 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.