From 5bad3e344ee5842d86aebe443bb001e27d1e735b Mon Sep 17 00:00:00 2001 From: Alex Gherghisan Date: Fri, 13 Oct 2023 17:31:37 +0100 Subject: [PATCH] feat: add deployed contract to PXE from CLI (#2850) Please provide a paragraph or two giving a summary of the change, including relevant motivation and context. # Checklist: Remove the checklist to signal you've completed it. Enable auto-merge if the PR is ready to merge. - [ ] If the pull request requires a cryptography review (e.g. cryptographic algorithm implementations) I have added the 'crypto' tag. - [ ] I have reviewed my diff in github, line by line and removed unexpected formatting changes, testing logs, or commented-out code. - [ ] Every change is related to the PR description. - [ ] I have [linked](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) this pull request to relevant issues (if any exist). --- yarn-project/cli/src/index.ts | 42 ++++++++++++++++++++++++++++++++--- yarn-project/cli/src/utils.ts | 16 ++++++++++++- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/yarn-project/cli/src/index.ts b/yarn-project/cli/src/index.ts index 5fe1099d6bd..04ebfed912a 100644 --- a/yarn-project/cli/src/index.ts +++ b/yarn-project/cli/src/index.ts @@ -1,6 +1,8 @@ import { + AztecAddress, Contract, ContractDeployer, + EthAddress, Fr, GrumpkinScalar, NotePreimage, @@ -33,6 +35,7 @@ import { getFunctionArtifact, getTxSender, parseAztecAddress, + parseEthereumAddress, parseField, parseFields, parseOptionalAztecAddress, @@ -218,14 +221,19 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command { const args = encodeArgs(rawArgs, constructorArtifact!.parameters); debugLogger(`Encoded arguments: ${args.join(', ')}`); - const tx = deployer.deploy(...args).send({ contractAddressSalt: salt }); + const deploy = deployer.deploy(...args); + + await deploy.create({ contractAddressSalt: salt }); + const tx = deploy.send({ contractAddressSalt: salt }); const txHash = await tx.getTxHash(); debugLogger(`Deploy tx sent with hash ${txHash}`); if (wait) { const deployed = await tx.wait(); - log(`\nContract deployed at ${deployed.contractAddress!.toString()}\n`); + log(`\nContract deployed at ${deployed.contract.completeAddress.address.toString()}\n`); + log(`Contract partial address ${deployed.contract.completeAddress.partialAddress.toString()}\n`); } else { - log(`\nContract Address: ${tx.completeContractAddress?.address.toString() ?? 'N/A'}`); + log(`\nContract Address: ${deploy.completeAddress?.address.toString() ?? 'N/A'}`); + log(`Contract Partial Address: ${deploy.completeAddress?.partialAddress.toString() ?? 'N/A'}`); log(`Deployment transaction hash: ${txHash}\n`); } }); @@ -247,6 +255,34 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command { else log(`\nNo contract found at ${address.toString()}\n`); }); + program + .command('add-contract') + .description( + 'Adds an existing contract to the PXE. This is useful if you have deployed a contract outside of the PXE and want to use it with the PXE.', + ) + .requiredOption( + '-c, --contract-artifact ', + "A compiled Aztec.nr contract's ABI in JSON format or name of a contract ABI exported by @aztec/noir-contracts", + ) + .requiredOption('-ca, --contract-address
', 'Aztec address of the contract.', parseAztecAddress) + .requiredOption('-pa, --partial-address
', 'Partial address of the contract', parsePartialAddress) + .option('-p, --public-key ', 'Optional public key for this contract', parsePublicKey) + .option('--portal-address
', 'Optional address to a portal contract on L1', parseEthereumAddress) + .addOption(pxeOption) + .action(async options => { + const artifact = await getContractArtifact(options.contractArtifact, log); + const contractAddress: AztecAddress = options.contractAddress; + const completeAddress = new CompleteAddress( + contractAddress, + options.publicKey ?? Fr.ZERO, + options.partialAddress, + ); + const portalContract: EthAddress = options.portalContract ?? EthAddress.ZERO; + const client = await createCompatibleClient(options.rpcUrl, debugLogger); + + await client.addContracts([{ artifact, completeAddress, portalContract }]); + log(`\nContract added to PXE at ${contractAddress.toString()}\n`); + }); program .command('get-tx-receipt') .description('Gets the receipt for the specified transaction hash.') diff --git a/yarn-project/cli/src/utils.ts b/yarn-project/cli/src/utils.ts index 708212b212c..6c9d81cdae5 100644 --- a/yarn-project/cli/src/utils.ts +++ b/yarn-project/cli/src/utils.ts @@ -1,4 +1,4 @@ -import { AztecAddress, Fr, FunctionSelector, GrumpkinScalar, PXE, Point, TxHash } from '@aztec/aztec.js'; +import { AztecAddress, EthAddress, Fr, FunctionSelector, GrumpkinScalar, PXE, Point, TxHash } from '@aztec/aztec.js'; import { L1ContractArtifactsForDeployment, createEthereumChain, deployL1Contracts } from '@aztec/ethereum'; import { ContractArtifact } from '@aztec/foundation/abi'; import { DebugLogger, LogFn } from '@aztec/foundation/log'; @@ -211,6 +211,20 @@ export function parseAztecAddress(address: string): AztecAddress { } } +/** + * Parses an Ethereum address from a string. + * @param address - A serialized Ethereum address + * @returns An Ethereum address + * @throws InvalidArgumentError if the input string is not valid. + */ +export function parseEthereumAddress(address: string): EthAddress { + try { + return EthAddress.fromString(address); + } catch { + throw new InvalidArgumentError(`Invalid address: ${address}`); + } +} + /** * Parses an AztecAddress from a string. * @param address - A serialized Aztec address