기타 개발 공부/Blockchain

블록체인 기초 정리

DevBabamba 2019. 7. 10. 16:31
반응형

해당 글은

를 참고로 작성되었습니다.

오류사항이 있더라도 너그러히 이해해 주세요!

Blockchain

블록체인?

  • 블록체인은 신뢰를 위해 설계된것! (효율성이 아니다!)

  • 전자 결제, 디지털 인증, 화물 추적, P2P 대출, 식자재 유통 과정, 전자투표, 전자시민권, 부동산 등기부, 병원간 의료기록 관리처럼 투명성과 신뢰성이 요구되는 다양한 분야에 우선 도입 유망

  • 블록 : 데이터 집합

    • 예 : a가 b에게 송금한 기록, c가 d에게 송금한 기록을 한데 모아 블록이 됨.
  • 그 블록들을 하나하나 연결한것이 블록체인.

  • 그 블록 체인들은 사용자 각각이 가져감.
  • 모두 같은 로그를 가지고 있기에 누군가 다른 로그를 가져간다면, 잘못된 정보를 가지고 있다는 것이 증명됨.

  • 즉 많은 사람이 접근해야 더 신뢰를 가질 수 있음.
  • 그리고 이를 가능하게 하는 것이 암호학

블록체인과 암호학

머클트리(이진트리)

  • 머클이라는 사람이 만든 트리구조
  • 해싱을 이용한 데이터 검증을 하는 트리구조

'쉽게 설명하는 블록체인: 머클트리(Merkle Trees) - 뱅크샐러드' 캡처

  • 두개씩 거래로 묶은 다음 SHA256 알고리즘을 통해 해시값으로 나타냄.
  • 이렇게 묶은 값들을 다시 두개로 묶어 또 해싱하여 수백개의 거랩 값들을 그림의 가장 꼭대기 위치한 하나의 데이터로 만들어 주는 것
    • 거래가 몇 천개든 뭉쳐 요약된 머클트리의 용량은 32비트로 항상 같다.
  • 이진트리이기 때문에 검색 속도는 Log2(N)

  • 만일 1024거래일 경우, log2[1024] = 10 이므로 10번의 경로 만으로도 특정거래 데이터를 찾을 수 있다.
  • 따라서 , 특정거래 데이터를 쉽게 찾을 수 있고, 트리경로를 따라가면 해시값이 다른것이 나오게 되어 거래의 위변조도 쉽고 빠르게 찾을 수 있다.
  • 라이트 노드(light node) : 블록데이터의 일부만 다운 받는 형태. 모바일로도 쉽게 특정 거래를 찾도록 해줌.

블록체인 문제점

1.프라이버시

  • 데이터조작 불가. 평생 기록이 남음

2.트랜잭션 코스트

3.트랜잭션 스피드

4.블록사이즈

솔리디티

튜링완전

  • 어떤 프로그래밍 언어나 추상머신이 튜링 머신과 동일한 계산 능력을 가진다는 의미.
  • 튜링 머신으로 풀수 있는 문제, 즉 계산적인 문제를 그 프로그래밍 언어나 추상머신으로 풀 수 있다는 의미
  • msg.sender : 메세이를 보낼 주소
  • msg.value : 메세지 보낼 값

스마트컨트랙트

  • 이더리움 스마트 컨트랙트 예시
    // 1. 컨트랙트 선언
    contract Sample {
        // 2. 상태 변수 선언
        uint256 data;
        address owner;

        // 3. 이벤트 정의
        event logData(uint256 dataToLog);

        // 4. 함수 변경자 정의
        modifier onlyOwner() {
            if(msg.sender != owner) revert();
            _;
        }

        // 5. 생성자
        function Sample(uint256 initData, address initOwner) {
            data = initData;
            onwer = initOwner;
        }

        // 6. 함수(메소드) 정의
        function getData() returns (uint256 returned) {
            return data;
        }
        function setData(uint256 newData) onlyOwner {
            logData(newData);
            data = newData;
        }
    }

데이터 타입

    contract Sample {
        string public myString = "wow"; // utf8
        bytes12 public myRawString = "wowowo";
    }

맵핑 (key:value 쌍)

    contract Sample {
        mapping (address => string) myMap;

        constructor(string value) public {
            myMap[msg.sender] = value;
        }
    }
  • 동적 배열, 정적 배열 모두 사용 가능
    contract Sample {
        uint[] myDynamicArray = [0, 0];
        uint[3] myStaticArray = [1,1,0];
    }
  • 인터페이스를 사용하여 추상 계층을 사용할 수 있음
    interface Token {
        function transfer(address recipient, uint amount) external;
    }

modifier 한정자 선언

  • 함수를 실행시키는 조건으로 사용할 수 있음
  • 함수를 실행시키기 전과 실행시킨 후에 특정한 기능을 할 수 있도록 만들 수 있음.
    contract Sample {
        address owner;
        modifier onlyOnwer {
            require(msg.sender == owner);
            _;
        }
        funciton ownerCanDoIt(string something) public onlyOnwer view returns (string) {
            return something;
        }
    }

데이터위치

  • storage : 상태변수, 로컬변수 (전역변수와 같음, 블로체인 내에 저장됨)
  • memory : 로컬변수(사용 후 휘발됨)

솔리디티 문법

  • if, else, while, for, break, continue, return, ? :

가시성

  • 누가 접근할 수 있는가 (접근 한정자)

external

  • 다른 컨트렉트나 트랜젝션에서 호출 가능
  • f() ✖︎ , this.f() ✓

public

  • 모든 방법으로 접근 가능

internal

  • 내부적으로만 접근 가능

private

  • internal과 비슷하지만, 상속된 컨트렉트에서는 접근 불가

가스

  • evm 에서 뭔가 실행시 가스라는것이 발생됨
  • 쉽게 말해 수수료라 생각하면 됨

가스리밋

  • 수수료의 한계치
  • 낮게 설정시 일을 끝마치기전에 수수료를 다 써버림
  • 이럴 경우 이더리움에서는 지금까지한 일을 모두 취소 시키고, 지금까지 사용한 수수료는 돌려주지 않음
  • 채굴자들이 일을 했기에 돌려주지 않는것

가스 프라이스

  • 가스당 가격

  • 비싸지면 채굴자들은 수수료를 많이 받을 수 있음

  • 따라서 비싼 가스프라이스가 먼저 채굴되는 경향이 있음

  • 가스프라이스 * 가스사용량 = 수수료

  • 솔리디티에서 가스를 사용할 때마다 가스를 사용하므로 신중하게 스마트 컨트랙트를 짜야함

투표용 이더리움 컨트랙트 만들기

  • 오토컴파일 설정

  • 자바스크립트 vm 을 쓰고, 작성한 컨트랙트를 선택하여 Deploy 함.
  • 또한 어카운트를 바꿔 실행 해 볼 수 있음.

  • 배포 됐다면, 만들어진 함수에 값을 넣거 나 하영 사용하면 된다.

  • 디버깅화면도 제공한다.

코드 예

    // 어떤버전의 솔리디티를 쓸건지
    pragma solidity >=0.4.24 < 0.6.0;

    // 컨트렉트 작성
    contract Vote {
        // strutcure
        struct candidator {
            string name;
            uint upVote;
        }
        // variable (get candidator 후보자를 확인)
        candidator[] public candidatorList;
        bool live;
        address owner;

        // mapping
        mapping(address => bool) Voted;

        // event
        event AddCandidator(string name);
        event UpVote(string candidator, uint UpVote);
        event FinishVote(bool live);
        event Voting(address owner);


        // modifier 컨트랙트를 만든 사람만 투표를 끝낼 수 있도록 | 컨트랙트를 만든 사람만 후보자 등록 할 수 있도록
        modifier onlyOwner {
            require(msg.sender == owner);
            _;
        }
        // constructor
        constructor() public {
            owner = msg.sender;
            live = true;

            emit Voting(owner);
        }

        //기능 정의
        // candidator 후보자
        function addCandidator(string memory _name) public onlyOwner { // 컨트랙트를 만든 사람만 후보자 등록 할 수 있도록(onlyOwner)  
            require(live == true);
            require(candidatorList.length < 5); // candidatorList.length 가 5보다 작아야지 아래 함수로 내려감. 가스 조절을 위해 필요함

            candidatorList.push(candidator(_name, 0));

            // emit event
            emit AddCandidator(_name);
        }

        //voting 투표
        function upVote(uint _indexOfCandidator) public {
            // 이미 투표를 한사람은 제외 시키기
            require(live == true);
            require(Voted[msg.sender] == false);

            candidatorList[_indexOfCandidator].upVote++;

            Voted[msg.sender] = true;

            candidator memory tmpCd = candidatorList[_indexOfCandidator];

            // emit event
            emit UpVote(tmpCd.name, tmpCd.upVote);
        }
        // finish vote 투표끝내기. 컨트랙트를 만든 사람만 투표를 끝낼 수 있도록(onlyOwner)  
        function finishVote() public onlyOwner {
            require(live == true);
            live = false;

            emit FinishVote(live);
        }
    }
반응형