블록체인 TIL-8Week-51Day

디오·2023년 5월 2일
1

어제에 이어 복습부분과 새롭게 부분 배운 그리고 Solidity를 배운 부분에 대해서 정리해보도록 하겠다.



😊SmallTalk 및 추가정보.

  • 우리가 들어갔을때 항상 풀노드처럼 행동 할 필요는 없고, SPV노드처럼 행동을 한다.
    SPV노드는 풀노드처럼 전체 정보를 다 가지고 있지 않기 때문에 SPV노드가 풀노드에게 요청을 해야하는데 어떻게 해야하는지와 내가 새로운 풀노드가 되고싶어서 네트워크에 참가했을때 어떤형식으로 주변 이웃노드들의 정보를 얻고, 어떤 형식으로 체인을 동기화 시키는지에 대해 공부할 예정.

  • 수업에서는 큰 맥락을 이해하고 세부내용에 대해서 이해를 해야한다. 세부적인 부분만 신경쓰다보면 모든 내용이 다 연결되어 설명이 되는데 내가 기억하는 내용 자체가 다 조각난 기억으로 남겨질 수 있다. 그러다보면 두가지 다 놓치게 된다.

  • '머클루트(Merkle Root)'란 블록체인의 원소 역할을 수행하는 블록의 부분에 저장된 트랜잭션들의 해시트리라고 생각하면 된다.

  • '머클트리(Merkle Tree)' 혹은 '해시트리(Hash Tree)'라는 데이터 구조는 Ralph Merkle이라는 사람이 1979년에 특허를 낸 개념이다. 머클트리의 목적은 빠른 검색이 아니라 데이터의 간편하고 확실한 인증을 위해 사용한다.



☑️ 이전 블록체인 이론 복습.

  • 모서리가 둥근 푸른 사각형이 노드이고, 그 안에 역할이 포함됨.
    • 왼쪽 상단부터 모든 역할을 하는건 Reference Client.
    • 바로 아래 Full block chain과 network routing만 하는건 Full block chain node.
    • 그 아래 Miner까지 들어가면 Solo Miner.
    • 우측상단에는 SPV Wallet.
  • 이런방식으로 진행이 됨.

  • 지갑 어플이 깔려있는 테블릿이나 휴대폰도 노드로 생각할 수 있다.

  • 내가 유지하지 않으면 정보를 받을 수 없다. 그리고 내가 일으킨 거래를 전파를 시킬 수 없다.

  • 그래서 기본적으로 이웃간의 연결 유지 기능이 있다.

  • 모든 노드가 동등한 위치에 있지만 하는 역할이 다 다르다.

  • 풀노드와 대비되는 것이 SPV Node.

  • 두 노드는 가지고 있는 정보의 양이 다르다. 그렇기 때문에 거래를 검증하거나 할때 검증을 하는 방법이 다르다.

    • 풀노드의 경우 모든 정보를 가지고 있기 때문에 자신의 정보를 기반으로 거래를 검증해낼 수 있다.
    • SPV노드는 모든 정보를 가지고 있지 않기 때문에 풀노드의 도움을 받아야 한다.
  • 역할에 따라 지위가 정해지는것은 아니지만 확실히 풀노드가 유리한 부분은 있다.

  • 이 과정들은 실제로 어떤 정보를 주고 받기전에 내가 가지고 있는 정보나 나 자신에 대한 정보를 상대방에게 넘겨주는 것이다.

    • A가 version이라는 메세지를 보내고 B가 니가 version이라고 보낸 메세지를 받았어 라는 verack 답장을 보낸다.

    • 그리고 B가 version을 보낸다.

    • 그리고 A는 보내준 version을 받았다고 verack를 보낸다.

  • 안정적으로 작동하는 노드들의 리스트.

    • A가 자신의 addr을 보낸다.

    • A가 addr을 보내고 나면 B에게 이웃노드들에 대한 정보를 달라고 geraddr을 보낸다.

    • B가 getaddr을 받으면 자신이 가지고 있는 이웃노드들에 대한 정보를 보낸다.

  • A와 B가 getblocks를 통해 가장 마지막 블록을 확인한다.

  • 더 긴체인을 보유한 B가 A에게 inv라는 메세지를 보낸다.(그 안에는 공유받아야 할 첫 500개 노드의 해시정보가 있다.)

  • 만약 A가 일정 해시정보를 가지고 있어 500개가 다 필요하지 않다면 자신이 가진것 외에 필요한 양만큼의 블록만 달라고 getdata 요청을 보낸다.

  • B는 요청받은 블록을 A에게 보내준다. 한번 더 원하면 이 과정을 반복한다.

  • 이 모든 과정이 최초로 네트워크에 들어와 처음 통신을 연결하고 동기화가 되는 절차에 대한 것.

  • 앞의 전반적 내용은 새로들어간 풀노드가 어떻게 행동하는지에 대한 내용.



SPV Node.

  • 거래에 대한 정보가 없기 때문에 풀노드의 도움을 받아야함.

  • SPV노드는 정보가 없기 때문에 다른 경로로 거래를 검증함. 이를 위해 풀노드에게 정보를 요청하고 path를 받게됨.

  • path를 구하라는 문제가 나오면 지정된 해시와 반대에 위치하는 해시를 찾아주면 됨.

  • 예시를 아래에 이미지로 붙이도록 하겠음.




  • 새노드는 풀노드가 될지 SPV노드가 될지 선택할 수 있음.

    • 새노드 - 풀노드 - 동기화과정(체인을 받아야하기 때문에)

      • 그러면 두가지 문제에 직면하게 된다. 누구에게 연락할건지, 어떻게 연락할건지

      • 누구에게 연락할건지는 시드노드들에게.

      • 어떻게 연락할건지는 1) 연락의 시작(version을 주고받는걸로) 2) getblock(가장 마지막블록헤더 해시를 비교, inv 보내주고, getdata를 요청하면 block을 받음.)

      • 이렇게 풀노드가 되기위한 동기화 과정을 거치게됨.

    • 새노드 - SPV노드 - 검증을 받기위해서는 도움이 필요함.

      • 도움을 풀노드에게 요청함.

      • 풀노드에게 tx에 대한 정보를 요청

      • 그에 대한 답변으로 path를 받음.

      • path는 이진트리와 관련이 있음.

      • 그래서 이 과정을 거치고 나면 머클트리가 나옴.



💻 Solidity.

// SPDX-License-Identifier: GPL-3.0
// 없으면 경고 먹음 / 라이센스

pragma solidity ^0.8.18;
//컴파일 버전 : 컴파일과 맞지 않거나 낮으면 안됨 실행안됨 / 왠만하면 18,18 고고

contract StoreandReturn {
    uint a; //숫자형 변수 a
    uint b; //숫자형 변수 b
    uint c=2; // 숫자형 변수 c, 값은 2

    // 상태 변수 
    // 수정하려면 돈든다
    // view에 지역변수 선언하고 담아서 수정가능 -> view는 돈 안듬
    // 돈들면 주황색이랑 콘솔에 녹색 스티커 
  

    // 함수이고, 이름은 getA, input값은 없음, public 하고 view 함, output 값은 1개 있음, uint 형임
    function getA() public view returns(uint) {
        return a;
    }

    function setA(uint _a) public {
        a = _a;
    }

    function setAasFive() public {
        a = 5;
    }

    function getB() public view returns(uint) {
        return b;
    }

    function setB(uint _b) public {
        b = _b;
    }

    function setBasSeven() public {
        b = 7;
    }

    // 함수, 이름은 getAB, input 없음, public하고 view 함, output 값은 2개, 둘 다 uint형
    function getAB() public view returns(uint, uint) {
        return (a, b);
    }

    // view : 상태변수 참고가능 값 변경 불가능 -> 가스 안씀
    // pure : 상태변수 변경 및 참조도 불가  -> 가스 안씀
    // view, pure 없으면 가스비 나옴 

    //view와 pure 함수는 state variable(상태변수)의 값을 변화시키지는 않음 -> gas비 안씀

    function getABC() public view returns(uint, uint, uint) {
        return (a,b,c);
    }

    //숫자 _aa와 _bb를 받아서 이 2개의 숫자를 더한 결과값을 반환하는 함수 Add를 구현하세요.
    function Add(uint _aa, uint _bb) public pure/*상태변수는 하나도 필요없을때 pure*/ returns(uint) {
        return _aa + _bb;
    }

    // 숫자 a와 b를 갖고와서 이 2개의 숫자를 더한 결과값을 반환하는 함수 Add2를 구현하세요
    function Add2() public view/*상태변수를 갖고오기 때문에 view로*/ returns(uint) {
        return a+b;
    }

}
  • 상태변수는 contract와 function 사이 지정된 값을 지칭.

    • 상태변수도 수정이 가능하지만 수정할때 가스비가 든다.
  • 지역변수는 function안에 넣는 변수로 수정이 가능.

  • view : 상태변수 참고가능 값 변경 불가능 -> 가스 안씀

    • 상태변수를 가져올때 view 사용.
  • pure : 상태변수 변경 및 참조도 불가 -> 가스 안씀

    • 상태변수 하나도 없을때 pure 사용.
  • view, pure 없으면 가스비 나옴

  • view와 pure 함수는 state variable(상태변수)의 값을 변화시키지는 않음 -> gas비 안씀



// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.18;

/*
계산기를 만드세요.
2개의 input 값을 받아 더한 값을 반환하는 함수 Add, 곱한 값을 반환하는 함수 Mul, 뺀 값을 반환하는 Sub, 몫을 반환하는 Div를 구현하세요
*/

contract Basic2 {

    function Add(uint _a, uint _b) public pure returns(uint){
        return _a+_b;
    }

    function Mul(uint _a, uint _b) public pure returns(uint) {
        return _a*_b;
    }

    function Sub(uint _a, uint _b) public pure returns(uint) {
        return _a-_b;
    }

    function Div(uint _a, uint _b) public pure returns(uint, uint) {
        return (_a/_b, _a%_b);
    }
}
  • 민서강사님이 문제를 내셨는데 못풀었음..ㅜㅜ

    • 2개의 인풋값을 받아 => ((uint _a, uint _b)
    • 더한 값을 변환하는 함수 => Add
    • 상태변수를 사용하지 않기 때문에 pure 사용.
    • output값이 하나이기 때문에 uint 하나만 작성.
    • input값에 들어가는 _a , 즉 a앞에 언더바는 큰 의미가 없음. a와 구분을 두기 위해서 작성된 것이라고 매니저님이 말씀하심. a로 적어도 상관없는데 상태변수가 있거나 a값이 이미 있는경우에는 작성해주는게 좋음.
  • 나누기의 경우 _a/_b 로 표현할 수 있는데 그러면 "몫"만 나오게 됨. 나머지까지 나오게 하려면 결과값이 2개가 되기 때문에 output을 두개 적어주고 아래에 _a%_b를 작성해줌.

    • % 가 나머지를 나타냄.



💻수업 중 참고한 링크.



🌜하루를 마치며..

오늘 수업 마지막에 민서강사님께 질문을 했는데 뭔가 나만 모르는 것 같고 하필 수업 끝날 시간이라 사람들이 내가 질문하면 싫어할 것 같고, 관심도 쏠리는 것 같아서 부끄럽고 숨고 싶었는데 모르는부분 질문은 또 하고싶고.. 참 힘들었다..
그래도 착한 동료들이 위로도 해주고 도와줘서 금방 기분을 회복할 수 있었다.😊
내일은 좀 더 단단한 마음으로 하루를 시작할 수 있을 것 같다. 오늘도 복습 끝!

profile
개발자가 되어가는 개린이"

0개의 댓글