2023. 6. 15. 10:03ㆍBlockchain/Cosmos
※ 원글 작성 : 22년 8월 18일
Genesis는 블록체인을 처음 구동 시에 체인에 들어갈 설정들이 집약되어 있다. Cosmos의 경우는 ethereum의 그것보다 parameter도 많고 설정 시 고려해야할 부분도 많다. Ethereum의 genesis.json을 간략히 알아보고, cosmos genesis가 어떤 paramter를 가지고 있는지 확인한다.
Ethereum genesis
현재 PoW 기반 ethereum의 genesis는 아래와 같다. 단계 별로 각 필드가 어떤것을 얘기하는지 보려한다. 아래 예시는 ethereum 가이드에서 확인한 genesis이다.
{
"config": {
"chainId": 12345,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"berlinBlock": 0,
"ethash": {}
},
"difficulty": "1",
"gasLimit": "8000000",
"alloc": {
"7df9a875a174b3bc565e6424a0050ebc1b2d1d82": { "balance": "300000" },
"f41c74c9ae680c1aa78f42e5647a62f353b7bdde": { "balance": "400000" }
}
}
config
config
는 ethereum 초기 구동 시 체인의 버전 및 chain ID를 지정하는 부분이다.
chainId
Simple replay attack을 막기 위해 적용된 EIP 155 이후 (적용된 지 오래됐지만) chainId
가 signing에 포함됨에 따라 chainId
의 중요성이 커졌다. ethereum-lists에서 관리되고 있고, coin tool web에서도 현재 EVM 기반 체인들의 chainId
를 확인할 수 있다. Ethereum의 chainId
는 1이며 ropsten의 경우는 3인것처럼 mainnet과 testnet의 chainId
가 보통 분리되어 운영되고 있다. Private network라면 딱히 chainId
가 다른 체인들과 겹치는 것을 걱정할 필요는 없고, 큰 문제가 되지 않는다.(분리하는게 좋다.)
homesteadBlock
Ethereum의 release 버전을 확인할 수 있다. geth 상의 Homestead switch block (nil = no fork, 0 = already homestead)
에서 확인할 수 있는것처럼 0일 시 homesteadBlock
버전이다.
eipBlock
eip150Block
, eip155Block
, eip158Block
은 모두 각 EIP가 채택된 block을 수용할 것이라는 parameter이다.
forkBlock
byzantiumBlock
, constantinopleBlock
, petersburgBlock
, istanbulblock
, berlinBlock
모두 hard fork된 block을 수용할 것이라는 paramter이다.
ethash
ethash
는 clique 등 다른 consensus algorithm을 사용하지 않고 기본 algorithm을 사용한다는 뜻으로, 다른 변수 없이 선언만 해준다.
difficulty
Block 생성 난이도를 정의한다. Ethereum mainnet genesis 상의 difficulty
는 "0x0400000000"이다. Ethereum genesis 10진수로는 "17179869184"이다. difficulty
는 miner가 hash function을 얼마나 계산을 해야 조건에 만족하는 block을 찾을 수 있는지를 통계적으로 확인가능하다. 블록 생성 마다 변경이 되는데, miner가 증가해서 hashrate가 증가하면 block 생성시간이 앞당겨지기 때문에 block 생성 시간을 difficulty
증가를 통해 조정한다.
Ethereum difficulty chart에서 현재 difficulty를 확인할 수 있는데, 무려 12.10p(12,102,768,399,568,242.00/2022-08-17 기준)이다.
gasLimit
Gas fee 계산에 필요한 gasLimit
을 설정한다. 위에서 확인한 genesis에서 gasLimit
을 확인해 보면 "0x1388"로, 10진수로 5000이다. Ethereum gas 관련 참고
alloc
genesis account에 할당되는 balance를 확인할 수 있다. 위에서 표현된 예시처럼 각 account 마다 balance를 지정하여 처음 체인 구동 시에 account에 ETH를 할당 가능하다.
Cosmos genesis
Cosmos에서 채택한 genesis.json은 작성되어야 할 것들이 더욱 많다. 기본적으로 genesis 상에서 설정이 필요한 것 뿐만 아니라 이전 글에서 처럼 module화가 이루어져 있기 때문에 각 module이 필요로 하는 기본 값들을 설정해 주어야 한다.
Cosmosbub-1의 genesis 파일을 기준으로 하나하나 간략히 살펴본다.
genesis_time
"genesis_time": "2019-03-13T23:00:00Z",
말 그대로 genesis time이다 이 genesis block이 생성되는 시간을 뜻한다.
chain-id
"chain_id": "cosmoshub-1",
Ethereum과 마찬가지로 각 mainnet/testnet들을 구분해주는 ID이다. Cosmos의 chain-id
도 ethereum의 것처럼 unique한 상태가 중요하며, 보통 XX-number
의 형태로 main name과 version 정보를 함께 나타낸다.
consensus_params
"consensus_params": {
"block_size": {
"max_bytes": "150000",
"max_gas": "1500000"
},
"evidence": {
"max_age": "1000000"
},
"validator": {
"pub_key_types": [
"ed25519"
]
}
},
Consensus를 위한 parameters를 정의한다.
block_size
block_size
는max_bytes
와max_gas
params를 포함하고 있다.max_bytes
는 블록 당 최대 byte 수를 설정하고,max_gas
는 블록 당 최대 gas를 설정한다.- 한 블록 내에서 transaction들에게서 발생하는 수수료 gas fee의 합은
max_gas
를 넘을 수 없다. 이는 ethereum과 마찬가지이다.
evidence
evidence
는 validator의 잘못된 행동들을 기록하는 module이다. double signing(한 round에 두 개의 다른 블록에 signing) 등의 행동 시에evidence
로 확인한다.evidence
내의max_age
는 이 증거(evidence)가 더 이상 유효하지 않음을 나타내는 최대 블록 수를 설정한다.
validator
validator
내의pub_key_types
는 validator에게 허용되는 public key의 type을 설정한다. 현재 "ed25519" 만 사용되고 있다.
app_hash
app_hash
는 어플리케이션 단의 state root hash이다.- 해당 필드는 genesis.json에 mandatory로 지정되어야 하는 param은 아니며, 어플리케이션 단의
InitChain
을 통해 설정 가능하다.
app_state
app_state
필드 내에서 genesis의 state machine의 최초 state를 정의한다.app_state
내에서 많은 정보가 저장이 되기 때문에 genesis.json 내에서 가장 중요한 parameter로 볼 수 있다.
accounts
"accounts": [
{
"address": "cosmos1000ya26q2cmh399q4c5aaacd9lmmdqp92z6l7q",
"coins": [
{
"denom": "uatom",
"amount": "5000000000"
}
],
"sequence_number": "0",
"account_number": "0",
"original_vesting": null,
"delegated_free": null,
"delegated_vesting": null,
"start_time": "0",
"end_time": "0"
},
...
],
accounts
필드에서 genesis account들의 정보를 기록한다.
accounts
내에 포함되는 parameter들의 형식은 설정되는 account의 성질에 따라 다양하게 변경될 수 있다. 위 예시로 존재하는 genesis.json 에는 기본적인 baseAccount 형식으로 설정이 되어 있지만, private key를 생성하는 알고리즘이 변경된다거나, vesting account로 설정이 된다면 형태가 바뀔 수 있다. 예시를 cosmoshub로 들었으니 기본적인 parameter의 정의만 확인해 본다.address
는 account의 주소이다. Byte형식이 아닌 Bech32 형식으로 지정이 되어야 한다.coins
는 이 account가 갖는 genesis amount이다. 체인에 따른 denomination과 수량이 설정된다.sequence_number
와account_number
는 genesis account로 0이 설정된다. Sequence는 이 account가 발생한 transaction에 따라 증가되는 global 변수이고,account_number
는 account의 구분 번호이다.- 위에서 언급한 parameter를 제외한 나머지 params는 vesting account로 설정 시 입력되는 값들이다.
- Genesis account가 소유한 물량에서 차츰 vested되는 총량을
original_vesting
필드에 선언한다. 전체 소유한 물량 중 vesting된 정도에 따라delegated_free
값과delegated_vesting
값이 설정된다. start_time
과end_time
은 vesting하는 시작-종료 기간을 뜻한다. Unix time으로 설정이 되어야 하며start_time
과end_time
이 동시에 존재하면 continous vesting,end_time
만 존재하면 delayed vesting으로 설정된다. 이 두 params를 보고 account가 어떤 vesting 방식을 가지고 있는지 확인할 수 있지만, vesing account 설정시@type
가 생기고 해당 parameter에서 쉽게 확인 가능하다.- Genesis account들은 모두 이
accounts
필드 내에 정의가 되어야 한다.
auth
"auth": {
"collected_fees": null,
"params": {
"max_memo_characters": "512",
"tx_sig_limit": "7",
"tx_size_cost_per_byte": "10",
"sig_verify_cost_ed25519": "590",
"sig_verify_cost_secp256k1": "1000"
}
},
auth
필드는 transaction들과 account type을 지정한다.
collected_fees
- 이전 block에 collected fee를 지칭한다. 이 collected fee들은 distribution 때 각 validator들로 reward 된다.
params
params
내의 parameter들은 transaction 과 account 관련 설정을 정의한다.max_memo_characters
는 transaction에 포함되는 memo의 최대 글자수를 나타낸다.tx_sig_limit
은 transaction에 대한 multi signature의 최대 서명 수를 나타낸다. cosmoshub의 default는 7이므로 최대 7명의 서명을 transaction 내에 multi sig로 서명할 수 있다.tx_size_cost_per_byte
는 transaction 처리에 사용되는 gas의 양을 결정할 때, tx의 byte당 소비되는 gas양을 뜻한다. 즉, byte수에tx_size_cost_per_byte
를 곱한 값에 gas price를 다시 곱해 총 tx fee가 설정된다.sig_verify_cost_ed25519
와sig_verify_cost_secp256k1
은 각각 ED25519, Secp256k1으로 키로 서명된 signature를 확인할 때 사용되는 gas 비용이다.params
의 값은 늘이거나 줄일 때 trade-off가 발생한다. 체인의 목적에 맞게 적절한 값을 세팅하여 genesis에 등록이 필요하다.
bank
"bank": {
"send_enabled": false
},
bank
는 cosmos 내부 bank module에서 사용되는 parameter 값이다.
- 현재 예시로 나와 있는 cosmos의 genesis에서는
send_enabled
param만 존재하는데, genesis 단에서 transfer를 허용할 지를 결정하는 parameter이다. bank
필드 내에는balances
라는 필드가 존재할 수 있는데, 위에서 언급된accounts
필드의 account 내에coin
값이 지정되어 있지 않다면, genesis account가 보유하고 있는 amount를balances
필드 내에 denom/amount로 설정되어 있을 수 있다.- 또다른 필드로
supply
가 존재할 수 있는데, 이는 해당 체인이 제한적인 총 공급량을 가지고 있다는 뜻이며, 이supply
에 선언되어 있는 amount 만큼이 체인의 총 물량을 뜻한다.
staking
"staking": {
"pool": {
"not_bonded_tokens": "236198958120000",
"bonded_tokens": "0"
},
"params": {
"unbonding_time": "1814400000000000",
"max_validators": 100,
"max_entries": 7,
"bond_denom": "uatom"
},
"last_total_power": "0",
"last_validator_powers": null,
"validators": null,
"delegations": null,
"unbonding_delegations": null,
"redelegations": null,
"exported": false
},
staking
은 staking module에서 사용이 필요한 parameters를 정의한다. Staking 및 delegating 관련한 사항들이 모두 포함되어 있다.
pool
pool
내에는 genesis에서의 staking량을 뜻한다.not_bonded_tokens
는 delegated token양을,bonded_tokens
는 staked token 양을 말한다.
params
unbonding_time
은 staking된 token을 unbonding(unstaking) 신청 했을 시 staking module address에 지니고 있다가 account 소유주에 다시 전달되는 기간을 뜻한다. 단위는 ns(nano sec)이지만 뒤에 "s" 단위를 선언하면 second 단위로 정의될 수 있다.max_validators
는 validator의 최대 숫자를 나타내고,max_entries
는 validator/delegator 간 최대로 연결되는 숫자를 나타낸다.bond_denom
은 staking 가능한 token의 denomination을 말한다.
last_total_power
- Voting 가능한 총량을 말한다. 최초로 실행되는 체인에는 0이지만 hard fork되었을 시에는 이전 체인들에서 확인된 voting power 총합이 해당 parameter에 선언된다.
- 아래 선언되는 parameter들도 초기 체인에서는 0또는 null이지만 hard fork 되었을 시 선언되어 진다.
last_validators_powers
- 마지막으로 확인된 validator들의 총 voting power를 말한다.
validators
- 마지막으로 확인된 validator의 목록이다.
delegations
- 마지막으로 확인된 delegator의 목록이다.
unbonding_delegation
- 마지막으로 확인된 unbonding된 delegation 상태의 목록이다.
redelegations
- 마지막으로 확인된 redelegations(재위임) 상태의 목록이다.
exported
- 해당 genesis가 이전 state에서 export 되었는지를 확인해주는 parameter이다. 초기 체인에는 false지만 hard fork시에는 위의 값들이 null값이 아님과 동시에
exported
가 true이다.
mint
"mint": {
"minter": {
"inflation": "0.070000000000000000",
"annual_provisions": "0.000000000000000000"
},
"params": {
"mint_denom": "uatom",
"inflation_rate_change": "0.130000000000000000",
"inflation_max": "0.200000000000000000",
"inflation_min": "0.070000000000000000",
"goal_bonded": "0.670000000000000000",
"blocks_per_year": "6311520"
}
},
Native token이나 CW20 등 token을 mint 시에 적용되는 parameter들이다. 역시 mint module에서 사용되는 값이다.
minter
inflation
은 token의 공급으로 인한 inflation 값을 정의한다. 복리로 계산되며, 위 cosmoshub-1의 예시인0.070000000000000000
의 경우 7%로 매주 복리 계산되는 연간 inflation을 뜻한다.annual_provisions
는 각 블록에 대해 계산되는 값이다.
params
mint_denom
은 minting된 token의 denomination을 뜻한다.inflation_rate_exchange
는 inflation의 연간 최대 change 비율이며,inflation_max
,inflation_min
은 각각 inflation되는 최대/최소 수준을 정의한다.goal_bonded
는 bonding되는 총 supply의 비율이다. bonding된 staking token 비율이goal_bonded
보다 낮으면 inflation이inflation_rate_change
만큼inflation_max
에 도달할 때 까지 증가되며, 반대의 경우는inflation_min
에 도달할 때 가지 감소한다.blocks_per_year
는 연간 생성되는 블록 수를 결정하고, minting된 staking token이annual_provisions
의 값으로 block 보상을 계산하는데 사용된다.
distr
"distr": {
"fee_pool": {
"community_pool": null
},
"community_tax": "0.020000000000000000",
"base_proposer_reward": "0.010000000000000000",
"bonus_proposer_reward": "0.040000000000000000",
"withdraw_addr_enabled": false,
"delegator_withdraw_infos": null,
"previous_proposer": "",
"outstanding_rewards": null,
"validator_accumulated_commissions": null,
"validator_historical_rewards": null,
"validator_current_rewards": null,
"delegator_starting_infos": null,
"validator_slash_events": null
},
Distribution module에 사용되는 paramter이다.
fee_pool
fee_pool
내의community_pool
은 보상을 지불하는데 사용되는 token pool이다.
community_tax
- Community pool에서의 fee 및 block 생성 보상에 대한 tax 비율을 정의한다.
base_proposer_reward
- Block proposer가 block을 생성했을 시 fee에 대한 기본 reward 값이다. 위의 예시에서는 2%가 proposer에게 전달된다.
bonus_proposer_reward
- Block proposer가 block을 생성했을 시 fee에 대한 최대 reward 값이다. Precommits proposer가 voting으로 가중치를 부여한 2/3(블록이 유효하는 최소 값)을 포함하면
base_proposer_reward
를 받고 100 voting을 포함할 때 가지bonus_proposer_reward
까지 reward가 linear하게 증가한다.
withdraw_addr_enabled
- true인 경우 delegator는 reward를 인출하기 위해 다른 주소를 설정할 수 있음을 정의하는 paramter이다. false로 설정 시 불가능하다.
delegator_withdraw_infos
- Withdraw한 delegators의 목록을 나타낸다.
previous_proposer
- 이전 블록의 proposer을 나타낸다.
outstanding_rewards
- Un-withdrawn reward를 나타낸다.
validator_accumulated_commission
- Validator의 un-withdrawn 수수료를 나타낸다.
validator_historical_rewards
- Validator의 이전 rewards와 관련된 정보들의 리스트이다. 해당 리스트는 distribution module에서 계산에 사용된다.
validators_current_rewards
- Validator의 현재 rewards와 관련된 정보의 리스트이다.
delegator_starting_infos
- Privious validator period, delegation의 staking amount, 생성된 블록 height의 정보를 나타낸다.
validator_slash_events
- Validator의 과거에 slashing 된 정보를 나타낸다.
gov
"gov": {
"starting_proposal_id": "1",
"deposits": null,
"votes": null,
"proposals": null,
"deposit_params": {
"min_deposit": [
{
"denom": "uatom",
"amount": "512000000"
}
],
"max_deposit_period": "1209600000000000"
},
"voting_params": {
"voting_period": "1209600000000000"
},
"tally_params": {
"quorum": "0.400000000000000000",
"threshold": "0.500000000000000000",
"veto": "0.334000000000000000"
}
},
gov 또한 governance module에 사용되는 parameter들의 집합이다.
starting_proposal_id
- 첫 proposal의 ID를 정의한다. 각 proposal은 unique한 ID로 구분될 수 있다.
deposits
- Proposal ID 별 deposit(입금)된 목록이다.
votes
- Proposal ID 별 votes(투표) 목록이다.
proposals
- Proposal 별로 제안된 목록이다.
deposit_params
min_deposit
은 proposal이 voting period로 입력되는데 필요한 최소 보증금이다. 여러 코인 종류(denomination)을 사용할 수 있다.max_deposit_period
는 proposal에 deposit 할 수 있는 최대 기간(nano sec)을 정의한다.
voting_params
voting_period
는 voting 시 유지되는 시간(nano sec)을 정의한다.
tally_params
quorum
은 proposal이 유효하기 위해 voting되어야 하는 staking token의 최소 비율이다.threshold
는 proposal이 YES로써 유효할 수 있는 최소한의 voting 비율이다.veto
는 proposal 결과가 유효하기 위한NO_WITH_VETO
voting의 최대 비율이다.
slashing
"slashing": {
"params": {
"max_evidence_age": "1814400000000000",
"signed_blocks_window": "10000",
"min_signed_per_window": "0.050000000000000000",
"downtime_jail_duration": "600000000000",
"slash_fraction_double_sign": "0.050000000000000000",
"slash_fraction_downtime": "0.000100000000000000"
},
"signing_infos": {},
"missed_blocks": {}
},
Slashing은 validator를 처벌하기 위한 slash module에 사용되는 parameters이다.
params
max_evidence_age
는evidence
가 유효하기 위한 나노초 단위의 최대 age이다.signed_blocks_window
는 block을 moving window하여 offline validator를 파악한다. 보통 slashing 될 때에는 10,000개의 window 시 95% 이상을 missing할 시 발생한다. 대략 10시간min_signed_per_window
는 validator가 online으로 될 때 block window내에서 precommits된 최소 비율을 정의한다.downtime_jail_duration
은 Downtime으로 인해 validator가 jail되는 기간을 정의한다.(nano second)slash_fraction_double_sign
은 validator가 double signing을 할 시 delegator가 staking된 지분을 제거하는 비율이다.slash_fraction_downtime
은 validator가 downtime이 될 시 delegator가 staking 지분을 축소하는 비율이다.
signing_infos
- slashing module에서 필요한 validator 별 정보들의 list이다.
missed_blocks
- slashing module에서 필요한 missing block과 관련된 정보들의 list이다.
gentxs
"gentxs": [
{
"type": "auth/StdTx",
"value": {
"msg": [
{
"type": "cosmos-sdk/MsgCreateValidator",
"value": {
"description": {
"moniker": "ATEAM",
"identity": "0CB9A4E7643FF992",
"website": "nodeateam.com",
"details": "Node A-Team promises to provide validator node operation services at the highest quality."
},
"commission": {
"rate": "0.200000000000000000",
"max_rate": "1.000000000000000000",
"max_change_rate": "1.000000000000000000"
},
"min_self_delegation": "5000",
"delegator_address": "cosmos14l0fp639yudfl46zauvv8rkzjgd4u0zk0fyvgr",
"validator_address": "cosmosvaloper14l0fp639yudfl46zauvv8rkzjgd4u0zk2aseys",
"pubkey": "cosmosvalconspub1zcjduepq7jsrkl9fgqk0wj3ahmfr8pgxj6vakj2wzn656s8pehh0zhv2w5as5gd80a",
"value": {
"denom": "uatom",
"amount": "5000000000"
}
}
}
],
"fee": {
"amount": null,
"gas": "200000"
},
"signatures": [
{
"pub_key": {
"type": "tendermint/PubKeySecp256k1",
"value": "A6WjB8Rb39iqfkPqTU+2oNa/EFzhzCqo4MPNFiMgNQHQ"
},
"signature": "pQAaAGR1XjxWsm+jKuKkSDwmjcr2pKKSahxf4sJ48UIDODvQb66bH3+ANa/LibPg7aGjyD4jwNU3xDdWrmMYew=="
}
],
"memo": ""
}
},
gentxs
는 최초로 chain이 genesis될 시 생성이 필요한 transaction들의 집합이다. 각 gentx에는 체인을 구성하는 초기 validator들의 정보가 포함되어 있다. 각 validator들이 자신들의 gentx를 생성하고, 추후 한꺼번에 collect-gentx를 통해 gentx를 통합한 결과가 gentxs
에 포함된다.
상위 parameter로 type
과 value
가 있는데, type
은 gentx의 type을 나타내고, value
를 따로 빼서 설명한다.
msg
type
은 해당 message의 type을 나타낸다. 보통MsgCreateValidator
가 존재한다.description
에는 validator의 정보가 정의된다.moniker
는 validator node의 nickname이며,identity
는 해당 노드를 나타내는 난수(keybase),website
는 node 운영 주체사가 소개하는 website url,details
는 node 운영 validator가 소개하고 싶은 말은 언급한다. 이description
필드는 체인운영에 직접적으로 영향을 끼치는 부분은 아니며, explorer 같은 곳에서 확인이 가능하도록 정보를 제공해준다.commission
은 수수료 commission 받는 비율을 정의한다.max_rate
는 commission을 최대로 받을 수 있는 범위를 정의한다.min_self_delegation
은 validator가 자기 자신에게 delegation하는 최소 수량을 정의한다.delegation_address
는 validator의 일반 base account address,validator_address
는 해당 account가 validator의 역할을 할 시 나타내는 account address이다. 둘 다 같은 private key로 생성되므로 근본은 같은것이라 볼 수 있다. debug addr로 확인하면 두 주소가 같이 확인 될 수 있다.pubkey
는 validator의 public key이다.value
는 genesis account로써 처음 공급받은 물량에 대해 자체적으로 self-delegation한 수량을 정의한다.
fee
fee
는 gentx 생성 시에 발생한 gas fee를 의미한다.
signatures
signatures
는 해당 gentx에 서명한 account의 정보인 pubkey와 signature 정보를 기록한다.- multi signature의 경우에는 해당 필드가 조금 달라져서,
LegacyAminoPubKey
를 가지는 multisignature account pubkey의@type
과 최소 서명이 필요한threshold
, gentx에 multisig로 서명한 sign mode의 정보를 취합한mode_info
등의 parameter가 추가로 기입된다.
memo
memo
는 gentx 상에서 memo가 노출되며 보통 node ID와 IP가 기록된다.
Conclusion
Ethereum의 genesis와 cosmos의 genesis가 가지는 paramter들에 대해 확인해보았다. 위 예시로 든 genesis 파일은 각 체인들이 설정한 방식마다 조금씩 형태가 다를 수 있다. 가장 기본적인 genesis를 확인하였기 때문에 조금씩 다르더라도 해당 parameter가 어떤 의미를 가지고 있는지 얼추 이해할 수 있을것이다.
참고
https://geth.ethereum.org/docs/interface/private-network
https://hub.cosmos.network/main/resources/genesis.html
'Blockchain > Cosmos' 카테고리의 다른 글
Cosmos state query 방법 (0) | 2023.06.22 |
---|---|
Cosmos SDK 기반 체인 다중 validator 환경 구성 (0) | 2023.06.15 |
Cosmos chain module 및 components (0) | 2023.06.14 |
Cosmos SDK 기반 체인 configuration (1) | 2023.06.14 |
Cosmos SDK 기반 체인 로컬 테스트넷 구성 (0) | 2023.06.14 |