All repositories specified below contain smart contracts that implement confidentiality features using the COTI V2 protocol. The contracts provide examples for various use cases, such as Non-Fungible Tokens (NFTs), ERC20 tokens, Auction, and Identity management.
These contracts demonstrate how to leverage the confidentiality features of the COTI V2 protocol to enhance privacy and security in decentralized applications. The contracts are written in Solidity and can be compiled and deployed using popular development tools like Hardhat and Foundry.
Docs | Devnet Explorer | Discord | Faucet
Interact with the network using any of the following:
The following contracts are available in each of the packages:
Contract | python sdk | hardhat sdk | typescript sdk | Contract Description | |
---|---|---|---|---|---|
AccountOnboard |
deployment | ✅ * | ✅ | ❌ | Onboard a EOA account - During onboard network creates AES unique for that EOA which is used for decrypting values sent back from the network |
AccountOnboard |
execution | âś… | âś… | âś… | " |
ERC20Example |
deployment | ✅ | ✅ | ❌ | Confidential ERC20 - deploy and transfer encrypted amount of funds |
ERC20Example |
execution | âś… | âś… | âś… | " |
NFTExample |
deployment | ❌ | ✅ | ❌ | Confidential NFT example - saving encrypted data |
NFTExample |
execution | ❌ | ✅ | ❌ | " |
ConfidentialAuction |
deployment | ❌ | ✅ | ❌ | Confidential auction - encrypted bid amount |
ConfidentialAuction |
execution | ❌ | ✅ | ❌ | " |
ConfidentialIdentityRegistry |
deployment | ❌ | ✅ | ❌ | Confidential Identity Registry - Encrypted identity data |
ConfidentialIdentityRegistry |
execution | ❌ | ✅ | ❌ | " |
DataOnChain |
deployment | ✅ | ❌ | ❌ | Basic encryption and decryption - Good place to start explorining network capabilties |
DataOnChain |
execution | ✅ | ❌ | ✅ | " |
Precompile |
deployment | ✅ | ✅ | ❌ | Thorough examples of the precompile functionality |
Precompile |
execution | ✅ | ✅ | ❌ | " |
(*) no deployment needed (system contract)
Note
Due to the nature of ongoing development, future versions might break existing functionality
🤖 To request devnet/testnet funds use our faucet ([join discord] (https://discord.gg/cuCykh8P4m)))
Note
Please refer to the latest tags to find the most stable version to use. All tagged versions are available to install via pypi
The COTI Python SDK can be installed as pypi package named coti_sdk
, its modules are:
crypto_utils
: used for cryptographic operationsutils
: used for web3 related operations
The Python script examples project contain scripts covering various use cases, such as Non-Fungible Tokens (NFTs), ERC20 tokens, Auctions, and Identity management. It contains smart contracts that implement confidentiality features using the COTI V2 protocol. These contracts demonstrate how to leverage the confidentiality features of the COTI V2 protocol to implement privacy and enhance security in decentralized applications.
The COTI faucet provides devnet/testnet funds for developers. To request devnet/testnet tokens:
- Head to https://faucet.coti.io/
- Send a message to the bot in the following format:
devnet <your_eoa_address>
For Example:
devnet 0x71C7656EC7ab88b098defB751B7401B5f6d8976F
There are two libraries located in the libs folder that will allow you to interact with the COTI network.
Purpose: Encrypts a plaintext message using AES encryption with a provided key.
Usage:
ciphertext, r = encrypt(key, plaintext)
Parameters:
key
: A 128-bit (16-byte) AES key.plaintext
: The plaintext message to be encrypted. Must be 128 bits (16 bytes) or smaller.
Returns:
ciphertext
: The encrypted message.r
: The random value used during encryption.
Purpose: Decrypts a ciphertext message using AES decryption with a provided key and random value.
Usage:
plaintext = decrypt(key, r, ciphertext)
Parameters:
key
: A 128-bit (16-byte) AES key.r
: The random value used during encryption.ciphertext
: The encrypted message to be decrypted.
Returns:
plaintext
: The decrypted message.
Purpose: Generates a random 128-bit AES key.
Usage:
key = generate_aes_key()
Returns:
key
: The generated 128-bit AES key.
Purpose: Generates a new ECDSA private key.
Usage:
private_key = generate_ECDSA_private_key()
Returns:
private_key
: The raw bytes of the ECDSA private key.
Purpose: Signs a message composed of various inputs using a private key.
Usage:
signature = signIT(sender, addr, func_sig, ct, key)
Parameters:
sender
: The sender's address.addr
: The contract address.func_sig
: The function signature.ct
: The ciphertext.key
: The private key used for signing.
Returns:
signature
: The generated signature.
Purpose: Signs a message using a private key.
Usage:
signature = sign(message, key)
Parameters:
message
: The message to be signed.key
: The private key used for signing.
Returns:
signature
: The generated signature.
Purpose: Builds input text by encrypting the plaintext and signing it.
Usage:
int_cipher_text, signature = build_input_text(plaintext, user_aes_key, sender, contract, func_sig, signing_key)
Parameters:
plaintext
: The plaintext message.user_aes_key
: The user's AES key.sender
: The sender's address.contract
: The contract address.func_sig
: The function signature.signing_key
: The private key used for signing.
Returns:
int_cipher_text
: The integer representation of the ciphertext.signature
: The generated signature.
Purpose: Generates an RSA key pair.
Usage:
private_key_bytes, public_key_bytes = generate_rsa_keypair()
Returns:
private_key_bytes
: The serialized private key.public_key_bytes
: The serialized public key.
Purpose: Encrypts plaintext using RSA encryption with a provided public key.
Usage:
ciphertext = encrypt_rsa(public_key_bytes, plaintext)
Parameters:
public_key_bytes
: The serialized public key.plaintext
: The plaintext message to be encrypted.
Returns:
ciphertext
: The encrypted message.
Purpose: Decrypts ciphertext using RSA decryption with a provided private key.
Usage:
plaintext = decrypt_rsa(private_key_bytes, ciphertext)
Parameters:
private_key_bytes
: The serialized private key.ciphertext
: The encrypted message to be decrypted.
Returns:
plaintext
: The decrypted message.
Purpose: Computes the Keccak-256 hash of the provided data.
Usage:
hash_value = keccak256(data)
Parameters:
data
: The data to be hashed.
Returns:
hash_value
: The computed hash.
Purpose: Computes the function signature hash using Keccak-256.
Usage:
func_sig_hash = get_func_sig(function_signature)
Parameters:
function_signature
: The function signature string.
Returns:
func_sig_hash
: The first 4 bytes of the computed hash.
Purpose: Decrypts a value stored in a contract using a user key
Usage:
plaintext = decrypt_uint(ciphertext, user_key)
Parameters:
ciphertext
: The value to be decrypted.userKey
: The user's AES key.
Returns:
result
: The decrypted value.
Purpose: Decrypts a value stored in a contract using a user key
Usage:
plaintext = decrypt_string(ciphertext, user_key)
Parameters:
ciphertext
: The value to be decrypted.userKey
: The user's AES key.
Returns:
result
: The decrypted value.
Purpose: Checks if the Web3 instance is connected.
Usage:
connected = web3_connected(web3)
Parameters:
web3
: An instance of Web3.
Returns:
connected
: Boolean indicating if Web3 is connected.
Purpose: Prints the network details of the Web3 instance.
Usage:
print_network_details(web3)
Parameters:
web3
: An instance of Web3.
Purpose: Prints the account details of the default account in the Web3 instance.
Usage:
print_account_details(web3)
Parameters:
web3
: An instance of Web3.
Purpose: Initializes the Web3 instance with the given node address and externally owned account (EOA).
Usage:
web3 = init_web3(node_https_address, eoa)
Parameters:
node_https_address
: The HTTPS address of the COTI node.eoa
: The externally owned account.error_not_connected
: Boolean indicating whether to raise an error if not connected.
Returns:
web3
: The initialized Web3 instance.
Purpose: Generates an externally owned account (EOA) from a private key.
Usage:
eoa = get_eoa(account_private_key)
Parameters:
account_private_key
: The private key of the account.
Returns:
eoa
: The generated EOA.
Purpose: Validates and returns the checksum address for a given address.
Usage:
result = validate_address(address)
Parameters:
address
: The address to be validated.
Returns:
result
: A dictionary withvalid
(boolean) andsafe
(checksum address).
Purpose: Retrieves the latest block from the COTI network.
Usage:
latest_block = get_latest_block(web3)
Parameters:
web3
: An instance of Web3.
Returns:
latest_block
: The latest block object.
Purpose: Retrieves the nonce for the default account.
Usage:
nonce = get_nonce(web3)
Parameters:
web3
: An instance of Web3.
Returns:
nonce
: The nonce for the default account.
Purpose: Validates an address and returns the checksum address.
Usage:
result = get_address_valid_and_checksum(address)
Parameters:
address
: The address to be validated.
Returns:
result
: A dictionary withvalid
(boolean) andsafe
(checksum address).
Purpose: Checks if an address is valid.
Usage:
valid = address_valid(address)
Parameters:
address
: The address to be validated.
Returns:
valid
: Boolean indicating if the address is valid.
Purpose: Retrieves the native balance of an address.
Usage:
balance = get_native_balance(web3, address)
Parameters:
web3
: An instance of Web3.address
: The address to check the balance of (default is the default account).
Returns:
balance
: The native balance in wei.
Purpose: Loads a Solidity contract source code from a file.
Usage:
contract_code = load_contract(file_path)
Parameters:
file_path
: Path to the Solidity source code file.
Returns:
contract_code
: The content of the file.
13. transfer_native(web3, recipient_address, private_key, amount_to_transfer_ether, native_gas_units)
Purpose: Transfers native cryptocurrency from the default account to a recipient address.
Usage:
tx_receipt = transfer_native(web3, recipient_address, private_key, amount_to_transfer_ether, native_gas_units)
Parameters:
web3
: An instance of Web3.recipient_address
: The address of the recipient.private_key
: The private key of the sender.amount_to_transfer_ether
: The amount of Ether to transfer.native_gas_units
: The gas limit for the transaction.
Returns:
tx_receipt
: The transaction receipt.
Purpose: Validates the gas estimation for a transaction.
Usage:
validate_gas_estimation(web3, tx)
Parameters:
web3
: An instance of Web3.tx
: The transaction object.
Purpose: Checks if the provided gas units are sufficient for the transaction.
Usage:
valid, gas_estimate = is_gas_units_estimation_valid(web3, tx)
Parameters:
web3
: An instance of Web3.tx
: The transaction object.
Returns:
valid
: Boolean indicating if the gas units are sufficient.gas_estimate
: The estimated gas units.
Purpose: Generates the function signature from the ABI.
Usage:
func_sig = get_function_signature(function_abi)
Parameters:
function_abi
: The ABI of the function.
Returns:
func_sig
: The function signature.
Purpose: Deploys a contract with the given parameters.
Usage:
tx_receipt = deploy_contract(contract, kwargs, tx_params)
Parameters:
contract
: The contract object.kwargs
: Keyword arguments for the contract constructor.tx_params
: Transaction parameters.
Returns:
tx_receipt
: The transaction receipt.
Purpose: Executes a contract function via a transaction.
Usage:
tx_receipt = exec_func_via_transaction(func, tx_params)
Parameters:
func
: The contract function to be executed.tx_params
: Transaction parameters.
Returns:
tx_receipt
: The transaction receipt.
Purpose: Signs and sends a transaction.
Usage:
tx_receipt = sign_and_send_tx(web3, private_key, transaction)
Parameters:
web3
: An instance of Web3.private_key
: The private key of the sender.transaction
: The transaction object.
Returns:
tx_receipt
: The transaction receipt.
Purpose: Decrypts a value stored in a contract using a user key.
Usage:
decrypted_balance = decrypt_value(contract_value, user_key)
Parameters:
contract_value
: The value to be decrypted.user_key
: The user's AES key.
Returns:
decrypted_balance
: The decrypted value.