티스토리 뷰

0. 이전 게시글

 

[Solitidy+Go] geth로 스마트 컨트랙트 배포하기 - 4. 배포된 스마트 컨트랙트와 상호작용

0. 이전 게시글 [Solitidy+Go] geth로 스마트 컨트랙트 배포하기 - 3. 생성된 Go 코드로 스마트 컨트랙트 배포 1. 로컬 테스트넷 실행 $ anvil 2. 최상위 경로에 .env 파일 생성 PRIVATE_KEY= RPC_ENDPOINT=http://localho

piatoss3612.tistory.com


1. .env 파일 업데이트

PRIVATE_KEY=<YOUR_PRIVATE_KEY>
RPC_ENDPOINT=http://localhost:8545
RPC_WS_ENDPOINT=ws://localhost:8545

 

 이벤트 구독을 위해서는 웹소켓 주소가 필요


2. 코드 작성

cmd/subscribe/main.go

package main

import (
	"context"
	"fmt"
	token "go-ethereum-example/gen"
	"os"

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

	"github.com/ethereum/go-ethereum/accounts/abi/bind"
	"github.com/ethereum/go-ethereum/common"
	"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_WS_ENDPOINT"))
	handleError(err)

	defer client.Close()

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

	// Change these addresses to match your contract!
	contractAddress := common.HexToAddress("0x5FbDB2315678afecb367f032d93F642f64180aa3")

	// Create an instance of the contract, specifying its address
	tokenInstance, err := token.NewToken(contractAddress, client)
	handleError(err)

	transferChan := make(chan *token.TokenTransfer)

	// Subscribe to Transfer events
	sub, err := tokenInstance.WatchTransfer(&bind.WatchOpts{}, transferChan, nil, nil)
	handleError(err)

	defer sub.Unsubscribe()

	fmt.Println("Successfully subscribed to Transfer events")

	for {
		select {
		case err := <-sub.Err():
			handleError(err)
		case transfer := <-transferChan:
			fmt.Printf("Transfer event received: from=%s to=%s value=%d\n", transfer.From.Hex(), transfer.To.Hex(), transfer.Value)
		}
	}
}

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

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

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

defer client.Close()

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

 웹소켓을 통해 클라이언트 연결

배포된 스마트 컨트랙트의 인스턴스 생성

// Change these addresses to match your contract!
contractAddress := common.HexToAddress("0x5FbDB2315678afecb367f032d93F642f64180aa3")

// Create an instance of the contract, specifying its address
tokenInstance, err := token.NewToken(contractAddress, client)
handleError(err)

이벤트 구독

transferChan := make(chan *token.TokenTransfer)

// Subscribe to Transfer events
sub, err := tokenInstance.WatchTransfer(&bind.WatchOpts{}, transferChan, nil, nil)
handleError(err)

defer sub.Unsubscribe()

fmt.Println("Successfully subscribed to Transfer events")

WatchTransfer 메서드의 인수로 구독 옵션, 이벤트를 받을 채널, 그리고 세 번째부터는 이벤트에서 indexed로 지정된 값들을 필터링하기 위한 값들을 지정할 수 있다. 여기서는 굳이 필요하지 않으므로 nil을 넘겨준다.

이벤트 받기

for {
	select {
	case err := <-sub.Err():
		handleError(err)
	case transfer := <-transferChan:
		fmt.Printf("Transfer event received: from=%s to=%s value=%d\n", transfer.From.Hex(), transfer.To.Hex(), transfer.Value)
	}
}

3. 코드 실행

이벤트 구독

$ go run ./cmd/subscribe/
Successfully connected to Ethereum client
Successfully subscribed to Transfer events

이벤트 발생

$ go run ./cmd/interact/

발생한 이벤트 출력

Transfer event received: from=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 to=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 value=1000000

4. 전체 코드

 

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
글 보관함