UNPKG

l1-lottery-contracts

Version:

This repo contains smart contracts and related scripts for ZkNoid L1 Lottery proposed [here](https://forums.minaprotocol.com/t/zknoid-l1-lottery/6269)

147 lines 5.2 kB
// import * as fs from 'fs'; import { Field, Provable, provable, Struct, UInt32, UInt64, } from 'o1js'; // import { PackedUInt32Factory } from 'o1js-pack'; const MAX_BITS_PER_FIELD = 254n; const L = 7; // 7 32-bit uints fit in one Field const SIZE_IN_BITS = 32n; export function PackingPlant(elementType, l, bitSize) { if (bitSize * BigInt(l) > MAX_BITS_PER_FIELD) { throw new Error(`The Packing Plant is only accepting orders that can fit into one Field, try using MultiPackingPlant`); } class Packed_ extends Struct({ packed: Field, }) { constructor(packed) { super({ packed }); } // Must implement these in type-specific implementation static extractField(input) { throw new Error('Must implement extractField'); } static sizeInBits() { throw new Error('Must implement sizeInBits'); } static unpack(f) { throw new Error('Must implement unpack'); } // End /** * * @param unpacked Array of the implemented packed type * @throws if the length of the array is longer than the length of the implementing factory config */ static checkPack(unpacked) { if (unpacked.length > l) { throw new Error(`Input of size ${unpacked.length} is larger than expected size of ${l}`); } } /** * * @param unpacked Array of the implemented packed type, must be shorter than the max allowed, which varies by type, will throw if the input is too long * @returns Field, packed with the information from the unpacked input */ static pack(unpacked) { this.checkPack(unpacked); let f = this.extractField(unpacked[0]); const n = Math.min(unpacked.length, l); for (let i = 1; i < n; i++) { const c = Field((2n ** this.sizeInBits()) ** BigInt(i)); f = f.add(this.extractField(unpacked[i]).mul(c)); } return f; } /** * * @param f Field, packed with the information, as returned by #pack * @returns Array of bigints, which can be decoded by the implementing class into the final type */ static unpackToBigints(f) { let unpacked = new Array(l); unpacked.fill(0n); let packedN; if (f) { packedN = f.toBigInt(); } else { throw new Error('No Packed Value Provided'); } for (let i = 0; i < l; i++) { unpacked[i] = packedN & ((1n << this.sizeInBits()) - 1n); packedN >>= this.sizeInBits(); } return unpacked; } // NOTE: adding to fields here breaks the proof generation. Probably not overriding it correctly /** * @returns array of single Field element which constitute the packed object */ toFields() { return [this.packed]; } assertEquals(other) { this.packed.assertEquals(other.packed); } } Packed_.type = provable({ packed: Field }, {}); Packed_.l = l; Packed_.bitSize = bitSize; return Packed_; } export function PackedUInt32Factory(l = L) { class PackedUInt32_ extends PackingPlant(UInt32, l, SIZE_IN_BITS) { static extractField(input) { return input.value; } static sizeInBits() { return SIZE_IN_BITS; } /** * * @param f Field, packed with the information, as returned by #pack * @returns Array of UInt32 */ static unpack(f) { const unpacked = Provable.witness(Provable.Array(UInt32, l), () => { const unpacked = this.unpackToBigints(f); return unpacked.map((x) => UInt32.from(x)); }); f.assertEquals(PackedUInt32_.pack(unpacked)); return unpacked; } /** * * @param uint32s Array of UInt32s to be packed * @returns Instance of the implementing class */ static fromUInt32s(uint32s) { const packed = PackedUInt32_.pack(uint32s); return new PackedUInt32_(packed); } /** * * @param bigints Array of bigints to be packed * @returns Instance of the implementing class */ static fromBigInts(bigints) { const uint32s = bigints.map((x) => UInt32.from(x)); return PackedUInt32_.fromUInt32s(uint32s); } toBigInts() { return PackedUInt32_.unpack(this.packed).map((x) => x.toBigint()); } } return PackedUInt32_; } export class NumberPacked extends PackedUInt32Factory() { } export function convertToUInt64(value) { let val = UInt64.Unsafe.fromField(value); UInt64.check(val); return val; } export function convertToUInt32(value) { let val = UInt32.Unsafe.fromField(value); UInt32.check(val); return val; } //# sourceMappingURL=util.js.map