Skip to content

Commit

Permalink
adding token burn mechanic
Browse files Browse the repository at this point in the history
  • Loading branch information
45930 committed Nov 6, 2023
1 parent 693d703 commit 4b8a4bf
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 40 deletions.
23 changes: 7 additions & 16 deletions src/Election.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,37 +27,28 @@ describe("Election", () => {
sender = Local.testAccounts[0].publicKey;
senderKey = Local.testAccounts[0].privateKey;


// a special account that is allowed to pull out half of the zkapp balance, once
privilegedKey = PrivateKey.random();
privilegedAddress = privilegedKey.toPublicKey();
});

describe("Votes in the Election", () => {
it("Updates the State", async () => {
console.time('deploy');
let tx = await Mina.transaction(sender, () => {
let senderUpdate = AccountUpdate.fundNewAccount(sender);
senderUpdate.send({ to: zkappAddress, amount: initialBalance });
zkapp.deploy({ zkappKey });
let senderUpdate = AccountUpdate.fundNewAccount(sender);
senderUpdate.send({ to: zkappAddress, amount: initialBalance });
zkapp.deploy({ zkappKey });
});
await tx.prove();
await tx.sign([senderKey]).send();
console.timeEnd('deploy');

console.log(
'initial state: ',
zkapp.ballot1.get().toBigInts(),
);

console.time('vote on ballot 1');

tx = await Mina.transaction(sender, () => {
const myVote = Ballot.fromBigInts([0n, 0n, 1n, 0n, 0n, 0n, 0n]);
zkapp.castBallot1(myVote);
const myVote = Ballot.fromBigInts([0n, 0n, 1n, 0n, 0n, 0n, 0n]);
zkapp.castBallot1(myVote);
});
await tx.prove();
await tx.sign([senderKey]).send();
console.timeEnd('vote on ballot 1');
const zkappState = zkapp.ballot1.get();
expect(String(zkappState.toBigInts())).toBe(String([0n, 0n, 1n, 0n, 0n, 0n, 0n]));
});
Expand Down
38 changes: 26 additions & 12 deletions src/TokenElection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,38 +34,52 @@ describe("TokenElection", () => {
});

describe("Votes in the TokenElection", () => {
it("Updates the State", async () => {
console.time('deploy');
beforeEach(async () => {
let Local = Mina.LocalBlockchain({ proofsEnabled: true });
zkappKey = PrivateKey.random();
zkappAddress = zkappKey.toPublicKey();
zkapp = new TokenElection(zkappAddress);
Mina.setActiveInstance(Local);

sender = Local.testAccounts[0].publicKey;
senderKey = Local.testAccounts[0].privateKey;


// a special account that is allowed to pull out half of the zkapp balance, once
privilegedKey = PrivateKey.random();
privilegedAddress = privilegedKey.toPublicKey();

let tx = await Mina.transaction(sender, () => {
let senderUpdate = AccountUpdate.fundNewAccount(sender);
senderUpdate.send({ to: zkappAddress, amount: initialBalance });
zkapp.deploy({ zkappKey });
});
await tx.prove();
await tx.sign([senderKey]).send();
console.timeEnd('deploy');

console.log(
'initial state: ',
zkapp.ballot1.get().toBigInts(),
);

console.time('vote on ballot 1');
tx = await Mina.transaction(sender, () => {
let senderUpdate = AccountUpdate.fundNewAccount(sender);
zkapp.faucet(sender);
const myVote = Ballot.fromBigInts([0n, 0n, 100n, 0n, 10n, 0n, 0n]);
zkapp.castBallot1(myVote, UInt32.from(110));
zkapp.castBallot(myVote, UInt32.from(110));
});
await tx.prove();
await tx.sign([senderKey]).send();
console.timeEnd('vote on ballot 1');
});

it("Updates the State", async () => {
const tx2 = await Mina.transaction(sender, () => {
zkapp.reduceVotes();
})
await tx2.prove();
await tx2.sign([senderKey]).send();
const zkappState = zkapp.ballot1.get();
const zkappState = zkapp.ballot.get();
expect(String(zkappState.toBigInts())).toBe(String([0n, 0n, 100n, 0n, 10n, 0n, 0n]));
});

it("has the correct number of tokens remaining", async () => {
const remainingVoteBalance = await Mina.getBalance(sender, zkapp.token.id);
expect(remainingVoteBalance.toString()).toBe(String(50_000 - 110))
});
});
});
33 changes: 21 additions & 12 deletions src/TokenElection.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
import { SmartContract, state, State, method, UInt32, AccountUpdate, UInt64, Reducer, Field } from 'o1js';
import { SmartContract, state, State, method, UInt32, AccountUpdate, UInt64, Reducer, Field, PublicKey } from 'o1js';
import { PackedUInt32Factory, MultiPackedStringFactory } from 'o1js-pack';

export class IpfsHash extends MultiPackedStringFactory(4) { }
export class Ballot extends PackedUInt32Factory() { }

export class TokenElection extends SmartContract {
@state(IpfsHash) electionDetailsIpfs = State<IpfsHash>();
@state(Ballot) ballot1 = State<Ballot>();
@state(Ballot) ballot = State<Ballot>();
@state(Field) actionState = State<Field>();

reducer = Reducer({ actionType: Ballot });

init() {
super.init();
this.electionDetailsIpfs.set(IpfsHash.fromString(''));
this.ballot1.set(Ballot.fromBigInts([0n, 0n, 0n, 0n, 0n, 0n, 0n]));
this.ballot.set(Ballot.fromBigInts([0n, 0n, 0n, 0n, 0n, 0n, 0n]));
this.actionState.set(Reducer.initialActionState);
}

@method
faucet(toAddress: PublicKey) {
this.token.mint({
address: toAddress,
amount: 50_000
});
}

@method
setElectionDetails(electionDetailsIpfs: IpfsHash) {
this.electionDetailsIpfs.getAndAssertEquals();
Expand All @@ -26,21 +34,22 @@ export class TokenElection extends SmartContract {
}

@method
castBallot1(vote: Ballot, amount: UInt32) {
castBallot(vote: Ballot, amount: UInt32) {
const unpackedVote = Ballot.unpack(vote.packed);
const ballot1 = this.ballot1.getAndAssertEquals();
const unpackedBallot1 = Ballot.unpack(ballot1.packed);
const ballot = this.ballot.getAndAssertEquals();
const unpackedBallot = Ballot.unpack(ballot.packed);

let voteSum = UInt32.from(0);
for (let i = 0; i < Ballot.l; i++) {
voteSum = voteSum.add(unpackedVote[i]);
unpackedBallot1[i] = unpackedBallot1[i].add(unpackedVote[i]);
unpackedBallot[i] = unpackedBallot[i].add(unpackedVote[i]);
}
voteSum.assertEquals(amount); // sum of votes must equal asserted amount (can vote for multiple options)
let au = AccountUpdate.create(this.sender);
au.requireSignature();
au.send({ to: this, amount: UInt64.from(amount) }); // todo, send amounts in UInt64 instead of 32
this.reducer.dispatch(Ballot.fromUInt32s(unpackedBallot1));
this.token.burn({
address: this.sender,
amount: UInt64.from(amount)
});
this.reducer.dispatch(Ballot.fromUInt32s(unpackedBallot));
}

@method
Expand All @@ -65,6 +74,6 @@ export class TokenElection extends SmartContract {
{ state: new Ballot(Field(0)), actionState: actionState }
);

this.ballot1.set(new Ballot(newVotes.packed));
this.ballot.set(new Ballot(newVotes.packed));
}
}

0 comments on commit 4b8a4bf

Please sign in to comment.