코어 이더리움 프로그래밍 - HiroSung/Study GitHub Wiki

[예제로 배우는 스마트컨트랙트 개발|http://www.etherstudy.net/bloter.html]

- Mist 설치 및 환경 준비

- 예제 명령 gethconsole에서

  • 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 > 블럭의 개수를 알 수 있음

51% Attact 하기 위해서

  • 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에 저장함. 로컬의 정보.

트랜잭션

Functions (예제 : GreeterV2.sol)

  • external : 외부에서 호출시 사용
  • private : 상속구조 아래에서 부를 수 있음.

Data Location

  • 모든 complex type은 datalocation 가짐. Gas 값이 다름.
  • memory : 함수파라미터,반환값이 저장됨.
  • storage : 상태변수는 Local var. storage(blockchain)에 저장됨.

Special Variables

  • msg

Token

  • 이더리움은 대부분 ERC20 토큰임.
  • 이더리움 에코 시스템에서 유동성있고 교환가능한 상품
  • transfer : return type은 있지만 바로 오지 않음. miner가 채굴하고 채굴된 block이 전달되는 것임.

Events

  • 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                                                                                                   
}                                                                                                                       

토큰만들기 (SecureGeneralWalletCompatibleToken2)

  • 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

  • 이더를 투자하면, 토큰을 리워드 하게 함.
  • 콘트랙과 토큰이 필요 함.
  • 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% attack

  • 51% 공격을 위한 조건
    • 두 노드이 genesis 블록이 동일해야 함.
    • 동일한 genesis.json을 이용해서 genesis 블록을 초기화해야 (% geth --datadir test-data init genesis.json)

Function Call vs Message Call

  • stack 사이즈가 있음.
  • Crowd Func 컨트랙트에 이더 전송

Function Modifier (p.116)

  • 중복코드를 관리하는 방법

Special Variables

DAO Hack (DaoHack.sol)

  • Address
    • transfer 함수가 없는 상태에서 송금이 안되므로, 컨트랙트에서 payable이 있는 함수로 선택하여 송금해야 함.
    • call function

ERC223

  • 토큰을 처리 하지 못하는 컨트랙은 입금을 못받도록 제한처리함.
  • ERC721 : 캐릭터 처리
  • https://etherscan.io

Mist Install

블로터

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 설치 : 바로가기
⚠️ **GitHub.com Fallback** ⚠️