o1js-pack 0.4.2 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,11 +3,11 @@ export declare function PackingPlant<A, T extends InferProvable<A> = InferProvab
3
3
  assertEquals(other: any): void;
4
4
  packed: import("o1js/dist/node/lib/field").Field;
5
5
  }) & {
6
- type: import("o1js/dist/node/bindings/lib/provable-snarky").ProvableExtended<{
6
+ type: import("o1js/dist/node/bindings/lib/generic").GenericProvableExtendedPure<{
7
7
  packed: import("o1js/dist/node/lib/field").Field;
8
8
  }, {
9
9
  packed: string;
10
- }>;
10
+ }, import("o1js/dist/node/lib/field").Field>;
11
11
  l: number;
12
12
  bitSize: bigint;
13
13
  extractField(input: T): Field;
@@ -61,16 +61,19 @@ export declare function PackingPlant<A, T extends InferProvable<A> = InferProvab
61
61
  }) => {
62
62
  packed: import("o1js/dist/node/lib/field").Field;
63
63
  };
64
+ empty: () => {
65
+ packed: import("o1js/dist/node/lib/field").Field;
66
+ };
64
67
  };
65
68
  export declare function MultiPackingPlant<A, T extends InferProvable<A> = InferProvable<A>>(elementType: A, l: number, bitSize: bigint): (abstract new (packed: Array<Field>) => {
66
69
  assertEquals(other: any): void;
67
70
  packed: import("o1js/dist/node/lib/field").Field[];
68
71
  }) & {
69
- type: import("o1js/dist/node/bindings/lib/provable-snarky").ProvableExtended<{
72
+ type: import("o1js/dist/node/bindings/lib/generic").GenericProvableExtendedPure<{
70
73
  packed: import("o1js/dist/node/lib/field").Field[];
71
74
  }, {
72
75
  packed: string[];
73
- }>;
76
+ }, import("o1js/dist/node/lib/field").Field>;
74
77
  l: number;
75
78
  n: number;
76
79
  bitSize: bigint;
@@ -129,4 +132,7 @@ export declare function MultiPackingPlant<A, T extends InferProvable<A> = InferP
129
132
  }) => {
130
133
  packed: import("o1js/dist/node/lib/field").Field[];
131
134
  };
135
+ empty: () => {
136
+ packed: import("o1js/dist/node/lib/field").Field[];
137
+ };
132
138
  };
@@ -42,11 +42,11 @@ export declare function PackedBoolFactory(l?: number): {
42
42
  }): void;
43
43
  packed: import("o1js/dist/node/lib/field.js").Field;
44
44
  };
45
- type: import("o1js/dist/node/bindings/lib/provable-snarky.js").ProvableExtended<{
45
+ type: import("o1js/dist/node/bindings/lib/generic.js").GenericProvableExtendedPure<{
46
46
  packed: import("o1js/dist/node/lib/field.js").Field;
47
47
  }, {
48
48
  packed: string;
49
- }>;
49
+ }, import("o1js/dist/node/lib/field.js").Field>;
50
50
  l: number;
51
51
  bitSize: bigint;
52
52
  checkPack(unpacked: import("o1js/dist/node/lib/bool.js").Bool[]): void;
@@ -82,4 +82,7 @@ export declare function PackedBoolFactory(l?: number): {
82
82
  }) => {
83
83
  packed: import("o1js/dist/node/lib/field.js").Field;
84
84
  };
85
+ empty: () => {
86
+ packed: import("o1js/dist/node/lib/field.js").Field;
87
+ };
85
88
  };
@@ -47,11 +47,11 @@ export declare function PackedStringFactory(l?: number): {
47
47
  * @param f Field, packed with the information, as returned by #pack
48
48
  * @returns Array of Character
49
49
  */
50
- type: import("o1js/dist/node/bindings/lib/provable-snarky.js").ProvableExtended<{
50
+ type: import("o1js/dist/node/bindings/lib/generic.js").GenericProvableExtendedPure<{
51
51
  packed: import("o1js/dist/node/lib/field.js").Field;
52
52
  }, {
53
53
  packed: string;
54
- }>;
54
+ }, import("o1js/dist/node/lib/field.js").Field>;
55
55
  l: number;
56
56
  bitSize: bigint;
57
57
  checkPack(unpacked: Character[]): void;
@@ -87,6 +87,9 @@ export declare function PackedStringFactory(l?: number): {
87
87
  }) => {
88
88
  packed: import("o1js/dist/node/lib/field.js").Field;
89
89
  };
90
+ empty: () => {
91
+ packed: import("o1js/dist/node/lib/field.js").Field;
92
+ };
90
93
  };
91
94
  /**
92
95
  *
@@ -137,11 +140,11 @@ export declare function MultiPackedStringFactory(n?: number): {
137
140
  }): void;
138
141
  packed: import("o1js/dist/node/lib/field.js").Field[];
139
142
  };
140
- type: import("o1js/dist/node/bindings/lib/provable-snarky.js").ProvableExtended<{
143
+ type: import("o1js/dist/node/bindings/lib/generic.js").GenericProvableExtendedPure<{
141
144
  packed: import("o1js/dist/node/lib/field.js").Field[];
142
145
  }, {
143
146
  packed: string[];
144
- }>;
147
+ }, import("o1js/dist/node/lib/field.js").Field>;
145
148
  l: number;
146
149
  n: number;
147
150
  bitSize: bigint;
@@ -178,4 +181,7 @@ export declare function MultiPackedStringFactory(n?: number): {
178
181
  }) => {
179
182
  packed: import("o1js/dist/node/lib/field.js").Field[];
180
183
  };
184
+ empty: () => {
185
+ packed: import("o1js/dist/node/lib/field.js").Field[];
186
+ };
181
187
  };
@@ -42,11 +42,11 @@ export declare function PackedUInt32Factory(l?: number): {
42
42
  }): void;
43
43
  packed: import("o1js/dist/node/lib/field.js").Field;
44
44
  };
45
- type: import("o1js/dist/node/bindings/lib/provable-snarky.js").ProvableExtended<{
45
+ type: import("o1js/dist/node/bindings/lib/generic.js").GenericProvableExtendedPure<{
46
46
  packed: import("o1js/dist/node/lib/field.js").Field;
47
47
  }, {
48
48
  packed: string;
49
- }>;
49
+ }, import("o1js/dist/node/lib/field.js").Field>;
50
50
  l: number;
51
51
  bitSize: bigint;
52
52
  checkPack(unpacked: UInt32[]): void;
@@ -82,4 +82,7 @@ export declare function PackedUInt32Factory(l?: number): {
82
82
  }) => {
83
83
  packed: import("o1js/dist/node/lib/field.js").Field;
84
84
  };
85
+ empty: () => {
86
+ packed: import("o1js/dist/node/lib/field.js").Field;
87
+ };
85
88
  };
@@ -0,0 +1,7 @@
1
+ ## Using Tokens as State Smart Contract
2
+
3
+ Using o1js-pack, a token can actually be a packed value. Token balances are natively a `UInt64`, so there is not as much room as a full `Field`, but we can still pack 2 `UInt32`, or we could pack 8 characters, or 64 booleans.
4
+
5
+ The `mint` and `burn` mechanisms are used like an unspent transaction output system. The state going in is always burnt, and the state coming out is unrelated numerically. In the example in `run.ts`, the token balance is set to 5 when the state is (5, 0). But when the state is (5, 10), the token balance becomes 42949672965.
6
+
7
+ This can be useful for per-user state in a zkapp. Booleans could be used to track feature flags or whether or not a user account is active, in good standing, etc... Characters could be used to store shore strings on a per-user basis, perhaps a country code? UInts can be used like in this example to track the first and last time a user has used an app. Or you could use half of the state to track an actual user balance, and the other half to track another number like number of token transactions.
@@ -0,0 +1,62 @@
1
+ import {
2
+ SmartContract,
3
+ state,
4
+ State,
5
+ method,
6
+ UInt32,
7
+ UInt64,
8
+ Account,
9
+ Provable,
10
+ } from 'o1js';
11
+ import { PackedUInt32Factory } from '../../../src/index.js';
12
+
13
+ /**
14
+ * 2 UInt32s representing the first-joined block and the last-updated block
15
+ * Could be used in conjunction with some other app logic to ensure only active users can access some resource, or similar
16
+ */
17
+ export class UserBlockStamps extends PackedUInt32Factory(2) {}
18
+
19
+ export class UserBlockStampsToken extends SmartContract {
20
+ /**
21
+ * Initializes the user state by setting the first-joined blockstamp to the current blockheight
22
+ */
23
+ @method
24
+ joinSystem() {
25
+ const account = Account(this.sender, this.token.id);
26
+ const currentTokenBalance = account.balance.getAndAssertEquals();
27
+ currentTokenBalance.assertEquals(UInt64.from(0));
28
+
29
+ const userBlockStamps = UserBlockStamps.fromUInt32s([
30
+ this.network.blockchainLength.getAndAssertEquals(),
31
+ UInt32.from(0),
32
+ ]);
33
+ this.token.mint({
34
+ address: this.sender,
35
+ amount: UInt64.from(userBlockStamps.packed),
36
+ });
37
+ }
38
+
39
+ /**
40
+ * Updates the user state by setting the last-updated blockstamp to the current blockheight
41
+ */
42
+ @method
43
+ interactWithSystem() {
44
+ const account = Account(this.sender, this.token.id);
45
+ const currentTokenBalance = account.balance.getAndAssertEquals();
46
+ const existingUserBlockstamps = UserBlockStamps.unpack(
47
+ currentTokenBalance.value
48
+ );
49
+
50
+ this.token.burn({
51
+ address: this.sender,
52
+ amount: currentTokenBalance,
53
+ });
54
+
55
+ existingUserBlockstamps[1] =
56
+ this.network.blockchainLength.getAndAssertEquals();
57
+ this.token.mint({
58
+ address: this.sender,
59
+ amount: UInt64.from(UserBlockStamps.pack(existingUserBlockstamps)),
60
+ });
61
+ }
62
+ }
@@ -0,0 +1,71 @@
1
+ import { AccountUpdate, Mina, PrivateKey, UInt32 } from 'o1js';
2
+ import { UserBlockStamps, UserBlockStampsToken } from './contract.js';
3
+
4
+ let Local = Mina.LocalBlockchain({ proofsEnabled: true });
5
+ Mina.setActiveInstance(Local);
6
+
7
+ // a test account that pays all the fees, and puts additional funds into the zkapp
8
+ let { privateKey: senderKey, publicKey: sender } = Local.testAccounts[0];
9
+
10
+ // the zkapp account
11
+ let zkappKey = PrivateKey.random();
12
+ let zkappAddress = zkappKey.toPublicKey();
13
+
14
+ // a special account that is allowed to pull out half of the zkapp balance, once
15
+ let privilegedKey = PrivateKey.random();
16
+ let privilegedAddress = privilegedKey.toPublicKey();
17
+
18
+ let initialBalance = 10_000_000_000;
19
+ let zkapp = new UserBlockStampsToken(zkappAddress);
20
+
21
+ console.time('compile');
22
+ await UserBlockStampsToken.compile();
23
+ console.timeEnd('compile');
24
+
25
+ console.time('deploy');
26
+ let tx = await Mina.transaction(sender, () => {
27
+ let senderUpdate = AccountUpdate.fundNewAccount(sender);
28
+ senderUpdate.send({ to: zkappAddress, amount: initialBalance });
29
+ zkapp.deploy({ zkappKey });
30
+ });
31
+ await tx.prove();
32
+ await tx.sign([senderKey]).send();
33
+ console.timeEnd('deploy');
34
+
35
+ Local.setBlockchainLength(UInt32.from(5));
36
+
37
+ console.time('join system');
38
+ tx = await Mina.transaction(sender, () => {
39
+ AccountUpdate.fundNewAccount(sender);
40
+ zkapp.joinSystem();
41
+ });
42
+ await tx.prove();
43
+ await tx.sign([senderKey]).send();
44
+ console.timeEnd('join system');
45
+
46
+ let tokenBalance = Mina.getBalance(sender, zkapp.token.id);
47
+ console.log(tokenBalance.toString());
48
+ console.log(UserBlockStamps.unpack(tokenBalance.value).toString());
49
+
50
+ Local.setBlockchainLength(UInt32.from(10));
51
+
52
+ console.time('interact with system');
53
+ tx = await Mina.transaction(sender, () => {
54
+ zkapp.interactWithSystem();
55
+ });
56
+ await tx.prove();
57
+ await tx.sign([senderKey]).send();
58
+ console.timeEnd('interact with system');
59
+
60
+ tokenBalance = Mina.getBalance(sender, zkapp.token.id);
61
+ console.log(tokenBalance.toString());
62
+ console.log(UserBlockStamps.unpack(tokenBalance.value).toString());
63
+
64
+ // compile: 1.818s
65
+ // deploy: 615.559ms
66
+ // join system: 23.085s
67
+ // 5
68
+ // 5,0
69
+ // interact with system: 15.263s
70
+ // 42949672965
71
+ // 5,10
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "o1js-pack",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "description": "",
5
5
  "author": "45930",
6
6
  "license": "Apache-2.0",
@@ -40,11 +40,9 @@
40
40
  "husky": "^7.0.1",
41
41
  "jest": "^27.3.1",
42
42
  "lint-staged": "^11.0.1",
43
+ "o1js": "^0.15.1",
43
44
  "prettier": "^2.3.2",
44
45
  "ts-jest": "^27.0.7",
45
46
  "typescript": "^4.7.2"
46
- },
47
- "peerDependencies": {
48
- "o1js": "^0.13.*"
49
47
  }
50
48
  }
@@ -1,5 +1,5 @@
1
1
  import {
2
- Experimental,
2
+ ZkProgram,
3
3
  SelfProof,
4
4
  Character,
5
5
  Poseidon,
@@ -10,7 +10,8 @@ import { MultiPackedStringFactory } from '../../src/lib/packed-types/PackedStrin
10
10
 
11
11
  export class TextInput extends MultiPackedStringFactory(3) {}
12
12
 
13
- export const TextInputProgram = Experimental.ZkProgram({
13
+ export const TextInputProgram = ZkProgram({
14
+ name: 'TextInputProgram',
14
15
  publicInput: TextInput,
15
16
 
16
17
  methods: {
@@ -43,5 +44,5 @@ export const TextInputProgram = Experimental.ZkProgram({
43
44
  },
44
45
  });
45
46
 
46
- export let TextInputProof_ = Experimental.ZkProgram.Proof(TextInputProgram);
47
+ export let TextInputProof_ = ZkProgram.Proof(TextInputProgram);
47
48
  export class TextInputProof extends TextInputProof_ {}
@@ -1,9 +1,10 @@
1
- import { Experimental, SelfProof } from 'o1js';
1
+ import { ZkProgram, SelfProof } from 'o1js';
2
2
  import { PackedUInt32Factory } from '../../src/lib/packed-types/PackedUInt32';
3
3
 
4
4
  export class Votes extends PackedUInt32Factory() {}
5
5
 
6
- export const VotesProgram = Experimental.ZkProgram({
6
+ export const VotesProgram = ZkProgram({
7
+ name: 'VotesProgram',
7
8
  publicInput: Votes,
8
9
 
9
10
  methods: {
@@ -35,5 +36,5 @@ export const VotesProgram = Experimental.ZkProgram({
35
36
  },
36
37
  });
37
38
 
38
- export let VotesProof_ = Experimental.ZkProgram.Proof(VotesProgram);
39
+ export let VotesProof_ = ZkProgram.Proof(VotesProgram);
39
40
  export class VotesProof extends VotesProof_ {}