Lesson 3 고급 솔리디티 개념
Chapter 1 컨트랙트의 불변성
스마트컨트랙트는 불변성을 갖는다. 그 누구도 수정/변형 할 수 없다.
따라서 보안적 이슈가 있어도 새로운 스마트컨트랙트를 작성할 수 있을 뿐, 기존의 것을 수정할 수 없다.
이는 곧 코드작성에 있어서도 하드코딩을 기피해야하는 이유가 된다.
얘를 들어 interface에서 사용할 스마트컨트랙트 주소를 하드코드로 넣는 경우, 해당 스마트컨트랙트가 모종의 이유로 폐기된다면 우리가 작성한, 해당 스마트컨트랙트를 사용하고 있었던 스마트컨트랙트도 폐기해야한다.
KittyInterface kittyContract;
function setKittyContractAddress (address _address) external {
kittyContract = KittyInterface(_address);
}
그렇기 때문에 이런식으로 address는 변경가능하게 만들 필요가 있다.
Chapter 2 소유가능한 컨트랙트
OpenZeppelin 이라는 스마트컨트랙트 라이브러리가 있다고 한다. 나름 검증된 것들만 모아둔 패키지인 듯.
아래는 OpenZeppelin에 있는 Ownable 컨트랙트이다.
/**
* @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;
}
}
이 코드는 컨트랙트 생성자에 의해, 컨트랙트 생성과 함께 owner라는 메소드를 만들면서 msg.sender 값을 대입시킨다.
그 후 특정 함수에 대해 소유자만 접근가능하도록 하는 onlyOwner 제어자를 추가한 뒤,
소유권 이전에 관한 기능까지 구현되어 있는 것을 볼 수 있다.
"onlyOwner는 컨트랙트에서 흔히 쓰는 것 중 하나라, 대부분의 솔리디티 DApp들은 Ownable 컨트랙트를 복사/붙여넣기 하면서 시작한다네. 그리고 첫 컨트랙트는 이 컨트랙트를 상속해서 만들지"
그렇다고 한다.
Chapter 3 OnlyOwner 함수 제어자
modifier 는 함수의 정의부 끝부분에 쓸 수 있는 함수의 제어자이다. 우리는 modifier를 통해 public, private 뿐만 아니라 다양한 제어자를 커스터마이징하여 쓸 수 있다.
modifier가 붙어있는 함수는 반드시 modifer를 먼저 실행한다. 그리고 modifier의 _; 부분에서 기존 함수의 내용을 실행한다.
//cryptozombies 예제코드
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
contract MyContract is Ownable {
event LaughManiacally(string laughter);
function likeABoss() external onlyOwner {
LaughManiacally("Muahahahaha");
}
}
이 코드에서 likeABoss는 onlyOwner라는 modifier가 붙어있다. 따라서 솔리디티는 likeABoss를 실행할 때 onlyOwner를 먼저 실행하고, _;를 만나는 부분에서 다시 기존 함수의 내용인 LaughManiacally event를 실행하게 된다.
Chapter 4
이더리움의 스마트컨트랙트를 작동시킬때는 연산의 복잡도에 따라 가스비가 천차만별로 책정된다. 따라서 다른 언어에 비해 솔리디티는 코드 효율화와 최적화가 특히 더 중요하다.
uint의 경우 struct 밖에서는 uint256과 uint32가 똑같은 가스비를 발생시키지만, struct 안에서는 비용최적화가 가능하다. 따라서 struct를 짤 때 최대한 적은 정수공간을 할당하는 것이 바람직하다.
"또한 동일한 데이터 타입은 하나로 묶어놓는 것이 좋네. 즉, 구조체에서 서로 옆에 있도록 선언하면 솔리디티에서 사용하는 저장 공간을 최소화한다네.
예를 들면, uint c; uint32 a; uint32 b; 라는 필드로 구성된 구조체가 uint32 a; uint c; uint32 b; 필드로 구성된 구조체보다 가스를 덜 소모하네. uint32 필드가 묶여있기 때문이지."
Chapter 5
now 변수는 현재의 유닉스 타임스탬프를 제공하지만, 2038년에 더이상 32비트로 표현할 수 없는 시점이 올 때 문제가 생길 수 있다. 또한, seconds, minutes, hours, days, weeks, years 등의 경우 각각의 시간 단위에 맞는 초 단위의 값을 제공한다. 즉, 1 minutes 는 60 을, 1 days 는 86400 을 의미한다.
참고로 now는 기본적으로 uint256 이므로 최적화를 위해 uint32로 변환할 것을 추천한다.
Chapter 6
private 또는 internal 함수에는 struct 의 storage 포인터를 인수로 전달할 수 있다.
Chapter 7
public과 external 함수는 보안을 신경써야한다.
Chapter 8
modifier는 인수도 전달 받을 수 있다.
//cryptozombie 예제코드
// 사용자의 나이를 저장하기 위한 매핑
mapping (uint => uint) public age;
// 사용자가 특정 나이 이상인지 확인하는 제어자
modifier olderThan(uint _age, uint _userId) {
require (age[_userId] >= _age);
_;
}
// 차를 운전하기 위햐서는 16살 이상이어야 하네(적어도 미국에서는).
// `olderThan` 제어자를 인수와 함께 호출하려면 이렇게 하면 되네:
function driveCar(uint _userId) public olderThan(16, _userId) {
// 필요한 함수 내용들
}
Chapter 9
Chapter 10
external view 함수는 가스비가 공짜다!! 즉, 외부에서 호출되어 읽기만 할 때 공짜다!
Chapter 11
메모리 배열은 길이 인수가 반드시 같이 선언되어야한다.
Chapter 12
for 문은 JS와 같다.
Chapter 13
Chapter 14
'Learning-Log > Computer Science' 카테고리의 다른 글
[Ubuntu] 압축파일(zip, rar) 풀기 (0) | 2023.04.01 |
---|---|
[Solidity] CryptoZombies : Lesson 2 정리 (0) | 2023.03.31 |
[Ethereum] 이더리움 입문자를 위한 사이트, CryptoZombies (0) | 2023.03.25 |
[Express.js] Cookie와 Session - BackEnd와 FrontEnd의 통신 수단 (0) | 2023.01.20 |
[Express] res.sendFile(path.join(__dirname, '~~'));에 대하여 (0) | 2023.01.12 |