COTI V2 Documentation
  • Welcome
  • Networks
    • Faucet
    • Contracts Addresses
    • Adding the COTI Network to Metamask
  • How COTI Works
    • Introduction
      • EVM Introduction
      • Conceptual Overview
      • Use Cases and Applications
      • COTI Architecture
    • Advanced Topics
      • Garbled Circuits
      • AES Keys
      • Precompiles
      • Whitepaper
      • COTI vs others
  • Build on COTI
    • Core Concepts
      • Account Onboarding Procedure
      • Private Data Types
      • Supported Operations on Private Data Types
    • Quickstart
    • Guides
      • Basic Private Smart Contract
      • Account Onboard
      • Sending a Transaction with Encrypted Inputs
      • Resolving a Transaction's Encrypted Outputs
      • Writing a Private Smart Contract
      • Dos and Don'ts
        • Proper Use of Types
        • No Constant/Immutable Secret Types
        • No Public Contract Variables
      • Best Practices
        • Careful Onboarding
        • Careful Decrypting
        • Don't loop over an array without an index
        • Check Overflow
    • Tools
      • TypeScript SDK
      • Ethers.js
      • Python SDK
      • Web3.py
      • Contracts Library
        • MPC Core
        • Data Privacy Framework
        • Tokens
          • Private ERC20
          • Private ERC721
        • Onboard
      • Hardhat
      • Remix Plugin
      • COTI MetaMask Snap
      • Developer Sandbox
  • Running a COTI Node
    • COTI Node Ecosystem Litepaper
  • COTI Bridge
    • Swap COTI V1 Funds to COTI V2
  • Support and Community
    • Glossary
    • Telegram
    • Discord
    • GitHub
    • X
    • YouTube
  • COTI Builders Program
Powered by GitBook
On this page

Was this helpful?

Edit on GitHub
  1. Build on COTI
  2. Guides
  3. Best Practices

Careful Decrypting

The creator of a contract must understand the implications of decryption in various scenarios. For instance, decryption should never occur within a view function without considering alternative security measures, as relying solely on msg.sender can be unreliable due to the potential for forging.

As a general precaution, handling a call to decrypt should be approached with caution, considering the various options for invoking such a function. For example, a secret intended for a specific user should not be decrypted in a manner that exposes it to everyone.

Don't: Do not reveal data intended for a specific user to everybody

contract BadContract {
  //...
  function balanceOf() public returns (uint64 balance){
    ctUint64 balance = balances[msg.sender];
   
    gtUint64 balanceGt = MpcCore.onBoard(balance);
    
    // SHOULD NEVER BE CALLED
    // A SIMPLE CALL TO GETBALANCE REVEALS THE BALANCE TO EVERYBODY
    return MpcCore.decrypt(balanceGt);
  }
  //...
}

Do : Offboard to a specific user.

contract GoodContract {
   //...
  function balanceOf() public returns (ctUint64 balance){
    ctUint64 balance = balances[msg.sender];
    // The balance is saved encrypted using the system key. However, to allow 
    // the user to access it, the balance needs to be re-encrypted using the user key. 
    // Therefore, we decrypt the balance (onBoard) and then encrypt it again using 
    // the user key (offBoardToUser).
    gtUint64 balanceGt = MpcCore.onBoard(balance);
    return MpcCore.offBoardToUser(balanceGt, msg.sender);
  }
  //...
}
PreviousCareful OnboardingNextDon't loop over an array without an index

Last updated 6 months ago

Was this helpful?