From bb2f0bbcd356d9e54d2f66a321365934dcdd550f Mon Sep 17 00:00:00 2001 From: renjt Date: Sun, 1 Dec 2024 22:23:01 +0800 Subject: [PATCH 1/2] task2 todo --- learn/renjuntao/task2/readme.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 learn/renjuntao/task2/readme.md diff --git a/learn/renjuntao/task2/readme.md b/learn/renjuntao/task2/readme.md new file mode 100644 index 000000000..2bb3092fe --- /dev/null +++ b/learn/renjuntao/task2/readme.md @@ -0,0 +1,8 @@ +### task2: 设计一个简单的投票统计器 + +1. 设计一个简单的投票统计器用于小团队内部投票,要求能累积统计出赞成票和反对票的票数 +2. 考虑检查投票者属于团队成员,假设队员不会重复投票 + +请提交测试执行脚本。 + +#todo \ No newline at end of file From a63fac286dfdc0824693d0d5e37aab6cbacb053b Mon Sep 17 00:00:00 2001 From: renjt Date: Tue, 3 Dec 2024 20:10:23 +0800 Subject: [PATCH 2/2] task2 --- learn/renjuntao/task2/.readme.md.swp | 6 + learn/renjuntao/task2/Vote.test.ts | 158 +++++++++++++++++++++++++++ learn/renjuntao/task2/Vote.ts | 60 ++++++++++ learn/renjuntao/task2/readme.md | 2 - learn/renjuntao/task2/test.png | Bin 0 -> 26595 bytes 5 files changed, 224 insertions(+), 2 deletions(-) create mode 100644 learn/renjuntao/task2/.readme.md.swp create mode 100644 learn/renjuntao/task2/Vote.test.ts create mode 100644 learn/renjuntao/task2/Vote.ts create mode 100644 learn/renjuntao/task2/test.png diff --git a/learn/renjuntao/task2/.readme.md.swp b/learn/renjuntao/task2/.readme.md.swp new file mode 100644 index 000000000..4226c0fe2 --- /dev/null +++ b/learn/renjuntao/task2/.readme.md.swp @@ -0,0 +1,6 @@ +### task2: 设计一个简单的投票统计器 + +1. 设计一个简单的投票统计器用于小团队内部投票,要求能累积统计出赞成票和反对票的票数 +2. 考虑检查投票者属于团队成员,假设队员不会重复投票 + +请提交测试执行脚本。 diff --git a/learn/renjuntao/task2/Vote.test.ts b/learn/renjuntao/task2/Vote.test.ts new file mode 100644 index 000000000..ae76fdbe9 --- /dev/null +++ b/learn/renjuntao/task2/Vote.test.ts @@ -0,0 +1,158 @@ +import { AccountUpdate, Field, MerkleMap, Mina, Poseidon, PrivateKey, PublicKey } from 'o1js'; +import Vote from './Vote'; + +let proofsEnabled = false; + +interface Member { + key: PrivateKey; + account: Mina.TestPublicKey; + hashKey: Field; +} + +describe('Vote test', () => { + let deployerAccount: Mina.TestPublicKey; + let deployerKey: PrivateKey; + + let members: Member[] = []; + let notMembers: Member[] = []; + + let zkAppAddress: PublicKey; + let zkAppPrivateKey: PrivateKey; + let zkApp: Vote; + let memberMap = new MerkleMap(); + + beforeAll(async () => { + if (proofsEnabled) await Vote.compile(); + }); + + beforeEach(async () => { + const Local = await Mina.LocalBlockchain({ proofsEnabled }); + Mina.setActiveInstance(Local); + deployerAccount = Local.testAccounts[0]; + deployerKey = deployerAccount.key; + + Local.testAccounts.slice(1, 6).forEach((item, index) => { + members[index] = { + account: item, + key: item.key, + hashKey: Poseidon.hash(item.toFields()), + }; + memberMap.set(members[index].hashKey, Field(1)); + }); + + Local.testAccounts.slice(6, 10).forEach((item, index) => { + notMembers[index] = { + account: item, + key: item.key, + hashKey: Poseidon.hash(item.toFields()), + }; + }); + + zkAppPrivateKey = PrivateKey.random(); + zkAppAddress = zkAppPrivateKey.toPublicKey(); + + zkApp = new Vote(zkAppAddress); + }); + + async function localDeploy() { + const txn = await Mina.transaction(deployerAccount, async () => { + AccountUpdate.fundNewAccount(deployerAccount); + await zkApp.deploy(); + }); + await txn.prove(); + await txn.sign([deployerKey, zkAppPrivateKey]).send(); + + const txnInit = await Mina.transaction(deployerAccount, async () => { + await zkApp.updateMemberRoot(memberMap.getRoot()); + }); + await txnInit.prove(); + await txnInit.sign([deployerKey, zkAppPrivateKey]).send(); + } + + it('member vote approve', async () => { + await localDeploy(); + + const user = members[Math.floor(Math.random() * members.length)]; + const state1 = zkApp.getVoteCounts(); + const txn = await Mina.transaction(user.account, async () => { + await zkApp.vote(Field(1), memberMap.getWitness(user.hashKey)); + }); + await txn.prove(); + await txn.sign([user.key]).send(); + const state2 = zkApp.getVoteCounts(); + expect([state2.approve, state2.reject]) + .toEqual([state1.approve.add(Field(1)), state1.reject]); + }); + + it('member vote reject', async () => { + await localDeploy(); + + const user = members[Math.floor(Math.random() * members.length)]; + const state1 = zkApp.getVoteCounts(); + const txn = await Mina.transaction(user.account, async () => { + await zkApp.vote(Field(0), memberMap.getWitness(user.hashKey)); + }); + await txn.prove(); + await txn.sign([user.key]).send(); + const state2 = zkApp.getVoteCounts(); + expect([state2.approve, state2.reject]) + .toEqual([state1.approve, state1.reject.add(Field(1))]); + }); + + it('member vote complex scene', async () => { + await localDeploy(); + + const state1 = zkApp.getVoteCounts(); + + const castVote = async (user: any, voteOption: Field) => { + const txn = await Mina.transaction(user.account, async () => { + await zkApp.vote(voteOption, memberMap.getWitness(user.hashKey)); + }); + await txn.prove(); + await txn.sign([user.key]).send(); + }; + + await Promise.all([ + await castVote(members[0], Field(0)), + await castVote(members[1], Field(1)), + await castVote(members[2], Field(1)), + await castVote(members[3], Field(1)), + await castVote(members[4], Field(0)) + ]); + + const state2 = zkApp.getVoteCounts(); + + expect([state2.approve, state2.reject]) + .toEqual([state1.approve.add(Field(3)), state1.reject.add(Field(2))]); + }); + + it('notmember vote approve', async () => { + await localDeploy(); + const user = notMembers[Math.floor(Math.random() * notMembers.length)]; + const state1 = zkApp.getVoteCounts(); + await expect(async () => { + const txn = await Mina.transaction(user.account, async () => { + await zkApp.vote(Field(1), memberMap.getWitness(user.hashKey)); + }); + await txn.prove(); + await txn.sign([user.key]).send(); + }).rejects.toThrow('Member validation failed'); + const state2 = zkApp.getVoteCounts(); + expect(state2).toEqual(state1); + }); + + it('merkle tree root update and access', async () => { + await localDeploy(); + const tree = new MerkleMap(); + members.forEach((member) => { + tree.set(member.hashKey, Field(1)); + }); + const txnRootUpdate = await Mina.transaction(deployerAccount, async () => { + await zkApp.updateMemberRoot(tree.getRoot()); + }); + await txnRootUpdate.prove(); + await txnRootUpdate.sign([deployerKey, zkAppPrivateKey]).send(); + const currentRoot = zkApp.getMemberRoot(); + expect(currentRoot).toEqual(tree.getRoot()); + }); +}); \ No newline at end of file diff --git a/learn/renjuntao/task2/Vote.ts b/learn/renjuntao/task2/Vote.ts new file mode 100644 index 000000000..8193e894e --- /dev/null +++ b/learn/renjuntao/task2/Vote.ts @@ -0,0 +1,60 @@ +import { Bool, Field, MerkleMapWitness, method, Poseidon, PublicKey, SmartContract, state, State } from 'o1js'; + +export default class Vote extends SmartContract { + @state(PublicKey) deployerPublicKey = State(); + // 赞成 + @state(Field) yesVotes = State(); + // 反对 + @state(Field) noVotes = State(); + // 成员证明 + @state(Field) VoteMemberMapRoot = State(); + + init() { + super.init(); + this.deployerPublicKey.set(this.sender.getAndRequireSignature()); + this.yesVotes.set(Field(0)); + this.noVotes.set(Field(0)); + this.VoteMemberMapRoot.set(Field(0)); + } + + @method async vote(ticket: Field, witness: MerkleMapWitness) { + // 成员检测 + const currentRoot = this.VoteMemberMapRoot.getAndRequireEquals(); + const sender = this.sender.getAndRequireSignature(); + const key = Poseidon.hash(sender.toFields()); + const [root, keyWitness] = witness.computeRootAndKey(Field(1)); + Bool.and( + currentRoot.equals(root), + keyWitness.equals(key), + ).assertTrue('Member validation failed'); + + // 参数验证 + ticket.equals(Field(0)).or(ticket.equals(Field(1))).assertTrue('isYes must be 0 or 1'); + + // 获取当前的“是”票和“否”票数量 + const currentYesVotes = this.yesVotes.getAndRequireEquals(); + const currentNoVotes = this.noVotes.getAndRequireEquals(); + + // 更新票数 + this.yesVotes.set(currentYesVotes.add(ticket)); + this.noVotes.set(currentNoVotes.add(Field(1).sub(ticket))); + } + + @method async updateMemberRoot(newRoot: Field) { + const deployer = this.deployerPublicKey.getAndRequireEquals(); + const sender = this.sender.getAndRequireSignature(); + sender.equals(deployer).assertTrue('Only deployer can perform this action'); + this.VoteMemberMapRoot.set(newRoot); + } + + getVoteCounts() { + return { + approve: this.yesVotes.get(), + reject: this.noVotes.get(), + }; + } + + getMemberRoot() { + return this.VoteMemberMapRoot.get(); + } +} \ No newline at end of file diff --git a/learn/renjuntao/task2/readme.md b/learn/renjuntao/task2/readme.md index 2bb3092fe..4226c0fe2 100644 --- a/learn/renjuntao/task2/readme.md +++ b/learn/renjuntao/task2/readme.md @@ -4,5 +4,3 @@ 2. 考虑检查投票者属于团队成员,假设队员不会重复投票 请提交测试执行脚本。 - -#todo \ No newline at end of file diff --git a/learn/renjuntao/task2/test.png b/learn/renjuntao/task2/test.png new file mode 100644 index 0000000000000000000000000000000000000000..f65296c7882476977c19ea45a6d6185f67ac28fe GIT binary patch literal 26595 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 literal 0 HcmV?d00001