require
:조건이 충족되지 않으면 예외를 발생하고 함수 실행을 중단, 예외 메시지를 함께 출력가능
function require(uint _n) public pure returns(uint){ require(_n < 10, "error"); return _n; }
assert
:조건이 충족되지 않으면 예외를 발생하고 함수 실행을 중단한다. 예외 메시지 출력 가능. 가스를 소모하지 않고 일반적으로 불변식을 검증하는데 사용된다.
function transfer(address _to, uint256 _value) public { require(_value <= balances[msg.sender], "insufficient balance"); require(_to != address(0), "invalid address."); balances[msg.sender] -= _value; balances[_to] += _value; assert(balances[msg.sender] + balances[_to] == previousBalances); // 불변식 검증 emit Transfer(msg.sender, _to, _value); } //emit:solidity에서 event를 발생 시키는 키워드ㅡ
revert
:예외를 발생시키고, 상태를 롤백한다. 예외 메세지 출력가능
function transfer(address _to, uint256 _value) public { require(_value <= balances[msg.sender], "Insufficient balance."); require(_to != address(0), "Invalid address."); balances[msg.sender] -= _value; balances[_to] += _value; emit Transfer(msg.sender, _to, _value); if (balances[msg.sender] == 0) { revert("Balance cannot be zero."); } }
- balances[msg.sender]가 0이 되는 경우 예외를 발생, 상태를 롤백한다. -> 이전 상태로 돌아감
contract CONSTRUCTOR{
address payable owner;
constructor () payable{
//생성자 함수가 호출 될 때, msg.value로 전송된 이더리움을 컨트랙트 계정으로 전송
payable(this).transfer(msg.value);
owner = payable(msg.sender);
}
//owner 변수의 값을 반환하는 함수
function getOwner() public view returns(address){
return owner;
}
//owner만 호출 가능한 함수, _to 주소로 _amount만큼의 이더리움을 전송
function transferTo(address payable _to, uint _amount) public {
require(msg.sender == owner, "only owner can transfer asset");
_to.transfer(_amount);
}
//fallback함수로, 이더리움을 컨트택트 계정으로 전송 할 때 호출된다.
//receive()가 호출되는 경우 - 컨트랙트 주소로 이더리움을 전송 or selfdestruct() 함수를 호출하여 컨트랙트를 파괴하는 경우 or 잘못된 함수 이름을 호출하는 경우
receive() external payable{}
//이더리움을 컨트랙트로 전송하는 함수, 함수가 호출 될 때 msg.value로 전송된 이더리움을 컨트랙트 계정으로 전송하고 전송된 이더리움의 양을 반환한다.
function deposit() public payable returns(uint){
return msg.value;
}
//owner만 호출 할 수 있는 함수, 컨트랙트 계정에 있는 모든 이더리움을 owner 주소로 전송한다.
function withdraw() public {
require(msg.sender == owner, "only owner can withdraw asset");
owner.transfer(address(this).balance);
}
//_amount만큼의 이더리움을 owner주소로 전송, owner만 호출 가능한 함수
function withdraw(uint _amount) public{
require(msg.sender == owner, "only owner can withdraw asset");
owner.transfer(_amount);
}
//owner만 호출 가능한 함수로 1이더리움을 owner 주소로 전송
function withdraw3() public{
require(msg.sender == owner, "only owner can withdraw asset");
owner.transfer(1 ether);
}
}
contract MODIFIER {
struct Person {
uint age;
string name;
}
Person P;
modifier overTwenty(uint _age, string memory _criminal) {
//_age가 20 보다 큰지 확인, 만약 20 보다 작다면 예외 발생
require(_age >20, "Too young");
//_criminal이 "Bob"이라는 문자열과 같은지 확인, 같다면 예외 발생
require(keccak256(abi.encodePacked(_criminal)) != keccak256(abi.encodePacked("Bob")), "Bob is criminal. She can't buy it");
//require 두 조건을 모두 통과화면 _; 함수 실행
_;
}
function buyCigar(uint _a, string memory _name) public pure overTwenty(_a, _name) returns(string memory) {
return "Passed";
}
function buyAlcho(uint _a, string memory _name) public pure overTwenty(_a, _name) returns(string memory) {
return "Passed";
}
function buyGun(uint _a, string memory _name) public pure overTwenty(_a, _name) returns(string memory) {
return "Passed";
}