From 8ee626cf2257c8fc937a83a5bd771c1ebe9073f1 Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Wed, 10 Jul 2024 09:54:41 -0700 Subject: [PATCH 01/18] WIP --- documentation/leo/03_language.md | 2 ++ documentation/leo/17_testnet_beta.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/documentation/leo/03_language.md b/documentation/leo/03_language.md index 04c614177..a9458a967 100644 --- a/documentation/leo/03_language.md +++ b/documentation/leo/03_language.md @@ -363,6 +363,7 @@ Transition functions in Leo are declared as `transition {name}() {}`. Transition functions can be called directly when running a Leo program (via `leo run`). Transition functions contain expressions and statements that can compute values. Transition functions must be in a program's current scope to be called. +Transition functions that call [async functions](#async-function) to execute code on-chain must be declared as `async transition`. ```leo showLineNumbers program hello.aleo { @@ -447,6 +448,7 @@ The rules for functions (in the traditional sense) are as follows: ### Async Function An async function is declared as `async function` and is used to define computation run on-chain. +A call to an async function returns a [`Future`](#future) object. It is asynchronous because the code gets executed at a later point in time. One of its primary uses is to initiate or change public on chain state within mappings. An async function can only be called by an async [transition function](#transition-function) and is executed on chain, after the zero-knowledge proof of the execution of the associated transition is verified. diff --git a/documentation/leo/17_testnet_beta.md b/documentation/leo/17_testnet_beta.md index 0f8cc1df5..063d5f192 100644 --- a/documentation/leo/17_testnet_beta.md +++ b/documentation/leo/17_testnet_beta.md @@ -12,7 +12,7 @@ We are about to reach a huge milestone in Aleo's developement. Testnet Beta is a **IMPORTANT:** - **Leo v1.12.0 will be the last Testnet3 compatible version.** -- **Leo v.2.0.0 (to be released) will be the first Testnet Beta compatible version.** (In the meantime, you can build from source on the `testnet-beta` branch of the Leo repository.) +- **Leo v.2.0.0 is the first Testnet Beta compatible version.** (In the meantime, you can build from source on the `testnet-beta` branch of the Leo repository.) For additional support, please feel free to: - File an issue [here](https://github.com/AleoHQ/leo/issues/new/choose). From e38d347b1a552bd4b8fabfde6cf3fc2fc3511c82 Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Wed, 10 Jul 2024 19:49:01 -0700 Subject: [PATCH 02/18] Delete unusable updates --- .../book.toml | 6 -- .../src/SUMMARY.md | 77 ------------------- .../intro-to-zksnark/general-intuition.md | 10 --- .../src/build/README.md | 1 - .../src/build/data-and-analytics/README.md | 1 - .../src/build/development-network/README.md | 1 - .../src/build/leo/README.md | 1 - .../leo/ale-sdk/python/zkml-transpiler.md | 1 - .../src/build/leo/aleo-sdk/README.md | 1 - .../leo/aleo-sdk/create-aleo-app/README.md | 1 - .../create-aleo-app/react-js-leo-tutorial.md | 1 - .../src/build/leo/aleo-sdk/js-ts.md | 1 - .../src/build/leo/aleo-sdk/js-ts/README.md | 1 - .../src/build/leo/aleo-sdk/js-ts/account.md | 1 - .../leo/aleo-sdk/js-ts/development-client.md | 1 - .../src/build/leo/aleo-sdk/overview.md | 1 - .../src/build/leo/aleo-sdk/python/README.md | 1 - .../src/build/leo/aleo-sdk/python/aleo-sdk.md | 1 - .../src/build/leo/aleo-sdk/wasm/README.md | 1 - .../aleo-sdk/wasm/browser-multi-threaded.md | 1 - .../build/leo/aleo-sdk/wasm/installation.md | 1 - .../build/leo/aleo-sdk/wasm/nodejs-browser.md | 1 - .../src/build/leo/compiling-programs.md | 1 - .../src/build/leo/deploying-programs.md | 1 - .../src/build/leo/executing-programs.md | 1 - .../src/build/leo/helloleo.md | 1 - .../src/build/leo/installation.md | 1 - .../src/build/leo/language.md | 1 - .../build/leo/manage-your-program/README.md | 1 - .../src/build/leo/operators.md | 1 - .../src/build/leo/overview.md | 1 - .../src/build/leo/resources/README.md | 1 - .../leo/resources/developer-resources.md | 1 - .../src/build/leo/resources/leo-playground.md | 1 - .../leo/resources/leo-syntax-cheatsheet.md | 1 - .../src/build/leo/resources/tooling.md | 1 - .../src/build/overview.md | 1 - .../src/build/snarkos-node-rpc/README.md | 1 - .../src/learn/README.md | 1 - .../src/learn/concepts/README.md | 1 - .../src/learn/concepts/blocks.md | 1 - .../src/learn/concepts/fee.md | 1 - .../src/learn/concepts/transactions.md | 1 - .../src/learn/concepts/transitions.md | 1 - .../src/learn/network/README_zh.md | 20 ----- .../src/learn/network/provers_zh.md | 40 ---------- .../src/learn/network/validators_zh.md | 45 ----------- .../src/overview.md | 1 - 48 files changed, 240 deletions(-) delete mode 100644 documentation updates aleo ambassadors/book.toml delete mode 100644 documentation updates aleo ambassadors/src/SUMMARY.md delete mode 100644 documentation updates aleo ambassadors/src/build/README.md delete mode 100644 documentation updates aleo ambassadors/src/build/data-and-analytics/README.md delete mode 100644 documentation updates aleo ambassadors/src/build/development-network/README.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/README.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/ale-sdk/python/zkml-transpiler.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/aleo-sdk/README.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/aleo-sdk/create-aleo-app/README.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/aleo-sdk/create-aleo-app/react-js-leo-tutorial.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts/README.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts/account.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts/development-client.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/aleo-sdk/overview.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/aleo-sdk/python/README.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/aleo-sdk/python/aleo-sdk.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/aleo-sdk/wasm/README.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/aleo-sdk/wasm/browser-multi-threaded.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/aleo-sdk/wasm/installation.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/aleo-sdk/wasm/nodejs-browser.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/compiling-programs.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/deploying-programs.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/executing-programs.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/helloleo.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/installation.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/language.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/manage-your-program/README.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/operators.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/overview.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/resources/README.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/resources/developer-resources.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/resources/leo-playground.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/resources/leo-syntax-cheatsheet.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/resources/tooling.md delete mode 100644 documentation updates aleo ambassadors/src/build/overview.md delete mode 100644 documentation updates aleo ambassadors/src/build/snarkos-node-rpc/README.md delete mode 100644 documentation updates aleo ambassadors/src/learn/README.md delete mode 100644 documentation updates aleo ambassadors/src/learn/concepts/README.md delete mode 100644 documentation updates aleo ambassadors/src/learn/concepts/blocks.md delete mode 100644 documentation updates aleo ambassadors/src/learn/concepts/fee.md delete mode 100644 documentation updates aleo ambassadors/src/learn/concepts/transactions.md delete mode 100644 documentation updates aleo ambassadors/src/learn/concepts/transitions.md delete mode 100644 documentation updates aleo ambassadors/src/learn/network/README_zh.md delete mode 100644 documentation updates aleo ambassadors/src/learn/network/provers_zh.md delete mode 100644 documentation updates aleo ambassadors/src/learn/network/validators_zh.md delete mode 100644 documentation updates aleo ambassadors/src/overview.md diff --git a/documentation updates aleo ambassadors/book.toml b/documentation updates aleo ambassadors/book.toml deleted file mode 100644 index 2b70c5d76..000000000 --- a/documentation updates aleo ambassadors/book.toml +++ /dev/null @@ -1,6 +0,0 @@ -[book] -title = "zero-to-zk" -authors = ["Zk"] -language = "en" -multilingual = false -src = "src" diff --git a/documentation updates aleo ambassadors/src/SUMMARY.md b/documentation updates aleo ambassadors/src/SUMMARY.md deleted file mode 100644 index 1b99c09c9..000000000 --- a/documentation updates aleo ambassadors/src/SUMMARY.md +++ /dev/null @@ -1,77 +0,0 @@ -# Summary - -- [Overview](./overview.md) -- [LEARN](./learn/README.md) - - - [Core Architecture](./learn/core-architecture.md) - - [Concepts](./learn/concepts/README.md) - - [Accounts](./learn/concepts/accounts.md) - - [Programs](./learn/concepts/programs/README.md) - - [Execution](./learn/concepts/programs/execution.md) - - [Deployment](./learn/concepts/programs/deployment.md) - - [Blocks](./learn/concepts/blocks.md) - - [Transactions](./learn/concepts/transactions.md) - - [Transitions](./learn/concepts/transitions.md) - - [Storage](./learn/concepts/storage.md) - - [Fee](./learn/concepts/fee.md) - - [zkCloud](./learn/zkcloud/README.md) - - [snarkOS](./learn/zkcloud/snarkos.md) - - [snarkVM](./learn/zkcloud/snarkvm.md) - - [Network](./learn/network/README.md) - - [Validators](./learn/network/validators.md) - - [Clients](./learn/network/clients.md) - - [Provers](./learn/network/provers.md) - - [Consensus](./learn/network/concensus.md) - -- [BUILD](./build/README.md) - - - [Leo](./build/leo/README.md) - - - [Overview](./build/leo/overview.md) - - [Installation](./build/installation/installation.md) - - [HelloLeo](./build/leo/helloleo.md) - - [Core Components](./build/leo/README.md) - - [Language](./build/leo/language.md) - - [Operators](./build/leo/operators.md) - - [Commands](./build/leo/commands.md) - - [Manage your Program](./build/leo/manage-your-program/README.md) - - [Compiling Programs](./build/leo/compiling-programs.md) - - [Deploying Programs](./build/leo/deploying-programs.md) - - [Executing Programs](./build/leo/executing-programs.md) - - [Resources](./build/leo/resources/README.md) - - [Tooling](./build/leo/resources/tooling.md) - - [Leo Playground](./build/leo/resources/leo-playground.md) - - [Leo Syntax Cheatsheet](./build/leo/resources/leo-syntax-cheatsheet.md) - - [Developer Resources](./build/leo/resources/developer-resources.md) - - [Aleo SDK](./build/leo/aleo-sdk/README.md) - - - [Overview](./build/leo/aleo-sdk/overview.md) - - [Javascript/TypeScript](./build/leo/aleo-sdk/js-ts/README.md) - - - [Guide](./build/leo/aleo-sdk/js-ts/guide.md) - - [Account](./build/leo/aleo-sdk/js-ts/account.md) - - [Aleo Network Client](./build/leo/aleo-sdk/js-ts/aleo-network-client.md) - - [Development Client](./build/leo/aleo-sdk/js-ts/development-client.md) - - - [Create Aleo App](./build/leo/aleo-sdk/create-aleo-app/README.md) - - [Installation](./build/leo/aleo-sdk/create-aleo-app/installation.md) - - [React + JS + Leo Tutorial](./build/leo/aleo-sdk/create-aleo-app/react-js-leo-tutorial.md) - - [Wasm](./build/leo/aleo-sdk/wasm/README.md) - - - [Installation](./build/leo/aleo-sdk/wasm/installation.md) - - [NodeJS + Browser](./build/leo/aleo-sdk/wasm/nodejs-browser.md) - - [Browser(Multi-Threaded)](./build/leo/aleo-sdk/wasm/browser-multi-threaded.md) - - - [Python](./build/leo/aleo-sdk/python/README.md) - - [Aleo SDK](./build/leo/aleo-sdk/python/aleo-sdk.md) - - [zkML Transpiler](./build/leo/ale-sdk/python/zkml-transpiler.md) - - - [Development Netowrk](./build/development-network/README.md) - - [snarkOS Node RPC](./build/snarkos-node-rpc/README.md) - - [Data and analytics](./build/data-and-analytics/README.md) - - - [Advanced](./advanced/README.md) - - [InclusionProof](./advanced/inclusion-proof..md) - - [Dive into AVM](./advanced/dive-into-avm/README.md) - - [Circuit](./advanced/dive-into-avm/circuits-r1cs.md) - - [Aleo Account](./advanced/dive-into-avm/aleo-account-keys.md) diff --git a/documentation updates aleo ambassadors/src/advanced/intro-to-zksnark/general-intuition.md b/documentation updates aleo ambassadors/src/advanced/intro-to-zksnark/general-intuition.md index c95cb0608..4c4c776ae 100644 --- a/documentation updates aleo ambassadors/src/advanced/intro-to-zksnark/general-intuition.md +++ b/documentation updates aleo ambassadors/src/advanced/intro-to-zksnark/general-intuition.md @@ -1,14 +1,4 @@ # Advanced - In this section we cover the general intuition of a zk proof, we outline the steps in creating a zksnark, we define the actors in a zk proof mainly the prover and verifier. We also introduce the elements in a zkproof like the witness, intermediate representation, trusted setups, structured reference strings and random oracles. We also give the context of where the zksnark proof is used in Aleo. ## Introduction diff --git a/documentation updates aleo ambassadors/src/build/README.md b/documentation updates aleo ambassadors/src/build/README.md deleted file mode 100644 index 405d1ab08..000000000 --- a/documentation updates aleo ambassadors/src/build/README.md +++ /dev/null @@ -1 +0,0 @@ -# BUILD diff --git a/documentation updates aleo ambassadors/src/build/data-and-analytics/README.md b/documentation updates aleo ambassadors/src/build/data-and-analytics/README.md deleted file mode 100644 index d742cf0f8..000000000 --- a/documentation updates aleo ambassadors/src/build/data-and-analytics/README.md +++ /dev/null @@ -1 +0,0 @@ -# Data and analytics diff --git a/documentation updates aleo ambassadors/src/build/development-network/README.md b/documentation updates aleo ambassadors/src/build/development-network/README.md deleted file mode 100644 index 7d75dc849..000000000 --- a/documentation updates aleo ambassadors/src/build/development-network/README.md +++ /dev/null @@ -1 +0,0 @@ -# Development Netowrk diff --git a/documentation updates aleo ambassadors/src/build/leo/README.md b/documentation updates aleo ambassadors/src/build/leo/README.md deleted file mode 100644 index 28e40cf76..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/README.md +++ /dev/null @@ -1 +0,0 @@ -# Leo diff --git a/documentation updates aleo ambassadors/src/build/leo/ale-sdk/python/zkml-transpiler.md b/documentation updates aleo ambassadors/src/build/leo/ale-sdk/python/zkml-transpiler.md deleted file mode 100644 index 63b8048bb..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/ale-sdk/python/zkml-transpiler.md +++ /dev/null @@ -1 +0,0 @@ -# zkML Transpiler diff --git a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/README.md b/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/README.md deleted file mode 100644 index 7567930ba..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/README.md +++ /dev/null @@ -1 +0,0 @@ -# Aleo SDK diff --git a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/create-aleo-app/README.md b/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/create-aleo-app/README.md deleted file mode 100644 index abe525963..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/create-aleo-app/README.md +++ /dev/null @@ -1 +0,0 @@ -# Create Aleo App diff --git a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/create-aleo-app/react-js-leo-tutorial.md b/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/create-aleo-app/react-js-leo-tutorial.md deleted file mode 100644 index c5b42317d..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/create-aleo-app/react-js-leo-tutorial.md +++ /dev/null @@ -1 +0,0 @@ -# React + JS + Leo Tutorial diff --git a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts.md b/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts.md deleted file mode 100644 index d081981f1..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts.md +++ /dev/null @@ -1 +0,0 @@ -# Javascript/TypeScript diff --git a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts/README.md b/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts/README.md deleted file mode 100644 index d081981f1..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts/README.md +++ /dev/null @@ -1 +0,0 @@ -# Javascript/TypeScript diff --git a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts/account.md b/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts/account.md deleted file mode 100644 index 50b219504..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts/account.md +++ /dev/null @@ -1 +0,0 @@ -# Account diff --git a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts/development-client.md b/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts/development-client.md deleted file mode 100644 index 3faf21754..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts/development-client.md +++ /dev/null @@ -1 +0,0 @@ -# Development Client diff --git a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/overview.md b/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/overview.md deleted file mode 100644 index 07dd0c5c7..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/overview.md +++ /dev/null @@ -1 +0,0 @@ -# Overview diff --git a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/python/README.md b/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/python/README.md deleted file mode 100644 index 4193ef4be..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/python/README.md +++ /dev/null @@ -1 +0,0 @@ -# Python diff --git a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/python/aleo-sdk.md b/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/python/aleo-sdk.md deleted file mode 100644 index 7567930ba..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/python/aleo-sdk.md +++ /dev/null @@ -1 +0,0 @@ -# Aleo SDK diff --git a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/wasm/README.md b/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/wasm/README.md deleted file mode 100644 index d4fdb1ba1..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/wasm/README.md +++ /dev/null @@ -1 +0,0 @@ -# Wasm diff --git a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/wasm/browser-multi-threaded.md b/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/wasm/browser-multi-threaded.md deleted file mode 100644 index 8b9cd6e9d..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/wasm/browser-multi-threaded.md +++ /dev/null @@ -1 +0,0 @@ -# Browser(Multi-Threaded) diff --git a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/wasm/installation.md b/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/wasm/installation.md deleted file mode 100644 index 25267fe2b..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/wasm/installation.md +++ /dev/null @@ -1 +0,0 @@ -# Installation diff --git a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/wasm/nodejs-browser.md b/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/wasm/nodejs-browser.md deleted file mode 100644 index d4e4f16ad..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/wasm/nodejs-browser.md +++ /dev/null @@ -1 +0,0 @@ -# NodeJS + Browser diff --git a/documentation updates aleo ambassadors/src/build/leo/compiling-programs.md b/documentation updates aleo ambassadors/src/build/leo/compiling-programs.md deleted file mode 100644 index 676ddafef..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/compiling-programs.md +++ /dev/null @@ -1 +0,0 @@ -# Compiling Programs diff --git a/documentation updates aleo ambassadors/src/build/leo/deploying-programs.md b/documentation updates aleo ambassadors/src/build/leo/deploying-programs.md deleted file mode 100644 index ef3aa7070..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/deploying-programs.md +++ /dev/null @@ -1 +0,0 @@ -# Deploying Programs diff --git a/documentation updates aleo ambassadors/src/build/leo/executing-programs.md b/documentation updates aleo ambassadors/src/build/leo/executing-programs.md deleted file mode 100644 index 1adb0d45b..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/executing-programs.md +++ /dev/null @@ -1 +0,0 @@ -# Executing Programs diff --git a/documentation updates aleo ambassadors/src/build/leo/helloleo.md b/documentation updates aleo ambassadors/src/build/leo/helloleo.md deleted file mode 100644 index f39483a26..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/helloleo.md +++ /dev/null @@ -1 +0,0 @@ -# HelloLeo diff --git a/documentation updates aleo ambassadors/src/build/leo/installation.md b/documentation updates aleo ambassadors/src/build/leo/installation.md deleted file mode 100644 index 25267fe2b..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/installation.md +++ /dev/null @@ -1 +0,0 @@ -# Installation diff --git a/documentation updates aleo ambassadors/src/build/leo/language.md b/documentation updates aleo ambassadors/src/build/leo/language.md deleted file mode 100644 index 403a5489d..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/language.md +++ /dev/null @@ -1 +0,0 @@ -# Language diff --git a/documentation updates aleo ambassadors/src/build/leo/manage-your-program/README.md b/documentation updates aleo ambassadors/src/build/leo/manage-your-program/README.md deleted file mode 100644 index ed1516c01..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/manage-your-program/README.md +++ /dev/null @@ -1 +0,0 @@ -# Manage your Program diff --git a/documentation updates aleo ambassadors/src/build/leo/operators.md b/documentation updates aleo ambassadors/src/build/leo/operators.md deleted file mode 100644 index 0d12c6d61..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/operators.md +++ /dev/null @@ -1 +0,0 @@ -# Operators diff --git a/documentation updates aleo ambassadors/src/build/leo/overview.md b/documentation updates aleo ambassadors/src/build/leo/overview.md deleted file mode 100644 index 07dd0c5c7..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/overview.md +++ /dev/null @@ -1 +0,0 @@ -# Overview diff --git a/documentation updates aleo ambassadors/src/build/leo/resources/README.md b/documentation updates aleo ambassadors/src/build/leo/resources/README.md deleted file mode 100644 index 3c1229ee1..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/resources/README.md +++ /dev/null @@ -1 +0,0 @@ -# Resources diff --git a/documentation updates aleo ambassadors/src/build/leo/resources/developer-resources.md b/documentation updates aleo ambassadors/src/build/leo/resources/developer-resources.md deleted file mode 100644 index a67a44392..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/resources/developer-resources.md +++ /dev/null @@ -1 +0,0 @@ -# Developer Resources diff --git a/documentation updates aleo ambassadors/src/build/leo/resources/leo-playground.md b/documentation updates aleo ambassadors/src/build/leo/resources/leo-playground.md deleted file mode 100644 index 83325e6d4..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/resources/leo-playground.md +++ /dev/null @@ -1 +0,0 @@ -# Leo Playground diff --git a/documentation updates aleo ambassadors/src/build/leo/resources/leo-syntax-cheatsheet.md b/documentation updates aleo ambassadors/src/build/leo/resources/leo-syntax-cheatsheet.md deleted file mode 100644 index db21440dd..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/resources/leo-syntax-cheatsheet.md +++ /dev/null @@ -1 +0,0 @@ -# Leo Syntax Cheatsheet diff --git a/documentation updates aleo ambassadors/src/build/leo/resources/tooling.md b/documentation updates aleo ambassadors/src/build/leo/resources/tooling.md deleted file mode 100644 index a07e7c8bb..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/resources/tooling.md +++ /dev/null @@ -1 +0,0 @@ -# Tooling diff --git a/documentation updates aleo ambassadors/src/build/overview.md b/documentation updates aleo ambassadors/src/build/overview.md deleted file mode 100644 index 07dd0c5c7..000000000 --- a/documentation updates aleo ambassadors/src/build/overview.md +++ /dev/null @@ -1 +0,0 @@ -# Overview diff --git a/documentation updates aleo ambassadors/src/build/snarkos-node-rpc/README.md b/documentation updates aleo ambassadors/src/build/snarkos-node-rpc/README.md deleted file mode 100644 index 3553f74fc..000000000 --- a/documentation updates aleo ambassadors/src/build/snarkos-node-rpc/README.md +++ /dev/null @@ -1 +0,0 @@ -# snarkOS Node RPC diff --git a/documentation updates aleo ambassadors/src/learn/README.md b/documentation updates aleo ambassadors/src/learn/README.md deleted file mode 100644 index 58e167b7b..000000000 --- a/documentation updates aleo ambassadors/src/learn/README.md +++ /dev/null @@ -1 +0,0 @@ -# LEARN diff --git a/documentation updates aleo ambassadors/src/learn/concepts/README.md b/documentation updates aleo ambassadors/src/learn/concepts/README.md deleted file mode 100644 index 74d42e13c..000000000 --- a/documentation updates aleo ambassadors/src/learn/concepts/README.md +++ /dev/null @@ -1 +0,0 @@ -# Concepts diff --git a/documentation updates aleo ambassadors/src/learn/concepts/blocks.md b/documentation updates aleo ambassadors/src/learn/concepts/blocks.md deleted file mode 100644 index 54e0a5ff9..000000000 --- a/documentation updates aleo ambassadors/src/learn/concepts/blocks.md +++ /dev/null @@ -1 +0,0 @@ -# Blocks diff --git a/documentation updates aleo ambassadors/src/learn/concepts/fee.md b/documentation updates aleo ambassadors/src/learn/concepts/fee.md deleted file mode 100644 index af609bd26..000000000 --- a/documentation updates aleo ambassadors/src/learn/concepts/fee.md +++ /dev/null @@ -1 +0,0 @@ -# Fee diff --git a/documentation updates aleo ambassadors/src/learn/concepts/transactions.md b/documentation updates aleo ambassadors/src/learn/concepts/transactions.md deleted file mode 100644 index a5fd09c18..000000000 --- a/documentation updates aleo ambassadors/src/learn/concepts/transactions.md +++ /dev/null @@ -1 +0,0 @@ -# Transactions diff --git a/documentation updates aleo ambassadors/src/learn/concepts/transitions.md b/documentation updates aleo ambassadors/src/learn/concepts/transitions.md deleted file mode 100644 index bbe279abd..000000000 --- a/documentation updates aleo ambassadors/src/learn/concepts/transitions.md +++ /dev/null @@ -1 +0,0 @@ -# Transitions diff --git a/documentation updates aleo ambassadors/src/learn/network/README_zh.md b/documentation updates aleo ambassadors/src/learn/network/README_zh.md deleted file mode 100644 index 97fa4ba40..000000000 --- a/documentation updates aleo ambassadors/src/learn/network/README_zh.md +++ /dev/null @@ -1,20 +0,0 @@ -![aleo_network](images/aleo_network.jpg) - -在Aleo中存在着两个网络:一个是共识网络、一个是P2P网络。有三种节点类型:Validator、Prover、Client。 - -### Validator - -Validator会加入到两个网络中,一个是共识网络,通常监听5000端口,另一个是P2P网络,通常监听4130端口。Validator之间会通过5000端口互相连接,形成一个共识网络,Client和Prover不被允许连接共识网络。 - -Validator节点的主要职责,是按照AleoBFT的规则产生新的块。 - -在Aleo P2P Network中,除了Client 和 Prover之间会通过P2P互相连接之外,Client和Prover也会连接一定数量的Validator节点,以获取共识网络中最新块以及状态信息。 - -### Client - -Client节点的主要职责,是同步来自共识网络产生的块并更新账本信息。用户可以通过Client的RPC来访问当前Aleo网络的最新状态信息,也可以通过RPC来将Transaction广播到网络中。当共识网络产生的新的块包含Transaction,则意味着Transaction被成功的执行了。 - -### Prover - -Prover节点的主要职责,是同步来自共识网络产生的CoinbasePuzzle,并运行CoinbasePuzzle的算法得到满足要求的Solution,然后通过P2P网络广播给共识网络,当共识网络产生的新的块中包含这个Solution,Solution对应的Prover会获得相应的CoinbaseReward奖励。 - diff --git a/documentation updates aleo ambassadors/src/learn/network/provers_zh.md b/documentation updates aleo ambassadors/src/learn/network/provers_zh.md deleted file mode 100644 index 0e8b5565a..000000000 --- a/documentation updates aleo ambassadors/src/learn/network/provers_zh.md +++ /dev/null @@ -1,40 +0,0 @@ -# Provers - - - -### Prover在网络中扮演的角色 - -Prover是Aleo网络中的一个重要组成部分,它不参与到Aleo的网络共识中。Prover运行特定的算法,通过求解*CoinbasePuzzle*得到满足*ProofTarget*的*ProverSolution*,然后广播,当*ProverSolution*被验证者节点确认并被打包到区块中时,Prover可以获得相应的*CoinbaseReward*奖励。 - - - -### Prover的经济激励 - -从长期的角度来看,Prover能够获得的*CoinbaseReward*的奖励与它的算力在整个网络中的占比成正比。Prover的经济激励与Bitcoin中的PoW相类似,不同点在于Aleo网络中并不是赢家通吃的策略,*ProverSolution*只要满足*ProofTarget*就可以被网络接受,这样的方式使得Prover获得的奖励更加公平和稳定。值得注意的是,与Validator的*BlockReward*不同,*CoinbaseReward*会随着时间而递减,每年的产出会缩减10%,直到10年后,将不再有*CoinbaseReward*奖励。 - -用户可以通过[浏览器](https://testnet3.aleoscan.io)来查看CoinbaseReward、BlockReward、以及PuzzleReward。 - -> PuzzleReward = CoinbaseReward * 2 / 3 -> -> BlockReward = 23.8 + CoinbaseReward * 1 / 3 -> -> 其中: -> -> BlockReward的奖励由Validator根据质押占比进行分配 -> -> PuzzleReward的奖励由Prover提交的Solution的ProofTarget的占比进行分配 - - - -### CoinbasePuzzle - -Aleo网络中每360个区块组成一个Epoch,当新的Epoch产生时,CoinbasePuzzle也会发生相应的变化,如果Prover依然在计算旧的CoinbasePuzzle,则其计算出的ProverSolution不会再被网络接收。这意味着Prover需要监听共识网络的区块变化,当新的Epoch产生时,更新当前的CoinbasePuzzle信息。 - -除了要求ProverSolution是合法的之外,网络还要求ProverSolution满足大于等于ProofTarget。ProofTarget是用来衡量Prover的工作量的,类似于PoW,ProofTarget越大,Prover所需要进行的计算的工作就越大。Aleo网络会根据当前参与到网络中Prover的算力来调整ProofTarget,当参与到网络中的算力增加时,网络会增大ProofTarget来保证网络中不会出现过多的ProverSolution,防止网络拥堵和大量的ProverSolution没有办法呗打包的情况。 - - - -### 如何成为Prover节点 - -成为Prover节点不需要质押和授权,任何人都可以启动一个Prover节点。 - diff --git a/documentation updates aleo ambassadors/src/learn/network/validators_zh.md b/documentation updates aleo ambassadors/src/learn/network/validators_zh.md deleted file mode 100644 index 6fdd33dc6..000000000 --- a/documentation updates aleo ambassadors/src/learn/network/validators_zh.md +++ /dev/null @@ -1,45 +0,0 @@ -# Validators - -1.验证者节点在网络中的角色以及作用 - -Aleo Validators之间组成一个共识网络,并通过AleoBFT共识协议来决定区块的生成。Validator通过质押Aleo Credits来获得投票权(节点的投票权与质押的Aleo Credits的数量成正比),AleoBFT保证了:当一个新的区块被生成时,这个区块至少获得了超过2/3的投票,这意味着网络中诚实的Validators已经对这个区块达成一致意见,这有效保证了网络的安全,阻止了恶意节点的攻击。区块一旦形成,便认为是达到了最终确定性,区块以及包含的交易将不会被回滚。 - - - - - -2.验证者节点的经济激励 - -AleoBFT的机制保证了如果一个恶意的节点想要攻击网络,则至少需要获得超过1/3的投票权才能阻止新的区块的产生。这意味着,当网络中中质押的Aleo Credits越多时,共识网络会越安全。为了激励验证者节点质押自己的Aleo Credits,当每个区块被产生时,区块中会包含给验证者节点相应的BlockReward奖励。Validator节点获得BlockReward的奖励占比与它质押的Aleo Credits的占比相等。(TODO: Add Link) - - - -3.如何成为验证者节点? - -在Aleo主网上线时,将会拥有10个初始的Validator节点,随后用户可以通过质押至少10,000,000(一百万)的Aleo Credits。当质押的交易请求被共识网络接受之后,新的验证者节点可以立马参与到共识中,并获得BlockReward奖励,这得益于AleoBFT对Narwhal Bullshark所进行的改进。 - -由于网络中的验证者节点在运行的过程中,会通过相互的通信来获得彼此的状态信息,这意味着网络中的验证者节点越多,需要的网络通信的数量级就越大,通信复杂度为O(n)。通信复杂度的上升会导致区块产生的时间延长,在Aleo网络中限制了验证者节点的最大数量为200,以此来平衡去中心化与网络效率。 - -当我们只有少量的Aleo Credits时,虽然我们不能成为独立的验证者节点,但是我们可以通过委托质押的方式来获得BlockReward奖励。 - - - -4.什么是委托质押? - -委托质押是指用户可以通过Program(Aleo的智能合约)将Aleo Credits质押在某个Validator节点上,质押的AleoCredits所得到的投票权也会委托给相应的Validator节点。用户可以获得线性比例的BlockReward奖励,Validator可以通过Program的设置收取一定比例的Fee。XXX(TODO:ADD Link)钱包、浏览器为用户提供了委托质押的功能,用户可以在他们提供的UI界面上看到各个Validator的Fee比例,方便地完成质押。 - -用户也可以随时取消质押,取消质押后的360个区块之后,用户可以将取消质押返还的Aleo Credits提取到余额中。 - - - -5.Transaction和Solution被验证者节点确认的过程 - -![image-20240422165659999](./images/validator-process-transaction.png) - -- Transaction/Solution通过P2P网络或者RPC进入到验证者节点的的消息池 -- 验证者节点将从消息池中选出一些Transactions/Solutions放入到BatchPropose(除了Transactions和Solutions,BatchPropose需要包含前一个轮次的2f + 1个BatchCertificate),并广播给其他的验证者节点。 -- 其他的验证者节点在收到BatchPropose并确保它的合法性之后,会对该BatchPropose进行签名得到BatchSignature,并将BatchSignature返回给该验证者节点。 -- 当验证者节点收到超过2f + 1的BatchSignature之后,将其聚合成为一个BatchCertificate,并广播给其他的验证者节点。 -- 所有的节点都会执行并重复这个过程,产生的BatchCertificate构成一个DAG。当DAG被Commit后,新的区块产生,Transaction和Solution都会被包含在新的区块中。 - -![Illustration_DAG](./images/Illustration_DAG.png) diff --git a/documentation updates aleo ambassadors/src/overview.md b/documentation updates aleo ambassadors/src/overview.md deleted file mode 100644 index 07dd0c5c7..000000000 --- a/documentation updates aleo ambassadors/src/overview.md +++ /dev/null @@ -1 +0,0 @@ -# Overview From ff01dc7071ab985bdbe03dfb4bff0e4e22b20728 Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Wed, 10 Jul 2024 20:06:20 -0700 Subject: [PATCH 03/18] Integrate SDK doc updates --- .../aleo-sdk/create-aleo-app/installation.md | 32 - .../leo/aleo-sdk/js-ts/aleo-network-client.md | 364 ----- .../src/build/leo/aleo-sdk/js-ts/guide.md | 1187 ----------------- .../create-aleo-app/00_app_installation.md | 17 +- .../sdk/typescript/00_sdk_overview.md | 412 +++--- .../sdk/typescript/02_aleo_network_client.md | 123 +- 6 files changed, 331 insertions(+), 1804 deletions(-) delete mode 100644 documentation updates aleo ambassadors/src/build/leo/aleo-sdk/create-aleo-app/installation.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts/aleo-network-client.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts/guide.md diff --git a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/create-aleo-app/installation.md b/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/create-aleo-app/installation.md deleted file mode 100644 index b0d432174..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/create-aleo-app/installation.md +++ /dev/null @@ -1,32 +0,0 @@ -# Create Aleo App -# Installation - - Create Aleo App - -## Scaffolding Your First Aleo Project - -:::note -**Compatibility:** -[Node.js](https://nodejs.org/en/) version 18+ -::: - -With NPM: - -```bash -npm create aleo-app@latest -``` - -1. Enter the project name. -2. This will prompt you to choose a preferred framework from the following options: - - `React` - - `Node.js` - - `Vanilla (JavaScript)` - -3. If you choose `React` as your framework, the supported templates are: - - `JavaScript` + `Leo` - - `TypeScript` + `Leo` - - `TypeScript` + `Next.js` - -## More Information - -Based on create-vite: https://github.com/vitejs/vite/tree/main/packages/create-vite diff --git a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts/aleo-network-client.md b/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts/aleo-network-client.md deleted file mode 100644 index 7c0b23633..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts/aleo-network-client.md +++ /dev/null @@ -1,364 +0,0 @@ -# Aleo Network Client - - - -## Overview -

Connection management class that encapsulates REST calls to publicly exposed endpoints of Aleo nodes. -The methods provided in this class provide information on the Aleo Blockchain

- -**Kind**: global class - -* [AleoNetworkClient](#AleoNetworkClient) - * [new AleoNetworkClient(host)](#new_AleoNetworkClient_new) - * [.setAccount(host)](#AleoNetworkClient+setHost) - * [.setAccount(account)](#AleoNetworkClient+setAccount) - * [.getAccount()](#AleoNetworkClient+getAccount) - * [.getBlock(height)](#AleoNetworkClient+getBlock) - * [.getBlockRange(start, end)](#AleoNetworkClient+getBlockRange) - * [.getProgram(programId)](#AleoNetworkClient+getProgram) - * [.getProgramObject(programId)](#AleoNetworkClient+getProgramObject) - * [.getProgramImports(programId)](#AleoNetworkClient+getProgramImports) - * [.getDeploymentTransactionIDForProgram(programId)](#AleoNetworkClient+getDeploymentTransactionIDForProgram) - * [.getDeploymentTransactionForProgram(programId)](#AleoNetworkClient+getDeploymentTransactionForProgram) - * [.getProgramMappingNames(programId)](#AleoNetworkClient+getProgramMappingNames) - * [.getMappingValue(programId, mappingName, key)](#AleoNetworkClient+getMappingValue) - * [.getLatestBlock()](#AleoNetworkClient+getLatestBlock) - * [.getLatestHeight()](#AleoNetworkClient+getLatestHeight) - * [.getStateRoot()](#AleoNetworkClient+getStateRoot) - * [.getTransaction(id)](#AleoNetworkClient+getTransaction) - * [.getTransactions(height)](#AleoNetworkClient+getTransactions) - * [.getTransactionsInMempool()](#AleoNetworkClient+getTransactionsInMempool) - * [.getTransitionId()](#AleoNetworkClient+getTransitionId) - * [.findUnspentRecords()](#AleoNetworkClient+findUnspentRecords) - - - -### new AleoNetworkClient(host) - -| Param | Type | -| --- | --- | -| host | string | - -**Example** -```js -// Connection to a local node -let local_connection = new AleoNetworkClient("http://localhost:3030"); - -// Connection to a public beacon node -let public_connection = new AleoNetworkClient("https://api.explorer.aleo.org/v1"); -``` - - -### aleoNetworkClient.setHost(host) -

Set a new host for the networkClient

- -| Param | Type | -| --- | --- | -| host | string | - -**Example** -```js -// New connection to a public beacon node -let public_connection = AleoNetworkClient.setHost("https://api.explorer.aleo.org/v1"); -``` - - -### aleoNetworkClient.setAccount(account) -

Set an account

- -**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) - -| Param | Type | -| --- | --- | -| account | Account | - -**Example** -```js -let account = new Account(); -connection.setAccount(account); -``` - - -### aleoNetworkClient.getAccount() -

Return the Aleo account used in the node connection

- -**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) -**Example** -```js -let account = connection.getAccount(); -``` - - -### aleoNetworkClient.getBlock(height) -

Returns the block contents of the block at the specified block height

- -**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) - -| Param | Type | -| --- | --- | -| height | number | - -**Example** -```js -let block = connection.getBlock(1234); -``` - - -### aleoNetworkClient.getBlockRange(start, end) -

Returns a range of blocks between the specified block heights

- -**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) - -| Param | Type | -| --- | --- | -| start | number | -| end | number | - -**Example** -```js -let blockRange = connection.getBlockRange(2050, 2100); -``` - - -### aleoNetworkClient.getProgram(programId) -

Returns the source code of a program

- -**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) - -| Param | Type | -| --- | --- | -| programId | string | - -**Example** -```js -let program = connection.getProgram("foo.aleo"); -``` - - - -### aleoNetworkClient.getProgramObject(programId) -

Returns a program object from a program ID or program source code

- -**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) - -| Param | Type | -| --- | --- | -| programId | string | - -**Example** -```js -let program = connection.getProgramObject("foo.aleo"); -``` - - - -### aleoNetworkClient.getProgramImports(programId) -

Returns an object containing the source code of a program and the source code of all programs it imports

- -**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) - -| Param | Type | -| --- | --- | -| programId | string | - -**Example** -```js -let program = connection.getProgramImports("foo.aleo"); -``` - - - -### aleoNetworkClient.getDeploymentTransactionIDForProgram(programId) -

Returns the deployment transaction id associated with the specified program

- -**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) - -| Param | Type | -| --- | --- | -| programId | string | - -**Example** -```js -let program = connection.getDeploymentTransactionIDForProgram("foo.aleo"); -``` - - - -### aleoNetworkClient.getDeploymentTransactionForProgram(programId) -

Returns the deployment transaction associated with a specified program

- -**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) - -| Param | Type | -| --- | --- | -| programId | string | - -**Example** -```js -let program = connection.getDeploymentTransactionForProgram("foo.aleo"); -``` - - - -### aleoNetworkClient.getProgramMappingNames(programId) -

Returns the names of the mappings of a program

- -**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) - -| Param | Type | -| --- | --- | -| programId | string | - -**Example** -```js -let mappings = connection.getProgramMappingNames("credits.aleo"); -``` - - - -### aleoNetworkClient.getProgramImportNames(programId) -

Get a list of the program names that a program imports

- -**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) - -| Param | Type | -| --- | --- | -| programId | string | - -**Example** -```js -let mappings = connection.getProgramImportNames("foo.aleo"); -``` - - - -### aleoNetworkClient.getMappingValue(programId, mappingName, key) -

Returns the value of a program's mapping for a specific key

- -**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) - -| Param | Type | -| --- | --- | -| programId | string | -| mappingName | string | -| key | string | - -**Example** -```js -## Get public balance of an account -let mappingValue = connection.getMappingValue("credits.aleo", "account", "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px"); -``` - - -### aleoNetworkClient.getLatestBlock() -

Returns the block contents of the latest block

- -**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) -**Example** -```js -let latestHeight = connection.getLatestBlock(); -``` - - - -### aleoNetworkClient.getLatestHeight() -

Returns the latest block height

- -**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) -**Example** -```js -let latestHeight = connection.getLatestHeight(); -``` - - - -### aleoNetworkClient.getLatestCommittee() -

Returns the latest committee

- -**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) -**Example** -```js -let latestCommittee = connection.getLatestCommittee(); -``` - - -### aleoNetworkClient.getStateRoot() -

Returns the latest state/merkle root of the Aleo blockchain

- -**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) -**Example** -```js -let stateRoot = connection.getStateRoot(); -``` - - -### aleoNetworkClient.getTransaction(id) -

Returns a transaction by its unique identifier

- -**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) - -| Param | Type | -| --- | --- | -| id | string | - -**Example** -```js -let transaction = connection.getTransaction("at1handz9xjrqeynjrr0xay4pcsgtnczdksz3e584vfsgaz0dh0lyxq43a4wj"); -``` - - - -### aleoNetworkClient.getTransactions(height) -

Returns the transactions present at the specified block height

- -**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) - -| Param | Type | -| --- | --- | -| height | number | - -**Example** -```js -let transactions = connection.getTransactions(654); -``` - - -### aleoNetworkClient.getTransactionsInMempool() -

Returns the transactions in the memory pool.

- -**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) -**Example** -```js -let transactions = connection.getTransactionsInMempool(); -``` - - -### aleoNetworkClient.getTransitionId() -

Returns the transition id by its unique identifier

- -**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) -**Example** -```js -let transition = connection.getTransitionId("2429232855236830926144356377868449890830704336664550203176918782554219952323field"); -``` - - -### aleoNetworkClient.findUnspentRecords() -

Attempts to find unspent records in the Aleo blockchain for a specified private key

- -**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) -**Example** -```js -// Find all unspent records -const privateKey = "[PRIVATE_KEY]"; -let records = connection.findUnspentRecords(0, undefined, privateKey); - -// Find specific amounts -const startHeight = 500000; -const amounts = [600000, 1000000]; -let records = connection.findUnspentRecords(startHeight, undefined, privateKey, amounts); - -// Find specific amounts with a maximum number of cumulative microcredits -const maxMicrocredits = 100000; -let records = connection.findUnspentRecords(startHeight, undefined, privateKey, undefined, maxMicrocredits); -``` diff --git a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts/guide.md b/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts/guide.md deleted file mode 100644 index f65662a5f..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/aleo-sdk/js-ts/guide.md +++ /dev/null @@ -1,1187 +0,0 @@ -# Javascript/Typescript - - - - Aleo SDK - - - - -## Tools for Building Zero Knowledge Web Apps - -The Aleo SDK is a collection of JavaScript libraries for building zero knowledge web applications in both the browser -and node.js. - -## Overview - -Aleo provides the ability to run programs in zero knowledge. The Aleo SDK provides the tools to use these programs -within the browser and all other levels of the web stack to build privacy preserving applications. - -The Aleo SDK provides the following functionality (Click to see examples): -1. [Aleo account management](https://provable.tools/account) -2. [Web-based program execution and deployment](https://provable.tools/develop) -3. [Aleo credit transfers](https://provable.tools/transfer) -4. [Management of program state and data](https://provable.tools/record) -5. [Communication with the Aleo network](https://provable.tools/rest) - -## Table of Contents - -* [Installation](#Installation) -* [Usage](#Usage) - * [Zero Knowledge Web App Examples](#Zero-Knowledge-Web-App-Examples) - * [Create Aleo App](#create-aleo-app) - * [Provable.tools](#provabletools) - * [Create An Aleo Account](#1-create-an-aleo-account) - * [Execute Aleo Programs](#2-execute-aleo-programs) - * [Aleo Programs](#21-aleo-programs) - * [Program Execution Model](#22-program-execution-model) - * [WebAssembly Initialization](#23-webassembly-initialization) - * [Local Program Execution](#24-local-program-execution) - * [Online Program Execution](#25-program-execution-on-the-aleo-network) - * [Program Proving Keys and Records](#26-program-proving-keys--program-records) - * [Deploy Programs](#27-deploy-a-new-program-to-the-aleo-network) - * [React Example](#28-react-example) - * [Aleo Credit Transfers](#3-aleo-credit-transfers) - * [Aleo Credits](#31-aleo-credits) - * [Transfer Aleo Credits](#32-transfer-aleo-credits) - * [Check Public Balances](#32-checking-public-balances) - * [Program Data and Private State](#4-managing-program-data-and-private-state) - * [Private State Data: Records](#41-private-state-data-records) - * [Record Usage Example](#42-record-usage-example-private-value-transfers) - * [Public State Data: Mappings](#43-public-state-data-mappings) - * [Reading Mappings](#44-reading-mappings) - * [Initializing and Updating Mappings](#45-initializing--updating-mappings) - * [Communicating with the Aleo Network](#5-communicating-with-the-aleo-network) -* [Further Documentation](#further-documentation) - -## Installation - -### NPM - -To install the Aleo SDK from NPM run: - -`npm install @aleohq/sdk` or `yarn add @aleohq/sdk`. - -### Build from source - -To build the project from source, go to this project's root and execute: - -`npm install && npm run build` - -## Usage - -## Zero Knowledge Web App Examples - -### Create Aleo App -A set of fully functional examples of zero knowledge web apps can be found in -[create-aleo-app](https://github.com/AleoHQ/sdk/tree/testnet3/create-aleo-app). Create-aleo-app provides several web-app -templates in common web frameworks such as React that can be used as a starting point for building zero knowledge web apps. - -Developers can get started immediately with create-react-app by running: -`npm create aleo-app@latest` - -### Provable.tools - -Additionally, the SDK powers [Provable.tools](https://provable.tools) - a React app that provides a graphical interface for most -of the functionality provided by the SDK and can be used as a reference for usage of the SDK. Source code for provable.tools -can be found [in the SDK repo here](https://github.com/AleoHQ/sdk/tree/testnet3/website) - -## 1. Create an Aleo Account - -The first step in operating a zero knowledge web application is creating a cryptographic identity for a user. In the -context of Aleo, this process starts by generating a private key. From this private key, several keys that enable a user -to interact with Aleo programs can be derived. - -These keys include: -#### Private Key -The key used to represent an identity of an individual user. This key is used to authorize zero -knowledge program execution. -#### View Key -This key is derived from the private key and can be used to identify all records and transaction data that -belongs to an individual user. -#### Compute Key -A key that can be used to trustlessly run applications and generate transactions on a user's behalf. -#### Address -A public address that can be used to trustlessly identify a user in order for that user to receive official -Aleo credits or unique data defined by other zero-knowledge Aleo programs. - -All of these keys can be created using the account object: -```typescript -import { Account } from '@aleohq/sdk'; - -const account = new Account(); - -// Individual keys can then be accessed through the following methods -const privateKey = account.privateKey(); -const viewKey = account.viewKey(); -const address = account.address(); -``` - -Please note that all keys are considered sensitive information and should be stored securely. - -## 2. Execute Aleo Programs - -### 2.1 Aleo Programs - -Aleo programs provide the ability for users to make any input or output of a program private and prove that the program -was run correctly. Keeping program inputs and outputs private allows developers to build privacy into their applications. - -Zero-Knowledge programs are written in one of two languages: -1. [Leo](https://developer.aleo.org/leo/language): A high level, developer friendly language for developing - zero knowledge programs. -2. [Aleo Instructions](https://developer.aleo.org/aleo/): A low level language that provides developers fine - grained control over the execution flow of zero knowledge programs. Leo programs are compiled into Aleo Instructions - under the hood. - -Documentation for both languages can be found at [developer.aleo.org](https://developer.aleo.org). - -#### Hello world in the Leo Language -``` -// A simple program adding two numbers together -program helloworld.aleo { - transition hello(public a: u32, b: u32) -> u32 { - let c: u32 = a + b; - return c; - } -} -``` - -#### Hello world in Aleo instructions -``` -program helloworld.aleo; - -// The leo code above compiles to the following Aleo instructions -function hello: - input r0 as u32.public; - input r1 as u32.private; - add r0 r1 into r2; - output r2 as u32.private; -``` - -### 2.2 Program Execution Model - -The SDK provides the ability to execute Aleo Instructions programs %100 client-side within the browser. - -The `ProgramManager` object encapsulates the functionality for executing programs and making zero knowledge proofs about -them. Under the hood it uses cryptographic code compiled from [snarkVM](https://developer.aleo.org/aleo) into WebAssembly. -JavaScript bindings to this WebAssembly code allows execution of programs in zero knowledge fully within the browser -without requiring any external communication with the internet. Users interested in lower level details on how this is -achieved can visit the [aleo-wasm](https://github.com/AleoHQ/sdk/tree/testnet3/wasm) crate. - -The basic execution flow of a program is as follows: -1. A web app is loaded with an instance of the `ProgramManager` object -2. An Aleo program in `Aleo Instructions` format is loaded into the `ProgramManager` as a wasm object -3. The web app provides a user input form for the program -4. The user submits the inputs and the zero knowledge execution is performed client-side within WebAssembly -5. The result is returned to the user -6. (Optional) A fully encrypted zero knowledge transcript of the execution is optionally sent to the Aleo network - -A diagrammatic representation of the program execution flow is shown below. -```mermaid -graph LR - p1[Leo Program] - p2[Aleo Instructions] - - subgraph Browser Web-App - subgraph ProgramManager - subgraph Aleo-Wasm-Module - in-memory-program - end - end - end - - p1-->p2--load program--oin-memory-program-.ZK result.->user - user-.user input.->in-memory-program - in-memory-program-."ZK result (Optional)".->Aleo-Network -``` - -### 2.3 WebAssembly Initialization - -❗WebAssembly must be initialized before calling any SDK functions. The current Aleo SDK manages the wasm initialization. Therefore, the workers must be defined properly. - -Aleo programs are made zero knowledge through the usage of `ZkSnarks`. The Rust code behind Aleo programs and the ZkSnarks -that make them zero knowledge are hosted in the [snarkVM Repository](https://github.com/AleoHQ/SnarkVM). The Aleo SDK -compiles this code to WebAssembly and creates JavaScript bindings, enabling Aleo programs to run directly in the browser. - -Before any logic within the SDK is run within the browser however, the WebAssembly module the SDK contains must be -initialized before any SDK functions can be executed. This is done simply by calling the `initializeWasm` function at a -point in your code before any other SDK functions are called: -```typescript -import { Account, initializeWasm } from '@aleohq/sdk'; - -// Assuming top-level await is enabled. This can also be initialized within a promise. -await initializeWasm(); - -/// Create a new Aleo account -const account = new Account(); -```` - -An example of how to initialize WebAssembly in a React app is shown in [Section 2.8](#28-React-Example) - -### 2.4 Local Program Execution -A simple example of running the hello world program within the web browser is shown below: -```typescript -import { Account, Program } from '@aleohq/sdk'; - -/// Create the source for the "hello world" program -const program = "program helloworld.aleo;\n\nfunction hello:\n input r0 as u32.public;\n input r1 as u32.private;\n add r0 r1 into r2;\n output r2 as u32.private;\n"; -const programManager = new ProgramManager(); - -/// Create a temporary account for the execution of the program -const account = new Account(); -programManager.setAccount(account); - -/// Get the response and ensure that the program executed correctly -const executionResponse = await programManager.executeOffline(program, "hello", ["5u32", "5u32"]); -const result = executionResponse.getOutputs(); -assert(result === ["10u32"]); -``` - -### 2.5 Program execution on the Aleo Network -The SDK also provides the ability to execute programs and record an encrypted transcript of the execution on the Aleo -network that anyone can trustlessly verify. - -This process can be thought of being executed in three steps: -1. A program is run locally -2. A proof that the program was executed correctly and that the outputs follow from the inputs is generated -3. A transcript of the proof is generated client-side containing encrypted proof data (see [Section 4](#4-managing-program-data-and-private-state)) - and any public outputs or state the user of the program wishes to reveal -4. The proof transcript is posted to the Aleo network and verified by the Aleo validator nodes in a trustless manner -5. If the proof is valid, it is stored and anyone can later verify the proof and read the outputs the author of the - program has chosen to make public. Private inputs will remain encrypted, but the author of the proof can also choose to - retrieve this encrypted state at any point and decrypt it locally for their own use. - -This process of posting the execution to the Aleo Network serves as a globally trustless and verifiable record of -program execution. It also provides a global record of any state changes made to either records or data stored on the Aleo network. - -A simple example of running the hello world program on the Aleo network is shown below: -```typescript - import { Account, AleoNetworkClient, NetworkRecordProvider, ProgramManager, KeySearchParams} from '@aleohq/sdk'; - -// Create a key provider that will be used to find public proving & verifying keys for Aleo programs -const keyProvider = new AleoKeyProvider(); -keyProvider.useCache = true; - -// Define an account which will execute the transaction on-chain -const account = new Account({ privateKey: private_key }); -const privateKeyObject = PrivateKey.from_string(private_key); - -// Create a record provider that will be used to find records and transaction data for Aleo programs -const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1"); -const recordProvider = new NetworkRecordProvider(account, networkClient); - -// Initialize a program manager to talk to the Aleo network with the configured key and record providers -const programName = "hello_hello.aleo"; -const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider); -programManager.setHost("https://api.explorer.aleo.org/v1") -programManager.setAccount(account); - -// For example: "cacheKey": "hello_hello:hello" -const cacheKey = `${programId}:${aleoFunction}`; -const keySearchParams = new AleoKeyProviderParams({ "cacheKey": cacheKey }); - -// Execute the program function -const executionResponse = await programManager.execute( - programId, - aleoFunction, - fee, - false, - inputs, - undefined, - keyParams, - undefined, - undefined, - undefined, - privateKeyObject - ); - -const transaction = await programManager.networkClient.getTransaction(executionResponse); - -``` - -A reader of the above example may notice the `RecordProvider` and `KeyProvider` classes that were not present in the local -execution example. The `KeyProvider` class helps users of the SDK find `Proving Keys` for programs. `Proving Keys` -allow zero knowledge proofs that the programs were executed correctly to be created. The `RecordProvider` class helps -find `Records` which are private data associated with programs that can be changed and updated throughout time. -These two concepts are explained in more detail below. - -### 2.6 Program Proving Keys & Program Records - -Executing Aleo programs in zero knowledge requires two additional pieces of information. - -1. **Function Proving & Verifying Keys:** Proving and Verifying keys are cryptographic keys that are generated when a - program function is executed. These keys are public and unique for each function in a program. The proving key allows any party to - execute the program and generate a proof that the program was executed correctly. The verifying keys allow any party - to verify that the proof was generated correctly and the execution is correct. These keys are required to create the - zero knowledge property of program execution. -2. **Program Records:** Records are private state generated by a program belonging to a unique private keyholder. Records - are generated by a program's functions and can be changed and updated by when a user runs various functions of the - program. These records are private by default and are used to manage updatable private state. One of the most clear - usages of records is to the `credits` record in the `credits.aleo`. Credits records are one of two official ways of - representing Aleo credits on the Aleo Network and are used to pay all transaction fees on the network. More information - on Records can be found in the [Records](#41-private-state-data--records) section below. - -For this reason, all programs will need proving and verifying keys to operate and many functions in Aleo programs will -require records as inputs. To simplify the process of managing keys and records, the Aleo SDK provides two abstractions -for managing these concepts: - -1. **KeyProvider:** When programs execute, by default, they will synthesize the proving and verifying keys needed to - make a zero knowledge proof. However, these keys are large and expensive to generate. For this reason, applications may - want to store these keys and re-use them for future execution. The `KeyProvider` interface provides the ability for - users of the SDK to provide their own key storage and retrieval mechanism. The SDK provides a default implementation - of the `KeyProvider` interface via the `AleoKeyProvider` class. -2. **RecordProvider:** When programs execute, they will often need to find records that belong to a user. The - `RecordProvider` interface allows users of the SDK to implement their own record storage and retrieval mechanism. The - SDK provides a default implementation of the `RecordProvider` interface via the `NetworkRecordProvider` class which - searches the Aleo network for records uniquely belonging to a user. - -The `ProgramManager` class is capable of taking a `KeyProvider` and `RecordProvider` as arguments and will use them to -find the correct keys and records for a program execution. - -### 2.7 Deploy a new Program to the Aleo Network - -The Aleo Network contains a public registry of programs that can be executed by anyone. Any user can add an Aleo program -to the network (as long as it doesn't already currently exist) by paying a deployment fee in Aleo credits. The SDK -provides a simple interface for deploying programs to the Aleo network using the program manager. - -```typescript -import { Account, AleoNetworkClient, NetworkRecordProvider, ProgramManager, KeySearchParams} from '@aleohq/sdk'; - -// Create a key provider that will be used to find public proving & verifying keys for Aleo programs -const keyProvider = new AleoKeyProvider(); -keyProvider.useCache = true; - -// Create a record provider that will be used to find records and transaction data for Aleo programs -const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1"); -const recordProvider = new NetworkRecordProvider(account, networkClient); - -// Initialize a program manager to talk to the Aleo network with the configured key and record providers -const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider); - -// Define an Aleo program to deploy -const program = "program hello_hello.aleo;\n\nfunction hello:\n input r0 as u32.public;\n input r1 as u32.private;\n add r0 r1 into r2;\n output r2 as u32.private;\n"; - -// Define a fee to pay to deploy the program -const fee = 1.8; // 1.8 Aleo credits - -// Deploy the program to the Aleo network -const tx_id = await programManager.deploy(program, fee); - -// Verify the transaction was successful -const transaction = await programManager.networkClient.getTransaction(tx_id); -``` - -### 2.8 React Example - -The above concepts can be tied together in a concrete example of a React web app. This example can be installed in one -step by running: - -`npm create aleo-app@latest` - -#### Wasm Initialization - -The WASM module can be initialized within the browser. A common way of achieving this within a React App is using a React UseEffect hook. - -`aleo-wasm-hook.js` -```jsx -import { useEffect, useState } from "react"; -import * as sdk from "@aleohq/sdk"; - -await sdk.initializeWasm(); -export const useAleoWASM = () => { - const [aleoInstance, setAleoInstance] = useState(null); - - useEffect(() => { - if (aleoInstance === null) { - setAleoInstance(sdk); - } - }, []); // eslint-disable-line react-hooks/exhaustive-deps - return aleoInstance; -}; -```` -Once a hook for the WASM initialization is created, it can be used anywhere within the app. - -#### Program Execution - -Program execution is a computationally expensive process. For this reason, it is recommended to execute programs in -webworkers. - -We will have 2 main components for workers: -- worker.js -- AleoWorker.js (Manager for worker file) - -
-Example Web Worker Usage - -A worker file that performs the execution can be created as follows: -`worker.js` -```jsx -import { - Account, - ProgramManager, - PrivateKey, - initThreadPool, - AleoKeyProvider, - AleoNetworkClient, - NetworkRecordProvider, -} from "@aleohq/sdk"; -import { expose, proxy } from "comlink"; - -await initThreadPool(); - -async function localProgramExecution(program, aleoFunction, inputs) { - const programManager = new ProgramManager(); - - // Create a temporary account for the execution of the program - const account = new Account(); - programManager.setAccount(account); - - const executionResponse = await programManager.run( - program, - aleoFunction, - inputs, - false, - ); - return executionResponse.getOutputs(); -} - -async function getPrivateKey() { - const key = new PrivateKey(); - return proxy(key); -} - -async function deployProgram(program) { - const keyProvider = new AleoKeyProvider(); - keyProvider.useCache(true); - - // Create a record provider that will be used to find records and transaction data for Aleo programs - const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1"); - - // Use existing account with funds - const account = new Account({ - privateKey: "user1PrivateKey", - }); - - const recordProvider = new NetworkRecordProvider(account, networkClient); - - // Initialize a program manager to talk to the Aleo network with the configured key and record providers - const programManager = new ProgramManager( - "https://api.explorer.aleo.org/v1", - keyProvider, - recordProvider, - ); - - programManager.setAccount(account); - - // Define a fee to pay to deploy the program - const fee = 1.9; // 1.9 Aleo credits - - // Deploy the program to the Aleo network - const tx_id = await programManager.deploy(program, fee); - - return tx_id; -} - -const workerMethods = { localProgramExecution, getPrivateKey, deployProgram }; -expose(workerMethods); -``` - -`AleoWorker.js` -```jsx -import { wrap } from "comlink"; - -let singletonWorker = null; - -const AleoWorker = () => { - if (!singletonWorker) { - const worker = new Worker(new URL("worker", import.meta.url), { - type: "module", - }); - - worker.onerror = function(event) { - console.error("Error in worker: " + event?.message); - }; - - singletonWorker = wrap(worker); - } - return singletonWorker; -}; - -export { AleoWorker }; -``` -
- -Using both WebWorkers and SDK initialization in React, a single-page app can be created by importing `AleoWorker.js`, which executes Aleo zero-knowledge programs. - -
-Example App.jsx Implementing Zero Knowledge Program Execution - -```jsx -import { useState } from "react"; -import reactLogo from "./assets/react.svg"; -import aleoLogo from "./assets/aleo.svg"; -import "./App.css"; -import helloworld_program from "../helloworld/build/main.aleo?raw"; -import { AleoWorker } from "./workers/AleoWorker"; - -const aleoWorker = AleoWorker(); -function App() { - const [count, setCount] = useState(0); - const [account, setAccount] = useState(null); - const [executing, setExecuting] = useState(false); - const [deploying, setDeploying] = useState(false); - - const generateAccount = async () => { - const key = await aleoWorker.getPrivateKey(); - setAccount(await key.to_string()); - }; - - async function execute() { - setExecuting(true); - const result = await aleoWorker.localProgramExecution( - helloworld_program, - "main", - ["5u32", "5u32"], - ); - setExecuting(false); - - alert(JSON.stringify(result)); - } - - async function deploy() { - setDeploying(true); - try { - const result = await aleoWorker.deployProgram(helloworld_program); - console.log("Transaction:") - console.log("https://api.explorer.aleo.org/v1/transaction?id=" + result) - alert("Transaction ID: " + result); - } catch (e) { - console.log(e) - alert("Error with deployment, please check console for details"); - } - setDeploying(false); - } - - return ( - <> -
- - Aleo logo - - - React logo - -
-

Aleo + React

-
- -

- -

-

- -

-

- Edit src/App.jsx and save to test HMR -

-
- - {/* Advanced Section */} -
-

Advanced Actions

-

- Deployment on Aleo requires certain prerequisites like seeding your - wallet with credits and retrieving a fee record. Check README for more - details. -

-

- -

-
-

- Click on the Aleo and React logos to learn more -

- - ); -} - -export default App; -``` - -
- -#### Integrating Aleo Programs Into Your App - -If you are starting with a simple framework template rather than with Aleo templates, handling files with a .aleo extension in a web application requires specific configurations because these files are not natively recognized by most web development environments. The .aleo extension typically belongs to Aleo zero-knowledge programs, which are special scripts or codes used within the Aleo platform to ensure privacy and security through cryptographic proofs. - -To integrate these files into a web application, such as a React app, you need to define how they should be treated during the build process. - -**Configuration File** - -Adding configuration rules in your build system (like Vite, Webpack, or Next.js) is necessary to tell the build tool how to process these files. Using something like raw-loader in this configuration ensures that .aleo files are loaded as plain text. This step is essential because it converts the content of .aleo files into a usable format that your web application can execute or display. - -``` -module:{ - rules:[ - { - test: /\.aleo$/i, - use: 'raw-loader', - }, - ] -} -``` - -
-Handling .aleo Types in TypeScript -`config.d.ts` -If you are using TypeScript, you need to inform the TypeScript compiler about the type of content these files contain by declaring a module for *.aleo files: -``` -declare module '*.aleo' { - const content: string; - export default content; - } -``` -Make sure that you included custom types in your `tsconfig` file. - -
- - -A full example of this implementation can be found [here](https://github.com/AleoHQ/sdk/blob/testnet3/create-aleo-app/template-react-leo/src/App.jsx) - -## 3. Aleo Credit Transfers - -### 3.1 Aleo Credits - -The official token of operation of the Aleo Network are Aleo credits. Aleo credits are used to pay all fees for program -execution on the Aleo network. - - - -Aleo credits are defined in the [credits.aleo](https://explorer.aleo.org/program/credits.aleo) program. This program is -deployed to the Aleo Network and defines data structures representing Aleo credits and the functions used to manage them. - - - -There are two ways to hold Aleo credits. - -#### 1 - Private balances via credits.aleo records -The first method is owning a `credits` record which enables a participant in the Aleo -network to hold a private balance of Aleo credits. -``` -record credits: - owner as address.private; - microcredits as u64.private; -``` - -A user's total private credits balance will consist of all unspent `credits` records owned by the user with a nonzero -`microcredits` value. - -#### 2 - Public balances via credits.aleo account mapping -The second is by holding a `balance` in the `account` mapping in the `credits.aleo` program on the Aleo Network. - -``` -mapping account: - key owner as address.public; - value microcredits as u64.public; -``` - -The total public credits balance of a user is the value of account mapping at the user's address. Users can hold both private and public balances simultaneously. - -More information about `records` and `mappings` and how they related to private and public balances are explained in the -[Managing Program Data and Private State](#4-managing-program-data-and-private-state) section. - -### 3.2 Transfer Aleo Credits -The `ProgramManager` allows transfers of aleo credits via the `transfer` method. This function executes the credits.aleo -program under the hood. - -There are four transfer functions available. - -#### 1. transfer_private - -Takes a `credits` record of owned by the sender, subtracts an amount from it, and adds that amount -to a new record owned by the receiver. This function is %100 private and does not affect the `account` mapping. - -```mermaid -graph LR - user1--record1 \n owner: user1address \n balance: 10000u64-->t1[transfer_private] - user1--amount: 4000u64-->t1 - t1-.record2 \n owner: user1address \n amount: 6000u64.->user1 - t1--record3 \n owner: user2address \n balance: 4000u64-->user2 - -``` - -#### 2. transfer_private_to_public -Takes a `credits` record of owned by the sender, subtracts an amount from it, and adds -that amount to the `account` mapping of the receiver. This function is %50 private and %50 public. It consumes a record -as a private input and generates a public balance in the `account` mapping entry belonging to the receiver. - -```mermaid -graph LR - subgraph credits.aleo - m1[account mapping \n key: user3address \n value: 3000u64] - end - user1--record3 \n owner: user2address \n balance: 4000u64-->t1[transfer_private_to_public] - t1-.record4 \n owner: user2address \n amount: 1000u64.->user1 - t1--amount 3000u64-->m1 -``` - -#### 3. transfer_public - -Subtracts an amount of `credits` stored in the `account` mapping of the `credits.aleo program`, and -adds that amount to the `account` mapping of the receiver. This function is 100% public and does not consume or generate -any records. - -```mermaid -graph LR - subgraph credits.aleo account mappings - state 2 - m3[account mapping \n key: user4address \n value: 3000u64] - m4[account mapping \n key: user3address \n value: 0u64] - end - - subgraph credits.aleo account mappings - state 1 - m2[account mapping \n key: user3address \n value: 3000u64]--transfer_public \n recipient: user4address \n amount: 3000u64-->m3 - m1[account mapping \n key: user4address \n value: N/A] - end -``` - -#### 4. transfer_public_to_private -Subtracts an amount `credits` stored in the `account` mapping of the `credits.aleo program` -and adds that amount to a new private record owned by the receiver. This function is %50 private and %50 public. -It publicly consumes a balance in the `account` mapping entry belonging to the sender and generates a private record -as a private output. - -```mermaid -graph LR - subgraph credits.aleo account mappings - state 2 - m2[account mapping \n key: user5address \n value: 0u64] - end - - subgraph credits.aleo account mappings - state 1 - m1[account mapping \n key: user5address \n value: 3000u64] - end - - m1--recipient: user6address \n amount: 3000u64-->transfer_public_to_private - transfer_public_to_private--record5 \n owner: user6address \n amount: 3000u64-->user6 -``` - -All four of these functions can be used to transfer credits between users via the `transfer` function in the -`ProgramManager` by specifying the transfer type as the third argument. - -```typescript -import { Account, ProgramManager, AleoKeyProvider, NetworkRecordProvider, AleoNetworkClient } from '@aleo/sdk'; - -// Create a new NetworkClient, KeyProvider, and RecordProvider -const account = Account.from_string({privateKey: "user1PrivateKey"}); -const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1"); -const keyProvider = new AleoKeyProvider(); -const recordProvider = new NetworkRecordProvider(account, networkClient); - -// Initialize a program manager with the key provider to automatically fetch keys for executions -const USER_1_ADDRESS = "user1Address"; -const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider); -programManager.setAccount(account); - -// Send a private transfer to yourself -const tx_id = await programManager.transfer(1, USER_1_ADDRESS, "transfer_private", 0.2); - -// Update or initialize a public balance in your own account mapping -const tx_id_2 = await programManager.transfer(1, USER_1_ADDRESS, "transfer_private_to_public", 0.2); - -// Check the value of your public balance -let public_balance = programManager.networkClient.getMappingValue("credits.aleo", USER_1_ADDRESS); -assert(public_balance === 0.2*1_000_000); - -/// Send public transfer to another user -const USER_2_ADDRESS = "user2Address"; -const tx_id_3 = await programManager.transfer(1, USER_2_ADDRESS, "transfer_public", 0.1); - -// Check the value of the public balance and assert that it has been updated -public_balance = programManager.networkClient.getMappingValue("credits.aleo", USER_1_ADDRESS); -const user2_public_balance = programManager.networkClient.getMappingValue("credits.aleo", USER_1_ADDRESS); -assert(public_balance === 0.1*1_000_000); -assert(user2_public_balance === 0.1*1_000_000); - -/// Create a private record from a public balance -const tx_id_4 = await programManager.transfer(1, USER_1_ADDRESS, "transfer_public_to_private", 0.1); - -// Check the value of the public balance and assert that it has been updated -public_balance = programManager.networkClient.getMappingValue("credits.aleo", USER_1_ADDRESS); -assert(public_balance === 0); -``` - -### 3.2 Checking Public Balances -As shown above, a public balance of any address can be checked with `getMappingValue` function of the `NetworkClient`. - -```typescript -const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1"); -const USER_1_ADDRESS = "user1Address"; -const public_balance = networkClient.getMappingValue("credits.aleo", USER_1_ADDRESS); -``` - -## 4. Managing Program Data and Private State - -### 4.1 Private State Data: Records -Records in are analogous to concept of [UTXOs](https://en.wikipedia.org/wiki/Unspent_transaction_output). When a record is -created by a program, it can then be consumed later by the same program as an input to a function. Once a record is used -as input, it is considered consumed and cannot be used again. In many cases a new record will be created from the output -of the function. Records are private by default and are associated with a single Aleo program and a single private key -representing a user. - -### 4.2 Record Usage Example: Private Value Transfers - -A straightforward example of a usage of records in a program can be demonstrated by explaining the process of private -value transfers of official Aleo credits on the Aleo network. - - - -Aleo credits are the official token in which all on-chain execution and deployment fees are paid. Credits can be public -or private. Private credits are represented by the `credits` record in the [credits.aleo](https://explorer.aleo.org/programs/credits.aleo) -program. - - - -``` -record credits: - owner as address.private; - microcredits as u64.private; -``` - -Credits records contain an `owner` field representing the address which owns the record and a `microcredits` field -representing the amount of microcredits in the record. 1 credit is equal to 1,000,000 microcredits. - -An example of an Aleo function that both takes a record as input and outputs a record is the `transfer_private` function -of the `credits.aleo` program. This function takes a private `credits` record as input and outputs two new private `credits` -records as output (one that sends the credits to the recipient and one that sends the remaining credits to the sender). - -The source code for the `transfer_private` is: -``` -function transfer_private: - input r0 as credits.record; - input r1 as address.private; - input r2 as u64.private; - sub r0.microcredits r2 into r3; - cast r1 r2 into r4 as credits.record; - cast r0.owner r3 into r5 as credits.record; - output r4 as credits.record; - output r5 as credits.record; -``` - -The `transfer_private` function can be graphically represented by the graph below. In the graph the first record "Record 1" -is consumed and can never be used again. From the data in Record 1, two more records are created. One containing -the intended amount for the recipient which is now owned by the recipient and another containing the remaining credits -which is sent back to the sender. - -```mermaid -graph LR - User1[Sender Address] - i1[Input 1: Credits Record 1]-->p1 - i2[Input 2: Recipient Address]-->p1 - p1[Credits.aleo:transfer_private] - p1--Credits Record 2-->User1 - p1--Credits Record 3-->R1[Recipient Address] -``` - -This chain of ownership is tracked by the Aleo Blockchain when users choose to submit their transactions to the Aleo -Network. This allows other users who receive records to receive the updated data and verify that this data was -provably generated by the intended program. - -What this process allows is a private chain of state to be created between multiple users. In the context of value -transfers, a chain of state might look like the following: - -```mermaid -graph LR - user1--record1-->t1[transfer_private] - t1-.record2.->user1 - t1--record3-->user2 - user2--record3-->t2[transfer_private] - t2--record5-->user3 - t2-.record4.->user2 -``` - -The above state chain would be executed in the following way using the SDK: -#### Step 1 - User 1 sends a private value transfer to User 2 -```typescript -// USER 1 -import { Account, ProgramManager, AleoKeyProvider, NetworkRecordProvider, AleoNetworkClient } from '@aleo/sdk'; - -// Create a new NetworkClient, KeyProvider, and RecordProvider -const account = Account.from_string({privateKey: "user1PrivateKey"}); -const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1"); -const keyProvider = new AleoKeyProvider(); -const recordProvider = new NetworkRecordProvider(account, networkClient); - -// Initialize a program manager with the key provider to automatically fetch keys for executions -const USER_2_ADDRESS = "user2Address"; -const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider); -programManager.setAccount(account); - -/// Send private transfer to user 2 -const tx_id = await programManager.transfer(1, USER_2_ADDRESS, "transfer_private", 0.2); -``` - -#### Step 2 - User 2 receives the transaction ID and fetches the credits record they received from user 1 from the network. They then send it to user 3 - -```typescript -// USER 2 -import { Account, ProgramManager, AleoKeyProvider, NetworkRecordProvider, AleoNetworkClient } from '@aleo/sdk'; - -// Create a new NetworkClient, KeyProvider, and RecordProvider -const account = Account.from_string({privateKey: "user2PrivateKey"}); -const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1"); -const keyProvider = new AleoKeyProvider(); -const recordProvider_User2 = new NetworkRecordProvider(account, networkClient); - -// Initialize a program manager with the key provider to automatically fetch keys for executions -const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider); -programManager.setAccount(account); - -// Fetch the transaction from the network that user 1 sent -const transaction = await programManager.networkClient.getTransaction(tx_id); -const record = transaction.execution.transitions[0].outputs[0].value; - -// Decrypt the record with the user's view key -const recordCiphertext = RecordCiphertext.fromString(record); -const recordPlaintext = recordCiphertext.decrypt(account.viewKey()); - -// Send a transfer to user 3 using the record found above -const USER_3_ADDRESS = "user3Address"; -const tx_id = await programManager.transfer(1, USER_3_ADDRESS, "transfer_private", 0.2, undefined, recordPlaintext); -``` - -When an execution such as `transfer_private` consumes or generates a record is posted on the network and encrypted transcript -of the execution is posted, containing an encrypted version of the record output and a transaction ID. - -Because the records are encrypted when they're posted on the network, they do not reveal any information about the party -who executed the program, nor the contents of the record. The only information that is revealed is the program ID, -function name, encrypted function inputs, and the transaction ID of the program execution. No user except for the recipient -of the record can see the contents of the record. - -Below you can see what the exact data which is posted to the Aleo Network when `transfer_private` is run. Note that the -record, the amount transferred, and both the sender & recipient addresses are all encrypted. - -
-transfer_private Execution Transcript - -```json - "transactions": [ - { - "status": "accepted", - "type": "execute", - "index": 0, - "transaction": { - "type": "execute", - "id": "at1s7dxunms8xhdzgaxrwf0yvq2dqgxtf4a3j8g878rhfr0zwhap5gqywsw8y", - "execution": { - "transitions": [ - { - "id": "as1thy8fvkz0rkls5wnmfq5udrcvvzurq7mqk8pkhjf63htqjf9mugqp0mfhd", - "program": "credits.aleo", - "function": "transfer_private", - "inputs": [ - { - "type": "record", - "id": "1406044754369042876058586523429806531093330762697573675195902502647806778955field", - "tag": "242626059121157295593694555515381893342956813170338731374395259242800138642field" - }, - { - "type": "private", - "id": "1533599744296862879610225011439684001995294756698105572984689232395187168232field", - "value": "ciphertext1qgqgpu7m8p0rwjahwffyvm4g4n6903d6ufqty74z4504w4rn356hgp9jvpuvx8suu0pukr3sl7n8x65dz35nu4jdy4lgcguxldygufrfpyqd6xr5" - }, - { - "type": "private", - "id": "4081557229261486898857101724786348855190759711760925564309233047223407640812field", - "value": "ciphertext1qyqxd9wue0qh8hs6dgevn7zleedfkzf7pft8ecked2xq3pw54pgqzyqr69sgx" - } - ], - "outputs": [ - { - "type": "record", - "id": "1388064668770056715587596299070268626507043043686185311840561493640415146425field", - "checksum": "5376939704883651492329501631722578074516322228314928758786996843926470523116field", - "value": "record1qyqsq4r7mcd3ystjvjqda0v2a6dxnyzg9mk2daqjh0wwh359h396k7c9qyxx66trwfhkxun9v35hguerqqpqzqzshsw8dphxlzn5frh8pknsm5zlvhhee79xnhfesu68nkw75dt2qgrye03xqm4zf5xg5n6nscmmzh7ztgptlrzxq95syrzeaqaqu3vpzqf03s6" - }, - { - "type": "record", - "id": "4635504195534945632234501197115926012056789160185660629718795843347495373207field", - "checksum": "3428805926164481449334365355155755448945974546383155334133384781819684465685field", - "value": "record1qyqsp2vsvvfulmk0q0tmxq7p9pffhfhha9h9pxsftujh57kkjuahx9s0qyxx66trwfhkxun9v35hguerqqpqzq8etfmzt2elj37hkf9fen2m2qes8564sr8k970zyud5eqmq7ztzq5r3095mkfdzqzz7yp6qfavqsl3t22t6dvgauqqt2xqk98zwmtusq5ck7fm" - } - ], - "tpk": "5283803395323806407328334221689294196419052177553228331323093330938016699852group", - "tcm": "4398026033398688325681745841147300822741685834906186660771751747897598751646field" - } - ], -``` -
- - -#### Record Decryption - -If a user receives a private record from a program execution, they can use the SDK to decrypt encrypted records with -their view keys and view their contents. Only records that are owned by the user can be decrypted. Decryption of records -that are not owned by the user will fail. - -Record decryption and ownership verification can be done in the SDK using the following code: - -```typescript -import { Account, RecordCiphertext, RecordPlaintext } from '@aleo/sdk'; - -// Create an account from an existing private key -const account = Account.from_string({privateKey: "existingPrivateKey"}); - -// Record value received as a string from program output or found on the Aleo network -const record = "record1qyqsq4r7mcd3ystjvjqda0v2a6dxnyzg9mk2daqjh0wwh359h396k7c9qyxx66trwfhkxun9v35hguerqqpqzqzshsw8dphxlzn5frh8pknsm5zlvhhee79xnhfesu68nkw75dt2qgrye03xqm4zf5xg5n6nscmmzh7ztgptlrzxq95syrzeaqaqu3vpzqf03s6"; - -const recordCiphertext = RecordCiphertext.fromString(record); - -// Check ownership of the record. If the account is the owner, decrypt the record -if (RecordCiphertext.is_owner(account.viewKey())) { - // Decrypt the record with the account's view key - const recordPlaintext = recordCiphertext.decrypt(account.viewKey()); - - // View the record data - console.log(recordPlaintext.toString()); -} -``` - -### 4.3 Public State Data: Mappings -Mappings are simple key value stores defined in a program. They are represented by a key and a value each of a specified -type. They are stored directly within the Aleo blockchain and can be publicly read by any participant in the Aleo network. - -An example of a mapping usage is `account` mapping in the `credits.aleo` program. -``` -mapping account: - key owner as address.public; - value microcredits as u64.public; -``` - -The `account` mapping is used to store public credits balances on the Aleo network. It takes a public address as a key -and a public u64 value representing the number of microcredits owned by the address. - -Mappings within programs are identified by the `mapping` identifier. Any program where this keyword appears contains an -on-chain mapping. An example of a program that uses a mapping is shown below: -``` -program player_mapping_example.aleo - -// The mapping identifier representing a score -mapping score: - key player as address.public; - value score as u64.public; - -// The update score function -function update_score: - input r0 as address.public; - input r1 as u64.public; - -// The finalize code block will be executed by Aleo network nodes. -// When it runs it will update the value of the mapping. -finalize update_score: - input r0 as address.public; - input r1 as u64.public; - get.or_use score[r0] 0u64 into r2; - add r1 r2 into r3; - set r3 into account[r0]; -``` - -Note that the above function has a `finalize` identifier. This identifier is used to identify a portion of a function's -code that should be executed by nodes on the Aleo network. Program mappings are updated exclusively by code run by nodes -on the Aleo Network written in `finalize` blocks. - -### 4.4 Reading Mappings -Any state within a program mapping is public and can be read by any participant in the Aleo network. The `NetworkClient` -class provides the `getMapping` method to read the public mappings within a program and the `getMappingValue` method to -read the value of a specific key within a mapping. - -```typescript -import { AleoNetworkClient } from '@aleo/sdk'; - -const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1"); -const creditsMappings = networkClient.getMappings("credits.aleo"); -assert(creditsMappings === ["account"]); - -const publicCredits = networkClient.getMapping("credits.aleo", "[a valid aleo account with zero balance]"); -assert(publicCredits === "0u64"); -``` - -### 4.5 Initializing & Updating Mappings -Updating mappings is done by executing a program function on the Aleo network which has a finalize block that updates the -program's mapping. For instance the `transfer_public` function in the `credits.aleo` program updates the `account` -mapping (and thus a user's balance) when called. - -``` -// The public interface called by users -function transfer_public: - input r0 as address.public; - input r1 as u64.public; - finalize self.signer r0 r1; - -// The finalize block run by nodes on the Aleo network which update a user's public balance -finalize transfer_public: - input r0 as address.public; - input r1 as address.public; - input r2 as u64.public; - get.or_use account[r0] 0u64 into r3; - sub r3 r2 into r4; - set r4 into account[r0]; - get.or_use account[r1] 0u64 into r5; - add r5 r2 into r6; - set r6 into account[r1]; -``` - -From the perspective of the caller of the API, this is as simple as executing a normal Aleo function. Given the inputs -to a function with a finalize scope that updates a mapping are valid, the mapping will either be intialized or updated -by the Aleo network. All the user of the SDK must do is ensure that the inputs to the function are valid. - -If function inputs are Invalid, the Network will return an error, but the fee paid for the transaction will still be -consumed. So it is important to ensure that the inputs to a function are valid before executing it. - -A simple example of a mapping update can be shown by simply executing the 'transfer_public` as shown below. - -```typescript -import { Account, ProgramManager, AleoKeyProvider, NetworkRecordProvider, AleoNetworkClient } from '@aleo/sdk'; - -// Create a new NetworkClient, KeyProvider, and RecordProvider -const account = Account.from_string({privateKey: "user1PrivateKey"}); -const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1"); -const keyProvider = new AleoKeyProvider(); -const recordProvider = new NetworkRecordProvider(account, networkClient); - -// Initialize a program manager with the key provider to automatically fetch keys for executions -const RECIPIENT_ADDRESS = "user1Address"; -const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider); -programManager.setAccount(account); - -// Update or initialize a public balance -const tx_id = await programManager.transfer(1, RECIPIENT_ADDRESS, "transfer_private_to_public", 0.2); -``` - - -## 5. Communicating with the Aleo Network - -Communication with the Aleo network is done through the `AleoNetworkClient` class. This class provides methods to query -data from Aleo network nodes and submit transactions to the Aleo network. - -A full list of methods provided by the `AleoNetworkClient` class and usage examples can be found in the -[Network Client API documentation](https://developer.aleo.org/sdk/typescript/aleo_network_client). - -## Further Documentation - -API documentation for this package, the Leo Language, and Aleo instructions can be found on the [Aleo Developer Hub](https://developer.aleo.org/sdk/typescript/overview). - -To view the API documentation for this package locally, open `docs/index.html`. -To regenerate the documentation, run `npx jsdoc --configure jsdoc.json --verbose` diff --git a/documentation/sdk/create-aleo-app/00_app_installation.md b/documentation/sdk/create-aleo-app/00_app_installation.md index b72627c6d..c64255c35 100644 --- a/documentation/sdk/create-aleo-app/00_app_installation.md +++ b/documentation/sdk/create-aleo-app/00_app_installation.md @@ -19,14 +19,17 @@ With NPM: npm create aleo-app@latest ``` -Then follow the prompts! +1. Enter the project name. +2. This will prompt you to choose a preferred framework from the following options: + - `React` + - `Node.js` + - `Vanilla (JavaScript)` -Currently supported template presets include: -- `react` + `javascript` -- `react` + `javascript` + `leo` -- `node` + `javascript` -- `vanilla (javascript)` +3. If you choose `React` as your framework, the supported templates are: + - `JavaScript` + `Leo` + - `TypeScript` + `Leo` + - `TypeScript` + `Next.js` ## More Information -Based off of create-vite: https://github.com/vitejs/vite/tree/main/packages/create-vite +Based on create-vite: https://github.com/vitejs/vite/tree/main/packages/create-vite diff --git a/documentation/sdk/typescript/00_sdk_overview.md b/documentation/sdk/typescript/00_sdk_overview.md index 9a2cb296d..4206ce6ea 100644 --- a/documentation/sdk/typescript/00_sdk_overview.md +++ b/documentation/sdk/typescript/00_sdk_overview.md @@ -33,7 +33,7 @@ The Aleo SDK provides the following functionality (Click to see examples): * [Usage](#Usage) * [Zero Knowledge Web App Examples](#Zero-Knowledge-Web-App-Examples) * [Create Aleo App](#create-aleo-app) - * [Aleo.tools](#aleotools) + * [provable.tools](#provabletools) * [Create An Aleo Account](#1-create-an-aleo-account) * [Execute Aleo Programs](#2-execute-aleo-programs) * [Aleo Programs](#21-aleo-programs) @@ -83,7 +83,7 @@ templates in common web frameworks such as React that can be used as a starting Developers can get started immediately with create-react-app by running: `npm create aleo-app@latest` -### Aleo.tools +### Provable Tools Additionally, the SDK powers [provable.tools](https://provable.tools) - a React app that provides a graphical interface for most of the functionality provided by the SDK and can be used as a reference for usage of the SDK. Source code for provable.tools @@ -200,7 +200,7 @@ graph LR ### 2.3 WebAssembly Initialization -❗WebAssembly must be initialized before any SDK functions can be called. +❗WebAssembly must be initialized before calling any SDK functions. The current Aleo SDK manages the wasm initialization. Therefore, the workers must be defined properly. Aleo programs are made zero knowledge through the usage of `ZkSnarks`. The Rust code behind Aleo programs and the ZkSnarks that make them zero knowledge are hosted in the [snarkVM Repository](https://github.com/AleoHQ/SnarkVM). The Aleo SDK @@ -219,7 +219,7 @@ await initializeWasm(); const account = new Account(); ```` -An example of how to initialize WebAssembly in a React app is shown in [Section 2.7](#27-React-Example) +An example of how to initialize WebAssembly in a React app is shown in [Section 2.8](#28-React-Example) ### 2.4 Local Program Execution A simple example of running the hello world program within the web browser is shown below: @@ -247,7 +247,7 @@ network that anyone can trustlessly verify. This process can be thought of being executed in three steps: 1. A program is run locally 2. A proof that the program was executed correctly and that the outputs follow from the inputs is generated -3. A transcript of the proof is generated client-side containing encrypted proof data (see [Section 2.6](#4-managing-records-and-private-state)) +3. A transcript of the proof is generated client-side containing encrypted proof data (see [Section 4](#4-managing-program-data-and-private-state)) and any public outputs or state the user of the program wishes to reveal 4. The proof transcript is posted to the Aleo network and verified by the Aleo validator nodes in a trustless manner 5. If the proof is valid, it is stored and anyone can later verify the proof and read the outputs the author of the @@ -265,6 +265,10 @@ import { Account, AleoNetworkClient, NetworkRecordProvider, ProgramManager, KeyS const keyProvider = new AleoKeyProvider(); keyProvider.useCache = true; +// Define an account which will execute the transaction on-chain +const account = new Account({ privateKey: private_key }); +const privateKeyObject = PrivateKey.from_string(private_key); + // Create a record provider that will be used to find records and transaction data for Aleo programs const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1"); const recordProvider = new NetworkRecordProvider(account, networkClient); @@ -272,11 +276,30 @@ const recordProvider = new NetworkRecordProvider(account, networkClient); // Initialize a program manager to talk to the Aleo network with the configured key and record providers const programName = "hello_hello.aleo"; const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider); +programManager.setHost("https://api.explorer.aleo.org/v1") +programManager.setAccount(account); + +// For example: "cacheKey": "hello_hello:hello" +const cacheKey = `${programId}:${aleoFunction}`; +const keySearchParams = new AleoKeyProviderParams({ "cacheKey": cacheKey }); + +// Execute the program function +const executionResponse = await programManager.execute( + programId, + aleoFunction, + fee, + false, + inputs, + undefined, + keyParams, + undefined, + undefined, + undefined, + privateKeyObject + ); + +const transaction = await programManager.networkClient.getTransaction(executionResponse); -// Provide a key search parameter to find the correct key for the program if they are stored in a memory cache -const keySearchParams = { "cacheKey": "hello_hello:hello" }; -const tx_id = await programManager.execute(programName, "hello_hello", 0.020, ["5u32", "5u32"], undefined, undefined, undefined, keySearchParams); -const transaction = await programManager.networkClient.getTransaction(tx_id); ``` A reader of the above example may notice the `RecordProvider` and `KeyProvider` classes that were not present in the local @@ -360,8 +383,7 @@ step by running: #### Wasm Initialization -Before functionality from the SDK can be used, the WASM module must be initialized within the browser. A common way of -achieving this within a React App is using a React UseEffect hook. +The WASM module can be initialized within the browser. A common way of achieving this within a React App is using a React UseEffect hook. `aleo-wasm-hook.js` ```jsx @@ -387,240 +409,169 @@ Once a hook for the WASM initialization is created, it can be used anywhere with Program execution is a computationally expensive process. For this reason, it is recommended to execute programs in webworkers. +We will have 2 main components for workers: +- worker.js +- AleoWorker.js (Manager for worker file) +
Example Web Worker Usage A worker file that performs the execution can be created as follows: `worker.js` ```jsx -import * as aleo from "@aleohq/sdk"; - -// Web Workers contain their own WASM instance, so we initialize it separately from the main thread -await aleo.initializeWasm(); - -// Eight threads are then initialized to execute the program in parallel using multithreading -await aleo.initThreadPool(8); - -/// The program manager is initialized with a key provider and a record provider -const defaultHost = "https://api.explorer.aleo.org/v1"; -const keyProvider = new aleo.AleoKeyProvider(); -const recordProvider = new aleo.NetworkRecordProvider(new Account(), "https://api.explorer.aleo.org/v1"); -const programManager = new aleo.ProgramManager( - defaultHost, - keyProvider, - recordProvider, -); - -// The key provider is set to use an in-memory cache to store keys -keyProvider.useCache(true); - -self.postMessage({ - type: "ALEO_WORKER_READY", -}); - -// The program is executed when specific events are dispatched and then communicates the result to the main thread -// when execution has finished -let lastLocalProgram = null; -self.addEventListener("message", (ev) => { - if (ev.data.type === "ALEO_EXECUTE_PROGRAM_LOCAL") { - const {localProgram, aleoFunction, inputs, privateKey} = ev.data; - - console.log("Web worker: Executing function locally..."); - let startTime = performance.now(); - - (async function () { - try { - // Ensure the program is valid and that it contains the function specified - const program = programManager.createProgramFromSource(localProgram); - const program_id = program.id(); - if (!program.hasFunction(aleoFunction)) { - throw `Program ${program_id} does not contain function ${aleoFunction}`; - } - const cacheKey = `${program_id}:${aleoFunction}`; - - // Get the program imports - const imports = - programManager.networkClient.getProgramImports(localProgram); - - // Get the proving and verifying keys for the function - if (lastLocalProgram !== localProgram) { - const keys = programManager.executionEngine.synthesizeKeypair( - localProgram, - aleoFunction, - ); - programManager.keyProvider.cacheKeys(cacheKey, [ - keys.provingKey(), - keys.verifyingKey(), - ]); - lastLocalProgram = localProgram; - } - - // Pass the cache key to the execute function - const keyParams = new aleo.AleoKeyProviderParams({ - cacheKey: cacheKey, - }); - - // Execute the function locally - let response = await programManager.executeOffline( - localProgram, - aleoFunction, - inputs, - imports, - keyParams, - undefined, - undefined, - aleo.PrivateKey.from_string(privateKey), - ); - - // Return the outputs to the main thread - self.postMessage({ - type: "OFFLINE_EXECUTION_COMPLETED", - outputs, - }); - } catch (error) { - console.error(error); - self.postMessage({ - type: "ERROR", - errorMessage: error.toString(), - }); - } - })(); - } -}); -``` +import { + Account, + ProgramManager, + PrivateKey, + initThreadPool, + AleoKeyProvider, + AleoNetworkClient, + NetworkRecordProvider, +} from "@aleohq/sdk"; +import { expose, proxy } from "comlink"; + +await initThreadPool(); + +async function localProgramExecution(program, aleoFunction, inputs) { + const programManager = new ProgramManager(); + + // Create a temporary account for the execution of the program + const account = new Account(); + programManager.setAccount(account); + + const executionResponse = await programManager.run( + program, + aleoFunction, + inputs, + false, + ); + return executionResponse.getOutputs(); +} + +async function getPrivateKey() { + const key = new PrivateKey(); + return proxy(key); +} -The WebWorker can then be initialized in worker provider component which uses React effects +async function deployProgram(program) { + const keyProvider = new AleoKeyProvider(); + keyProvider.useCache(true); + // Create a record provider that will be used to find records and transaction data for Aleo programs + const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1"); + + // Use existing account with funds + const account = new Account({ + privateKey: "user1PrivateKey", + }); + + const recordProvider = new NetworkRecordProvider(account, networkClient); + + // Initialize a program manager to talk to the Aleo network with the configured key and record providers + const programManager = new ProgramManager( + "https://api.explorer.aleo.org/v1", + keyProvider, + recordProvider, + ); + + programManager.setAccount(account); + + // Define a fee to pay to deploy the program + const fee = 1.9; // 1.9 Aleo credits + + // Deploy the program to the Aleo network + const tx_id = await programManager.deploy(program, fee); + + return tx_id; +} + +const workerMethods = { localProgramExecution, getPrivateKey, deployProgram }; +expose(workerMethods); +``` + +`AleoWorker.js` ```jsx -import { useEffect, useState } from "react"; -import WorkerContext from "./WorkerContext"; +import { wrap } from "comlink"; -const WorkerProvider = ({ children }) => { - const [worker, setWorker] = useState(null); - const [workerReady, setWorkerReady] = useState(false); +let singletonWorker = null; - useEffect(() => { - let worker = new Worker(new URL("./worker.js", import.meta.url), { +const AleoWorker = () => { + if (!singletonWorker) { + const worker = new Worker(new URL("worker", import.meta.url), { type: "module", }); - setWorker(worker); - worker.onmessage = (event) => { - if (event.data.type === "ALEO_WORKER_READY") { - setWorkerReady(true); - } + worker.onerror = function(event) { + console.error("Error in worker: " + event?.message); }; - return () => { - worker.terminate(); - }; - }, []); - - if (!workerReady) { - return ( - <> -
-
-
- - ); + singletonWorker = wrap(worker); } - - return ( - - {children} - - ); + return singletonWorker; }; -export default WorkerProvider; +export { AleoWorker }; ``` -
-Using both webworkers and a wasm initialization in a React hook, a single page app can be created that executes -Aleo zero knowledge programs. +Using both WebWorkers and SDK initialization in React, a single-page app can be created by importing `AleoWorker.js`, which executes Aleo zero-knowledge programs.
Example App.jsx Implementing Zero Knowledge Program Execution - + ```jsx -import { useEffect, useState } from "react"; +import { useState } from "react"; import reactLogo from "./assets/react.svg"; -import aleoLogo from "./assets/aleo.png"; +import aleoLogo from "./assets/aleo.svg"; import "./App.css"; -import { useAleoWASM } from "./aleo-wasm-hook"; +import helloworld_program from "../helloworld/build/main.aleo?raw"; +import { AleoWorker } from "./workers/AleoWorker"; +const aleoWorker = AleoWorker(); function App() { const [count, setCount] = useState(0); - const aleo = useAleoWASM(); const [account, setAccount] = useState(null); - const [loading, setLoading] = useState(false); + const [executing, setExecuting] = useState(false); + const [deploying, setDeploying] = useState(false); - const generateAccount = () => { - setAccount(new aleo.PrivateKey()); + const generateAccount = async () => { + const key = await aleoWorker.getPrivateKey(); + setAccount(await key.to_string()); }; - const [worker, setWorker] = useState(null); - - useEffect(() => { - if (worker === null) { - const spawnedWorker = spawnWorker(); - setWorker(spawnedWorker); - return () => { - spawnedWorker.terminate(); - }; - } - }, []); - - function spawnWorker() { - return new Worker(new URL("workers/worker.js", import.meta.url), { - type: "module", - }); - } - - function postMessagePromise(worker, message) { - return new Promise((resolve, reject) => { - worker.onmessage = (event) => { - resolve(event.data); - }; - worker.onerror = (error) => { - reject(error); - }; - worker.postMessage(message); - }); - } - async function execute() { - const hello_hello_program = - "program hello_hello.aleo;\n" + - "\n" + - "function hello:\n" + - " input r0 as u32.public;\n" + - " input r1 as u32.private;\n" + - " add r0 r1 into r2;\n" + - " output r2 as u32.private;\n"; - - setLoading(true); - const result = await postMessagePromise(worker, { - type: "ALEO_EXECUTE_PROGRAM_LOCAL", - localProgram: hello_hello_program, - aleoFunction: "hello", - inputs: ["5u32", "5u32"], - privateKey: account.to_string(), - }); - setLoading(false); + setExecuting(true); + const result = await aleoWorker.localProgramExecution( + helloworld_program, + "main", + ["5u32", "5u32"], + ); + setExecuting(false); alert(JSON.stringify(result)); } + async function deploy() { + setDeploying(true); + try { + const result = await aleoWorker.deployProgram(helloworld_program); + console.log("Transaction:") + console.log("https://api.explorer.aleo.org/v1/transaction?id=" + result) + alert("Transaction ID: " + result); + } catch (e) { + console.log(e) + alert("Error with deployment, please check console for details"); + } + setDeploying(false); + } + return ( <>
- + Aleo logo - + React logo
@@ -632,21 +583,38 @@ function App() {

-

Edit src/App.jsx and save to test HMR

+ + {/* Advanced Section */} +
+

Advanced Actions

+

+ Deployment on Aleo requires certain prerequisites like seeding your + wallet with credits and retrieving a fee record. Check README for more + details. +

+

+ +

+

Click on the Aleo and React logos to learn more

@@ -656,6 +624,42 @@ function App() { export default App; ``` + +
+ +#### Integrating Aleo Programs Into Your App + +If you are starting with a simple framework template rather than with Aleo templates, handling files with a .aleo extension in a web application requires specific configurations because these files are not natively recognized by most web development environments. The .aleo extension typically belongs to Aleo zero-knowledge programs, which are special scripts or codes used within the Aleo platform to ensure privacy and security through cryptographic proofs. + +To integrate these files into a web application, such as a React app, you need to define how they should be treated during the build process. + +**Configuration File** + +Adding configuration rules in your build system (like Vite, Webpack, or Next.js) is necessary to tell the build tool how to process these files. Using something like raw-loader in this configuration ensures that .aleo files are loaded as plain text. This step is essential because it converts the content of .aleo files into a usable format that your web application can execute or display. + +``` +module:{ + rules:[ + { + test: /\.aleo$/i, + use: 'raw-loader', + }, + ] +} +``` + +
+Handling .aleo Types in TypeScript +`config.d.ts` +If you are using TypeScript, you need to inform the TypeScript compiler about the type of content these files contain by declaring a module for *.aleo files: +``` +declare module '*.aleo' { + const content: string; + export default content; + } +``` +Make sure that you included custom types in your `tsconfig` file. +
diff --git a/documentation/sdk/typescript/02_aleo_network_client.md b/documentation/sdk/typescript/02_aleo_network_client.md index 2e57e9731..1bb813cc3 100644 --- a/documentation/sdk/typescript/02_aleo_network_client.md +++ b/documentation/sdk/typescript/02_aleo_network_client.md @@ -13,15 +13,19 @@ The methods provided in this class provide information on the Aleo Blockchain

+ +### aleoNetworkClient.setHost(host) +

Set a new host for the networkClient

+ +| Param | Type | +| --- | --- | +| host | string | + +**Example** +```js +// New connection to a public beacon node +let public_connection = AleoNetworkClient.setHost("https://api.explorer.aleo.org/v1"); +``` ### aleoNetworkClient.setAccount(account) @@ -118,6 +136,71 @@ let blockRange = connection.getBlockRange(2050, 2100); ```js let program = connection.getProgram("foo.aleo"); ``` + + + +### aleoNetworkClient.getProgramObject(programId) +

Returns a program object from a program ID or program source code

+ +**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) + +| Param | Type | +| --- | --- | +| programId | string | + +**Example** +```js +let program = connection.getProgramObject("foo.aleo"); +``` + + + +### aleoNetworkClient.getProgramImports(programId) +

Returns an object containing the source code of a program and the source code of all programs it imports

+ +**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) + +| Param | Type | +| --- | --- | +| programId | string | + +**Example** +```js +let program = connection.getProgramImports("foo.aleo"); +``` + + + +### aleoNetworkClient.getDeploymentTransactionIDForProgram(programId) +

Returns the deployment transaction id associated with the specified program

+ +**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) + +| Param | Type | +| --- | --- | +| programId | string | + +**Example** +```js +let program = connection.getDeploymentTransactionIDForProgram("foo.aleo"); +``` + + + +### aleoNetworkClient.getDeploymentTransactionForProgram(programId) +

Returns the deployment transaction associated with a specified program

+ +**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) + +| Param | Type | +| --- | --- | +| programId | string | + +**Example** +```js +let program = connection.getDeploymentTransactionForProgram("foo.aleo"); +``` + ### aleoNetworkClient.getProgramMappingNames(programId) @@ -133,6 +216,23 @@ let program = connection.getProgram("foo.aleo"); ```js let mappings = connection.getProgramMappingNames("credits.aleo"); ``` + + + +### aleoNetworkClient.getProgramImportNames(programId) +

Get a list of the program names that a program imports

+ +**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) + +| Param | Type | +| --- | --- | +| programId | string | + +**Example** +```js +let mappings = connection.getProgramImportNames("foo.aleo"); +``` + ### aleoNetworkClient.getMappingValue(programId, mappingName, key) @@ -161,25 +261,27 @@ let mappingValue = connection.getMappingValue("credits.aleo", "account", "aleo1r ```js let latestHeight = connection.getLatestBlock(); ``` - -### aleoNetworkClient.getLatestHash() -

Returns the hash of the last published block

+ + +### aleoNetworkClient.getLatestHeight() +

Returns the latest block height

**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) **Example** ```js -let latestHash = connection.getLatestHash(); +let latestHeight = connection.getLatestHeight(); ``` - -### aleoNetworkClient.getLatestHeight() -

Returns the latest block height

+ + +### aleoNetworkClient.getLatestCommittee() +

Returns the latest committee

**Kind**: instance method of [AleoNetworkClient](#AleoNetworkClient) **Example** ```js -let latestHeight = connection.getLatestHeight(); +let latestCommittee = connection.getLatestCommittee(); ``` @@ -206,6 +308,7 @@ let stateRoot = connection.getStateRoot(); ```js let transaction = connection.getTransaction("at1handz9xjrqeynjrr0xay4pcsgtnczdksz3e584vfsgaz0dh0lyxq43a4wj"); ``` + ### aleoNetworkClient.getTransactions(height) @@ -261,4 +364,4 @@ let records = connection.findUnspentRecords(startHeight, undefined, privateKey, // Find specific amounts with a maximum number of cumulative microcredits const maxMicrocredits = 100000; let records = connection.findUnspentRecords(startHeight, undefined, privateKey, undefined, maxMicrocredits); -``` \ No newline at end of file +``` From 1934c55d974249acd0e8f560623dad0d328d4784 Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Wed, 10 Jul 2024 20:10:29 -0700 Subject: [PATCH 04/18] Integrate more updates --- .../src/build/leo/commands.md | 91 ------------------ .../src/build/leo/images/execute-output.png | Bin 216809 -> 0 bytes .../src/build/leo/images/run-output.png | Bin 24732 -> 0 bytes 3 files changed, 91 deletions(-) delete mode 100644 documentation updates aleo ambassadors/src/build/leo/commands.md delete mode 100644 documentation updates aleo ambassadors/src/build/leo/images/execute-output.png delete mode 100644 documentation updates aleo ambassadors/src/build/leo/images/run-output.png diff --git a/documentation updates aleo ambassadors/src/build/leo/commands.md b/documentation updates aleo ambassadors/src/build/leo/commands.md deleted file mode 100644 index c3cdfc4f0..000000000 --- a/documentation updates aleo ambassadors/src/build/leo/commands.md +++ /dev/null @@ -1,91 +0,0 @@ -# Commands - -In this section we explore the Leo CLI and explain what each command does. - -Let's get started with creating a new basic project. - - -## leo new -``` -leo new hello -cd hello -``` -This creates a new folder with the following directory structure. -``` -package/ -├── .env # Your program environment -├── program.json # Your program manifest -├── README.md # Your program description -├── build/ # Your built program will be placed here -├── inputs/ # Will be deprecated in the future -└── src/ - └── main.leo # Your program file -``` - -## leo example -Creates a sample program in a new directory -Example: -``` -leo example token -``` -This creates the token example program in a new directory. - -## leo run - -``` -leo run {$TRANSITION} {$INPUTS} -``` -To run a Leo transition function with inputs from the command line. {$INPUTS} should be a list of inputs to the program separated by spaces. This command does not synthesize the program circuit or generate proving and verifying keys. Running this command also builds the program under the build directory. - -Example: - -``` -leo run main 1u32 2u32 -``` -![run output example](./images/run-output.png) - - - -## leo execute - -``` -leo execute {$TRANSITION} {$INPUTS} -``` -To execute a Leo transition function with inputs from the command line. {$INPUTS} should be a list of inputs to the program separated by spaces. This command synthesizes the program circuit and generates proving and verifying keys. - -Example: - -``` -leo execute main 1u32 2u32 -``` - -![run output example](./images/execute-output.png) - - -## leo clean -``` -leo clean -``` -This command cleans the build directory - -## leo account -To create a new Aleo account, run: -``` -leo account new - -# Output: - Private Key APrivateKey1zkp... - View Key AViewKey1... - Address aleo1... -``` - -To import an existing Aleo account, run: -``` -leo account import {$PRIVATE_KEY} -``` - -## leo update -To download and install the latest Leo version, run: -``` -leo update -``` diff --git a/documentation updates aleo ambassadors/src/build/leo/images/execute-output.png b/documentation updates aleo ambassadors/src/build/leo/images/execute-output.png deleted file mode 100644 index bc31e6d274e258db47a8c5d5d89cc0f3a61b9ecc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 216809 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 l_)IQ(nEsuAe>0j%XPSTx*6sZ3o>1@~St$j{ diff --git a/documentation updates aleo ambassadors/src/build/leo/images/run-output.png b/documentation updates aleo ambassadors/src/build/leo/images/run-output.png deleted file mode 100644 index 742663edf50e422c848c87f1e8d87f8b6e0f97ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24732 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 Date: Wed, 10 Jul 2024 20:22:59 -0700 Subject: [PATCH 05/18] Integrate advanced guides --- .../src/advanced/README.md | 1 - documentation/00_overview.md | 13 ++++++++++++- .../advanced/dive-into-avm/00_overview.md | 6 +++++- .../advanced/dive-into-avm/01_aleo_account_keys.md | 6 +++++- .../advanced/dive-into-avm/02_r1cs.md | 6 +++++- .../advanced/dive-into-avm/03_inclusion_proof.md | 8 ++++++-- .../dive-into-avm/images/aleo_key_generation.png | Bin .../images/avm_execution_flow_overview.png | Bin .../dive-into-avm/images/avs_global_state.png | Bin .../advanced/intro-to-zksnark/00_overview.md | 7 ++++++- 10 files changed, 39 insertions(+), 8 deletions(-) delete mode 100644 documentation updates aleo ambassadors/src/advanced/README.md rename documentation updates aleo ambassadors/src/advanced/dive-into-avm/README.md => documentation/advanced/dive-into-avm/00_overview.md (99%) rename documentation updates aleo ambassadors/src/advanced/dive-into-avm/aleo-account-keys.md => documentation/advanced/dive-into-avm/01_aleo_account_keys.md (96%) rename documentation updates aleo ambassadors/src/advanced/dive-into-avm/circuits-r1cs.md => documentation/advanced/dive-into-avm/02_r1cs.md (97%) rename documentation updates aleo ambassadors/src/advanced/inclusion-proof..md => documentation/advanced/dive-into-avm/03_inclusion_proof.md (95%) rename {documentation updates aleo ambassadors/src => documentation}/advanced/dive-into-avm/images/aleo_key_generation.png (100%) rename {documentation updates aleo ambassadors/src => documentation}/advanced/dive-into-avm/images/avm_execution_flow_overview.png (100%) rename {documentation updates aleo ambassadors/src => documentation}/advanced/dive-into-avm/images/avs_global_state.png (100%) rename documentation updates aleo ambassadors/src/advanced/intro-to-zksnark/general-intuition.md => documentation/advanced/intro-to-zksnark/00_overview.md (99%) diff --git a/documentation updates aleo ambassadors/src/advanced/README.md b/documentation updates aleo ambassadors/src/advanced/README.md deleted file mode 100644 index 931fae06c..000000000 --- a/documentation updates aleo ambassadors/src/advanced/README.md +++ /dev/null @@ -1 +0,0 @@ -# Advanced diff --git a/documentation/00_overview.md b/documentation/00_overview.md index 54775cb37..6b38cd218 100644 --- a/documentation/00_overview.md +++ b/documentation/00_overview.md @@ -91,7 +91,18 @@ An index of all pages available in this documentation. ## Advanced Topics -### Chapter 7: The Aleo Curves +### Chapter 7: Dive into the AVM + +- [Overview](./advanced/dive-into-avm/00_overview.md) +- [Aleo Account Keys](./advanced/dive-into-avm/01_aleo_account_keys.md) +- [Circuits and R1CS](./advanced/dive-into-avm/02_r1cs.md) +- [Inclusion Proofs](./advanced/dive-into-avm/03_inclusion_proof.md) + +### Chapter 8: Introduction to zk-SNARKs + +- [Overview](./advanced/intro-to-zksnark/00_overview.md) + +### Chapter 9: The Aleo Curves - [Overview](./advanced/the_aleo_curves/00_overview.md) - [Edwards BLS12](./advanced/the_aleo_curves/01_edwards_bls12.md) diff --git a/documentation updates aleo ambassadors/src/advanced/dive-into-avm/README.md b/documentation/advanced/dive-into-avm/00_overview.md similarity index 99% rename from documentation updates aleo ambassadors/src/advanced/dive-into-avm/README.md rename to documentation/advanced/dive-into-avm/00_overview.md index c13073271..db26d96f0 100644 --- a/documentation updates aleo ambassadors/src/advanced/dive-into-avm/README.md +++ b/documentation/advanced/dive-into-avm/00_overview.md @@ -1,4 +1,8 @@ -# Aleo’s Virtual Machine (AVM) +--- +id: overview +title: Overview +sidebar_label: Overview +--- The Aleo Virtual Machine (AVM) is a computational platform integral to the Aleo blockchain, designed to run privacy-focused applications. It operates as a stack machine that executes queued instructions. Its primary function is to construct arithmetic circuits described as Rank-1 Constraint System (R1CS), from each instruction in a function. diff --git a/documentation updates aleo ambassadors/src/advanced/dive-into-avm/aleo-account-keys.md b/documentation/advanced/dive-into-avm/01_aleo_account_keys.md similarity index 96% rename from documentation updates aleo ambassadors/src/advanced/dive-into-avm/aleo-account-keys.md rename to documentation/advanced/dive-into-avm/01_aleo_account_keys.md index f618d90b9..d85041a9a 100644 --- a/documentation updates aleo ambassadors/src/advanced/dive-into-avm/aleo-account-keys.md +++ b/documentation/advanced/dive-into-avm/01_aleo_account_keys.md @@ -1,4 +1,8 @@ -# Aleo Account Key Generation +--- +id: aleo_account_keys +title: Aleo Account Keys +sidebar_label: Aleo Account Keys +--- An Aleo account is similar to accounts on other blockchain platforms but designed with a focus on privacy, leveraging cryptographic techniques unique to the platform. Here's a detailed breakdown of the components of an Aleo account and the processes involved in generating addresses, public keys, and private keys: diff --git a/documentation updates aleo ambassadors/src/advanced/dive-into-avm/circuits-r1cs.md b/documentation/advanced/dive-into-avm/02_r1cs.md similarity index 97% rename from documentation updates aleo ambassadors/src/advanced/dive-into-avm/circuits-r1cs.md rename to documentation/advanced/dive-into-avm/02_r1cs.md index e340930e8..2b28eba8c 100644 --- a/documentation updates aleo ambassadors/src/advanced/dive-into-avm/circuits-r1cs.md +++ b/documentation/advanced/dive-into-avm/02_r1cs.md @@ -1,4 +1,8 @@ -# R1CS Circuits +--- +id: r1cs +title: R1CS +sidebar_label: R1CS +--- Aleo Virtual Machine leverages a type of intermediate representation for their circuits called “Rank-1 Constrained System” (R1CS). This format is used to express computations as a system of equations that can later be formally verified. diff --git a/documentation updates aleo ambassadors/src/advanced/inclusion-proof..md b/documentation/advanced/dive-into-avm/03_inclusion_proof.md similarity index 95% rename from documentation updates aleo ambassadors/src/advanced/inclusion-proof..md rename to documentation/advanced/dive-into-avm/03_inclusion_proof.md index 4aed30d41..6024881ac 100644 --- a/documentation updates aleo ambassadors/src/advanced/inclusion-proof..md +++ b/documentation/advanced/dive-into-avm/03_inclusion_proof.md @@ -1,4 +1,8 @@ -# Inclusion Proofs +--- +id: inclusion_proof +title: Inclusion Proofs +sidebar_label: Inclusion Proofs +--- Inclusion proofs are like a special handshake or password that gets you past verifier without revealing the actual element. In Aleo, inclusion proofs are like digital receipts that verify transactions without compromising users' privacy. @@ -12,4 +16,4 @@ In addition to producing these proofs, a user also produces 𝑛+1 “inclusion An inclusion proof also publicly outputs the serial numbers (also called a nullifier in ZCash-like systems) that uniquely identify the records without leaking any information about them. This way, records cannot be consumed more than once. (In addition, the network enforces that no serial number is seen twice within the same transaction.) -**Note:** All of these different proofs are eventually aggregated together into a single proof using Varuna’s batching capabilities. \ No newline at end of file +**Note:** All of these different proofs are eventually aggregated together into a single proof using Varuna’s batching capabilities. diff --git a/documentation updates aleo ambassadors/src/advanced/dive-into-avm/images/aleo_key_generation.png b/documentation/advanced/dive-into-avm/images/aleo_key_generation.png similarity index 100% rename from documentation updates aleo ambassadors/src/advanced/dive-into-avm/images/aleo_key_generation.png rename to documentation/advanced/dive-into-avm/images/aleo_key_generation.png diff --git a/documentation updates aleo ambassadors/src/advanced/dive-into-avm/images/avm_execution_flow_overview.png b/documentation/advanced/dive-into-avm/images/avm_execution_flow_overview.png similarity index 100% rename from documentation updates aleo ambassadors/src/advanced/dive-into-avm/images/avm_execution_flow_overview.png rename to documentation/advanced/dive-into-avm/images/avm_execution_flow_overview.png diff --git a/documentation updates aleo ambassadors/src/advanced/dive-into-avm/images/avs_global_state.png b/documentation/advanced/dive-into-avm/images/avs_global_state.png similarity index 100% rename from documentation updates aleo ambassadors/src/advanced/dive-into-avm/images/avs_global_state.png rename to documentation/advanced/dive-into-avm/images/avs_global_state.png diff --git a/documentation updates aleo ambassadors/src/advanced/intro-to-zksnark/general-intuition.md b/documentation/advanced/intro-to-zksnark/00_overview.md similarity index 99% rename from documentation updates aleo ambassadors/src/advanced/intro-to-zksnark/general-intuition.md rename to documentation/advanced/intro-to-zksnark/00_overview.md index 4c4c776ae..4871a3d0a 100644 --- a/documentation updates aleo ambassadors/src/advanced/intro-to-zksnark/general-intuition.md +++ b/documentation/advanced/intro-to-zksnark/00_overview.md @@ -1,4 +1,9 @@ -# Advanced +--- +id: overview +title: Overview +sidebar_label: Overview +--- + In this section we cover the general intuition of a zk proof, we outline the steps in creating a zksnark, we define the actors in a zk proof mainly the prover and verifier. We also introduce the elements in a zkproof like the witness, intermediate representation, trusted setups, structured reference strings and random oracles. We also give the context of where the zksnark proof is used in Aleo. ## Introduction From 14450a71c18bd94bd9e12503ba756d04ee6dcb76 Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Wed, 10 Jul 2024 20:44:57 -0700 Subject: [PATCH 06/18] Integrate more concepts --- .../src/blog/exploring_aleo_record_model.md | 178 ----------------- .../src/blog/public_vs_private_state.md | 90 --------- documentation/00_overview.md | 1 + documentation/concepts/02_records.md | 184 ++++++++++++++---- documentation/concepts/06_public_private.md | 95 +++++++++ .../{06_glossary.md => 07_glossary.md} | 0 .../concepts}/images/account_vs_utxo.png | Bin .../concepts}/images/aleo.jpeg | Bin .../concepts}/images/aleo_ledger.png | Bin .../concepts}/images/ethereum_storage.png | Bin .../concepts}/images/ethereum_world_state.png | Bin .../concepts}/images/record.png | Bin .../concepts}/images/transaction_in_aleo.png | Bin .../concepts}/images/utxo.png | Bin 14 files changed, 246 insertions(+), 302 deletions(-) delete mode 100644 documentation updates aleo ambassadors/src/blog/exploring_aleo_record_model.md create mode 100644 documentation/concepts/06_public_private.md rename documentation/concepts/{06_glossary.md => 07_glossary.md} (100%) rename {documentation updates aleo ambassadors/src/blog => documentation/concepts}/images/account_vs_utxo.png (100%) rename {documentation updates aleo ambassadors/src/blog => documentation/concepts}/images/aleo.jpeg (100%) rename {documentation updates aleo ambassadors/src/blog => documentation/concepts}/images/aleo_ledger.png (100%) rename {documentation updates aleo ambassadors/src/blog => documentation/concepts}/images/ethereum_storage.png (100%) rename {documentation updates aleo ambassadors/src/blog => documentation/concepts}/images/ethereum_world_state.png (100%) rename {documentation updates aleo ambassadors/src/blog => documentation/concepts}/images/record.png (100%) rename {documentation updates aleo ambassadors/src/blog => documentation/concepts}/images/transaction_in_aleo.png (100%) rename {documentation updates aleo ambassadors/src/blog => documentation/concepts}/images/utxo.png (100%) diff --git a/documentation updates aleo ambassadors/src/blog/exploring_aleo_record_model.md b/documentation updates aleo ambassadors/src/blog/exploring_aleo_record_model.md deleted file mode 100644 index ec49ab5e7..000000000 --- a/documentation updates aleo ambassadors/src/blog/exploring_aleo_record_model.md +++ /dev/null @@ -1,178 +0,0 @@ -# Exploring Aleo's Record Model - -![alt text](./images/aleo.jpeg) - -## Introduction -Before we can dive into the explanation of a record, we first have to make sure that you understand what Aleo is, and why it chose a record model as its core data structure. - -Autonomous Ledger Execution Offchain (Aleo) is a layer-1 blockchain that combines general-purpose programmability with privacy by default. - -The core idea behind Aleo is ZEXE or zero-knowledge execution initially written in this [research paper](https://eprint.iacr.org/2018/962.pdf) in 2018. It first introduced the record model which extends the UTXO model from Zcash and enables storing and encrypting arbitrary data (user assets and application states), rather than just values of specific assets or tokens. - - -## Privacy -There are generally four different types of privacy that relate to blockchains. - -Aleo fulfils the 3 of them: -- [x] Private inputs (messages) -- [x] Private outputs (state changes) -- [x] Private user -- [ ] Private function - -Initially, Aleo was aiming for function privacy as well (as detailed in the original ZEXE paper) but decided against it as it would have led to worse performance and longer proving times. - - - -## Comparing state storage in blockchains -There are two main state models used in blockchains - UTXO (unspent transaction output) and the account model (introduced by Ethereum). - -Aleo uses a variation of the UTXO model - the record model. - - -

-Account vs UTXO -

- -

-Source: galaxy.com -

-
- -### Account Model -In the account model as used in Ethereum, the application state can be found by referencing to a particular address. - -As such, anyone would be able to view the activities of any account, simply with the knowledge of the address. - -

-Ethereum Storage Diagram -

- -

-Source: ethereum.org -

-
- - -

-Ethereum World State Diagram -

- -

-Source: Article by Lucas Saldanha -

- -
- - -### Record Model -In the record model, the application state, along with its owner are encrypted and stored on the blockchain. - - -

-Aleo Records Diagram -

- -

-Source: Zexe: Enabling Decentralized Private Computation -

- -
- - -

-Aleo World State Diagram -

- - -

-Source: Zexe: Enabling Decentralized Private Computation -

-
- - -## Record Model Explained -Records are a fundamental data structure that can contain any arbitrary payload and are used for encoding user assets or application states. Records represent a fragment of the global state kept on-chain. For example, the balance of your credits in a given account is composed by the multiple credit records that have your address as the owner. - - -An Aleo record is serialized in the following format: - -| Parameter | Type | Description | -|------------|:----------------------------:|-----------------------------------------------------------------------------------------------------| -| owner | address | The address public key of the owner of the program record | -| data | Map | A data payload containing arbitrary application-dependent information | -| nonce | group | The serial number nonce of the program record | - - -An example record: -```bash -{ - owner: aleo13ssze66adjjkt795z9u5wpq8h6kn0y2657726h4h3e3wfnez4vqsm3008q.private, - amount: 100u64.private, - _nonce: 5861592911433819692697358191094794940442348980903696700646555355124091569429group.public -} -``` - -Owner -
-`aleo13ssze66adjjkt795z9u5wpq8h6kn0y2657726h4h3e3wfnez4vqsm3008q` - -The record owner is an account address, and specifies the party who is authorized to spend the record. - - -Data -
-`100u64` - -The record can encode arbitrary application information. The "amount" key is the data payload that the record carries. - - -Nonce -
-`5861592911433819692697358191094794940442348980903696700646555355124091569429group` - -The serial number nonce is used to create a unique identifier for each record, and is computed via a PRF evaluation of the address secret key ask of the owner and the record's serial number. - - - - -For a practical demonstration of a record in Aleo, see [here](https://youtu.be/JIgrKv_Q6Jo?feature=shared). - - -### Updating State -In the record model, applications update their state by consuming records containing the old state, and producing new records that contain the updated state. Records that have been used will be marked as spent and cannot be used again. - - -

-UTXO diagram -

- -

-Source: adapulse.io -

-
- -The consumption and production of records is typically done in a transition function. A transaction in Aleo can contain up to 32 transitions, one of which is reserved for the transaction fee. - - - -

-Transaction in Aleo -

- -## Why Record Model? - -In the account-based model, an application's data is stored in a persistent location tied to the application's account, and updates are made directly to this stored data. For a typical token transfer transaction using this model, user balances would be stored in a table mapping user account addresses to their respective balances. When User A transfers money to User B, A's balance in the table is reduced, and B's balance is increased by the same amount. - -If we were to try making the transactions private (hiding the amount transferred and the identities of A and B), instead of storing actual balances, the application can store commitments to these balances. Transactions would then update these commitments rather than the actual balances. However, while this approach hides transaction values, it does not hide user identities. To also hide user identities, every transaction would need to update all commitments in the table, which becomes increasingly inefficient as the number of users grows. - -Although the account model is more intuitive for developers, it uses account addresses to index global state. This means that while a private account model can achieve privacy for inputs and outputs, it still compromises user privacy since account addresses cannot be encrypted. Another issue with the private account model is the lack of concurrency, as only one user can access and update the entire program state at a time. - -Aleo's record model uses program IDs to uniquely identify programs instead of account addresses. This improves privacy and enables programs to have internal states. This approach is more efficient and solves the concurrency issue. - -## Conclusion -Aleo is new a layer-1 blockchain that emphasizes on programmable privacy and scalability. It has chosen the record model as it's fundamental data structure because the account-based model cannot provide privacy with scalability. The record model also provides an enhancement over the UTXO model used in bitcoin, by it's ability to encode any arbitrary data, thus providing programmable privacy. - - - diff --git a/documentation updates aleo ambassadors/src/blog/public_vs_private_state.md b/documentation updates aleo ambassadors/src/blog/public_vs_private_state.md index a1752293b..3d95da026 100644 --- a/documentation updates aleo ambassadors/src/blog/public_vs_private_state.md +++ b/documentation updates aleo ambassadors/src/blog/public_vs_private_state.md @@ -1,93 +1,3 @@ # Public vs. Private State -![aleo logo](./images/aleo.jpeg) - -## Introduction -The concept of Zero Knowledge proofs was first introduced in 1985 in the paper [The Knowledge Complexity of Interactive Proof Systems](https://epubs.siam.org/doi/10.1137/0218012?utm_source=the+new+stack&utm_medium=referral&utm_content=inline-mention&utm_campaign=tns+platform). However, it is only in recent years that the groundbreaking technology has been feasible to be applicable to blockchains. - -Zcash was one of the earliest chains to utilize the power of zero knowledge proofs to provide privacy to an account's balance. Unlike traditional cryptocurrencies like Bitcoin, where transaction details are publicly visible on the blockchain, Zcash enables users to shield their transactions, rendering them completely opaque to outside observers. It utilizes zk-SNARKs (Zero-Knowledge Succinct Non-Interactive Argument of Knowledge), a type of zero-knowledge proof system that allows parties to verify the validity of a computation without revealing the underlying data. - -In even more recent times, we have seen several Ethereum virtual machine-compatible Layer-2 chains that have employed zero-knowledge cryptography techniques to solve Ethereum's scalability issues. They use zk-rollups, which compute multiple state changes off-chain, followed by posting the summary of those transactions and proofs on-chain. This helps to reduce transaction fees significantly. However, all of them utilize zero-knowledge technology mainly for scalability reasons. - -Aleo is a new layer-1 blockchain that combines general-purpose programmability with privacy by default. Unlike the other chains, Aleo is one of the first blockchains to utilize zero-knowledge for both privacy and scalability. - - -## Privacy -There are generally four different types of privacy that relate to blockchains, of which Aleo fulfils the 3 of them: -- [x] Private inputs (messages) -- [x] Private outputs (state changes) -- [x] Private user -- [ ] Private function - -The core belief at Aleo is that privacy is necessary in order for blockchains to have mainstream adoption. For instance, how many of us would be comfortable revealing our bank account numbers if anyone in public were able to trace all the transactions we have ever made? - -## Aleo State Storage -In order to have privacy native to a chain, Aleo uses a record model for application state storage, which is similar to the UTXO model in Bitcoin. However, Aleo provides developers the option to make application states public should they choose to do so. Public states are stored using the account model as done in Ethereum. - -### Storing Private States via Record -Records are a fundamental data structure that can contain any arbitrary payload and are used for encoding user assets or application states. A record represents a certain state of a program in the global state, for example, the balance of an account or your identity document. - - -An Aleo record is serialized in the following format: - -| Parameter | Type | Description | -|------------|:----------------------------:|-----------------------------------------------------------------------------------------------------| -| owner | address | The address public key of the owner of the program record | -| data | `map` | A data payload containing arbitrary application-dependent information | -| nonce | group | The serial number nonce of the program record | - -Records are tied to programs deployed on Aleo, and only the owner has permissions to alter the state of the record. - -Records are private by default and are stored as ciphertext on-chain. - -### Storing Public State via Mapping - -A public state in Aleo is stored in the form of a mapping, which are key-value pairs. Anyone is able to query the state of the mapping by querying the Aleo blockchain explorer. - -### Switching Between Privacy States -By supporting both private and public storage states, an interesting feature emerges in Aleo where states can be converted from private to public and vice versa. - -An example of such a use case would be in a poker game. The state of the shuffled deck after dealing the cards to players should be kept private initially. Proceeding, as the "flop" reveals the top 3 cards, the state of those cards should be revealed to the public. - -### View Key -Aleo has a unique feature known as a view key for each account. The view key allows one to decrypt all transactions of it's account. It is different from the private key in that it does not provide the permission to spend the records. - -## Private Inputs and Outputs of Programs -Apart from stored program states being private, the program function inputs and outputs can also be made private or public. The following shows an example of an Aleo program which adds two input numbers and stores the result into a record known as 'sum'. The developer has the choice to specify if the input of a program transition function should be public or private. The individual record fields can also be made public or private via the 'public' modifier. As Aleo is private by default, the fields are considered as private if the modifier is not specified. - - - -``` -program sum.aleo { - record sum { - public owner: address, - amount: u64, - } - - transition main(public a: u64, b: u64) -> sum { - let c: u64 = a + b; - return sum { - owner: self.caller, - amount: c, - }; - } -} -``` -## Public vs. Private States - -The choice to store an application state as public or private should depend on the particular use case of the program. Instead of simply being a completely privacy or a public chain, Aleo believes in a two pronged approach by offering developers a choice. - -Moreover, real-world applications often rely on a combination of public and private information. - -A practical example would be in voting. As stated by the Aleo founder, Howard Wu, "In elections, people want to vote, but they don’t want to show other people how they voted. The tally of the votes needs to be public to understand the outcome. Having private votes and public tallies ends up being a capable functionality in applications here." - - -## Conclusion -Aleo is one of the very first few layer-1 blockchains that emphasizes on programmable privacy. Developers are able to choose if they wish to make certain states of their program public or private. This opens up a whole new set of interesting applications that cannot be built easily with other blockchains. This is certainly an exciting chain to keep an eye out for. diff --git a/documentation/00_overview.md b/documentation/00_overview.md index 6b38cd218..fcae9a79d 100644 --- a/documentation/00_overview.md +++ b/documentation/00_overview.md @@ -54,6 +54,7 @@ An index of all pages available in this documentation. - [Transaction Fees](./concepts/03A_transaction_fees.md) - [Transitions](./concepts/04_transitions.md) - [Blocks](./concepts/05_blocks.md) +- [Public vs. Private State](./concepts/06_public_private.md) ## Testnet III diff --git a/documentation/concepts/02_records.md b/documentation/concepts/02_records.md index 964968176..5a3444b36 100644 --- a/documentation/concepts/02_records.md +++ b/documentation/concepts/02_records.md @@ -4,54 +4,170 @@ title: Records sidebar_label: Records --- + A **record** is a fundamental data structure for encoding user assets and application state. -Each account record contains information that specifies the record owner, its stored value, and its application state. -Records in Aleo are consumed and newly created from a [transition](04_transitions.md) function. A [transaction](03_transactions.md) will store multiple transitions, each of which is responsible for the consumption and creation of its individual records. -Optionally, if the `visibility` of the record is `private`, it can be encrypted using the owner's address secret key. +Each account record contains information that specifies the record owner, its stored value, and its application state. +Records in Aleo are consumed and newly created from a [transition](04_transitions.md) function. A [transaction](03_transactions.md) will store multiple transitions, each of which is responsible for the consumption and creation of its individual records. +Optionally, if the `visibility` of an entry in the record is `private`, it is be encrypted using the owner's address secret key. ## Components of a Record An Aleo record is serialized in the following format: -| Parameter | Type | Description | -|:--------------:|:----------------------:|:---------------------------------------------------------------------:| -| `apk` | address | The address public key of the owner of the program record | -| `data` | Map | A data payload containing arbitrary application-dependent information | -| `nonce` | group | The serial number nonce of the program record | -| `visibility` | enum | The record's visibility, which can either be `public` or `private` | -### Owner - +| Parameter | Type | Description | +|:---------:|:----------------------:|:----------------------------------------------------------------------------------------------------------------------:| +| `owner` | address | The address public key of the owner of the program record | +| `data` | Map | A data payload containing arbitrary application-dependent information. Each entry can either be `public` or `private`. | +| `nonce` | group | The serial number nonce of the program record | +An example record: +```bash +{ + owner: aleo13ssze66adjjkt795z9u5wpq8h6kn0y2657726h4h3e3wfnez4vqsm3008q.private, + amount: 100u64.private, + _nonce: 5861592911433819692697358191094794940442348980903696700646555355124091569429group.public +} ``` -aleo1r0dry2tlhjt0yplctz85692kjpqsadn7xgxsmrehkasykjxynypqza3fpl -``` -The **record owner** is an [account address](00_accounts.md#account-address), -and specifies the party who is authorized to spend the record. -### Gates +Owner +
+`aleo13ssze66adjjkt795z9u5wpq8h6kn0y2657726h4h3e3wfnez4vqsm3008q` -``` -4130 -``` +The record owner is an account address, and specifies the party who is authorized to spend the record. + + +Data +
+`100u64.private` + +The record can encode arbitrary application information. The "amount" key is the data payload that the record carries. +An entry which has a `visibility` of `private` is encrypted and stored on the ledger. +This enables users to securely and privately transfer record data and values between one another over the public network. +Only the sender and receiver with their corresponding account view keys are able to decrypt the private entries. + +Nonce +
+`5861592911433819692697358191094794940442348980903696700646555355124091569429group` + +The serial number nonce is used to create a unique identifier for each record, and is computed via a PRF evaluation of the address secret key ask of the owner and the record's serial number. +For a practical demonstration of a record in Aleo, see [here](https://youtu.be/JIgrKv_Q6Jo?feature=shared). + + +## Diving into the Concepts +To understand how to use records, we must understand the design principles behind Aleo. +Autonomous Ledger Execution Offchain (Aleo) is a layer-1 blockchain that combines general-purpose programmability with privacy by default. +The core idea behind Aleo is ZEXE or zero-knowledge execution initially written in this [research paper](https://eprint.iacr.org/2018/962.pdf) in 2018. It first introduced the record model which extends the UTXO model from Zcash and enables storing and encrypting arbitrary data (user assets and application states), rather than just values of specific assets or tokens. + +### Privacy +There are generally four different types of privacy that relate to blockchains. + +Aleo fulfils the 3 of them: +- [x] Private inputs (messages) +- [x] Private outputs (state changes) +- [x] Private user +- [ ] Private function + +Initially, Aleo was aiming for function privacy as well (as detailed in the original ZEXE paper) but decided against it as it would have led to worse performance and longer proving times. + + +### Comparing state storage in blockchains +There are two main state models used in blockchains - UTXO (unspent transaction output) and the account model (introduced by Ethereum). + +Aleo uses a variation of the UTXO model - the record model. + + +

+Account vs UTXO +

+ +

+Source: galaxy.com +

+
+ +### Account Model +In the account model as used in Ethereum, the application state can be found by referencing to a particular address. + +As such, anyone would be able to view the activities of any account, simply with the knowledge of the address. + +

+Ethereum Storage Diagram +

+ +

+Source: ethereum.org +

+
+ + +

+Ethereum World State Diagram +

+ +

+Source: Article by Lucas Saldanha +

+ +
+ + +### Record Model +In the record model, the application state, along with its owner are encrypted and stored on the blockchain. + + +

+Aleo Records Diagram +

+ +

+Source: Zexe: Enabling Decentralized Private Computation +

+ +
+ + +

+Aleo World State Diagram +

+ + +

+Source: Zexe: Enabling Decentralized Private Computation +

+
+ + +### Updating State +In the record model, applications update their state by consuming records containing the old state, and producing new records that contain the updated state. Records that have been used will be marked as spent and cannot be used again. + + +

+UTXO diagram +

+ +

+Source: adapulse.io +

+
+ +The consumption and production of records is typically done in a transition function. A transaction in Aleo can contain up to 32 transitions, one of which is reserved for the transaction fee. + + + +

+Transaction in Aleo +

+ +### Why is the Record Model Useful? + +In the account-based model, an application's data is stored in a persistent location tied to the application's account, and updates are made directly to this stored data. For a typical token transfer transaction using this model, user balances would be stored in a table mapping user account addresses to their respective balances. When User A transfers money to User B, A's balance in the table is reduced, and B's balance is increased by the same amount. +If we were to try making the transactions private (hiding the amount transferred and the identities of A and B), instead of storing actual balances, the application can store commitments to these balances. Transactions would then update these commitments rather than the actual balances. However, while this approach hides transaction values, it does not hide user identities. To also hide user identities, every transaction would need to update all commitments in the table, which becomes increasingly inefficient as the number of users grows. +Although the account model is more intuitive for developers, it uses account addresses to index global state. This means that while a private account model can achieve privacy for inputs and outputs, it still compromises user privacy since account addresses cannot be encrypted. Another issue with the private account model is the lack of concurrency, as only one user can access and update the entire program state at a time. +Aleo's record model uses program IDs to uniquely identify programs instead of account addresses. This improves privacy and enables programs to have internal states. This approach is more efficient and solves the concurrency issue. -### Data -``` -[ RECORD BYTE MAP ] -``` -The **record data** encodes arbitrary application information. -### Nonce -``` -3024738992072387217402876176731225730589877991873828351104009809002984426287group -``` -The **serial number nonce** is used to create a unique identifier for each record, -and is computed via a `PRF` evaluation of the address secret key `ask` of the `owner` and the record's serial number. -### (Optional) Record Encryption -A record which has a `visibility` of `private` is verifiably encrypted in the transition and stored on the ledger. -This enables users to securely and privately transfer record data and values between one another over the public network. -Only the sender and receiver with their corresponding account view keys are able to decrypt these records. diff --git a/documentation/concepts/06_public_private.md b/documentation/concepts/06_public_private.md new file mode 100644 index 000000000..4df930d20 --- /dev/null +++ b/documentation/concepts/06_public_private.md @@ -0,0 +1,95 @@ +--- +id: public_private +title: Public vs. Private State +sidebar_label: Public vs. Private State +--- + +## Introduction +The concept of Zero Knowledge proofs was first introduced in 1985 in the paper [The Knowledge Complexity of Interactive Proof Systems](https://epubs.siam.org/doi/10.1137/0218012?utm_source=the+new+stack&utm_medium=referral&utm_content=inline-mention&utm_campaign=tns+platform). However, it is only in recent years that the groundbreaking technology has been feasible to be applicable to blockchains. + +Zcash was one of the earliest chains to utilize the power of zero knowledge proofs to provide privacy to an account's balance. Unlike traditional cryptocurrencies like Bitcoin, where transaction details are publicly visible on the blockchain, Zcash enables users to shield their transactions, rendering them completely opaque to outside observers. It utilizes zk-SNARKs (Zero-Knowledge Succinct Non-Interactive Argument of Knowledge), a type of zero-knowledge proof system that allows parties to verify the validity of a computation without revealing the underlying data. + +In even more recent times, we have seen several Ethereum virtual machine-compatible Layer-2 chains that have employed zero-knowledge cryptography techniques to solve Ethereum's scalability issues. They use zk-rollups, which compute multiple state changes off-chain, followed by posting the summary of those transactions and proofs on-chain. This helps to reduce transaction fees significantly. However, all of them utilize zero-knowledge technology mainly for scalability reasons. + +Aleo is a new layer-1 blockchain that combines general-purpose programmability with privacy by default. Unlike the other chains, Aleo is one of the first blockchains to utilize zero-knowledge for both privacy and scalability. + + +## Privacy +There are generally four different types of privacy that relate to blockchains, of which Aleo fulfils the 3 of them: +- [x] Private inputs (messages) +- [x] Private outputs (state changes) +- [x] Private user +- [ ] Private function + +The core belief at Aleo is that privacy is necessary in order for blockchains to have mainstream adoption. For instance, how many of us would be comfortable revealing our bank account numbers if anyone in public were able to trace all the transactions we have ever made? + +## Aleo State Storage +In order to have privacy native to a chain, Aleo uses a record model for application state storage, which is similar to the UTXO model in Bitcoin. However, Aleo provides developers the option to make application states public should they choose to do so. Public states are stored using the account model as done in Ethereum. + +### Storing Private States via Record +Records are a fundamental data structure that can contain any arbitrary payload and are used for encoding user assets or application states. A record represents a certain state of a program in the global state, for example, the balance of an account or your identity document. + + +An Aleo record is serialized in the following format: + +| Parameter | Type | Description | +|------------|:----------------------------:|-----------------------------------------------------------------------------------------------------| +| owner | address | The address public key of the owner of the program record | +| data | `map` | A data payload containing arbitrary application-dependent information | +| nonce | group | The serial number nonce of the program record | + +Records are tied to programs deployed on Aleo, and only the owner has permissions to alter the state of the record. + +Records are private by default and are stored as ciphertext on-chain. + +### Storing Public State via Mapping + +A public state in Aleo is stored in the form of a mapping, which are key-value pairs. Anyone is able to query the state of the mapping by querying the Aleo blockchain explorer. + +### Switching Between Privacy States +By supporting both private and public storage states, an interesting feature emerges in Aleo where states can be converted from private to public and vice versa. + +An example of such a use case would be in a poker game. The state of the shuffled deck after dealing the cards to players should be kept private initially. Proceeding, as the "flop" reveals the top 3 cards, the state of those cards should be revealed to the public. + +### View Key +Aleo has a unique feature known as a view key for each account. The view key allows one to decrypt all transactions of it's account. It is different from the private key in that it does not provide the permission to spend the records. + +## Private Inputs and Outputs of Programs +Apart from stored program states being private, the program function inputs and outputs can also be made private or public. The following shows an example of an Aleo program which adds two input numbers and stores the result into a record known as 'sum'. The developer has the choice to specify if the input of a program transition function should be public or private. The individual record fields can also be made public or private via the 'public' modifier. As Aleo is private by default, the fields are considered as private if the modifier is not specified. + + + +``` +program sum.aleo { + record sum { + public owner: address, + amount: u64, + } + + transition main(public a: u64, b: u64) -> sum { + let c: u64 = a + b; + return sum { + owner: self.caller, + amount: c, + }; + } +} +``` +## Public vs. Private States + +The choice to store an application state as public or private should depend on the particular use case of the program. Instead of simply being a completely privacy or a public chain, Aleo believes in a two pronged approach by offering developers a choice. + +Moreover, real-world applications often rely on a combination of public and private information. + +A practical example would be in voting. As stated by the Aleo founder, Howard Wu, "In elections, people want to vote, but they don’t want to show other people how they voted. The tally of the votes needs to be public to understand the outcome. Having private votes and public tallies ends up being a capable functionality in applications here." + + +## Conclusion +Aleo is one of the very first few layer-1 blockchains that emphasizes on programmable privacy. Developers are able to choose if they wish to make certain states of their program public or private. This opens up a whole new set of interesting applications that cannot be built easily with other blockchains. This is certainly an exciting chain to keep an eye out for. + diff --git a/documentation/concepts/06_glossary.md b/documentation/concepts/07_glossary.md similarity index 100% rename from documentation/concepts/06_glossary.md rename to documentation/concepts/07_glossary.md diff --git a/documentation updates aleo ambassadors/src/blog/images/account_vs_utxo.png b/documentation/concepts/images/account_vs_utxo.png similarity index 100% rename from documentation updates aleo ambassadors/src/blog/images/account_vs_utxo.png rename to documentation/concepts/images/account_vs_utxo.png diff --git a/documentation updates aleo ambassadors/src/blog/images/aleo.jpeg b/documentation/concepts/images/aleo.jpeg similarity index 100% rename from documentation updates aleo ambassadors/src/blog/images/aleo.jpeg rename to documentation/concepts/images/aleo.jpeg diff --git a/documentation updates aleo ambassadors/src/blog/images/aleo_ledger.png b/documentation/concepts/images/aleo_ledger.png similarity index 100% rename from documentation updates aleo ambassadors/src/blog/images/aleo_ledger.png rename to documentation/concepts/images/aleo_ledger.png diff --git a/documentation updates aleo ambassadors/src/blog/images/ethereum_storage.png b/documentation/concepts/images/ethereum_storage.png similarity index 100% rename from documentation updates aleo ambassadors/src/blog/images/ethereum_storage.png rename to documentation/concepts/images/ethereum_storage.png diff --git a/documentation updates aleo ambassadors/src/blog/images/ethereum_world_state.png b/documentation/concepts/images/ethereum_world_state.png similarity index 100% rename from documentation updates aleo ambassadors/src/blog/images/ethereum_world_state.png rename to documentation/concepts/images/ethereum_world_state.png diff --git a/documentation updates aleo ambassadors/src/blog/images/record.png b/documentation/concepts/images/record.png similarity index 100% rename from documentation updates aleo ambassadors/src/blog/images/record.png rename to documentation/concepts/images/record.png diff --git a/documentation updates aleo ambassadors/src/blog/images/transaction_in_aleo.png b/documentation/concepts/images/transaction_in_aleo.png similarity index 100% rename from documentation updates aleo ambassadors/src/blog/images/transaction_in_aleo.png rename to documentation/concepts/images/transaction_in_aleo.png diff --git a/documentation updates aleo ambassadors/src/blog/images/utxo.png b/documentation/concepts/images/utxo.png similarity index 100% rename from documentation updates aleo ambassadors/src/blog/images/utxo.png rename to documentation/concepts/images/utxo.png From f4ca0812b3d7076acc50a46e4f15cd050fcd0691 Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Wed, 10 Jul 2024 20:49:27 -0700 Subject: [PATCH 07/18] More cleanup --- .../src/blog/public_vs_private_state.md | 3 -- .../src/learn/concepts/accounts.md | 2 - .../src/learn/concepts/accounts_zh.md | 53 ------------------- .../src/learn/concepts/programs/README.md | 1 - .../src/learn/concepts/programs/deployment.md | 1 - .../src/learn/concepts/programs/execution.md | 1 - 6 files changed, 61 deletions(-) delete mode 100644 documentation updates aleo ambassadors/src/blog/public_vs_private_state.md delete mode 100644 documentation updates aleo ambassadors/src/learn/concepts/accounts_zh.md delete mode 100644 documentation updates aleo ambassadors/src/learn/concepts/programs/README.md delete mode 100644 documentation updates aleo ambassadors/src/learn/concepts/programs/deployment.md delete mode 100644 documentation updates aleo ambassadors/src/learn/concepts/programs/execution.md diff --git a/documentation updates aleo ambassadors/src/blog/public_vs_private_state.md b/documentation updates aleo ambassadors/src/blog/public_vs_private_state.md deleted file mode 100644 index 3d95da026..000000000 --- a/documentation updates aleo ambassadors/src/blog/public_vs_private_state.md +++ /dev/null @@ -1,3 +0,0 @@ -# Public vs. Private State - - diff --git a/documentation updates aleo ambassadors/src/learn/concepts/accounts.md b/documentation updates aleo ambassadors/src/learn/concepts/accounts.md index 82ba51090..cbd2c7d2a 100644 --- a/documentation updates aleo ambassadors/src/learn/concepts/accounts.md +++ b/documentation updates aleo ambassadors/src/learn/concepts/accounts.md @@ -1,6 +1,4 @@ --- -Author: [Cedric](syyanyuhui@gmail.com) -LastUpdate: 2024-05-06 --- ## Address Types in Aleo diff --git a/documentation updates aleo ambassadors/src/learn/concepts/accounts_zh.md b/documentation updates aleo ambassadors/src/learn/concepts/accounts_zh.md deleted file mode 100644 index 9e6cd1c5f..000000000 --- a/documentation updates aleo ambassadors/src/learn/concepts/accounts_zh.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -Author: [Cedric](syyanyuhui@gmail.com) -LastUpdate: 2024-05-06 ---- - -## Aleo的地址类型 - -在Aleo中存在两种地址类型,分别是用户地址和程序地址。 - -用户地址有唯一对应的ViewKey和PrivateKey。在Aleo网络中,我们可以创建具有隐私保护的程序,用户与程序的交互对于其他所有人都是不可见的。这里的**用户地址隐私性**是由ViewKey提供的,也就是说,谁拥有用户地址对应的ViewKey谁就拥有该地址的所有的可见性。PrivateKey是**用户地址所有权**的证明,谁拥有用户地址对应的PrivateKey谁就拥有该地址下的所有资产。Address、ViewKey、PrivateKey是根据密码学设计出来的紧密相关的一组数学对象。PrivateKey可以推导出ViewKey,ViewKey则可以推导出Address,这个过程是单向的,我们没有办法从Address反向推出ViewKey,或者根据ViewKey反向推出PrivateKey。 - - - -程序的地址由ProgramID通过安全的哈希算法而来,与用户地址不同,程序地址没有对应的ViewKey或者PrivateKey。更准确的来说,实际上存在与程序地址唯一确定的ViewKey和PrivateKey,但任何人都没有办法从程序地址推导出对应的ViewKey和PrivateKey。因为程序地址不存在PrivateKey和ViewKey,程序地址的资产完全由程序中所定义的逻辑进行控制,这对于在Aleo网络中构建去中心的Dapp,保护用户存放在Dapp中的资产非常重要。 - - - -## 如何在Aleo上存储资产? - -以Aleo Credits为例,用户地址可以同时拥有Private Balance和Public Balance,这两者之间可以随意进行转换,并且都可以用来支付Aleo网络的Fee。 - -Private Balance是基于Record Model实现的(类似于比特币的UTXO模型),我们可以将它类比为纸币。 - -Public Balance类似于以太坊的Account模型,我们可以将其类比于银行卡余额。 - -Record Model是类似于比特币UTXO的模型,但功能更加强大,我们可以在Program中定义Record并存储在定义的数据,并且在链上以加密的形式存在,只有Record的所有者地址对应的ViewKey才查看Record的具体信息以及是否被消耗。 - -Record的产生完全取决于Program是如何定义的。 - -Record的消耗则需要满足三个条件: - -- Record确实存在并且尚未被消耗 -- Record消耗需要满足程序的定义规则(如Aleo Credits转账,需要消耗一个Record同时产生两个Record,两个新产生的Record的金额之和等于消耗的Record的金额) -- 需要Record的Owner进行签名授权,只有Record的Owner可以消耗Record。 - -[Learn more about Record Model](TODO: Add link to record model) - - - -Public Balance以Mapping的形式存储,是公开可见的,每个地址对应一个条目。 - - - -## 支付Aleo网络费用 - -在Aleo网络中,用户需要使用Aleo Credits为他们的交易支付Fee。当用户发送交易时,交易由两部分组成,一部分是交易真正的负载信息,只能是Execution(调用一个Program)或者 是Deployment(部署一个Program),另一部分是Fee Transaction。Fee Transaction是特定的一个Transaction类型,不会单独存在,其中有一个参数是ExecutionID或者是DeploymentID,这个参数保证了Fee Transaction是为特定的Execution或者Deployment承担费用的,由此将Execution 和 Fee绑定起来。 - -``` -Transaction -- Execution || Deployment -- Fee(execution_id, fee_amount) -``` - diff --git a/documentation updates aleo ambassadors/src/learn/concepts/programs/README.md b/documentation updates aleo ambassadors/src/learn/concepts/programs/README.md deleted file mode 100644 index 19a7859d9..000000000 --- a/documentation updates aleo ambassadors/src/learn/concepts/programs/README.md +++ /dev/null @@ -1 +0,0 @@ -# Programs diff --git a/documentation updates aleo ambassadors/src/learn/concepts/programs/deployment.md b/documentation updates aleo ambassadors/src/learn/concepts/programs/deployment.md deleted file mode 100644 index d36c65e59..000000000 --- a/documentation updates aleo ambassadors/src/learn/concepts/programs/deployment.md +++ /dev/null @@ -1 +0,0 @@ -# Deployment diff --git a/documentation updates aleo ambassadors/src/learn/concepts/programs/execution.md b/documentation updates aleo ambassadors/src/learn/concepts/programs/execution.md deleted file mode 100644 index a2e753b62..000000000 --- a/documentation updates aleo ambassadors/src/learn/concepts/programs/execution.md +++ /dev/null @@ -1 +0,0 @@ -# Execution From 36bf175c68e130a057bbce6db227912bf59b3076 Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Wed, 10 Jul 2024 21:42:28 -0700 Subject: [PATCH 08/18] Fix --- documentation/sdk/typescript/00_sdk_overview.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/documentation/sdk/typescript/00_sdk_overview.md b/documentation/sdk/typescript/00_sdk_overview.md index 4206ce6ea..68c1337db 100644 --- a/documentation/sdk/typescript/00_sdk_overview.md +++ b/documentation/sdk/typescript/00_sdk_overview.md @@ -217,7 +217,7 @@ await initializeWasm(); /// Create a new Aleo account const account = new Account(); -```` +``` An example of how to initialize WebAssembly in a React app is shown in [Section 2.8](#28-React-Example) @@ -299,7 +299,6 @@ const executionResponse = await programManager.execute( ); const transaction = await programManager.networkClient.getTransaction(executionResponse); - ``` A reader of the above example may notice the `RecordProvider` and `KeyProvider` classes that were not present in the local @@ -401,7 +400,7 @@ export const useAleoWASM = () => { }, []); // eslint-disable-line react-hooks/exhaustive-deps return aleoInstance; }; -```` +``` Once a hook for the WASM initialization is created, it can be used anywhere within the app. #### Program Execution From 844542cace661e63bb9a7470ed96756d7d9e6c26 Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Wed, 10 Jul 2024 21:49:24 -0700 Subject: [PATCH 09/18] Fix --- documentation/concepts/02_records.md | 35 ++++++++++++++++------------ 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/documentation/concepts/02_records.md b/documentation/concepts/02_records.md index 5a3444b36..2efc3333b 100644 --- a/documentation/concepts/02_records.md +++ b/documentation/concepts/02_records.md @@ -29,15 +29,13 @@ An example record: } ``` -Owner -
+### Owner `aleo13ssze66adjjkt795z9u5wpq8h6kn0y2657726h4h3e3wfnez4vqsm3008q` The record owner is an account address, and specifies the party who is authorized to spend the record. -Data -
+### Data `100u64.private` The record can encode arbitrary application information. The "amount" key is the data payload that the record carries. @@ -45,8 +43,7 @@ An entry which has a `visibility` of `private` is encrypted and stored on the le This enables users to securely and privately transfer record data and values between one another over the public network. Only the sender and receiver with their corresponding account view keys are able to decrypt the private entries. -Nonce -
+### Nonce `5861592911433819692697358191094794940442348980903696700646555355124091569429group` The serial number nonce is used to create a unique identifier for each record, and is computed via a PRF evaluation of the address secret key ask of the owner and the record's serial number. @@ -75,7 +72,7 @@ There are two main state models used in blockchains - UTXO (unspent transaction Aleo uses a variation of the UTXO model - the record model. - +

Account vs UTXO

@@ -83,13 +80,15 @@ Aleo uses a variation of the UTXO model - the record model.

Source: galaxy.com

-
+
+
### Account Model In the account model as used in Ethereum, the application state can be found by referencing to a particular address. As such, anyone would be able to view the activities of any account, simply with the knowledge of the address. +

Ethereum Storage Diagram

@@ -97,7 +96,7 @@ As such, anyone would be able to view the activities of any account, simply with

Source: ethereum.org

-
+

@@ -108,13 +107,15 @@ Source: ethereum.o Source: Article by Lucas Saldanha

-
+
+ +
### Record Model In the record model, the application state, along with its owner are encrypted and stored on the blockchain. - +

Aleo Records Diagram

@@ -123,7 +124,7 @@ In the record model, the application state, along with its owner are encrypted a Source: Zexe: Enabling Decentralized Private Computation

-
+

@@ -134,13 +135,15 @@ Source: Zexe: Enabling Decentral

Source: Zexe: Enabling Decentralized Private Computation

-
+
+ +
### Updating State In the record model, applications update their state by consuming records containing the old state, and producing new records that contain the updated state. Records that have been used will be marked as spent and cannot be used again. - +

UTXO diagram

@@ -149,14 +152,16 @@ In the record model, applications update their state by consuming records contai Source: adapulse.io


+
The consumption and production of records is typically done in a transition function. A transaction in Aleo can contain up to 32 transitions, one of which is reserved for the transaction fee. - +

Transaction in Aleo

+
### Why is the Record Model Useful? From 8c4ddb7d079539d4925e5e98ebfabd2de5a1f808 Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Wed, 10 Jul 2024 21:51:18 -0700 Subject: [PATCH 10/18] Fix --- documentation/concepts/02_records.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/documentation/concepts/02_records.md b/documentation/concepts/02_records.md index 2efc3333b..e2283de4c 100644 --- a/documentation/concepts/02_records.md +++ b/documentation/concepts/02_records.md @@ -80,7 +80,7 @@ Aleo uses a variation of the UTXO model - the record model.

Source: galaxy.com

-
+

### Account Model @@ -96,7 +96,7 @@ As such, anyone would be able to view the activities of any account, simply with

Source: ethereum.org

-
+

@@ -107,7 +107,7 @@ Source: ethereum.o Source: Article by Lucas Saldanha

-
+

@@ -124,7 +124,7 @@ In the record model, the application state, along with its owner are encrypted a Source: Zexe: Enabling Decentralized Private Computation

-
+

@@ -135,7 +135,7 @@ Source: Zexe: Enabling Decentral

Source: Zexe: Enabling Decentralized Private Computation

-
+

@@ -151,7 +151,7 @@ In the record model, applications update their state by consuming records contai

Source: adapulse.io

-
+

The consumption and production of records is typically done in a transition function. A transaction in Aleo can contain up to 32 transitions, one of which is reserved for the transaction fee. From 94e808317e3b3b905f1b7f56325bade20202ba24 Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Wed, 10 Jul 2024 21:54:06 -0700 Subject: [PATCH 11/18] Fix --- documentation/concepts/02_records.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/documentation/concepts/02_records.md b/documentation/concepts/02_records.md index e2283de4c..55d8f8db7 100644 --- a/documentation/concepts/02_records.md +++ b/documentation/concepts/02_records.md @@ -74,7 +74,7 @@ Aleo uses a variation of the UTXO model - the record model.

-Account vs UTXO +Account vs UTXO

@@ -90,7 +90,7 @@ As such, anyone would be able to view the activities of any account, simply with

-Ethereum Storage Diagram +Ethereum Storage Diagram

@@ -100,7 +100,7 @@ Source: ethereum.o

-Ethereum World State Diagram +Ethereum World State Diagram

@@ -117,7 +117,7 @@ In the record model, the application state, along with its owner are encrypted a

-Aleo Records Diagram +Aleo Records Diagram

@@ -128,7 +128,7 @@ Source: Zexe: Enabling Decentral

-Aleo World State Diagram +Aleo World State Diagram

@@ -145,7 +145,7 @@ In the record model, applications update their state by consuming records contai

-UTXO diagram +UTXO diagram

@@ -159,7 +159,7 @@ The consumption and production of records is typically done in a transition func

-Transaction in Aleo +Transaction in Aleo

From f22c79f1ada52be62c6cd190eca4875516ce9ffb Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Wed, 10 Jul 2024 21:56:00 -0700 Subject: [PATCH 12/18] Fix --- documentation/sdk/typescript/00_sdk_overview.md | 1 - 1 file changed, 1 deletion(-) diff --git a/documentation/sdk/typescript/00_sdk_overview.md b/documentation/sdk/typescript/00_sdk_overview.md index 68c1337db..bad35c1e3 100644 --- a/documentation/sdk/typescript/00_sdk_overview.md +++ b/documentation/sdk/typescript/00_sdk_overview.md @@ -623,7 +623,6 @@ function App() { export default App; ``` -
#### Integrating Aleo Programs Into Your App From 9fad96c4c63bd4e52b48a51bd615b1740c46476e Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Wed, 10 Jul 2024 21:57:28 -0700 Subject: [PATCH 13/18] Fix --- documentation/sdk/typescript/00_sdk_overview.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/documentation/sdk/typescript/00_sdk_overview.md b/documentation/sdk/typescript/00_sdk_overview.md index bad35c1e3..51279ed89 100644 --- a/documentation/sdk/typescript/00_sdk_overview.md +++ b/documentation/sdk/typescript/00_sdk_overview.md @@ -517,7 +517,8 @@ Using both WebWorkers and SDK initialization in React, a single-page app can be
Example App.jsx Implementing Zero Knowledge Program Execution - + +`App.jsx` ```jsx import { useState } from "react"; import reactLogo from "./assets/react.svg"; From 6266c39c1e660c62017b451ce909e41a139dc56b Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Wed, 10 Jul 2024 21:58:39 -0700 Subject: [PATCH 14/18] Fix --- documentation/sdk/typescript/00_sdk_overview.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/documentation/sdk/typescript/00_sdk_overview.md b/documentation/sdk/typescript/00_sdk_overview.md index 51279ed89..7bc008122 100644 --- a/documentation/sdk/typescript/00_sdk_overview.md +++ b/documentation/sdk/typescript/00_sdk_overview.md @@ -649,9 +649,10 @@ module:{
Handling .aleo Types in TypeScript -`config.d.ts` If you are using TypeScript, you need to inform the TypeScript compiler about the type of content these files contain by declaring a module for *.aleo files: -``` + +`config.d.ts` +```typescript declare module '*.aleo' { const content: string; export default content; From e4415c8ec029e214cff2b9dbb51a7baa29b47f15 Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Wed, 10 Jul 2024 22:04:43 -0700 Subject: [PATCH 15/18] Fix --- documentation/concepts/02_records.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/documentation/concepts/02_records.md b/documentation/concepts/02_records.md index 55d8f8db7..e3fc2c7e8 100644 --- a/documentation/concepts/02_records.md +++ b/documentation/concepts/02_records.md @@ -72,7 +72,6 @@ There are two main state models used in blockchains - UTXO (unspent transaction Aleo uses a variation of the UTXO model - the record model. -

Account vs UTXO

@@ -81,14 +80,12 @@ Aleo uses a variation of the UTXO model - the record model. Source:
galaxy.com



-
### Account Model In the account model as used in Ethereum, the application state can be found by referencing to a particular address. As such, anyone would be able to view the activities of any account, simply with the knowledge of the address. -

Ethereum Storage Diagram

@@ -109,13 +106,11 @@ Source: Aleo Records Diagram

@@ -137,13 +132,11 @@ Source:
Zexe: Enabling Decentral



-
### Updating State In the record model, applications update their state by consuming records containing the old state, and producing new records that contain the updated state. Records that have been used will be marked as spent and cannot be used again. -

UTXO diagram

@@ -152,16 +145,13 @@ In the record model, applications update their state by consuming records contai Source:
adapulse.io



-
The consumption and production of records is typically done in a transition function. A transaction in Aleo can contain up to 32 transitions, one of which is reserved for the transaction fee. -

Transaction in Aleo

-
### Why is the Record Model Useful? From f23e8f377753d0778ef9369d719e82a58e24b4cb Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Wed, 10 Jul 2024 22:06:38 -0700 Subject: [PATCH 16/18] Fix --- documentation/concepts/02_records.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/documentation/concepts/02_records.md b/documentation/concepts/02_records.md index e3fc2c7e8..d91676fe6 100644 --- a/documentation/concepts/02_records.md +++ b/documentation/concepts/02_records.md @@ -73,7 +73,7 @@ There are two main state models used in blockchains - UTXO (unspent transaction Aleo uses a variation of the UTXO model - the record model.

-Account vs UTXO +Account vs UTXO

@@ -87,7 +87,7 @@ In the account model as used in Ethereum, the application state can be found by As such, anyone would be able to view the activities of any account, simply with the knowledge of the address.

-Ethereum Storage Diagram +Ethereum Storage Diagram

@@ -97,7 +97,7 @@ Source: ethereum.o

-Ethereum World State Diagram +Ethereum World State Diagram

@@ -112,7 +112,7 @@ Source: -Aleo Records Diagram +Aleo Records Diagram

@@ -123,7 +123,7 @@ Source: Zexe: Enabling Decentral

-Aleo World State Diagram +Aleo World State Diagram

@@ -138,7 +138,7 @@ Source: Zexe: Enabling Decentral In the record model, applications update their state by consuming records containing the old state, and producing new records that contain the updated state. Records that have been used will be marked as spent and cannot be used again.

-UTXO diagram +UTXO diagram

@@ -150,7 +150,7 @@ The consumption and production of records is typically done in a transition func

-Transaction in Aleo +Transaction in Aleo

### Why is the Record Model Useful? From 7ffcf2a79f34617c5f2ab70aa35b39e61ce3aedc Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Thu, 11 Jul 2024 07:15:20 -0700 Subject: [PATCH 17/18] Fix --- documentation/concepts/02_records.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/documentation/concepts/02_records.md b/documentation/concepts/02_records.md index d91676fe6..6cb854c69 100644 --- a/documentation/concepts/02_records.md +++ b/documentation/concepts/02_records.md @@ -73,7 +73,7 @@ There are two main state models used in blockchains - UTXO (unspent transaction Aleo uses a variation of the UTXO model - the record model.

-Account vs UTXO +Account vs UTXO

@@ -87,7 +87,7 @@ In the account model as used in Ethereum, the application state can be found by As such, anyone would be able to view the activities of any account, simply with the knowledge of the address.

-Ethereum Storage Diagram +Ethereum Storage Diagram

@@ -97,7 +97,7 @@ Source: ethereum.o

-Ethereum World State Diagram +Ethereum World State Diagram

@@ -112,7 +112,7 @@ Source: -Aleo Records Diagram +Aleo Records Diagram

@@ -123,7 +123,7 @@ Source: Zexe: Enabling Decentral

-Aleo World State Diagram +Aleo World State Diagram

From 70f6ff3b18037b9bdd4c64aaa560b85616b85ad1 Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Thu, 11 Jul 2024 07:18:33 -0700 Subject: [PATCH 18/18] Fix --- documentation/concepts/02_records.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/concepts/02_records.md b/documentation/concepts/02_records.md index 6cb854c69..b26df8961 100644 --- a/documentation/concepts/02_records.md +++ b/documentation/concepts/02_records.md @@ -138,7 +138,7 @@ Source: Zexe: Enabling Decentral In the record model, applications update their state by consuming records containing the old state, and producing new records that contain the updated state. Records that have been used will be marked as spent and cannot be used again.

-UTXO diagram +UTXO diagram

@@ -150,7 +150,7 @@ The consumption and production of records is typically done in a transition func

-Transaction in Aleo +Transaction in Aleo

### Why is the Record Model Useful?