Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion boxes/boxes/react/src/hooks/useNumber.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export function useNumber({ contract }: { contract: Contract }) {

setWait(true);
const deployerWallet = await deployerEnv.getWallet();
const viewTxReceipt = await contract!.methods.getNumber(deployerWallet.getCompleteAddress()).view();
const viewTxReceipt = await contract!.methods.getNumber(deployerWallet.getCompleteAddress()).simulate();
toast(`Number is: ${viewTxReceipt.value}`);
setWait(false);
};
Expand Down
2 changes: 1 addition & 1 deletion boxes/boxes/react/tests/node.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('BoxReact Contract Tests', () => {
}, 40000);

test('Can read a number', async () => {
const viewTxReceipt = await contract.methods.getNumber(wallet.getCompleteAddress()).view();
const viewTxReceipt = await contract.methods.getNumber(wallet.getCompleteAddress()).simulate();
expect(numberToSet.toBigInt()).toEqual(viewTxReceipt.value);
}, 40000);
});
2 changes: 1 addition & 1 deletion boxes/boxes/vanilla/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,6 @@ document.querySelector('#set').addEventListener('submit', async (e: Event) => {
});

document.querySelector('#get').addEventListener('click', async () => {
const viewTxReceipt = await contract.methods.getNumber(wallet.getCompleteAddress().address).view();
const viewTxReceipt = await contract.methods.getNumber(wallet.getCompleteAddress().address).simulate();
alert(`Number is: ${viewTxReceipt.value}`);
});
2 changes: 1 addition & 1 deletion docs/docs/developers/tutorials/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ WARN Error processing tx 06dc87c4d64462916ea58426ffcfaf20017880b353c9ec3e0f0ee5f

### State

We can check private or public state directly rather than going through view-only methods, as we did in the initial example by calling `token.methods.balance().view()`. Bear in mind that directly accessing contract storage will break any kind of encapsulation.
We can check private or public state directly rather than going through view-only methods, as we did in the initial example by calling `token.methods.balance().simulate()`. Bear in mind that directly accessing contract storage will break any kind of encapsulation.

To query storage directly, you'll need to know the slot you want to access. This can be checked in the [contract's `Storage` definition](../contracts/writing_contracts/storage/main.md) directly for most data types. However, when it comes to mapping types, as in most EVM languages, we'll need to calculate the slot for a given key. To do this, we'll use the [`CheatCodes`](../sandbox/references/cheat_codes.md) utility class:

Expand Down
4 changes: 2 additions & 2 deletions docs/docs/misc/migration_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -935,13 +935,13 @@ To parse a `AztecAddress` to BigInt, use `.inner`
Before:

```js
const tokenBigInt = await bridge.methods.token().view();
const tokenBigInt = await bridge.methods.token().simulate();
```

Now:

```js
const tokenBigInt = (await bridge.methods.token().view()).inner;
const tokenBigInt = (await bridge.methods.token().simulate()).inner;
```

### [Aztec.nr] Add `protocol_types` to Nargo.toml
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/accounts/src/testing/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export async function deployInitialTestAccounts(pxe: PXE) {
skipPublicDeployment: true,
universalDeploy: true,
});
await deployMethod.simulate({});
await deployMethod.prove({});
return deployMethod;
}),
);
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/accounts/src/testing/create_account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export async function createAccounts(pxe: PXE, numberOfAccounts = 1): Promise<Ac
// the results get stored within the account object. By calling it here we increase the probability of all the
// accounts being deployed in the same block because it makes the deploy() method basically instant.
await account.getDeployMethod().then(d =>
d.simulate({
d.prove({
contractAddressSalt: account.salt,
skipClassRegistration: true,
skipPublicDeployment: true,
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/aztec.js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ const tx = await contract.methods.transfer(amount, recipientAddress).send().wait
console.log(`Transferred ${amount} to ${recipientAddress} on block ${tx.blockNumber}`);
```

### Call a view function
### Simulate a function

```typescript
import { Contract } from '@aztec/aztec.js';

const contract = await Contract.at(contractAddress, MyContractArtifact, wallet);
const balance = await contract.methods.get_balance(wallet.getAddress()).view();
const balance = await contract.methods.get_balance(wallet.getAddress()).simulate();
console.log(`Account balance is ${balance}`);
```
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ export abstract class BaseContractInteraction {
public abstract create(options?: SendMethodOptions): Promise<TxExecutionRequest>;

/**
* Simulates a transaction execution request and returns a tx object ready to be sent.
* Proves a transaction execution request and returns a tx object ready to be sent.
* @param options - optional arguments to be used in the creation of the transaction
* @returns The resulting transaction
*/
public async simulate(options: SendMethodOptions = {}): Promise<Tx> {
public async prove(options: SendMethodOptions = {}): Promise<Tx> {
const txRequest = this.txRequest ?? (await this.create(options));
this.tx = await this.pxe.simulateTx(txRequest, !options.skipPublicSimulation);
this.tx = await this.pxe.proveTx(txRequest, !options.skipPublicSimulation);
return this.tx;
}

Expand All @@ -58,7 +58,7 @@ export abstract class BaseContractInteraction {
*/
public send(options: SendMethodOptions = {}) {
const promise = (async () => {
const tx = this.tx ?? (await this.simulate(options));
const tx = this.tx ?? (await this.prove(options));
return this.pxe.sendTx(tx);
})();

Expand Down
14 changes: 4 additions & 10 deletions yarn-project/aztec.js/src/contract/contract.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Tx, TxExecutionRequest, TxHash, TxReceipt } from '@aztec/circuit-types';
import { AztecAddress, CompleteAddress, EthAddress } from '@aztec/circuits.js';
import { L1ContractAddresses } from '@aztec/ethereum';
import { ABIParameterVisibility, ContractArtifact, FunctionType } from '@aztec/foundation/abi';
import { ABIParameterVisibility, ContractArtifact, DecodedReturn, FunctionType } from '@aztec/foundation/abi';
import { NodeInfo } from '@aztec/types/interfaces';

import { MockProxy, mock } from 'jest-mock-extended';
Expand Down Expand Up @@ -113,10 +113,10 @@ describe('Contract Class', () => {
wallet.createTxExecutionRequest.mockResolvedValue(mockTxRequest);
wallet.getContractInstance.mockResolvedValue(contractInstance);
wallet.sendTx.mockResolvedValue(mockTxHash);
wallet.viewTx.mockResolvedValue(mockViewResultValue);
wallet.viewTx.mockResolvedValue(mockViewResultValue as any as DecodedReturn);
wallet.getTxReceipt.mockResolvedValue(mockTxReceipt);
wallet.getNodeInfo.mockResolvedValue(mockNodeInfo);
wallet.simulateTx.mockResolvedValue(mockTx);
wallet.proveTx.mockResolvedValue(mockTx);
wallet.getRegisteredAccounts.mockResolvedValue([account]);
});

Expand All @@ -137,7 +137,7 @@ describe('Contract Class', () => {

it('should call view on an unconstrained function', async () => {
const fooContract = await Contract.at(contractAddress, defaultArtifact, wallet);
const result = await fooContract.methods.qux(123n).view({
const result = await fooContract.methods.qux(123n).simulate({
from: account.address,
});
expect(wallet.viewTx).toHaveBeenCalledTimes(1);
Expand All @@ -149,10 +149,4 @@ describe('Contract Class', () => {
const fooContract = await Contract.at(contractAddress, defaultArtifact, wallet);
await expect(fooContract.methods.qux().create()).rejects.toThrow();
});

it('should not call view on a secret or open function', async () => {
const fooContract = await Contract.at(contractAddress, defaultArtifact, wallet);
expect(() => fooContract.methods.bar().view()).toThrow();
expect(() => fooContract.methods.baz().view()).toThrow();
});
});
38 changes: 12 additions & 26 deletions yarn-project/aztec.js/src/contract/contract_function_interaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,35 +63,22 @@ export class ContractFunctionInteraction extends BaseContractInteraction {
}

/**
* Execute a view (read-only) transaction on an unconstrained function.
* This method is used to call functions that do not modify the contract state and only return data.
* Throws an error if called on a non-unconstrained function.
* Simulate a transaction and get its return values
* @param options - An optional object containing additional configuration for the transaction.
* @returns The result of the view transaction as returned by the contract function.
*/
public view(options: ViewMethodOptions = {}) {
if (this.functionDao.functionType !== FunctionType.UNCONSTRAINED) {
throw new Error('Can only call `view` on an unconstrained function.');
public async simulate(options: ViewMethodOptions = {}): Promise<any> {
if (this.functionDao.functionType == FunctionType.UNCONSTRAINED) {
return this.wallet.viewTx(this.functionDao.name, this.args, this.contractAddress, options.from);
}

const { from } = options;
return this.wallet.viewTx(this.functionDao.name, this.args, this.contractAddress, from);
}

/**
* Execute a view (read-only) transaction on an unconstrained function.
* This method is used to call functions that do not modify the contract state and only return data.
* Throws an error if called on a non-unconstrained function.
* @param options - An optional object containing additional configuration for the transaction.
* @returns The result of the view transaction as returned by the contract function.
*/
public async viewConstrained(options: ViewMethodOptions = {}) {
const packedArgs = PackedArguments.fromArgs(encodeArguments(this.functionDao, this.args));
// TODO: If not unconstrained, we return a size 4 array of fields.
// TODO: It should instead return the correctly decoded value
// TODO: The return type here needs to be fixed! @LHerskind

const a = FunctionData.fromAbi(this.functionDao);

if (a.isPrivate) {
if (this.functionDao.functionType == FunctionType.SECRET) {
const nodeInfo = await this.wallet.getNodeInfo();
const packedArgs = PackedArguments.fromArgs(encodeArguments(this.functionDao, this.args));

const txRequest = TxExecutionRequest.from({
argsHash: packedArgs.hash,
Expand All @@ -101,12 +88,11 @@ export class ContractFunctionInteraction extends BaseContractInteraction {
packedArguments: [packedArgs],
authWitnesses: [],
});

const vue = await this.pxe.simulateCall(txRequest, options.from ?? this.wallet.getAddress());
const vue = await this.pxe.simulateTx(txRequest, false, options.from ?? this.wallet.getAddress());
return vue.privateReturnValues && vue.privateReturnValues[0];
} else {
await this.create();
const vue = await this.pxe.simulateCall(this.txRequest!);
const txRequest = await this.create();
const vue = await this.pxe.simulateTx(txRequest, true);
return vue.publicReturnValues && vue.publicReturnValues[0];
}
}
Expand Down
8 changes: 4 additions & 4 deletions yarn-project/aztec.js/src/contract/deploy_method.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,12 +193,12 @@ export class DeployMethod<TContract extends ContractBase = Contract> extends Bas
}

/**
* Simulate the request.
* Prove the request.
* @param options - Deployment options.
* @returns The simulated tx.
* @returns The proven tx.
*/
public simulate(options: DeployOptions): Promise<Tx> {
return super.simulate(options);
public prove(options: DeployOptions): Promise<Tx> {
return super.prove(options);
}

/** Return this deployment address. */
Expand Down
6 changes: 3 additions & 3 deletions yarn-project/aztec.js/src/contract/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
*
* The {@link Contract} class is the main class in this module, and provides static methods for deploying
* a contract or interacting with an already deployed one. The `methods` property of the contract instance
* provides access to private, public, and view methods, that can be invoked in a transaction via `send()`,
* or can be queried via `view()`.
* provides access to private, public, and simulate methods, that can be invoked in a transaction via `send()`,
* or can be queried via `simulate()`.
*
* ```ts
* const contract = await Contract.deploy(wallet, MyContractArtifact, [...constructorArgs]).send().deployed();
Expand All @@ -17,7 +17,7 @@
* ```ts
* const contract = await Contract.at(address, MyContractArtifact, wallet);
* await contract.methods.mint(1000, owner).send().wait();
* console.log(`Total supply is now ${await contract.methods.totalSupply().view()}`);
* console.log(`Total supply is now ${await contract.methods.totalSupply().simulate()}`);
* ```
*
* The result of calling a method in a contract instance, such as `contract.methods.mint(1000, owner)`
Expand Down
3 changes: 2 additions & 1 deletion yarn-project/aztec.js/src/rpc_clients/pxe_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
TxHash,
TxReceipt,
UnencryptedL2BlockL2Logs,
Vue,
} from '@aztec/circuit-types';
import {
AztecAddress,
Expand Down Expand Up @@ -53,7 +54,7 @@ export const createPXEClient = (url: string, fetch = makeFetch([1, 2, 3], false)
TxExecutionRequest,
TxHash,
},
{ Tx, TxReceipt, EncryptedL2BlockL2Logs, UnencryptedL2BlockL2Logs, NullifierMembershipWitness },
{ Tx, Vue, TxReceipt, EncryptedL2BlockL2Logs, UnencryptedL2BlockL2Logs, NullifierMembershipWitness },
false,
'pxe',
fetch,
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/aztec.js/src/wallet/account_wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ export class AccountWallet extends BaseWallet {
messageHash,
]);

const [isValidInPrivate, isValidInPublic] = await interaction.view();
const [isValidInPrivate, isValidInPublic] = (await interaction.simulate()) as [boolean, boolean];
return { isValidInPrivate, isValidInPublic };
}

Expand Down
8 changes: 4 additions & 4 deletions yarn-project/aztec.js/src/wallet/base_wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,11 @@ export abstract class BaseWallet implements Wallet {
getContracts(): Promise<AztecAddress[]> {
return this.pxe.getContracts();
}
simulateTx(txRequest: TxExecutionRequest, simulatePublic: boolean): Promise<Tx> {
return this.pxe.simulateTx(txRequest, simulatePublic);
proveTx(txRequest: TxExecutionRequest, simulatePublic: boolean): Promise<Tx> {
return this.pxe.proveTx(txRequest, simulatePublic);
}
simulateCall(txRequest: TxExecutionRequest, msgSender: AztecAddress): Promise<Vue> {
return this.pxe.simulateCall(txRequest, msgSender);
simulateTx(txRequest: TxExecutionRequest, simulatePublic: boolean, msgSender: AztecAddress): Promise<Vue> {
return this.pxe.simulateTx(txRequest, simulatePublic, msgSender);
}
sendTx(tx: Tx): Promise<TxHash> {
return this.pxe.sendTx(tx);
Expand Down
6 changes: 3 additions & 3 deletions yarn-project/aztec/src/examples/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,18 @@ async function main() {
await tokenAlice.methods.redeem_shield(alice, ALICE_MINT_BALANCE, aliceSecret).send().wait();
logger(`${ALICE_MINT_BALANCE} tokens were successfully minted and redeemed by Alice`);

const balanceAfterMint = await tokenAlice.methods.balance_of_private(alice).view();
const balanceAfterMint = await tokenAlice.methods.balance_of_private(alice).simulate();
logger(`Tokens successfully minted. New Alice's balance: ${balanceAfterMint}`);

// We will now transfer tokens from Alice to Bob
logger(`Transferring ${TRANSFER_AMOUNT} tokens from Alice to Bob...`);
await tokenAlice.methods.transfer(alice, bob, TRANSFER_AMOUNT, 0).send().wait();

// Check the new balances
const aliceBalance = await tokenAlice.methods.balance_of_private(alice).view();
const aliceBalance = await tokenAlice.methods.balance_of_private(alice).simulate();
logger(`Alice's balance ${aliceBalance}`);

const bobBalance = await tokenBob.methods.balance_of_private(bob).view();
const bobBalance = await tokenBob.methods.balance_of_private(bob).simulate();
logger(`Bob's balance ${bobBalance}`);
}

Expand Down
2 changes: 1 addition & 1 deletion yarn-project/circuit-types/src/interfaces/aztec-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
PUBLIC_DATA_TREE_HEIGHT,
} from '@aztec/circuits.js';
import { L1ContractAddresses } from '@aztec/ethereum';
import { DecodedReturn, ProcessReturnValues } from '@aztec/foundation/abi';
import { ProcessReturnValues } from '@aztec/foundation/abi';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { Fr } from '@aztec/foundation/fields';
import { ContractClassPublic, ContractInstanceWithAddress } from '@aztec/types/contracts';
Expand Down
18 changes: 5 additions & 13 deletions yarn-project/circuit-types/src/interfaces/pxe.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AztecAddress, CompleteAddress, Fr, GrumpkinPrivateKey, PartialAddress } from '@aztec/circuits.js';
import { ContractArtifact, ProcessReturnValues } from '@aztec/foundation/abi';
import { ContractArtifact } from '@aztec/foundation/abi';
import { ContractClassWithId, ContractInstanceWithAddress } from '@aztec/types/contracts';
import { NodeInfo } from '@aztec/types/interfaces';

Expand All @@ -8,19 +8,11 @@ import { L2Block } from '../l2_block.js';
import { GetUnencryptedLogsResponse, LogFilter } from '../logs/index.js';
import { ExtendedNote } from '../notes/index.js';
import { NoteFilter } from '../notes/note_filter.js';
import { Tx, TxHash, TxReceipt } from '../tx/index.js';
import { Tx, TxHash, TxReceipt, Vue } from '../tx/index.js';
import { TxEffect } from '../tx_effect.js';
import { TxExecutionRequest } from '../tx_execution_request.js';
import { SyncStatus } from './sync-status.js';

export class Vue {
constructor(
public tx: Tx,
public privateReturnValues?: ProcessReturnValues,
public publicReturnValues?: ProcessReturnValues,
) {}
}

// docs:start:pxe-interface
/**
* Private eXecution Environment (PXE) runs locally for each user, providing functionality for all the operations
Expand Down Expand Up @@ -147,12 +139,12 @@ export interface PXE {
* @throws If the code for the functions executed in this transaction has not been made available via `addContracts`.
* Also throws if simulatePublic is true and public simulation reverts.
*/
simulateTx(txRequest: TxExecutionRequest, simulatePublic: boolean): Promise<Tx>;
simulateCall(txRequest: TxExecutionRequest, msgSender?: AztecAddress): Promise<Vue>;
proveTx(txRequest: TxExecutionRequest, simulatePublic: boolean): Promise<Tx>;
simulateTx(txRequest: TxExecutionRequest, simulatePublic: boolean, msgSender?: AztecAddress): Promise<Vue>;

/**
* Sends a transaction to an Aztec node to be broadcasted to the network and mined.
* @param tx - The transaction as created via `simulateTx`.
* @param tx - The transaction as created via `proveTx`.
* @returns A hash of the transaction, used to identify it.
*/
sendTx(tx: Tx): Promise<TxHash>;
Expand Down
Loading