// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
contract Counter{
// 1이더를 내면 숫자를 올릴 수 있는 로직
// 트랜잭션을 최초로 만든 EOA는 리셋하고 출금할 수 있다
// 1. DATA
// * value : private
// * owner - 계정주 : public
// 2. ACIIONS
// * getValue : public 사람들이 온체인에서 데이터를 가져올 수 있도록
// * increment - 돈을 내야함, 숫자를 올린 기록 : 상태 변경 함수, 이더를 내면 모두가 호출할 수 있음, 데이터 + payment 둘 다 필요 : public, payable
// * reset - value = 0, 리셋했다는 기록, owner만 실행할 수 있는 함수 - 제약조건이 까다로운 누구나 호출할 수 있는 함수 : public, but owner만 호출 가능
// 컨트랙트를 최초로 만든 사람, 계정주를 알아야 함
// 컨트랙트의 주인이라는 걸 컨트랙트로 구현필요,
// * withdraw - 출금 : public, owner만 호출 가능, private으로 하면 아무도 실행할 수 없게 됨
// internal external public private 차이
// 스토리지 저장은 비싸기 때문에 로그에 저장한다
// 3. EVENTS
// * Reset기록을 한 번에 조회할 수 있게 함
// 함수 종류
// view - storage를 읽기만 하고 변경은 안 함
// pure - storage를 아예 읽지 않는 함수, 연산, 스토리지와 관련 없음을 의미
// constant - 상수를 리턴,
// payable - 함수의 동작 결정, 이더를 받는다~
// 상태를 변경하는 것 = view는 아님
// payable - 받을 수 있다 ㅇ, 받아야 한다 x
// 이더리움 account 구성
// address = 0x1, 0x2, ...
// account = {nonce, balance, storageRoot, codeHash} 코드 해시가 비어있으면 EOA 있으면 CA
// 1) global variable : msg(컨트랙트가 컨트랙트를 호출, eoa가 컨트랙트를 호출, .. ) msg.sender(owner가 됨), msg.value(메세지가 담고있는 이더의 양)
// 2) Error : assert, revert, require (많이 씀)
// 이더를 전송하는 방법 : address.transfer, address.send, address.call
// transfer는 오류 생길시 transaction revert
// send -???
// call = 함수 실행, {gas: , value: }식으로
uint private value = 0;
address public owner;
// constructor : 컨트랙트 생성시 딱 한 번만 수행됨, 여기서 owner를 지정한다
constructor() {
// 이게 생성될 떄 메세지를 보낸 사람 = owner가 됨
owner = msg.sender; // 이 트랜잭션 매세지를 최초로 서명하기 위한 계정
}
modifier onlyOwner() {
require(msg.sender == owner, "only owner!");
_;
}
event Reset(address owner, uint currentValue);
function getValue() public view returns (uint) {
return value;
}
function increment() public payable {
require(msg.value == 1 ether, "1 Ether"); //1 이더일때만 실행 , 에러메세지
value = value + 1;
}
function reset() public onlyOwner {
emit Reset(msg.sender, value); // 이벤트 로그 보기
value = 0;
}
function withdraw() public onlyOwner {
// address -> payable address로 변경, 현재 밸런스 값의 이더를 보낸다
// address(this) 컨트랙트의 주소
payable(owner).transfer(address(this).balance);
}
// 트랜잭션 receipt = 트랜잭션 로그가 인코딩 되어 들어
}
이더리움에서 데이터 저장하는 방식
1. stroage에 저장 - 컨트랙트 변수 선언하는 경우
2. 로그
dune - 온체인 데이터 플랫폼
TX - 트랜잭션
1) invocation
트랜잭션을 생성하는 데 데이터가 있는 것
보통의 함수 호출
2) payment
이더 전송, 데이터는 없고 pay만 함
둘 다 있는 예시 - 민팅