diff --git a/src/boilerplate/common/bin/setup b/src/boilerplate/common/bin/setup index e915e4c56..6902324e7 100644 --- a/src/boilerplate/common/bin/setup +++ b/src/boilerplate/common/bin/setup @@ -38,8 +38,6 @@ cp docker-compose.zapp.override.default.yml docker-compose.zapp.override.yml cp entrypoint_default.sh entrypoint.sh -cp bin/default_startup bin/startup - perl -i -pe "s,docker-compose.zapp.yml -f docker-compose.zapp.override.yml,docker-compose.zapp.yml,g" package.json if [[ $network == 'mumbai' ]] || [[ $network == 'sepolia' ]] || [[ $network == 'goerli' ]] @@ -97,7 +95,5 @@ printf "\n${GREEN}*** Setup complete! Writing verification key to db... ***${NC} docker-compose -f docker-compose.zapp.yml run zapp-setup node /app/write-vk.mjs -i '' -CONSTRUCTOR_CALL - fi printf "\n${GREEN}*** Finished! ***${NC}\n" diff --git a/src/boilerplate/common/bin/startup b/src/boilerplate/common/bin/startup index 6c6ecfeec..999e1af10 100644 --- a/src/boilerplate/common/bin/startup +++ b/src/boilerplate/common/bin/startup @@ -10,6 +10,8 @@ docker-compose -f docker-compose.zapp.yml up -d zokrates sleep 5 +CONSTRUCTOR_CALL + docker-compose -f docker-compose.zapp.yml up -d deployer sleep 25 diff --git a/src/boilerplate/common/commitment-storage.mjs b/src/boilerplate/common/commitment-storage.mjs index b5545dcf7..f7e73d44d 100644 --- a/src/boilerplate/common/commitment-storage.mjs +++ b/src/boilerplate/common/commitment-storage.mjs @@ -12,6 +12,7 @@ import { poseidonHash } from './number-theory.mjs'; import { generateProof } from './zokrates.mjs'; import { SumType, reduceTree, toBinArray, poseidonConcatHash } from './smt_utils.mjs'; import { hlt } from './hash-lookup.mjs'; +import fs from "fs"; const { MONGO_URL, COMMITMENTS_DB, COMMITMENTS_COLLECTION } = config; const { generalise } = gen; @@ -879,3 +880,26 @@ export function getupdatedNullifierPaths(nullifier) { const witness = { path: membershipPath.path, root: root }; return witness; } +// This updates the nullifier Tree with constructor inputs +export async function addConstructorNullifiers() { + const constructorInput = JSON.parse( + fs.readFileSync("/app/orchestration/common/db/constructorTx.json", "utf-8") + ); + const { nullifiers } = constructorInput; + console.log(nullifiers); + const { isNullfiersAdded } = constructorInput; + if(isNullfiersAdded == false) + { + nullifiers.forEach(nullifier => { + smt_tree = insertLeaf(nullifier, smt_tree); + }) + temp_smt_tree = smt_tree; + console.log(getHash(smt_tree)); + constructorInput.isNullfiersAdded = true; + fs.writeFileSync( + "/app/orchestration/common/db/constructorTx.json", + JSON.stringify(constructorInput, null, 4) + ); + + } +} \ No newline at end of file diff --git a/src/boilerplate/common/services/generic-api_services.mjs b/src/boilerplate/common/services/generic-api_services.mjs index 6dba0b2a6..829d48a16 100644 --- a/src/boilerplate/common/services/generic-api_services.mjs +++ b/src/boilerplate/common/services/generic-api_services.mjs @@ -33,6 +33,7 @@ export async function service_FUNCTION_NAME (req, res, next){ try { await startEventFilter('CONTRACT_NAME'); const FUNCTION_SIG; + CONSTRUCTOR_INPUTS; const { tx , encEvent, _RESPONSE_} = await FUNCTION_NAME(FUNCTION_SIG); // prints the tx console.log(tx); diff --git a/src/boilerplate/orchestration/javascript/nodes/boilerplate-generator.ts b/src/boilerplate/orchestration/javascript/nodes/boilerplate-generator.ts index f19bff972..4c29082cc 100644 --- a/src/boilerplate/orchestration/javascript/nodes/boilerplate-generator.ts +++ b/src/boilerplate/orchestration/javascript/nodes/boilerplate-generator.ts @@ -304,6 +304,7 @@ export function buildBoilerplateNode(nodeType: string, fields: any = {}): any { case 'IntegrationApiServicesBoilerplate': { const { contractName, + functionNames = [], functions = [], constructorParams = [], contractImports = [], @@ -311,6 +312,7 @@ export function buildBoilerplateNode(nodeType: string, fields: any = {}): any { return { nodeType, contractName, + functionNames, functions, constructorParams, contractImports, @@ -350,6 +352,7 @@ export function buildBoilerplateNode(nodeType: string, fields: any = {}): any { parameters = buildNode('ParameterList', fields), returnParameters = buildNode('ParameterList', fields), decrementsSecretState = [], + isConstructor = false, } = fields; return { nodeType, @@ -357,6 +360,7 @@ export function buildBoilerplateNode(nodeType: string, fields: any = {}): any { parameters, returnParameters, decrementsSecretState, + isConstructor }; } case 'IntegrationApiRoutesFunction': { diff --git a/src/boilerplate/orchestration/javascript/raw/boilerplate-generator.ts b/src/boilerplate/orchestration/javascript/raw/boilerplate-generator.ts index 958aac764..3e99f917c 100644 --- a/src/boilerplate/orchestration/javascript/raw/boilerplate-generator.ts +++ b/src/boilerplate/orchestration/javascript/raw/boilerplate-generator.ts @@ -570,6 +570,7 @@ sendTransaction = { mappingKey, burnedOnly, structProperties, + isConstructor }): string[] { let value; switch (stateType) { @@ -706,7 +707,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, reinstateNullifiers, getBalance, getBalanceByState, } 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, getBalance, getBalanceByState, addConstructorNullifiers } 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(). */ @@ -824,11 +825,6 @@ integrationApiRoutesBoilerplate = { zappFilesBoilerplate = () => { return [ - { - readPath: pathPrefix + '/bin/startup', - writePath: '/bin/startup', - generic: true, - }, { readPath: pathPrefix + '/bin/startup', writePath: '/bin/default_startup', diff --git a/src/boilerplate/orchestration/javascript/raw/toOrchestration.ts b/src/boilerplate/orchestration/javascript/raw/toOrchestration.ts index 4278b6f12..7531efc7c 100644 --- a/src/boilerplate/orchestration/javascript/raw/toOrchestration.ts +++ b/src/boilerplate/orchestration/javascript/raw/toOrchestration.ts @@ -598,6 +598,7 @@ export const OrchestrationCodeBoilerPlate: any = (node: any) => { : ``, burnedOnly: false, structProperties: stateNode.structProperties, + isConstructor: node.isConstructor, })); break; @@ -613,6 +614,7 @@ export const OrchestrationCodeBoilerPlate: any = (node: any) => { : ``, burnedOnly: false, structProperties: stateNode.structProperties, + isConstructor: node.isConstructor, })); break; @@ -630,6 +632,7 @@ export const OrchestrationCodeBoilerPlate: any = (node: any) => { : ``, burnedOnly: stateNode.burnedOnly, structProperties: stateNode.structProperties, + isConstructor: node.isConstructor, })); } } @@ -834,7 +837,7 @@ export const OrchestrationCodeBoilerPlate: any = (node: any) => { if (node.functionName === 'cnstrctr') return { statements: [ `\n\n// Save transaction for the constructor: - \nconst tx = { proofInput: [${params[0][0]}${params[0][1]} ${params[0][2]} ${params[0][3]} proof], ${node.publicInputs?.map(input => `${input}: ${input}.integer,`)}};` + \nconst tx = { proofInput: [${params[0][0]}${params[0][1]} ${params[0][2]} ${params[0][3]} proof], nullifiers: ${params[0][1]} isNullfiersAdded: false, ${node.publicInputs?.map(input => `${input}: ${input}.integer,`)}};` ] } diff --git a/src/codeGenerators/orchestration/files/toOrchestration.ts b/src/codeGenerators/orchestration/files/toOrchestration.ts index e964763d0..be6ec6b17 100644 --- a/src/codeGenerators/orchestration/files/toOrchestration.ts +++ b/src/codeGenerators/orchestration/files/toOrchestration.ts @@ -129,7 +129,7 @@ const prepareIntegrationTest = (node: any) => { }; const prepareIntegrationApiServices = (node: any) => { - // import generic test skeleton + // import generic test skeletonfr const genericApiServiceFile: any = Orchestrationbp.integrationApiServicesBoilerplate; // replace references to contract and functions with ours let outputApiServiceFile = genericApiServiceFile.preStatements().replace( @@ -141,7 +141,8 @@ const prepareIntegrationApiServices = (node: any) => { relevantFunctions.forEach((fn: any) => { let fnboilerplate = genericApiServiceFile.postStatements() .replace(/CONTRACT_NAME/g, node.contractName) - .replace(/FUNCTION_NAME/g, fn.name); + .replace(/FUNCTION_NAME/g, fn.name) + .replace(/CONSTRUCTOR_INPUTS/g, node.functionNames.includes('cnstrctr') ? `await addConstructorNullifiers();` : ``); let fnParam: string[] = []; let structparams; const paramName = fn.parameters.parameters.map((obj: any) => obj.name); @@ -354,6 +355,7 @@ const prepareMigrationsFile = (file: localFile, node: any) => { customProofImport += `const constructorInput = JSON.parse( fs.readFileSync('/app/orchestration/common/db/constructorTx.json', 'utf-8'), ); + \nconst { proofInput } = constructorInput;`; iwsConstructorParams?.forEach((param: any) => { customProofImport += `\nconst { ${param.name} } = constructorInput;` @@ -375,7 +377,7 @@ const prepareMigrationsFile = (file: localFile, node: any) => { * @param node - a SetupCommonFilesBoilerplate node */ -const prepareSetupScript = (file: localFile, node: any) => { +const prepareStartupScript = (file: localFile, node: any) => { let constructorCall = ``; if (!node.functionNames.includes('cnstrctr')) { file.file = file.file.replace(/CONSTRUCTOR_CALL/g, ``); @@ -392,6 +394,7 @@ const prepareSetupScript = (file: localFile, node: any) => { file.file = file.file.replace(/CONSTRUCTOR_CALL/g, constructorCall); } + /** * @param {string} file - a stringified file * @param {string} contextDirPath - the import statements of the `file` will be @@ -408,8 +411,6 @@ export default function fileGenerator(node: any) { .filter((x: any) => x.nodeType !== 'NonSecretFunction') .flatMap(fileGenerator)); - - case 'File': return [ { @@ -440,8 +441,11 @@ export default function fileGenerator(node: any) { 'orchestration', ); - const readPath = path.resolve(fileURLToPath(import.meta.url), '../../../../../src/boilerplate/common/bin/setup'); - const startupScript = { filepath: 'bin/setup', file: fs.readFileSync(readPath, 'utf8') }; + let readPath = path.resolve(fileURLToPath(import.meta.url), '../../../../../src/boilerplate/common/bin/setup'); + const setupScript = { filepath: 'bin/setup', file: fs.readFileSync(readPath, 'utf8') }; + files.push(setupScript); + readPath = path.resolve(fileURLToPath(import.meta.url), '../../../../../src/boilerplate/common/bin/startup'); + const startupScript = { filepath: 'bin/startup', file: fs.readFileSync(readPath, 'utf8') }; files.push(startupScript); const vkfile = files.filter(obj => obj.filepath.includes(`write-vk`))[0]; const setupfile = files.filter(obj => @@ -454,7 +458,7 @@ export default function fileGenerator(node: any) { 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); + prepareStartupScript(redeployFile, node); files.push(redeployFile); } // replace placeholder values with ours @@ -468,7 +472,7 @@ export default function fileGenerator(node: any) { ); // build the migrations file prepareMigrationsFile(migrationsfile, node); - prepareSetupScript(startupScript, node); + prepareStartupScript(startupScript, node); return files; } diff --git a/src/transformers/visitors/toOrchestrationVisitor.ts b/src/transformers/visitors/toOrchestrationVisitor.ts index 8a9caec82..8946c90c9 100644 --- a/src/transformers/visitors/toOrchestrationVisitor.ts +++ b/src/transformers/visitors/toOrchestrationVisitor.ts @@ -458,6 +458,7 @@ const visitor = { } } if (file.nodes?.[0].nodeType === 'IntegrationApiServicesBoilerplate') { + file.nodes?.[0].functionNames.push(node.fileName); for (const fn of file.nodes[0].functions) { if (fn.name === node.fileName) thisIntegrationApiServiceFunction = fn; } diff --git a/test/contracts/Assign.zol b/test/contracts/Assign.zol index 1d99e7667..af00b923c 100644 --- a/test/contracts/Assign.zol +++ b/test/contracts/Assign.zol @@ -12,4 +12,5 @@ contract Assign { function remove(secret uint256 value) public { a -= value; } + }