스마트 컨트랙트 만들면서 배운 내용
Solidity 기본사항
- Solidity에서 세미콜론 없으면 오류
- 객체지향 프로그래밍 언어(OOP)
분해해서 보기전 전체 코드 😓
Buy Me a Coffee를 블록체인위에 만드는 간단한 스마트 컨트랙트
분해하기 전 예시
pragma solidity ^0.8.0;
contract BuyMeABubbleTea {
event NewMemo(
address indexed from,
uint256 timestamp,
string name,
string message
);
struct Memo{
address from;
uint256 timestamp;
string name;
string message;
}
Memo[] memos;
address payable owner;
constructor() {
// 컨트랙트 배포한 메타마스크 주소, solidity msg 변수 사용
owner = payable(msg.sender);
}
function buyBubbleTea(string memory _name, string memory _message) public payable {
require(msg.value > 0, "Can't buy bubble tea with 0 ETH");
memos.push(Memo(
msg.sender,
block.timestamp,
_name,
_message
));
emit NewMemo(
msg.sender,
block.timestamp,
_name,
_message
);
}
function withdrawTips() public {
require(owner.send(address(this).balance));
}
function getMemos() public view returns(Memo[] memory){
return memos;
}
}
코드 분해 돌입
1. pragma
Solidity는 버전 pragma로 시작되어야 한다.
Solidity 컴파일러 버전을 알려주는 것
다음 예시는 최소 0.8.0 이상 컴파일러가 사용된다는 말인듯
pragma solidity ^0.8.0;
2. contract
객체지향(Object-oriented) 언어의 클래스와 비슷하다고 한다.
이 contract 키워드 안에 계약서를 작성한다
contract BuyMeABubbleTea {
// 함수들!
}
3. event
다른 프로그래밍 언어와 같은 이벤트. 실행되면 트랜잭션 로그에 전달된다.
작성한 event를 emit하면,
event 안에 있는 로직이 실행되고 저장된다고(블록의 트랙잭션에) 생각하고 넘어가자
event NewMemo(
address indexed from,
uint256 timestamp,
string name,
string message
);
emit NewMemo(
msg.sender,
block.timestamp,
_name,
_message
);
4. struct
사용할 데이터의 타입을 정의해서 구조(struct)를 만든다.
접근할 때는 객체 접근하듯 dot(.) 문법 사용한다
밑의 예시는
- Memo 구조 만들고
- 받은 메모 전체 저장할 배열 만들고 memos
- 받은 메모를 memos에 저장
struct Memo{
address from;
uint256 timestamp;
string name;
string message;
}
Memo[] memos;
memos.push(Memo(
msg.sender,
block.timestamp,
_name,
_message
));
5. address & address payable
Solidity 데이터 타입으로 주소를 나타낼 때 사용한다.
이더리움 주소 사이즈인 20 byte 값을 갖는다
address와 address payable의 다른 점은 Ether를 보낼 수 있는지 여부다
address payable로 선언된 주소에는 Ether를 보낼 수 있지만, address로는 안된다.
예시
owner로는 Ether 보낼 수 있지만, customer로는 안된다.
address customer;
address payable owner;
6. constructor
스마트 컨트랙트의 초기 값(상태)를 지정하는 함수로 만들어질 때 한 번만 실행된다.
한글로 생성자라고도 불리며 다른 언어의 constructor 비슷하다
owner를 msg.sender 주소로 초기화하는 예시
constructor() {
owner = payable(msg.sender);
}
7. msg.sender
직접적인 의미는 메시지를 보낸 사람이다.
정확히는, Solidity 컨트랙트에서 어떤 함수를 호출했다면, 이 컨트랙트는 내 계정을 갖게된다.
이 상황에서 msg.sender는 이 함수를 호출한 내 계정이 된다.
Ether를 받을 수 있는 내 계정을 owner에 할당하는 예시
owner = payable(msg.sender);
8. function public
public이 붙으면 컨트랙트 내부와 외부 모두에서 사용할 수 있다
function buyBubbleTea(string memory _name, string memory _message) public payable {
// 로직
}
9. require()
조건문으로 true일 때만 다음 코드로 넘어간다. 아니면 에러를 던진다
에러 내용을 적어줄 수도 있다.
require(msg.value > 0);
require(msg.value > 0, "Can't buy bubble tea with 0 ETH");
10. .send
Ether를 보내는 방법 중 하나.
boolean 값을 리턴한다.
require과 함께 쓰면 잘 안보내졌을 때 에러를 던질 수 있다
require(owner.send(address(this).balance));
11. view
함수를 읽기전용(read-only)으로 만들어준다.
그냥 메모 변수를 읽기만 해서 리턴을 해주는 함수 예시
function getMemos() public view returns(Memo[] memory){
return memos;
}
참고 링크
=> https://docs.soliditylang.org/en/v0.8.14/contracts.html
=> https://www.geeksforgeeks.org/what-is-smart-contract-in-solidity/
=> https://www.geeksforgeeks.org/what-are-events-in-solidity/
=> https://www.geeksforgeeks.org/solidity-enums-and-structs/
=> https://docs.soliditylang.org/en/v0.8.12/types.html#address
=> https://www.tutorialspoint.com/solidity/solidity_constructors.htm
=> https://stackoverflow.com/questions/70799103/what-is-the-use-of-msg-sender-in-solidity
=> https://www.geeksforgeeks.org/solidity-view-and-pure-functions/
=> https://medium.com/coinmonks/solidity-transfer-vs-send-vs-call-function-64c92cfc878a
=> https://dayone.tistory.com/7
'Web Dev > Web3' 카테고리의 다른 글
Web3 :: 10주 챌린지 1주 - 스마트 계약서 작성, 첫 NFT 민트 (0) | 2022.05.11 |
---|---|
Web3 :: 웹3 10주 챌린지 뭘 배울까? (0) | 2022.05.05 |
Web3 :: Blockchain developer roadmap (0) | 2022.02.25 |