Encryption

In order to store an encrypted values on-chain, a plain text can be converted into a cipher text on the client side using with the public key of the network.

Node.js

The first step is to retrieve the network's public key by connecting to our RPC and using createInstance from fhevmjs:

const { createInstance } = require("fhevmjs");
const { JsonRpcProvider } = require("ethers");

const provider = new JsonRpcProvider(`https://testnet.inco.org`);

// Contract address of TFHE.sol
const FHE_LIB_ADDRESS = "0x000000000000000000000000000000000000005d";

let _instance;

const getInstance = async () => {
  if (_instance) return _instance;

  const network = await provider.getNetwork();
  const chainId = +network.chainId.toString(); // chainId: 9090

  console.log("network", network);
  console.log("chainId", chainId);
  
  // Get blockchain public key
  const ret = await provider.call({
    to: FHE_LIB_ADDRESS,
    // first four bytes of keccak256('fhePubKey(bytes1)') + 1 byte for library
    data: "0xd9d47bb001",
  });
  const decoded = AbiCoder.defaultAbiCoder().decode(["bytes"], ret);
  const publicKey = decoded[0];

  _instance = await createInstance({ chainId, publicKey });
};

The functions encrypt8, encrypt16 and encrypt32 are available to encrypt your plain text into a cipher text. For example:

const encryptedUint32 = instance.encrypt32(10);

Browser / React

Here's a react starter with fhevmjs: https://github.com/Inco-fhevm/fhevmjs-react-example

To use fhevmjs inside the browser, you need to load WASM (WebAssembly) first with initFhevm, to perform cryptographic computations.

import { BrowserProvider } from 'ethers';
import { initFhevm, createInstance } from 'fhevmjs';

// Contract address of TFHE.sol.
// From https://github.com/zama-ai/fhevmjs/blob/c4b8a80a8783ef965973283362221e365a193b76/bin/fhevm.js#L9
const FHE_LIB_ADDRESS = "0x000000000000000000000000000000000000005d";

const createFhevmInstance = async () => {
  // Make sure your MetaMask is connected to Inco Gentry Testnet
  const provider = new BrowserProvider(window.ethereum);

  const network = await provider.getNetwork();
  const chainId = +network.chainId.toString(); // 9090

  console.log("network", network);
  console.log("chainId", chainId);

  const publicKey = await provider.call({
    to: FHE_LIB_ADDRESS,
    // first four bytes of keccak256('fhePubKey(bytes1)') + 1 byte for library
    data: "0xd9d47bb001",
  });
  const decoded = AbiCoder.defaultAbiCoder().decode(["bytes"], ret);
  const publicKey = decoded[0];

  return createInstance({ chainId, publicKey });
};

const init = async () => {
  await initFhevm(); // Load TFHE
  return createFhevmInstance();
};

init().then((instance) => {
  console.log(instance);
});

Last updated