Skip to content

Commit 116a520

Browse files
authored
Merge pull request #120 from AztecProtocol/jc/add-helpers
Implement environment configuration and enhance contract deployment scripts
2 parents 088dc1b + e9a2ab5 commit 116a520

File tree

9 files changed

+401
-13
lines changed

9 files changed

+401
-13
lines changed

.env-example

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
L1_URL=https://ethereum-sepolia-rpc.publicnode.com
2+
NODE_URL="https://aztec-alpha-testnet-fullnode.zkv.xyz" # testnet
3+
VOTING_CONTRACT_ADDRESS="0x2320c9938b3e87feb4e475413456d028572f3367e18d61e7d198d342b557f297"
4+
SECRET="0x29aa7f43021f964fe46527ff4df0e9211de94274f54eff12ec81070ee3e16300"
5+
SALT="0x23c46f2dd4450fb881f0b0e70c3974f84dfa9d199493001b3fe8eb136dc612cd"
6+
7+
L1_CHAIN_ID="11155111" # Sepolia

.github/workflows/tests.yaml

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,82 @@ jobs:
5454
- name: Run tests
5555
run: script -e -c "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --no-cache --runInBand --config jest.integration.config.json && aztec test"
5656

57-
- name: Run scripts
58-
run: script -e -c "yarn deploy && yarn deploy-account && yarn fees && yarn multiple-pxe && yarn profile"
57+
- name: Deploy account and capture SECRET/SALT
58+
run: |
59+
# Create a temporary file to store the output
60+
TEMP_OUTPUT=$(mktemp)
61+
62+
# Run deploy-account script and capture both stdout and stderr
63+
if script -e -c "yarn deploy-account" > "$TEMP_OUTPUT" 2>&1; then
64+
echo "✅ Deploy account script completed successfully"
65+
else
66+
echo "❌ Deploy account script failed"
67+
cat "$TEMP_OUTPUT"
68+
rm "$TEMP_OUTPUT"
69+
exit 1
70+
fi
71+
72+
# Show the full output for debugging
73+
cat "$TEMP_OUTPUT"
74+
75+
# Extract SECRET and SALT from the output
76+
SECRET_KEY=$(grep -o "🔑 Secret key generated: 0x[a-fA-F0-9]*" "$TEMP_OUTPUT" | head -1 | sed 's/🔑 Secret key generated: //' || echo "")
77+
SALT_VALUE=$(grep -o "🧂 Salt generated: 0x[a-fA-F0-9]*" "$TEMP_OUTPUT" | head -1 | sed 's/🧂 Salt generated: //' || echo "")
78+
79+
# Clean up temp file
80+
rm "$TEMP_OUTPUT"
81+
82+
# Validate and create .env file
83+
if [ -n "$SECRET_KEY" ] && [ -n "$SALT_VALUE" ]; then
84+
85+
# Create .env file with all necessary values
86+
echo "SECRET=\"$SECRET_KEY\"" >> .env
87+
echo "SALT=\"$SALT_VALUE\"" >> .env
88+
echo "📋 Current .env file contents:"
89+
cat .env
90+
else
91+
echo "❌ Failed to extract SECRET and/or SALT from deploy output"
92+
echo "🔍 SECRET_KEY: '$SECRET_KEY'"
93+
echo "🔍 SALT_VALUE: '$SALT_VALUE'"
94+
exit 1
95+
fi
96+
97+
- name: Deploy contract and capture address
98+
run: |
99+
# Create a temporary file to store the output
100+
TEMP_OUTPUT=$(mktemp)
101+
102+
# Run deploy script and capture both stdout and stderr
103+
if script -e -c "yarn deploy" > "$TEMP_OUTPUT" 2>&1; then
104+
echo "✅ Deploy script completed successfully"
105+
else
106+
cat "$TEMP_OUTPUT"
107+
rm "$TEMP_OUTPUT"
108+
exit 1
109+
fi
110+
111+
# Show the full output for debugging
112+
cat "$TEMP_OUTPUT"
113+
114+
# Try multiple extraction patterns in order of preference
115+
VOTING_CONTRACT_ADDRESS=""
116+
117+
# Look for "Contract address:" pattern
118+
if [ -z "$VOTING_CONTRACT_ADDRESS" ]; then
119+
VOTING_CONTRACT_ADDRESS=$(grep -o "Contract address: 0x[a-fA-F0-9]*" "$TEMP_OUTPUT" | head -1 | sed 's/Contract address: //' || echo "")
120+
fi
121+
122+
# Clean up temp file
123+
rm "$TEMP_OUTPUT"
124+
125+
# Validate and save the address
126+
if [ -n "$VOTING_CONTRACT_ADDRESS" ]; then
127+
echo "VOTING_CONTRACT_ADDRESS=\"$VOTING_CONTRACT_ADDRESS\"" >> .env
128+
fi
129+
130+
- name: Run other scripts
131+
run: |
132+
script -e -c "yarn fees"
133+
script -e -c "yarn multiple-pxe"
134+
script -e -c "yarn profile"
135+
script -e -c "yarn interaction"

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ aztec start --sandbox
6060

6161
## 📦 **Install Packages**
6262

63-
6463
```bash
6564
yarn install
6665
```
@@ -136,6 +135,15 @@ You can find a handful of scripts in the `./scripts` folder.
136135
- `./scripts/fees.ts` is an example of how to pay for a contract deployment using various fee payment methods.
137136
- `./scripts/multiple_pxe.ts` is an example of how to deploy a contract from one PXE instance and interact with it from another.
138137
- `./scripts/profile_deploy.ts` shows how to profile a transaction and print the results.
138+
- `./scripts/interaction_existing_contract.ts` demonstrates how to interact with an already deployed voting contract, including casting votes and checking vote counts.
139+
140+
### Utility Functions
141+
142+
The `./src/utils/` folder contains utility functions:
143+
144+
- `./src/utils/create_account_from_env.ts` provides functions to create Schnorr accounts from environment variables (SECRET and SALT), useful for account management across different environments.
145+
- `./src/utils/setup_pxe.ts` provides a function to set up and configure the Private Execution Environment (PXE) service with proper configuration for local development.
146+
- `./src/utils/deploy_account.ts` provides a function to deploy Schnorr accounts to the network with sponsored fee payment, including key generation and deployment verification.
139147

140148
## **Error Resolution**
141149

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"compile": "${AZTEC_NARGO:-aztec-nargo} compile",
1616
"deploy": "node --loader ts-node/esm scripts/deploy_contract.ts",
1717
"deploy-account": "node --loader ts-node/esm scripts/deploy_account.ts",
18+
"interaction": "node --loader ts-node/esm scripts/interaction_existing_contract.ts",
1819
"multiple-pxe": "node --loader ts-node/esm scripts/multiple_pxe.ts",
1920
"get-block": "node --loader ts-node/esm scripts/get_block.ts",
2021
"profile": "node --loader ts-node/esm scripts/profile_deploy.ts",

scripts/deploy_contract.ts

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,78 @@
11
import { EasyPrivateVotingContract } from "../src/artifacts/EasyPrivateVoting.js"
22
import { createLogger, PXE, Logger, SponsoredFeePaymentMethod, Fr } from "@aztec/aztec.js";
3+
import { TokenContract } from "@aztec/noir-contracts.js/Token"
34
import { setupPXE } from "../src/utils/setup_pxe.js";
45
import { getSponsoredFPCInstance } from "../src/utils/sponsored_fpc.js";
56
import { SponsoredFPCContract } from "@aztec/noir-contracts.js/SponsoredFPC";
67
import { deploySchnorrAccount } from "../src/utils/deploy_account.js";
78

89
async function main() {
9-
1010
let pxe: PXE;
1111
let logger: Logger;
1212

1313
logger = createLogger('aztec:aztec-starter');
14+
logger.info('🚀 Starting contract deployment process...');
1415

16+
// Setup PXE
17+
logger.info('📡 Setting up PXE connection...');
1518
pxe = await setupPXE();
19+
const nodeInfo = await pxe.getNodeInfo();
20+
logger.info(`📊 Node info: ${JSON.stringify(nodeInfo, null, 2)}`);
1621

22+
// Setup sponsored FPC
23+
logger.info('💰 Setting up sponsored fee payment contract...');
1724
const sponsoredFPC = await getSponsoredFPCInstance();
25+
logger.info(`💰 Sponsored FPC instance obtained at: ${sponsoredFPC.address}`);
26+
27+
logger.info('📝 Registering sponsored FPC contract with PXE...');
1828
await pxe.registerContract({ instance: sponsoredFPC, artifact: SponsoredFPCContract.artifact });
1929
const sponsoredPaymentMethod = new SponsoredFeePaymentMethod(sponsoredFPC.address);
30+
logger.info('✅ Sponsored fee payment method configured');
2031

32+
// Deploy account
33+
logger.info('👤 Deploying Schnorr account...');
2134
let accountManager = await deploySchnorrAccount(pxe);
2235
const wallet = await accountManager.getWallet();
23-
const address = accountManager.getAddress();
36+
const address = await accountManager.getAddress();
37+
logger.info(`✅ Account deployed successfully at: ${address}`);
2438

25-
const votingContract = await EasyPrivateVotingContract.deploy(wallet, address).send({ fee: { paymentMethod: sponsoredPaymentMethod } }).deployed();
26-
logger.info(`Voting Contract deployed at: ${votingContract.address}`);
39+
// Deploy voting contract
40+
logger.info('🗳️ Starting voting contract deployment...');
41+
logger.info(`📋 Admin address for voting contract: ${address}`);
42+
43+
const deployTx = EasyPrivateVotingContract.deploy(wallet, address).send({
44+
fee: { paymentMethod: sponsoredPaymentMethod }
45+
});
46+
47+
logger.info('⏳ Waiting for deployment transaction to be mined...');
48+
const votingContract = await deployTx.deployed({ timeout: 120000 });
49+
50+
logger.info(`🎉 Voting Contract deployed successfully!`);
51+
logger.info(`📍 Contract address: ${votingContract.address}`);
52+
logger.info(`👤 Admin address: ${address}`);
53+
54+
// Verify deployment
55+
logger.info('🔍 Verifying contract deployment...');
56+
try {
57+
// Test a read operation
58+
logger.info('🧪 Testing contract read operation...');
59+
const initialVoteCount = await votingContract.methods.get_vote(Fr.fromString("1")).simulate();
60+
logger.info(`📊 Initial vote count for candidate 1: ${initialVoteCount}`);
61+
62+
} catch (error) {
63+
logger.error(`❌ Contract verification failed: ${error}`);
64+
}
65+
66+
logger.info('🏁 Deployment process completed successfully!');
67+
logger.info(`📋 Summary:`);
68+
logger.info(` - Contract Address: ${votingContract.address}`);
69+
logger.info(` - Admin Address: ${address}`);
70+
logger.info(` - Sponsored FPC: ${sponsoredFPC.address}`);
2771
}
2872

29-
main();
73+
main().catch((error) => {
74+
const logger = createLogger('aztec:aztec-starter');
75+
logger.error(`❌ Deployment failed: ${error.message}`);
76+
logger.error(`📋 Error details: ${error.stack}`);
77+
process.exit(1);
78+
});

scripts/interaction_existing.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { createLogger, Logger, SponsoredFeePaymentMethod, Fr, AztecAddress } from "@aztec/aztec.js";
2+
import { EasyPrivateVotingContract } from "../src/artifacts/EasyPrivateVoting.js";
3+
import { SponsoredFPCContract } from "@aztec/noir-contracts.js/SponsoredFPC";
4+
import { setupPXE } from "../src/utils/setup_pxe.js";
5+
import { getSponsoredFPCInstance } from "../src/utils/sponsored_fpc.js";
6+
import { getAccountFromEnv } from "../src/utils/create_account_from_env.js";
7+
8+
async function main() {
9+
let logger: Logger;
10+
logger = createLogger('aztec:voting-operations-existing');
11+
12+
// Setup PXE
13+
const pxe = await setupPXE();
14+
15+
// Setup sponsored fee payment
16+
const sponsoredFPC = await getSponsoredFPCInstance();
17+
await pxe.registerContract({ instance: sponsoredFPC, artifact: SponsoredFPCContract.artifact });
18+
const sponsoredPaymentMethod = new SponsoredFeePaymentMethod(sponsoredFPC.address);
19+
20+
// Get account from environment variables
21+
const accountManager = await getAccountFromEnv(pxe);
22+
const wallet = await accountManager.getWallet();
23+
24+
// Connect to existing voting contract (replace with your deployed contract address)
25+
const contractAddress = process.env.VOTING_CONTRACT_ADDRESS;
26+
if (!contractAddress) {
27+
logger.error("Please set VOTING_CONTRACT_ADDRESS environment variable with your deployed contract address");
28+
return;
29+
}
30+
31+
logger.info(`Connecting to voting contract at: ${contractAddress}`);
32+
const votingContract = await EasyPrivateVotingContract.at(
33+
AztecAddress.fromString(contractAddress),
34+
wallet
35+
);
36+
37+
// Define a candidate to vote for (using a Field value)
38+
const candidate = Fr.fromString("1"); // Voting for candidate "1"
39+
40+
// First get_vote call - check initial vote count
41+
logger.info("Getting initial vote count...");
42+
const initialVoteCount = await votingContract.methods.get_vote(candidate).simulate();
43+
logger.info(`Initial vote count for candidate ${candidate}: ${initialVoteCount}`);
44+
45+
// Cast a vote
46+
logger.info("Casting vote...");
47+
await votingContract.methods.cast_vote(candidate)
48+
.send({ fee: { paymentMethod: sponsoredPaymentMethod } })
49+
.wait({ timeout: 120000 });
50+
logger.info("Vote cast successfully!");
51+
52+
// Second get_vote call - check updated vote count
53+
logger.info("Getting updated vote count...");
54+
const updatedVoteCount = await votingContract.methods.get_vote(candidate).simulate();
55+
logger.info(`Updated vote count for candidate ${candidate}: ${updatedVoteCount}`);
56+
57+
logger.info(`Vote count increased from ${initialVoteCount} to ${updatedVoteCount}`);
58+
}
59+
60+
main().catch((error) => {
61+
console.error("Error:", error);
62+
process.exit(1);
63+
});
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { createLogger, Logger, SponsoredFeePaymentMethod, Fr, AztecAddress } from "@aztec/aztec.js";
2+
import { EasyPrivateVotingContract } from "../src/artifacts/EasyPrivateVoting.js";
3+
import { SponsoredFPCContract } from "@aztec/noir-contracts.js/SponsoredFPC";
4+
import { setupPXE } from "../src/utils/setup_pxe.js";
5+
import { getSponsoredFPCInstance } from "../src/utils/sponsored_fpc.js";
6+
import { getAccountFromEnv } from "../src/utils/create_account_from_env.js";
7+
8+
async function main() {
9+
let logger: Logger;
10+
logger = createLogger('aztec:voting-operations-existing');
11+
12+
// Setup PXE
13+
const pxe = await setupPXE();
14+
15+
// Setup sponsored fee payment
16+
const sponsoredFPC = await getSponsoredFPCInstance();
17+
await pxe.registerContract({ instance: sponsoredFPC, artifact: SponsoredFPCContract.artifact });
18+
const sponsoredPaymentMethod = new SponsoredFeePaymentMethod(sponsoredFPC.address);
19+
20+
// Get account from environment variables
21+
const accountManager = await getAccountFromEnv(pxe);
22+
const wallet = await accountManager.getWallet();
23+
24+
// Connect to existing voting contract (replace with your deployed contract address)
25+
const contractAddress = process.env.VOTING_CONTRACT_ADDRESS;
26+
if (!contractAddress) {
27+
logger.error("Please set VOTING_CONTRACT_ADDRESS environment variable with your deployed contract address");
28+
return;
29+
}
30+
31+
logger.info(`Connecting to voting contract at: ${contractAddress}`);
32+
const votingContract = await EasyPrivateVotingContract.at(
33+
AztecAddress.fromString(contractAddress),
34+
wallet
35+
);
36+
37+
// Define a candidate to vote for (using a Field value)
38+
const candidate = Fr.fromString("1"); // Voting for candidate "1"
39+
40+
// First get_vote call - check initial vote count
41+
logger.info("Getting initial vote count...");
42+
const initialVoteCount = await votingContract.methods.get_vote(candidate).simulate();
43+
logger.info(`Initial vote count for candidate ${candidate}: ${initialVoteCount}`);
44+
45+
// Cast a vote
46+
logger.info("Casting vote...");
47+
await votingContract.methods.cast_vote(candidate)
48+
.send({ fee: { paymentMethod: sponsoredPaymentMethod } })
49+
.wait({ timeout: 120000 });
50+
logger.info("Vote cast successfully!");
51+
52+
// Second get_vote call - check updated vote count
53+
logger.info("Getting updated vote count...");
54+
const updatedVoteCount = await votingContract.methods.get_vote(candidate).simulate();
55+
logger.info(`Updated vote count for candidate ${candidate}: ${updatedVoteCount}`);
56+
57+
logger.info(`Vote count increased from ${initialVoteCount} to ${updatedVoteCount}`);
58+
}
59+
60+
main().catch((error) => {
61+
console.error("Error:", error);
62+
process.exit(1);
63+
});

0 commit comments

Comments
 (0)