티스토리 뷰

0. 이전 게시글

 

[Solitidy+Go] geth로 스마트 컨트랙트 배포하기 - 6. 메타데이터를 사용한 standard json input 생성

0. 이전 게시글 [Solitidy+Go] geth로 스마트 컨트랙트 배포하기 - 5. 이벤트 구독 0. 이전 게시글 [Solitidy+Go] geth로 스마트 컨트랙트 배포하기 - 4. 배포된 스마트 컨트랙트와 상호작용 0. 이전 게시글 [Sol

piatoss3612.tistory.com


1. .env 파일 업데이트

PRIVATE_KEY=<YOUR_PRIVATE_KEY>
RPC_ENDPOINT=<YOUR_RPC_ENDPOINT>
RPC_WS_ENDPOINT=ws://localhost:8545
ETHERSCAN_API_KEY=<YOUR_ETHERSCAN_API_KEY>

Polygon Mumbai 테스트넷 사용

PRIVATE\_KEY : Polygon Mumbai 테스트 이더를 가지고 있는 지갑의 프라이빗 키
RPC_ENDPOINT : Alchemy에서 제공하는 Polygon Mumbai 테스트넷 RPC URL을 사용
ETHERSCAN_API_KEY : Polygonscan의 API 키


2. Polygon Mumbai 테스트넷에 컨트랙트 배포

$ go run ./cmd/deploy/

3. solc 버전 확인

$ solc --version
solc, the solidity compiler commandline interface
Version: 0.8.22+commit.4fc1097e.Linux.g++

4. 코드 작성

cmd/verify/main.go

package main

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"math/big"
	"net/http"
	"net/url"
	"os"
	"time"

	"github.com/ethereum/go-ethereum/accounts/abi"
	_ "github.com/joho/godotenv/autoload"
)

var etherscanURL = "https://api-testnet.polygonscan.com/api"

func main() {
	// read input file
	f, err := os.Open("verify/MyToken_input.json")
	handleErr(err)

	defer f.Close()

	sourceCodeBytes, err := io.ReadAll(f)
	handleErr(err)

	// generate abi-encoded constructor arguments
	initialSupply := big.NewInt(0).Mul(big.NewInt(1000000), big.NewInt(0).Exp(big.NewInt(10), big.NewInt(18), nil))

	uint256Ty, err := abi.NewType("uint256", "uint256", nil)
	handleErr(err)

	args := abi.Arguments{
		{
			Type: uint256Ty,
		},
	}

	encodedArgsBytes, err := args.Pack(initialSupply)
	handleErr(err)

	encodedArgsHex := fmt.Sprintf("%x", encodedArgsBytes)

	// set url encode data
	data := url.Values{
		"apiKey":                []string{os.Getenv("ETHERSCAN_API_KEY")},
		"module":                []string{"contract"},
		"action":                []string{"verifysourcecode"},
		"sourceCode":            []string{string(sourceCodeBytes)},
		"contractaddress":       []string{"0x7Fc3c9ae336291EC87296bb10D4B03f7d23357e4"},
		"codeformat":            []string{"solidity-standard-json-input"},
		"contractname":          []string{"contracts/MyToken.sol:MyToken"}, // contractfile.sol:contractname format
		"compilerversion":       []string{"v0.8.22+commit.4fc1097e"},
		"optimizationUsed":      []string{"1"},
		"constructorArguements": []string{encodedArgsHex}, // abi-encoded constructor arguments
	}

	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	// create request
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, etherscanURL, bytes.NewBufferString(data.Encode()))
	handleErr(err)

	// set request headers
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

	client := http.DefaultClient

	// send request
	resp, err := client.Do(req)
	handleErr(err)

	defer resp.Body.Close()

	// read response body
	body, err := io.ReadAll(resp.Body)
	handleErr(err)

	// success: 200 OK

	// print response body
	fmt.Println(string(body))
}

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

standard json input 불러오기

// read input file
f, err := os.Open("verify/MyToken_input.json")
handleErr(err)

defer f.Close()

sourceCodeBytes, err := io.ReadAll(f)
handleErr(err)

스마트 컨트랙트 생성자 인수 abi 인코딩

// generate abi-encoded constructor arguments
initialSupply := big.NewInt(0).Mul(big.NewInt(1000000), big.NewInt(0).Exp(big.NewInt(10), big.NewInt(18), nil))

uint256Ty, err := abi.NewType("uint256", "uint256", nil)
handleErr(err)

args := abi.Arguments{
	{
		Type: uint256Ty,
	},
}

encodedArgsBytes, err := args.Pack(initialSupply)
handleErr(err)

encodedArgsHex := fmt.Sprintf("%x", encodedArgsBytes)

 생성자 인수는 abi 인코딩이 필요하며, 16진수값으로 전달되어야 함

API 호출 인수 설정

// set url encode data
data := url.Values{
	"apiKey":                []string{os.Getenv("ETHERSCAN_API_KEY")},
	"module":                []string{"contract"},
	"action":                []string{"verifysourcecode"},
	"sourceCode":            []string{string(sourceCodeBytes)},
	"contractaddress":       []string{"0x7Fc3c9ae336291EC87296bb10D4B03f7d23357e4"},
	"codeformat":            []string{"solidity-standard-json-input"},
	"contractname":          []string{"contracts/MyToken.sol:MyToken"}, // contractfile.sol:contractname format
	"compilerversion":       []string{"v0.8.22+commit.4fc1097e"},
	"optimizationUsed":      []string{"1"},
	"constructorArguements": []string{encodedArgsHex}, // abi-encoded constructor arguments
}

요청 실행

// create request
req, err := http.NewRequestWithContext(ctx, http.MethodPost, etherscanURL, bytes.NewBufferString(data.Encode()))
handleErr(err)

// set request headers
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

client := http.DefaultClient

// send request
resp, err := client.Do(req)
handleErr(err)

defer resp.Body.Close()

// read response body
body, err := io.ReadAll(resp.Body)
handleErr(err)

// success: 200 OK

// print response body
fmt.Println(string(body))

5. 코드 실행

$ go run ./cmd/verify
{"status":"1","message":"OK","result":"vykmzujkyimxbzxn5cek1iyfmv8hj1hf2xdwxw4ephyk8maeyb"}

6. 전체 코드

 

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