반응형
solidity03_data_var

Solidity 03. Variables/Datatypes

변수를 어떻게 사용하는가?

  • 멤버 변수들은 Storage 변수. 상태 변수이다.
  • 파라미터들은 Memory 변수. 함수 리턴시 날라간다.
  • 파라미터에 Storage를 지정하면? 참조가 된다?

integer와 string을 get/set 하는 예제

pragma solidity >=0.4.0 <0.6.0;

contract SimpleStorage {
    uint storedData;
    string storedNm;

    function set(uint x) public {
        storedData = x;
    }

    function setNm(string memory x) public {
        storedNm = x;
    }

    function get() public view returns (uint) {
        return storedData;
    }

    function getNm() public view returns (string memory ) {
        return storedNm;
    }
}
  • 기본 자료형이 아닌 것은 저장소를 명시해 주어야 한다. string을 사용하는 부분에 memory 타입으로 명시함.

datatype

  • 기본형
    uint/int ; uint, int는 뒤에 256이 생략되어 있다. (u는 unsigned 의미)
    uint8~uint256 ; 여기서 숫자는 비트수를 의미. 1바이트부터 32바이트까지 있다.
    bool : true or false
    byte : uint8과 같다고 생각하면 된다.
    address : 20바이트 주소값
    address payable : address타입인데 멤버함수가 있다. transfer, send.
    address payable x = address(uint160(to));

enum State { Created, Locked, Inactive } ;
산술/비교/비트/논리 연산자는 C 와 같음. enum도 같다.

  • 참조형
    배열 : [] array
    구조체: struct
0xffff ; int16(-1)
0x42 ; bytes1(0x42)
0x0003 ; uint16(0x03)
0x48656c6c6f2c20776f726c6421 ; string("Hello, world!") (without null)

address의 멤버

  • balance ; 계정 주소에 있는 이더를 wei로 반환
  • transfer(uint amount) ; 계정 주소(받는 사람 주소)에 있는 amount 금액을 송금. to.transfer(_amount)
  • send(uint amount) returns (bool) ; 상동. 실패시 false 리턴. to_send(_amount)
  • call(…) returns (bool) : 상동, 실패시 false 리턴. 가스량 조절 가능. to.call.value(_amount).gas(1000000)() . 리턴값을 확인하여 false이면 revert()로 롤백한다.
  • delegatecall(…) returns (bool) : 다른 계약의 함수를 호출.
address x=0x123 ;
address myAddress = this ;
if (x.balance<10 && myAddress.balance>=10) x.transfer(10) ;
  • send : low-level의 transfer임. (실패시 롤백없음). 리턴값(true/false)을 반드시 확인.

고정크기 바이트 배열

bytes1/bytes2/bytes3/… bytes32 : bytes뒤에 숫자를 붙인다. 바이트수를 의미.
byte : bytes1과 같다.
멤버
length : 고정된 길이를 반환. 읽기 전용.
bytes32는 32바이트까지만 담을 수 있다.
ex)
bytes2 b = “bac”

동적 크기 바이트 배열

bytes : 임의 길이의 원시데이터.
string : UTF-8 인코딩 문자열. 임의의 길이. 거의 무제한.(2^256 * 256 비트)

  • 멤버로 length, push()가 있다.
  • 작은 따옴표나 큰 따옴표 상관없다.
    ex) bytes memory a = ‘aaaaaaaaaa’;
    a.length ;
    a.push(‘c’) ;
    a.push(“C”) ;
    a.push(“AB”) ; // error. byte[]라서 byte 하나만 push 가능.

문자열 리터럴

작은 따옴표, 큰 따옴표 둘 다 가능.
C랑 다르게 null terminated가 아니다. 보이는 문자 개수만큼만 메모리를 차지함.
\n, \xNN (16진수), \uNNNN (유니코드) 도 지원.

16진수 리터럴

hex"001122FF"
앞에 hex를 지정.

이중배열

uint [][5] : 주의할 점은 행과 열이 다른 언어와 반대임.
이것을 C로 보면 uint [5][] 이 된다.

  • 웃긴건 접근할 때는 C처럼 행, 열 순으로 접근한다.
  • 선언할 때랑 사용할 때랑 다르다니 문화충격이다.
uint[3][2] dArray ;
// row index는 0,1까지 가능. column index는 0,1,2까지 가능.
// C나 java로 치면 uint dArray[2][3] 으로 생각해야 함.
dArray[1][2] = 100 ;  // last element.

dArray[2][2] = 100 ; // error. 
dArray[0][3] = 100 ; // error. 
function f(uint len) public pure {
	uint[] memory a = new uint[](7) ;
	bytes memory b = new bytes(len) ;
	// a.length==7, b.length=len
	a[6]=8 ;
}
function f() public pure {
	g([uint(1), 2, 3]) ;
}
function g(uint[3] _data) pubilc pure {
}

[1,2,3] 은 uint8[3] memory 타입이다. array에 첫 번째 요소에 타입을 명시해 줄 수 있다.

  • 고정 크기 배열을 동적크기 배열에 할당할 수 없다.!
uint8[] memory x = [uint8(1),2,3] ;	// 에러
uint8[3] memory x = [uint8(1),2,3] ;	// 가능.

uint[] dArray ;
dArray.push(2) ;
dArray.push(3) ;
  • 삭제는 delete로 배열을 삭제한다.
  • 일반 변수에 delete를 하면 초기값(0)으로 할당된다.

자료구조

struct 지원

struct Voter {
uint w ;
bool v ;
address dele ;
uint vote ;
}

Enum Types

enum State { Created, Locked, Inactive }

Type Conversion

  • uint를 스트링으로 변환. 하나씩 바이트 단위로 ascii char로 변환한다.
function uintToString(uint v) constant returns (string str) {
        uint maxlength = 100;
        bytes memory reversed = new bytes(maxlength);
        uint i = 0;
        while (v != 0) {
            uint remainder = v % 10;
            v = v / 10;
            reversed[i++] = byte(48 + remainder);
        }
        bytes memory s = new bytes(i + 1);
        for (uint j = 0; j <= i; j++) {
            s[j] = reversed[i - j];
        }
        str = string(s);
}

function uint2str(uint i) internal pure returns (string)
{ 
	if (i == 0) return "0"; 
	uint j = i; 
	uint length; 
	while (j != 0){ length++; j /= 10; } 
	bytes memory bstr = new bytes(length); 
	uint k = length - 1; 
	while (i != 0){ bstr[k--] = byte(48 + i % 10); 
	i /= 10; 
	} 
	return string(bstr); 
}
  • 타입 캐스팅은 타입을 함수처럼 사용하여 파라미터로 받는다.
  • 32비트를 16비트로 타입 캐스팅시 하위 바이트(낮은 자리 값)만 가져온다.
  • 예를 들면. uint32 a= 0x12345678 ; 이것을 uint16 b = uint16(a) ; 이렇게 하면 하위 바이트인 0x5678을 가져온다.

Mapping

contract Mappings {
 struct User {
   string name ;
   string email ;
 }
 mapping(address => User) users ;
 function addUser(string memory _name, string memory _email) public {
   users[msg.sender].name = _name ;
   users[msg.sender].email = _email ;
 }
 function getUser() public returns (string memory, string memory) {
   return (users[msg.sender].name, users[msg.sender].email) ;
 }
}

이더리움 단위

wei ; 가장 작은 단위
1000 배씩 올라간다.
kwei, mwei, gwei, micro, milli, ether
kether, mether, gether, tether
위 단위를 코드에 그대로 사용한다.
즉, 1 이더는 10**18 wei

시간 단위

second, minute, hour, day, week, year

블록 및 거래 속성

  • block.blockhash(uint blockNumber) returns (bytes32) : 지정한 블록의 해시값을 리턴. (최근 256개 블록만 사용 가능)
  • block.coinbase ; address 채굴자 계정 주소
  • block.difficulty ; uint 현재 블록 난이도
  • block.gaslimit ; uint 현재 블록의 가스 제한량
  • block.number ; uint 현재 블록 번호
  • block.timestamp ; uint 현재 블록의 타임스탬프
  • msg.data ; bytes 호출 데이터
  • msg.gas ; 남은 가스양
  • msg.sender ; address 메시지를 보낸사람
  • msg.sig ; bytes4 calldata의 첫 4바이트로 함수 식별자
  • msg.value ; uint 메시지와 같이 보낸 wei
  • now ; block.timestamp와 같다. (현재 시간을 의미하는 값은 아니다. 현재시간과 대략 비슷)
  • tx.gasprice ; uint 거래의 가스가격
  • tx.origin ; 거래 발신자 주소. (sender.address와 같을 수도 다를 수도 있다.)
  • this ; 현재 계약
  • selfdestruct(address) ; 현재 계약을 파기해 지정한 주소로 금액을 보냄
  • suicide(address) ; 상동

예외 처리

  • assert(bool condition) ; 조건이 실패하면 에러를 발생시킨다. (보통 내부에러)
  • require(bool condition) ; 위와 같다. 입력값 체크시 사용. (보통 외부에러)
  • revert() ; 에러가 발생하면 롤백을 시킨다.

기타 연산

  • addmod(uint x, uint y, uint k) returns (uint) : (x+y)%k
  • mulmod(uint x, uint y, uint k) returns (uint) : (x*y)%k
  • keccak256( data ) returns (bytes32) : 이더리움 sha3 (KECCAK256) 해시
  • sha256
  • sha3 ; keccak256과 동일
  • ripecmd160(data) returns (bytes20)
  • ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) return (address) : 타원곡선암호서명에서 공개키와 연결된 주소를 리턴

할당

  • 복수 데이터를 할당 할 수 있다. 리턴도 복수개가 가능
    • (x,y) = f() ;
  • swap
    • (x,y) = (y,x) ;
  • 함수 파라미터를 이름대로 지정할 수 있다.
    • f(3, 2) 대신 f({value:2, key:3}) 이렇게 사용. (파라미터 이름)
    • new로 다른 계약을 만들 수 있다.

Author: crazyj7@gmail.com

'BlockChain' 카테고리의 다른 글

Solidity#2 HelloWorld  (0) 2019.12.06
Solidity 0.4 vs 0.5  (0) 2019.12.06
Windows Ethereum python module install error  (0) 2019.12.04
[ether02] 코인만들기  (0) 2019.11.10
[ether01] solidity 맛보기  (0) 2019.11.10

+ Recent posts