Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Update aztec sandbox getting started markdown #2374

Merged
merged 4 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 2 additions & 2 deletions docs/docs/dev_docs/dapps/tutorials/contract_interaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ In this section, we'll write the logic in our app that will interact with the co

## Showing user balance

Let's start by showing our user balance for the private token across their accounts. To do this, we can leverage the `getBalance` [unconstrained](../../contracts/functions.md#unconstrained-functions) view function of the private token contract:
Let's start by showing our user balance for the private token across their accounts. To do this, we can leverage the `balance_of_private` [unconstrained](../../contracts/functions.md#unconstrained-functions) view function of the private token contract:

#include_code getBalance yarn-project/noir-contracts/src/contracts/private_token_contract/src/main.nr rust
#include_code balance_of_private yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr rust

:::info
Note that this function will only return a valid response for accounts registered in the RPC Server, since it requires access to the [user's private state](../../wallets/main.md#private-state). In other words, you cannot query the balance of another user for a private token contract.
Expand Down
177 changes: 106 additions & 71 deletions docs/docs/dev_docs/getting_started/sandbox.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ With the help of Aztec.js you will be able to:

## I have the Sandbox running, show me how to use it!

We will deploy a private token contract, and send tokens privately, using the Sandbox.
We will deploy a token contract, and send tokens privately, using the Sandbox.

Writing the contract itself is out of scope for this tutorial, so we will use a Private Token Contract which has been pre-supplied as an example. See [here](../contracts/main.md) for more information on how to write contracts for Aztec.
Writing the contract itself is out of scope for this tutorial, so we will use a Token Contract which has been pre-supplied as an example. See [here](../contracts/main.md) for more information on how to write contracts for Aztec.

The following should work for MacOS, Linux or even WSL2 Ubuntu under Windows.

Let's create an empty project called `private-token`. If you are familiar with setting up Typescript projects then you can skip to step 6.
Let's create an empty project called `token`. If you are familiar with setting up Typescript projects then you can skip to step 6.

Although both `yarn` and `npm` would work, this example uses `yarn`. Open the terminal and do the following

Expand All @@ -79,18 +79,18 @@ node -v
2. Initialize a yarn project

```sh
mkdir private-token
cd private-token
mkdir token
cd token
yarn init
```

This should ask a series of questions that you can fill like so:

```
yarn init v1.22.19
question name (private-token):
question name (token):
question version (1.0.0):
question description: My first private token contract
question description: My first token contract
question entry point (index.js):
question repository url:
question author: Phil
Expand All @@ -100,7 +100,7 @@ success Saved package.json
Done in 23.60s.
```

3. Create a `src` folder inside your new `private-token` directory:
3. Create a `src` folder inside your new `token` directory:

```sh
mkdir src
Expand Down Expand Up @@ -144,9 +144,9 @@ Add a `tsconfig.json` file into the project root, here is an example:

```json
{
"name": "private-token",
"name": "token",
"version": "1.0.0",
"description": "My first private token contract",
"description": "My first token contract",
"main": "index.js",
"author": "Phil",
"license": "MIT",
Expand All @@ -155,7 +155,7 @@ Add a `tsconfig.json` file into the project root, here is an example:
"build": "yarn clean && tsc -b",
"build:dev": "tsc -b --watch",
"clean": "rm -rf ./dest tsconfig.tsbuildinfo",
"start": "yarn build && export DEBUG='private-token' && node ./dest/index.js"
"start": "yarn build && export DEBUG='token' && node ./dest/index.js"
},
"devDependencies": {
"@types/node": "^20.4.9",
Expand Down Expand Up @@ -187,7 +187,15 @@ yarn start
A successful run should show:

```
private-token Aztec Sandbox Info { version: 1, chainId: 31337 } +0ms
token Aztec Sandbox Info {
version: 1,
chainId: 31337,
rollupAddress: EthAddress {
buffer: <Buffer cf 7e d3 ac ca 5a 46 7e 9e 70 4c 70 3e 8d 87 f6 34 fb 0f c9>
},
client: '[email protected]',
compatibleNargoVersion: '0.11.1-aztec.0'
}
```

Great!. The Sandbox is running and we are able to interact with it.
Expand All @@ -206,10 +214,18 @@ Continue with adding the following to the `index.ts` file in our example:
Running `yarn start` should now output:

```
private-token Aztec Sandbox Info { version: 1, chainId: 31337 } +0ms
private-token Creating accounts using schnorr signers... +2ms
private-token Created Alice's account at 0x054d89d0...f17e +23s
private-token Created Bob's account at 0x0a8410a1...7c48 +1ms
token Aztec Sandbox Info {
version: 1,
chainId: 31337,
rollupAddress: EthAddress {
buffer: <Buffer cf 7e d3 ac ca 5a 46 7e 9e 70 4c 70 3e 8d 87 f6 34 fb 0f c9>
},
client: '[email protected]',
compatibleNargoVersion: '0.11.1-aztec.0'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want this to be fixed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really. Would want it to be depending on the tests, but not sure what the best way is for that right now and just wanted it fixed in this case as people need it shortly

}
token Creating accounts using schnorr signers... +3ms
token Created Alice's account at 0x1509b252...0027 +10s
token Created Bob's account at 0x031862e8...e7a3 +0ms
```

That might seem like a lot to digest but it can be broken down into the following steps:
Expand All @@ -232,13 +248,20 @@ Now that we have our accounts setup, let's move on to deploy our private token c
`yarn start` will now give the following output:

```
private-token Aztec Sandbox Info { version: 1, chainId: 31337 } +0ms
private-token Creating accounts using schnorr signers... +2ms
private-token Created Alice's account at 0x054d89d0...f17e +23s
private-token Created Bob's account at 0x0a8410a1...7c48 +1ms
private-token Deploying private token contract minting an initial 1000000 tokens to Alice... +0ms
private-token Transaction status is mined +8s
private-token Contract successfully deployed at address 0x143e0af4...11b6 +7ms
token Aztec Sandbox Info {
version: 1,
chainId: 31337,
rollupAddress: EthAddress {
buffer: <Buffer cf 7e d3 ac ca 5a 46 7e 9e 70 4c 70 3e 8d 87 f6 34 fb 0f c9>
},
client: '[email protected]',
compatibleNargoVersion: '0.11.1-aztec.0'
}
token Creating accounts using schnorr signers... +3ms
token Created Alice's account at 0x1509b252...0027 +10s
token Created Bob's account at 0x031862e8...e7a3 +0ms
token Deploying token contract minting an initial 1000000 tokens to Alice... +1ms
token Contract successfully deployed at address 0x1c3dc2ed...1362 +15s
```

We can break this down as follows:
Expand All @@ -249,22 +272,11 @@ We can break this down as follows:
4. We use the `getContractInfo()` api on the RPC Server to retrieve information about the reported contract address.
5. The fact that this api returns a valid object tells us that the contract was successfully deployed in a prior block.

Our output will now be:

```
private-token Aztec Sandbox Info { version: 1, chainId: 31337 } +0ms
private-token Creating accounts using schnorr signers... +2ms
private-token Created Alice's account at 0x054d89d0...f17e +23s
private-token Created Bob's account at 0x0a8410a1...7c48 +1ms
private-token Deploying private token contract minting an initial 1000000 tokens to Alice... +0ms
private-token Contract successfully deployed at address 0x143e0af4...11b6 +7ms
```

## Viewing the balance of an account

A token contract wouldn't be very useful if you aren't able to query the balance of an account. As part of the deployment, tokens were minted to Alice. We can now call the contract's `getBalance()` function to retrieve the balances of the accounts.
A token contract wouldn't be very useful if you aren't able to query the balance of an account. As part of the deployment, tokens were minted to Alice. We can now call the contract's `balance_of_private()` function to retrieve the balances of the accounts.

#include_code getBalance /yarn-project/noir-contracts/src/contracts/private_token_contract/src/main.nr rust
#include_code balance_of_private /yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr rust

Call this function using the following code:

Expand All @@ -273,15 +285,22 @@ Call this function using the following code:
Running now should yield output:

```
private-token Aztec Sandbox Info { version: 1, chainId: 31337 } +0ms
private-token Creating accounts using schnorr signers... +2ms
private-token Created Alice's account at 0x054d89d0...f17e +23s
private-token Created Bob's account at 0x0a8410a1...7c48 +1ms
private-token Deploying private token contract minting an initial 1000000 tokens to Alice... +0ms
private-token Transaction status is mined +8s
private-token Contract successfully deployed at address 0x143e0af4...11b6 +7ms
private-token Alice's balance 1000000 +4s
private-token Bob's balance 0 +3s
token Aztec Sandbox Info {
version: 1,
chainId: 31337,
rollupAddress: EthAddress {
buffer: <Buffer cf 7e d3 ac ca 5a 46 7e 9e 70 4c 70 3e 8d 87 f6 34 fb 0f c9>
},
client: '[email protected]',
compatibleNargoVersion: '0.11.1-aztec.0'
}
token Creating accounts using schnorr signers... +3ms
token Created Alice's account at 0x1509b252...0027 +10s
token Created Bob's account at 0x031862e8...e7a3 +0ms
token Deploying token contract minting an initial 1000000 tokens to Alice... +1ms
token Contract successfully deployed at address 0x1c3dc2ed...1362 +15s
token Alice's balance 1000000 +9s
token Bob's balance 0 +33ms
```

In this section, we first created 2 instances of the `PrivateTokenContract` contract abstraction. One for each of our deployed accounts. This contract abstraction offers a Typescript interface reflecting the abi of the contract. We then call `getBalance()` as a `view` method. View methods can be thought as read-only. No transaction is submitted as a result but a user's state can be queried.
Expand All @@ -296,24 +315,32 @@ Now lets transfer some funds from Alice to Bob by calling the `transfer` functio
2. The sender.
3. The recipient.

#include_code transfer /yarn-project/noir-contracts/src/contracts/private_token_contract/src/main.nr rust
#include_code transfer /yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr rust

#include_code Transfer /yarn-project/end-to-end/src/e2e_sandbox_example.test.ts typescript

Our output should now look like this:

```
private-token Aztec Sandbox Info { version: 1, chainId: 31337 } +0ms
private-token Creating accounts using schnorr signers... +2ms
private-token Created Alice's account at 0x054d89d0...f17e +23s
private-token Created Bob's account at 0x0a8410a1...7c48 +1ms
private-token Deploying private token contract minting an initial 1000000 tokens to Alice... +0ms
private-token Contract successfully deployed at address 0x143e0af4...11b6 +7ms
private-token Alice's balance 1000000 +4s
private-token Bob's balance 0 +3s
private-token Transferring 543 tokens from Alice to Bob... +0ms
private-token Alice's balance 999457 +4s
private-token Bob's balance 543 +3s
token Aztec Sandbox Info {
version: 1,
chainId: 31337,
rollupAddress: EthAddress {
buffer: <Buffer cf 7e d3 ac ca 5a 46 7e 9e 70 4c 70 3e 8d 87 f6 34 fb 0f c9>
},
client: '[email protected]',
compatibleNargoVersion: '0.11.1-aztec.0'
}
token Creating accounts using schnorr signers... +3ms
token Created Alice's account at 0x1509b252...0027 +10s
token Created Bob's account at 0x031862e8...e7a3 +0ms
token Deploying token contract minting an initial 1000000 tokens to Alice... +1ms
token Contract successfully deployed at address 0x1c3dc2ed...1362 +15s
token Alice's balance 1000000 +9s
token Bob's balance 0 +33ms
token Transferring 543 tokens from Alice to Bob... +0ms
token Alice's balance 999457 +5s
token Bob's balance 543 +40ms
```

Here, we used the same contract abstraction as was previously used for reading Alice's balance. But this time we called `send()` generating and sending a transaction to the network. After waiting for the transaction to settle we were able to check the new balance values.
Expand All @@ -332,20 +359,28 @@ Let's mint some tokens to Bob's account:
Our complete output should now be:

```
private-token Aztec Sandbox Info { version: 1, chainId: 31337 } +0ms
private-token Creating accounts using schnorr signers... +2ms
private-token Created Alice's account at 0x054d89d0...f17e +23s
private-token Created Bob's account at 0x0a8410a1...7c48 +1ms
private-token Deploying private token contract minting an initial 1000000 tokens to Alice... +0ms
private-token Contract successfully deployed at address 0x143e0af4...11b6 +7ms
private-token Alice's balance 1000000 +4s
private-token Bob's balance 0 +3s
private-token Transferring 543 tokens from Alice to Bob... +0ms
private-token Alice's balance 999457 +4s
private-token Bob's balance 543 +3s
private-token Minting 10000 tokens to Bob... +1ms
private-token Alice's balance 999457 +4s
private-token Bob's balance 10543 +4s
token Aztec Sandbox Info {
version: 1,
chainId: 31337,
rollupAddress: EthAddress {
buffer: <Buffer cf 7e d3 ac ca 5a 46 7e 9e 70 4c 70 3e 8d 87 f6 34 fb 0f c9>
},
client: '[email protected]',
compatibleNargoVersion: '0.11.1-aztec.0'
}
token Creating accounts using schnorr signers... +3ms
token Created Alice's account at 0x1509b252...0027 +10s
token Created Bob's account at 0x031862e8...e7a3 +0ms
token Deploying token contract minting an initial 1000000 tokens to Alice... +1ms
token Contract successfully deployed at address 0x1c3dc2ed...1362 +15s
token Alice's balance 1000000 +9s
token Bob's balance 0 +33ms
token Transferring 543 tokens from Alice to Bob... +0ms
token Alice's balance 999457 +5s
token Bob's balance 543 +40ms
token Minting 10000 tokens to Bob... +0ms
token Alice's balance 999457 +9s
token Bob's balance 10543 +47ms
```

That's it! We have successfully deployed a private token contract to an instance of the Aztec network and mined private state-transitioning transactions. We have also queried the resulting state all via the interfaces provided by the contract.
Expand Down
15 changes: 4 additions & 11 deletions yarn-project/end-to-end/src/e2e_sandbox_example.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,27 @@ import {
AztecRPC,
Fr,
computeMessageSecretHash,
createAztecRpcClient,
createDebugLogger,
getSchnorrAccount,
waitForSandbox,
} from '@aztec/aztec.js';
// docs:end:imports

/* eslint-enable @typescript-eslint/no-unused-vars */
// Note: this is a hack to make the docs use http://localhost:8080 and CI to use the SANDBOX_URL
import { createAztecRpcClient as createAztecRpcClient2 } from '@aztec/aztec.js';
import { GrumpkinScalar } from '@aztec/circuits.js';
import { TokenContract } from '@aztec/noir-contracts/types';

const { SANDBOX_URL = 'http://localhost:8080' } = process.env;
// docs:end:imports

describe('e2e_sandbox_example', () => {
// Note: this is a hack to make the docs use http://localhost:8080 and CI to use the SANDBOX_URL
const createAztecRpcClient = (_url: string) => {
return createAztecRpcClient2(SANDBOX_URL!);
};

it('sandbox example works', async () => {
// docs:start:setup
////////////// CREATE THE CLIENT INTERFACE AND CONTACT THE SANDBOX //////////////
const logger = createDebugLogger('token');
const sandboxUrl = 'http://localhost:8080';

// We create AztecRPC client connected to the sandbox URL
const aztecRpc = createAztecRpcClient(sandboxUrl);
const aztecRpc = createAztecRpcClient(SANDBOX_URL);
// Wait for sandbox to be ready
await waitForSandbox(aztecRpc);

Expand Down Expand Up @@ -98,7 +91,6 @@ describe('e2e_sandbox_example', () => {
////////////// DEPLOY OUR TOKEN CONTRACT //////////////

// Deploy a token contract, create a contract abstraction object and link it to the owner's wallet
// The contract's constructor takes 2 arguments, the initial supply and the owner of that initial supply
const initialSupply = 1_000_000n;

logger(`Deploying token contract minting an initial ${initialSupply} tokens to Alice...`);
Expand All @@ -107,6 +99,7 @@ describe('e2e_sandbox_example', () => {
// Create the contract abstraction and link to Alice's wallet for future signing
const tokenContractAlice = await TokenContract.at(contract.address, await accounts[0].getWallet());

// Initialize the contract and add Bob as a minter
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be cleaner to use withWallet() on tokenContract instead of what this file does here (instantiating tokenContract twice (for Alice and Bob each)?

await tokenContractAlice.methods._initialize({ address: alice }).send().wait();
await tokenContractAlice.methods.set_minter({ address: bob }, true).send().wait();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ contract PrivateToken {
}
// docs:end:mint

// docs:start:transfer
// Transfers `amount` of tokens from msg_sender to a `recipient`.
#[aztec(private)]
fn transfer(
Expand All @@ -83,9 +82,7 @@ contract PrivateToken {
let recipient_balance = storage.balances.at(recipient);
increment(recipient_balance, amount, recipient);
}
// docs:end:transfer

// docs:start:getBalance
// Helper function to get the balance of a user ("unconstrained" is a Noir alternative of Solidity's "view" function).
unconstrained fn getBalance(
owner: Field,
Expand All @@ -98,7 +95,6 @@ contract PrivateToken {
// Return the sum of all notes in the set.
balance_utils::get_balance(owner_balance)
}
// docs:end:getBalance

// Computes note hash and nullifier.
// Note 1: Needs to be defined by every contract producing logs.
Expand Down
Loading