-
IntroductionHi, ExplanationNow, I have downloaded the whole rollup example, created a few functions (seen below) based on the However, I can't get the rollup example to work properly for weeks. I have tried creating an Issue 1in the circuit file under the 18:47:36 INF compiling circuit
18:47:36 INF parsed circuit inputs nbPublic=2 nbSecret=46
18:47:36 INF building constraint builder nbConstraints=21695
Circuit compiled
Setup groth16 rank 1 constraint system
2023/11/28 18:47:40 Could not create witnesses: can't set fr.Element from type expr.LinearExpression
exit status 1 Does anybody have an idea what to do? I thought the Issue 2Another, maybe related, issue is, once I try to compile the circuit with ERR parsing circuit error="runtime error: invalid memory address or nil pointer dereference\nfrontend.parseCircuit.func2\n\tcompile.go:117\nruntime.panicmem\n\tpanic.go:261\nruntime.sigpanic\n\tsignal_windows.go:364\nutils.FromInterface\n\tconvert.go:85\nbn254.(*arithEngine).FromInterface\n\tcoeff.go:106\nr1cs.(*builder).toVariable\n\tbuilder.go:323\nr1cs.(*builder).toVariables.func1\n\tbuilder.go:333\nr1cs.(*builder).toVariables\n\tbuilder.go:340\nr1cs.(*builder).Add\n\tapi.go:42\nmimc.encryptPow5\n\tencrypt.go:150\nmimc.(*MiMC).Sum\n\tmimc.go:66\nmerkle.leafSum\n\tverify.go:69\nmerkle.(*MerkleProof).VerifyProof\n\tverify.go:92\ngnark_rollup.(*Circuit).Define\n\tcircuit.go:158\n"
2023/11/28 18:37:34 Could not compile circuit: parse circuit: runtime error: invalid memory address or nil pointer dereference
frontend.parseCircuit.func2
compile.go:117
runtime.panicmem
panic.go:261
runtime.sigpanic
signal_windows.go:364
utils.FromInterface
convert.go:85
bn254.(*arithEngine).FromInterface
coeff.go:106
r1cs.(*builder).toVariable
builder.go:323
r1cs.(*builder).toVariables.func1
builder.go:333
r1cs.(*builder).toVariables
builder.go:340
r1cs.(*builder).Add
api.go:42
mimc.encryptPow5
encrypt.go:150
mimc.(*MiMC).Sum
mimc.go:66
merkle.leafSum
verify.go:69
merkle.(*MerkleProof).VerifyProof
verify.go:92
gnark_rollup.(*Circuit).Define
circuit.go:158
exit status 1 I assumed, the My CodeFollowing a part of my main.go: package main
import (
"fmt"
"log"
"math/big"
"os"
. "rollup/src/gnark_rollup"
. "rollup/src/tools"
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/backend/groth16"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/frontend/cs/r1cs"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/tidwall/gjson"
)
func main() {
var amount uint64 = 10
var operatorA, privKeys = CreateOP(10)
// get info on both parties of the transaction
sender, err := operatorA.ReadAcc(0)
if err != nil {
log.Fatalf("Error reading sender account: %v", err)
}
receiver, err := operatorA.ReadAcc(1)
if err != nil {
log.Fatalf("Error reading receiver account: %v", err)
}
// Transactions
firstTx := NewTransfer(amount, sender.PubKey, receiver.PubKey, sender.Nonce)
firstTx.Sign(privKeys[0], operatorA.H)
err = operatorA.UpdateState(firstTx, 0)
if err != nil {
log.Fatalf("Error updating operator state: %v", err)
}
r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &operatorA.Witnesses)
if err != nil {
log.Fatalln("Could not compile circuit:", err)
}
fmt.Println("Circuit compiled")
// groth16 zkSNARK: Setup
pk, vk, err := groth16.Setup(r1cs)
if err != nil {
log.Fatalln("Could not setup pk and vk:", err)
}
fmt.Println("Setup groth16 rank 1 constraint system")
// create witness and proof
witness, err := frontend.NewWitness(&operatorA.Witnesses, ecc.BN254.ScalarField())
if err != nil {
log.Fatalf("Could not create witnesses: %v", err)
}
fmt.Println("witness created: ", witness)
publicWitness, err := witness.Public()
if err != nil {
log.Fatalf("Could not create public witness: %v", err)
}
// generate the proof
proof, err = groth16.Prove(r1cs, pk, witness)
if err != nil {
log.Fatalf("Could not create proof using pk and witnesses: %v", err)
}
fmt.Println("Proof created")
// verify the proof
err = groth16.Verify(proof, vk, publicWitness)
if err != nil {
log.Fatalf("invalid proof: %v", err)
}
} Following the functions I copy pasted from func CreateOP(nbAccounts int) (Operator, []eddsa.PrivateKey) {
// TODO: create Rollup object and create respective smart contract
op, userKeys := genOperator(nbAccounts)
return op, userKeys
}
// returns a single account on the rollup
func genAccount(i int) (Account, eddsa.PrivateKey) {
var acc Account
var rnd fr.Element
var privkey eddsa.PrivateKey
// create account, the i-th account has a balance of 20+i
acc.index = uint64(i)
acc.Nonce = uint64(i)
acc.balance.SetUint64(uint64(i) + 20)
rnd.SetUint64(uint64(i))
src := rand.NewSource(int64(i))
r := rand.New(src)
pkey, err := eddsa.GenerateKey(r)
if err != nil {
panic(err)
}
privkey = *pkey
acc.PubKey = privkey.PublicKey
return acc, privkey
}
// Returns a newly created operator and the private keys of the associated accounts
func genOperator(nbAccounts int) (Operator, []eddsa.PrivateKey) {
operator := NewOperator(nbAccounts)
operator.Witnesses.allocateSlicesMerkleProofs()
userAccounts := make([]eddsa.PrivateKey, nbAccounts)
// randomly fill the accounts
for i := 0; i < nbAccounts; i++ {
acc, privkey := genAccount(i)
// fill the index map of the operator
b := acc.PubKey.A.X.Bytes()
operator.AccountMap[string(b[:])] = acc.index
// fill user accounts list
userAccounts[i] = privkey
baccount := acc.Serialize()
copy(operator.State[SizeAccount*i:], baccount)
// create the list of hashes of account
operator.H.Reset()
operator.H.Write(acc.Serialize())
buf := operator.H.Sum([]byte{})
copy(operator.HashState[operator.H.Size()*i:], buf)
}
return operator, userAccounts
} Friendly requestI am a literal noob in all of this and would very much appreciate any Feedback in what I might be doing wrong. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
The given example is incomplete. I cannot get it to compile as a Go program. If you would like feedback then please provide full working example. If everything is in a file then a gist is sufficient, otherwise it should be a working git repo. But I think it has to do that you have commented out As for why compiling fails when you have slice allocation uncommented - dunno. Would have to see full example. |
Beta Was this translation helpful? Give feedback.
-
Alright, I think one of the problems I have is that I try to use
And then an assignment/witnesses variable, also of type circuit, but filled with the necessary information:
Current errorHowever, if I pass on the
Even if I use If I leave
Existing ProblemSo my problem is that I still can't get the rollup example to work for a simple transaction. Probably because I do not exactly know how to use the library, e.g., when to use |
Beta Was this translation helpful? Give feedback.
After lots of trying out, I found the problem.
I wasn't allocating the slices before calling the
frontend.Define()
function. Unfortunately, it is not well documented, but I found it in this discussion post:Also in the test file, if you know what you are doing, you can see in e.g. in the test in line 122
func TestCircuitFull(t *testing.T)
, that the slices also get allocated separately there as well beforeassert.ProverSucceeded()
is called.Solution
Allocate the slices before calling the
frontend.Define()
function. Either by makingcircuit.allocateSlicesMerkleProofs()
and also its respective variables public, i.e., changing (Uppercase) the function and variable names (e.g.:AllocateSlices…