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

Resolving a Transaction's Encrypted Outputs

PreviousSending a Transaction with Encrypted InputsNextWriting a Private Smart Contract

Last updated 5 months ago

Was this helpful?

This guide assumes you have already deployed the Counter.sol contract. If you haven't already, check out our guide for deploying a .

After calling add, we can use our AES encryption key to decrypt the value of sum and check the result.

Setup

npm install @coti-io/coti-ethers

Code

import { Contract, CotiNetwork, getDefaultProvider, Wallet } from "@coti-io/coti-ethers"

const PRIVATE_KEY = "<EOA_PRIVATE_KEY>"
const AES_KEY = "<AES_KEY>"
const COUNTER_ADDRESS = "<COUNTER_ADDRESS>"
const COUNTER_ABI = [
    {
        "inputs": [],
        "stateMutability": "nonpayable",
        "type": "constructor"
    },
    {
        "inputs": [
            {
                "components": [
                    {
                        "internalType": "ctUint64",
                        "name": "ciphertext",
                        "type": "uint256"
                    },
                    {
                        "internalType": "bytes",
                        "name": "signature",
                        "type": "bytes"
                    }
                ],
                "internalType": "struct itUint64",
                "name": "value",
                "type": "tuple"
            }
        ],
        "name": "add",
        "outputs": [],
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "inputs": [],
        "name": "sum",
        "outputs": [
            {
                "internalType": "ctUint64",
                "name": "",
                "type": "uint256"
            }
        ],
        "stateMutability": "view",
        "type": "function"
    }
]

const provider = getDefaultProvider(CotiNetwork.Testnet)
const wallet = new Wallet(PRIVATE_KEY, provider)
wallet.setAesKey(AES_KEY)

const counter = new Contract(COUNTER_ADDRESS, COUNTER_ABI, wallet)

const ctSum = await counter.sum()

const clearSum = await wallet.decryptValue(ctSum)

console.log(clearSum)

Setup

npm install @coti-io/coti-ethers

Code

import { Contract, CotiNetwork, getDefaultProvider, Wallet } from "@coti-io/coti-ethers"

const PRIVATE_KEY = "<EOA_PRIVATE_KEY>"
const AES_KEY = "<AES_KEY>"
const COUNTER_ADDRESS = "<COUNTER_ADDRESS>"
const COUNTER_ABI = [
    {
        "inputs": [],
        "stateMutability": "nonpayable",
        "type": "constructor"
    },
    {
        "inputs": [
            {
                "components": [
                    {
                        "internalType": "ctUint64",
                        "name": "ciphertext",
                        "type": "uint256"
                    },
                    {
                        "internalType": "bytes",
                        "name": "signature",
                        "type": "bytes"
                    }
                ],
                "internalType": "struct itUint64",
                "name": "value",
                "type": "tuple"
            }
        ],
        "name": "add",
        "outputs": [],
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "inputs": [],
        "name": "sum",
        "outputs": [
            {
                "internalType": "ctUint64",
                "name": "",
                "type": "uint256"
            }
        ],
        "stateMutability": "view",
        "type": "function"
    }
]

const provider = new BrowserProvider(window.ethereum as Eip1193Provider)
const signer = await provider.getSigner()
signer.setAesKey(AES_KEY)

const counter = new Contract(COUNTER_ADDRESS, COUNTER_ABI, signer)

const ctSum = await counter.sum()

const clearSum = await signer.decryptValue(ctSum)

console.log(clearSum)

Setup

pip install coti-web3

Code

from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from web3.utils.coti import (
  CotiNetwork,
  init_web3
)

PRIVATE_KEY = "<EOA_PRIVATE_KEY>"
AES_KEY = "<AES_KEY>"
COUNTER_ADDRESS = "<COUNTER_ADDRESS>"
COUNTER_ABI = [
    {
        "inputs": [],
        "stateMutability": "nonpayable",
        "type": "constructor"
    },
    {
        "inputs": [
            {
                "components": [
                    {
                        "internalType": "ctUint64",
                        "name": "ciphertext",
                        "type": "uint256"
                    },
                    {
                        "internalType": "bytes",
                        "name": "signature",
                        "type": "bytes"
                    }
                ],
                "internalType": "struct itUint64",
                "name": "value",
                "type": "tuple"
            }
        ],
        "name": "add",
        "outputs": [],
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "inputs": [],
        "name": "sum",
        "outputs": [
            {
                "internalType": "ctUint64",
                "name": "",
                "type": "uint256"
            }
        ],
        "stateMutability": "view",
        "type": "function"
    }
]

account: LocalAccount = Account.from_key(PRIVATE_KEY, { 'aes_key': AES_KEY })
w3: Web3 = init_web3(CotiNetwork.TESTNET)

counter_contract = w3.eth.contract(address=COUNTER_ADDRESS, abi=COUNTER_ABI)

ct_sum = counter_contract.functions.sum().call({'from': account.address})

clear_sum = account.decrypt_value(ct_sum)

print(clear_sum)
Basic Private Smart Contract