Skip to content

Commit

Permalink
Added buy ticket script
Browse files Browse the repository at this point in the history
  • Loading branch information
aii23 committed Oct 9, 2024
1 parent cd67344 commit fdcee1c
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 159 deletions.
27 changes: 7 additions & 20 deletions scripts/deploy_1rnd_pottery.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Field, Mina, PrivateKey, PublicKey } from 'o1js';
import { AccountUpdate, Field, Mina, PrivateKey, PublicKey } from 'o1js';
import { DeployEvent, PlotteryFactory } from '../src/Factory.js';
import { FactoryManager } from '../src/StateManager/FactoryStateManager.js';
import { configDefaultInstance } from './utils.js';
import { configDefaultInstance, getFedFactoryManager } from './utils.js';
import * as fs from 'fs';

let { transactionFee } = configDefaultInstance();
Expand All @@ -25,8 +25,6 @@ const networkId = Mina.activeInstance.getNetworkId().toString();

let { verificationKey } = await PlotteryFactory.compile();

const factoryManager = new FactoryManager();

let factoryAddress: PublicKey;

if (
Expand All @@ -47,8 +45,6 @@ if (fs.existsSync(factoryDataPath)) {

let factory = new PlotteryFactory(factoryAddress);

let factoryEvents = await factory.fetchEvents();

let deployments;

const deploymentsPath = `./deployV2/${networkId}/${verificationKey.hash.toString()}/deployments.json`;
Expand All @@ -60,18 +56,7 @@ if (fs.existsSync(deploymentsPath)) {
deployments = {};
}

// Restore state of factoryManager
for (const event of factoryEvents) {
let deployEvent = event.event.data as any;

console.log('event');
console.log(deployEvent);
factoryManager.addDeploy(
+deployEvent.round,
deployEvent.randomManager,
deployEvent.plottery
);
}
const factoryManager = await getFedFactoryManager(factory);

for (let round = +from; round <= +to; round++) {
if (factoryManager.roundsMap.get(Field(round)).greaterThan(0).toBoolean()) {
Expand All @@ -92,6 +77,9 @@ for (let round = +from; round <= +to; round++) {
let tx = Mina.transaction(
{ sender: deployer, fee: 5 * transactionFee },
async () => {
AccountUpdate.fundNewAccount(deployer);
AccountUpdate.fundNewAccount(deployer);

await factory.deployRound(witness, randomManagerAddress, plotteryAddress);
}
);
Expand All @@ -105,9 +93,8 @@ for (let round = +from; round <= +to; round++) {

if (txResult.status === 'rejected') {
console.log(`Transaction failed due to following reason`);
console.log(txResult.toPretty());
console.log(txResult.errors);
continue;
break;
}

factoryManager.addDeploy(round, randomManagerAddress, plotteryAddress);
Expand Down
188 changes: 70 additions & 118 deletions scripts/pbuy_ticket.ts
Original file line number Diff line number Diff line change
@@ -1,118 +1,70 @@
// /**
// * 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, Field, Mina, NetworkId, PrivateKey, fetchAccount } from 'o1js';
// import { DistributionProgram } from '../src/Proofs/DistributionProof.js';
// import { Ticket } from '../src/Structs/Ticket.js';
// import { TicketReduceProgram } from '../src/Proofs/TicketReduceProof.js';
// import { PStateManager } from '../src/StateManager/PStateManager.js';
// import { findPlottery } from './utils.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,
// 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 { plottery: lottery, PLottery } = findPlottery();

// // compile the contract to create prover keys
// console.log('compile the DP');
// await DistributionProgram.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: 'B62qnBkcyABfjz2cqJPzNZKjVt9M9kx1vgoiWLbkJUnk16Cz8KX8qC4',
// });

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

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

// const state = new PStateManager(lottery, lottery.startBlock.get().value);

// const ticket = Ticket.from([1, 1, 1, 1, 1, 1], feepayerAddress, 1);

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

// let tx = await Mina.transaction({ sender: feepayerAddress, fee }, async () => {
// await lottery.buyTicket(ticket, Field(0));
// });
// await tx.prove();
// let txResult = await tx.sign([feepayerKey]).send();

// console.log(`Tx successful. Hash: `, txResult.hash);
import fs from 'fs';
import {
Cache,
Field,
Mina,
NetworkId,
PrivateKey,
UInt32,
fetchAccount,
} from 'o1js';
import { DistributionProgram } from '../src/Proofs/DistributionProof.js';
import { Ticket } from '../src/Structs/Ticket.js';
import { TicketReduceProgram } from '../src/Proofs/TicketReduceProof.js';
import { PStateManager } from '../src/StateManager/PStateManager.js';
import { configDefaultInstance, getFedFactoryManager } from './utils.js';
import { PlotteryFactory } from '../src/Factory.js';
import { BLOCK_PER_ROUND } from '../src/constants.js';
import { PLottery } from '../src/PLottery.js';

const { transactionFee } = configDefaultInstance();

const networkId = Mina.activeInstance.getNetworkId().toString();
const { verificationKey } = await PlotteryFactory.compile();

const deployerKey = PrivateKey.fromBase58(process.env.DEPLOYER_KEY!);
const deployer = deployerKey.toPublicKey();

// Get factory
const factoryDataPath = `./deployV2/${networkId}/${verificationKey.hash.toString()}/factory.json`;

const factoryAddress = JSON.parse(
fs.readFileSync(factoryDataPath).toString()
).address;

const factory = new PlotteryFactory(factoryAddress);
const startSlot = factory.startSlot.get();
const currentSlot = Mina.currentSlot();
const currentRound = currentSlot.sub(startSlot).div(BLOCK_PER_ROUND);

const factoryManager = await getFedFactoryManager(factory);

const ticket = Ticket.from([1, 1, 1, 1, 1, 1], deployer, 1);

const plottery = factoryManager.plotteryManagers[+currentRound].contract;

// compile the contract to create prover keys
console.log('compile the DP');
await DistributionProgram.compile({ cache: Cache.FileSystem('../cache') });
console.log('compile reduce proof');
await TicketReduceProgram.compile({ cache: Cache.FileSystem('../cache') });
console.log('compile the Lottery');
await PLottery.compile({
cache: Cache.FileSystem('../cache'),
});

await fetchAccount({ publicKey: plottery.address });
await fetchAccount({
publicKey: deployer,
});

let tx = await Mina.transaction(
{ sender: deployer, fee: transactionFee },
async () => {
await plottery.buyTicket(ticket);
}
);
await tx.prove();
let txResult = await tx.sign([deployerKey]).send();

console.log(`Tx successful. Hash: `, txResult.hash);
24 changes: 24 additions & 0 deletions scripts/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {
import { DistributionProgram } from '../src/Proofs/DistributionProof.js';
import { ZkOnCoordinatorAddress } from '../src/constants.js';
import { RandomManagerManager } from '../src/StateManager/RandomManagerManager.js';
import { FactoryManager } from '../src/StateManager/FactoryStateManager.js';
import { PlotteryFactory } from '../src/Factory.js';

export const configDefaultInstance = (): { transactionFee: number } => {
const transactionFee = 100_000_000;
Expand Down Expand Up @@ -162,6 +164,28 @@ export const getDeployer = (): {
};
*/

export const getFedFactoryManager = async (
factory: PlotteryFactory
): Promise<FactoryManager> => {
const factoryManager = new FactoryManager();

const factoryEvents = await factory.fetchEvents();

for (const event of factoryEvents) {
const deployEvent = event.event.data as any;

console.log('event');
console.log(deployEvent);
factoryManager.addDeploy(
+deployEvent.round,
deployEvent.randomManager,
deployEvent.plottery
);
}

return factoryManager;
};

export const getIPFSCID = (): { hashPart1: Field; hashPart2: Field } => {
function segmentHash(ipfsHashFile: string) {
const ipfsHash0 = ipfsHashFile.slice(0, 30); // first part of the ipfsHash
Expand Down
8 changes: 5 additions & 3 deletions src/Factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,20 @@ export class DeployEvent extends Struct({
plottery: PublicKey,
}) {}

const startSlot = Field(87117); // Current slot on devnet

///Just copy with other vk for random manager
export class PlotteryFactory extends SmartContract {
events = {
'deploy-plottery': DeployEvent,
};

@state(Field) roundsRoot = State<Field>();
@state(UInt32) startSlot = State<UInt32>();

init() {
super.init();
this.roundsRoot.set(emptyMerkleMapRoot);
this.network.globalSlotSinceGenesis.requireNothing();
this.startSlot.set(this.network.globalSlotSinceGenesis.get());
}

@method
Expand All @@ -75,7 +76,8 @@ export class PlotteryFactory extends SmartContract {
const [newRoot] = witness.computeRootAndKeyV2(Field(1));
this.roundsRoot.set(newRoot);

const localStartSlot = startSlot.add(round.mul(BLOCK_PER_ROUND));
const startSlot = this.startSlot.getAndRequireEquals();
const localStartSlot = startSlot.value.add(round.mul(BLOCK_PER_ROUND));

// Deploy and initialize random manager
{
Expand Down
4 changes: 1 addition & 3 deletions src/Random/RandomManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@ import {
state,
} from 'o1js';
import { BLOCK_PER_ROUND, ZkOnCoordinatorAddress } from '../constants.js';
import { convertToUInt32 } from '../util.js';

import {
ZkonZkProgram,
ZkonRequestCoordinator,
ExternalRequestEvent,
} from 'zkon-zkapp';
import { getIPFSCID } from '../../scripts/utils.js';
import { getIPFSCID } from '../util.js';

const emptyMapRoot = new MerkleMap().getRoot();

Expand Down
6 changes: 5 additions & 1 deletion src/StateManager/FactoryStateManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Field, MerkleMap, PublicKey } from 'o1js';
import { PStateManager } from './PStateManager.js';
import { PLottery } from '../PLottery.js';
import { RandomManagerManager } from './RandomManagerManager.js';
import { RandomManager } from '../Random/RandomManager.js';

interface IDeployInfo {
round: number;
Expand Down Expand Up @@ -35,12 +36,15 @@ export class FactoryManager {
this.roundsMap.set(Field(round), Field(1));

const plotteryContract = new PLottery(plottery);
const randomManagerContract = new RandomManager(randomManager);

this.plotteryManagers[round] = new PStateManager(
plotteryContract,
this.isMock,
this.shouldUpdateState
);
this.randomManagers[round] = new RandomManagerManager();
this.randomManagers[round] = new RandomManagerManager(
randomManagerContract
);
}
}
Loading

0 comments on commit fdcee1c

Please sign in to comment.