Confidential Smart Contracts
Oasis supports contracts with secret state, called confidential smart contracts.
This document describes how confidential smart contracts work, how they differ from standard (non-confidential) contracts, and how to develop with confidential smart contracts on the Oasis Devnet.
We highly recommend you read this document before using confidential smart contracts.
Confidential smart contracts are currently intended for development purposes. The Oasis Devnet is designed to allow developers to begin building applications using our confidentiality APIs. Although most of the functionality for confidentiality is already supported, our Devnet is still in beta and we don't recommend storing sensitive information at this time. We will keep you updated once this changes.
Introduction to Confidential Smart Contracts
In most blockchains, the data and state of a contract are publicly stored on-chain, limiting the types of decentralized applications that can be supported.
There are many examples of applications that benefit from confidentiality, for example:
- Private analytics and data sharing. Computation over sensitive datasets requires the underlying data remain secret, with only the computation results revealed publicly.
- Voting. Voting applications often require individual votes to remain private.
- Auctions. Second-price and blind auctions require that bids are kept secret until the auction ends.
- And many more...
With confidential contracts, applications do not need to use commit-reveal schemes and other complex workarounds that would otherwise be required to prevent information leakage on a public blockchain.
How Confidentiality Works
Confidential smart contracts differ from traditional smart contracts in two important ways:
- Confidential state. The data and state of confidential smart contracts is protected from the outside world by default, enabling the contract to dictate the rules of how data or results are shared to users.
- Confidential transactions. Users interact with confidential smart contracts through an end-to-end encrypted channel, ensuring that nobody else can see transaction details—not even the nodes on the network.
In this initial version on the Devnet, we protect the state of confidential contracts by running them inside a secure enclave. Future versions of confidential smart contracts will include support for zero-knowledge proofs (ZKP) and secure multi-party computation.
What Information Is Confidential?
When designing applications with confidentiality it is important to understand what information is secret (to whom) and what information is visible to other users and nodes on the network.
Smart Contract data
A confidential smart contract's state is secret and cannot be viewed by anyone (not even the smart contract's creator). If a confidential smart contract wishes to release information about its secret state, it has full control over how, when, and to whom the information is released.
The metadata associated with confidential smart contracts is public, including the smart contract bytecode, the contract's address, and the balance of the contract.
As with standard Ethereum smart contracts, a confidential smart contract can define methods that can be called by users via transactions sent to the contract. These methods can return data, which is included in the transaction result.
Confidentiality is different from access control. Since anyone can call methods on a confidential contract, it is up to the contract logic to limit disclosure to authorized callers. See the releasing confidential state section for best practices and code patterns for selective information disclosure.
The content of transactions—including the
data field of requests and the
confidential_call_enc responses—is private between the user issuing the transaction and the smart contract.
Consequently, any information encoded in the transaction (the method name, arguments, and return data) cannot
be viewed externally by anyone on the network, not even by the web3 provider that receives and dispatches the
The metadata associated with transactions including
from addresses and the
value (i.e. DEV
tokens included in the transaction) is public.
In other words, when making calls and sending transactions to a confidential smart contract, anyone on the network can see the fact that you are interacting with the contract, but nobody can tell what you are doing.
Smart contracts can emit events (logs) in response to transactions, and these events are stored in the blockchain.
In Ethereum, events are part of the public ledger and can be retrieved by anyone on the network.
With confidential smart contracts, events are only visible to the user who caused the event to be generated.
data field of event logs is encrypted such that it can only be decrypted by the client who sent the
transaction that produced the log.
Other users can be notified that an event has been emitted, and can filter by the name and topics of the event, but will not be able to see its contents. If other clients need to update or track local state based on events, they will instead need to make their own confidential call in response to an event in order to read that state within their own confidential session with the contract.
How are Keys Managed?
When an end user interacts with a confidential smart contract, their communication is encrypted using a key known only to the user's application and the instance of the contract they are interacting with. This means nobody else, not even the web3 provider, can inspect transactions between a user and a confidential smart contract.
Our confidentiality model operates on the principle of least privilege. As such, the client interacting with a confidential
contract manages a keypair for the confidential channel, and it is up to the application to decide on the
lifetime and policy around this keypair. Our web3c.js library (described below) transparently generates a
key and establishes a secure channel before sending transactions, so application developers need not worry about underlying
details unless they wish to customize the behavior, lifetime, or handling of the key pair for a secure channel. If used in the browser, web3c.js stores the generated key pairs in a browser's localStorage and has no specified expiration. Similarly, when used as part of a node application, web3c.js stores the key pairs using node-localstorage into the
./.web3c directory the application is invoked.
Note that the keypair is not associated with the user's wallet, and data from an application is encrypted before it is sent to the wallet to minimize exposure of confidential state outside of the application. The user keys are unique for each application and each browser/node session (which do not expire as explained in the previous paragraph). Thus if a key is exposed, it only affects events and return values generated for that user's session for that specific application.