Please refer to https://docs.brevis.network for the full documentation.
This SDK aims to provide developers with a framework to implement custom data analysis computations and to interoperate with Brevis' provers.
github.com/brevis-network/brevis-sdk/sdkHouses all things needed for writing custom circuits, compiling, proving, and interacting with brevis systems.github.com/brevis-network/brevis-sdk/testContains testing utilities.
BrevisApp is the entry point for most of the operations. To create a new app, use
app := sdk.NewBrevisApp(1, "RPC_URL", "OutputDir")The data that your circuit uses must be fed into the app before we can generate proofs.
app.AddReceipt(sdk.ReceiptData{/*...*/})
app.AddStorage(sdk.StorageData{/*...*/})
app.AddTransaction(sdk.TransactionData{/*...*/})package app
import "github.com/brevis-network/brevis-sdk/sdk"
// AppCircuit must be a struct
type AppCircuit struct{
// Custom inputs. These fields must be exported (first letter capitalized)
// These are the inputs that can be different for each proof you generate
// using the same circuit
MyInput sdk.Uint248
MyInput2 sdk.Bytes32
}
func DefaultAppCircuit() *AppCircuit {
return &AppCircuit{
MyInput: sdk.ConstUint248(0),
MyInput2: sdk.ConstBytes32([]byte{}),
}
}
// the struct AppCircuit must implement the sdk.AppCircuit interface
var _ sdk.AppCircuit = &AppCircuit{}
func (c *AppCircuit) Allocate() (maxReceipts, maxStorage, maxTransactions int) {
// When we return 32, 32, 64, it means that we are allowing our circuit to process
// a maximum of 32 receipts, 32 storages, and 64 transactions
return 32, 32, 64
}
var ConstEventID = ParseEventID(/* 0x123456... */)
func (c *AppCircuit) Define(api *sdk.CircuitAPI, input sdk.DataInput) error {
// You can access the data you added through app.AddReceipt etc.
receipts := sdk.NewDataStream(api, input.Receipts)
// Checking some the receipts properties against some constants
// In this example, by checking these, you are proving to your
// contract that you have checked that all events have a certain
// event ID
sdk.AssertEach(receipts, func(receipt sdk.Receipt) Variable {
return api.Equal(receipt.Fields[0].EventID, ConstEventID)
})
// You can then perform various data stream operations on the data.
// You can find the usage of specific API later.
blockNums := sdk.Map(receipts, func(r sdk.Receipt) sdk.Uint248 {
return r.BlockNum
})
minBlockNum := sdk.Min(blockNums)
values := sdk.Map(receipts, func(r sdk.Receipt) sdk.Uint248 {
return api.ToUint248(r.Value)
})
sum := sdk.Sum(values)
// sdk.Reduce(...)
// sdk.GroupBy(...)
// and more ...
// You can output any number of computation results using sdk.OutputXXX APIs
// These results will be available for use in your contract when the proof
// is verified on-chain
api.OutputUint(64, minBlockNum)
api.OutputUint(248, sum)
// more output...
return nil
}package app
import (
"testing"
"github.com/brevis-network/brevis-sdk/sdk"
"github.com/brevis-network/brevis-sdk/test"
)
func TestAppCircuit(t *testing.T) {
appCircuit := DefaultAppCircuit()
appCircuitAssignment := &AppCircuit{
MyInput: sdk.ConstUint248(123),
MyInput2: sdk.ConstBytes32([]byte{0, 1, 2, 3}),
}
// BuildAppCircuit fetches additional data required to generate proofs from the
// ETH RPC you provided and package the actual queried data into sdk.CircuitInput
circuitInput, err := app.BuildCircuitInput(appCircuitAssignment)
// brevis-sdk/test package
// IsSolved is a quick way to check if your circuit can be solved using the given
// inputs. This utility doesn't invoke the actual prover, so it's very fast. This
// function is more useful when you want to quickly iterate and debug your
// circuit logic.
test.IsSolved(t, appCircuit, appCircuitAssignment, circuitInput)
// ProverSucceeded is like IsSolved, but it internally goes through the entire
// proving/verifying cycle. This function is favored for real testing.
test.ProverSucceeded(t, appCircuit, appCircuitAssignment, circuitInput)
}