A confidential contract can be interacted with through an interface very
similar to the one already exposed through Web3. Instead of the
web3.eth.contract
API, one uses
web3.confidential.contract
. Confidential contracts are
instantiated in the same way as a standard contract - by providing the
ABI defining the methods and properties which can be called. An
instance of a contract is made in a slightly different way, and this is
the only way in which the API diverges from non-confidential contracts.
Instead of calling at(deployed_address)
, to instantiate an
interface to a contract deployed at an address on the chain, one intead
calls at(deployed_address, public_key)
. The additional
parameter specifies the long-term public key of the confidential contract,
providing a root of trust allowing the client to securely negotiate a
confidential channel for requests to the remote contract.
A new confidential contract is deployed in much the same way as a
normal contract deployment: A transaction containing the contract
code is sent with no to destination specified. Confidential
contracts are distinguished from normal contracts by a prefix in the
data parameter of the transaction. This is the same mechanism that
would distinguish a wasm contract from an EVM contract. In the case
of confidential contracts, the prefix is \0enc
The
initial 0 byte, as in wasm contracts, is a stop instruction to the
evm interpreter for backwards compatibility.
In the standard mental model of interaction with a smart contract, the contract is identified by the address it is deployed on chain. A client can validate that it is interacting with the expected contract by checking what's deployed at that location, and making sure the code of the contract meets expectations.
In confidential contracts, an additional step is needed - the client must determine the public key with which to encrypt messages to the contract. This key is dynamic - it may change over time - meaning that a request for the current public key, and associated validation, is nessicary at the beginning of each session.
The current encryption key for a confidential contract can be
retrieved by calling confidential_getPublicKey
for the contract
address.
To make a confidential call, the public key above is used to encrypt the data field of a standard call. This field contains a reference to which method of the contract should be called, along with the arguments.
The low-level confidential_call_enc
and
confidential_sendRawTransaction_enc
should be
provided with this encrypted state. It is up to the client to have
encrypted the call, and gotten a local wallet to sign the resulting
serialized data.