Substrate private network

Yechan Jeon·2022년 2월 18일
0

Substrate

목록 보기
3/3
post-thumbnail

이 튜토리얼에서는 consensus model에 관한 기본 개념과 블록체인 네트워크를 시작하는 법에 대해서 다룬다.

모든 블록체인들은 노드를 필요로 한다. 노드들은 메세지의 집합체를 동의하고 새로운 블록을 성공적으로 생성하는데 쓰임(하나의 블록이 다음 블록으로 넘어가는 과정).
각각의 블록은 특정한 시점의 데이터 상태를 말해주고 노드들의 동의가 consensus(합의)라고 불려진다.

1세대 블록체인 비트코인과 그 다음 이더리움에 전반적으로 사용된 Proof of Work와
현 3세대 블록체인에 적용됀 Proof of Stake가 잘 알려진 consensus방식이다.

  • Proof of Work(작업증명) : 합의가 validator에 의해 행해지는 컴퓨터 연산에 의존한다. validator는 miner라고도 알려져 있음. 그리고 Validator들이 연산(해시값을 추적하는 퀴즈)를 풀어내면 새로운 블록을 체인에 추가한다.

  • Proof of Stake(지분증명): 해당 블록체인이 사용하는 암호화폐의 지분율을 기준으로 validator들이 선택된다. -> 내부 알고리즘에 의해 결정되므로 validator의 자격이 없는 pow방식에 비해 에너지 소모량이 현저히 낮지만, 지분에 의해 인센티브가 중앙화될 가능성이 있다는 점이 단점이다.

  • Proof of Authority(권한증명): 권한증명은 validators로 활동하는 승인된 계정들에게 의존한다. 승인된 노드들은 거래를 블럭안에 넣을 권한을 가짐.

substrate node template은 PoA방식을 사용한다. (authroity round 혹은 Aura consensus라고도 불림)


튜토리얼 목표

  1. 미리 정의된 계정을 사용하여 peer blockchain node를 시작하기
  2. 네트워크 권한을 위한 key pairs 생성
  3. 커스텀 체인 생성
  4. private two-node 블록체인 네트워크 시작하기

사전에 정의된 계정으로 시작하기

만약 substrate-node-template 폴더가 없다면, substrate node template <- 이 링크의 튜토리얼을 따라 원하는 운영체제에 설치하면 된다.

  1. terminal shell을 열고 node-template으로 이동
  2. 다음의 커맨드를 통해 오래된 체인 데이터를 purge(삭제) 시켜준다.
    ./target/release/node-template purge-chain --base-path /tmp/alice --chain local
  3. 기존 데이터를 삭제시켰으면 이 커맨드를 통해 alice account를 생성하고 local blockchain을 시작할 수 있다.
./target/release/node-template \
--base-path /tmp/alice \
--chain local \
--alice \
--port 30333 \
--ws-port 9945 \
--rpc-port 9933 \
--node-key 0000000000000000000000000000000000000000000000000000000000000001 \
--telemetry-url "wss://telemetry.polkadot.io/submit/ 0" \
--validator

--base-path: 이 체인과 관련된 모든 데이터의 저장소
--chain local: chain specification을 명시함(local, development and staging)
--alice : predefined keys를 alice계정에게 추가
--port 30333: p2p traffic을 위한 포트 명시. 이 튜토리얼에서는 두개의 다른 노드를 하나의 동일한 컴퓨터에서 시연하기 때문에 꼭 서로 다른 두 포트를 할당시켜야함!
--ws-port 9945: WebSocket traffic을 위한 포트
--rpc-port 9933: RPC traffic을 위한 포트
--node-key <key>: libp2p 네트워킹을 위한 Ed25519 secret key 설정
--telemetry-url: 어디에 telemetry data를 보낼지 설정. 여기에서는 parity tech의 공용 서버를 사용
--validator: 이 노드가 블록 생산과 마침과정에 참여한다는 것을 명시함.

위의 커맨드 라인을 실행시키고 정상적으로 블록체인 네트워크가 작동할 경우 몇 가지 짚고 넘어갈 정보들이 있다.
2022-02-17 20:57:40 🔨 Initializing Genesis block/state (state: 0x90bb…45b6, header-hash: 0x43ea…ab38)
노드가 사용하고 있는 최초의 블록을 식별한다.(다음 노드를 실행할 때도, 이 값들이 같아야함)
2022-02-17 20:57:40 🏷 Local node identity is: 12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp
이 문자열은 --node-key command에 의해 결정된다.
2022-02-17 20:57:45 💤 Idle (0 peers), best: #0 (0x43ea…ab38), finalized #0 (0x43ea…ab38), ⬇ 0 ⬆ 0
이것은 현재 다른 노드가 네트워크에 존재하지 않는다는 것을 알려준다. 블록이 생성되기 위해서는 또 다른 노드가 네트워크에 참여해야함.

frontend에서 체인 정보 확인

사용하는 웹브라우저에서 해당 링크로 이동한다.
Polkadot-JS Explorer
자세한 사용법은 substrate 공식 문서에서 확인

네트워크에 두 번째 node추가하기

커맨드는 상당히 비슷하다.
먼저 중요한 것은 지금 실행중인 terminal을 종료하지 말고 새로운 terminal shell을 연다.
그리고 이번에는 bob계정을 purge해주고 alice계정과 마찬가지로 명령어 묶음을 실행해주면 두 번째 노드가 뚝딱하고 만들어진다.
./target/release/node-template purge-chain --base-path /tmp/bob --chain local -y
이름이 bob으로 바꼈음을 확인해보자

./target/release/node-template \
--base-path /tmp/bob \
--chain local \
--bob \
--port 30334 \
--ws-port 9946 \
--rpc-port 9934 \
--telemetry-url "wss://telemetry.polkadot.io/submit/ 0" \
--validator \
--bootnodes /ip4/127.0.0.1/tcp/30333/p2p/12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp

앞서 말한대로 3 개의 포트를 alice에게 할당된 것과 다르게 할당해주었다.
이 명령어 묶음에서는 --bootnodes라는 명령어가 추가 됐는데, 단일의 boot node를 명시해주는 것이다.
해석해보면 ip4(ipv4), 127.0.0.1(localhost ip), tcp(p2p 소통을 위한 통신 프로토콜), 30333(p2p 소통을 위한 포트숫자), 12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp(alice계정을 사용하는 노드의 식별자)

이렇게 두 번째 노드까지 네트워크에 참여시키고 나면 블록이 생성되는 것을 확인할 수 있다.


key 생성하기

이제 노드를 시작하고 연결하는 방법을 알았으니, secret keys를 생성할 차례다.
각각의 블록체인 네트워크 참여자들은 본인의 고유한 키를 생성할 책임이있음을 기억하자!

node template을 통해서 key 생성하기

앞서 alice와 bob계정을 사용하기 위해서 command line options을 이용했지만 random keys를 생성하기 위해서도 사용할 수 있음.
참고로 production level의 blockchain을 위해서 key를 생성할 때는 인트라넷처럼 인터넷과 연결된 적이 없는 격리 컴퓨터를 사용하는게 바람직함. 최소한 랜뽑 정도는 하고 key를 생성하는게 안전하다..

튜토리얼은 local환경이니 앞의 보안문제를 무시하고
1. 다시 터미널을 키고 node-template으로 이동
2. 다음 커맨드로 secret phrase와 scheme Sr25519 keys(aura key)를 생성한다.
./target/release/node-template key generate --scheme Sr25519 --password-interactive
그럼 이런 결과를 볼 수 있음. (Key password에는 원하는 비밀번호 입력하면 됌)

Key password:
Secret phrase:       demand spell suspect awkward window rotate media man remain wrap across lunar
  Secret seed:       0x65ae5f7bde64c29ded76213e8af2b4e01d529fd734706f4354e6f7739b031117
  Public key (hex):  0x50e496756cf915a8aeaa632d8814602a999ec084871aaca457a2fe3d82a4e45d
  Account ID:        0x50e496756cf915a8aeaa632d8814602a999ec084871aaca457a2fe3d82a4e45d
  Public key (SS58): 5DtmbL1t87uodcnSaNqfxaLBiog4MLVMPJnDECXSLc79apuR
  SS58 Address:      5DtmbL1t87uodcnSaNqfxaLBiog4MLVMPJnDECXSLc79apuR

secret phrase는 Ed25519 signature scheme(grandpa key)사용하는 키를 얻기 위해서, public key는 이제 블록을 생성하기 위해서 사용된다.
phrase로 key 얻기
./target/release/node-template key inspect --password-interactive --scheme Ed25519 "dust hold myself random fluid valid artwork sheriff desk fetch side draft"
-> 아까 key생성할 때 썻던 비밀번호 입력하면 된다.
결과:

  Secret seed:       0x65ae5f7bde64c29ded76213e8af2b4e01d529fd734706f4354e6f7739b031117
  Public key (hex):  0x9f7112cc8df0bc4e2a3c8b96e157a7c51659b3d9bfbaa2714ddf74168473cfbc
  Account ID:        0x9f7112cc8df0bc4e2a3c8b96e157a7c51659b3d9bfbaa2714ddf74168473cfbc
  Public key (SS58): 5Ffm4UJ4PNzKvmtpavukVnBcZmLdyfH5eQG4L4PDUP7iAtit
  SS58 Address:      5Ffm4UJ4PNzKvmtpavukVnBcZmLdyfH5eQG4L4PDUP7iAtit

두 번째 키 묶음 생성

aura

Secret phrase:       addict party purse crawl witness forum reform manual double vague owner sibling
  Secret seed:       0xd63d8e6163dfd4073480f8b479fcf699429df2e5fe0d98eb881070f7f8597ba2
  Public key (hex):  0x64878557347ca869d3ef9c70c1f0630dcd4d34939c2c1e87247ecef884f63c4d
  Account ID:        0x64878557347ca869d3ef9c70c1f0630dcd4d34939c2c1e87247ecef884f63c4d
  Public key (SS58): 5ELWuNRN9VY63Za9tuYnFppZGrfv2ym5n4NwSyUjQTkwA4r3
  SS58 Address:      5ELWuNRN9VY63Za9tuYnFppZGrfv2ym5n4NwSyUjQTkwA4r3

grandpa

  Secret seed:       0xd63d8e6163dfd4073480f8b479fcf699429df2e5fe0d98eb881070f7f8597ba2
  Public key (hex):  0x5087eac4730db985b31cfd95e793eb4c89d3d5a51c1c0d21be4569f403392274
  Account ID:        0x5087eac4730db985b31cfd95e793eb4c89d3d5a51c1c0d21be4569f403392274
  Public key (SS58): 5DtJ4efYpywDyV7kS2THYeJqLiYXAKaAMfvbcTp22FTtmjgJ
  SS58 Address:      5DtJ4efYpywDyV7kS2THYeJqLiYXAKaAMfvbcTp22FTtmjgJ

커스텀 chain spec생성

chain spec이란 블록체인 노드가 어느 네트워크에 연결될 것인지, 어떤 실체와 시초로 통신할 것인지, 초기에 가져야 하는 합의 모델은 무엇인지 등등 체인 구성에 대한 정보의 집합을 말한다.

이전에 생성한 key pairs를 사용해서 chain spec을 생성하고 validators에게 공유한다.

이미 있는 chain spec을 수정

  1. 이미 존재하는 스펙에 새로운 체인 스펙을 덧씌우기 위해서 node template 디렉토리로 이동하여 다음의 명령어를 실행한다.
  2. 명령어를 통해서 customSpec.json이라는 파일로 체인 스펙을 변환시킴
    ./target/release/node-template build-spec --disable-default-bootnode --chain local > customSpec.json
  3. customSpec.json 파일 미리보기
    head customSpec.json -> 파일 시작
    tail -n 80 customSpec.json -> 파일 끝 부분
  4. customSpec 파일을 editor에서 실행해 수정시켜주자
    aura와 grandpa field를 생성시킨 두 개의 key pair로 바꿔준다.
"aura": {
        "authorities": [
          "5DtmbL1t87uodcnSaNqfxaLBiog4MLVMPJnDECXSLc79apuR",
          "5ELWuNRN9VY63Za9tuYnFppZGrfv2ym5n4NwSyUjQTkwA4r3"
        ]
},
"grandpa": {
  "authorities": [
    [
      "5Ffm4UJ4PNzKvmtpavukVnBcZmLdyfH5eQG4L4PDUP7iAtit",
      1
    ],
    [
      "5DtJ4efYpywDyV7kS2THYeJqLiYXAKaAMfvbcTp22FTtmjgJ",
      1
    ]
  ]
},

네트워크에 validator를 추가시키거나 변경시키기 위해서 위의 과정을 반복하면 된다.
정리하면,
1. aura section에 Sr25519주소 추가
2. grandpa section에 Ed25519주소 와 voting weight 추가
만약 두명 이상의 validator가 동일한 key를 사용한다면 블록 충돌이 일어나므로 유의할 것

chain spec을 raw 형식으로 변환하기

./target/release/node-template build-spec --chain=customSpec.json --raw --disable-default-bootnode > customSpecRaw.json
raw spec은 같은 정보를 포함하지만 , 동시에 노드가 local storage안의 데이터를 참고하기 위해 사용하는 storage keys도 포합하고 있다.

참고: Rust 컴파일러는 최적화를 통해 웹어셈블리 바이너리를 만들기 때문에 항상 같은 결과가 나온다고 보장할 수 없다. 때문에 결과를 확실히 하기 위해선, 모든 네트워크 참가자가 정확히 같은 raw chain spec을 공유해야 하므로 단 한명의 사람만 chain spec을 생성하고 공유해야한다.
Hunting down a non-determinism-bug in our Rust Wasm build


private network 시작하기

private network를 시작하기 전 점검사항
1. 최소한 두 개 이상의 권한계정을 위한 keys를 생성해야함
2. 블록생산(aura)와 블록마침(grandpa)를 위해 위의 keys를 포함한 custom chain spec을 업데이트 해야함
3. custom chain spec -> raw chain spec으로 변환시키고 네트워크 참가 노드들에게 분배해야함.

bootnode 실행 (가장 첫번째 노드)

오래된 데이터를 퍼지하고, 커맨드 실행
./target/release/node-template purge-chain --base-path /tmp/node01 --chain local -y
custom chain spec을 사용한 첫번째 노드 실행

./target/release/node-template \
--base-path /tmp/node01 \
--chain ./customSpecRaw.json \
--port 30333 \
--ws-port 9945 \
--rpc-port 9933 \
--telemetry-url "wss://telemetry.polkadot.io/submit/ 0" \
--validator \
--rpc-methods Unsafe \
--name MyNode01

key저장소에 key 넣기

여기서는 key subcommand를 이용하여 키를 저장

먼저 aura 부터

./target/release/node-template key insert --base-path /tmp/node01 \
--chain customSpecRaw.json \
--scheme Sr25519 \
--suri <your-secret-seed> \
--password-interactive \
--key-type aura

your-secret-seed는 key를 생성할 때 얻었던 secret phrase로 대체하면 됌.
--suri "demand spell suspect awkward window rotate media man remain wrap across lunar"

그 다음 grandpa

./target/release/node-template key insert --base-path /tmp/node01 \
--chain customSpecRaw.json \
--scheme Ed25519 \
--suri "demand spell suspect awkward window rotate media man remain wrap across lunar" \
--password-interactive \
--key-type gran

다음 명령어로 key들이 첫번째 노드를 위해 제대로 저장되었는지 확인
ls /tmp/node01/chains/local_testnet/keystore

다른 참가자들을 참가할 수 있도록 하기

./target/release/node-template purge-chain --base-path /tmp/node02 --chain local -y
모든 validators가 동일한 chain spec을 가져야함을 확인(여기서는 customSpecRaw.json)
맨 아래에 bootnode 옵션에서 첫번째 노드의 식별자와 동일한지 체크

./target/release/node-template \
--base-path /tmp/node02 \
--chain ./customSpecRaw.json \
--port 30334 \
--ws-port 9946 \
--rpc-port 9934 \
--telemetry-url "wss://telemetry.polkadot.io/submit/ 0" \
--validator \
--rpc-methods Unsafe \
--name MyNode02 \
--bootnodes /ip4/127.0.0.1/tcp/30333/p2p/12D3KooWLmrYDLoNTyTYtRdDyZLWDe1paxzxTw5RgjmHLfzW96SX

마찬가지로 두번째 노드도 aura와 grandpa keys를 key subcommand를 이용하여 저장한다.
aura

./target/release/node-template key insert --base-path /tmp/node02 \
--chain customSpecRaw.json \
--scheme Sr25519 \
--suri "addict party purse crawl witness forum reform manual double vague owner sibling" \
--password-interactive \
--key-type aura

grandpa

./target/release/node-template key insert --base-path /tmp/node02 \
--chain customSpecRaw.json \
--scheme Ed25519 \
--suri "addict party purse crawl witness forum reform manual double vague owner sibling" \
--password-interactive \
--key-type gran

다시 네트워크를 시작했을 때, block finalized에 성공한다면 private network이 성공적으로 진행되고 있는 것!

profile
방황했습니다. 다시 웹 개발 하려고요!

0개의 댓글