# A Brief Introduction to Confidential Contract Provided by Eigen Network

By [ieigen](https://paragraph.com/@ieigen) · 2021-11-19

---

The Necessary of Confidential Contract
======================================

For the Ethereum public main chain, its most proud or important feature is that all transactions are open and transparent, which means that anyone who joins in this network can obtain the whole transaction history. They can analyze them freely.

However, a coin has two sides. The absolutely privacy still has its vitality. In the DeFi application, due to its transparency, the perpetrator can make some inferences from the transaction and “attacks” with these transaction histories. These transparency may be used to make the perpetrators profitable and cause losses to investors.

Eigen Network Confidential Contracts Framework — — EigenCC
==========================================================

Based on a series theoretical foundation and practical experience, The Eigen Network provides several technical infrastructure to support confidential contracts in a public blockchain network, with the L2 solution of Arbitrum.

The framework EigenCC provides an easy way to add new instructions in the trusted execution environment (TEE). We focus on 3 important parts to leverage the confidential trusted computing environment:

*   Confidential operators: what operators inside TEE can be provided and how it get done;
    
*   Secure transportation: how the privacy information is sent or received from the Eigen Network without privacy breach;
    
*   On-chain data protection: how we store the privacy information on the chain.
    

The TEE is often hardware based. It ensures that even the node operator does **NOT** have any access to private data, including immediate computation results. This feature ensures the security of private data. EigenCC provides a decentralized mechanism for TEE nodes. Due to the compatibility of Arbitrum with Ethereum, the Ethereum digital assets (e.g., ERC-20 tokens) can move between Ethereum and our own token, which means that anyone can develop smart contracts with a minor modification.

Confidential Operators
======================

Some fundamental confidential operators should be provided to simplify the development and abstract some common calculations. Thus we provide a series of confidential operators. For now, we’ve implemented:

*   Three arithmetic operators: addition, subtraction and multiplication on 256bits integer
    
*   Comparison operators: greater than, less than and equal
    
*   Debug operators: encryption and decryption
    

These operators are done inside TEE, which makes it confidential. The latest implementation and documents could be found in our Github.

Secure Transportation
=====================

Referring to the security mechanism of TLS, we adopt the RA-TLS schema for a secure channel between end-user and EigenCC. The general workflow is like below:

![](https://storage.googleapis.com/papyrus_images/d95829f36e0d51fcdf4fb95011b82451df69f88f129f5c6c3e0bd1f9ee189640.png)

The main update is that we put the Enclave Quote embedded in the X509 certificate, and the challenger verifies the quote after the general certificate verification.

In our implementation, we provide a socket-based channel between EGVM(AVM) and EigenCC.

Hence, all above encrypted items are encrypted by an ECC public key with ECIES. When EigenCC launches, it will generate an ECC key pair, and the public key will be registered to PKCS.

On-chain Data Protection
========================

This is a tough issue. Since the on-chain data is openly accessed by anyone, if a vulnerable logic or weak key was used, it leads to all the privacy inside the corresponding contract being exposed to everyone. Hence, how to encrypt the on-chain data becomes crucial.

It recommends taking the secret key into custody by the owner itself, and using re\_encrypt to encrypt the privacy information, and upgrade the key periodically.

Use Cases
=========

Some use cases are provided to show how to use the EigenCC framework.

EigenCall Library
=================

To make it easy to use and save gases, we implement a link library named EigenCallLibrary [here](https://github.com/ieigen/ieigen/blob/main/l2/eigen-tutorials/packages/confidential-contracts/contracts/tokenbridge/libraries/EigenCallLibrary.sol). It can be deployed on L2 and anyone can call them if deployed with the address.

EigenCallLibrary is implemented based on [EGIP 00001](https://github.com/ieigen/ieigen/blob/main/docs/egip/00001.md), for now, we have implemented these public functions in [here](https://github.com/ieigen/ieigen/blob/main/l2/eigen-tutorials/packages/confidential-contracts/contracts/tokenbridge/libraries/EigenCallLibrary.sol).

These functions hide the details of implementations of eigenCall, so the user does not care about how to compose an eigenCall input bytes, or how to decode the returning RLP encoded value. An assert is put into each wrapper function to ensure eigenCall is called successfully. If any error occurs, the contract call will cause a transaction revert with a message.

To use EigenCallLibrary in a contract, just import it with the right path, and regard it as a typical link library. For example, in [TestCCCustomToken.sol](https://github.com/ieigen/ieigen/blob/main/l2/eigen-tutorials/packages/confidential-contracts/contracts/tokenbridge/test/TestCCCustomToken.sol), demo\_addCipherCipher function calls EigenCallLibrary.addCipherCipher:

function demo\_addCipherCipher(bytes memory cipher1, bytes memory cipher2)

public

pure

returns (bytes memory)

{

bytes memory output = EigenCallLibrary.addCipherCipher(cipher1, cipher2);

return output;

}

The output is ensured a valid cipher result of addCipherCipher operator. So the user can use the result without caring about the correctness of the result.

Other demo\_\* functions can be found in _TestCCCustomToken.sol_.

If we want to call the contract function in Javascript or Typescript, we should tell the link library address in the contract we want to use EigenCallLibrary.

For example, we can see the snippet in [exec.js](https://github.com/ieigen/ieigen/blob/main/l2/eigen-tutorials/packages/demo-eigencall/scripts/exec.js):

// …

var L2EigenCallLibrary = await (

await ethers.getContractFactory(“EigenCallLibrary”)

).connect(l2Wallet);

L2EigenCallLibrary = await L2EigenCallLibrary.deploy();

await L2EigenCallLibrary.deployed();

console.log(

“EigenCallLibrary is deployed at address:”,

L2EigenCallLibrary.address

);

​

var L2EigenCallLibraryUseDemo = await (

await ethers.getContractFactory(“EigenCallLibraryUseDemo”, {

libraries: {

EigenCallLibrary: L2EigenCallLibrary.address,

},

})

).connect(l2Wallet);​

console.log(“Deploying EigenCallLibraryUseDemo contract to L2”);

L2EigenCallLibraryUseDemo = await L2EigenCallLibraryUseDemo.deploy({

gasLimit: 25000000,

});

await L2EigenCallLibraryUseDemo.deployed();

console.log(

\`EigencallDemo contract is deployed to ${L2EigenCallLibraryUseDemo.address}\`

);

// …

Before deploying EigenCallLibraryUseDemo which uses EigenCallLibrary, we should ensure that we have got the link address of it, after passing it to the factory function, the contract can be deployed successfully.

The Typescript example can be found in [cc.ts](https://github.com/ieigen/ieigen/blob/main/l2/eigen-tutorials/packages/confidential-contracts/scripts/cc.ts), it is similar with the Javascript snippet.

After the successful deployment, we can freely call these contract functions with TEE operators support!

Confidential ERC20
==================

The Standard ERC20 token is widely used for now. Following is an interface contract declaring the required functions and events to meet the ERC20 standard:

contract ERC20 {

function totalSupply() constant returns (uint totalSupply);

function balanceOf(address \_owner) constant returns (uint balance);

function transfer(address \_to, uint \_value) returns (bool success);

function transferFrom(address \_from, address \_to, uint \_value) returns (bool success);

function approve(address \_spender, uint \_value) returns (bool success);

function allowance(address \_owner, address \_spender) constant returns (uint remaining);

event Transfer(address indexed \_from, address indexed \_to, uint \_value);

event Approval(address indexed \_owner, address indexed \_spender, uint \_value);

}

One of the core functions of ERC20 is transfer. In brief, transfer applies two math operations on corresponding balances, that is, adding the amount to the receiver’s balance and minus the amount to the sender’s balance.

For our Confidential ERC20, which had been implemented at [TestCCCustomToken.sol](https://github.com/ieigen/ieigen/blob/main/l2/eigen-tutorials/packages/confidential-contracts/contracts/tokenbridge/test/TestCCCustomToken.sol), The math operators used in balance calculation are privacy operators.

For example, in _TestCCCustomToken.sol_, transfer can be implemented as:

function transfer(address recipient, uint256 amount) public virtual override returns (bool) {

// …

​

bytes memory sender\_cipher\_hex\_balance = \_cipher\_balances\[\_msgSender()\];

bytes memory sender\_cipher\_hex = EigenCallLibrary.subCipherPlain(

sender\_cipher\_hex\_balance,

amount

);

\_cipher\_balances\[\_msgSender()\] = EigenCallLibrary.copyBytes(sender\_cipher\_hex);

bytes memory recipient\_cipher\_hex\_balance = \_cipher\_balances\[recipient\];

bytes memory recipient\_cipher\_hex = EigenCallLibrary.addCipherPlain(

recipient\_cipher\_hex\_balance,

amount

);

\_cipher\_balances\[recipient\] = EigenCallLibrary.copyBytes(recipient\_cipher\_hex);

emit TransferCipher(\_msgSender(), recipient, bytes(amount.toString()));

return true;

}

Instead of store plain balances, cipher balances are used in Confidential ERC20. So typical add and sub are replaced with privacy operators, (here, we use addCipherPlain and subCipherPlain as replacement). Quite easy to implement such tokens with EigenCallLibrary.

Also, we can implement another version of transfer named cipherTransfer, which means the amount can be also cipher:

function cipherTransfer(address recipient, bytes memory cipher\_amount)

public

virtual

returns (bool)

{

// …

bytes memory sender\_cipher\_hex\_balance = \_cipher\_balances\[\_msgSender()\];

bytes memory sender\_cipher\_hex = EigenCallLibrary.subCipherCipher(

sender\_cipher\_hex\_balance,

cipher\_amount

);

\_cipher\_balances\[\_msgSender()\] = EigenCallLibrary.copyBytes(sender\_cipher\_hex);

bytes memory recipient\_cipher\_hex\_balance = \_cipher\_balances\[recipient\];

bytes memory recipient\_cipher\_hex = EigenCallLibrary.addCipherCipher(

recipient\_cipher\_hex\_balance,

cipher\_amount

);

\_cipher\_balances\[recipient\] = EigenCallLibrary.copyBytes(recipient\_cipher\_hex);

emit TransferCipher(\_msgSender(), recipient, cipher\_amount);

return true;

}

Just use addCipherCipher and subCipherCipher instead of addCipherPlain and subCipherPlain.

What about getting the balance? Of course, we can get the cipher balance with cipherBalanceOf.

Other functions are implemented similarly. To know more details, we can read the overall source code.

About Eigen Network

💻 Eigen Network：[https://www.ieigen.com/](https://www.ieigen.com/) 🦋 Twitter：[https://twitter.com/Eigen\_Network](https://twitter.com/Eigen_Network) 👬 Telegram：[https://t.me/EigenNetwork](https://t.me/EigenNetwork) 🕳️ Medium：[https://medium.com/@iEigen](https://medium.com/@iEigen) 🐵 Discord：[https://discord.gg/CkzGRuKwWU](https://discord.gg/CkzGRuKwWU) 🐱 GitHub：[https://github.com/ieigen](https://github.com/ieigen)

---

*Originally published on [ieigen](https://paragraph.com/@ieigen/a-brief-introduction-to-confidential-contract-provided-by-eigen-network)*
