Ownable API
This module provides the full Ownable module API.
For an overview of the module, read the Ownable guide.
Core
Ownable
import "./node-modules/@openzeppelin-compact/contracts/src/access/Ownable";
Ledger
_owner: Either<ZswapCoinPublicKey, ContractAddress>
ledger
#Either a ZswapCoinPublicKey
or ContractAddress
representing the owner.
Witnesses
None.
Circuits
initialize(initialOwner: Either<ZswapCoinPublicKey, ContractAddress>) → []
circuit
#Initializes the contract by setting the initialOwner
.
This must be called in the contract’s constructor.
Requirements:
- Contract is not already initialized.
initialOwner
is not a ContractAddress.initialOwner
is not the zero address.
owner() → Either<ZswapCoinPublicKey, ContractAddress>
circuit
#Returns the current contract owner.
Requirements:
- Contract is initialized.
transferOwnership(newOwner: Either<ZswapCoinPublicKey, ContractAddress>) → []
circuit
#Transfers ownership of the contract to newOwner
.
Ownership transfers to contract addresses are currently disallowed until contract-to-contract interactions are supported in Compact. This restriction prevents permanently disabling access to a circuit.
Requirements:
- Contract is initialized.
- The caller is the current contract owner.
newOwner
is not a ContractAddress.newOwner
is not the zero address.
_unsafeTransferOwnership(newOwner: Either<ZswapCoinPublicKey, ContractAddress>) → []
circuit
#Unsafe variant of transferOwnership
.
Ownership transfers to contract addresses are considered unsafe because contract-to-contract calls are not currently supported. Ownership privileges sent to a contract address may become uncallable. Once contract-to-contract calls are supported, this circuit may be deprecated.
Requirements:
- Contract is initialized.
- The caller is the current contract owner.
newOwner
is not the zero address.
renounceOwnership() → []
circuit
#Leaves the contract without an owner.
It will not be possible to call assertOnlyOwner
circuits anymore.
Can only be called by the current owner.
Requirements:
- Contract is initialized.
- The caller is the current contract owner.
assertOnlyOwner() → []
circuit
#Throws if called by any account other than the owner. Use this to restrict access of specific circuits to the owner.
Requirements:
- Contract is initialized.
- The caller is the current contract owner.
_transferOwnership(newOwner: Either<ZswapCoinPublicKey, ContractAddress>) → []
circuit
#Transfers ownership of the contract to a newOwner
without enforcing permission checks on the caller.
Ownership transfers to contract addresses are currently disallowed until contract-to-contract interactions are supported in Compact. This restriction prevents permanently disabling access to a circuit.
Requirements:
- Contract is initialized.
newOwner
is not a ContractAddress.
_unsafeUncheckedTransferOwnership(newOwner: Either<ZswapCoinPublicKey, ContractAddress>) → []
circuit
#Unsafe variant of _transferOwnership
.
Ownership transfers to contract addresses are considered unsafe because contract-to-contract calls are not currently supported. Ownership privileges sent to a contract address may become uncallable. Once contract-to-contract calls are supported, this circuit may be deprecated.
Requirements:
- Contract is initialized.
ZOwnablePK
import "./node-modules/@openzeppelin-compact/contracts/src/access/ZOwnablePK";
Ledger
_ownerCommitment: Bytes<32>
ledger
#Stores the current hashed commitment representing the owner.
This commitment is derived from the public identifier (e.g., SHA256(pk, nonce)
),
the instanceSalt
, the transfer counter
, and a domain separator.
A commitment of default<Bytes<32>>
(i.e. zero) indicates the contract is unowned.
_counter: Counter
ledger
#Internal transfer counter used to prevent commitment reuse.
Increments by 1 on every successful ownership transfer.
Combined with id
and instanceSalt
to compute unique owner commitments over time.
_instanceSalt: Bytes<32>
sealed ledger
#A per-instance value provided at initialization used to namespace commitments for this contract instance.
This salt prevents commitment collisions across contracts that might otherwise use the same owner identifiers or domain parameters. It is immutable after initialization.
Witnesses
wit_secretNonce(): Bytes<32>
witness
#A private per-user nonce used in deriving the shielded owner identifier.
Combined with the user's public key as SHA256(pk, nonce)
to produce an obfuscated, unlinkable identity commitment.
Users are encouraged to rotate this value on ownership changes.
Circuits
initialize(ownerId: Bytes<32>, instanceSalt: Bytes<32>): []
circuit
#Initializes the contract by setting the initial owner via ownerId
and storing the instanceSalt
that acts as a privacy additive
for preventing duplicate commitments among other contracts implementing ZOwnablePK.
The ownerId
must be calculated prior to contract deployment using the SHA256 hashing algorithm.
Using any other algorithm will result in a permanent loss of contract access.
See _computeOwnerId.
owner(): Bytes<32>
circuit
#Returns the current commitment representing the contract owner.
The full commitment is: SHA256(SHA256(pk, nonce), instanceSalt, counter, domain)
.
transferOwnership(newOwnerId: Bytes<32>): []
circuit
#Transfers ownership to newOwnerId
.
newOwnerId
must be precalculated and given to the current owner off chain.
The caller must be the current owner and newOwnerId
must not be empty.
renounceOwnership(): []
circuit
#Leaves the contract without an owner.
It will not be possible to call assertOnlyOwner
circuits anymore.
Can only be called by the current owner.
assertOnlyOwner(): []
circuit
#Throws if called by any account whose id hash SHA256(pk, nonce)
does not match
the stored owner commitment.
Use this to only allow the owner to call specific circuits.
_computeOwnerCommitment(id: Bytes<32>, counter: Uint<64>): Bytes<32>
circuit
#Computes the owner commitment from the given id
and counter
.
The commitment derivation follows:
commitment = SHA256(id, instanceSalt, counter, "ZOwnablePK:shield:")
Where:
id
: The unique identifierSHA256(pk, nonce)
.instanceSalt
: Per-deployment salt to prevent collisions.counter
: Incremented with each transfer for uniqueness.- Domain separator:
"ZOwnablePK:shield:"
padded to 32 bytes.
_computeOwnerId(pk: Either<ZswapCoinPublicKey, ContractAddress>, nonce: Bytes<32>): Bytes<32>
circuit
#Computes the unique identifier (id
) of the owner from their public key and a secret nonce.
The ID derivation follows: id = SHA256(pk, nonce)
Currently only supports ZswapCoinPublicKey
. Contract address owners are not yet supported.
We recommend using an Air-Gapped Public Key for strongest security guarantees.
_transferOwnership(newOwnerId: Bytes<32>): []
circuit
#Transfers ownership to owner id newOwnerId
without enforcing permission checks on the caller.
This is an internal function that increments the counter and updates the owner commitment.