Solidity

이민기·2022년 3월 13일
0
post-thumbnail
post-custom-banner

SPDX License Identifier

저작권 문제를 해소하기 위해 코드 최상단에 주석으로 명시

//SDPX-License-Identifier: MIT

Pragma

컴파일러의 버전을 표기할 때 사용하며, 자동으로 임포트되지 않음

pragma solidity 0.8.7;  //0.8.7버전 사용
pragma solidity ^0.8.7; //0.8.7이상의 버전 사용
  • Version 차이점
    차이점0.5 버전0.8 버전업데이트 버전
    배열의 length 권한length의 값을 변경하여 스토리지에 저장된 배열의 크기를 변경할 수 있다.length는 read-only0.6
    push(value) 반환값새로운 배열의 길이 반환아무것도 반환하지 않음0.6
    fallback 함수익명 함수 형태fallback과 receive 키워드를 사용해 fallback 함수를 지정할 수 있다.0.6
    now와 block.timestamp글로벌 변수 now가 블록의 생성 시간을 값으로 가진다.now는 deprecated되고, block.timestamp로 대체되었다.0.7
    UTF-8 지원-유니코드 문자열 지원한다. 문자열 앞에 unicode 키워드를 붙여 사용할 수 있다. (ex. uincode"Hello😀")0.7
    상태 변환성 키워드-pure와 view 키워드로 함수에서 일어나는 스토리지 CRUD 여부를 나타낸다.0.7
    누승법(exponentiation)왼쪽에서부터 파싱abc 연산은 (ab)c 순서로 수행된다.오른쪽에서부터 파싱abc 연산은 a(bc) 순서로 수행된다.0.8
    this, super, _모든 함수에서 사용 가능public 함수와 이벤트를 제외하고 사용 불가0.8
    address 타입과 address payable 타입address 타입 자체로 송금 가능한 주소 값address 타입 자체는 송금이 불가능한 주소 타입이며, address 타입을 payable(address 타입 변수) 로 변환하여야 송금 가능한 주소값 (address type)이 됨0.8
    글로벌 변수 tx.origin, msg.sender 타입address payable 타입송금이 안되는 address0.8

컨트랙트 구조

  • State Variables (상태변수) : 컨트랙트 스토리지에 영구적으로 저장되는 변수
    • 접근 수준 : 컨트랙트 안 상태변수를 선언할 때 지정할 수 있는 접근 수준을 표기
      • internal (default) : 컨트랙트 및 해당 컨트랙트를 상속받은 컨트랙트만 사용 가능
      • external : 해당 컨트랙내의 다른 함수에서만 실행이 불가능하며 외부에서 실행이 가능
      • public : 컴파일러가 퍼블릭 상태변수에 getter 함수를 생성, 퍼블릭 상태 변수는 컨트랙트 내에서 직접 상태변수 사용이 가능하며 외부 컨트랙트에서도 getter함수를 통해 접근 가능
      • private : 동일한 컨트랙트 멤버만 사용 가능
pragma solidity ^0.8.7;
contract exampleZ {
	uint public constant max = 1000;
        }

값형 데이터 타입

  • Bool
bool isOpen = true;
bool isOpen = false;
  • 정수
int8 temp = -20
uint16 age = 28
  • 고정바이트 배열
bytes2 number = '12'
            
number[0] // 1
number[1] // 2

Address

0x로 시작하는 최대 40자리의 16진수로 구성된 객체이며, 크기는 20바이트이다
계정의 잔액을 반환하는 balance()와 이더를 계정으로 전송하는 transfer()에서 자주 사용

// 0.8부터는 송금이 불가능
address mine = 0x8ec8AAC51ABcd6b208c2CFFBc05d2fc92b3CBEfD;
// 송금을 위해서는 address payable 사용
address payable p_mine = payable(mine);
  • 컨트랙트가 이더를 받을 수 있는 경우
contract A {
  constructor () payable { }
}
                
address payable p_cona = address(A); // address payable형식을 반환
  • 컨트랙트가 이더를 받지 않는 경우
contract B {
  constructor() { }
}
address conb = address(b); // address형식을 반환
address payable p_conb = payable(conb);

참조형 데이터 타입

배열처럼 데이터를 저장하는 영역에 연속되어 저장되어 있는 값의 첫번째 메모리를 참조하는 데이터 값

  • Memory : 프로그램이 동작하는 동안에만 기억
  • Storage : 블록체인에 기억되어 영구적으로 유지
  • 배열
uint[3] = {array1}  // 정적배열로 배열의 크기 지정 O
uint[] = {array2}   // 동적배열로 배열의 크기 지정 X
  • 문자열 : bytes와 동일하지만 length와 push()가 없다
string handphone = "iPhone"
  • 구조체 : 사용자 정의 형식
contract example{
  //정의
  struct User {
    address account;
    string username;
    uint age;
  }
  //추가
  function newUser (address newAddress, string newName, uint newAge){
  User memory newPerson = User({account: newAddress, username: newName, age: newAge})
  }
}
  • 매핑 : storage data영역에서 key-value구조로 저장할 때 사용
//mapping({키 형식} => {값 형식}) {변수명}
mapping(address => int)public userAddress;

글로벌 변수

  • block: 블록에 대한 정보
    • blockhash(uint blocknumber) : 주어진 블록의 해시를 bytes32로 반환
    • coinbase : 블록의 채굴자 주소 / address 형식
    • gaslimit : 블록의 가스 한도 / uint형식
    • number : 블록의 번호 / uint형식
    • timestamp : 블록 타임스탬프 / uint형식
  • msg : 컨트랙트를 시작한 트랜잭션 콜이나 메시지 콜에대한 정보
    • gasleft() : 남아 있는 가스의 양을 uin256형태로 반환
    • data : 전체 콜데이터의 본문 / bytes 형식
    • sender : 현재 호출을 수행하고 잇는 메시지의 발신자 / address 형식
    • gas : 남은 가스의 양 / uint 형식
    • value : 메세지와 함께 보낸 이더 금액 / uint 형식
  • tx : 트랜잭션 데이터
    • gasprice : 트랜잭션의 가스 비용 / uint형식
    • origin : 트랜잭션의 발신자 / address 형식
  • this : 현재 트랜잭션을 참조하며, 컨트랙트 주소로 암시적 변환

Functions

  • 함수 접근 수준 : 컨트랙트 안 함수를 선언할 때 접근 수준을 표기

    • external : 외부 컨트랙트나 클라이언트 코드에서 호출 가능하지만 내부는 호출 불가

    • public (default) : 컨트랙트 내부, 외부, 클라이언트 코드에서 호출 가능

    • internal : 컨트랙트 멤버와 상속된 컨트랙트만 호출 가능

    • private : 컨트랙트 멤버만 호출 가능

    • view : 상태변경이 안되는 읽기 전용 함수

      • => view로 만들어진 함수는 호출되어도 gas가 소모되지 않는다
    • pure : 스토리지에서 변수를 읽거나 쓰지 않는 함수

    • payable : 함수에서 이더를 받을 때 사용

    • constructor (생성자 함수) : 컨트랙트가 생성될 때 실행, 컨트랙트의 상태를 초기화할 때 사용

    • selfdestruct : 함수를 사용하여 컨트랙틀을 삭제

    //함수 선언
function funcName (파라미터 타입1, 파라미터1, ...) { ... }
function funcName (파라미터 타입1, 파라미터1, ...) ****returns 반환타입 { ... }

    **---------------------------------------------------------------------**
    
contract exampleFunc {
  uint public constant maxLimit = 2000;
  mapping(address => bool) public frozenAccount;
  address public account;
    
  constructor(address _account) internal { ... }
  function checkGas (uint256 amount) private pure returns (bool) {...}
  function changeName (address account,) internal view {...}
  function getEther() payable returns (bool) { ... }
}
    
selfdestruct(컨트랙트 생성자 주소)

Function Modifiers

함수 선언 시 함수에 변경자를 적용
변경자 : 함수를 실행하기 전, 조건에 맞는지 확인하는 작업 ⇒ 작성할 땐 _;를 사용

modifier changeNum {
  num++; // << anything실행 전 실행
  _;  // << anything 실행
  num--;  // << anything 실행 종료 후 실행
}
function anything() public changeNum {
  if(num != 1){ ... }
}

Interface

다른 컨트랙트와 상호작용을 위한 함수를 선언하며 함수 전체를 정의하기보다는 간략하게만 선언하므로 일반 함수처럼 {}를 사용하지 않는다

contract noMean {
	function changePlayer (string _name) public returns (string);
}    

Ingeritance

contract 객체는 상속을 지원하며, 다중 상속도 가능하다 ⇒ 사용시 is 사용

  contract ChildContract is ParentContract { ... }
  contract ChildContract is ParentContract1, ParentContract2 ... { ... }

Errors

에러처리는 assert, require, revert 함수 사용

  • revert : 해당 함수 종료 후 에러 리턴
  • require, assert : 설정한 조건이 참이면 진행하고 거짓이면 에러 리턴
// revert 예제
function buy(uint amount) public payable {
  if(amount > msg.value / 2 ether)
    revert("Not enough Ether Provided.");
}
----------------------------------------------------------------------
// require, assert 예제
function buy(uint amount) public payable {
  require(amount <= msg.value / 2 ether, "Not enough Ether Provided.");
  assert(amount <= msg.value / 2 ether, "Not enough Ether Provided.");
}

Enum Types

특정 값들로 집합을 만든 후 집합에 있는 데이터만 값으로 갖는다

//집합 지정
enum jobOf { doctor, programer, lawer }
//열거형으로 변수 선언
jobOf Bob = jobOf.doctor

Event

어떤 결과가 발생했을 때 해당 컨트랙트에서 dApp클라이언트, 또는 다른 컨트랙트에게 전달하며 이벤트 실행 시 트랜잭션에 기록

  • event : 이벤트 설정
  • emit : 이벤트 실행
contract coinTransfer {
  event Transfer(address from, address to, uint256 value);
  function transfer(address to, address amount) {
    emit Transfer(msg.sender, to, amount);
  }
}
profile
블로그를 옮기는 중입니다. https://min71.dev
post-custom-banner

0개의 댓글