메인 콘텐츠로 건너뛰기

로컬, 멀티클라이언트 테스트넷에서 dApp을 개발하고 테스트하는 방법

클라이언트
노드
스마트 계약
결합성
합의 레이어
실행 레이어
테스트
중급
Tedi Mitiku
2023년 4월 11일
19 1분의 읽기 소요시간

소개

이 가이드는 구성 가능한 로컬 이더리움 테스트넷을 인스턴스화하고, 스마트 계약을 배포하며, 테스트넷을 사용하여 dApp에 대한 테스트를 실행하는 과정을 안내합니다. 이 가이드는 라이브 테스트넷이나 메인넷에 배포하기 전에 다양한 네트워크 구성에 대해 로컬에서 dApp을 개발하고 테스트하려는 dApp 개발자를 위해 설계되었습니다.

이 가이드에서는 다음을 수행합니다.

  • Kurtosis (opens in a new tab)를 사용하여 eth-network-package (opens in a new tab)로 로컬 이더리움 테스트넷을 인스턴스화합니다.
  • Hardhat dApp 개발 환경을 로컬 테스트넷에 연결하여 dApp을 컴파일, 배포 및 테스트합니다.
  • 노드 수 및 특정 EL/CL 클라이언트 페어링과 같은 파라미터를 포함하여 로컬 테스트넷을 구성하여 다양한 네트워크 구성에 대한 개발 및 테스트 워크플로를 활성화합니다.

Kurtosis란 무엇인가요?

Kurtosis (opens in a new tab)는 다중 컨테이너 테스트 환경 구성을 위해 설계된 구성 가능한 빌드 시스템입니다. 이를 통해 개발자는 블록체인 테스트넷과 같이 동적 설정 로직이 필요한 재현 가능한 환경을 만들 수 있습니다.

이 가이드에서 Kurtosis eth-network-package는 geth (opens in a new tab) 실행 레이어(EL) 클라이언트와 teku (opens in a new tab), lighthouse (opens in a new tab), lodestar (opens in a new tab) 합의 레이어(CL) 클라이언트를 지원하는 로컬 이더리움 테스트넷을 가동합니다. 이 패키지는 Hardhat Network, Ganache, Anvil과 같은 프레임워크의 네트워크에 대한 구성 가능하고 조합 가능한 대안 역할을 합니다. Kurtosis는 개발자가 사용하는 테스트넷에 대한 더 큰 제어와 유연성을 제공하며, 이것이 이더리움 재단이 머지를 테스트하기 위해 Kurtosis를 사용한 (opens in a new tab) 주된 이유이며 네트워크 업그레이드를 테스트하기 위해 계속 사용하고 있습니다.

Kurtosis 설정

진행하기 전에 다음을 확인하십시오.

로컬 이더리움 테스트넷 인스턴스화

로컬 이더리움 테스트넷을 가동하려면 다음을 실행하세요.

1kurtosis --enclave local-eth-testnet run github.com/kurtosis-tech/eth-network-package

참고: 이 명령어는 '--enclave' 플래그를 사용하여 네트워크 이름을 "local-eth-testnet"으로 지정합니다.

Kurtosis는 지침을 해석, 검증 및 실행하는 동안 내부적으로 수행하는 단계를 출력합니다. 마지막으로 다음과 유사한 출력이 표시되어야 합니다.

1INFO[2023-04-04T18:09:44-04:00] ======================================================
2INFO[2023-04-04T18:09:44-04:00] || Created enclave: local-eth-testnet ||
3INFO[2023-04-04T18:09:44-04:00] ======================================================
4Name: local-eth-testnet
5UUID: 39372d756ae8
6Status: RUNNING
7Creation Time: Tue, 04 Apr 2023 18:09:03 EDT
8
9========================================= Files Artifacts =========================================
10UUID Name
11d4085a064230 cl-genesis-data
121c62cb792e4c el-genesis-data
13bd60489b73a7 genesis-generation-config-cl
14b2e593fe5228 genesis-generation-config-el
15d552a54acf78 geth-prefunded-keys
165f7e661eb838 prysm-password
17054e7338bb59 validator-keystore-0
18
19========================================== User Services ==========================================
20UUID Name Ports Status
21e20f129ee0c5 cl-client-0-beacon http: 4000/tcp -> <http://127.0.0.1:54261> RUNNING
22 metrics: 5054/tcp -> <http://127.0.0.1:54262>
23 tcp-discovery: 9000/tcp -> 127.0.0.1:54263
24 udp-discovery: 9000/udp -> 127.0.0.1:60470
25a8b6c926cdb4 cl-client-0-validator http: 5042/tcp -> 127.0.0.1:54267 RUNNING
26 metrics: 5064/tcp -> <http://127.0.0.1:54268>
27d7b802f623e8 el-client-0 engine-rpc: 8551/tcp -> 127.0.0.1:54253 RUNNING
28 rpc: 8545/tcp -> 127.0.0.1:54251
29 tcp-discovery: 30303/tcp -> 127.0.0.1:54254
30 udp-discovery: 30303/udp -> 127.0.0.1:53834
31 ws: 8546/tcp -> 127.0.0.1:54252
32514a829c0a84 prelaunch-data-generator-1680646157905431468 <none> STOPPED
3362bd62d0aa7a prelaunch-data-generator-1680646157915424301 <none> STOPPED
3405e9619e0e90 prelaunch-data-generator-1680646157922872635 <none> STOPPED
모두 보기

축하합니다! Docker를 통해 Kurtosis를 사용하여 CL(lighthouse) 및 EL 클라이언트(geth)가 있는 로컬 이더리움 테스트넷을 인스턴스화했습니다.

검토

이 섹션에서는 Kurtosis Enclave (opens in a new tab) 내에서 로컬 이더리움 테스트넷을 시작하기 위해 Kurtosis가 GitHub에 원격으로 호스팅된 eth-network-package (opens in a new tab)를 사용하도록 지시하는 명령을 실행했습니다. 엔클레이브 내부에는 "파일 아티팩트"와 "사용자 서비스"가 모두 있습니다.

엔클레이브의 파일 아티팩트 (opens in a new tab)에는 EL 및 CL 클라이언트를 부트스트랩하기 위해 생성 및 활용된 모든 데이터가 포함됩니다. 데이터는 이 Docker 이미지 (opens in a new tab)에서 빌드된 prelaunch-data-generator 서비스를 사용하여 생성되었습니다.

사용자 서비스는 엔클레이브에서 작동하는 모든 컨테이너화된 서비스를 표시합니다. EL 클라이언트와 CL 클라이언트를 모두 갖춘 단일 노드가 생성된 것을 알 수 있습니다.

dApp 개발 환경을 로컬 이더리움 테스트넷에 연결

dApp 개발 환경 설정

이제 실행 중인 로컬 테스트넷이 있으므로 dApp 개발 환경을 연결하여 로컬 테스트넷을 사용할 수 있습니다. 이 가이드에서는 Hardhat 프레임워크를 사용하여 블랙잭 dApp을 로컬 테스트넷에 배포합니다.

dApp 개발 환경을 설정하려면 샘플 dApp이 포함된 저장소를 클론하고 종속성을 설치한 후 다음을 실행하세요.

1git clone https://github.com/kurtosis-tech/awesome-kurtosis.git && cd awesome-kurtosis/smart-contract-example && yarn

여기서 사용되는 smart-contract-example (opens in a new tab) 폴더에는 Hardhat (opens in a new tab) 프레임워크를 사용하는 dApp 개발자를 위한 일반적인 설정이 포함되어 있습니다.

로컬 테스트넷을 사용하도록 Hardhat 구성

dApp 개발 환경이 설정되었으므로 이제 Kurtosis를 사용하여 생성된 로컬 이더리움 테스트넷을 사용하도록 Hardhat을 연결합니다. 이를 위해 hardhat.config.ts 구성 파일의 localnet 구조체에서 <$YOUR_PORT>el-client-<num> 서비스의 rpc uri 출력 포트로 바꿉니다. 이 샘플의 경우 포트는 64248입니다. 사용자의 포트는 다를 것입니다.

hardhat.config.ts의 예시:

1localnet: {
2url: 'http://127.0.0.1:<$YOUR_PORT>',// TODO: $YOUR_PORT를 ETH 네트워크 KURTOSIS 패키지에서 생성한 노드 URI의 포트로 교체하세요
3
4// 이들은 eth-network-package에 의해 생성된, 사전에 자금이 충전된 테스트 계정과 연관된 개인 키입니다
5// <https://github.com/kurtosis-tech/eth-network-package/blob/main/src/prelaunch_data_generator/genesis_constants/genesis_constants.star>
6accounts: [
7 "ef5177cd0b6b21c87db5a0bf35d4084a8a57a9d6a064f86d51ac85f2b873a4e2",
8 "48fcc39ae27a0e8bf0274021ae6ebd8fe4a0e12623d61464c498900b28feb567",
9 "7988b3a148716ff800414935b305436493e1f25237a2a03e5eebc343735e2f31",
10 "b3c409b6b0b3aa5e65ab2dc1930534608239a478106acf6f3d9178e9f9b00b35",
11 "df9bb6de5d3dc59595bcaa676397d837ff49441d211878c024eabda2cd067c9f",
12 "7da08f856b5956d40a72968f93396f6acff17193f013e8053f6fbb6c08c194d6",
13 ],
14},
모두 보기

파일을 저장하면 Hardhat dApp 개발 환경이 로컬 이더리움 테스트넷에 연결됩니다! 다음을 실행하여 테스트넷이 작동하는지 확인할 수 있습니다.

1npx hardhat balances --network localnet

출력은 다음과 같아야 합니다.

10x878705ba3f8Bc32FCf7F4CAa1A35E72AF65CF766 has balance 10000000000000000000000000
20x4E9A3d9D1cd2A2b2371b8b3F489aE72259886f1A has balance 10000000000000000000000000
30xdF8466f277964Bb7a0FFD819403302C34DCD530A has balance 10000000000000000000000000
40x5c613e39Fc0Ad91AfDA24587e6f52192d75FBA50 has balance 10000000000000000000000000
50x375ae6107f8cC4cF34842B71C6F746a362Ad8EAc has balance 10000000000000000000000000
60x1F6298457C5d76270325B724Da5d1953923a6B88 has balance 10000000000000000000000000

이는 Hardhat이 로컬 테스트넷을 사용하고 있으며 eth-network-package에 의해 생성된 사전에 자금이 충전된 계정을 감지했음을 확인합니다.

로컬에서 dApp 배포 및 테스트

dApp 개발 환경이 로컬 이더리움 테스트넷에 완전히 연결되었으므로 이제 로컬 테스트넷을 사용하여 dApp에 대한 개발 및 테스트 워크플로를 실행할 수 있습니다.

ChipToken.sol 스마트 계약을 로컬 프로토타이핑 및 개발을 위해 컴파일하고 배포하려면 다음을 실행하세요.

1npx hardhat compile
2npx hardhat run scripts/deploy.ts --network localnet

출력은 다음과 같아야 합니다.

1ChipToken이 0xAb2A01BC351770D09611Ac80f1DE076D56E0487d에 배포되었습니다

이제 로컬 dApp에 대해 simple.js 테스트를 실행하여 Blackjack dApp의 각 플레이어에게 1000개가 민팅되었는지 확인하세요.

출력은 다음과 같아야 합니다.

1npx hardhat test --network localnet

출력은 다음과 같아야 합니다.

1ChipToken
2 mint
3 ✔ should mint 1000 chips for PLAYER ONE
4
5 1 passing (654ms)

검토

이 시점에서 dApp 개발 환경을 설정하고, Kurtosis가 생성한 로컬 이더리움 네트워크에 연결했으며, dApp에 대해 컴파일, 배포 및 간단한 테스트를 실행했습니다.

이제 다양한 네트워크 구성에서 dApp을 테스트하기 위해 기본 네트워크를 구성하는 방법을 살펴보겠습니다.

로컬 이더리움 테스트넷 구성

클라이언트 구성 및 노드 수 변경

로컬 이더리움 테스트넷은 개발 또는 테스트하려는 시나리오 및 특정 네트워크 구성에 따라 다양한 EL 및 CL 클라이언트 쌍과 다양한 수의 노드를 사용하도록 구성할 수 있습니다. 즉, 일단 설정되면 맞춤형 로컬 테스트넷을 가동하고 이를 사용하여 동일한 워크플로(배포, 테스트 등)를 실행할 수 있습니다. 다양한 네트워크 구성 하에서 모든 것이 예상대로 작동하는지 확인합니다. 수정할 수 있는 다른 파라미터에 대해 자세히 알아보려면 이 링크를 방문하세요.

시도해 보세요! JSON 파일을 통해 eth-network-package에 다양한 구성 옵션을 전달할 수 있습니다. 이 네트워크 파라미터 JSON 파일은 Kurtosis가 로컬 이더리움 네트워크를 설정하는 데 사용할 특정 구성을 제공합니다.

기본 구성 파일을 사용하여 다른 EL/CL 쌍을 가진 두 개의 노드를 시작하도록 편집하세요.

  • 노드 1: geth/lighthouse
  • 노드 2: geth/lodestar
  • 노드 3: geth/teku

이 구성은 dApp 테스트를 위해 이더리움 노드 구현의 이기종 네트워크를 생성합니다. 이제 구성 파일은 다음과 같이 표시됩니다.

1{
2 "participants":
3 [
4 {
5 "el_client_type": "geth",
6 "el_client_image": "",
7 "el_client_log_level": "",
8 "cl_client_type": "lighthouse",
9 "cl_client_image": "",
10 "cl_client_log_level": "",
11 "beacon_extra_params": [],
12 "el_extra_params": [],
13 "validator_extra_params": [],
14 "builder_network_params": null,
15 },
16 {
17 "el_client_type": "geth",
18 "el_client_image": "",
19 "el_client_log_level": "",
20 "cl_client_type": "lodestar",
21 "cl_client_image": "",
22 "cl_client_log_level": "",
23 "beacon_extra_params": [],
24 "el_extra_params": [],
25 "validator_extra_params": [],
26 "builder_network_params": null,
27 },
28 {
29 "el_client_type": "geth",
30 "el_client_image": "",
31 "el_client_log_level": "",
32 "cl_client_type": "teku",
33 "cl_client_image": "",
34 "cl_client_log_level": "",
35 "beacon_extra_params": [],
36 "el_extra_params": [],
37 "validator_extra_params": [],
38 "builder_network_params": null,
39 },
40 ],
41 "network_params":
42 {
43 "preregistered_validator_keys_mnemonic": "giant issue aisle success illegal bike spike question tent bar rely arctic volcano long crawl hungry vocal artwork sniff fantasy very lucky have athlete",
44 "num_validator_keys_per_node": 64,
45 "network_id": "3151908",
46 "deposit_contract_address": "0x4242424242424242424242424242424242424242",
47 "seconds_per_slot": 12,
48 "genesis_delay": 120,
49 "capella_fork_epoch": 5,
50 },
51}
모두 보기

participants 구조체는 네트워크의 노드에 매핑되므로 3개의 participants 구조체는 Kurtosis에게 네트워크에 3개의 노드를 가동하도록 지시합니다. 각 participants 구조체를 통해 특정 노드에 사용되는 EL 및 CL 쌍을 지정할 수 있습니다.

network_params 구조체는 각 노드의 제네시스 파일을 생성하는 데 사용되는 네트워크 설정과 네트워크의 슬롯당 시간(초)과 같은 기타 설정을 구성합니다.

편집한 파라미터 파일을 원하는 디렉터리에 저장하고(아래 예에서는 바탕화면에 저장됨) 다음을 실행하여 Kurtosis 패키지를 실행하는 데 사용합니다.

1kurtosis clean -a && kurtosis run --enclave local-eth-testnet github.com/kurtosis-tech/eth-network-package "$(cat ~/eth-network-params.json)"

참고: kurtosis clean -a 명령어는 Kurtosis에게 새 테스트넷을 시작하기 전에 이전 테스트넷과 그 내용을 파괴하도록 지시하는 데 사용됩니다.

다시 한 번, Kurtosis가 잠시 작동하고 진행 중인 개별 단계를 출력합니다. 결과적으로 출력은 다음과 같아야 합니다.

1Starlark code successfully run. No output was returned.
2INFO[2023-04-07T11:43:16-04:00] ==========================================================
3INFO[2023-04-07T11:43:16-04:00] || Created enclave: local-eth-testnet ||
4INFO[2023-04-07T11:43:16-04:00] ==========================================================
5Name: local-eth-testnet
6UUID: bef8c192008e
7Status: RUNNING
8Creation Time: Fri, 07 Apr 2023 11:41:58 EDT
9
10========================================= Files Artifacts =========================================
11UUID Name
12cc495a8e364a cl-genesis-data
137033fcdb5471 el-genesis-data
14a3aef43fc738 genesis-generation-config-cl
158e968005fc9d genesis-generation-config-el
163182cca9d3cd geth-prefunded-keys
178421166e234f prysm-password
18d9e6e8d44d99 validator-keystore-0
1923f5ba517394 validator-keystore-1
204d28dea40b5c validator-keystore-2
21
22========================================== User Services ==========================================
23UUID Name Ports Status
24485e6fde55ae cl-client-0-beacon http: 4000/tcp -> http://127.0.0.1:65010 RUNNING
25 metrics: 5054/tcp -> http://127.0.0.1:65011
26 tcp-discovery: 9000/tcp -> 127.0.0.1:65012
27 udp-discovery: 9000/udp -> 127.0.0.1:54455
2873739bd158b2 cl-client-0-validator http: 5042/tcp -> 127.0.0.1:65016 RUNNING
29 metrics: 5064/tcp -> http://127.0.0.1:65017
301b0a233cd011 cl-client-1-beacon http: 4000/tcp -> 127.0.0.1:65021 RUNNING
31 metrics: 8008/tcp -> 127.0.0.1:65023
32 tcp-discovery: 9000/tcp -> 127.0.0.1:65024
33 udp-discovery: 9000/udp -> 127.0.0.1:56031
34 validator-metrics: 5064/tcp -> 127.0.0.1:65022
35949b8220cd53 cl-client-1-validator http: 4000/tcp -> 127.0.0.1:65028 RUNNING
36 metrics: 8008/tcp -> 127.0.0.1:65030
37 tcp-discovery: 9000/tcp -> 127.0.0.1:65031
38 udp-discovery: 9000/udp -> 127.0.0.1:60784
39 validator-metrics: 5064/tcp -> 127.0.0.1:65029
40c34417bea5fa cl-client-2 http: 4000/tcp -> 127.0.0.1:65037 RUNNING
41 metrics: 8008/tcp -> 127.0.0.1:65035
42 tcp-discovery: 9000/tcp -> 127.0.0.1:65036
43 udp-discovery: 9000/udp -> 127.0.0.1:63581
44e19738e6329d el-client-0 engine-rpc: 8551/tcp -> 127.0.0.1:64986 RUNNING
45 rpc: 8545/tcp -> 127.0.0.1:64988
46 tcp-discovery: 30303/tcp -> 127.0.0.1:64987
47 udp-discovery: 30303/udp -> 127.0.0.1:55706
48 ws: 8546/tcp -> 127.0.0.1:64989
49e904687449d9 el-client-1 engine-rpc: 8551/tcp -> 127.0.0.1:64993 RUNNING
50 rpc: 8545/tcp -> 127.0.0.1:64995
51 tcp-discovery: 30303/tcp -> 127.0.0.1:64994
52 udp-discovery: 30303/udp -> 127.0.0.1:58096
53 ws: 8546/tcp -> 127.0.0.1:64996
54ad6f401126fa el-client-2 engine-rpc: 8551/tcp -> 127.0.0.1:65003 RUNNING
55 rpc: 8545/tcp -> 127.0.0.1:65001
56 tcp-discovery: 30303/tcp -> 127.0.0.1:65000
57 udp-discovery: 30303/udp -> 127.0.0.1:57269
58 ws: 8546/tcp -> 127.0.0.1:65002
5912d04a9dbb69 prelaunch-data-generator-1680882122181135513 <none> STOPPED
605b45f9c0504b prelaunch-data-generator-1680882122192182847 <none> STOPPED
613d4aaa75e218 prelaunch-data-generator-1680882122201668972 <none> STOPPED
모두 보기

축하합니다! 로컬 테스트넷을 1개가 아닌 3개의 노드를 갖도록 성공적으로 구성했습니다. dApp에 대해 이전과 동일한 워크플로(배포 및 테스트)를 실행하려면 hardhat.config.ts 구성 파일의 localnet 구조체에서 <$YOUR_PORT>를 새 3노드 로컬 테스트넷의 el-client-<num> 서비스에서 출력된 rpc uri의 포트로 바꾸어 이전과 동일한 작업을 수행하세요.

결론

이것으로 끝입니다! 이 짧은 가이드를 요약하자면 다음과 같습니다.

  • Kurtosis를 사용하여 Docker를 통해 로컬 이더리움 테스트넷을 생성했습니다.
  • 로컬 dApp 개발 환경을 로컬 이더리움 네트워크에 연결했습니다.
  • 로컬 이더리움 네트워크에서 dApp을 배포하고 간단한 테스트를 실행했습니다.
  • 기본 이더리움 네트워크를 3개의 노드를 갖도록 구성했습니다.

잘된 점, 개선할 점 또는 질문에 대한 답변에 대해 여러분의 의견을 듣고 싶습니다. 주저하지 마시고 GitHub (opens in a new tab)를 통해 연락하시거나 이메일을 보내주세요 (opens email client)!

기타 예제 및 가이드

빠른 시작 (opens in a new tab)(Postgres 데이터베이스와 API를 구축)과 awesome-kurtosis 저장소 (opens in a new tab)의 다른 예제를 확인해 보시기 바랍니다. 여기에는 다음 패키지를 포함한 훌륭한 예제가 있습니다.

  • 동일한 로컬 이더리움 테스트넷을 가동하지만 트랜잭션 스패머(트랜잭션 시뮬레이션용), 포크 모니터, 연결된 Grafana 및 Prometheus 인스턴스와 같은 추가 서비스가 연결되어 있습니다.
  • 동일한 로컬 이더리움 네트워크에 대한 하위 네트워킹 테스트 (opens in a new tab) 수행

페이지 마지막 업데이트됨: 2025년 9월 23일

이 튜토리얼이 도움이 되셨나요?