코어 이더리움 프로그래밍 - HiroSung/Study GitHub Wiki
[예제로 배우는 스마트컨트랙트 개발|http://www.etherstudy.net/bloter.html]
- 1234 네트웍에 Node 1개가 붙어 있는 것임.
- personal.newAccount() > Account 생성 (mist 화면에 생성된 계정 확인)
- miner.start() > Main Account의 이더 생성.
- miner.stop() > 이더 생성 종료.
- eth.accounts > Account 정보 조회
- miner > 함수 정보
- miner.setEtherbase("account_id") > 메인 Account를 변경함. (메인 Account의 pharase 잊어 벼렸을 경우 활용 가능)
- admin > enode 주소 알 수 있음.
- eth.blockNumber > 블럭의 개수를 알 수 있음
- enisis block이 같으면 됨. (gethinit.bat 파일)
- 노드를 하나 만들어서 같은 네트웍/제니시스블럭이 같고 ... 어택할 수 있음.
- admin > enode 주소를 보고
- admin.addPeer("enode정보") > 블록 reorg가 일어나면서 한쪽 정보가 사라짐.
- 명령어
- gethinit2 수행 > gethclient2 수행 > gethconsole2 수행
- Mist > 컨트랙트 선택 > 컨트랙트 추가 [솔리더티 컨트랙트 소스 코드] 부분에 코딩함
- Mist > 개발 > Rimix IDE 열고 > [소스다운로드]smartcontract 의 파일들을 연다
- 소스 내용
pragma solidity ^0.4.18; contract GreeterV2 { string hello = "Hello"; function sayHello() public view returns (string) { return hello; } function changeHello(string _hello) external { hello = _hello; } }
- pure 가 있는 함수는 Mist 왼쪽에 배치 (Tran이 아님)
- view는 Mist 오른쪽에 배치 (Tran 임) > 그래서 Sign을 해야함. 위의 hello(는 상태변수) Tran에 저장함. 로컬의 정보.
- external : 외부에서 호출시 사용
- private : 상속구조 아래에서 부를 수 있음.
- 모든 complex type은 datalocation 가짐. Gas 값이 다름.
- memory : 함수파라미터,반환값이 저장됨.
- storage : 상태변수는 Local var. storage(blockchain)에 저장됨.
- msg
- 이더리움은 대부분 ERC20 토큰임.
- 이더리움 에코 시스템에서 유동성있고 교환가능한 상품
- transfer : return type은 있지만 바로 오지 않음. miner가 채굴하고 채굴된 block이 전달되는 것임.
- log 영역에 출력할때 사용
- atribute : indexed
- 특정이벤트 모니터링으로 사용
> **eth.getTransaction**("0x5680e93d87b6c98d0f3d8369b9139e2de11585949672c1e61e0c5014fbe6a485") { blockHash: "0x8217375939a8e58d69ba1c92646028e211a1414c16e26acabd774fa72d654ee6", blockNumber: 792, from: "0xac42827e828225db0544347d12319e101b041316", gas: 121000, gasPrice: 18000000000, hash: "0x5680e93d87b6c98d0f3d8369b9139e2de11585949672c1e61e0c5014fbe6a485", input: "0x", nonce: 9, r: "0x85781116f7f15ea400c28c433dc2e7d2bb72903e3d074190f186d77c57ef67b8", s: "0x399134737852efd2cedb82560c718e1642768c3f0d523fd7e18fe71af640c9e", to: "0xe4c9884340e6273a6d9a51c7ef5aab91c1991914", transactionIndex: 0, v: "0x1b", value: 2e+21 } > **eth.getTransactionReceipt**("0x5680e93d87b6c98d0f3d8369b9139e2de11585949672c1e61e0c5014fbe6a485") { blockHash: "0x8217375939a8e58d69ba1c92646028e211a1414c16e26acabd774fa72d654ee6", blockNumber: 792, contractAddress: null, cumulativeGasUsed: 21000, from: "0xac42827e828225db0544347d12319e101b041316", gasUsed: 21000, logs: [], logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000", status: "0x1", to: "0xe4c9884340e6273a6d9a51c7ef5aab91c1991914", transactionHash: "0x5680e93d87b6c98d0f3d8369b9139e2de11585949672c1e61e0c5014fbe6a485", transactionIndex: 0 }
- Decimals 처리 확인 (1000을 입력하고, decimal을 1 입력하면 Total Token은 100,0 으로 표현됨)
- ERC20 Token Standard
# 아래와 같은 I/F 구현해주면 거래소와 동일하게 처리 가능함. # 토큰간의 거래가 용이함 contract ERC20 { function totalSupply() constant returns (uint totalSupply); function balanceOf(address _owner) constant returns (uint balance); function transfer(address _to, uint _value) returns (bool success); function transferFrom(address _from, address _to, uint _value) returns (bool success); > 전송 function approve(address _spender, uint _value) returns (bool success); function allowance(address _owner, address _spender) constant returns (uint remaining); > 전송할 수 있는 권한이 있는지 여부 event Transfer(address indexed _from, address indexed _to, uint _value); event Approval(address indexed _owner, address indexed _spender, uint _value); } https
- 이더를 투자하면, 토큰을 리워드 하게 함.
- 콘트랙과 토큰이 필요 함.
- CrowdFund.sol
pragma solidity ^0.4.16; interface token { function transfer(address receiver, uint amount) external; } contract CrowdFund { address public beneficiary; uint public fundingGoal; uint public amountRaised; > 현재까지 모인 이더 uint public deadline; uint public price; > 리워드 비율. 대부분의 ICO들이 이렇게 처리 함. token public tokenReward; > 이미 만들어진 contract를 쓰겠다. mapping(address => uint256) public balanceOf; > 장부 bool public fundingGoalReached = false; bool public crowdsaleClosed = false; event GoalReached(address beneficiaryAddress, uint amountRaisedValue); event FundTransfer(address backer, uint amount, bool isContribution); function CrowdFund( > 생성자. address ifSuccessfulSendTo, uint fundingGoalInEthers, > 100이면. * 1 Eth (100* 100의 18승) uint durationInMinutes, uint etherCostOfEachToken, address addressOfTokenUsedAsReward ) public { beneficiary = ifSuccessfulSendTo; fundingGoal = fundingGoalInEthers * 1 ether; deadline = now + durationInMinutes * 1 minutes; > now 블럭생성타임. price = etherCostOfEachToken * 1 ether; > 비율 tokenReward = token(addressOfTokenUsedAsReward); > contrat 주소. 주소에 토큰을 전달함 } function () payable external { require(!crowdsaleClosed); uint amount = msg.value; balanceOf[msg.sender] += amount; amountRaised += amount; tokenReward.transfer(msg.sender, amount / price); > 메시지콜. 컨트랙트에서 해당 토큰으로 보내려고 할때 보래려고 함. FAIL! 이 수행됨. emit FundTransfer(msg.sender, amount, true); } modifier afterDeadline() { if (now >= deadline) _; > 원래함수의 내용을 넣어서 컴파일 하게 됨. } function checkGoalReached() external afterDeadline { if (amountRaised >= fundingGoal){ fundingGoalReached = true; emit GoalReached(beneficiary, amountRaised); } crowdsaleClosed = true; } function safeWithdrawal() external afterDeadline { if (!fundingGoalReached) { uint amount = balanceOf[msg.sender]; balanceOf[msg.sender] = 0; if (amount > 0) { if (msg.sender.send(amount)) { emit FundTransfer(msg.sender, amount, false); } else { balanceOf[msg.sender] = amount; } } } if (fundingGoalReached && beneficiary == msg.sender) { if (beneficiary.send(amountRaised)) { emit FundTransfer(beneficiary, amountRaised, false); } else { fundingGoalReached = false; } } } }
- 51% 공격을 위한 조건
- 두 노드이 genesis 블록이 동일해야 함.
- 동일한 genesis.json을 이용해서 genesis 블록을 초기화해야 (% geth --datadir test-data init genesis.json)
- stack 사이즈가 있음.
- Crowd Func 컨트랙트에 이더 전송
- 중복코드를 관리하는 방법
- Address
- transfer 함수가 없는 상태에서 송금이 안되므로, 컨트랙트에서 payable이 있는 함수로 선택하여 송금해야 함.
- call function
- 토큰을 처리 하지 못하는 컨트랙은 입금을 못받도록 제한처리함.
- ERC721 : 캐릭터 처리
- https://etherscan.io
Mist Install
- https://github.com/ethereum/mist/releases (또는 ethereum mist로 검색) 접속해서 Mist-installer-0-11-0.exe 다운로드
블로터
1일차 : 하루만에 끝내는 이더리움 이론 세션1. 코어 이더리움 이론 PDF 세션2. 예제로 배우는 스마트컨트랙트 개발 실습준비 PDF - Window용 스크립트 다운로드 - 맥 OSX용 전체 다운로드 - Window용 전체 다운로드 2일차 : ICO 하루만에 끝내기 세션3. ERC20 토큰 개발 (2시간) 세션4. First DApp 실습 (1시간) 실습하기 세션5. Geth 실습 - 프라이빗 네트워크 구축 (1시간) PDF 실습하기 세션6. DApp 실습 - 클라우드펀딩 개발 (2시간) PDF Github 세션7. P2P 파일 시스템 - IPFS (1시간) PDF * (참고) 맥/윈도우 64bit가 아닌 경우 1.Mist 설치 : 바로가기 2.Geth 설치 : 바로가기 3.IPFS 설치 : 바로가기 4.Node 설치 : 바로가기