티스토리 뷰
Solidity
[Solitidy+Go] geth로 스마트 컨트랙트 배포하기 - 7. standard json input을 사용해 배포한 컨트랙트 검증
piatoss 2023. 12. 16. 13:000. 이전 게시글
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. 전체 코드
'Solidity' 카테고리의 다른 글
OpenZeppelin Governor 이해하기 (1) | 2024.04.12 |
---|---|
[Solitidy+Go] geth로 스마트 컨트랙트 배포하기 - 6. 메타데이터를 사용한 standard json input 생성 (0) | 2023.12.15 |
[Solitidy+Go] geth로 스마트 컨트랙트 배포하기 - 5. 이벤트 구독 (0) | 2023.12.14 |
[Solitidy+Go] geth로 스마트 컨트랙트 배포하기 - 4. 배포된 스마트 컨트랙트와 상호작용 (0) | 2023.12.14 |
[Solitidy+Go] geth로 스마트 컨트랙트 배포하기 - 3. 생성된 Go 코드로 스마트 컨트랙트 배포 (0) | 2023.12.14 |