[TIL] 2023-05-17 DAY42
GIT 주소 : https://github.com/dowoo303/SOLIDITY
오늘 배운것들
- TEST3 풀이
1) 일반판
2) 확장판 - 컨트랙트 2개로 분리하여 서로 소통- TEST5
- TEST4 풀이 약간
각종 팁
function deposit() public payable {}: 돈받을 준비됐어!(단, 일반거래로는 못 받고 deposit함수를 실행해야만 받을 수 있어!) -> 그럼 CA가 일반거래로는 돈을 어떻게 받나? ->receive() external payable{}-> CA에게 돈을 받을 수 있는 방법을 가르쳐 줌
회고
- new사용법이나.. 형변환 방법들이나.. 예전에 다 배운 것들인데 활용을 못하고 있다. -> 복습 더 필요하다.
- 이 코드를 왜 사용하는지 정확히 설명할 수 있어야 한다. -> 역시나 복습 많이 필요하다 ..
20byte = 80bit = 16진수 자릿수 40
이더리움은 계정의 종류가 2가지 이다.
흔히 말하는 개인 지갑
개인키가 존재함
거래 종류가 3가지가 있다.
1) 다른 EOA 송수신 거래
2) Contract 호출 거래
3) Creation(컨트랙트 제작) 거래
흔히 말하는 스마트 컨트랙트로 스스로 거래를 일으키지 못한다.
개인키가 없음 -> 코드가 존재
nonce 값: 이때까지 거래한 횟수
컨트랙트와 소통
receive() external payable{}: CA가 돈을 받을 수 있게 만들어주는 코드이다.
강사님은 위 코드를 사용하지 않고 구성 = 즉, payable(this).transfer()를 사용하지않음.
✔ 개선할 곳들: 내 코드에는 transfer코드가 들어간 곳이 주유기능, 미리지불기능 두 곳에 들어가 있다. 주유기능에서는 require를 이용해서 걸러버리면 되고, 미리지불기능에서는 애초에 사용할 일이 없다.
초기 변수 선언
나는 차 상태관리 enum과 속도와 연료를 모두 각각의 상태변수로 관리한 반면, 강사님은 차 상태관리 enum을 만든다음 enum과 속도 연료를 하나의 구조체로 묶어서 관리했다.
세세한 차 동작관리
require을 이용하여 각 기능마다 차의 동작상태를 세세히 적어놨다. -> 물론 이 작업은 어느정도 코드를 완성시킨다음 생각해도됨.
확장판(컨트랙트 2개로 동작시키는법)
GASSTATION public gs;
constructor(address payable _a) {
gs = GASSTATION(_a);
}
위 코드를 통하여 gs를 GASSTATION의 인스턴스화 및 추적이 되도록 설정한다. 기본적으로 컨트랙트끼리의 상호작용을 확인할 수 있는 코드들도 구성되어 있다.
예전에 쓴 글 참고하면서 코드 고쳐봤다. 먼저 배열의 길이를 구하여 new를 통해 할당해줘야 아래 코드가 동작한다.
function hello(uint n) public pure returns(uint, uint[] memory) {
uint[] memory m;
uint a;
uint pre_n = n;
while (n != 0) {
n /= 10;
a++;
}
m = new uint[](a);
for(uint i=0; i<a; i++) {
m[(a-1) - i] = pre_n % 10;
pre_n /= 10;
}
return (a, m);
}
아래는 실패한 코드
function hello(uint n) public pure returns(uint, uint[] memory) {
uint[] memory m;
uint i;
while (n != 0) {
uint re = n % 10;
n = n / 10;
m[i++] = re;
}
return (i, m);
}
아래는 실패한 코드
function uintToStrings(string memory s) public pure returns(uint, string[] memory) {
uint count;
string[] memory a;
bytes memory len = bytes(s); // 먼저 문자열의 길이를 구한다.
bytes memory sLength = new bytes(len.length);
a = new string[](len.length);
for(uint i=0; i<len.length; i++) {
sLength[i] = bytes(s)[i];
a[i] = string(sLength[i]);
count++;
}
return (count, a);
}
bytes1 -> string 으로 변환 불가! 오류가 뜬다. -> sLength[i]는 bytes1이라 동적인 string으로 변환이 불가능하다는 것이다. 해결방법은 sLength[i]을 동적인 bytes로 다시 만들어 주는것이다.
function stringToStrings(string memory s) public pure returns(uint, string[] memory) {
uint count;
string[] memory a;
bytes memory len = bytes(s); // 먼저 문자열의 길이를 구한다.
a = new string[](len.length);
for(uint i=0; i<len.length; i++) {
a[i] = string(abi.encodePacked(bytes(s)[i])); // abi.encodePacked(bytes(s)[i]) -> bytes
count++;
}
return (count, a);
}
!TEST1 참조
abi.encodePacked를 이용하여 bytes(s)[i]를 bytes형으로 다시 변경한 다음 string[] a에 저장하여 출력해준다 !