티스토리 뷰

1. 로컬 테스트넷 실행

$ anvil

2. 최상위 경로에 .env 파일 생성

PRIVATE_KEY=<anvil 실행 시 제공되는 프라이빗 키 중 하나>
RPC_ENDPOINT=http://localhost:8545

이 때 PRIVATE\_KEY0x로 시작하면 파싱에서가 발생하므로 0x를 지워준 16진수값만 넣어줍니다.


3. 배포 코드 작성

cmd/deploy/main.go

package main

import (
	"context"
	"crypto/ecdsa"
	"fmt"
	token "go-ethereum-example/gen"
	"math/big"
	"os"

	_ "github.com/joho/godotenv/autoload"

	"github.com/ethereum/go-ethereum/accounts/abi/bind"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/ethclient"
)

func main() {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	// Connect to Ethereum client with RPC endpoint
	client, err := ethclient.DialContext(ctx, os.Getenv("RPC_ENDPOINT"))
	handleError(err)

	defer client.Close()

	fmt.Println("Successfully connected to Ethereum client")

	// Parse wallet private key
	privateKey := mustParsePrivateKey()

	address := crypto.PubkeyToAddress(privateKey.PublicKey)

	fmt.Printf("Deploying contract from address %s\n", address.Hex())

	// Get nonce, gas price and chain ID from the Ethereum client
	nonce, err := client.PendingNonceAt(ctx, address)
	handleError(err)

	gasPrice, err := client.SuggestGasPrice(ctx)
	handleError(err)

	fmt.Printf("Suggested gas price: %s\n", gasPrice)

	chainID, err := client.NetworkID(ctx)
	handleError(err)

	fmt.Printf("Chain ID: %d\n", chainID)

	// Create an signer with the private key, chain ID and nonce
	signer, err := bind.NewKeyedTransactorWithChainID(privateKey, chainID)
	handleError(err)

	signer.GasPrice = gasPrice
	signer.GasLimit = 3000000
	signer.Nonce = big.NewInt(int64(nonce))

	// Deploy the contract with initial supply of 1,000,000 tokens
	initialSupply := big.NewInt(0).Mul(big.NewInt(1000000), big.NewInt(0).Exp(big.NewInt(10), big.NewInt(18), nil))

	_, tx, _, err := token.DeployToken(signer, client, initialSupply)
	handleError(err)

	fmt.Printf("Transaction hash: %s\n", tx.Hash().Hex())

	// Wait for the deployment to be mined
	contractAddress, err := bind.WaitDeployed(ctx, client, tx)
	handleError(err)

	fmt.Printf("Contract deployed! Contract address: %s\n", contractAddress.Hex())
}

func mustParsePrivateKey() *ecdsa.PrivateKey {
	rawPrivateKey := os.Getenv("PRIVATE_KEY")

	// Parse the private key
	privateKey, err := crypto.HexToECDSA(rawPrivateKey)
	handleError(err)

	return privateKey
}

func handleError(err error) {
	if err != nil {
		panic(err)
	}
}

.env 파일 자동으로 불러오기

import (
	...

	_ "github.com/joho/godotenv/autoload"

	...
)

테스트넷 RPC 클라이언트 연결

// Connect to Ethereum client with RPC endpoint
client, err := ethclient.DialContext(ctx, os.Getenv("RPC_ENDPOINT"))
handleError(err)

defer client.Close()

fmt.Println("Successfully connected to Ethereum client")

16진수 프라이빗 키를 ECDSA 프라이빗 키로 파싱

// Parse wallet private key
privateKey := mustParsePrivateKey()
func mustParsePrivateKey() *ecdsa.PrivateKey {
	rawPrivateKey := os.Getenv("PRIVATE_KEY")

	// Parse the private key
	privateKey, err := crypto.HexToECDSA(rawPrivateKey)
	handleError(err)

	return privateKey
}

트랜잭션 서명자 생성

address := crypto.PubkeyToAddress(privateKey.PublicKey)

fmt.Printf("Deploying contract from address %s\n", address.Hex())

// Get nonce, gas price and chain ID from the Ethereum client
nonce, err := client.PendingNonceAt(ctx, address)
handleError(err)

gasPrice, err := client.SuggestGasPrice(ctx)
handleError(err)

fmt.Printf("Suggested gas price: %s\n", gasPrice)

chainID, err := client.NetworkID(ctx)
handleError(err)

fmt.Printf("Chain ID: %d\n", chainID)

// Create an signer with the private key, chain ID and nonce
signer, err := bind.NewKeyedTransactorWithChainID(privateKey, chainID)
handleError(err)

signer.GasPrice = gasPrice
signer.GasLimit = 3000000
signer.Nonce = big.NewInt(int64(nonce))

abigen으로 생성된 코드를 통해 스마트 컨트랙트 배포

// Deploy the contract with initial supply of 1,000,000 tokens
initialSupply := big.NewInt(0).Mul(big.NewInt(1000000), big.NewInt(0).Exp(big.NewInt(10), big.NewInt(18), nil))

_, tx, _, err := token.DeployToken(signer, client, initialSupply)
handleError(err)

fmt.Printf("Transaction hash: %s\n", tx.Hash().Hex())

// Wait for the deployment to be mined
contractAddress, err := bind.WaitDeployed(ctx, client, tx)
handleError(err)

fmt.Printf("Contract deployed! Contract address: %s\n", contractAddress.Hex())

4. 스마트 컨트랙트 배포

$ go run ./cmd/deploy/
Successfully connected to Ethereum client
Deploying contract from address 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
Suggested gas price: 2000000000
Chain ID: 31337
Transaction hash: 0x9b3b8b92cf9370e0a51c4f1f35726385839ef4aba748c42f22d7327f00cca5ad
Contract deployed! Contract address: 0x5FbDB2315678afecb367f032d93F642f64180aa3

5. 전체 코드

 

GitHub - piatoss3612/go-ethereum-practice

Contribute to piatoss3612/go-ethereum-practice development by creating an account on GitHub.

github.com

 

최근에 올라온 글
최근에 달린 댓글
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Total
Today
Yesterday
글 보관함