Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
A high-level overview of Secret smart contracts
Your start on privacy design for Secret smart contracts
Secret Network provides all the tools necessary to build fully private decentralized applications, but contracts do not automatically inherit perfect privacy. Privacy has a cost. Developers have both the freedom and the burden of choosing a privacy model that fits their applications' needs.
Protecting sensitive user data is not even the whole story when it comes to Secret dApps. Achieving a proper level of privacy can be mission critical in certain areas, such as competitive gaming, where an information leak could lead to a compromised system, say, if an attacker were able to cheat.
As a developer, it is your responsibility to understand the gamut of privacy risks, their implications, and how to best mitigate them.
Let's start off with a thought experiment. In an ideal world, a perfectly private application would be one that an attacker could not plausibly deduce any information about regarding its state, history, or participants. To an observer, any time a participant reads from or writes to the contract, it would be indistinguishable from every other action.
All outputs would appear to be random and unpredictable, with no discernible patterns that could be used to infer the underlying operations or data. On top of all that, the timing and frequency of executions would need to be consistent across the lifespan of the application.
Most of the items below are covered in greater detail here: Potential Attacks.
In reality, there are many forms of contextual data that an attacker can use to infer information, de-anonymize users, or compromise the privacy of applications purely through analysis:
transaction sender's address, their public transaction history, the timing and frequency of their transactions, and their relation to other accounts on the network
public inputs and outputs of an execution, such as sent or received funds (e.g., wrapping/unwrapping SCRT or IBC tokens)
timing of an execution, its temporal locality to other transactions (e.g., clustering, dispersion, co-ocurrence), and an execution's order relative to other on-chain events
size of the encrypted inputs and outputs of executions, shape and size of the event log, and public transaction metadata including gas_used
and nested calls to other contracts
timing, frequency, shape and size of query requests and query responses
storage access patterns when a contract reads from and writes to the encrypted application database
Additionally, there are active attacks that can expose unwanted leaks of information:
executions that produce measurable side-effects
tx replay attacks, side-chain attacks, the Millionaire's Problem
targeted storage access pattern attacks
Its important to note that a few of the risks listed above can only be mitigated by user OPSEC. For example, the timing and frequency of executions, tx sender address, and relations to other accounts are risks typically assumed by end-users. In these cases, education is the best instrument to protect users' privacy.
Some of the other risks should be mitigated by client-side software, such as wallets and dApp front-ends. This includes padding inputs to executions and queries, being strategic about the timing and distribution of query requests, and creating workflows that allow users to more easily create identities that are not linked to their public account.
The remaining privacy risks are those which can only be mitigated through contract design. Developers should strive to make all queries and executions appear indistinguishable from one another to an outside observer. This includes:
padding query and execution results (see pad_query_result
and pad_handle_result
from the Secret Toolkit)
using Gas Evaporation to make all methods consume a consistent amount of gas
adding decoy attributes to the event log when necessary
understanding storage access pattern attacks and employing a system of decoys or oblivious data models (or even UTXO)
Find code implementation of the above privacy preserving methods under our Privacy design section.
This page describes some of the core information required to get up to speed about the state of Secret Contracts in comparison to public (cosmos) networks.
Smart contracts on Secret Network follow the widely used CosmWasm framework. The framework is built as a module for the Cosmos SDK and allows developers to build smart contracts with Rust which compile to WebAssmebly (Wasm). This type of efficient and fast binary, combined with the power of a low-level typed coding language, makes CosmWasm a secure and efficient way for developers to write smart contracts. Contracts on Secret have a public binary just like any other smart contract network, only the contract input, output and state is encrypted.
Secret Contracts slightly differ from any standard CosmWasm implementation as they handle encrypted data, secure enclaves, and the key design around that. Secret currently emulates CosmWasm v1.1.9 and is completely compatible over IBC with other V1.0+ Cosmos Smart contract networks. To learn more about IBC compatible contracts you can read this section.
Private data (contract input, output and state) on Secret is encrypted using an unforgeable contract encryption key which is unique for every contract. Moreover, the user dedicated state in a contract is only visible to the user themselves. Because of this design, contract migration is a privacy risk. If enabled, a contract admin could upload a malicious contract that reads and prints data entrusted to the old contract. CosmWasm native contract migration is therefore disabled on Secret; workarounds are available here. Additionally, iterators and raw queries are not supported as one can not iterate over data stored by a different user as there is no access to their dedicated encryption key.
More information about the differences in implementations for a contract between Vanilla and Secret CosmWasm are listed here.
Secret contract encrypted input and access-controlled output is very powerful and enables many different usecases, combining this with novel development tools creates a powerful framework for developers to leverage. Below some of these tools and ideas are listed to get your brain going.
Privacy as a Service - More utility for other blockchains by leveraging Secret contracts cross-chain. Want to build on polygon, ethereum, Sei, Neutron or Aptos but want additional features only possible with data privacy? You can use Secret contracts cross-chain to keep your application decentralized and offer users new and interesting ways to explore your dApp.
Storage of private/encryption key (fragments) - One can use Secret contracts to store very sensitive info to enable cool usecases like access-controlled content or even cross-chain account ownership for DAOs and unstoppable threshold wallets.
on-chain randomness (secret-vrf) and hidden (game) state - Games on Secret benefit of true on-chain randomness that can remain hiddin inside the contract forever if so desired. Together with a hidden gamestate this brings a whole new dimension and fairness to turn-based games for Web3 like Poker or Mario party and more clarity and ownership to casino games and lootboxes.
Frontrunning resistant and privatized DeFi - because of an encrypted mempool secret is frontrunning resistant by default. Order size - unknown, Placed bids - unknown, liquidation points - unknown and many other features from orderbooks to dark pools have these privacy features as well.
Secret.js - a Javascript library for interacting with the Secret network, Secret contracts, providing encrypted input and creating viewing keys/permits for encrypted output. The library can also be considered as a more complete Cosm.js and can be used on every other cosmos chain. - Alternatives in Python, Kotlin, .Net and more exist as well.
Polar, Fadroma, Secret-toolkit (CW-plus) and Secret IDE - Secret has dedicated tooling sets built by external teams and core development that abstract boilerplate code (for DeFi), help with testing scenarios, simplify contract development nightmares like storage and type handling and even catch errors as you work in a dedicated IDE.
IBC, Interchain accounts/Queries/contracts, Axelar GMP, Bidshop messaging and more - Want to build your application crosschain? Secret has many options for both Message and Asset bridging protocols with the most renowned being IBC (current version IBC-go V4).
The privacy of Secret Network is reliant on secure enclaves, which impacts how the network performs but also how one should design their contracts to enhance privacy. Firstly, it is important to note that only data originating from inside the enclave is verifiable and any data coming from external resources has to be verified before relying on it for execution. This means data coming from contract callbacks is to be trusted, but the sender address is not. If I allow the sender to create an item on-chain, then only the sender should be able to remove that item. Verifying that it is indeed the sender (data owner) that is requesting this change is done by "input data verification". Explanation of the various network level integrated methods is available here.
In practice a Secret contract developer does not have to think too much about this as its abstracted away in the data verification process in the contract module of the network.
When designing contracts for Secret network, one should take into account the usage of so-called replay attacks and other theoretical attack vectors on secure enclave derived privacy. An example of this is the abundant usage of the Contract hash in Secret contract development. The usage of a contract hash is required to link the input to the specific contract being called. Otherwise one could make a forked chain and replace the contract with one that reads and prints the input parameters. Although encryption for Secret contracts is handled by the protocol, developers should still be mindful of their contract design to optimize for these privacy aspects.
One example of such a privacy optimized design would be the use of the Gas evaporation function as added in the v1.9 upgrade and documented here (link coming soon).
There are various types of outputs that can be expected, including:
An updated contract state (i.e., the user’s data should update the state or be stored for future computations)
A computation result encrypted for the transaction sender (i.e., a result should be returned privately to the sender)
Callbacks to other contracts (i.e., a contract is called conditional on the outcome of a Secret Contract function)
Send messages to other modules (i.e., for sending value transfer messages that depend on the outcome of a computation).
Reply - Send more detailed error logs of various submessages as explained here.
Want to dive deeper into the CosmWasm framework? - You can read more about it's design in the CosmWasm book.
Secret Contracts have private input, output and state. This means all data on-chain is stored as cyphertext and is only accessible by the owner (either the contract or the user). More details are available in the encryption specs.
The binary of any contract is public, meaning the execution logic is verifiable just like any other smart contract blockchain.
Secret smart contracts are IBC compatible (CosmWasm v1.0+), allowing for cross-chain logic with other IBC-connected chains.
from v1.11 Secret now supports migrate-able contracts just like vanilla CW, it does not support iterators due to contract privacy design. Workarounds are highlighted under storage.
When designing Secret contracts, the verification of input-data is key to ensure the secure execution of transactions as not all blockchain data is exposed automatically to the enclave.
Developers need to be mindful of data leakage via replay attacks, improper padding, and more so that the privacy for users of their contracts is optimized.
Secret network uses Tendermint as a consensus engine combined with the Cosmos SDK, as such it has a relatively high throughput and the possibility for easy horizontal scalability. Because of this, there is no fee market on Secret Network, which means there is no fee-based prioritization built into the standard tendermint binary required to run Secret. Using a higher transaction fee will only increase the number of block signers (validators) that are willing to process your transaction. This might speed up finality but does not prioritize your transaction in the cue.
The fee a user pays for a transaction is based on two things: the computational resources/block space that is used and the fee that validators ask for these resources. These two elements are called gas
and the gas fee
.
The gas
required for the computation is determined by the smart contract engine. The current gas estimates per type of contract interaction are listed here (for SDK components) and here (for enclave components). More complex transactions will consume more gas.
The gas fee
is determined by validators themselves as a parameter in their node service. The min_gas_fee
parameter allows validators to set a minimum fee denominated in uSCRT
. If a transaction has a lower allocated fee, they will not add it to blocks they propose. Validators propose blocks based on random selection following their Voting power. The min_gas_fee
for each block is dependent on the proposing validator. If blocks become too full or an attacker spams the network, the validators can increase their fee.
Secret validators run three tiers of fee's; this choice is up to the validator. Overall, we can assume more than 40% of validators support the "low" fee option, meaning pushing a TX with the low fee often gets processed within a few blocks. Pushing a TX with the "High" fee will increase the chance that the next block can fit your transaction. These TXs are therefore considered "faster". The current recommended fee options are listed in the Cosmos chain registry.
Now let's assume we execute a swap for a single Dex pool. We can expect this to take roughly 150000 Gas
. Executing this at the "low" fee option, we will pay 0.0125 uSCRT
for each Gas
unit used. The total fee for this transaction then becomes: 150000 * 0.0125 = 1.875 uSCRT = 1.875/1000000 = 0.001875 SCRT
. At 40% voting power supporting a min_gas_fee
of 0.0125 uSCRT
we can expect this transaction to be finalized after 4 blocks ( 4*6s = 24s
) with a 97.5% certainty [1- (40%**4) = 0,9744
].