o1-labs / o1js

TypeScript framework for zk-SNARKs and zkApps
https://docs.minaprotocol.com/en/zkapps/how-to-write-a-zkapp
Apache License 2.0
524 stars 118 forks source link

Add SmartContract.setVerificationKeyUnsafe(vk: VerificationKey) #1843

Open dfstio opened 1 month ago

dfstio commented 1 month ago

When building the SmartContract deploy transaction without calling compile(), o1js refuses to build, asking for the verification key to be present. In frontend, it does not make sense to compile the SmartContract if the proving is being made on backend. The workaround now is to directly set the _verificationKey variable using pre-calculated verification keys for different networks:

import { verificationKeys } from "./vk";

const adminContractVerificationKey = verificationKeys[chain]?.admin;
const tokenContractVerificationKey = verificationKeys[chain]?.token;

FungibleTokenAdmin._verificationKey = {
      hash: Field(adminContractVerificationKey.hash),
      data: adminContractVerificationKey.data,
    };
FungibleToken._verificationKey = {
      hash: Field(tokenContractVerificationKey.hash),
      data: tokenContractVerificationKey.data,
    };

The variable _verificationKey is an internal one and can be changed in future o1js versions.

Proposal:

Add SmartContract.setVerificationKeyUnsafe(vk: VerificationKey) to set verification key of the SmartContract without compiling it.

Trivo25 commented 1 month ago

We can definitely add that! But I am curious to understand if there are big benefits over disabling proving entirely?

await Mina.LocalBlockchain({ proofsEnabled: false });

Trivo25 commented 1 month ago

cc @dfstio

dfstio commented 1 month ago

We can definitely add that! But I am curious to understand if there are big benefits over disabling proving entirely?

await Mina.LocalBlockchain({ proofsEnabled: false });

It is a different case—I need this for devnet and mainnet and need to deploy a contract (in my case, FungibleToken) with a valid verification key that will be used later to send the transaction to the contract on devnet and mainnet. I prove all the transactions, just in the cloud. In the browser, I build the tx and sign it using Auro Wallet with the user's private key; then I send it to the cloud for proving.

Usually, I do not need to compile, prove, or have the verification keys for it. The deploy transaction is the exception as the verification key is needed for building the AccountUpdate, and I need a way to use it without compiling. Theoretically, I can build AccountUpdate manually, but it is better to rely on FungibleToken deploy().