From 0ca840d989ae4f0bb99bf3f98ab8d8a5d9c68cb3 Mon Sep 17 00:00:00 2001 From: Miranda Wood Date: Wed, 17 May 2023 17:32:33 +0100 Subject: [PATCH 1/7] doc: update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a412a5f08..fe0cf1f3c 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ _Solidity contract --> Zolidity contract --> zappify --> zApp_ The main objective of this transpiler is to enable developers to quickly draft frameworks for zApps. -See [here](./doc/WRITEUP.md) for an enormously detailed explanation of how the transpiler works. +See [here](https://starlight-3.gitbook.io/starlight/) for the gitbook, and [here](./doc/WRITEUP.md) for an enormously detailed explanation of how the transpiler works. --- From 0da9854e3f4fd0216fffd1d27b6edb7a0ae63745 Mon Sep 17 00:00:00 2001 From: Miranda Wood Date: Wed, 17 May 2023 17:34:30 +0100 Subject: [PATCH 2/7] doc: change writeup link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fe0cf1f3c..ef2122cfe 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ _Solidity contract --> Zolidity contract --> zappify --> zApp_ The main objective of this transpiler is to enable developers to quickly draft frameworks for zApps. -See [here](https://starlight-3.gitbook.io/starlight/) for the gitbook, and [here](./doc/WRITEUP.md) for an enormously detailed explanation of how the transpiler works. +See [here](https://starlight-3.gitbook.io/starlight/) for the gitbook, and [here](https://starlight-3.gitbook.io/starlight/doc/writeup/) for an enormously detailed explanation of how the transpiler works. --- From 274ca28910bad2160fd0573737ea9736fc90c99b Mon Sep 17 00:00:00 2001 From: Miranda Wood Date: Wed, 17 May 2023 17:42:55 +0100 Subject: [PATCH 3/7] Rename CONTRIBUTIONS.md to doc/CONTRIBUTIONS.md --- CONTRIBUTIONS.md => doc/CONTRIBUTIONS.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename CONTRIBUTIONS.md => doc/CONTRIBUTIONS.md (100%) diff --git a/CONTRIBUTIONS.md b/doc/CONTRIBUTIONS.md similarity index 100% rename from CONTRIBUTIONS.md rename to doc/CONTRIBUTIONS.md From d19e5e50149ede56a4630dea9738f8baeecad084 Mon Sep 17 00:00:00 2001 From: Miranda Wood Date: Wed, 17 May 2023 17:44:00 +0100 Subject: [PATCH 4/7] Rename SECURITY.md to doc/SECURITY.md --- SECURITY.md => doc/SECURITY.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename SECURITY.md => doc/SECURITY.md (100%) diff --git a/SECURITY.md b/doc/SECURITY.md similarity index 100% rename from SECURITY.md rename to doc/SECURITY.md From acb29536bcac524a5a8cb675386e04f712feaff0 Mon Sep 17 00:00:00 2001 From: MirandaWood Date: Thu, 22 Jun 2023 11:51:05 +0100 Subject: [PATCH 5/7] feat: added redeployment scripts --- README.md | 12 ++++++++++++ src/boilerplate/common/bin/redeploy | 3 +++ src/boilerplate/common/boilerplate-package.json | 1 + .../orchestration/files/toOrchestration.ts | 7 +++++++ 4 files changed, 23 insertions(+) create mode 100755 src/boilerplate/common/bin/redeploy diff --git a/README.md b/README.md index b89668ad3..06810676f 100644 --- a/README.md +++ b/README.md @@ -327,6 +327,18 @@ You can also filter these commitments by variable name. Using the example above, ``` as a GET request to `http://localhost:3000/getCommitmentsByVariableName`. +#### Using secret states in the constructor + +Starlight handles secret initiation in the constructor by creating a proof at the setup stage. Any user supplied inputs will be prompted for in the command line when running `./bin/setup`. + +Since this inevitably creates a commitment to be sent your local db, simply restarting the zapp will **not** work. The blockchain will be aware of the constructor commitment, but your zapp will not. + +If you would like to restart the zapp and redeploy the contract, always (with no running docker containers) run: + +`./bin/redeploy` <-- creates a new constructor proof and saves the commitment, then deploys the shield contract + +`npm run restart` <-- if you'd like to use the APIs, always **restart** rather than **start** since the latter clears your local dbs + #### Deploy on public testnets Apart from local ganache instance, Starlight output zapps can be now be deployed in Sepolia, Goerli and Polygon Mumbai as cli options. Connection to Sepolia and Goerli are made through [infura](https://infura.io/) endpoints and that of Polygon Mumbai is provided via [maticvigil](https://rpc.maticvigil.com/). diff --git a/src/boilerplate/common/bin/redeploy b/src/boilerplate/common/bin/redeploy new file mode 100755 index 000000000..b2c1fe639 --- /dev/null +++ b/src/boilerplate/common/bin/redeploy @@ -0,0 +1,3 @@ +#!/bin/sh +set -e +CONSTRUCTOR_CALL && docker-compose -f docker-compose.zapp.yml up -d deployer diff --git a/src/boilerplate/common/boilerplate-package.json b/src/boilerplate/common/boilerplate-package.json index 78c9e1308..4fd12f56f 100644 --- a/src/boilerplate/common/boilerplate-package.json +++ b/src/boilerplate/common/boilerplate-package.json @@ -5,6 +5,7 @@ "test": "./bin/startup && docker-compose -f docker-compose.zapp.yml run zapp npx mocha --exit --require @babel/register 'orchestration/test.mjs'", "retest": "docker-compose -f docker-compose.zapp.yml run zapp npx mocha --exit --require @babel/register 'orchestration/test.mjs'", "start": "./bin/startup && docker-compose -f docker-compose.zapp.yml run --name apiservice -p 3000:3000 zapp node orchestration/api.mjs", + "restart": "docker-compose -f docker-compose.zapp.yml run --name apiservice -p 3000:3000 zapp node orchestration/api.mjs", "apitest": "./bin/setup && ./bin/startup && docker-compose -f docker-compose.zapp.yml run --name apiservice -d -p 3000:3000 zapp node orchestration/api.mjs" }, "keywords": [ diff --git a/src/codeGenerators/orchestration/files/toOrchestration.ts b/src/codeGenerators/orchestration/files/toOrchestration.ts index 97566a3c2..f7dec41a9 100644 --- a/src/codeGenerators/orchestration/files/toOrchestration.ts +++ b/src/codeGenerators/orchestration/files/toOrchestration.ts @@ -435,6 +435,13 @@ export default function fileGenerator(node: any) { const migrationsfile = files.filter(obj => obj.filepath.includes(`shield`), )[0]; + + if (node.functionNames.includes('cnstrctr')) { + const redeployPath = path.resolve(fileURLToPath(import.meta.url), '../../../../../src/boilerplate/common/bin/redeploy'); + const redeployFile = { filepath: 'bin/redeploy', file: fs.readFileSync(redeployPath, 'utf8') }; + prepareSetupScript(redeployFile, node); + files.push(redeployFile); + } // replace placeholder values with ours vkfile.file = vkfile.file.replace( /FUNCTION_NAMES/g, From 3d42310e41e63e4297003f4bc6f5f9ccce05d303 Mon Sep 17 00:00:00 2001 From: MirandaWood Date: Tue, 18 Jul 2023 14:15:36 +0100 Subject: [PATCH 6/7] feat: added reinstate nullifier method + docs --- README.md | 2 ++ .../common/boilerplate-package.json | 2 +- src/boilerplate/common/commitment-storage.mjs | 34 +++++++++++++++++++ .../javascript/raw/boilerplate-generator.ts | 27 +++++++++++++-- src/transformers/toOrchestration.ts | 2 ++ .../visitors/toOrchestrationVisitor.ts | 6 ++++ 6 files changed, 69 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 06810676f..ac11cfd29 100644 --- a/README.md +++ b/README.md @@ -339,6 +339,8 @@ If you would like to restart the zapp and redeploy the contract, always (with no `npm run restart` <-- if you'd like to use the APIs, always **restart** rather than **start** since the latter clears your local dbs +Then, if you previously had nullifiers, reinstate them in your local sparse merkle tree by sending a POST to `http://localhost:3000/reinstateNullifiers`. + #### Deploy on public testnets Apart from local ganache instance, Starlight output zapps can be now be deployed in Sepolia, Goerli and Polygon Mumbai as cli options. Connection to Sepolia and Goerli are made through [infura](https://infura.io/) endpoints and that of Polygon Mumbai is provided via [maticvigil](https://rpc.maticvigil.com/). diff --git a/src/boilerplate/common/boilerplate-package.json b/src/boilerplate/common/boilerplate-package.json index 4fd12f56f..a0e69de31 100644 --- a/src/boilerplate/common/boilerplate-package.json +++ b/src/boilerplate/common/boilerplate-package.json @@ -5,7 +5,7 @@ "test": "./bin/startup && docker-compose -f docker-compose.zapp.yml run zapp npx mocha --exit --require @babel/register 'orchestration/test.mjs'", "retest": "docker-compose -f docker-compose.zapp.yml run zapp npx mocha --exit --require @babel/register 'orchestration/test.mjs'", "start": "./bin/startup && docker-compose -f docker-compose.zapp.yml run --name apiservice -p 3000:3000 zapp node orchestration/api.mjs", - "restart": "docker-compose -f docker-compose.zapp.yml run --name apiservice -p 3000:3000 zapp node orchestration/api.mjs", + "restart": "docker rm apiservice && docker-compose -f docker-compose.zapp.yml run --name apiservice -p 3000:3000 zapp node orchestration/api.mjs", "apitest": "./bin/setup && ./bin/startup && docker-compose -f docker-compose.zapp.yml run --name apiservice -d -p 3000:3000 zapp node orchestration/api.mjs" }, "keywords": [ diff --git a/src/boilerplate/common/commitment-storage.mjs b/src/boilerplate/common/commitment-storage.mjs index 469e3630c..a51db2048 100644 --- a/src/boilerplate/common/commitment-storage.mjs +++ b/src/boilerplate/common/commitment-storage.mjs @@ -16,6 +16,7 @@ const { MONGO_URL, COMMITMENTS_DB, COMMITMENTS_COLLECTION } = config; const { generalise } = gen; const TRUNC_LENGTH = 32; // Just for testing so we don't make more than 32 deep smt trees. +const WHOLE_STATES = [WHOLE_STATE_NAMES]; // structure for SMT const Branch = (leftTree, rightTree) => ({ tag: 'branch', @@ -96,6 +97,17 @@ export async function getCommitmentsByState(name, mappingKey = null) { return commitments; } +// function to retrieve all known nullified commitments +export async function getNullifiedCommitments() { + const connection = await mongo.connection(MONGO_URL); + const db = connection.db(COMMITMENTS_DB); + const commitments = await db + .collection(COMMITMENTS_COLLECTION) + .find({ isNullified: true }) + .toArray(); + return commitments; +} + /** * @returns all the commitments existent in this database. */ @@ -532,6 +544,28 @@ export async function temporaryUpdateNullifier(nullifier){ } +export async function reinstateNullifiers() { + const initialised = []; + const nullifiedCommitments = await getNullifiedCommitments(); + if (!nullifiedCommitments) { + logger.info('No nullifiers to add to the tree'); + return; + } + logger.warn( + 'Reinstatiating nullifiers - NOTE that any nullifiers added from another client may not be known here, so the tree will be out of sync.', + ); + for (const c of nullifiedCommitments) { + if (WHOLE_STATES.includes(c.name) && !initialised.includes(c.preimage.stateVarId)) { + logger.debug(`initialising state ${c.name}`); + smt_tree = insertLeaf(poseidonHash([BigInt(c.preimage.stateVarId), BigInt(0), BigInt(0)]).hex(32), smt_tree); + initialised.push(c.preimage.stateVarId); + } + logger.debug(`nullifying state ${c.name}: ${c.nullifier}`); + smt_tree = insertLeaf(c.nullifier, smt_tree); + } + temp_smt_tree = smt_tree; +} + export function getupdatedNullifierPaths(nullifier){ const binArr = toBinArray(generalise(nullifier)); const padBinArr = Array(254 - binArr.length) diff --git a/src/boilerplate/orchestration/javascript/raw/boilerplate-generator.ts b/src/boilerplate/orchestration/javascript/raw/boilerplate-generator.ts index 4bcf7f1ad..a5bef90b0 100644 --- a/src/boilerplate/orchestration/javascript/raw/boilerplate-generator.ts +++ b/src/boilerplate/orchestration/javascript/raw/boilerplate-generator.ts @@ -693,7 +693,7 @@ integrationApiServicesBoilerplate = { ` }, preStatements(): string{ - return ` import { startEventFilter, getSiblingPath } from './common/timber.mjs';\nimport fs from "fs";\nimport logger from './common/logger.mjs';\nimport { decrypt } from "./common/number-theory.mjs";\nimport { getAllCommitments, getCommitmentsByState } from "./common/commitment-storage.mjs";\nimport web3 from './common/web3.mjs';\n\n + return ` import { startEventFilter, getSiblingPath } from './common/timber.mjs';\nimport fs from "fs";\nimport logger from './common/logger.mjs';\nimport { decrypt } from "./common/number-theory.mjs";\nimport { getAllCommitments, getCommitmentsByState, reinstateNullifiers } from "./common/commitment-storage.mjs";\nimport web3 from './common/web3.mjs';\n\n /** NOTE: this is the api service file, if you need to call any function use the correct url and if Your input contract has two functions, add() and minus(). minus() cannot be called before an initial add(). */ @@ -740,7 +740,21 @@ integrationApiServicesBoilerplate = { logger.error(err); res.send({ errors: [err.message] }); } - }`; + } + + export async function service_reinstateNullifiers(req, res, next) { + try { + await reinstateNullifiers(); + res.send('Complete'); + await sleep(10); + } catch (err) { + logger.error(err); + res.send({ errors: [err.message] }); + } + }` + + + ; } @@ -759,12 +773,14 @@ integrationApiRoutesBoilerplate = { (fs.readFileSync(apiRoutesReadPath, 'utf8').match(/router.post?[\s\S]*/g)|| [])[0]}` }, commitmentImports(): string { - return `import { service_allCommitments, service_getCommitmentsByState } from "./api_services.mjs";\n`; + return `import { service_allCommitments, service_getCommitmentsByState, service_reinstateNullifiers } from "./api_services.mjs";\n`; }, commitmentRoutes(): string { return `// commitment getter routes router.get("/getAllCommitments", service_allCommitments); router.get("/getCommitmentsByVariableName", service_getCommitmentsByState); + // nullifier route + router.post("/reinstateNullifiers", service_reinstateNullifiers); `; } }; @@ -851,6 +867,11 @@ zappFilesBoilerplate = () => { writePath: './orchestration/api.mjs', generic: true, }, + { + readPath: pathPrefix + '/commitment-storage.mjs', + writePath: './orchestration/common/commitment-storage.mjs', + generic: false, + }, ]; } diff --git a/src/transformers/toOrchestration.ts b/src/transformers/toOrchestration.ts index 3d1fb0a91..f8626f018 100644 --- a/src/transformers/toOrchestration.ts +++ b/src/transformers/toOrchestration.ts @@ -63,6 +63,7 @@ export default function toOrchestration(ast: any, options: any) { const contractName = `${ contractNode.name.charAt(0).toUpperCase() + contractNode.name.slice(1) }Shield`; + const wholeStateNames = contractNode._newASTPointer.wholeNullified; // copy over existing backend files to the output dir: logger.verbose( @@ -79,6 +80,7 @@ export default function toOrchestration(ast: any, options: any) { if (!fileObj.generic) { file = file.replace(/CONTRACT_NAME/g, contractName); file = file.replace(/FUNCTION_NAME/g, options.zappName); + file = file.replace(/WHOLE_STATE_NAMES/g, wholeStateNames ? wholeStateNames.map(n => `'${n}'`).join(', ') : ''); } const dir = pathjs.dirname(filepath); logger.debug(`About to save to ${filepath}...`); diff --git a/src/transformers/visitors/toOrchestrationVisitor.ts b/src/transformers/visitors/toOrchestrationVisitor.ts index 451a5e93e..a498cc357 100644 --- a/src/transformers/visitors/toOrchestrationVisitor.ts +++ b/src/transformers/visitors/toOrchestrationVisitor.ts @@ -240,6 +240,7 @@ const visitor = { exit(path: NodePath, state: any) { const { node } = path; + node._newASTPointer.wholeNullified = state.wholeNullified; for (const file of node._newASTPointer) { if (file.nodeType === 'SetupCommonFilesBoilerplate') { file.constructorParams = state.constructorParams; @@ -445,6 +446,11 @@ const visitor = { || ''; } + if (stateVarIndicator.isWhole && stateVarIndicator.isNullified) { + state.wholeNullified ??= []; + if (!state.wholeNullified.includes(name)) state.wholeNullified.push(name) + } + let { incrementsArray, incrementsString } = isIncremented ? collectIncrements(stateVarIndicator) : { incrementsArray: null, incrementsString: null }; From a6ecd0caa58aee2fcec3def6ec05d447bce36973 Mon Sep 17 00:00:00 2001 From: Duncan Westland Date: Thu, 19 Oct 2023 09:13:01 +0100 Subject: [PATCH 7/7] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index ecd7dd1a0..45735aa5c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +_This code is not owned by EY and EY provides no warranty and disclaims any and all liability for use of this code. Users must conduct their own diligence with respect to use for their purposes and any and all usage is on an as-is basis and at your own risk._ + # starlight :stars: Generate a zApp from a Solidity contract.