Skip to content

Commit

Permalink
examples dir; clean up readme; curveOpts implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
drspacemn committed Apr 15, 2022
1 parent f696141 commit f9caf6e
Show file tree
Hide file tree
Showing 14 changed files with 271 additions and 185 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ vendor/

*.txt

tmp/
tmp/

examples/**/*.json
158 changes: 27 additions & 131 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,151 +12,47 @@
</a>
</p>

## Examples
Caigo is an MIT-licensed Go library for interacting with [StarkNet](https://docs.starknet.io/docs/intro).

### deploy/call/invoke
Deploy a compiled contract to testnet, query the initial state, and invoke a state transition.
### Getting Started
- library documentation available at [pkg.go.dev](https://pkg.go.dev/github.com/dontpanicdao/caigo).
- [example](./examples/starkcurve) initializing the StarkCurve for signing and verification
- [example](./examples/starknet) for StarkNet interactions including deploy, call, invoke, and poll transaction

### Compatibility and stability
Caigo is currently under active development and will under go breaking changes until the initial stable(v1.0.0) release. The example directories and *_test.go files should always be applicable for the latest commitment on the main branch.
*NOTE: examples and tests may be out of sync with tagged versions and pkg.go.dev documentation*


### Run Examples
starkcurve
```go
package main

import (
"fmt"

"github.com/dontpanicdao/caigo"
)

func main() {
// init the stark curve with constants
// will pull the 'pedersen_params.json' file if you don't have it locally
curve, err := caigo.SCWithConstants("")
if err != nil {
panic(err.Error())
}

// init starknet gateway client
gw := caigo.NewGateway() //defaults to goerli

// get random value for salt
priv, _ := curve.GetRandomPrivateKey()

// deploy StarkNet contract with random salt
deployRequest := caigo.DeployRequest{
ContractAddressSalt: caigo.BigToHex(priv),
ConstructorCalldata: []string{},
}

// example: https://github.com/starknet-edu/ultimate-env/blob/main/counter.cairo
deployResponse, err := gw.Deploy("counter_compiled.json", deployRequest)
if err != nil {
panic(err.Error())
}
fmt.Printf("Deployment Response: \n\t%+v\n\n", deployResponse)

// poll until the desired transaction status
pollInterval := 5
n, status, err := gw.PollTx(deployResponse.TransactionHash, caigo.ACCEPTED_ON_L2, pollInterval, 150)
if err != nil {
panic(err.Error())
}
fmt.Printf("Poll %dsec %dx \n\ttransaction(%s) status: %s\n\n", n * pollInterval, n, deployResponse.TransactionHash, status)

// fetch transaction details
tx, err := gw.GetTransaction(deployResponse.TransactionHash)
if err != nil {
panic(err.Error())
}

// call StarkNet contract
callResp, err := gw.Call(caigo.StarknetRequest{
ContractAddress: tx.Transaction.ContractAddress,
EntryPointSelector: caigo.BigToHex(caigo.GetSelectorFromName("get_count")),
})
if err != nil {
panic(err.Error())
}
fmt.Println("Counter is currently at: ", callResp[0])

// invoke StarkNet contract external function
invResp, err := gw.Invoke(caigo.StarknetRequest{
ContractAddress: tx.Transaction.ContractAddress,
EntryPointSelector: caigo.BigToHex(caigo.GetSelectorFromName("increment")),
})
if err != nil {
panic(err.Error())
}

n, status, err = gw.PollTx(invResp.TransactionHash, caigo.ACCEPTED_ON_L2, 5, 150)
if err != nil {
panic(err.Error())
}
fmt.Printf("Poll %dsec %dx \n\ttransaction(%s) status: %s\n\n", n * pollInterval, n, deployResponse.TransactionHash, status)

callResp, err = gw.Call(caigo.StarknetRequest{
ContractAddress: tx.Transaction.ContractAddress,
EntryPointSelector: caigo.BigToHex(caigo.GetSelectorFromName("get_count")),
})
if err != nil {
panic(err.Error())
}
fmt.Println("Counter is currently at: ", callResp[0])
}
cd examples/starkcurve
go run main.go
```

### sign/verify
Although the library adheres to the 'elliptic/curve' interface. All testing has been done against library function explicity. It is recommended to use in the same way(i.e. `curve.Sign` and not `ecdsa.Sign`).

starknet
```go
package main

import (
"fmt"
"math/big"

"github.com/dontpanicdao/caigo"
)

func main() {
// NOTE: when not given local file path this pulls the curve data from Starkware github repo
curve, err := caigo.SCWithConstants("")
if err != nil {
panic(err.Error())
}

hash, err := curve.PedersenHash([]*big.Int{caigo.HexToBN("0x12773"), caigo.HexToBN("0x872362")})
if err != nil {
panic(err.Error())
}

priv, _ := curve.GetRandomPrivateKey()

x, y, err := curve.PrivateToPoint(priv)
if err != nil {
panic(err.Error())
}

r, s, err := curve.Sign(hash, priv)
if err != nil {
panic(err.Error())
}

if curve.Verify(hash, r, s, x, y) {
fmt.Println("signature is valid")
} else {
fmt.Println("signature is invalid")
}
}
cd examples/starknet
wget https://github.com/starknet-edu/ultimate-env/blob/main/counter.cairo
python3.7 -m venv ~/cairo_venv; source ~/cairo_venv/bin/activate; export STARKNET_NETWORK=alpha-goerli
starknet-compile counter.cairo --output counter_compiled.json --abi counter_abi.json
go run main.go
```

### Test && Benchmark
### Run Tests

```go
// run tests
go test -v
```

### Run Benchmarks

// run benchmarks
```go
go test -bench=.
```


## Issues

If you find an issue/bug or have a feature request please submit an issue here
Expand Down
40 changes: 7 additions & 33 deletions caigo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

func TestHashAndSign(t *testing.T) {
curve, err := SCWithConstants("./pedersen_params.json")
curve, err := SC(WithConstants("./pedersen_params.json"))
if err != nil {
t.Errorf("Could not init with constant points: %v\n", err)
}
Expand Down Expand Up @@ -62,7 +62,7 @@ func TestComputeFact(t *testing.T) {
}

func TestBadSignature(t *testing.T) {
curve, err := SCWithConstants("./pedersen_params.json")
curve, err := SC(WithConstants("./pedersen_params.json"))
if err != nil {
t.Errorf("Could not init with constant points: %v\n", err)
}
Expand Down Expand Up @@ -103,7 +103,7 @@ func TestBadSignature(t *testing.T) {
}

func BenchmarkSignatureVerify(b *testing.B) {
curve, _ := SCWithConstants("./pedersen_params.json")
curve, _ := SC(WithConstants("./pedersen_params.json"))

pr, _ := curve.GetRandomPrivateKey()

Expand Down Expand Up @@ -145,7 +145,7 @@ func TestKnownSignature(t *testing.T) {
rIn, _ := new(big.Int).SetString("607684330780324271206686790958794501662789535258258105407533051445036595885", 10)
sIn, _ := new(big.Int).SetString("453590782387078613313238308551260565642934039343903827708036287031471258875", 10)

curve, err := SCWithConstants("./pedersen_params.json")
curve, err := SC(WithConstants("./pedersen_params.json"))
if err != nil {
t.Errorf("Could not init with constant points: %v\n", err)
}
Expand All @@ -170,7 +170,7 @@ func TestKnownSignature(t *testing.T) {
}

func TestDerivedSignature(t *testing.T) {
curve, err := SCWithConstants("./pedersen_params.json")
curve, err := SC(WithConstants("./pedersen_params.json"))
if err != nil {
t.Errorf("Could not init with constant points: %v\n", err)
}
Expand Down Expand Up @@ -208,34 +208,8 @@ func TestDerivedSignature(t *testing.T) {
}
}

// func TestTransactionHash(t *testing.T) {
// curve := SC()

// jtx := JSTransaction{
// Calldata: []string{"2914367423676101327401096153024331591451054625738519726725779300741401683065", "1284328616562954354594453552152941613439836383012703358554726925609665244667", "3", "1242951120254381876598", "9", "22108152553797646456187940211", "14"},
// ContractAddress: "0x6f8b21c8354e8ba21ead656932eaa21e728f8c81f001488c186a336d7038cf1",
// EntryPointSelector: "0x240060cdb34fcc260f41eac7474ee1d7c80b7e3607daff9ac67c7ea2ebb1c44",
// EntryPointType: "EXTERNAL",
// JSSignature: []string{"1941185432155203218742540925113146991052744726484097092312705586406341211736", "1060098570318028605648271956533461104484177708855341648099672514178101492604"},
// TransactionHash: "0x14ac93b17d35cc984ff7f186172175cd4341520d32748a406627e48605b38df",
// Nonce: "0xe",
// }

// tx := jtx.ConvertTx()
// hashFinal, err := curve.HashMsg(
// HexToBN("0x6f8b21c8354e8ba21ead656932eaa21e728f8c81f001488c186a336d7038cf1"),
// tx,
// )
// if err != nil {
// t.Errorf("Could not hash tx arguments: %v\n", err)
// }
// if hashFinal.Cmp(HexToBN("0x2c50e0db592d8149ef09c215846d629206b0d2d40509d313a0b1072f172f0ad")) != 0 {
// t.Errorf("Incorrect hash: got %v expected %v\n", hashFinal, HexToBN("0x2c50e0db592d8149ef09c215846d629206b0d2d40509d313a0b1072f172f0ad"))
// }
// }

func TestVerifySignature(t *testing.T) {
curve := SC()
curve, _ := SC()
hash := HexToBN("0x7f15c38ea577a26f4f553282fcfe4f1feeb8ecfaad8f221ae41abf8224cbddd")
r, _ := new(big.Int).SetString("2458502865976494910213617956670505342647705497324144349552978333078363662855", 10)
s, _ := new(big.Int).SetString("3439514492576562277095748549117516048613512930236865921315982886313695689433", 10)
Expand All @@ -249,7 +223,7 @@ func TestVerifySignature(t *testing.T) {
}

func TestUIVerifySignature(t *testing.T) {
curve := SC()
curve, _ := SC()
hash := HexToBN("0x324df642fcc7d98b1d9941250840704f35b9ac2e3e2b58b6a034cc09adac54c")
r, _ := new(big.Int).SetString("2849277527182985104629156126825776904262411756563556603659114084811678482647", 10)
s, _ := new(big.Int).SetString("3156340738553451171391693475354397094160428600037567299774561739201502791079", 10)
Expand Down
20 changes: 13 additions & 7 deletions curve.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,20 @@ type StarkCurvePayload struct {
ConstantPoints [][]*big.Int `json:"CONSTANT_POINTS"`
}

func SC() StarkCurve {
InitCurve()
return sc
}
func SC(opts ...CurveOption) (StarkCurve, error) {
var gopts curveOptions

for _, opt := range opts {
opt.apply(&gopts)
}

func SCWithConstants(path string) (StarkCurve, error) {
err := InitWithConstants(path)
return sc, err
if gopts.initConstants {
err := InitWithConstants(gopts.paramsPath)
return sc, err
} else {
InitCurve()
return sc, nil
}
}

/*
Expand Down
14 changes: 7 additions & 7 deletions curve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

func TestPedersenHash(t *testing.T) {
curve, err := SCWithConstants("./pedersen_params.json")
curve, err := SC(WithConstants("./pedersen_params.json"))
if err != nil {
t.Errorf("Could not init with constant points: %v\n", err)
}
Expand All @@ -33,7 +33,7 @@ func TestPedersenHash(t *testing.T) {
}

func BenchmarkPedersenHash(b *testing.B) {
curve, _ := SCWithConstants("./pedersen_params.json")
curve, _ := SC(WithConstants("./pedersen_params.json"))

var suite [][]*big.Int
suite = append(suite, []*big.Int{HexToBN("0x12773"), HexToBN("0x872362")})
Expand All @@ -51,7 +51,7 @@ func BenchmarkPedersenHash(b *testing.B) {
}

func TestInitCurveWithConstants(t *testing.T) {
curve, err := SCWithConstants("./pedersen_params.json")
curve, err := SC(WithConstants("./pedersen_params.json"))
if err != nil {
t.Errorf("Could not init with constant points: %v\n", err)
}
Expand All @@ -68,7 +68,7 @@ func TestInitCurveWithConstants(t *testing.T) {
}

func TestDivMod(t *testing.T) {
curve := SC()
curve, _ := SC()
inX, _ := new(big.Int).SetString("311379432064974854430469844112069886938521247361583891764940938105250923060", 10)
inY, _ := new(big.Int).SetString("621253665351494585790174448601059271924288186997865022894315848222045687999", 10)
DIVMODRES, _ := new(big.Int).SetString("2577265149861519081806762825827825639379641276854712526969977081060187505740", 10)
Expand All @@ -80,7 +80,7 @@ func TestDivMod(t *testing.T) {
}

func TestAdd(t *testing.T) {
curve := SC()
curve, _ := SC()
pub0, _ := new(big.Int).SetString("1468732614996758835380505372879805860898778283940581072611506469031548393285", 10)
pub1, _ := new(big.Int).SetString("1402551897475685522592936265087340527872184619899218186422141407423956771926", 10)
EXPX, _ := new(big.Int).SetString("2573054162739002771275146649287762003525422629677678278801887452213127777391", 10)
Expand All @@ -97,7 +97,7 @@ func TestAdd(t *testing.T) {
}

func TestMultAir(t *testing.T) {
curve := SC()
curve, _ := SC()
ry, _ := new(big.Int).SetString("2458502865976494910213617956670505342647705497324144349552978333078363662855", 10)
pubx, _ := new(big.Int).SetString("1468732614996758835380505372879805860898778283940581072611506469031548393285", 10)
puby, _ := new(big.Int).SetString("1402551897475685522592936265087340527872184619899218186422141407423956771926", 10)
Expand All @@ -119,7 +119,7 @@ func TestMultAir(t *testing.T) {
}

func TestGetY(t *testing.T) {
curve := SC()
curve, _ := SC()
h, _ := HexToBytes("04033f45f07e1bd1a51b45fc24ec8c8c9908db9e42191be9e169bfcac0c0d997450319d0f53f6ca077c4fa5207819144a2a4165daef6ee47a7c1d06c0dcaa3e456")
x, y := elliptic.Unmarshal(curve, h)

Expand Down
12 changes: 12 additions & 0 deletions examples/starkcurve/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module github.com/dontpanicdao/caigo/examples/starkcurve

go 1.18

replace github.com/dontpanicdao/caigo => ../../

require github.com/dontpanicdao/caigo v0.2.0

require (
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 // indirect
)
9 changes: 9 additions & 0 deletions examples/starkcurve/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
Loading

0 comments on commit f9caf6e

Please sign in to comment.