- 형변환에서 가장 중요한 부분은 정적, 동적인 부분을 아는것이다.
function bytesToString3(string memory _a) public pure returns(string memory) {
bytes memory _b = new bytes(1);
_b[0] = bytes(_a)[0];
return string(_b);
}
- 반복적인 연습이 중요.
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번째].요소이름
}
}
- 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;
}
*/
}
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이 좋다. (이름 = 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];
}
}
머클루트라는 이름으로 헤더에 올라간다.
가장 중요한건 어떻게 지갑주소를 넣었을때 balance에 도착하는지가 중요하다.
적은 개수가 있을때는 머클트리를 쓰면 되지만 그 수가 많아지면 for문을 너무 많이 써야한다.
패트리시아 트리를 사용하는 근본적인 이유는 저장, 수정, 삭제, 검색을 효율적으로 빠르게 하기 위해서다.
중간 부분도 종착지가 있을 수 있다는걸 보여준다.
i라는 키값을 넣으면 11, inn이라는 키값을 넣으면 9, tea라는 키값을 넣으면 3이라는것을 알 수 있다.
사람들이 아무리 늘어나더라도 일정범위 안까지는 검색기능을 제공을 해야한다는 생각을 하기시작.
머클트리를 좀 더 고침(수정)함으로서 머클 패트리시아 트리가 제공되었다고 생각하면 된다.
- Radix Trie에 대한 고민을 좀 더 했다고 생각하고 보는게 좋다.
Extension Node = 표현할 수 있는 숫자가 상대적으로 적다.
Branch Node = 다른아이들에 비해 표현할 수 있는 숫자가 많다.
Leaf Node = 최종적으로 알고싶은건 value값이기 때문에 Leaf Node에서 확인할 수 있다. 사실상 끝부분.
오늘 배운 내용 정리하고 Struct부분 복습하고 다시 작성해보면서 시간을 보내니 금방 하루가 넘어가 버렸다..
오늘 배운 부분을 머리에 꾹꾹 누르고 내일 또 배울 내용을 넣을 공간을 만들어야 할텐데..
그래도 주말에 복습도 하고 예습도해서 오늘은 그래도 생각보다 어렵지 않게 마무리할 수 있었다.
그리고 종우님 덕분에 복습도 많이 할 수 있어서 너무 좋았다.
내가 종우님 상황이였다면 나는 정말 아무것도 못했을 것 같다.
종우님은 정말 멘탈이 강철멘탈이신 것 같다.
이런말 하면 안되지만 내일도 누군가 복습할 수 있는 시간을 만들어줬으면 좋겠다.. 😊