/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/
contract Ownable {
address public owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
function Ownable() public {
owner = msg.sender;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0));
OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
✔ Ownable 컨트랙트가 하는 일
owner
에 msg.sender
(컨트랙트 배포자)를 대입한다.onlyOwner
제어자를 추가 : 오직 소유자만 접근할 수 있도록 제한하는 기능🔊 onlyOwner 제어자를 컨트랙트에서 자주 사용하기 때문에
대부분의 DApp은 제플린의 Ownable 컨트랙트를 복붙하고 상속받아서 사용한다고 함!
function
키워드가 아닌 modifier
키워드를 사용함modifier onlyOwner() {
require(msg.sender == owner);
_;
}
대부분의 제어자는 이렇게 require문
이 먼저 나오고, 그 후 _;
가 나온다.
이 제어자가 붙은 함수가 호출될 경우,
1. 함수 내부보다 제어자가 먼저 실행되어 require문
이 실행되고,
2. 그 후 제어자의 _;
에 도달하면 이 때 함수의 내부로 돌아가 그 내용을 실행한다.
-> 따라서 함수 내부를 실행하기 전에 확인하고자 하는 조건을 체크하는 용도로 사용되는 것!
🔊
_;
가 함수 내부로 돌아간다!는 의미라는 것 기억하기
uint8
, uint16
, uint32
...)uint32 a; uint c; uint32 b;
(X)uint c; uint32 a; uint32 b;
(O)솔리디티가 제공하는 시간 단위계 (Time units)
now
변수 : 현재의 유닉스 타임스탬프값 (1970/1/1부터 지금까지 지난 초)
seconds
, minutes
, hours
, days
, weeks
, years
: 해당 단위의 초 단위 길이로 변환됨
ex)
// `lastUpdated`를 `now`로 설정
function updateTimestamp() public {
lastUpdated = now;
}
// 마지막으로 `updateTimestamp`가 호출된 뒤 5분이 지났으면 `true`를, 5분이 아직 지나지 않았으면 `false`를 반환
function fiveMinutesHavePassed() public view returns (bool) {
return (now >= (lastUpdated + 5 minutes));
}
private
, internal
함수에 구조체의 포인터를 인수로 전달할 수 있음Zombie
라는 구조체를 전달할 경우function _doStuff(Zombie storage _zombie) internal {
// _zombie로 할 수 있는 것들을 처리
}
public
과 external
함수는 제어자가 없는 이상 모든 사용자가 함수를 호출할 수 있다internal
로 정의한다modifier olderThan(uint _age, uint _userId) {
require (age[_userId] >= _age);
_;
}
이렇게 제어자가 인수를 가질 수 있고,
사용할 땐, 제어자가 붙는 함수가 받는 인수를 전달받아 대입할 수 있다.
ex)
function driveCar(uint _userId) public olderThan(16, _userId) {
// 필요한 함수 내용들
}
(새로 배운 내용 없음)
view
함수 : 블록체인에서 데이터를 읽기만 하면 되는 함수storage
는 솔리디티의 비싼 연산 : 블록체인에 영구적으로 기록하는 것이기 때문storage
의 사용을 최소화하자.external view
함수라면, storage
를 사용하는 것 보다 저렴한 방식이다. storage
없이 함수 내 배열을 만들기 위해 memory
를 사용함.
함수가 끝날 때까지만 존재!
storage
로 영구 저장된 배열을 매번 업데이트하는 것보다 훨씬 나음
메모리에 배열 선언하는 법
uint[] memory values = new uint[](3);
//길이 3짜리 배열을 메모리에 생성한다는 뜻
storage
배열과 달리 array.push()
로 크기가 조절되지 않음!