본문 바로가기
전공공부/블록체인공학

Solidity - 배열 및 데이터삭제, 타입 캐스트

by 으노으뇨 2021. 11. 15.
728x90
반응형
SMALL

1) 개요

배열

자료형이 같은 데이터를 같은 이름으로 묶은 자료 구조

종류

정적 배열 배열 요소의 크기를 지정
예) uint[5] test;
동적 배열 배열 요소의 크기를 지정하지 않고 동적으로 변환
uint[] test;
PUBLIC 배열 동적배열의 경우, 다른 계정에서, 배열을 읽을 수 있도록 지정
예) uint[] public test;

자료형을 쓰고 [ ] 를 이용해서 배열을 만들 수 있다.


2) 표현

  • 자료형[크기] 배열이름 ;
  • 자료형[] 배열이름;
  • 자료형[] public 배열이름
SMALL
예제
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.10;

contract Arrayval {
 uint [5] test1; //정적배열
 uint [] test2; //동적배열
 uint [] public test3; //public 배열
 
}

 


3) 배열의 초기화

  • 자료형[크기] 배열이름 = [',' 로 구분하여 원소 나열]
  • 배열이 지역변수 (함수 안에서 사용하는 배열)인 경우 - 선언과 동시에 값 입력 불가
예제
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.10;

contract Arrayinit {
  uint [3] a1 = [1,2,3]; //정적배열 초기화
  uint [] a2 = [1,2,3]; //동적배열 초기화
  
}
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.10;

contract Fucntioninit {
    uint []a=[1, 2,3];

    function ex1() public pure {
        uint[]b = [1, 2,3]; //지역변수로 배열을 초기화 핼끼에 error 발생
    }
}

4) 저장위치

스토리지에 저장되는 배열 memory키워드를 붙이지 않으면 보통 스토리지에 저장
상태변수는 대부분 스토리지에 저장이 된다.
상태변수는  new 키워드를 붙여 메모리에 저장되는 동적 배열 생성기능
메모리에 저장되는 배열 memory 키워드를 붙여 생성
new 키워드를 붙여 동적 배열 생성
예제
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.10;

contract Storage {
    uint []a; // 스토리지에 저장

    function ex1() public pure {
        uint[] memory b;//메모리에 저장
    }

}

스토리지에 a라는 배열을 저장했는데 휘발성으로 배열 b를 만들어서 사용하고싶을땐 memory를 붙여서 메모리에 저장시키자, 그런데 상단의 상태변수일땐 불가하다.

예제
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.10;

contract Storage2 {
    uint []a; // 스토리지에 저장
    uint []b= new uint[](2); // 메모리에 저장

    function ex1(uint len) public pure {
        uint []memory d; // 메모리에 저장
    }
}

이때 new라는 걸 이용해서 b에 2만큼 메모리가 저장될 수 있게끔 했다.

즉 상태변수에서는 위처럼 new를 붙여주어 메모리에 저장시켜주는 방법이있다.

함수 안의 지역변수는 memory로 가능하다.

예제
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.10;

contract Storage3 {
    uint []a; // 스토리지에 저장
    uint []b= new uint[](2); // 메모리에 저장

    function ex1(uint len) public pure {
        uint []memory d; // 메모리 저장
        uint []memory e = new uint[](10); // 메모리에 저장
        e[1] = 10;
    }
}

함수 ex1안에서 메모리에 저장키위해 new와 memory를 같이사용해도 문제가 없다.

메모리에 저장되면 휘발성으로 저장되어 가스소모를 하지않는다. 그래서 단발적으로 활용해야한다면 사용할때 좋다.


5) Index

  • 0부터 시작
  • index 사용 : a[0], a[1] ...

6) 지원하는 함수

length 배열의 길이를 저장
push 동적배열에서만 사용
배열이 마지막에 값 추가
예 ) a.push(3)
예제
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.10;

contract Functionpush {
    uint []a; // 동적배열, 스토리지에 저장

    function ex1() public view returns (uint) { // view 사용해야함을 유의
        a.push(2); // 배열 a에 값 추가
        a.push(3); // 배열 a에 값 추가
        return a.length; // 배열 a의 길이 반환
    }
}

상태변수로 동적배열을 스토리지에 저장했다.

함수를 이용해 2와 3을 a에 추가해주었다.

그리고 해당 배열의 길이를 반환하는 계약이었고, 결과는 옳게 나왔다.

예제
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.10;

contract Functionpush {
    uint []a; // 동적배열, 스토리지에 저장

//    function ex1() public view returns (uint) { // view 사용해야함을 유의
//        a.push(2); // 배열 a에 값 추가
//        a.push(3); // 배열 a에 값 추가
//        return a.length; // 배열 a의 길이 반환
//    }
    function ex1() public view returns (uint) { // view 사용해야함을 유의
        a.push(2); // 배열 a에 값 추가
        a.push(3); // 배열 a에 값 추가
        return a; // 배열 a 반환
    }
}

이는 a배열을 반환하는 함수이다. 

2와 3이 출력되는 것을 볼 수 있었다.


7) 데이터 삭제

  • 값을 초기화 할 때 사용
  • 해당 값을 0으로 초기화하는 것이다.
 예제
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.10;

contract Delete {
    uint data = 1;
    uint []dataArray;

    function t1() public {
        uint x = data;
        delete x;
        //x를 0으로 초기화함
    }
}

8) 타입 캐스트

  • 변수의 자료형(타입)을 변경할 때 사용
  • 크기가 작은 타입의 값을 큰 타입 값으로 타입 캐스팅 가능
  • 크기가 큰 타입의 값을 작은 타입의 값으로 캐스팅하면 원본이 훼손될 수 있음
자료형 변수 = 변경할 자료형(변수);

예시 ) int8 a = -1;    ->    uint8 b = uint8(a);

 


해보기!!!!
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.10;

contract Storage3 {
   uint[] public values;
   
   function addVal(uint value)public{
       values.push(value);
   }
   function count() public view returns(uint){
       return values.length;
   }
}

우선 uint[] values를 선언할때 public을 사용하였다 .그리고

addVal을 보면 view나 퓨어가 적혀있지않다. 이는 실제 거래가 일어날수 있는 경우이므로, 참고만하는 것이아닌 내용수정도 가능하다. - 트랜잭션이 가능한 함수 

그래서 현재 함수에서 거래가 발생하게되면 브로드캐스트가 되고, 계약을 체결하는데 사용이 되고, 

가스도 거래를 위해 충분히 발생이 된다. 

이게 만약 Remix가 아니고 실제 거래라면 트랙잭트를 하면 거래가 발생할 수 있다.

예제
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.10;

contract Arrayex {
    // 고정 배열
    uint[5] tmp1 = [1, 2,3,4,5];
    // 동적 배열
    uint[] tmp2;

    function a() public view returns (uint) {
        uint res = 0;
        for (uint i=0;i < tmp1.length;i++) {
            res = res+tmp1[i];
        }
        return res;
    }

    function by() public view returns (uint) {
        tmp2.push(1);
        tmp2.push(2);
        uint sum =0;
        for (uint  i = 0 ; i < tmp2.length ;i++) {
            sum = sum +tmp2[i];
        }
        return sum;
    }
}

for문을 통해 tmp2에 값들을 tmp1에 값을 통해 더해진 값을 넣었다.

 

728x90
반응형
LIST

댓글