Skip to content

Instantly share code, notes, and snippets.

@charmful0x
Last active September 15, 2023 12:03
Show Gist options
  • Save charmful0x/c4ebb32b68e7e5f89a4553021209e228 to your computer and use it in GitHub Desktop.
Save charmful0x/c4ebb32b68e7e5f89a4553021209e228 to your computer and use it in GitHub Desktop.

xMEM Technical Overview Draft

Abstract

xMEM is a fork of MEM that implements privacy-focused features, such as encrypted states and interactions.

It enables secrets (.env-like), and provides a dedicated node to ensure Dappling's implementation isn't sharing the 4k/tps cap with other contracts.

Function code, inputs and outputs are encrypted by default with xMEM.

Core Tech Stack

xMEM will utilize Kwil and Bundlr for its tech stack. The core tool is Kwil, while Bundlr will be used solely as a utility helper to improve database performance by reducing data size during transportation.

tag -> "indexing_db" : "xkwilnsbuw2o2jwsmsks"

How it Works

xMEM will operate through an SDK with several functionalities, including:

Initializing an xMEM class instance that encapsulates both MEM functionalities and Kwil's.

1- Deploying an xMEM Function:

const xMEM = new MemClass.init({
  pk: "0x..123" // the PK of the Kwil DB deployer
});

Similar to MEM deployment functions, xMEM performs the same actions, but with the addition of a new attached data (an additional Arweave tag to the normal MEM contract data TX), which serves as the indexer DB reference dedicated to the deployed function. Each deployed function will have its dedicated Kwil DB, which serves both as a mem-orchestrator (indexing non-evaluated interactions-TXs) and mem-core (evaluating non-evaluated TXs and updating the state).

As you can see, xMEM is inherently decentralized, unlike MEM, as each contract deployer has their own DB instance. In other words, each contract acts as a mini-MEM node.

The attached KwilDB (with a contract) contains 2 tables:

  • table unresolved_txs: used to index unresolved TXs.
  • table evaluated_states: used to maintain a record of Bundlr TXs representing evaluated states.

Note that Bundlr TXs essentially contain the evaluated state (the result of an interaction), encrypted using Kwil's DB admin PK, and then packed as a text/plain Bundlr data transaction. Encryption takes place on the client-side (xMEM node), and all data transmissions are encrypted. Consequently, the KwilDB only stores references (Bundlr TXID) of the encrypted state's data, all of which are fixed-size strings, each 43 bytes in length.

2- xMEM Contract Interaction

const xMEM = new MemClass.init({
  pk: "0x..123", // the PK of the Kwil DB deployer
  function_id: "abc...xyz" // the FID of the xMEM contract 
});

Interaction Types:

  • Non-encrypted (public) write actions (faster): In this type, an array of interactions (JSON with a size <= 1 MiB) is packed into a Bundlr TX and then sent by the xMEM function admin to the xMEM contract's attached KwilDB.

  • Encrypted write actions (slower): This type is similar to the previous one, but before the data is packed into a Bundlr TX, it is encrypted using the KwilDB EOA PK, the same PK used for the xMEM contract state.

N.B: In both types, the state is encrypted.

xMEM Transaction (Interaction) Cycle:

// xMEM class instance initialized.
const interactionsRef = "123...xyz";
await xMEM.writeFunction(interactionsRef);
P.S: thinking more in this, we can ditch the Bundlr part for TX submission and just stick to cypher string of the encrypted interactions array. That way we make the process slightly faster (by removing the component that async request data from Bundlr).

we can do it that way for v0.0.1, and for for v0.0.2 we implement the Bundlr because it has higher scalability (infinie interactions size, while cipher is limited to <= 1MiB due to Kwil limitations)

xMEM TXs, according to this draft, are submitted exclusively via the xMEM SDK using an instance initialized by the xMEM function admin.

In the case of a new xMEM function transaction (how writeFunction works):

1- The interactions are packed into Bundlr data TXs, and the Arweave TXID is sent to the KwilDB's unresolved_txs table.

2- writeFunction fetches all pending TXs from the table (in case any TXs were non-evaluated and missed), sorts them chronologically (based on timestamps), and returns them.

3- The writeFunction (referred to as the SDK) retrieves the latest evaluated state reference from the evaluated_states table, decrypts it locally, then runs stimulateContract from the 3EM repo, using the list of fetched interactions, until it evaluates all of the bundle's TXs. Subsequently, it creates a new final state reference (Bundlr TXID) and pushes it to the evaluated_states table.

4- A new final encrypted state is achieved.

3- Reading Your xMEM Deployed Function State

// xMEM class instance initialized.
const xmem_id = "123...xyz";
const decryptedState = await xMEM.readState(xmem_id);

The readState() method requests the latest encrypted state reference (Bundlr TXID) from the KwilDB table evaluated_states, loads the data, decrypts it using the xMEM class instance PK (which is also the Kwil DB deployer PK), and then returns the decrypted JSON state.

Conclusion

This represents a high-level technical architecture design. An additional security layer can be implemented in the xMEM Kwil DBs template when the Kwil team implements the feature I mentioned in the group chat (@caller gated read and write access -- access control).

This xMEM model introduces a more decentralized, privacy-focused implementation of MEM, with the following trade-offs:

  • Probability suggests that actions (read/write) will be slower than MEM (though untested).
  • Only the xMEM function deployer can read and write, which is a feature rather than a bug.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment