From 5875c4ec42614c629a143f00bae1a23652f015d4 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Wed, 7 Feb 2024 09:55:33 -0300 Subject: [PATCH] Nicer API for broadcast functions --- boxes/package.json | 1 + boxes/yarn.lock | 21 ++++ yarn-project/aztec.js/src/api/deployment.ts | 1 + .../src/deployment/broadcast_function.ts | 118 ++++++++++++++++++ .../src/deployment/protocol_contracts.ts | 10 ++ .../aztec.js/src/deployment/register_class.ts | 9 +- .../__snapshots__/contract_class.test.ts.snap | 4 +- .../circuits.js/src/contract/artifact_hash.ts | 3 +- yarn-project/cli/src/cmds/unbox.ts | 2 + .../src/e2e_deploy_contract.test.ts | 107 +++------------- .../__snapshots__/index.test.ts.snap | 80 ++++++++++++ .../__snapshots__/index.test.ts.snap | 80 ++++++++++++ 12 files changed, 335 insertions(+), 101 deletions(-) create mode 100644 yarn-project/aztec.js/src/deployment/broadcast_function.ts create mode 100644 yarn-project/aztec.js/src/deployment/protocol_contracts.ts diff --git a/boxes/package.json b/boxes/package.json index 9b0417032de..f5c77e660e7 100644 --- a/boxes/package.json +++ b/boxes/package.json @@ -19,6 +19,7 @@ "@aztec/bb.js": "portal:../barretenberg/ts", "@aztec/circuit-types": "portal:../yarn-project/circuit-types", "@aztec/ethereum": "portal:../yarn-project/ethereum", + "@aztec/protocol-contracts": "portal:../yarn-project/protocol-contracts", "@aztec/types": "portal:../yarn-project/types" } } diff --git a/boxes/yarn.lock b/boxes/yarn.lock index 2b37f7139af..bdbf09c7ce4 100644 --- a/boxes/yarn.lock +++ b/boxes/yarn.lock @@ -70,6 +70,7 @@ __metadata: "@aztec/circuits.js": "workspace:^" "@aztec/ethereum": "workspace:^" "@aztec/foundation": "workspace:^" + "@aztec/protocol-contracts": "workspace:^" "@aztec/types": "workspace:^" tslib: "npm:^2.4.0" languageName: node @@ -289,6 +290,7 @@ __metadata: koa-router: "npm:^12.0.0" leveldown: "npm:^6.1.1" levelup: "npm:^5.1.1" + lodash.chunk: "npm:^4.2.0" lodash.clonedeepwith: "npm:^4.5.0" memdown: "npm:^6.1.1" pako: "npm:^2.1.0" @@ -297,6 +299,18 @@ __metadata: languageName: node linkType: soft +"@aztec/protocol-contracts@portal:../yarn-project/protocol-contracts::locator=%40aztec%2Fboxes%40workspace%3A.": + version: 0.0.0-use.local + resolution: "@aztec/protocol-contracts@portal:../yarn-project/protocol-contracts::locator=%40aztec%2Fboxes%40workspace%3A." + dependencies: + "@aztec/circuits.js": "workspace:^" + "@aztec/foundation": "workspace:^" + "@aztec/types": "workspace:^" + lodash.omit: "npm:^4.5.0" + tslib: "npm:^2.4.0" + languageName: node + linkType: soft + "@aztec/types@portal:../yarn-project/types::locator=%40aztec%2Fboxes%40workspace%3A.": version: 0.0.0-use.local resolution: "@aztec/types@portal:../yarn-project/types::locator=%40aztec%2Fboxes%40workspace%3A." @@ -9476,6 +9490,13 @@ __metadata: languageName: node linkType: hard +"lodash.omit@npm:^4.5.0": + version: 4.5.0 + resolution: "lodash.omit@npm:4.5.0" + checksum: 3808b9b6faae35177174b6ab327f1177e29c91f1e98dcbccf13a72a6767bba337306449d537a4e0d8a33d2673f10d39bc732e30c4b803274ea0c1168ea60e549 + languageName: node + linkType: hard + "lodash.times@npm:^4.3.2": version: 4.3.2 resolution: "lodash.times@npm:4.3.2" diff --git a/yarn-project/aztec.js/src/api/deployment.ts b/yarn-project/aztec.js/src/api/deployment.ts index 89d77f850e8..f0dd21091cb 100644 --- a/yarn-project/aztec.js/src/api/deployment.ts +++ b/yarn-project/aztec.js/src/api/deployment.ts @@ -1 +1,2 @@ export { registerContractClass } from '../deployment/register_class.js'; +export { broadcastPrivateFunction, broadcastUnconstrainedFunction } from '../deployment/broadcast_function.js'; diff --git a/yarn-project/aztec.js/src/deployment/broadcast_function.ts b/yarn-project/aztec.js/src/deployment/broadcast_function.ts new file mode 100644 index 00000000000..785cd1d2619 --- /dev/null +++ b/yarn-project/aztec.js/src/deployment/broadcast_function.ts @@ -0,0 +1,118 @@ +import { + ARTIFACT_FUNCTION_TREE_MAX_HEIGHT, + MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS, + computeArtifactFunctionTree, + computeArtifactFunctionTreeRoot, + computeArtifactMetadataHash, + computeFunctionArtifactHash, + computePrivateFunctionsTree, + getContractClassFromArtifact, +} from '@aztec/circuits.js'; +import { ContractArtifact, FunctionSelector, FunctionType, bufferAsFields } from '@aztec/foundation/abi'; +import { padArrayEnd } from '@aztec/foundation/collection'; +import { Fr } from '@aztec/foundation/fields'; + +import { ContractFunctionInteraction } from '../contract/contract_function_interaction.js'; +import { Wallet } from '../wallet/index.js'; +import { getRegistererContract } from './protocol_contracts.js'; + +/** + * Sets up a call to broadcast a private function's bytecode via the ClassRegisterer contract. + * Note that this is not required for users to call the function, but is rather a convenience to make + * this code publicly available so dapps or wallets do not need to redistribute it. + * @param wallet - Wallet to send the transaction. + * @param artifact - Contract artifact that contains the function to be broadcast. + * @param selector - Selector of the function to be broadcast. + * @returns A ContractFunctionInteraction object that can be used to send the transaction. + */ +export function broadcastPrivateFunction( + wallet: Wallet, + artifact: ContractArtifact, + selector: FunctionSelector, +): ContractFunctionInteraction { + const contractClass = getContractClassFromArtifact(artifact); + const privateFunction = contractClass.privateFunctions.find(fn => fn.selector.equals(selector)); + if (!privateFunction) { + throw new Error(`Private function with selector ${selector.toString()} not found`); + } + const privateFunctionArtifact = artifact.functions.find(fn => + FunctionSelector.fromNameAndParameters(fn).equals(selector), + )!; + + // TODO(@spalladino): The following is computing the unconstrained root hash twice. + // Feels like we need a nicer API for returning a hash along with all its preimages, + // since it's common to provide all hash preimages to a function that verifies them. + const artifactMetadataHash = computeArtifactMetadataHash(artifact); + const unconstrainedArtifactFunctionTreeRoot = computeArtifactFunctionTreeRoot(artifact, FunctionType.OPEN); + + // We need two sibling paths because private function information is split across two trees: + // The "private function tree" captures the selectors and verification keys, and is used in the kernel circuit for verifying the proof generated by the app circuit. + // The "artifact tree" captures function bytecode and metadata, and is used by the pxe to check that its executing the code it's supposed to be executing, but it never goes into circuits. + const privateFunctionTreePath = computePrivateFunctionsTree(contractClass.privateFunctions).getSiblingPath(0); + const artifactFunctionTreePath = computeArtifactFunctionTree(artifact, FunctionType.SECRET)!.getSiblingPath(0); + + const vkHash = privateFunction.vkHash; + const metadataHash = computeFunctionArtifactHash(privateFunctionArtifact); + const bytecode = bufferAsFields( + Buffer.from(privateFunctionArtifact.bytecode, 'hex'), + MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS, + ); + + const registerer = getRegistererContract(wallet); + return registerer.methods.broadcast_private_function( + contractClass.id, + Fr.fromBufferReduce(artifactMetadataHash), + Fr.fromBufferReduce(unconstrainedArtifactFunctionTreeRoot), + privateFunctionTreePath.map(Fr.fromBufferReduce), + padArrayEnd(artifactFunctionTreePath.map(Fr.fromBufferReduce), Fr.ZERO, ARTIFACT_FUNCTION_TREE_MAX_HEIGHT), + // eslint-disable-next-line camelcase + { selector, metadata_hash: Fr.fromBufferReduce(metadataHash), bytecode, vk_hash: vkHash }, + ); +} + +/** + * Sets up a call to broadcast an unconstrained function's bytecode via the ClassRegisterer contract. + * Note that this is not required for users to call the function, but is rather a convenience to make + * this code publicly available so dapps or wallets do not need to redistribute it. + * @param wallet - Wallet to send the transaction. + * @param artifact - Contract artifact that contains the function to be broadcast. + * @param selector - Selector of the function to be broadcast. + * @returns A ContractFunctionInteraction object that can be used to send the transaction. + */ +export function broadcastUnconstrainedFunction( + wallet: Wallet, + artifact: ContractArtifact, + selector: FunctionSelector, +): ContractFunctionInteraction { + const functionArtifactIndex = artifact.functions.findIndex( + fn => fn.functionType === FunctionType.UNCONSTRAINED && FunctionSelector.fromNameAndParameters(fn).equals(selector), + ); + if (functionArtifactIndex < 0) { + throw new Error(`Unconstrained function with selector ${selector.toString()} not found`); + } + const functionArtifact = artifact.functions[functionArtifactIndex]; + + // TODO(@spalladino): Same comment as above on computing duplicated hashes. + const artifactMetadataHash = computeArtifactMetadataHash(artifact); + const privateArtifactFunctionTreeRoot = computeArtifactFunctionTreeRoot(artifact, FunctionType.SECRET); + const functionTreePath = computeArtifactFunctionTree(artifact, FunctionType.UNCONSTRAINED)!.getSiblingPath( + functionArtifactIndex, + ); + + const contractClassId = getContractClassFromArtifact(artifact).id; + const metadataHash = computeFunctionArtifactHash(functionArtifact); + const bytecode = bufferAsFields( + Buffer.from(functionArtifact.bytecode, 'hex'), + MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS, + ); + + const registerer = getRegistererContract(wallet); + return registerer.methods.broadcast_unconstrained_function( + contractClassId, + Fr.fromBufferReduce(artifactMetadataHash), + Fr.fromBufferReduce(privateArtifactFunctionTreeRoot), + padArrayEnd(functionTreePath.map(Fr.fromBufferReduce), Fr.ZERO, ARTIFACT_FUNCTION_TREE_MAX_HEIGHT), + // eslint-disable-next-line camelcase + { selector, metadata_hash: Fr.fromBufferReduce(metadataHash), bytecode }, + ); +} diff --git a/yarn-project/aztec.js/src/deployment/protocol_contracts.ts b/yarn-project/aztec.js/src/deployment/protocol_contracts.ts new file mode 100644 index 00000000000..b14c64509f5 --- /dev/null +++ b/yarn-project/aztec.js/src/deployment/protocol_contracts.ts @@ -0,0 +1,10 @@ +import { getCanonicalClassRegisterer } from '@aztec/protocol-contracts/class-registerer'; + +import { UnsafeContract } from '../contract/unsafe_contract.js'; +import { Wallet } from '../wallet/index.js'; + +/** Returns a Contract wrapper for the class registerer. */ +export function getRegistererContract(wallet: Wallet) { + const { artifact, instance } = getCanonicalClassRegisterer(); + return new UnsafeContract(instance, artifact, wallet); +} diff --git a/yarn-project/aztec.js/src/deployment/register_class.ts b/yarn-project/aztec.js/src/deployment/register_class.ts index e3f13735aa6..4ac0532bef5 100644 --- a/yarn-project/aztec.js/src/deployment/register_class.ts +++ b/yarn-project/aztec.js/src/deployment/register_class.ts @@ -1,10 +1,9 @@ import { MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS, getContractClassFromArtifact } from '@aztec/circuits.js'; import { ContractArtifact, bufferAsFields } from '@aztec/foundation/abi'; -import { getCanonicalClassRegisterer } from '@aztec/protocol-contracts/class-registerer'; import { ContractFunctionInteraction } from '../contract/contract_function_interaction.js'; -import { UnsafeContract } from '../contract/unsafe_contract.js'; import { Wallet } from '../wallet/index.js'; +import { getRegistererContract } from './protocol_contracts.js'; /** Sets up a call to register a contract class given its artifact. */ export function registerContractClass(wallet: Wallet, artifact: ContractArtifact): ContractFunctionInteraction { @@ -14,9 +13,3 @@ export function registerContractClass(wallet: Wallet, artifact: ContractArtifact const registerer = getRegistererContract(wallet); return registerer.methods.register(artifactHash, privateFunctionsRoot, publicBytecodeCommitment, encodedBytecode); } - -/** Returns a Contract wrapper for the class registerer. */ -function getRegistererContract(wallet: Wallet) { - const { artifact, instance } = getCanonicalClassRegisterer(); - return new UnsafeContract(instance, artifact, wallet); -} diff --git a/yarn-project/circuits.js/src/contract/__snapshots__/contract_class.test.ts.snap b/yarn-project/circuits.js/src/contract/__snapshots__/contract_class.test.ts.snap index 9f9e8537ee8..acb681499c9 100644 --- a/yarn-project/circuits.js/src/contract/__snapshots__/contract_class.test.ts.snap +++ b/yarn-project/circuits.js/src/contract/__snapshots__/contract_class.test.ts.snap @@ -44,6 +44,8 @@ exports[`ContractClass creates a contract class from a contract compilation arti "isInternal": false } ], - "id": "0x09ad0dad993129857629f13ec2f3463d0c15615bd35266d0fb26c8793c6ee050" + "id": "0x09ad0dad993129857629f13ec2f3463d0c15615bd35266d0fb26c8793c6ee050", + "privateFunctionsRoot": "0x05fa82a96814b6294d557d507151f7ccc12f70522ec4d9d0395a90e87e8087c6", + "publicBytecodeCommitment": "0x05a06c2ee54a742daa2fa43a111c03335df68ff89fd8e7ba938ca2efb225c885" }" `; diff --git a/yarn-project/circuits.js/src/contract/artifact_hash.ts b/yarn-project/circuits.js/src/contract/artifact_hash.ts index f802ae40cf8..e51852a8aa6 100644 --- a/yarn-project/circuits.js/src/contract/artifact_hash.ts +++ b/yarn-project/circuits.js/src/contract/artifact_hash.ts @@ -40,7 +40,8 @@ export function computeArtifactHash(artifact: ContractArtifact): Fr { } export function computeArtifactMetadataHash(artifact: ContractArtifact) { - const metadata = { name: artifact.name, events: artifact.events }; // TODO(@spalladino): Should we use the sorted event selectors instead? They'd need to be unique for that. + // TODO(@spalladino): Should we use the sorted event selectors instead? They'd need to be unique for that. + const metadata = { name: artifact.name, events: artifact.events }; return sha256(Buffer.from(JSON.stringify(metadata), 'utf-8')); } diff --git a/yarn-project/cli/src/cmds/unbox.ts b/yarn-project/cli/src/cmds/unbox.ts index b1b6542b5e0..a04702d0e88 100644 --- a/yarn-project/cli/src/cmds/unbox.ts +++ b/yarn-project/cli/src/cmds/unbox.ts @@ -16,6 +16,7 @@ const resolutions: { [key: string]: string } = { '@aztec/bb.js': 'portal:.aztec-packages/barretenberg/ts', '@aztec/circuit-types': 'portal:.aztec-packages/yarn-project/circuit-types', '@aztec/ethereum': 'portal:.aztec-packages/yarn-project/ethereum', + '@aztec/protocol-contracts': 'portal:.aztec-packages/yarn-project/protocol-contracts', '@aztec/types': 'portal:.aztec-packages/yarn-project/types', }; @@ -71,6 +72,7 @@ function copyDependenciesToBox(dirName: string, destPath: string) { 'yarn-project/types', 'yarn-project/circuit-types', 'yarn-project/ethereum', + 'yarn-project/protocol-contracts', ].forEach(path => cpSync(dirName + '/../../../../' + path, destPath + '/.aztec-packages/' + path, { recursive: true, diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts index fd7d7783792..e493dece908 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts @@ -21,28 +21,15 @@ import { getContractInstanceFromDeployParams, isContractDeployed, } from '@aztec/aztec.js'; -import { registerContractClass } from '@aztec/aztec.js/deployment'; import { - ARTIFACT_FUNCTION_TREE_MAX_HEIGHT, - ContractClassIdPreimage, - MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS, - Point, - PublicKey, - computeArtifactFunctionTree, - computeArtifactFunctionTreeRoot, - computeArtifactMetadataHash, - computeFunctionArtifactHash, - computePrivateFunctionsTree, - computePublicKeysHash, -} from '@aztec/circuits.js'; + broadcastPrivateFunction, + broadcastUnconstrainedFunction, + registerContractClass, +} from '@aztec/aztec.js/deployment'; +import { ContractClassIdPreimage, Point, PublicKey, computePublicKeysHash } from '@aztec/circuits.js'; import { siloNullifier } from '@aztec/circuits.js/abis'; -import { FunctionSelector, FunctionType, bufferAsFields } from '@aztec/foundation/abi'; -import { padArrayEnd } from '@aztec/foundation/collection'; -import { - ContractClassRegistererContract, - ContractInstanceDeployerContract, - StatefulTestContract, -} from '@aztec/noir-contracts'; +import { FunctionSelector, FunctionType } from '@aztec/foundation/abi'; +import { ContractInstanceDeployerContract, StatefulTestContract } from '@aztec/noir-contracts'; import { TestContract, TestContractArtifact } from '@aztec/noir-contracts/Test'; import { TokenContractArtifact } from '@aztec/noir-contracts/Token'; import { SequencerClient } from '@aztec/sequencer-client'; @@ -272,24 +259,15 @@ describe('e2e_deploy_contract', () => { // These tests look scary, but don't fret: all this hodgepodge of calls will be hidden // behind a much nicer API in the near future as part of #4080. describe('registering a contract class', () => { - let registerer: ContractClassRegistererContract; let artifact: ContractArtifact; let contractClass: ContractClassWithId & ContractClassIdPreimage; - let registerTxHash: TxHash; beforeAll(async () => { artifact = StatefulTestContract.artifact; - const tx = await registerContractClass(wallet, artifact).send().wait(); + await registerContractClass(wallet, artifact).send().wait(); contractClass = getContractClassFromArtifact(artifact); - registerTxHash = tx.txHash; }, 60_000); - it('emits registered logs', async () => { - const logs = await pxe.getUnencryptedLogs({ txHash: registerTxHash }); - const registeredLog = logs.logs[0].log; // We need a nicer API! - expect(registeredLog.contractAddress).toEqual(registerer.address); - }); - it('registers the contract class on the node', async () => { const registeredClass = await aztecNode.getContractClass(contractClass.id); expect(registeredClass).toBeDefined(); @@ -300,72 +278,19 @@ describe('e2e_deploy_contract', () => { expect(registeredClass!.privateFunctions).toEqual([]); }); - it('broadcasts a private function and registers it on the node', async () => { - const privateFunction = contractClass.privateFunctions[0]; - const privateFunctionArtifact = artifact.functions.find(fn => - FunctionSelector.fromNameAndParameters(fn).equals(privateFunction.selector), - )!; - - // TODO(@spalladino): The following is computing the unconstrained root hash twice. - // Feels like we need a nicer API for returning a hash along with all its preimages, - // since it's common to provide all hash preimages to a function that verifies them. - const artifactMetadataHash = computeArtifactMetadataHash(artifact); - const unconstrainedArtifactFunctionTreeRoot = computeArtifactFunctionTreeRoot(artifact, FunctionType.OPEN); - - // We need two sibling paths because private function information is split across two trees: - // The "private function tree" captures the selectors and verification keys, and is used in the kernel circuit for verifying the proof generated by the app circuit. - // The "artifact tree" captures function bytecode and metadata, and is used by the pxe to check that its executing the code it's supposed to be executing, but it never goes into circuits. - const privateFunctionTreePath = computePrivateFunctionsTree(contractClass.privateFunctions).getSiblingPath(0); - const artifactFunctionTreePath = computeArtifactFunctionTree(artifact, FunctionType.SECRET)!.getSiblingPath(0); - - const selector = privateFunction.selector; - const metadataHash = computeFunctionArtifactHash(privateFunctionArtifact); - const bytecode = bufferAsFields( - Buffer.from(privateFunctionArtifact.bytecode, 'hex'), - MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS, - ); - const vkHash = privateFunction.vkHash; - - await registerer.methods - .broadcast_private_function( - contractClass.id, - Fr.fromBufferReduce(artifactMetadataHash), - Fr.fromBufferReduce(unconstrainedArtifactFunctionTreeRoot), - privateFunctionTreePath.map(Fr.fromBufferReduce), - padArrayEnd(artifactFunctionTreePath.map(Fr.fromBufferReduce), Fr.ZERO, ARTIFACT_FUNCTION_TREE_MAX_HEIGHT), - // eslint-disable-next-line camelcase - { selector, metadata_hash: Fr.fromBufferReduce(metadataHash), bytecode, vk_hash: vkHash }, - ) - .send() - .wait(); + it('broadcasts a private function', async () => { + const selector = contractClass.privateFunctions[0].selector; + await broadcastPrivateFunction(wallet, artifact, selector).send().wait(); + // TODO(#4428): Test that these functions are captured by the node and made available when + // requesting the corresponding contract class. }, 60_000); it('broadcasts an unconstrained function', async () => { const functionArtifact = artifact.functions.find(fn => fn.functionType === FunctionType.UNCONSTRAINED)!; - - // TODO(@spalladino): Same comment as above on computing duplicated hashes. - const artifactMetadataHash = computeArtifactMetadataHash(artifact); - const privateArtifactFunctionTreeRoot = computeArtifactFunctionTreeRoot(artifact, FunctionType.SECRET); - const functionTreePath = computeArtifactFunctionTree(artifact, FunctionType.UNCONSTRAINED)!.getSiblingPath(0); - const selector = FunctionSelector.fromNameAndParameters(functionArtifact); - const metadataHash = computeFunctionArtifactHash(functionArtifact); - const bytecode = bufferAsFields( - Buffer.from(functionArtifact.bytecode, 'hex'), - MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS, - ); - - await registerer.methods - .broadcast_unconstrained_function( - contractClass.id, - Fr.fromBufferReduce(artifactMetadataHash), - Fr.fromBufferReduce(privateArtifactFunctionTreeRoot), - padArrayEnd(functionTreePath.map(Fr.fromBufferReduce), Fr.ZERO, ARTIFACT_FUNCTION_TREE_MAX_HEIGHT), - // eslint-disable-next-line camelcase - { selector, metadata_hash: Fr.fromBufferReduce(metadataHash), bytecode }, - ) - .send() - .wait(); + await broadcastUnconstrainedFunction(wallet, artifact, selector).send().wait(); + // TODO(#4428): Test that these functions are captured by the node and made available when + // requesting the corresponding contract class. }, 60_000); describe('deploying a contract instance', () => { diff --git a/yarn-project/protocol-contracts/src/class-registerer/__snapshots__/index.test.ts.snap b/yarn-project/protocol-contracts/src/class-registerer/__snapshots__/index.test.ts.snap index 6292d1e68c6..1e0c5fe95d3 100644 --- a/yarn-project/protocol-contracts/src/class-registerer/__snapshots__/index.test.ts.snap +++ b/yarn-project/protocol-contracts/src/class-registerer/__snapshots__/index.test.ts.snap @@ -318,6 +318,86 @@ exports[`ClassRegisterer returns canonical protocol contract 1`] = ` }, }, ], + "privateFunctionsRoot": Fr { + "asBigInt": 14149643440615160691253002398502794418486578915412752764304101313202744681431n, + "asBuffer": { + "data": [ + 31, + 72, + 106, + 20, + 204, + 180, + 255, + 137, + 103, + 217, + 28, + 197, + 42, + 211, + 3, + 8, + 107, + 19, + 4, + 29, + 137, + 6, + 131, + 49, + 212, + 129, + 225, + 242, + 112, + 231, + 99, + 215, + ], + "type": "Buffer", + }, + }, + "publicBytecodeCommitment": Fr { + "asBigInt": 13424778679590722659186070167781649503057405647123863047387123265455936508181n, + "asBuffer": { + "data": [ + 29, + 174, + 39, + 204, + 127, + 226, + 175, + 52, + 95, + 22, + 2, + 83, + 190, + 56, + 117, + 212, + 73, + 167, + 233, + 186, + 107, + 214, + 135, + 71, + 216, + 125, + 78, + 112, + 84, + 184, + 17, + 21, + ], + "type": "Buffer", + }, + }, "publicFunctions": [], "version": 1, }, diff --git a/yarn-project/protocol-contracts/src/instance-deployer/__snapshots__/index.test.ts.snap b/yarn-project/protocol-contracts/src/instance-deployer/__snapshots__/index.test.ts.snap index 483d619e453..3ca5288c62a 100644 --- a/yarn-project/protocol-contracts/src/instance-deployer/__snapshots__/index.test.ts.snap +++ b/yarn-project/protocol-contracts/src/instance-deployer/__snapshots__/index.test.ts.snap @@ -226,6 +226,86 @@ exports[`InstanceDeployer returns canonical protocol contract 1`] = ` }, }, ], + "privateFunctionsRoot": Fr { + "asBigInt": 10175937322611504760053163396285173722489074882473725995897130952520062304283n, + "asBuffer": { + "data": [ + 22, + 127, + 96, + 93, + 15, + 118, + 143, + 145, + 206, + 97, + 129, + 56, + 23, + 230, + 12, + 1, + 170, + 115, + 219, + 197, + 231, + 133, + 116, + 128, + 74, + 71, + 30, + 51, + 115, + 5, + 128, + 27, + ], + "type": "Buffer", + }, + }, + "publicBytecodeCommitment": Fr { + "asBigInt": 13424778679590722659186070167781649503057405647123863047387123265455936508181n, + "asBuffer": { + "data": [ + 29, + 174, + 39, + 204, + 127, + 226, + 175, + 52, + 95, + 22, + 2, + 83, + 190, + 56, + 117, + 212, + 73, + 167, + 233, + 186, + 107, + 214, + 135, + 71, + 216, + 125, + 78, + 112, + 84, + 184, + 17, + 21, + ], + "type": "Buffer", + }, + }, "publicFunctions": [], "version": 1, },