[멋쟁이 사자처럼 블록체인 스쿨 3기] 23-05-22

임형석·2023년 5월 23일
0

Solidity


fixed array 다루기

만약, 다음과 같은 함수가 있다면, B 에는 4개의 요소만 들어갈 수 있을 것이다.

    uint[4] public b;
    uint count;

    function pushB2(uint _a) public {
        b[count] = _a;
        count++;
    }

이미 상태변수에서 [4] 네 자리임을 선언했기 때문이다.

그렇다면, 4개의 요소로 상태변수 B 에 가득 차게되었을 때,

B 를 초기화하고 새로 입력하는 값을 0번째 요소로 넣는 함수를 써보면 다음과 같다.

    uint[4] public b;

    function pushB(uint _a) public {
        require(_a !=0);
        if(getLengthOfB()==4) {
            delete b;
        }
        
        b[getLengthOfB()] = _a;
    }
    
    function getLengthOfB() public view returns(uint) {
        for(uint i=0; i<4; i++) {
            if(b[i]==0) {
                return i;
            }
        }
        return 4;
    }

먼저, 배열의 자릿수를 구해주는 함수를 만들고 자릿수가 가득 찼다면 배열을

Delete 로 초기화 해주고, 다시 0번째 배열부터 요소를 넣는 것이다.

이렇게 하면 배열의 길이도 추적할 수 있을 뿐만 아니라, 길이를 초과하면

배열을 초기화하고 새로운 요소를 넣을 수 있다.


byte20 , address

byte20 형은 16진수 값이 40자리가 들어갈 수 있다.

address 형은 이더리움의 주소형태로, 16진수 40자리 주소의 형태이다.

그래서 두 형태는 같은 자릿수가 정의되있으므로, 서로 변환시킬 수 있다.

다음과 같이 byte20 a, address b 를 선언한 컨트랙트를 작성했다.

contract AA {
    bytes20 a;
    address b;

    constructor() {
        b = msg.sender;
    }

    function AAA() public view returns(address) {
        return address(a);
    }

    function AAB() public view returns(bytes1) {
        return bytes20(b)[0];
    }
}

이 컨트랙트에서 AAA 함수를 호출하면, 0x 로 시작하는 40자리의 빈값이 나온다.

AAB 함수를 호출하면, msg.sender 의 주소. 즉, 컨트랙트를 배포한 내 지갑주소의 앞 2자리를 반환한다. 아래 사진에서 확인 가능하다.


multi mapping

mapping 은 key 와 value 쌍으로 이루어진 형태이다.

예를들어, 학생의 숫자와 이름을 key & value 쌍으로 묶는 mapping 을 선언하면 아래와 같다.

mapping(uint => string) student;

그리고 아래와 같은 방법으로 숫자 1은 "hyeongseok" 이라는 key value 쌍을 지정해줄 수 있다.

student[1] = "hyeongseok";

mapping 에도 struct 형태와 address 같은 다른 형태들도 사용이 가능하다.

그리고 mapping 안에도 mapping 이 가능하다. (multi mapping)

하지만, struct 형은 value 값으로만 가능하다. struct 엔 여러 형태의 값이 들어가 있기에, key 로 사용할 수 없다.

예시)

uint[] A;

mapping(string => A) 불가능
struct A{
	uint a;
   string b;
}

mapping(string => A) 가능
 

[주소 => 문자 => 숫자] 형태의 double mapping 을 사용해보면 아래와 같다.

	mapping(address=>mapping(string=>uint)) bankAccounts;

  	function setbank(string calldata _name) public {
       bank[msg.sender][_name] = 100;
   }

double mapping 뿐 아니라, 그 이상의 multi mapping 도 가능하며, struct 형태도 value 값으로 지정이 가능하다.

문자 => 문자 => 숫자 => 유저(struct) mapping

    struct user {
       uint number;
       string name;
   }

   user B;

mapping(string=>mapping(string=>mapping(uint=>user))) bankAccounts3;

    function setBankAccounts2(string calldata _city, string calldata _state, uint number) public {
       bankAccounts3[_city][_state][number] = B;
   }

만약 다음과 같이 struct 형태를 key 로 설정하려고 코드를 작성할 경우, 아래와 같은 오류메시지를 볼 수 있다.

mapping(address=>mapping(user=>uint)) structmapping;

기본적인 type, 사용자가 정의한 type, contract , enum 만 key 값으로 지정이 가능하다. 라는 오류메시지다.

그래서 contract , enum 을 key 값으로 지정해보았다.

contract abc{

    enum food {
        chicken,
        pizza,
        water
    }

    mapping(address=>mapping(abc=>uint)) contractmapping;
    mapping(address=>mapping(food=>uint)) enummapping;
}

contract test{
    uint public a = 4;
}

struct 와는 다르게 정의가 가능하다.


0개의 댓글