블록체인 TIL-9Week-57Day

디오·2023년 5월 8일
0

💻지난주 Solidity 내용 복습.

  • 형변환에서 가장 중요한 부분은 정적, 동적인 부분을 아는것이다.
function bytesToString3(string memory _a) public pure returns(string memory) {
        bytes memory _b = new bytes(1);
        _b[0] = bytes(_a)[0];
        return string(_b);
    }

  • bytes memory _b를 보면 동적으로 시작했기 때문에 동적인 아이 new bytes(1)를 가져와서 끝까지 동적으로 마무리를 하는것이 중요하다.






✅Struct 복습.(With 종우님.)

  • 반복적인 연습이 중요.
contract review {
//이름, 번호, 생년월일을 담은 student라는 구조체와 제목, 번호, 날짜를 담은 class라는 구조체를 선언하시오.

    struct student {
        string name;
        uint number;
        uint birth;
    }
    struct class {
        string title;
        uint number;
        uint date;
    }
    
//student형 변수 s 와 class형 변수 c를 선언하시오.
    student S;
    class C;
    
//s에 값을 부여하는 함수 setS와 c에 값을 부여하는 함수 setC를 각각 구현하시오
    function setS(string memory _name, uint _number, uint _birth) public {
        S = student(_name, _number, _birth);
    }

    function setC(string memory _title, uint _number, uint _date) public {
        C = class(_title, _number, _date);
    }

    function getS() public view returns(student memory) {
        return S;
    }
    
//변수 s의 값을 반환받는 함수 getS와 c의 값을 반환받는 함수 getC를 각각 구현하시오.
    function getC() public view returns(class memory) {
        return C;
    }
    
//student형 변수들이 들어가는 array students와 class형 변수들이 들어가는 array classes를 선언하시오.
    student[] students;
    class[] classes;

//students에 student 구조체를 넣는 pushStudent 함수를 구현하세요.
    function pushStudent(string memory _name, uint _number, uint _birth) public {
        students.push(student(_name, _number, _birth));
    }
//classes에 class 구조체를 넣는 pushClass 함수를 구현하세요.
    function pushClasses(string memory _title, uint _number, uint _date) public {
        classes.push(class(_title, _number, _date));
    }

}

contract review2 {
//숫자형 변수 a, 문자형 변수 b, bytes2형 변수 c를 담은 구조체 D를 선언하세요.
   struct D {
       uint a;
       string b;
       bytes2 c;
   }
   
//D형 변수 dd를 선언하세요.
   D dd;
   
//dd에 값을 부여하는 setDD함수를 구현하세요.
   function setDD(uint _a, string memory _b, bytes2 _c) public {
       dd = D(_a, _b, _c);
   }
   
 💡(추가내용)//dd의 값을 반환하는 getDD 함수를 구현하세요
   function getDD() public view returns(D memory) {
       return dd;
   }
   
//D형 변수들이 들어가는 array Ds를 선언하세요.
   D[] Ds;
   
//Ds에 새로운 D형 변수를 넣는 pushD 함수를 구현하세요.
   function pushD(uint _a, string memory _b, bytes2 _c) public {
       Ds.push(D(_a, _b, _c));
   }
   
💡(추가내용)//Ds array의 n번째 요소를 반환받는 getN이라는 함수를 구현하세요.(추가)
   function getN(uint _n) public view returns(D memory) {
       return Ds[_n-1];
   }
}

contract review3 {

//숫자형 변수 number, 문자형 변수 name, bytes2형 변수 password 그리고 member라는 구조체를 선언하세요.
   struct member {
       uint number;
       string name;
       bytes2 password;
   }
   
//member형 변수 Michael을 선언하세요.
   member Michael;
   
//Michael에 값을 부여하는 setM 함수를 구현하세요.
   function setM(uint _number, string memory _name, bytes2 _password) public {
       Michael = member(_number, _name, _password);
   }
   
//member형 변수들이 들어가는 members를 선언하세요.
   member[] members;
   
//members에 새로운 member 변수를 넣는 pushMember 함수를 구현하세요
   function pushMember(uint _number, string memory _name, bytes2 _password) public {
       members.push(member(_number, _name, _password));
   }
}






✅특정요소반환.

contract Struct {
    struct Student {
        string name;
        uint birthday;
        uint number;
    }

    Student[] students;

    function pushStudent(string memory _name, uint _birthday, uint _number) public {
        students.push(Student(_name, _birthday, _number)); // 배열명.push(구조체명(구조체 정보들))
    }

    function getStudent(uint _n) public view returns(Student memory) {
        return students[_n-1];
    }
    
    💡(특정요소반환)// n번째 아이의 생일을 알려줘.
    function getBirthday(uint _n) public view returns(uint) {
        return students[_n-1].birthday; // array이름[n번째].요소이름
    }
}
  • 특정요소를 반환하고 싶다면 array이름[_n-1].요소이름을 입력하면 특정선택하고 싶은 요소의 정보만 반환할 수 있다.






💻Address, Mapping, 머클트리.

✅Address.

  • Address형 변수가 따로 있음. (address형은 20bytes, 40자리.)
  • 기본적으로 이더리움의 경우, 스마트컨트랙트가 있기 때문에 사람과 스마트컨트랙트가 둘 다 지갑주소를 가질 수 있다.(이더리움에 있는 2가지 계정 종류.)
    • EOA(Externall Owned Accounts) = 사용자 계정 주소
    • CA(Contract Accountzzz) = 스마트 컨트랙트의 주소
contract Address {
    address a;

    // contract의 address
    function getAddress() public view returns(address) {
        return address(this);
    }

    // msg.sender의 address
    // 내 주소를 보는방법. (msg.sender는 누가 이 함수를 건드렸는지를 나타냄.)
    function getMyAddress() public view returns(address) {
        return address(msg.sender);
    }
    
    // 나의 가스값을 확인할 수 있다.
    function getMyBalance() public view returns(uint) {
        return address(msg.sender).balance;
    }
    
    // 해당 컨트랙트의 balance를 알아볼 수 있다.
    function getContractBalance() public view returns(uint) {
        return address(this).balance;
    }

    function setA(address _a) public {
        a = _a;
    }
    
    function getA() public view returns(address) {
        return a;
    }
    
    /*
    // x
    function setA(bytes20 _a) public {
        a = _a;
    }

    // x
    // bytes20과 address는 길이만 같고, 완벽하게 address형으로 사용할 수는 없다.(형이 다르기 때문에)
    function getA() public view returns(bytes20) {
        return a;
    }
    */
   
}

  • address(this)에서 this는 컨트랙트를 의미한다.

  • address(msg.sender)에서 msg.sender는 내 주소를 의미한다.
    • 이를 토대로 Deploy를 해보면 아래가 같이 컨트랙트 주소와 내 주소가 다른것을 확인할 수 있다.

  • balance는 .balance로 사용하면 가스비를 확인할 수 있다.

  • bytes20과 address는 길이만 같고, 형이 일치한다고 볼 수 없다. 완벽하게 address형으로 사용할 수는 없다.






✅가스비.

contract GasAndFee {

    uint b; // 상태변수

    // 상태변수 변화 -> gas비 소비, 잔액 변화
    function changeB() public {
        b = b+5;
    }

    // pure 함수를 사용하면 -> 잔액 변화 x
    function add(uint _a, uint _b) public pure returns(uint) {
        return _a+_b;
    }

    // pure와 같은 역할이지만 일반 함수를 사용하면 -> gas비 소비, 잔액 변화
    function add2(uint _a, uint _b) public returns(uint) {
        return _a+_b;
    }
}
  • 상태변수 변화에 따라 gas비가 소비되고, 잔액에 변화가 생긴다.

  • pure 함수를 사용하면 잔액에 대한 변화가 없다.

  • 위아래 코드가 같지만 다른 부분은 pure를 넣었느냐 아니냐에 차이다. 두 코드는 같은 역할을 하지만 pure를 적이 않은 코드는 gas비를 사용하게 되고, pure를 작성한 코드는 gas비를 사용하지 않는다.






✅Mapping.

// 누구는 점수가 얼마야? 라고 물어볼때는 mapping이 좋다. (이름 = key값, 신장 = value값)

contract Mapping {
    //숫자를 검색해서 숫자가 나온다.(숫자형 => 숫자형)
    // key-value 쌍이 숫자-숫자로 연결되어있는 mapping a
    mapping(uint => uint) a;
    
    // mapping(숫자형 => 자료형) mapping 이름;
    mapping(uint => string) b;
    // mapping(자료형 => address형) mapping 이름;
    mapping(string => address) c;
    
    // 2중 맵핑. 몇반에 누구라는 식으로 구분할 수 있다.
    //(한 데이터가 여러가지 방면에서 사용된다고 생각했을때 2중 맵핑을 사용하는것이 좋다)
    mapping(uint => mapping(string => uint)) score;

    // 이름을 검색하면 그 아이의 키를 반환하는 contract를 구현하고 싶다.
    mapping(string => uint) height;

    // 정보 넣기
    function setHeigth(string memory _name, uint _h) public {
        height[_name] = _h; // mapping이름[key 값] = value 값
    }

    // 정보 받기
    function getHeight(string memory _name) public view returns(uint) {
        return height[_name]; // mapping이름[key 값]
    } 

    // 정보 지우기
    function deleteHeight(string memory _name) public {
        delete height[_name];
    }
}

  • 정보 넣기는 아이의 이름과 신장수치가 필요하기 때문에 input값에 2개가 들어가고, 정보를 넣기 때문에 output값은 필요하지 않다.
    그리고 " height[_name] = _h; " 를 입력하면 아이의 이름과 신장값을 넣을 수 있다.

  • 정보 받기는 아이의 이름만 가져오면 아이의 신장을 알 수 있기 때문에 input값은 하나만 넣으면 된다. 그리고 아이의 신장정보를 받아오기 위해 output값인 "uint"가 들어가고, " return height[_name]; " 이름값을 반환하면 신장값을 알 수 있다.

  • 정보 지우기는 아이의 이름만 가져오면 아이의 신장정보를 초기화할 수 있기 때문에 input값은 1개이고, 초기화시킬것이기 때문에 output값은 필요없다. 그리고 " delete height[_name]; " 을 입력하면 값을 초기화 할 수 있다.






✅머클트리.

  • 머클루트라는 이름으로 헤더에 올라간다.

  • 가장 중요한건 어떻게 지갑주소를 넣었을때 balance에 도착하는지가 중요하다.

    • 다양하고 복잡한 아이들이 많은데 어떻게 효율적으로 알고싶은 value값을 뱉어내는지.

  • 적은 개수가 있을때는 머클트리를 쓰면 되지만 그 수가 많아지면 for문을 너무 많이 써야한다.

  • 패트리시아 트리를 사용하는 근본적인 이유는 저장, 수정, 삭제, 검색을 효율적으로 빠르게 하기 위해서다.

  • 라딕스가 더 효율성이 좋아보이지만 마냥 그렇지만도 않다.
    • 새로운 정보가 들어왔을때 힘들어질 수 있다.

  • 중간 부분도 종착지가 있을 수 있다는걸 보여준다.

  • i라는 키값을 넣으면 11, inn이라는 키값을 넣으면 9, tea라는 키값을 넣으면 3이라는것을 알 수 있다.

  • 사람들이 아무리 늘어나더라도 일정범위 안까지는 검색기능을 제공을 해야한다는 생각을 하기시작.

  • 머클트리를 좀 더 고침(수정)함으로서 머클 패트리시아 트리가 제공되었다고 생각하면 된다.

  • 지갑주소나 mapping도 이런식으로 저장된다는걸 알 수 있다.

  • Radix Trie에 대한 고민을 좀 더 했다고 생각하고 보는게 좋다.
  • Extension Node = 표현할 수 있는 숫자가 상대적으로 적다.

    • 공통적으로 무언가가 있고, 그 다음에 나뉘어질때 Extension Node의 역할을 한다.
    • Extension Node 밑에는 항상 Branch Node가 있다.
  • Branch Node = 다른아이들에 비해 표현할 수 있는 숫자가 많다.

  • Leaf Node = 최종적으로 알고싶은건 value값이기 때문에 Leaf Node에서 확인할 수 있다. 사실상 끝부분.






🌜하루를 마치며..

오늘 배운 내용 정리하고 Struct부분 복습하고 다시 작성해보면서 시간을 보내니 금방 하루가 넘어가 버렸다..
오늘 배운 부분을 머리에 꾹꾹 누르고 내일 또 배울 내용을 넣을 공간을 만들어야 할텐데..
그래도 주말에 복습도 하고 예습도해서 오늘은 그래도 생각보다 어렵지 않게 마무리할 수 있었다.
그리고 종우님 덕분에 복습도 많이 할 수 있어서 너무 좋았다.
내가 종우님 상황이였다면 나는 정말 아무것도 못했을 것 같다.
종우님은 정말 멘탈이 강철멘탈이신 것 같다.
이런말 하면 안되지만 내일도 누군가 복습할 수 있는 시간을 만들어줬으면 좋겠다.. 😊

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

0개의 댓글