Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade examples to use Sepolia network #579

Merged
merged 11 commits into from
Jun 27, 2024
8 changes: 8 additions & 0 deletions examples/.env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# ----- use this variable to set the RPC provider URL
#RPC_PROVIDER_URL=http_insert_end_point

# ----- Use these variables to set up your account
#ACCOUNT_ADDRESS=0xyour_account_address
#PUBLIC_KEY=0xyour_starknet_public_key
#PRIVATE_KEY=0xyour_private_key
#ACCOUNT_CAIRO_VERSION=2
39 changes: 39 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
### Welcome!
To successfully execute these examples you'll need to configure some environment variables. To do so:

1. Rename the ".env.template" file located at the root of this folder to ".env"
1. Uncomment, and assign your Sepolia testnet endpoint to the `RPC_PROVIDER_URL` variable in the ".env" file
thiagodeev marked this conversation as resolved.
Show resolved Hide resolved
1. Uncomment, and assign your account address to the `ACCOUNT_ADDRESS` variable in the ".env" file (make sure to have a few ETH in it)
1. Uncomment, and assign your starknet public key to the `PUBLIC_KEY` variable in the ".env" file
1. Uncomment, and assign your private key to the `PRIVATE_KEY` variable in the ".env" file

The variables used vary from example to example, you'll see the required ones on each `main.go` file, usually after a "// Load variables from '.env' file" comment.
To run an example:

1. Make sure you are in the chosen example directory
1. Execute `go run main.go` to run it

#### Some FAQ answered by these examples
1. How to deploy an account via `DEPLOY_TRANSACTION`?
R: See [deployAccount](./deployAccount/main.go)
1. How to estimate fees?
R: See [deployAccount](./deployAccount/main.go), line 89.
1. How to generate random public and private keys?
R: See [deployAccount](./deployAccount/main.go), line 46.
1. How to use my existing account importing my account address, and public and private keys?
R: See [deployContractUDC](./deployContractUDC/main.go), lines 54 and 64.
1. How to get my nonce?
R: See [deployContractUDC](./deployContractUDC/main.go), line 70.
1. How to deploy a smart contract using UDC?
R: See [deployContractUDC](./deployContractUDC/main.go).
1. How to send an invoke transaction?
R: See [simpleInvoke](./simpleInvoke/main.go).
1. How to get the transaction status?
R: See [simpleInvoke](./simpleInvoke/main.go), line 131.
1. How to deploy an ERC20 token?
R: See [deployContractUDC](./deployContractUDC/main.go).
1. How to get the balance of a ERC20 token?
R: See [simpleCall](./simpleCall/main.go).
1. How to make a function call?
R: See [simpleCall](./simpleCall/main.go).

2 changes: 0 additions & 2 deletions examples/deployAccount/.env.template

This file was deleted.

18 changes: 9 additions & 9 deletions examples/deployAccount/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@

This example uses a pre-existing contract on the goerli network to deploy a new account contract. To successfully run this example, you will need: 1) a goerli endpoint, and 2) to fund the precomputed address.
This example uses a pre-existing class on the Sepolia network to deploy a new account contract. To successfully run this example, you will need: 1) a Sepolia endpoint, and 2) some Sepolia ETH to fund the precomputed address.

Steps:
1. Rename the ".env.template" file to ".env.testnet"
2. Uncomment, and assign your testnet endpoint to the "INTEGRATION_BASE" variable
3. Execute `go mod tidy` (make sure you are in the "deployAccount" folder)
4. Execute `go run main.go`
5. Fund the precomputed address using a starknet faucet, eg https://faucet.goerli.starknet.io/
6. Press any key, then enter

At this point your account should be deployed on testnet, and you can use a block explorer like [Voyager](https://voyager.online/) to view your transaction using the transaction hash.
1. Rename the ".env.template" file located at the root of the "examples" folder to ".env"
1. Uncomment, and assign your Sepolia testnet endpoint to the `RPC_PROVIDER_URL` variable in the ".env" file
1. Make sure you are in the "deployAccount" directory
1. Execute `go run main.go`
1. Fund the precomputed address using a starknet faucet, eg https://starknet-faucet.vercel.app/
1. Press any key, then enter

At this point your account should be deployed on testnet, and you can use a block explorer like [Voyager](https://sepolia.voyager.online/) to view your transaction using the transaction hash.

38 changes: 0 additions & 38 deletions examples/deployAccount/go.mod

This file was deleted.

6 changes: 0 additions & 6 deletions examples/deployAccount/go.work

This file was deleted.

114 changes: 73 additions & 41 deletions examples/deployAccount/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,24 @@ package main
import (
"context"
"fmt"
"log"
"os"
"math"
"strconv"

"github.com/NethermindEth/juno/core/felt"
"github.com/NethermindEth/starknet.go/account"
"github.com/NethermindEth/starknet.go/rpc"
"github.com/NethermindEth/starknet.go/utils"
"github.com/joho/godotenv"

setup "github.com/NethermindEth/starknet.go/examples/internal"
)

var (
network string = "testnet"
predeployedClassHash = "0x2794ce20e5f2ff0d40e632cb53845b9f4e526ebd8471983f7dbd355b721d5a"
accountAddress = "0xdeadbeef"
accountContractVersion = 0 //Replace with the cairo version of your account contract
predeployedClassHash = "0x61dac032f228abef9c6626f995015233097ae253a7f72d68552db02f2971b8f"
)

// main initializes the client, sets up the account, deploys a contract, and sends a transaction to the network.
//
// It loads environment variables, dials the Ethereum RPC, creates a new account, casts the account address to a felt type,
// It loads environment variables, dials the Starknet Sepolia RPC, creates a new account, casts the account address to a felt type,
// sets up the account using the client, converts the predeployed class hash to a felt type, creates transaction data,
// precomputes an address, prompts the user to add funds to the precomputed address, signs the transaction,
// and finally sends the transaction to the network.
Expand All @@ -35,67 +33,101 @@ var (
//
// none
func main() {
// Initialise the client.
godotenv.Load(fmt.Sprintf(".env.%s", network))
url := os.Getenv("INTEGRATION_BASE")
// Load variables from '.env' file
rpcProviderUrl := setup.GetRpcProviderUrl()

clientv02, err := rpc.NewProvider(url)
// Initialise the client.
client, err := rpc.NewProvider(rpcProviderUrl)
if err != nil {
log.Fatal(fmt.Sprintf("Error dialing the RPC provider: %s", err))
panic(err)
}

// Get random keys for test purposes
ks, pub, _ := account.GetRandomKeys()
ks, pub, privKey := account.GetRandomKeys()
fmt.Printf("Generated public key: %v\n", pub)
fmt.Printf("Generated private key: %v\n", privKey)

accountAddressFelt, err := new(felt.Felt).SetString(accountAddress)
// Set up the account passing random values to 'accountAddress' and 'cairoVersion' variables,
// as for this case we only need the 'ks' to sign the deploy transaction.
accnt, err := account.NewAccount(client, pub, pub.String(), ks, 2)
if err != nil {
panic("Error casting accountAddress to felt")
panic(err)
}

// Set up account
acnt, err := account.NewAccount(clientv02, accountAddressFelt, pub.String(), ks, accountContractVersion)
classHash, err := utils.HexToFelt(predeployedClassHash)
if err != nil {
panic(err)
}

classHash, err := utils.HexToFelt(predeployedClassHash)
// Create transaction data
tx := rpc.BroadcastDeployAccountTxn{
DeployAccountTxn: rpc.DeployAccountTxn{
Nonce: &felt.Zero, // Contract accounts start with nonce zero.
MaxFee: new(felt.Felt).SetUint64(7268996239700),
thiagodeev marked this conversation as resolved.
Show resolved Hide resolved
Type: rpc.TransactionType_DeployAccount,
Version: rpc.TransactionV1,
Signature: []*felt.Felt{},
ClassHash: classHash,
ContractAddressSalt: pub,
ConstructorCalldata: []*felt.Felt{pub},
},
}

precomputedAddress, err := accnt.PrecomputeAddress(&felt.Zero, pub, classHash, tx.ConstructorCalldata)
if err != nil {
panic(err)
}
fmt.Println("PrecomputedAddress:", precomputedAddress)

// Create transaction data
tx := rpc.DeployAccountTxn{
Nonce: &felt.Zero, // Contract accounts start with nonce zero.
MaxFee: new(felt.Felt).SetUint64(4724395326064),
Type: rpc.TransactionType_DeployAccount,
Version: rpc.TransactionV1,
Signature: []*felt.Felt{},
ClassHash: classHash,
ContractAddressSalt: pub,
ConstructorCalldata: []*felt.Felt{pub},
// Sign the transaction
err = accnt.SignDeployAccountTransaction(context.Background(), &tx.DeployAccountTxn, precomputedAddress)
if err != nil {
panic(err)
}

precomputedAddress, err := acnt.PrecomputeAddress(&felt.Zero, pub, classHash, tx.ConstructorCalldata)
fmt.Println("precomputedAddress:", precomputedAddress)
// Estimate the transaction fee
feeRes, err := accnt.EstimateFee(context.Background(), []rpc.BroadcastTxn{tx}, []rpc.SimulationFlag{}, rpc.WithBlockTag("latest"))
if err != nil {
setup.PanicRPC(err)
}
estimatedFee := feeRes[0].OverallFee
var feeInETH float64
// If the estimated fee is higher than the current fee, let's override it and sign again
if estimatedFee.Cmp(tx.MaxFee) == 1 {
newFee, err := strconv.ParseUint(estimatedFee.String(), 0, 64)
if err != nil {
panic(err)
}
tx.MaxFee = new(felt.Felt).SetUint64(newFee + newFee/5) // fee + 20% to be sure
// Signing the transaction again
err = accnt.SignDeployAccountTransaction(context.Background(), &tx.DeployAccountTxn, precomputedAddress)
if err != nil {
panic(err)
}
feeInETH, _ = utils.FeltToBigInt(tx.MaxFee).Float64()
} else {
feeInETH, _ = utils.FeltToBigInt(estimatedFee).Float64()
feeInETH += feeInETH / 5 // fee + 20% to be sure
}
//converts fee value from WEI to ETH
feeInETH = feeInETH / (math.Pow(10, 18))

// At this point you need to add funds to precomputed address to use it.
var input string

fmt.Println("The `precomputedAddress` account needs to have enough ETH to perform a transaction.")
fmt.Println("Use the starknet faucet to send ETH to your `precomputedAddress`")
fmt.Printf("Use the starknet faucet to send ETH to your `precomputedAddress`. You need aproximately %f ETH. \n", feeInETH)
fmt.Println("When your account has been funded by the faucet, press any key, then `enter` to continue : ")
fmt.Scan(&input)

// Sign the transaction
err = acnt.SignDeployAccountTransaction(context.Background(), &tx, precomputedAddress)
if err != nil {
panic(err)
}

// Send transaction to the network
resp, err := acnt.AddDeployAccountTransaction(context.Background(), rpc.BroadcastDeployAccountTxn{DeployAccountTxn: tx})
resp, err := accnt.AddDeployAccountTransaction(context.Background(), tx)
if err != nil {
panic(fmt.Sprintf("Error returned from AddDeployAccountTransaction: %s", err))
fmt.Println("Error returned from AddDeployAccountTransaction: ")
setup.PanicRPC(err)
}
fmt.Println("AddDeployAccountTransaction response:", resp)

fmt.Println("AddDeployAccountTransaction successfully submitted! Wait a few minutes to see it in Voyager.")
fmt.Printf("Transaction hash: %v \n", resp.TransactionHash)
fmt.Printf("Contract address: %v \n", resp.ContractAddress)
}
2 changes: 0 additions & 2 deletions examples/deployAccountUDC/.env.template

This file was deleted.

9 changes: 0 additions & 9 deletions examples/deployAccountUDC/README.md

This file was deleted.

33 changes: 0 additions & 33 deletions examples/deployAccountUDC/go.mod

This file was deleted.

6 changes: 0 additions & 6 deletions examples/deployAccountUDC/go.work

This file was deleted.

Loading
Loading