본문 바로가기

블록체인/크립토 좀비

[크립토 좀비] 레슨02 정리

 

크립토 좀비의 솔리디티 버전은 0.4.19 이므로 현재 최신 버전과는 다른 점이 있을 수 있습니다. 솔리디티 공식문서 한국어

 

mapping 

키와 밸류로 이루어진 집합체이다. 자료구조의 해시 테이블과 같다. 

선언

mapping(uint => string) name;

uint이 키 값이고 string이 밸류로 사용된다. 

사용 예시

 

name[26] = "satoshi";

 

address

블록체인에서 사용자의 지갑 주소는 필수이다. address는 지갑 주소를 나타내는 자료형이다. 

 

예시

address target = 0x0cE446255506E92DF41614C46F1d6df9Cc969183;

 

msg.sender

msg.sender는 컨트랙트를 호출한 사용자의 지갑 주소를 가리킨다. 

counts[msg.sender] = 10;

 

Require

함수가 실행될 때 require의 조건식이 참이 아니라면 함수가 바로 종료된다.

function sayHiToVitalik(string _name) public returns (string) {
  // _name이 "Vitalik"인지 비교한다. 참이 아닐 경우 에러 메시지를 발생하고 함수를 벗어난다
  require(keccak256(_name) == keccak256("Vitalik"));
  // 참이면 함수 실행을 진행한다:
  return "Hi!";
}

 

상속

상속은 상속받는 자식 컨트랙트가 부모 컨트랙트의 구성 요소 중 private 가 아닌 모든 상태 변수, 함수에 접근 가능하다.

contract Doge {
  function catchphrase() public returns (string) {
    return "So Wow CryptoDoge";
  }
}

contract BabyDoge is Doge {
  function anotherCatchphrase() public returns (string) {
    return "Such Moon BabyDoge";
  }
}

 

Storage vs Memory

storage는 블록체인 상에 영구적으로 저장되는 변수, memory는 임시적으로 저장되는 변수로 컨트랙트 함수에 대한 외부 호출들이 일어나는 사이에 지워진다. 

일반적으로 함수 외부에 선언되는 변수(상태 변수)는 자동적으로 storage로 선언되며 함수 내부에서 선언되는 변수는 memory로 선언된다. 

하지만 함수 내부에서 구조체나 배열을 처리할 때는 이 키워드들을 신경 써서 사용해야 한다. 

contract SandwichFactory {
  struct Sandwich {
    string name;
    string status;
  }

  Sandwich[] sandwiches;

  function eatSandwich(uint _index) public {
    // Sandwich mySandwich = sandwiches[_index];

   
    // `storage`나 `memory`를 명시적으로 선언해야 한다는 경고 메시지를 발생한다. 
    // 그러므로 `storage` 키워드를 활용하여 다음과 같이 선언해야 한다.
    Sandwich storage mySandwich = sandwiches[_index];
    // ...이 경우, `mySandwich`는 저장된 `sandwiches[_index]`를 가리키는 포인터이다.
    // 그리고 
    mySandwich.status = "Eaten!";
    // ...이 코드는 블록체인 상에서 `sandwiches[_index]`을 영구적으로 변경한다. 

    // 단순히 복사를 하고자 한다면 `memory`를 이용하면 된다: 
    Sandwich memory anotherSandwich = sandwiches[_index + 1];
    // ...이 경우, `anotherSandwich`는 단순히 메모리에 데이터를 복사하는 것이 된다. 
    // 그리고 
    anotherSandwich.status = "Eaten!";
    // ...이 코드는 임시 변수인 `anotherSandwich`를 변경하는 것으로 
    // `sandwiches[_index + 1]`에는 아무런 영향을 끼치지 않는다. 그러나 다음과 같이 코드를 작성할 수 있다: 
    sandwiches[_index + 1] = anotherSandwich;
    // ...이는 임시 변경한 내용을 블록체인 저장소에 저장하고자 하는 경우이다.
  }
}

 

함수 접근 제어자( Internal va External)

internal 은 정의된 컨트랙트 내부(상속받는 컨트랙트 포함)에서만 접근 가능

external은 컨트랙트 내부에서 호출 불가하고 외부(다른 컨트랙트)에서만 접근 가능하다.

contract Sandwich {
  uint private sandwichesEaten = 0;

  function eat() internal {
    sandwichesEaten++;
  }
}

contract BLT is Sandwich {
  uint private baconSandwichesEaten = 0;

  function eatWithBacon() public returns (string) {
    baconSandwichesEaten++;
    // eat 함수가 internal로 선언되었기 때문에 여기서 호출이 가능하다 
    eat();
  }
}

인터페이스

인터페이스는 구조체, 함수와 같은 것을 선언을 할 수 있지만 몸통을 가질 수 없다.  인터페이스의 선언에는 규칙이 있다. 

  • 함수는 external로 선언되어야 한다.
  • 생성자를 선언하지 못한다.
  • 상태 변수를 선언하지 못한다.

위의 규칙을 따른다면 인터페이스는 함수와 구조체 그리고 enum을 가질 수 있다. 

pragma solidity >=0.4.11 <0.6.0;

interface Token {
    enum TokenType { Fungible, NonFungible }
    struct Coin { string obverse; string reverse; }
    function transfer(address recipient, uint amount) external;
}

함수에서 다수의 값을 반환

 

unction multipleReturns() internal returns(uint a, uint b, uint c) {
  return (1, 2, 3);
}

function processMultipleReturns() external {
  uint a;
  uint b;
  uint c;
  // 다음과 같이 다수 값을 할당한다:
  (a, b, c) = multipleReturns();
}

// 혹은 단 하나의 값에만 관심이 있을 경우: 
function getLastReturnValue() external {
  uint c;
  // 다른 필드는 빈칸으로 놓기만 하면 된다: 
  (,,c) = multipleReturns();
}

 

조건문 

if, else if, else 가 있는데 다른 언어와 큰 차이점 없이 사용 가능하다.

function conditionExample(uint _a) {
  if(_a > 10) {
    ...
  }
  else if( _a > 5) {
    ...
  }
  else {
    ...
  }
}

'블록체인 > 크립토 좀비' 카테고리의 다른 글