Hyperledger Besu 빨리 따라하기 (Private Networks)

SuJeongShim 631 views 53 slides Jun 22, 2024
Slide 1
Slide 1 of 53
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32
Slide 33
33
Slide 34
34
Slide 35
35
Slide 36
36
Slide 37
37
Slide 38
38
Slide 39
39
Slide 40
40
Slide 41
41
Slide 42
42
Slide 43
43
Slide 44
44
Slide 45
45
Slide 46
46
Slide 47
47
Slide 48
48
Slide 49
49
Slide 50
50
Slide 51
51
Slide 52
52
Slide 53
53

About This Presentation

Hyperledger Besu의 Private Networks에서 진행하는 실습입니다. 주요 내용은 공식 문서인https://besu.hyperledger.org/private-networks/tutorials 의 내용에서 발췌하였으며, Privacy Enabled Network와 Permissioned Network까지 다루고 있습니다.
This is a training ses...


Slide Content

Hyperledger Besu 빨리 따라하기 Privat Networks

Hyperledger Besu Hyperledger BESU = Hyperledger Ethereum Public & Permissioned Chain source : https:// besu.hyperledger.org /private-networks

Hello World (Quorum Developer Quickstart ) Docker 를 활용한 Private Network 구성 - 필요 도구 : Docker Compose, Node.js, Hardhat, MetaMask - 실습 목적 : Private Network 구동 (5 초 마다 블록 자동 생성 ) 하여 이더리움 스마트 컨트랙트 배포 및 토큰 전송 실습 - 실습 환경 : Four Besu IBFT 2.0 validator nodes and a non-validator node are created to simulate a base network.

프로젝트 생성 및 기동 위 웹사이트의 가이드에 따라서 npx quorum-dev- quickstart 로 프로젝트 생성 - 프로젝트 생성 단계에서 ELK Stack 은 N 으로 설정 ( 설정시 docker image pull 및 기동에 상당 시간 소요 ) - 프로젝트 디렉토리 이름은 자유롭게 설정 - 생성된 프로젝트 디렉토리에서 ./ run.sh 로 기동 - 로그는 프로젝트 디렉토리에서 docker-compose logs -f docker- compose.yml 를 통해 확인 가능 - 초기에 노드간 연결이 완성되지 못해 로그에 에러 메시지가 많이 보이나 , 10 분 정도 기다리면 자동 정상화됨 - block explorer, Grafana 등 서비스 모니터링을 위한 주소 확인은 ./ list.sh - 필요 메모리 : 8GB https:// besu.hyperledger.org /private-networks/tutorials/ quickstart

hre_1559_public_tx.js - 스마트 컨트랙트 배포 - increment 함수 호출 , 특정 변수 값 +1 - decrement 함수 호출 , 특정 변수 값 -1 누가 호출하던 상관 없이 전역 count 의 값이 변경되게 예제가 구현되어 있음 async function main(){ const provider = new ethers.JsonRpcProvider (host); const wallet = new ethers.Wallet ( accountPrivateKey , provider); createContract (provider, wallet, contractAbi , contractBytecode ) .then(async function(contract){ console.log (contract); contractAddress = await contract.getAddress (); console.log ("Use the smart contracts 'get' function to read the contract's initialized value .. " ) await getValueAtAddress (provider, contractAbi , contractAddress ); console.log ("Use the smart contracts 'increment' function to update that value .. " ); await incrementValueAtAddress (provider, wallet, contractAbi , contractAddress ); console.log ("Verify the updated value that was set .. " ) await getValueAtAddress (provider, contractAbi , contractAddress ); console.log ("Use the smart contracts 'decrement' function to update that value .. " ); await decrementValueAtAddress (provider, wallet, contractAbi , contractAddress ); console.log ("Verify the updated value that was set .. " ) await getValueAtAddress (provider, contractAbi , contractAddress ); }) .catch( console.error ); } source : https:// besu.hyperledger.org /private-networks

hre_1559_public_tx.js node scripts/public/ hre_1559_public_tx.js BaseContract { target: ' 0xBca0fDc68d9b21b5bfB16D784389807017B2bbbc ', interface: Interface { fragments: [ [ FunctionFragment ], [ FunctionFragment ], [ FunctionFragment ] ], deploy: ConstructorFragment { type: 'constructor', inputs: [], payable: false, gas: null }, fallback: null, receive: false }, runner: Wallet { provider: JsonRpcProvider {}, address: ' 0xC9C913c8c3C1Cd416d80A0abF475db2062F161f6 ' }, filters: {}, fallback: null, [Symbol(_ ethersInternal_contract )]: {} } Use the smart contracts 'get' function to read the contract's initialized value .. Obtained value at deployed contract is: 0 Use the smart contracts 'increment' function to update that value .. Verify the updated value that was set .. Obtained value at deployed contract is: 1 Use the smart contracts 'decrement' function to update that value .. Verify the updated value that was set .. Obtained value at deployed contract is: 0 source : https:// besu.hyperledger.org /private-networks

node scripts/public/ hre_1559_public_tx.js BaseContract { target: ' 0xBca0fDc68d9b21b5bfB16D784389807017B2bbbc ', interface: Interface { fragments: [ [ FunctionFragment ], [ FunctionFragment ], [ FunctionFragment ] ], deploy: ConstructorFragment { type: 'constructor', inputs: [], payable: false, gas: null }, fallback: null, receive: false }, runner: Wallet { provider: JsonRpcProvider {}, address: ' 0xC9C913c8c3C1Cd416d80A0abF475db2062F161f6 ' }, filters: {}, fallback: null, [Symbol(_ ethersInternal_contract )]: {} } Use the smart contracts 'get' function to read the contract's initialized value .. Obtained value at deployed contract is: 0 Use the smart contracts 'increment' function to update that value .. Verify the updated value that was set .. Obtained value at deployed contract is: 1 Use the smart contracts 'decrement' function to update that value .. Verify the updated value that was set .. Obtained value at deployed contract is: 0 hre_1559_public_tx.js source : https:// besu.hyperledger.org /private-networks

hre_public_tx.js - 컨트랙트 배포 ( 배포와 동시에 배포를 요청하는 지갑주소에 47 을 설정 - 위 값을 123 으로 업데이트 async function main(){ const provider = new ethers.JsonRpcProvider (host); const wallet = new ethers.Wallet ( accountPrivateKey , provider); createContract (provider, wallet, contractAbi , contractBytecode , 47 ) .then(async function(contract){ contractAddress = await contract.getAddress (); console.log ("Contract deployed at address: " + contractAddress ); console.log ("Use the smart contracts 'get' function to read the contract's constructor initialized value .. " ) await getValueAtAddress (provider, contractAbi , contractAddress ); console.log ("Use the smart contracts 'set' function to update that value to 123 .. " ); await setValueAtAddress (provider, wallet, contractAbi , contractAddress , 123 ); console.log ("Verify the updated value that was set .. " ) await getValueAtAddress (provider, contractAbi , contractAddress ); // await getAllPastEvents (host, contractAbi , tx.contractAddress ); }) source : https:// besu.hyperledger.org /private-networks

hre_eth_tx.js - A 계정의 잔고 (90000) 에서 B 계정 ( 잔고 0) 으로 16 wei 이체 Account A has balance of: 90000000000000000000000 Account B has balance of: create and sign the txn tx transactionHash : 0x2338ce8a2249de93b59dfa0e6e29eb7e5050c74880cfc20e8b6aaa0ebbc995b1 Account A has balance of: 89999999999999999999984 Account B has balance of: 16 source : https:// besu.hyperledger.org /private-networks

Create a transaction using MetaMask Add a Test Network source : https:// besu.hyperledger.org /private-networks

Create a transaction using MetaMask Add account ( 신규 계정 생성 - 이더를 수신 받기 위한 테스트용 계정 ) 계정 생성 결과 source : https:// besu.hyperledger.org /private-networks

Create a transaction using MetaMask Add account ( 네트워크 상 등록된 계정 Import - 이더 송신용 계정 ) Private Key Copy & Paste 계정 Import 결과 source : https:// besu.hyperledger.org /private-networks

Create a transaction using MetaMask In the Block Explorer, search for the new test account by selecting the 🔍 and pasting the test account address into the search box. The new test account displays with a zero balance. source : https:// besu.hyperledger.org /private-networks

Create a transaction using MetaMask 9 페이지에서 Import 한 계정에서 8 페이지에서 신규 생성한 계정으로 1 이더 전송 source : https:// besu.hyperledger.org /private-networks

Create a transaction using MetaMask 결과 확인 source : https:// besu.hyperledger.org /private-networks

Smart contract and dapp usage # install dependencies npm i # compile the contract npm run compile npm run test # deploy the contract to the quickstart network npm run deploy- quorumtoken import "@ openzeppelin /contracts/token/ ERC20 / ERC20.sol "; contract QuorumToken is ERC20 { constructor( uint256 initialSupply ) ERC20 (" QuorumToken ", "QT") { _mint( msg.sender , initialSupply ); } } Contract deploy at: 0x9a3DBCa554e9f6b9257aAa24010DA8377C57c17e

Smart contract and dapp usage

Create a QBFT network block header validator selection method 를 적용하여 validator 노드를 관리 ( 추가 / 삭제 ) 하는 예제 (  스마트 컨트랙트를 별도로 배포하여 관리하는 방법도 있음 (contract validator selection method)

Create a private network using QBFT 디렉토리 생성 [ root@master qbft -network]# pwd /root/ qbft -network [ root@master qbft -network]# tree . ├── Node-1 │   └── data ├── Node-2 │   └── data ├── Node-3 │   └── data └── Node-4 └── data 8 directories, 0 files source : https:// besu.hyperledger.org /private-networks

Create a private network using QBFT configuration file 생성 [ root@master qbft -network]# pwd /root/ qbft -network [ root@master qbft -network]# ll total 4 drwxr - xr -x. 3 root root 18 Jun 20 02:46 Node-1 drwxr - xr -x. 3 root root 18 Jun 20 02:46 Node-2 drwxr - xr -x. 3 root root 18 Jun 20 02:47 Node-3 drwxr - xr -x. 3 root root 18 Jun 20 02:47 Node-4 - rw -r--r--. 1 root root 1513 Jun 20 02:54 qbftConfigFile.json { "genesis": { "config": { " chainId ": 1337 , " berlinBlock ": 0, " qbft ": { " blockperiodseconds ": 2, " epochlength ": 30000, " requesttimeoutseconds ": 4 } }, "nonce": " 0x0 ", "timestamp": " 0x58ee40ba ", " gasLimit ": " 0x47b760 ", "difficulty": " 0x1 ", " mixHash ": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", " coinbase ": " 0x0000000000000000000000000000000000000000 ", " alloc ": { " fe3b557e8fb62b89f4916b721be55ceb828dbd73 ": { " privateKey ": "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", "balance": " 0xad78ebc5ac6200000 " }, " 627306090abaB3A6e1400e9345bC60c78a8BEf57 ": { " privateKey ": "c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", "balance": "90000000000000000000000" }, " f17f52151EbEF6C7334FAD080c5704D77216b732 ": { " privateKey ": "ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f", "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", "balance": "90000000000000000000000" } } }, "blockchain": { "nodes": { "generate": true, "count": 4 } } } genesis property ( 참고로 , extraData 섹션은 Besu 에서 자동 생성 ) blockchain property : 생성할 key pair 수 source : https:// besu.hyperledger.org /private-networks

Create a private network using QBFT 노드 키 ( 공개키 / 비밀키 ) 및 genesis.json 생성 # ../ besu /bin/ besu operator generate-blockchain-config --config-file= qbftConfigFile.json --to= networkFiles --private-key-file-name=key 03:15:38.052-04:00 | main | INFO | GenerateBlockchainConfig | Generating 4 nodes keys. 03:15:38.062-04:00 | main | INFO | GenerateBlockchainConfig | Generating keypair for node 0. 03:15:38.377-04:00 | main | INFO | GenerateBlockchainConfig | Generating keypair for node 1. 03:15:38.409-04:00 | main | INFO | GenerateBlockchainConfig | Generating keypair for node 2. 03:15:38.431-04:00 | main | INFO | GenerateBlockchainConfig | Generating keypair for node 3. 03:15:38.461-04:00 | main | INFO | GenerateBlockchainConfig | Generating QBFT extra data. 03:15:38.500-04:00 | main | INFO | GenerateBlockchainConfig | Writing genesis file. [ root@master qbft -network]# tree . ├── networkFiles │   ├── genesis.json │   └── keys │   ├── 0x258ed3d4c40fa5cfecb67597c6dba6248804014c │   │   ├── key │   │   └── key.pub │   ├── 0x4914ca1ac7afb825cc1a416817597144bf878180 │   │   ├── key │   │   └── key.pub │   ├── 0x898c92dc5fff31af05de0e1a465c0ff812120d15 │   │   ├── key │   │   └── key.pub │   └── 0x984769eacf61592cf42695a7147c9116c8ed738a │   ├── key │   └── key.pub ├── Node-1 │   └── data ├── Node-2 │   └── data ├── Node-3 │   └── data ├── Node-4 │   └── data └── qbftConfigFile.json 생성 결과 source : https:// besu.hyperledger.org /private-networks

Create a private network using QBFT genesis.json 파일 copy # cp networkFiles / genesis.json ./ # ll total 8 - rw -r--r--. 1 root root 1639 Jun 20 03:23 genesis.json drwxr - xr -x. 3 root root 38 Jun 20 03:15 networkFiles drwxr - xr -x. 3 root root 18 Jun 20 02:46 Node-1 drwxr - xr -x. 3 root root 18 Jun 20 02:46 Node-2 drwxr - xr -x. 3 root root 18 Jun 20 02:47 Node-3 drwxr - xr -x. 3 root root 18 Jun 20 02:47 Node-4 - rw -r--r--. 1 root root 1513 Jun 20 02:54 qbftConfigFile.json 키 파일들을 각 노드의 data 디렉토리로 copy # cp networkFiles /keys/ 0x258ed3d4c40fa5cfecb67597c6dba6248804014c /* Node-1/data/ # cp networkFiles /keys/ 0x4914ca1ac7afb825cc1a416817597144bf878180 /* Node-2/data/ # cp networkFiles /keys/ 0x898c92dc5fff31af05de0e1a465c0ff812120d15 /* Node-3/data/ # cp networkFiles /keys/ 0x984769eacf61592cf42695a7147c9116c8ed738a /* Node-4/data/ # tree ├── genesis.json ├── networkFiles │   ├── genesis.json │   └── keys │   ├── 0x258ed3d4c40fa5cfecb67597c6dba6248804014c │   │   ├── key │   │   └── key.pub │   ├── 0x4914ca1ac7afb825cc1a416817597144bf878180 │   │   ├── key │   │   └── key.pub │   ├── 0x898c92dc5fff31af05de0e1a465c0ff812120d15 │   │   ├── key │   │   └── key.pub │   └── 0x984769eacf61592cf42695a7147c9116c8ed738a │   ├── key │   └── key.pub ├── Node-1 │   └── data │   ├── key │   └── key.pub ├── Node-2 │   └── data │   ├── key │   └── key.pub ├── Node-3 │   └── data │   ├── key │   └── key.pub ├── Node-4 │   └── data │   ├── key │   └── key.pub └── qbftConfigFile.json source : https:// besu.hyperledger.org /private-networks

Create a private network using QBFT 1 번 노드 기동 ( bootnode ) # pwd /root/ qbft -network/Node-1 # ../../ besu /bin/ besu --data-path=data --genesis-file=../ genesis.json -- rpc -http-enabled -- rpc -http- api = ETH,NET,QBFT --host-allowlist="*" -- rpc -http- cors -origins="all" 2024-06-20 03:42:54.457-04:00 | main | INFO | DefaultP2PNetwork | Enode URL enode ://952bfa93e63eecb6adc4c07688df3af41c9d71c4d736b108102758835bb7672ec6abf15f0afc7ae19d9c402a7e48fc92d350fe0bacfe7a0d3fc082540af7cc56@127.0.0.1:30303 2024-06-20 03:42:54.458-04:00 | main | INFO | DefaultP2PNetwork | Node address 0x258ed3d4c40fa5cfecb67597c6dba6248804014c Copy the enode URL to specify Node-1 as the bootnode in the following steps. source : https:// besu.hyperledger.org /private-networks

Create a private network using QBFT 2 번 노드 기동 ( bootnode 와 연결 ) # pwd /root/ qbft -network/Node-2 [ root@master Node-2]# ../../ besu /bin/ besu --data-path=data --genesis-file=../ genesis.json -- bootnodes = enode ://952bfa93e63eecb6adc4c07688df3af41c9d71c4d736b108102758835bb7672ec6abf15f0afc7ae19d9c402a7e48fc92d350fe0bacfe7a0d3fc082540af7cc56@127.0.0.1:30303 -- p2p -port=30304 -- rpc -http-enabled -- rpc -http- api = ETH,NET,QBFT --host-allowlist="*" -- rpc -http- cors -origins="all" -- rpc -http-port=8546 3 번 노드 기동 ( bootnode 와 연결 ) # pwd /root/ qbft -network/Node-3 [ root@master Node-3]# ../../ besu /bin/ besu --data-path=data --genesis-file=../ genesis.json -- bootnodes = enode ://952bfa93e63eecb6adc4c07688df3af41c9d71c4d736b108102758835bb7672ec6abf15f0afc7ae19d9c402a7e48fc92d350fe0bacfe7a0d3fc082540af7cc56@127.0.0.1:30303 -- p2p -port=30305 -- rpc -http-enabled -- rpc -http- api = ETH,NET,QBFT --host-allowlist="*" -- rpc -http- cors -origins="all" -- rpc -http-port=8547 이전 장에서 복사한 bootnode 의 enode url source : https:// besu.hyperledger.org /private-networks

Create a private network using QBFT 4 번 노드 기동 ( bootnode 와 연결 ) # pwd /root/ qbft -network/Node-4 [ root@master Node-4]# ../../ besu /bin/ besu --data-path=data --genesis-file=../ genesis.json -- bootnodes = enode ://952bfa93e63eecb6adc4c07688df3af41c9d71c4d736b108102758835bb7672ec6abf15f0afc7ae19d9c402a7e48fc92d350fe0bacfe7a0d3fc082540af7cc56@127.0.0.1:30303 -- p2p -port=30306 -- rpc -http-enabled -- rpc -http- api = ETH,NET,QBFT --host-allowlist="*" -- rpc -http- cors -origins="all" -- rpc -http-port=8548 이전 장에서 복사한 bootnode 의 enode url source : https:// besu.hyperledger.org /private-networks

Create a private network using QBFT 정상 기동 확인 curl -X POST --data '{"jsonrpc":"2.0","method":"qbft_getValidatorsByBlockNumber","params":["latest"], " id":1 }' localhost:8545 {" jsonrpc ":" 2.0","id":1,"result ":["0x258ed3d4c40fa5cfecb67597c6dba6248804014c","0x4914ca1ac7afb825cc1a416817597144bf878180","0x898c92dc5fff31af05de0e1a465c0ff812120d15","0x984769eacf61592cf42695a7147c9116c8ed738a"]} 4 개 노드의 주소 확인 - 이전 실습에서 노드키 자동 생성 결과로 얻었던 주소와 일치 여부 확인 at page 20 source : https:// besu.hyperledger.org /private-networks

Create a private network using QBFT 추가 학습 - 검증 노드 추가 / 삭제 - 스마트컨트랙트 배포 및 토큰 전송 등 ( 이전 챕터 Quorum Developer Quickstart 참고 ) https:// besu.hyperledger.org /private-networks/how-to/configure/consensus/ qbft#add-and-remove-validators-using-block-headers You can switch from the block header validator selection method configured here, to the contract validator selection method by updating the genesis file and configuring a transition.

Create a privacy-enabled network - Privacy transacion 기능 사용을 위해 Tessera 적용 - tx data 를 암호화 , 참여자 간에만 공유 , 기밀성 - 각 노드마다 Tessera 실행 이전 챕터의 Developer Quickstart 에서 초기 프로젝트 설정에서 privacy transaction 을 y 로 설정할 경우 tessera 가 자동 적용된다 . 이번 장은 tessera 를 step by step 으로 적용하는 실습 챕터임

Create a privacy-enabled network - 이전 챕터에서 실습한 QBFT 합의 알고리즘에 기반하여 실습 진행 - 각 Node-<N>/data 디렉토리에서 아래 명령 수행 ( 각 노드의 data 디렉토리에서 기 실습한 db 삭제 ) rm -rf caches/ database/ DATABASE_METADATA.json uploads ☞ bonsai 는 privacy mode 지원하지 않음  forest 로 설정하여 실습하기 위함 - Tessera 설치 (https:// docs.tessera.consensys.io / HowTo /Get-started/Install/Distribution) ① https:// github.com / ConsenSys / tessera /releases/latest 에서 최신 버전 다운로드 및 서버 업로드 ② tar xvf tessera-[version].tar ③ vi / etc /profile ④ source / etc /profile ⑤ tessera help 명령어로 정상동작 확인 환경변수 추가

Create a privacy-enabled network [ root@master qbft -network]# pwd /root/ qbft -network 디렉토리 구조 생성 mkdir -p Node-1/Tessera Node-2/Tessera Node-3/Tessera Node-4/Tessera source : https:// besu.hyperledger.org /private-networks

Create a privacy-enabled network 각 노드 Tessera 디렉토리에서 Tessera 통신용 공개키 / 개인키 생성 cd qbft -network/Node-<N>/ Tessera / [ root@master Tessera ]# tessera -keygen -filename nodeKey # ls nodeKey.key nodeKey.pub 생성 결과 source : https:// besu.hyperledger.org /private-networks

Create a privacy-enabled network 각 노드 Tessera 디렉토리에서 config 생성 - 각 노드 config 설정 값은 아래 링크 참조 https:// besu.hyperledger.org /private-networks/tutorials/ privacy#3-create-tessera-configuration-files cd qbft -network/ # vi Node-<N>/Tessera/tessera.conf source : https:// besu.hyperledger.org /private-networks

Create a privacy-enabled network 각 Tessera 노드 실행 각 Node-<N>/ Tessera 에서 tessera - configfile tessera.conf source : https:// besu.hyperledger.org /private-networks

Create a privacy-enabled network Besu 노드 1 실행 ( 실행 옵션으로 Tessera 연결 및 Privacy 지원 활성화 ) Node-1 에서 실행 ../../ besu /bin/ besu --data-path=data --genesis-file=../ genesis.json --data-storage-format=FOREST -- rpc -http-enabled -- rpc -http- api = ETH,NET, QBFT ,EEA,PRIV --host-allowlist="*" -- rpc -http- cors -origins="all" --privacy-enabled --privacy- url =http://127.0.0.1:9102 --privacy-public-key-file= Tessera / nodeKey.pub --min-gas-price=0 Copy the enode URL to specify Node-1 as the bootnode in the following steps. Enode URL enode ://952bfa93e63eecb6adc4c07688df3af41c9d71c4d736b108102758835bb7672ec6abf15f0afc7ae19d9c402a7e48fc92d350fe0bacfe7a0d3fc082540af7cc56@127.0.0.1:30303 2024-06-21 09:21:11.319-04:00 | main | INFO | DefaultP2PNetwork | Node address 0x258ed3d4c40fa5cfecb67597c6dba6248804014c source : https:// besu.hyperledger.org /private-networks

Create a privacy-enabled network Besu 노드 2 실행 ( 실행 옵션으로 Tessera 연결 및 Privacy 지원 활성화 ) Node-2 에서 실행 ../../ besu /bin/ besu --data-path=data --genesis-file=../ genesis.json --data-storage-format=FOREST -- bootnodes = enode ://952bfa93e63eecb6adc4c07688df3af41c9d71c4d736b108102758835bb7672ec6abf15f0afc7ae19d9c402a7e48fc92d350fe0bacfe7a0d3fc082540af7cc56@127.0.0.1:30303 -- p2p -port=30304 -- rpc -http-enabled -- rpc -http- api = ETH,NET, QBFT ,EEA,PRIV --host-allowlist="*" -- rpc -http- cors -origins="all" -- rpc -http-port=8546 --privacy-enabled --privacy- url =http://127.0.0.1:9202 --privacy-public-key-file= Tessera / nodeKey.pub --min-gas-price=0 이전 장에서 복사한 bootnode 의 enode url source : https:// besu.hyperledger.org /private-networks

Create a privacy-enabled network ../../ besu /bin/ besu --data-path=data --genesis-file=../ genesis.json --data-storage-format=FOREST -- bootnodes = enode ://952bfa93e63eecb6adc4c07688df3af41c9d71c4d736b108102758835bb7672ec6abf15f0afc7ae19d9c402a7e48fc92d350fe0bacfe7a0d3fc082540af7cc56@127.0.0.1:30303 -- p2p -port=30305 -- rpc -http-enabled -- rpc -http- api = ETH,NET,QBFT,EEA,PRIV --host-allowlist="*" -- rpc -http- cors -origins="all" -- rpc -http-port=8547 --privacy-enabled --privacy- url =http://127.0.0.1:9302 --privacy-public-key-file= Tessera / nodeKey.pub --min-gas-price=0 이전 장에서 복사한 bootnode 의 enode url Besu 노드 3 실행 ( 실행 옵션으로 Tessera 연결 및 Privacy 지원 활성화 ) Node-3 에서 실행 source : https:// besu.hyperledger.org /private-networks

Create a privacy-enabled network ../../ besu /bin/ besu --data-path=data --genesis-file=../ genesis.json --data-storage-format=FOREST -- bootnodes = enode ://952bfa93e63eecb6adc4c07688df3af41c9d71c4d736b108102758835bb7672ec6abf15f0afc7ae19d9c402a7e48fc92d350fe0bacfe7a0d3fc082540af7cc56@127.0.0.1:30303 -- p2p -port=30306 -- rpc -http-enabled -- rpc -http- api = ETH,NET,QBFT,EEA,PRIV --host-allowlist="*" -- rpc -http- cors -origins="all" -- rpc -http-port=8548 --privacy-enabled --privacy- url =http://127.0.0.1:9402 --privacy-public-key-file= Tessera / nodeKey.pub --min-gas-price=0 이전 장에서 복사한 bootnode 의 enode url Besu 노드 4 실행 ( 실행 옵션으로 Tessera 연결 및 Privacy 지원 활성화 ) Node-4 에서 실행 source : https:// besu.hyperledger.org /private-networks

Create a privacy-enabled network 결과 Tessera 노드 Besu 노드 source : https:// besu.hyperledger.org /private-networks

Create a privacy-enabled network Configure a multi-tenant node - https:// besu.hyperledger.org /private-networks/tutorials/privacy/multi-tenancy ① 특정 노드의 인스턴스를 복수로 실행할 수 있음 ② 특정 노드에 jwt 토큰을 발행하고 , 해당 토큰으로 클라이언트 요청으로 전달되는 jwt 를 파싱하여 허가된 API 에 대한 JSON-RPC 요청을 처리할 수 있음 (<- Privacy-enabled network 사용 이유 ) - keyData 가 여러 개 설정된 경우 각 Tessera 인스턴스는 자신의 키를 사용하여 트랜잭션을 처리

Create a permissioned network account-allowlist 와 nodes-allowlist 로 계정과 노드의 permission 을 관리 - perm_addNodesToAllowlist , removeAccountsFromAllowList , getAccountAllowlist 등의 API 로 권한관리 - 이전 챕터에서 실습한 QBFT 합의 알고리즘에 기반하여 실습 진행

Create a permissioned network Permission 설정 파일 생성 각 노드 Node-<N>/data 디렉토리에 아래 파일 생성 accounts-allowlist=[" 0xfe3b557e8fb62b89f4916b721be55ceb828dbd73 ", " 0x627306090abaB3A6e1400e9345bC60c78a8BEf57 "] nodes-allowlist=[] permissions_config.toml Permission 에 genesis 파일에서 명시한 첫 2 개의 account 만 allowlist 에 추가하여 실습하기 source : https:// besu.hyperledger.org /private-networks

Create a permissioned network Node 1 기동 ../../ besu /bin/ besu --data-path=data --genesis-file=../ genesis.json --permissions-nodes-config-file-enabled --permissions-accounts-config-file-enabled --data-storage-format=FOREST -- rpc -http-enabled -- rpc -http- api = ADMIN,ETH,NET,PERM,QBFT -- rpc -http-host="0.0.0.0" --host-allowlist="*" -- rpc -http- cors -origins="*" < 기존 Privacy enabled network 실습과 차이 > -- rpc -http-host="0.0.0.0" 은 외부 네트워크 ( 메타마스크 ) 등에서 접속을 허용하기 위함 -- rpc -http- api 에서 EEA, PRIV 제거 (  Private 기능을 사용하지 않는 실습 ) --privacy-enabled --privacy- url =http://127.0.0.1:9202 --privacy-public-key-file= Tessera / nodeKey.pub 제거 -- bootnode 제거 (Permission 을 추가하여 노드간 연결을 뒤에서 진행 (1 번 노드를 bootnode 로 설정예정 ) 결과 로그에서 enode 복사 enode ://952bfa93e63eecb6adc4c07688df3af41c9d71c4d736b108102758835bb7672ec6abf15f0afc7ae19d9c402a7e48fc92d350fe0bacfe7a0d3fc082540af7cc56@127.0.0.1:30303 source : https:// besu.hyperledger.org /private-networks

Create a permissioned network Node 2 기동 ../../ besu /bin/ besu --data-path=data --genesis-file=../ genesis.json --permissions-nodes-config-file-enabled --permissions-accounts-config-file-enabled --data-storage-format=FOREST -- rpc -http-enabled -- rpc -http- api = ADMIN,ETH,NET,PERM,QBFT -- rpc -http-host="0.0.0.0" --host-allowlist="*" -- rpc -http- cors -origins="*" -- p2p -port=30304 -- rpc -http-port=8546 결과 로그에서 enode 복사 enode ://f1e0e6ee986f7c189bc75b3a2f0ff4256b9d5a0ce5e799a7d81d0422eae400db96903dc09dbe1626fe4a4c7963cba5de1bae83d5e9e3a8a03e5f53819eebf518@127.0.0.1:30304 source : https:// besu.hyperledger.org /private-networks

Create a permissioned network Node 3 기동 ../../ besu /bin/ besu --data-path=data --genesis-file=../ genesis.json --permissions-nodes-config-file-enabled --permissions-accounts-config-file-enabled --data-storage-format=FOREST -- rpc -http-enabled -- rpc -http- api = ADMIN,ETH,NET,PERM,QBFT -- rpc -http-host="0.0.0.0" --host-allowlist="*" -- rpc -http- cors -origins="*" -- p2p -port=30305 -- rpc -http-port=8547 결과 로그에서 enode 복사 enode ://00e334d5195139102afb717e3eede9c5c68d86e7cfc4e66e56f879c19ec0dfdd56ac244c03ef6cf80c94233db35e99f9a82af2d07e135a38ce27e6c411ba569e@127.0.0.1:30305 source : https:// besu.hyperledger.org /private-networks

Create a permissioned network Node 4 기동 ../../ besu /bin/ besu --data-path=data --genesis-file=../ genesis.json --permissions-nodes-config-file-enabled --permissions-accounts-config-file-enabled -- rpc -http-enabled --data-storage-format=FOREST -- rpc -http- api = ADMIN,ETH,NET,PERM,QBFT --host-allowlist="*" -- rpc -http-host="0.0.0.0" -- rpc -http- cors -origins="*" -- p2p -port=30306 -- rpc -http-port=8548 결과 로그에서 enode 복사 enode ://1da03cac51d4fc896950ca9399fa98923ac10a0b18135f198a905cf6ad563e95396d634f0dd2f9beae0375e7da5bb16628980dcfe2bc2d91ecbcb2da8b1189cd@127.0.0.1:30306 source : https:// besu.hyperledger.org /private-networks

Create a permissioned network Permission 이 적용될 node 등록 - 각 노드의 rpc endpoint 에 각 노드 구동시 출력된 enode (4 개 ) 를 등록함 - 이는 permissions_config.toml 에 nodes-allowlist 에 노드를 추가하는 동작과 동일 curl -X POST --data '{"jsonrpc":"2.0","method":"perm_addNodesToAllowlist","params":[["enode://952bfa93e63eecb6adc4c07688df3af41c9d71c4d736b108102758835bb7672ec6abf15f0afc7ae19d9c402a7e48fc92d350fe0bacfe7a0d3fc082540af7cc56@127.0.0.1:30303","enode://f1e0e6ee986f7c189bc75b3a2f0ff4256b9d5a0ce5e799a7d81d0422eae400db96903dc09dbe1626fe4a4c7963cba5de1bae83d5e9e3a8a03e5f53819eebf518@127.0.0.1:30304","enode://00e334d5195139102afb717e3eede9c5c68d86e7cfc4e66e56f879c19ec0dfdd56ac244c03ef6cf80c94233db35e99f9a82af2d07e135a38ce27e6c411ba569e@127.0.0.1:30305","enode://1da03cac51d4fc896950ca9399fa98923ac10a0b18135f198a905cf6ad563e95396d634f0dd2f9beae0375e7da5bb16628980dcfe2bc2d91ecbcb2da8b1189cd@127.0.0.1:30306"]], "id":1}' http://127.0.0.1:8545 curl -X POST --data '{"jsonrpc":"2.0","method":"perm_addNodesToAllowlist","params":[["enode://952bfa93e63eecb6adc4c07688df3af41c9d71c4d736b108102758835bb7672ec6abf15f0afc7ae19d9c402a7e48fc92d350fe0bacfe7a0d3fc082540af7cc56@127.0.0.1:30303","enode://f1e0e6ee986f7c189bc75b3a2f0ff4256b9d5a0ce5e799a7d81d0422eae400db96903dc09dbe1626fe4a4c7963cba5de1bae83d5e9e3a8a03e5f53819eebf518@127.0.0.1:30304","enode://00e334d5195139102afb717e3eede9c5c68d86e7cfc4e66e56f879c19ec0dfdd56ac244c03ef6cf80c94233db35e99f9a82af2d07e135a38ce27e6c411ba569e@127.0.0.1:30305","enode://1da03cac51d4fc896950ca9399fa98923ac10a0b18135f198a905cf6ad563e95396d634f0dd2f9beae0375e7da5bb16628980dcfe2bc2d91ecbcb2da8b1189cd@127.0.0.1:30306"]], "id":1}' http://127.0.0.1:8546 curl -X POST --data '{"jsonrpc":"2.0","method":"perm_addNodesToAllowlist","params":[["enode://952bfa93e63eecb6adc4c07688df3af41c9d71c4d736b108102758835bb7672ec6abf15f0afc7ae19d9c402a7e48fc92d350fe0bacfe7a0d3fc082540af7cc56@127.0.0.1:30303","enode://f1e0e6ee986f7c189bc75b3a2f0ff4256b9d5a0ce5e799a7d81d0422eae400db96903dc09dbe1626fe4a4c7963cba5de1bae83d5e9e3a8a03e5f53819eebf518@127.0.0.1:30304","enode://00e334d5195139102afb717e3eede9c5c68d86e7cfc4e66e56f879c19ec0dfdd56ac244c03ef6cf80c94233db35e99f9a82af2d07e135a38ce27e6c411ba569e@127.0.0.1:30305","enode://1da03cac51d4fc896950ca9399fa98923ac10a0b18135f198a905cf6ad563e95396d634f0dd2f9beae0375e7da5bb16628980dcfe2bc2d91ecbcb2da8b1189cd@127.0.0.1:30306"]], "id":1}' http://127.0.0.1:8547 curl -X POST --data '{"jsonrpc":"2.0","method":"perm_addNodesToAllowlist","params":[["enode://952bfa93e63eecb6adc4c07688df3af41c9d71c4d736b108102758835bb7672ec6abf15f0afc7ae19d9c402a7e48fc92d350fe0bacfe7a0d3fc082540af7cc56@127.0.0.1:30303","enode://f1e0e6ee986f7c189bc75b3a2f0ff4256b9d5a0ce5e799a7d81d0422eae400db96903dc09dbe1626fe4a4c7963cba5de1bae83d5e9e3a8a03e5f53819eebf518@127.0.0.1:30304","enode://00e334d5195139102afb717e3eede9c5c68d86e7cfc4e66e56f879c19ec0dfdd56ac244c03ef6cf80c94233db35e99f9a82af2d07e135a38ce27e6c411ba569e@127.0.0.1:30305","enode://1da03cac51d4fc896950ca9399fa98923ac10a0b18135f198a905cf6ad563e95396d634f0dd2f9beae0375e7da5bb16628980dcfe2bc2d91ecbcb2da8b1189cd@127.0.0.1:30306"]], "id":1}' http://127.0.0.1:8548

Create a permissioned network Peer 노드 등록 - 노드 1 을 노드 2,3,4 에 peer 노드로 등록 - 노드 2 를 노드 3,4 에 peer 노드로 등록 - 노드 3 을 노드 4 에 peer 노드로 등록  노드 1 이 bootnode 로 인식됨 curl -X POST --data '{"jsonrpc":"2.0","method":"admin_addPeer","params":["enode://952bfa93e63eecb6adc4c07688df3af41c9d71c4d736b108102758835bb7672ec6abf15f0afc7ae19d9c402a7e48fc92d350fe0bacfe7a0d3fc082540af7cc56@127.0.0.1:30303"],"id":1}' http://127.0.0.1:8546 curl -X POST --data '{"jsonrpc":"2.0","method":"admin_addPeer","params":["enode://952bfa93e63eecb6adc4c07688df3af41c9d71c4d736b108102758835bb7672ec6abf15f0afc7ae19d9c402a7e48fc92d350fe0bacfe7a0d3fc082540af7cc56@127.0.0.1:30303"],"id":1}' http://127.0.0.1:8547 curl -X POST --data '{"jsonrpc":"2.0","method":"admin_addPeer","params":["enode://952bfa93e63eecb6adc4c07688df3af41c9d71c4d736b108102758835bb7672ec6abf15f0afc7ae19d9c402a7e48fc92d350fe0bacfe7a0d3fc082540af7cc56@127.0.0.1:30303"],"id":1}' http://127.0.0.1:8548 curl -X POST --data '{"jsonrpc":"2.0","method":"admin_addPeer","params":["enode://f1e0e6ee986f7c189bc75b3a2f0ff4256b9d5a0ce5e799a7d81d0422eae400db96903dc09dbe1626fe4a4c7963cba5de1bae83d5e9e3a8a03e5f53819eebf518@127.0.0.1:30304"],"id":1}' http://127.0.0.1:8547 curl -X POST --data '{"jsonrpc":"2.0","method":"admin_addPeer","params":["enode://f1e0e6ee986f7c189bc75b3a2f0ff4256b9d5a0ce5e799a7d81d0422eae400db96903dc09dbe1626fe4a4c7963cba5de1bae83d5e9e3a8a03e5f53819eebf518@127.0.0.1:30304"],"id":1}' http://127.0.0.1:8548 curl -X POST --data '{"jsonrpc":"2.0","method":"admin_addPeer","params":["enode://00e334d5195139102afb717e3eede9c5c68d86e7cfc4e66e56f879c19ec0dfdd56ac244c03ef6cf80c94233db35e99f9a82af2d07e135a38ce27e6c411ba569e@127.0.0.1:30305"],"id":1}' http://127.0.0.1:8548 source : https:// besu.hyperledger.org /private-networks

Create a permissioned network 정상 동작 확인 ○ 참여 peer 노드 갯수 확인 curl -X POST --data '{" jsonrpc ":"2.0","method":"net_ peerCount ","params":[]," id":1 }' localhost:8545 - 결과 : {" jsonrpc ":"2.0","id":1,"result":" 0x3 "} ○ allowlist 확인 curl -X POST --data '{" jsonrpc ":"2.0","method":"perm_ getAccountsAllowlist ","params":[]," id":1 }' -H "Content-Type: application/ json " http:// localhost:8545 - 결과 : {" jsonrpc ":" 2.0","id":1,"result ":["0xfe3b557e8fb62b89f4916b721be55ceb828dbd73","0x627306090abab3a6e1400e9345bc60c78a8bef57"]} ○ bootnode 확인 curl -X POST --data '{" jsonrpc ":"2.0","method":"admin_ nodeInfo ","params":[]," id":1 }' -H "Content-Type: application/ json " http:// localhost:8545 - 결과 : {" jsonrpc ":" 2.0","id":1,"result ":{" enode ":" enode ://952bfa93e63eecb6adc4c07688df3af41c9d71c4d736b108102758835bb7672ec6abf15f0afc7ae19d9c402a7e48fc92d350fe0bacfe7a0d3fc082540af7cc56@127.0.0.1:30303","listenAddr":"127.0.0.1:30303","ip":"127.0.0.1","name":"besu/ v24.5.2 / linux-x86_64 /oracle-java-17","id":"952bfa93e63eecb6adc4c07688df3af41c9d71c4d736b108102758835bb7672ec6abf15f0afc7ae19d9c402a7e48fc92d350fe0bacfe7a0d3fc082540af7cc56","ports":{" discovery":30303,"listener":30303 },"protocols":{"eth":{"config":{" chainId ":1337," berlinBlock ":0," qbft ":{"epochLength":30000,"blockPeriodSeconds":2,"requestTimeoutSeconds":4}},"difficulty":5288,"genesis":"0x0bfff602eb27908c50212176f59c5a40e634c9a9da745f9d32f4bf5f2acbbd07","head":"0x93ff7d6663c8a449cb3f0f0c3930ba26ff2cd65a5a9c8d89abda9a0c4f79c70e","network":1337}}}}

Create a permissioned network 테스트 - allowlist 에 있는 1 번 계정에서 allowlist 에 없는 3 번 계정으로 transfer 시도  Pending 으로 실패 0xfe3b557e8fb62b89f4916b721be55ceb828dbd73 0xf17f52151EbEF6C7334FAD080c5704D77216b732

Create a permissioned network besu 로그에 pending transaction 확인 가능 ① peding transaction 을 삭제하는 기능을 besu 에서 제공하지 않음 ② pending tx 를 삭제하기 위해서는 transaction pool size 를 작게 조절해서 oldest tx 부터 자동 삭제되게 하거나 , ③ besu 를 전체 재기동한다 . 다만 , 이때에도 메타마스크에서 pending 중인 tx 가 있기 때문에 , 재기동하고 정상 tx 를 메타마스크에서 요청하여도 이전 pending 된 내역을 다시 메타마스크에서 처리를 시도하기 때문에 정상 tx 도 처리가 안된다 . ④ 이를 위해서 아래와 같이 besu 재기동 이후에 메타마스크에서 우측과 같은 처리가 필요하다 . 메타마스크  Advanced  Clear activity and nonce data 섹션의 버튼 클릭

Create a permissioned network 테스트 - allowlist 에 있는 1 번 계정에서 allowlist 에 존재하는 2 번 계정으로 transfer 시도  성공 0xfe3b557e8fb62b89f4916b721be55ceb828dbd73 0x627306090abaB3A6e1400e9345bC60c78a8BEf57 source : https:// besu.hyperledger.org /private-networks

Create a permissioned network 노드 allowlist 에 없는 임의의 besu 노드 5 를 기동 ( 기동시 bootnode 를 1 번으로 지정 )  노드 5 에서 peer 노드의 갯수를 조회하면 으로 출력  perm_addNodesToAllowlist 를 통해 등록하지 않았기 때문에 예상된 결과임 source : https:// besu.hyperledger.org /private-networks

앞으로 다룰 내용 Kubernetes 배포 및 관리 Public Networks 실습 프로젝트 과제