솔리디티(Solidity) 문법 정리(1)

이준호·2022년 9월 20일
0

이더리움

목록 보기
1/1
post-thumbnail

한빛미디어에서 소스코드를 발췌했음

//SPDX-License-Identifier: UNLICENSED

pragma solidity >=0.4.11;
contract CrowdFunding {
	// 투자자 구조체
	struct Investor {
		address addr;	// 투자자의 어드레스
		uint amount;	// 투자액
	}
	
	address payable public owner;		// 컨트랙트 소유자
	uint public numInvestors;	// 투자자 수
	uint public deadline;		// 마감일 (UnixTime)
	string public status;		// 모금활동 스테이터스
	bool public ended;			// 모금 종료여부
	uint public goalAmount;		// 목표액
	uint public totalAmount;	// 총 투자액
	mapping (uint => Investor) public investors;	// 투자자 관리를 위한 매핑
	
	modifier onlyOwner () {
		require(msg.sender == owner);
		_;
	}
	
	/// 생성자
	constructor (uint _duration, uint _goalAmount) {
		owner = payable(msg.sender);

		// 마감일 설정 (Unixtime)
		deadline = block.timestamp + _duration;

		goalAmount = _goalAmount;
		status = "Funding";
		ended = false;

		numInvestors = 0;
		totalAmount = 0;
	}
	
	/// 투자 시에 호출되는 함수
	function fund() public payable {
		// 모금이 끝났다면 처리 중단
		require(!ended);
		
		Investor storage inv = investors[numInvestors++];
		inv.addr = msg.sender;
		inv.amount = msg.value;
		totalAmount += inv.amount;
	}
	
	/// 목표액 달성 여부 확인
	/// 그리고 모금 성공/실패 여부에 따라 송금
	function checkGoalReached () public onlyOwner {		
		// 모금이 끝났다면 처리 중단
		require(!ended);
		
		// 마감이 지나지 않았다면 처리 중단
		require(block.timestamp >= deadline);
		
		if(totalAmount >= goalAmount) {	// 모금 성공인 경우
			status = "Campaign Succeeded";
			ended = true;
			// 컨트랙트 소유자에게 컨트랙트에 있는 모든 이더를 송금
			if(!owner.send(address(this).balance)) {
				revert();
			}
		} else {	// 모금 실패인 경우
			uint i = 0;
			status = "Campaign Failed";
			ended = true;
			
			// 각 투자자에게 투자금을 돌려줌
			while(i <= numInvestors) {
				if(!payable(investors[i].addr).send(investors[i].amount)) {
					revert();
				}
				i++;
			}
		}
	}
	
	/// 컨트랙트를 소멸시키기 위한 함수
	function kill() public onlyOwner {
		selfdestruct(owner);
	}

    // 현재 얼마가 있는지 알기 위한 함수
    function getBalance() view public returns(uint) {
        return address(this).balance;
    }
}

위 코드를 실행하고 싶을 경우 Remix IDE를 사용하면 된다.

Address(주소)

블록체인에서 주소의 의미는 계좌와도 같다.
Bob 에게 1 eth를 송금하기 위해서는 Bob의 EOA(Externally Owned Account)를 알아야한다.

  • 솔리디티에서는 msg.sender로 계약을 시도한 사용자의 address를 가져올 수 있다.
  • address 타입에 payable 키워드를 붙이면 출금이 가능하게 된다. 최근 솔리디티에서는 payable을 꼭 쓰지 않아도 되지만 안쓰는 경우 송금할 때는 type converting이 필요하다. (ex. owner.send() 함수)

constructor(생성자)

다른 언어의 생성자와 동일하다. 이전 코드에서는 function 클래스명으로 생성자를 정의했지만 최근에는 constructor (param1, param2 ...) {...}로 정의한다.

onlyOwner

	function kill() public onlyOwner {
		selfdestruct(owner);
	}

이 함수는 스마트 컨트랙트를 시작한 (이후에 변경된 경우 변경된 사람이 소유권을 가짐) owner 이외에는 실행 할 수 없다.

storage & memory

필드에 선언한 변수들 이외의 매개변수, 함수 내의 지역변수 등은 메모리 관리를 위해 storage, memory 키워드를 붙여줘야 한다.

  • storage: 이전 함수 호출에서 저장했던 데이터에 접근할 수 있다.
  • memory: 함수가 끝나면 memory를 반환한다.

주로 파라미터에는 memory 키워드를 사용하고 지역 변수의 경우 storage를 사용한다.
더 자세한 내용

mapping(typeA=>typeB)

다른 언어들의 map과 유사하지만 솔리디티에서는 key의 타입을 A로 value의 타입을 B로 지정하는 것이다

profile
코딩 조아

0개의 댓글