diff --git a/examples/deployAccount/go.mod b/examples/deployAccount/go.mod new file mode 100644 index 00000000..eb24beb6 --- /dev/null +++ b/examples/deployAccount/go.mod @@ -0,0 +1,11 @@ +module account + +go 1.18 + +require github.com/NethermindEth/starknet.go v0.2.1-0.20220620163912-1db2ca279608 +replace github.com/NethermindEth/starknet.go => ../../ +require ( + github.com/google/go-querystring v1.1.0 // indirect + golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect + golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c // indirect +) diff --git a/examples/deployAccount/go.work b/examples/deployAccount/go.work new file mode 100644 index 00000000..b32bc53a --- /dev/null +++ b/examples/deployAccount/go.work @@ -0,0 +1,6 @@ +go 1.18 + +use ( + . + ../.. +) diff --git a/examples/deployAccount/main.go b/examples/deployAccount/main.go new file mode 100644 index 00000000..589f92d3 --- /dev/null +++ b/examples/deployAccount/main.go @@ -0,0 +1,185 @@ +package main + +import ( + "fmt" + "math/big" + "os" + + "github.com/NethermindEth/juno/core/felt" + starknetgo "github.com/NethermindEth/starknet.go" + "github.com/NethermindEth/starknet.go/utils" +) + +var ( + name string = "testnet" + counterContract string = "0x0331034cbde9af8aef62929b5886b096ae3d11e33e6ca23122669e928d406500" + someMainnetContract string = "0x024dE48Fb640DB135B3dc85ef0FE2789e032FbCA2fca54E58aB8dB93ca22F767" + address string = "0x126dd900b82c7fc95e8851f9c64d0600992e82657388a48d3c466553d4d9246" + privakeKey string = "0x879d7dad7f9df54e1474ccf572266bba36d40e3202c799d6c477506647c126" + feeMargin uint64 = 115 + maxPoll int = 100 + pollInterval int = 6 + compiledOZAccount = "./contracts/account/OZAccount_compiled.json" // update + compiledERC20Contract = "./contracts/erc20/erc20_custom_compiled.json" // update + predeployedClassHash = "0x2794ce20e5f2ff0d40e632cb53845b9f4e526ebd8471983f7dbd355b721d5a" +) + +func getRandomKeys() (*felt.Felt, *felt.Felt) { + privateKey, err := starknetgo.Curve.GetRandomPrivateKey() + if err != nil { + fmt.Println("can't get random private key:", err) + os.Exit(1) + } + pubX, _, err := starknetgo.Curve.PrivateToPoint(privateKey) + if err != nil { + fmt.Println("can't generate public key:", err) + os.Exit(1) + } + privFelt, err := utils.BigIntToFelt(privateKey) + if err != nil { + panic(err) + } + pubFelt, err := utils.BigIntToFelt(pubX) + if err != nil { + panic(err) + } + return pubFelt, privFelt +} + +func precomputeAddress(CONTRACT_ADDRESS_PREFIX *felt.Felt, deployerAddress *felt.Felt, salt *felt.Felt, classHash *felt.Felt, constructorCalldataHash *felt.Felt) (*big.Int, error) { + bigIntArr, err := utils.FeltArrToBigIntArr([]*felt.Felt{ + CONTRACT_ADDRESS_PREFIX, + deployerAddress, + salt, + classHash, + constructorCalldataHash, + }) + if err != nil { + return nil, err + } + return starknetgo.Curve.ComputeHashOnElements(*bigIntArr) +} + +// Matches let qwe = computeHashOnElements([0,0,0,0,0,]); +func precomputeAddress_test() (*big.Int, error) { + + bigIntArr, err := utils.FeltArrToBigIntArr([]*felt.Felt{ + &felt.Zero, + &felt.Zero, + &felt.Zero, + &felt.Zero, + &felt.Zero, + }) + if err != nil { + return nil, err + } + return starknetgo.Curve.ComputeHashOnElements(*bigIntArr) +} + +// 1. Precompute addresss [Done!] +// 2. Fund account +// 3. Deploy + +func main() { + // init starknet gateway client + // godotenv.Load(".env.testnet") + // base := os.Getenv("INTEGRATION_BASE") + // c, err := ethrpc.DialContext(context.Background(), base) + // if err != nil { + // panic(err) + // } + // clientv02 := rpcv02.NewProvider(c) + + pub, _ := getRandomKeys() + classHash, err := utils.HexToFelt(predeployedClassHash) + if err != nil { + panic(err) + } + constructorCallData := pub + CONTRACT_ADDRESS_PREFIX, err := utils.HexToFelt("0x535441524b4e45545f434f4e54524143545f41444452455353") // Equivalent to 'STARKNET_CONTRACT_ADDRESS' + if err != nil { + panic(err) + } + deployerAddress := &felt.Zero + + precomputedAddress, err := precomputeAddress(CONTRACT_ADDRESS_PREFIX, deployerAddress, pub, classHash, constructorCallData) + + fmt.Println("precomputedAddress:", precomputedAddress) + + test, err := precomputeAddress_test() + testFelt, err := utils.BigIntToFelt(test) + fmt.Println("precomputeAddress_test:", testFelt) + + // Create starknet account + // ks := starknetgo.NewMemKeystore() + // account, err := starknetgo.NewRPCAccount() + + // // Make read contract call + // tx := rpcv02.FunctionCall{ + // ContractAddress: contractAddress, + // EntryPointSelector: types.GetSelectorFromNameFelt("getName"), + // } + // fmt.Println(tx.EntryPointSelector) + // // get count before tx + // callResp, err := clientv02.Call(context.Background(), tx, rpcv02.BlockID{Tag: "latest"}) + // if err != nil { + // panic(err.Error()) + // } + // fmt.Println("Response ", callResp[0]) + + // // init account handler + // ks := starknetgo.NewMemKeystore() + // fakeSenderAddress := privakeKey + // fakeSenderAddressFelt, err := utils.HexToFelt(fakeSenderAddress) + // if err != nil { + // panic(err) + // } + // addressFelt, err := utils.HexToFelt(address) + // if err != nil { + // panic(err) + // } + // ks.Put(fakeSenderAddress, types.SNValToBN(fakeSenderAddress)) + // account, err := starknetgo.NewGatewayAccount(fakeSenderAddressFelt, addressFelt, ks, gw) + // if err != nil { + // panic(err.Error()) + // } + + // increment := []types.FunctionCall{ + // { + // ContractAddress: counterContAddress, + // EntryPointSelector: types.GetSelectorFromNameFelt("increment"), + // }, + // } + + // // estimate fee for executing transaction + // feeEstimate, err := account.EstimateFee(context.Background(), increment, types.ExecuteDetails{}) + // if err != nil { + // panic(err.Error()) + // } + // fee, _ := big.NewInt(0).SetString(string(feeEstimate.OverallFee), 0) + // expandedFee := big.NewInt(0).Mul(fee, big.NewInt(int64(feeMargin))) + // max := big.NewInt(0).Div(expandedFee, big.NewInt(100)) + // fmt.Printf("Fee:\n\tEstimate\t\t%v wei\n\tEstimate+Margin\t\t%v wei\n\n", feeEstimate.OverallFee, max) + + // // execute transaction + // execResp, err := account.Execute(context.Background(), increment, types.ExecuteDetails{MaxFee: big.NewInt(1000000000000)}) + // if err != nil { + // panic(err.Error()) + // } + + // n, receipt, err := gw.WaitForTransaction(context.Background(), execResp.TransactionHash.String(), pollInterval, maxPoll) + // if err != nil { + // panic(err.Error()) + // } + // fmt.Printf("Poll %dsec %dx \n\ttransaction(%s) receipt: %s\n\n", n*pollInterval, n, execResp.TransactionHash, receipt.Status) + + // // get count after tx + // callResp, err = gw.Call(context.Background(), types.FunctionCall{ + // ContractAddress: counterContAddress, + // EntryPointSelector: types.GetSelectorFromNameFelt("get_count"), + // }, "") + // if err != nil { + // panic(err.Error()) + // } + // fmt.Println("Counter is currently at: ", callResp[0]) +} diff --git a/utils/Felt.go b/utils/Felt.go index db97b235..d92883f4 100644 --- a/utils/Felt.go +++ b/utils/Felt.go @@ -1,6 +1,7 @@ package utils import ( + "errors" "math/big" "github.com/NethermindEth/juno/core/felt" @@ -33,3 +34,14 @@ func FeltToBigInt(f *felt.Felt) (*big.Int, bool) { func BigIntToFelt(big *big.Int) (*felt.Felt, error) { return new(felt.Felt).SetString(big.String()) } +func FeltArrToBigIntArr(f []*felt.Felt) (*[]*big.Int, error) { + var bigArr []*big.Int + for _, felt := range f { + bint, ok := FeltToBigInt(felt) + if !ok { + return nil, errors.New("Failed to convert felt to big.Int") + } + bigArr = append(bigArr, bint) + } + return &bigArr, nil +}