Skip to content

Commit

Permalink
Merge pull request #1 from ZkNoid/state_manager_update
Browse files Browse the repository at this point in the history
State manager update
  • Loading branch information
aii23 authored Jul 13, 2024
2 parents 8eaa238 + ced1d5d commit 74db7f3
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 2 deletions.
9 changes: 9 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@
"feepayerAlias": "deployer",
"fee": "0.1",
"smartContract": "PLottery"
},
"plottery_10_bpr_3": {
"networkId": "testnet",
"url": "https://api.minascan.io/node/devnet/v1/graphql",
"keyPath": "keys/plottery_10_bpr_3.json",
"feepayerKeyPath": "/home/alex/.cache/zkapp-cli/keys/deployer.json",
"feepayerAlias": "deployer",
"fee": "1",
"smartContract": "PLottery"
}
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "l1-lottery-contracts",
"version": "0.7.5",
"version": "0.7.6",
"description": "",
"author": "",
"license": "Apache-2.0",
Expand Down
172 changes: 172 additions & 0 deletions scripts/proof.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/**
* This script can be used to interact with the Add contract, after deploying it.
*
* We call the update() method on the contract, create a proof and send it to the chain.
* The endpoint that we interact with is read from your config.json.
*
* This simulates a user interacting with the zkApp from a browser, except that here, sending the transaction happens
* from the script and we're using your pre-funded zkApp account to pay the transaction fee. In a real web app, the user's wallet
* would send the transaction and pay the fee.
*
* To run locally:
* Build the project: `$ npm run build`
* Run with node: `$ node build/scripts/buy_ticket.js <deployAlias>`.
*/
import fs from 'fs/promises';
import { Cache, Mina, NetworkId, PrivateKey, UInt32, fetchAccount } from 'o1js';
import { DistibutionProgram } from '../src/DistributionProof.js';
import { PLottery } from '../src/PLottery.js';
import { TicketReduceProgram } from '../src/TicketReduceProof.js';
import { PStateManager } from '../src/StateManager/PStateManager.js';
import { BLOCK_PER_ROUND } from '../src/constants.js';

// check command line arg
let deployAlias = process.argv[2];
if (!deployAlias)
throw Error(`Missing <deployAlias> argument.
Usage:
node build/src/interact.js <deployAlias>
`);
Error.stackTraceLimit = 1000;
const DEFAULT_NETWORK_ID = 'testnet';

// parse config and private key from file
type Config = {
deployAliases: Record<
string,
{
networkId?: string;
url: string;
keyPath: string;
fee: string;
feepayerKeyPath: string;
feepayerAlias: string;
}
>;
};
let configJson: Config = JSON.parse(await fs.readFile('config.json', 'utf8'));
let config = configJson.deployAliases[deployAlias];
let feepayerKeysBase58: { privateKey: string; publicKey: string } = JSON.parse(
await fs.readFile(config.feepayerKeyPath, 'utf8')
);

let zkAppKeysBase58: { privateKey: string; publicKey: string } = JSON.parse(
await fs.readFile(config.keyPath, 'utf8')
);

let feepayerKey = PrivateKey.fromBase58(feepayerKeysBase58.privateKey);
let zkAppKey = PrivateKey.fromBase58(zkAppKeysBase58.privateKey);

// set up Mina instance and contract we interact with
const Network = Mina.Network({
// We need to default to the testnet networkId if none is specified for this deploy alias in config.json
// This is to ensure the backward compatibility.
networkId: (config.networkId ?? DEFAULT_NETWORK_ID) as NetworkId,
// graphql: 'https://api.minascan.io/node/devnet/v1/graphql',
archive: 'https://api.minascan.io/archive/devnet/v1/graphql',
mina: config.url,
});
// const Network = Mina.Network(config.url);
const fee = Number(config.fee) * 1e9; // in nanomina (1 billion = 1.0 mina)
Mina.setActiveInstance(Network);
let feepayerAddress = feepayerKey.toPublicKey();
let zkAppAddress = zkAppKey.toPublicKey();
let lottery = new PLottery(zkAppAddress);

// compile the contract to create prover keys
console.log('compile the DP');
await DistibutionProgram.compile();
console.log('compile reduce proof');
await TicketReduceProgram.compile();
console.log('compile the Lottery');
let lotteryCompileResult = await PLottery.compile();

// let mockLotteryCompileResult = await MockLottery.compile({
// cache: Cache.FileSystem('../cache'),
// });

console.log(`Fetch: ${zkAppAddress.toBase58()}`);
console.log(`Onchain VK: `, lottery.account.verificationKey);
console.log(
`Local VK1: `,
lotteryCompileResult.verificationKey.hash.toString()
);
// console.log(
// `Local VK2: `,
// mockLotteryCompileResult.verificationKey.hash.toString()
// );
await fetchAccount({ publicKey: zkAppAddress });
await fetchAccount({
publicKey: 'B62qj3DYVUCaTrDnFXkJW34xHUBr9zUorg72pYN3BJTGB4KFdpYjxxQ',
});

console.log(lottery.bankRoot.get().toString());

console.log(lottery.ticketRoot.get().toString());

const startSlot = lottery.startBlock.get();

const state = new PStateManager(lottery, startSlot.value, false);

// const curSlot = lottery.network.globalSlotSinceGenesis.get();

// const curRound = curSlot.sub(startSlot).div(BLOCK_PER_ROUND);

const curRound = UInt32.from(8);

console.log('Generate reduce proof');
const reduceProof = await state.reduceTickets();

// console.log(`Digest: `, await MockLottery.digest());

console.log('Send reduce transaction');

let tx = await Mina.transaction({ sender: feepayerAddress, fee }, async () => {
await lottery.reduceTickets(reduceProof, curRound.value);
});
await tx.prove();
let txResult = await tx.sign([feepayerKey]).send();

console.log(`Tx successful. Hash: `, txResult.hash);

/*
try {
// call update() and send transaction
console.log('build transaction and create proof...');
let tx = await Mina.transaction(
{ sender: feepayerAddress, fee },
async () => {
await zkApp.update();
}
);
await tx.prove();
console.log('send transaction...');
const sentTx = await tx.sign([feepayerKey]).send();
if (sentTx.status === 'pending') {
console.log(
'\nSuccess! Update transaction sent.\n' +
'\nYour smart contract state will be updated' +
'\nas soon as the transaction is included in a block:' +
`\n${getTxnUrl(config.url, sentTx.hash)}`
);
}
} catch (err) {
console.log(err);
}
function getTxnUrl(graphQlUrl: string, txnHash: string | undefined) {
const hostName = new URL(graphQlUrl).hostname;
const txnBroadcastServiceName = hostName
.split('.')
.filter((item) => item === 'minascan')?.[0];
const networkName = graphQlUrl
.split('/')
.filter((item) => item === 'mainnet' || item === 'devnet')?.[0];
if (txnBroadcastServiceName && networkName) {
return `https://minascan.io/${networkName}/tx/${txnHash}?type=zk-tx`;
}
return `Transaction hash: ${txnHash}`;
}
*/
2 changes: 1 addition & 1 deletion src/StateManager/PStateManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ export class PStateManager extends BaseStateManager {
)
: await TicketReduceProgram.addTicket(input, curProof);

this.addTicket(action.ticket, +action.round);
this.addTicket(action.ticket, +action.round, true);
}

// Again here we do not need specific input, as it is not using here
Expand Down

0 comments on commit 74db7f3

Please sign in to comment.