오늘은
require
,constructor
,modifier
에 대해 배웠고 세번째 퀴즈를 봤다.
function Require1(uint _n) public pure returns(uint) {
require(_n < 10, "Input should be lower than 10.");
return _n*3;
}
uint a = 1;
function Require3() public {
bool c;
a = 5;
require(c, "error");
}
다음은 uint형 변수 a를 1로 상태변수로 선언해주었고
Require3
함수에서 a를 5로 바꾸었지만 require문에서 bool타입 변수 c의 초기값은 false이기 때문에 에러처리 됐다.
이 경우에는 require문 전에 a를 5로 바꾸는 것 또한 revert된다.
이 뿐 아니라 앞서 외부함수를 호출하는 것 또한 revert된다.
if문과의 차이점은 함수 끝까지 진행되지 않고 require에서 끊는다는 점이다.
따라서 가스비를 절약하는 장점이 있다.
생성자 함수는 선택적인 함수로, 계약 생성시 실행된다.
또한 생성자 함수는 한 컨트랙트에 하나의 생성자 함수만 선언이 가능하다.
address payable owner;
constructor() payable {
payable(this).transfer(msg.value);
owner = payable(msg.sender);
}
다음과 같이 생성자에도 payable이 붙을 수 있다.
이 생성자는 (this=현재 스마트컨트랙트 주소)로 msg.value만큼 이더를 보내는 생성자이다.
또한 아래에서 owner address 타입 변수를 msg.sender,즉 스마트컨트랙트에 이더를 보내는 주소로 설정한다.
modifier는 함수 제어자라고도 불리며 함수가 실행되기 전에 조건에 부합하는지 확인하고 함수가 실행되게끔 해주는 키워드이다.
uint a;
modifier lessThanFive() {
require(a<5, "should be less than five");
_; // 함수가 실행되는 시점
}
function doubleA() public lessThanFive {
a = a*2;
}
}
즉 다음코드 처럼 a가 보다 작을 경우 revert시키고 5보다 크면 doubleA함수를 실행할 수 있다.
_;
는 함수가 실행되는 시점을 나타낼 수 있다.
즉 require문이 끝나고 함수가 실행되는 방식의 코드이다.
contract MODIFIER {
struct Person {
uint age;
string name;
}
Person p;
modifier overTwenty(uint _age, string memory _criminal) {
require (_age >= 20, "not adult.");
require (keccak256(abi.encodePacked(_criminal)) != keccak256(abi.encodePacked("Bob")), "you are criminal!!");
_;
}
function getCigar(uint _age, string memory _name) public pure overTwenty(_age, _name) returns(string memory) {
return "passed.";
}
}
다음은 구조체를 선언하고 modifier overTwenty를 만들었다.
overTwenty
에는 age가 20이 넘으면 에러처리하고, name이 Bob일 경우 에러 처리하는 제어자이다.