Web3.Confidentiality

Interaction with confidential contracts

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.

confidential.contract




Creating Confidential Contracts

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.



Under the hood

Establishing a secure channel

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.

confidential_getPublicKey


An encrypted call

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.

confidential_call_enc