์ด๋๋ฆฌ์์ ์คํ ๋ถ๋ถ์ ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌํ๋ ๊ฒ์ด ๋ชฉ์ ์ ๋๋ค.
operating system: 18.04.02 LTS live-server, golang: >=1.10
golang ์ค์น. golang version์ 1.10 ์ด์์ด๋ค.
$ sudo add-apt-repository ppa:longsleep/golang-backports
$ sudo apt-get update
$ sudo apt-get install golang-go
ํธ์๋ฅผ ์ํด ํ๊ฒฝ์ค์ ์ ๋ฑ๋ก.
$ cd $home
$ echo "PATH=\$PATH:/home/`logname`/ethereum_parallel_execution/go-ethereum/build/bin" >> ~/.bashrc
$ source .bashrc
$ git clone <github address>
$ cd go-ethereum
$ make all
ํน์ geth๋ง ๋น๋ํ๊ณ ์ถ์ผ๋ฉด
$ make geth
solc ์ปดํ์ผ๋ฌ๋ฅผ ์ปจํธ๋ํธ ์ฝ๋๊ฐ ์์นํ ํด๋์ ๋์ด ํด๋น ํด๋์์ ์ปดํ์ผํ๋๋ก ํจ. ํ๊ฒฝ๋ณ์ ๋ฑ๋กํ์ฌ ์ฌ์ฉํ์ฌ๋ ๋ฌด๋ฐฉ
$ cd ethereum_parallel_execution/solidity
$ ./scripts/install_deps.sh
$ sudo apt remove --purge libz3-dev
$ mkdir build
$ cd build
$ cmake .. && make
$ cp solc/solc ../../sol_file
๋จ์ํ ๋ณ๋ ฌ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ์ง๋ฅผ ๋ณด๊ธฐ ์ํ ๊ฒ์ด๋ฏ๋ก no-discover ์ต์ ์ผ๋ก public network๋ฅผ ๊ตฌ์ถํด์ ์ฌ์ฉํ๋ค. Network Id๋ 940625๋ก ์ฌ์ฉํ๋ค.
์ฐธ๊ณ ์ฌ์ดํธ 1 - geth ์ปจํธ๋ํธ ํธ์ถ: https://stackoverflow.com/questions/48184969/calling-smart-contracts-methods-using-web3-ethereum?rq=1
๋ฐ์ดํฐ ํด๋(workspace) ์์ฑ(github์ ์ฌ๋ผ์์๋ paralleltestwork๋ ๋ฌด์ํด๋ ๋ฌด๋ฐฉ)
$ cd go-ethereum
$ mkdir paralleltestwork
๊ณ์ข ์์ฑ: ๋ฏธ๋ฆฌ ๊ณ์ข๋ฅผ ์์ฑํ์ฌ genesis ํ์ผ์์ ์ด๊ธฐ์ ์ฝ์ธ์ ๋ณด์ ํ ์ ์๊ฒ ํจ.
geth --datadir paralleltestwork/ account new
์ ๋นํ ๋น๋ฐ๋ฒํธ๋ฅผ ๊ธฐ์ตํ๋ค. Public address of the key ๊ฐ์ด ์ถ๋ ฅ์ด ๋๋ฉด ๊ธฐ์ตํ๋ค.
์์: Passphrase-> 2523, Public address of the key-> 0xcb2940b6766Dd4bfFF30616e4e1d3e911C8d803e
puppeth ๋ชจ๋์ด๋ genesis.json ํ์ผ์ ์์ฑํ๋ ๋ชจ๋์ด๋ค.(๋ง์ฝ ํ์ํ๋ฉด ์ฌ์ฉํ๊ณ github.com์ ์์ genesis.json ํ์ผ์ด ์ฌ๋ผ์ ์์ด ์ด๋ฅผ ์ฌ์ฉํด๋ ๋ฌด๋ฐฉ)
$ cd go-ethereum
$ puppeth
$ cp <networkname>.json genesis.json
์์: network name=yoomeetestnet, what would you do=2, what would you do=1, which consensus engine=1,
which accounts should be pre-funded=๋ฏธ๋ฆฌ ์์ฑํด ๋์ ๊ณ์ข์ public key๋ฅผ ๋ณต์ฌํ์ฌ ๋ฃ์,
pre-funded with 1 wei=yes, chain/network ID=940625, what would you like to do=2,2.
cp ๋ช ๋ น์ด๋ฅผ ํตํด genesis.json ํ์ผ์ด ์์ฑ๋๋ฉด genesis.json ํ์ผ์ ์์ ํ์ฌ ์ถ๊ฐ ์ค์ ์ ์๋ฃํ๋ค.
์์: difficulty=0x0100, balance="0x200000000000000000000"
์ถํ password ํ์ผ์ ์์ฑํ์ฌ geth ์คํ ์ password๋ฅผ ์ฃผ๋ ํ์ผ๋ก ์ฌ์ฉํ๋ค.
$ geth --datadir paralleltestwork/ init genesis.json
$ geth --datadir paralleltestwork/ --networkid 940625 --rpc --rpcaddr "0.0.0.0" \
--rpcport 8600 --rpccorsdomain "*" --rpcapi "admin,db,eth,debug,miner,net,shh,txpool,personal,web3" \
--allow-insecure-unlock --nodiscover --port 30303 --unlock 0,1 --password password console
$ personal.newAccount(โ2523โ)
$ eth.accounts / personal.listAccounts
$ eth.getBalance(eth.accounts[0])
$ eth.coinbase
$ miner.setEtherbase(eth.accounts[3])
$ miner.start(1)
$ miner.stop()
$ eth.mining
$ eth.blockNumber
$ personal.unlockAccount(eth.accounts[0])
$ eth.sendTransaction({from:eth.accounts[0], to:eth.accounts[2], value:10000})
$ eth.pendingTransactions
$ eth.getBlock(22)
$ eth.getTransaction("ํธ๋์ญ์
์ฃผ์")
$ eth.getTransactionReceipt("ํธ๋์ญ์
์ฃผ์") //๋ฐฐํฌํ contract์ ์ฃผ์๋ฅผ ๋ณด๊ธฐ ์ํด ์ฃผ๋ก ์ฌ์ฉ
$ eth.getCode("์ปจํธ๋ํธ ์ฃผ์") //๋ฐฐํฌํ contract์ ๋ฐ์ดํธ์ฝ๋๋ฅผ ํ์ธํ๊ธฐ ์ํด ์ฃผ๋ก ์ฌ์ฉ
F. geth๋ฅผ ํตํ Contract ์์ฑ๋ฐฉ๋ฒ (TODO: ํธ์๋ฅผ ์ํด javascript(+nodejs)๋ก ๋ณ๊ฒฝํจ, update ํ์)
remix๋ฅผ ์ฌ์ฉํ์ฌ contract๋ฅผ deployํ๋ฉด deploy ํ ๋๋ง๋ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ contract๋ ๊ณ์ ์๋ก ์์ฑ๋๋ ๋จ์ ์ด ์กด์ฌํ๋ค.
mutex ์ปจํธ๋ํธ๊ฐ ๋๋ฌดํ๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด geth์์ contract์ deployํ๋ ๊ฒ์ ์ ํํ์๋ค.
์ค๋น์ฌํญ์ ์ํ๋ ์์น์ .sol ์์คํ์ผ์ ์์นํ๋ ๊ฒ์ด๋ค. ํธ์๋ฅผ ์ํด paralleltestwork(์์
ํด๋)์์ solidity_file์ด๋
ํด๋๋ฅผ ์์ฑํ์ฌ ์ปดํ์ผ์ ์ํ๋ ์์ค์ฝ๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ค์ฝ๋๋ฅผ ๊ฐ์ด ์์น์ํจ๋ค.
$ cd ~/paralleltestwork/solidity_file
$ solc --abi voting_v2.sol
$ solc --bin voting_v2.sol
$ var contract = eth.contract([{"constant":false,"inputs":[{"name":"candidate_num","type":"uint256"}],"name":"vote","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"candidate_num","type":"uint256"}],"name":"get_candidate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"get_v","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}])
$ var bytecode = '0x608060405234801561001057600080fd5b5061048f806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80630121b93f1461004657806395fc395d1461008c578063fbfbfd97146100ce575b600080fd5b6100726004803603602081101561005c57600080fd5b81019080803590602001909291905050506100ec565b604051808215151515815260200191505060405180910390f35b6100b8600480360360208110156100a257600080fd5b8101908080359060200190929190505050610439565b6040518082815260200191505060405180910390f35b6100d6610450565b6040518082815260200191505060405180910390f35b600073efe38f307df41975ba058dfe2824ed53dd36be00637308809e60056040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b15801561013e57600080fd5b505af4158015610152573d6000803e3d6000fd5b505050506005600354106101d15773efe38f307df41975ba058dfe2824ed53dd36be0063b5fba83d60056040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b1580156101b057600080fd5b505af41580156101c4573d6000803e3d6000fd5b5050505060009050610434565b60036000815480929190600101919050555073efe38f307df41975ba058dfe2824ed53dd36be0063b5fba83d60056040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b15801561023357600080fd5b505af4158015610247573d6000803e3d6000fd5b5050505073efe38f307df41975ba058dfe2824ed53dd36be00637308809e60066040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b15801561029b57600080fd5b505af41580156102af573d6000803e3d6000fd5b50505050600560035414156102da576001600460006101000a81548160ff0219169083151502179055505b73efe38f307df41975ba058dfe2824ed53dd36be0063b5fba83d60066040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b15801561032a57600080fd5b505af415801561033e573d6000803e3d6000fd5b5050505073efe38f307df41975ba058dfe2824ed53dd36be00637308809e60076040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b15801561039257600080fd5b505af41580156103a6573d6000803e3d6000fd5b505050506001600083600381106103b957fe5b016000828254019250508190555073efe38f307df41975ba058dfe2824ed53dd36be0063b5fba83d60076040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b15801561041757600080fd5b505af415801561042b573d6000803e3d6000fd5b50505050600190505b919050565b600080826003811061044757fe5b01549050919050565b600060035490509056fea265627a7a7230582042e82287105bbb594545c04327f3a4d14702d2c56f6fe113e6c480cc6bddfa8d64736f6c63430005090032'
$ var deploy = {from:eth.coinbase, data:bytecode, gas: 2000000}
$ var contract_instance = contract.new("DISQUALIFIED!", deploy)
contract ํจ์๋ฅผ ํธ์ถํ๊ธฐ ์ํด์๋ contract์ abi์ ์ปจํธ๋ํธ ์ฃผ์๊ฐ ํ์ํ๋ค. ์ฌ๊ธฐ์๋ vote ์ปจํธ๋ํธ๋ฅผ ์ฌ์ฉํ์๋ค. abi์ address๋ 6๋ฒ์ ํตํด ์์๋ด์ผ ํ๋ค.
$ abi = [{"constant":false,"inputs":[{"name":"candidate_num","type":"uint256"}],"name":"vote","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"candidate_num","type":"uint256"}],"name":"get_candidate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"get_v","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]
$ c_address = "0xcef3434d109bb33b9dca073c4970ed174318eb0a"
$ c_instance = eth.contract(abi).at(c_address)
์ฝ๊ธฐ๋ง ํ๋ ํจ์์ ๊ฒฝ์ฐ geth์ call์ ์ฌ์ฉํ์ฌ ํธ์ถํ๋ค. ํธ๋์ญ์ ์ ๋ฐ์์ํค์ง ์๋๋ค. ์์์ ์์ฑํ ์ปจํธ๋ํธ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ๋ค๊ฐ ์ฌ์ฉํ์๋ค.
$ c_instance.get_v.call()
$ c_instance.get_candidate.call()
state๋ฅผ ๋ณ๊ฒฝ์ํค๋ ๊ฒฝ์ฐ sendTransaction์ ํธ์ถํ์ฌ ํธ๋์ญ์ ์ ์์ฑํด์ค๋ค. ๋ง์ด๋์ด ๋ ํ ๊ฒฐ๊ณผ๊ฐ ๋ฐ์๋๋ค.
$ c_instance.vote.sendTransaction(0,{from: eth.accounts[0]})
Git ์ค์น ๋ฐ ์ด๊ธฐ ์ค์
$ sudo apt-get install git
$ git config --global user.name "John Doe"
$ git config --global user.email [email protected]
Gitlab ์ ssh๋ก ์ ๊ทผํ๋ ๊ฒ์ด ํธํ๋ฏ๋ก ๋ด ๊ฐ์๋จธ์ (์ปดํจํฐ)์์ ssh ํค ์์ฑ ํ gitlab์ ๋ฑ๋กํด์ค
์ฐธ๊ณ - https://dejavuqa.tistory.com/139
$ ssh-keygen -t rsa -C "GitLab" -b 4096
gitlab.com์ผ๋ก ๋ค์ด๊ฐ ๋ก๊ทธ์ธ ํ ํ๋ก์ ํธ๋ฅผ ์ํ git repository ์์ฑ. ์์ฑํ์ผ๋ฉด git repository๋ฅผ ssh ๋ฒ์ ์ผ๋ก git clone
$ git clone [email protected]:yoomeeko/ethereum_parallel_execution.git
$ mv go_ethereum ethereum_parallel_execution.git/go_ethereum
$ mv genesis.json ethereum_parallel_execution.git/genesis.json
$ git add *
$ git commit -m โEthereum ์ถ๊ฐโ
$ git push
git ์์ ํ commit ๋ฐ push ๋ฐฉ๋ฒ
$ git add *
$ git commit -m โadded ~~โ
$ git push
git ์ต์ ๋ฒ์ ๊ฐ์ ธ์ค๊ธฐ
$ git pull
block explorer๋ ๋ธ๋ก์ ๋ณด, ๋ธ๋ก ์์ ๋ด๊ฒจ ์๋ ํธ๋์ญ์ ์ ๋ณด, account ์ ๋ณด๋ฅผ ui๋ก ์์๊ฒ ๋ณผ ์ ์๋ ํด์ ๋งํ๋ค. ์์ง ์ด๋๋ฆฌ์์์ private chain์ ์ํด ๊ณต์์ ์ผ๋ก ์ง์ํ๋ ํด์ ์์ง๋ง, ์คํ์์ค๊ฐ ๊ต์ฅํ ๋ง๋ค. ์ฐ๋ฆฌ๋ ๊ทธ์ค์์๋ Carsenk์ ์คํ์์ค explorer๋ฅผ ์ฌ์ฉํ ๊ฒ์ด๋ค. ํ๊ฒฝ ์ค์ ํ๋ ๋ฐ ์๋ฌ๊ฐ ๋์ ์ค์ ๋ก๋ ๋ชป ์คํํด ๋ณด์์ง๋ง, ๋์ค์ ์ด์ฉํ๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค.
์ฐธ๊ณ github: https://github.com/carsenk/explorer
1. CRDT: Conflict-free Replicated Data Types(modification์ ๋ํด ๋ฝ์ ์ฌ์ฉํ์ง ์๊ณ ํ๋กํ ์ฝ๋ง์ ์ฌ์ฉํ์ฌ ๋๊ธฐํ๊ฐ ๊ฐ๋ฅํ๊ฒ ํ๋ ๊ธฐ๋ฒ ์ค์ ํ๋)
https://medium.com/@amberovsky/crdt-conflict-free-replicated-data-types-b4bfc8459d26