Skip to main content

Solidity API

PrivateToken

Implementation of PrivateToken. total supply is set at construction by the deployer and cannot exceed type(uint40).max = 1099511627775 because during Exponential ElGamal decryption we must solve the DLP quickly Balances are encrypted to each owner's public key, according to the registered keys inside the PublicKeyInfrastructure. Because we use Exponential ElGamal encryption, each EncryptedAmount is a pair of points on Baby Jubjub (C1,C2) = ((C1x,C1y),(C2x,C2y)).

EncryptedAmount

struct EncryptedAmount {
uint256 C1x;
uint256 C1y;
uint256 C2x;
uint256 C2y;
}

PendingTransfer

struct PendingTransfer {
struct PrivateToken.EncryptedAmount amount;
uint40 fee;
uint256 time;
}

PendingDeposit

struct PendingDeposit {
uint256 amount;
uint40 fee;
}

PROCESS_DEPOSIT_VERIFIER

contract UltraVerifier PROCESS_DEPOSIT_VERIFIER

PROCESS_TRANSFER_VERIFIER

contract UltraVerifier PROCESS_TRANSFER_VERIFIER

TRANSFER_VERIFIER

contract UltraVerifier TRANSFER_VERIFIER

WITHDRAW_VERIFIER

contract UltraVerifier WITHDRAW_VERIFIER

LOCK_VERIFIER

contract UltraVerifier LOCK_VERIFIER

totalSupply

uint40 totalSupply

token

contract IERC20 token

SOURCE_TOKEN_DECIMALS

uint256 SOURCE_TOKEN_DECIMALS

decimals

uint8 decimals

balances

mapping(bytes32 => struct PrivateToken.EncryptedAmount) balances

pendingTransferCounts

mapping(bytes32 => uint256) pendingTransferCounts

pendingDepositCounts

mapping(bytes32 => uint256) pendingDepositCounts

allPendingTransfersMapping

mapping(bytes32 => mapping(uint256 => struct PrivateToken.PendingTransfer)) allPendingTransfersMapping

allPendingDepositsMapping

mapping(bytes32 => mapping(uint256 => struct PrivateToken.PendingDeposit)) allPendingDepositsMapping

nonce

mapping(bytes32 => mapping(uint256 => bool)) nonce

lockedTo

mapping(bytes32 => address) lockedTo

Transfer

event Transfer(bytes32 to, bytes32 from, struct PrivateToken.EncryptedAmount amount)

TransferProcessed

event TransferProcessed(bytes32 to, struct PrivateToken.EncryptedAmount newBalance, uint256 processFee, address processFeeRecipient)

Deposit

event Deposit(address from, bytes32 to, uint256 amount, uint256 processFee)

DepositProcessed

event DepositProcessed(bytes32 to, uint256 amount, uint256 processFee, address feeRecipient)

Withdraw

event Withdraw(bytes32 from, address to, uint256 amount, address _relayFeeRecipient, uint256 relayFee)

Lock

event Lock(bytes32 publicKey, address lockedTo, uint256 relayerFee, address relayerFeeRecipient)

Unlock

event Unlock(bytes32 publicKey, address unlockedFrom)

constructor

constructor(address _processDepositVerifier, address _processTransferVerifier, address _transferVerifier, address _withdrawVerifier, address _lockVerifier, address _token, uint256 _decimals, address _addEthSignerVerifier, address _changeEthSignerVerfier, address _changeMultisigEthSignerVerifier) public

Constructor - setup up verifiers and link to token @dev

Parameters

NameTypeDescription
_processDepositVerifieraddressaddress of the processDepositVerifier contract
_processTransferVerifieraddressaddress of the processTransferVerifier contract
_transferVerifieraddressaddress of the transferVerifier contract
_withdrawVerifieraddressaddress of the withdrawVerifier contract
_lockVerifieraddressaddress of the lockVerifier contract
_tokenaddress- ERC20 token address
_decimalsuint256
_addEthSignerVerifieraddress
_changeEthSignerVerfieraddress
_changeMultisigEthSignerVerifieraddress

deposit

function deposit(address _from, uint256 _amount, bytes32 _to, uint40 _processFee) public

Deposits the assocated token into the contract to be used privately. The deposited amount is pushed to the recepients PendingDeposits queue. The fee is the amount that will be paid to the processor of the tx (when processPendingDeposits is called) This function converts the token to 2 decimal places, the remainder is lost. @dev

Parameters

NameTypeDescription
_fromaddress- sender of the tokens, an ETH address
_amountuint256- amount to deposit
_tobytes32- the packed public key of the recipient in the system
_processFeeuint40- (optional, can be 0) amount to pay the processor of the tx (when processPendingDeposits is called)

transferLocals

This functions transfers an encrypted amount of tokens to the recipient (_to). If the sender is sending to an account with a 0 balance, they can omit the fee, as the funds will be directly added to their account. Otherwise a fee can be specified to incentivize processing of the tx by an unknown third party (see processPendingTranfer). This is required two account cannot simultaneously update the encrypted balance of the recipient. Having a pending transfer queue allows the sender to always succeed in debiting their account, and the recipient receiving the funds. The account must not be locked to a contract to call this function. @dev

Parameters

NameTypeDescription
struct transferLocals {
uint256 txNonce;
address lockedByAddress;
struct PrivateToken.EncryptedAmount oldBalance;
struct PrivateToken.EncryptedAmount receiverBalance;
uint256 transferCount;
bool zeroBalance;
bytes32[] publicInputs;
}

transfer

function transfer(bytes32 _to, bytes32 _from, uint40 _processFee, uint40 _relayFee, address _relayFeeRecipient, struct PrivateToken.EncryptedAmount _amountToSend, struct PrivateToken.EncryptedAmount _senderNewBalance, bytes _proof_transfer) public

withdraw

function withdraw(bytes32 _from, address _to, uint40 _amount, uint40 _relayFee, address _relayFeeRecipient, bytes _withdraw_proof, struct PrivateToken.EncryptedAmount _newEncryptedAmount) public

withdraws the amount of tokens from the contract to the recipient (_to). the account must not be locked to a contract to call this function. @dev @param _from - the packed public key of the sender in the system @param _to - the ETH address of the recipient @param _amount - amount to withdraw @param _relayFee - (optional, can be 0) amount to pay the relayer of the tx, if the sender of the ETH tx is not the creator of the proof. sharing of the proof can happen in off-chain channels the relayer can check that they will get the fee by verifing the proof off-chain before submitting the tx

Parameters

NameTypeDescription
_frombytes32
_toaddress
_amountuint40
_relayFeeuint40
_relayFeeRecipientaddress- the recipient of the relay fee @param _withdraw_proof - proof @param _newEncryptedAmount - the new encrypted balance of the sender after the withdraw and fee
_withdraw_proofbytes
_newEncryptedAmountstruct PrivateToken.EncryptedAmount

processPendingDeposit

function processPendingDeposit(bytes _proof, uint256[] _txsToProcess, address _feeRecipient, bytes32 _recipient, struct PrivateToken.EncryptedAmount _zeroBalance, struct PrivateToken.EncryptedAmount _newBalance) public

the circuit processing this takes in a fixes number of pending transactions. It will take up to 4 at a time (TODO: research how big this num should this be?). The circuit checks that the publicKey and recipient match. it encrypts the totalAmount and adds it to the recipients encrypted balance. It checks that the provided encrypted balance and the calculated encrypted balances match. @dev

Parameters

NameTypeDescription
_proofbytes- proof to verify with the ProcessPendingTransfers circuit
_txsToProcessuint256[]- an array of keys of PendingDeposits to process from allPendingDepositsMapping max length 4
_feeRecipientaddress- the recipient of the fees (typically the processor of these txs)
_recipientbytes32- the packed public key of the recipient in the system
_zeroBalancestruct PrivateToken.EncryptedAmount
_newBalancestruct PrivateToken.EncryptedAmount- the new balance of the recipient after processing the pending transfers

processPendingTransfer

function processPendingTransfer(bytes _proof, uint8[] _txsToProcess, address _feeRecipient, bytes32 _recipient, struct PrivateToken.EncryptedAmount _newBalance) public

the circuit processing this takes in a fixes number of pending transactions. It will take up to 4 at a time (TODO: research how big this num should this be?). The circuit adds all of the encrypted amounts sent and then checks that the _newBalance is the sum of the old balance and the sum of the amounts to add. All of the fees are summed and sent to the _feeRecipient @dev

Parameters

NameTypeDescription
_proofbytes- proof to verify with the ProcessPendingTransfers circuit
_txsToProcessuint8[]- the indexs of the userPendingTransfersArray to process; max length 4
_feeRecipientaddress- the recipient of the fees (typically the processor of these txs)
_recipientbytes32- the recipient of the pending transfers within the system
_newBalancestruct PrivateToken.EncryptedAmount- the new balance of the recipient after processing the pending transfers

lock

function lock(bytes32 _from, address _lockToContract, uint40 _relayFee, address _relayFeeRecipient, bytes _proof, struct PrivateToken.EncryptedAmount _newEncryptedAmount) public

the contract this is locked to must call unlock to give control back to this contract locked contracts cannot transfer or withdraw funds. @param _from - the public key of the account to lock

Parameters

NameTypeDescription
_frombytes32
_lockToContractaddress- the contract to lock the account to
_relayFeeuint40- (optional, can be 0) amount to pay the relayer of the tx, if the sender of the ETH tx is not the creator of the proof. sharing of the proof can happen in off-chain channels the relayer can check that they will get the fee by verifing the proof off-chain before submitting the tx
_relayFeeRecipientaddress- the recipient of the relay fee
_proofbytes- proof to verify with the ProcessPendingTransfers circuit
_newEncryptedAmountstruct PrivateToken.EncryptedAmount- the new encrypted balance of the sender after the fee

unlock

function unlock(bytes32 publicKey) public

unlocks an account locked by a contract. This function must be called by the contract that is locked to an account. Users must lock their account to a contract that has a function that calls this function, or their funds will be locked forever. @dev

Parameters

NameTypeDescription
publicKeybytes32- the packed public key of the account to unlock

checkAndUpdateNonce

function checkAndUpdateNonce(bytes32 _from, struct PrivateToken.EncryptedAmount _encryptedAmount) internal returns (uint256)

_stageCommonTransferInputs

function _stageCommonTransferInputs(struct PrivateToken.transferLocals local, bytes32 _from, bytes32 _to, uint40 _processFee, uint40 _relayFee, struct PrivateToken.EncryptedAmount _amountToSend, struct PrivateToken.EncryptedAmount _senderNewBalance) internal pure returns (struct PrivateToken.transferLocals)

PrivateTokenFactory

privateToken

address privateToken

processDepositVerifier

address processDepositVerifier

processTransferVerifier

address processTransferVerifier

transferVerifier

address transferVerifier

withdrawVerifier

address withdrawVerifier

lockVerifier

address lockVerifier

addEthSignerVerifier

address addEthSignerVerifier

changeEthSignerVerifier

address changeEthSignerVerifier

changeMultisigEthSignerVerifier

address changeMultisigEthSignerVerifier

Deployed

event Deployed(address token)

constructor

constructor(address _pendingDepositVerifier, address _pendingTransferVerifier, address _transferVerifier, address _withdrawVerifier, address _lockVerifier, address _addEthSignerVerifier, address _changeEthSignerVerfier, address _changeMultisigEthSignerVerifier) public

deploy

function deploy(address _token) public returns (address)

UsingAccountControllers

Use this contract with PrivateToken.sol to use the non-default private/public key pairs

MultisigParams

struct MultisigParams {
address[] ethSigners;
uint256 threshold;
}

ethSigner

mapping(bytes32 => address) ethSigner

Mapping of packed public key to eth signer address

erc4337Controller

mapping(bytes32 => address) erc4337Controller

Mapping of packed public key to erc4337 controller address

multisigEthSigners

mapping(bytes32 => struct UsingAccountControllers.MultisigParams) multisigEthSigners

Mapping of packed public key to multisig params

otherNonce

mapping(bytes32 => uint256) otherNonce

Mapping of packed public key to nonce to prevent replay attacks when changing eth signers

BJJ_PRIME

uint256 BJJ_PRIME

The prime field that the circuit is constructed over. This is used to make message hashes fit in 1 field element

addEthSignerVerifier

contract UltraVerifier addEthSignerVerifier

change functions can be used to revoke, just set to address(0)

changeEthSignerVerifier

contract UltraVerifier changeEthSignerVerifier

changeMultisigEthSignerVerifier

contract UltraVerifier changeMultisigEthSignerVerifier

AddController

event AddController(bytes32 packedPublicKey, address controllerAddress)

Change4337Controller

event Change4337Controller(bytes32 packedPublicKey, address oldControllerAddress, address newControllerAddress)

ChangeEthSigner

event ChangeEthSigner(bytes32 packedPublicKey, address oldEthSignerAddress, address newEthSignerAddress)

AddMultisigEthSigners

event AddMultisigEthSigners(bytes32 packedPublicKey, address[] ethSignerAddresses, uint256 threshold)

ChangeMultisigEthSigners

event ChangeMultisigEthSigners(bytes32 packedPublicKey, address[] oldEthSignerAddresses, address[] newEthSignerAddresses, uint256 oldThreshold, uint256 newThreshold)

constructor

constructor(address _addEthSignerVerifier, address _changeEthSignerVerfier, address _changeMultisigEthSignerVerifier) public

addOtherController

function addOtherController(bytes32 _packedPublicKey, address _ethAddress, bytes _proof) public

This function allows a Private Token account to assign an eth signer or an erc4337 controller. The address associated with the packed public key must be 0x0.

See the add_eth_signers circuit for circuit details

Parameters

NameTypeDescription
_packedPublicKeybytes32The packed public key of the account to update
_ethAddressaddressThe eth address of the signer or the 4337 account
_proofbytesThe proof that the caller has the private key corresponding to the packed public key

change4337Controller

function change4337Controller(bytes32 _packedPublicKey, address _newAddress) public

This function updates the erc4337 controller. It must be called by the current 4337 controller.

There is no proof validation required because the caller must be the current controller.

Parameters

NameTypeDescription
_packedPublicKeybytes32The packed public key of the account to update
_newAddressaddressThe new erc4337 controller address. Can be address(0) to revoke.

changeEthSigner

function changeEthSigner(bytes _proof, bytes32 _packedPublicKey, address _newEthSignerAddress) public

This function updates the eth signer address. The proof will verify a signature from the current registered signer

The message hash is calculated in the function to prevent replay attacks. The caller must sign the corresponding hash and use it when generating the proof See the change_eth_signer circuit for circuit details

Parameters

NameTypeDescription
_proofbytesThe proof that the caller can create a signautre corresponding to the registered eth signer
_packedPublicKeybytes32The packed public key of the account to update
_newEthSignerAddressaddressThe new eth signer address. Can be address(0) to revoke.

addMultisigEthSigners

function addMultisigEthSigners(bytes _proof, bytes32 _packedPublicKey, address[] _ethSignerAddresses, uint256 _threshold) public

This function adds a multisig eth signer. It uses the addEthSignerVerifier circuit.

See the add_eth_signers circuit for circuit details

Parameters

NameTypeDescription
_proofbytesThe proof that the caller has the private key corresponding to the packed public key
_packedPublicKeybytes32The packed public key of the account to update
_ethSignerAddressesaddress[]The new eth signer addresses on the multisig
_thresholduint256The threshold of signatures required to sign a message

changeMultisigEthSigners

function changeMultisigEthSigners(bytes _proof, bytes32 _packedPublicKey, address[] _newEthSignerAddresses, uint256 _threshold) public

This function changes the multisig eth signers.

See the change_multi_eth_signers circuit for circuit details

Parameters

NameTypeDescription
_proofbytesThe proof that the caller has enough signatures to change the multisig eth signers
_packedPublicKeybytes32The packed public key of the account to update
_newEthSignerAddressesaddress[]The new eth signer addresses on the multisig
_thresholduint256The threshold of signatures required