Skip to content

Commit

Permalink
Merge branch 'main' into use-fhe-lib
Browse files Browse the repository at this point in the history
  • Loading branch information
david-zk authored Sep 21, 2023
2 parents f9a7ee7 + 5f36be8 commit 227b541
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 32 deletions.
52 changes: 38 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<p align="center">
<img width=600 src="https://github.com/zama-ai/fhevm-solidity/assets/1384478/265d051c-e177-42b4-b9a2-d2b2e474131b" />
<img width=600 src="https://github.com/zama-ai/fhevm/assets/1384478/265d051c-e177-42b4-b9a2-d2b2e474131b" />
</p>
<hr/>
<p align="center">
<a href="https://docs.zama.ai/fhevm"> 📃 Read white paper</a> |<a href="https://docs.zama.ai/fhevm"> 📒 Read documentation</a> | <a href="https://zama.ai/community"> 💛 Community support</a>
<a href="https://zama.ai/fhevm-whitepaper.pdf"> 📃 Read white paper</a> |<a href="https://docs.zama.ai/fhevm"> 📒 Read documentation</a> | <a href="https://zama.ai/community"> 💛 Community support</a>
</p>
<p align="center">
<!-- Version badge using shields.io -->
<a href="https://github.com/zama-ai/fhevm-solidity/releases">
<img src="https://img.shields.io/github/v/release/zama-ai/fhevm-solidity?style=flat-square">
<a href="https://github.com/zama-ai/fhevm/releases">
<img src="https://img.shields.io/github/v/release/zama-ai/fhevm?style=flat-square">
</a>
<!-- Zama Bounty Program -->
<a href="https://github.com/zama-ai/bounty-program">
Expand All @@ -17,7 +17,33 @@
</p>
<hr/>

A Solidity library for interacting with an fhEVM blockchain.
## Bring confidential smart contracts to your blockchain with fhEVM

There used to be a dilemma in blockchain: keep your application and user data on-chain, allowing everyone to see it, or keep it privately off-chain and lose contract composability.
Thanks to a breakthrough in homomorphic encryption, Zama’s fhEVM makes it possible to run confidential smart contracts on encrypted data, guaranteeing both confidentiality and composability.

### Zama’s fhEVM enables confidential smart contracts using fully homomorphic encryption (FHE)

- **End-to-end encryption of transactions and state:** Data included in transactions is encrypted and never visible to anyone.
- **Composability and data availability on-chain:** States are updated while remaining encrypted at all times.
- **No impact on existing dapps and state:** Data stored on-chain remains encrypted end-to-end.

### Developers can write confidential smart contracts without learning cryptography

- **Solidity Integration:** fhEVM contracts are simple solidity contracts that are built using traditional solidity toolchains.
- **Simple DevX:** Developers can use the `euint` data types to mark which part of their contracts should be private.
- **SC-defined ACL:** All the logic for access control of encrypted states is defined by developers in their smart contracts.

You can take a look at our list of [examples](/examples).

### Powerful features available out of the box

- **High Precision Integers -** Up to 256 bits of precision for integers
- **Full range of Operators -** All typical operators are available: `+`, `-`, `*`, `/`, `<`, `>`, `==`, …
- **Encrypted If-Else Conditionals -** Check conditions on encrypted states
- **On-chain Secure Randomness -** Generate randomness without using oracles
- **Configurable Decryption -** Threshold, centralized or KMS decryption
- **Unbounded Compute Depth -** Unlimited consecutive FHE operations

## Install

Expand Down Expand Up @@ -88,12 +114,9 @@ test/tfheOperations/tfheOperations.ts

### Tests

The easiest way to understand how to write/dev smart contract and interact with them using **fhevmjs** is to read and explore the few tests available in this repository.
The easiest way to understand how to write/dev smart contract and interact with them using **fhevmjs** is to read and explore the available tests in this repository.

<br />
<details>
<summary>Fast start</summary>
<br />
#### Fast start

```bash
# in one terminal
Expand All @@ -120,7 +143,8 @@ npm run fhevm:stop

#### Faucet

To use a ready to use test (only for dev) wallet first, prepare the .env file that contains the mnemonic.
For development purpose, we provide a ready to use wallet. In order to use
it, prepare the .env file that contains the mnemonic.

```bash
cp .env.example .env
Expand Down Expand Up @@ -169,9 +193,9 @@ This library uses several dependencies and we would like to thank the contributo

## Need support?

<a target="_blank" href="https://community.zama.ai">
<img src="https://github.com/zama-ai/fhevm-solidity/assets/1384478/049dfc9b-3caa-4c56-8bee-3d1700664db9">
</a>
- Ask technical questions on the Zama discourse forum: [community.zama.ai](https://community.zama.ai)
- Discuss live with the team on the FHE.org discord server: [discord.fhe.org](https://discord.fhe.org)
- Follow Zama on Twitter: [@zama_fhe](https://twitter.com/zama_fhe)

## License

Expand Down
21 changes: 18 additions & 3 deletions examples/Rand.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ contract Rand {
euint8 value8;
euint16 value16;
euint32 value32;
uint8 public value8Decrypted;
uint16 public value16Decrypted;
uint32 public value32Decrypted;

function generate8() public {
value8 = TFHE.randEuint8();
Expand All @@ -21,18 +24,30 @@ contract Rand {
value32 = TFHE.randEuint32();
}

function get8() public view returns (uint8) {
function decrypt8() public view returns (uint8) {
return TFHE.decrypt(value8);
}

function get16() public view returns (uint16) {
function decrypt16() public view returns (uint16) {
return TFHE.decrypt(value16);
}

function get32() public view returns (uint32) {
function decrypt32() public view returns (uint32) {
return TFHE.decrypt(value32);
}

function decryptAndStore8() public {
value8Decrypted = TFHE.decrypt(value8);
}

function decryptAndStore16() public {
value16Decrypted = TFHE.decrypt(value16);
}

function decryptAndStore32() public {
value32Decrypted = TFHE.decrypt(value32);
}

// Must fail.
function generate8InView() public view {
TFHE.randEuint8();
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"typechain": "cross-env TS_NODE_TRANSPILE_ONLY=true hardhat typechain",
"codegen": "npx ts-node codegen/main.ts && npm run prettier",
"task:getEthereumAddress": "hardhat task:getEthereumAddress",
"fhevm:start": "docker run -i -p 8545:8545 --rm --name fhevm ghcr.io/zama-ai/evmos-dev-node:v0.1.9-beta",
"fhevm:start": "docker run -i -p 8545:8545 --rm --name fhevm ghcr.io/zama-ai/evmos-dev-node:v0.1.9",
"fhevm:stop": "docker rm -f fhevm",
"fhevm:restart": "fhevm:stop && fhevm:start",
"fhevm:faucet": "npm run fhevm:faucet:alice && sleep 5 && npm run fhevm:faucet:bob && sleep 5 && npm run fhevm:faucet:carol && sleep 5 && npm run fhevm:faucet:dave",
Expand All @@ -31,14 +31,14 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/zama-ai/fhevm-solidity.git"
"url": "git+https://github.com/zama-ai/fhevm.git"
},
"author": "",
"license": "BSD-3-Clause-Clear",
"bugs": {
"url": "https://github.com/zama-ai/fhevm-solidity/issues"
"url": "https://github.com/zama-ai/fhevm/issues"
},
"homepage": "https://github.com/zama-ai/fhevm-solidity#readme",
"homepage": "https://github.com/zama-ai/fhevm#readme",
"devDependencies": {
"@nomicfoundation/hardhat-chai-matchers": "^2.0.0",
"@nomicfoundation/hardhat-ethers": "^3.0.0",
Expand Down
10 changes: 5 additions & 5 deletions test/governor/GovernorZama.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('GovernorZama', function () {

beforeEach(async function () {
// Increase timeout for beforeEach
this.timeout(120000);
this.timeout(130000);

this.comp = await deployCompFixture();
const instances = await createInstances(await this.comp.getAddress(), ethers, this.signers);
Expand Down Expand Up @@ -61,7 +61,7 @@ describe('GovernorZama', function () {
const proposals = await this.governor.proposals(proposalId);
expect(proposals.id).to.equal(proposalId);
expect(proposals.proposer).to.equal(this.signers.alice.address);
}).timeout(120000);
}).timeout(130000);

it('should vote and return a Succeed', async function () {
const callDatas = [ethers.AbiCoder.defaultAbiCoder().encode(['address'], [this.signers.alice.address])];
Expand Down Expand Up @@ -104,7 +104,7 @@ describe('GovernorZama', function () {

const state = await this.governor.state(proposalId);
expect(state).to.equal(4n);
}).timeout(120000);
}).timeout(130000);

it('should vote and return a Defeated ', async function () {
const callDatas = [ethers.AbiCoder.defaultAbiCoder().encode(['address'], [this.signers.alice.address])];
Expand Down Expand Up @@ -146,7 +146,7 @@ describe('GovernorZama', function () {

const state = await this.governor.state(proposalId);
expect(state).to.equal(3n);
}).timeout(120000);
}).timeout(130000);

it('should cancel', async function () {
await this.comp.delegate(this.signers.alice.address);
Expand All @@ -173,5 +173,5 @@ describe('GovernorZama', function () {
await txCancel.wait();
const newState = await this.governor.state(proposalId);
expect(newState).to.equal(2n);
}).timeout(120000);
}).timeout(130000);
});
33 changes: 27 additions & 6 deletions test/rand/Rand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ describe('Rand', function () {
this.instances = await createInstances(this.contractAddress, ethers, this.signers);
});

it('8 bits', async function () {
it('8 bits generate and decrypt', async function () {
const values: bigint[] = [];
for (let i = 0; i < 5; i++) {
const txn = await this.rand.generate8();
await txn.wait();
const value = await this.rand.get8();
const value = await this.rand.decrypt8();
expect(value).to.be.lessThanOrEqual(0xff);
values.push(value);
}
Expand All @@ -31,13 +31,13 @@ describe('Rand', function () {
expect(unique.size).to.be.greaterThanOrEqual(2);
});

it('16 bits', async function () {
it('16 bits generate and decrypt', async function () {
const values: bigint[] = [];
let has16bit: boolean = false;
for (let i = 0; i < 5; i++) {
const txn = await this.rand.generate16();
await txn.wait();
const value = await this.rand.get16();
const value = await this.rand.decrypt16();
expect(value).to.be.lessThanOrEqual(0xffff);
if (value > 0xff) {
has16bit = true;
Expand All @@ -51,13 +51,13 @@ describe('Rand', function () {
expect(unique.size).to.be.greaterThanOrEqual(2);
});

it('32 bits', async function () {
it('32 bits generate and decrypt', async function () {
const values: bigint[] = [];
let has32bit: boolean = false;
for (let i = 0; i < 5; i++) {
const txn = await this.rand.generate32();
await txn.wait();
const value = await this.rand.get32();
const value = await this.rand.decrypt32();
expect(value).to.be.lessThanOrEqual(0xffffffff);
if (value > 0xffff) {
has32bit = true;
Expand All @@ -71,6 +71,27 @@ describe('Rand', function () {
expect(unique.size).to.be.greaterThanOrEqual(2);
});

it('8 bits generate, decrypt and store', async function () {
const txnGen = await this.rand.generate8();
await txnGen.wait();
const txnDecAndStore = await this.rand.decryptAndStore8();
await expect(txnDecAndStore.wait()).to.not.be.rejected;
});

it('16 bits generate, decrypt and store', async function () {
const txnGen = await this.rand.generate16();
await txnGen.wait();
const txnDecAndStore = await this.rand.decryptAndStore16();
await expect(txnDecAndStore.wait()).to.not.be.rejected;
});

it('32 bits generate, decrypt and store', async function () {
const txnGen = await this.rand.generate32();
await txnGen.wait();
const txnDecAndStore = await this.rand.decryptAndStore32();
await expect(txnDecAndStore.wait()).to.not.be.rejected;
});

it('8 bits in view', async function () {
await expect(this.rand.generate8InView()).to.be.rejected;
});
Expand Down

0 comments on commit 227b541

Please sign in to comment.