solidity.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract Hello{
string public hello = "Hello Dworld";
}
data type
boolean
! (Not)
&& (And)
|| (Or)
== (Equality)
!= (Inequality)
string
솔리디티에서는 가스를 많이 소비하기 때문에 string 사용을 지양한다.
솔리디티는 string을 받아서 byte화 시켜서 이해한다.
반대로 byte를 string화 하여 꺼낸다.
string과 byte를 왔다갔다 변경하며 가스를 소비하는 것 보다
byte로 받는 것이 가스비가 적게 나온다.
bytes(byte1~byte32)
byte4 public bt = 0x12345678;
bytes public bt2 = "STRING";
Integer
int: 기호있음
uint: 기호없음
(기호 유무는 음수 값을 쓰냐 안쓰냐에 따라 Integer 범위가 다름)
int
int8: -2^7 ~ 2^7-1
int16: -2^15 ~ 2^15-1
int32: -2^31 ~ 2^31-1
int64: -2^63 ~ 2^63-1
int128 : -2^127 ~ 2^127-1
int256 (=int): -2^255 ~ 2^255-1
uint
uint8 : 0 ~ 2^8-1
uint16: -0 ~ 2^16-1
uint32: -0 ~ 2^32-1
uint64: -0 ~ 2^64-1
uint128 : -0 ~ 2^128-1
uint256 (=uint): 0 ~ 2^256-1
address: 20bytes 길이의 어드래스
Gas
uint256 public value = 1 ether; // 1000000000000000000
uint256 public value2 = 1 wei; // 1
uint256 public value3 = 1 gwei; // 1000000000
// 1 ether = 10^Gwei = 10^18 wei
0.00000000000000001 ehter = 1 wei
1ether = 10^9 Gwei
Gwei = 가스비용 단위
가스비 책정
코드의 길이에 따라 비용이 책정된다. 길이가 짧을수록 소비되는 가스가 적어진다.
string 이나 modifer를 사용하는 경우 가스가 더 들어간다.
가스는 디도스 공격에서 자유로워지기 위함.
function
// 1. 파라미터와 리턴 값이 없을때
function ff() public {}
// 2. 파라미터는 있고 리턴 값이 없을때
function ff(uint _value) public {}
// 3. 파라미터는 있고 리턴 값이 있을때
function ff(uint256 _value) public returns(uint256) {}
접근제어자(public, private, internal, external)
public: 다른 컨트랙 접근가능
private: 컨트랙 내부에서만
external: 컨트랙 외부에서만
internal: 컨트랙과 상속받은 자식 컨트랙에서만
view: function 밖의 변수들을 읽음 (변경 불가능)
pure: function 밖의 변수들을 못읽음 (변경 불가능)
view, pure 명시 안할때 : function 밖의 변수들을 읽음 (변경 가능)
contract Example{
uint256 public a = 1;
function vv() public view returns(uint256){
return a+2;
}
function pp() public pure returns(uint256){
uint256 b = 1;
return 6+b;
function vpx() public returns(uint256){
a = 13;
return a;
}
// a = 1, vv() = 3, pp() = 7, vpx() = 13
storage: 변수, 함수들을 영속적으로 저장 (가스비용 비쌈)
memory: 함수의 파라미터, 리턴값, 레퍼런스 타입 저장 (함수내에서만 유효, 영속적X, 가스비용 쌈)
Colldata: external function의 파라미터에서 사용
stack: EVM의 stack data 관리할때 씀(1024MB까지)
contract string_memory {
function sm(string memory _str) public pure returns(string memory){
return _str;
}
}
// string을 받아서 그대로 리턴
instance
(빵틀)
contract A{
uint256 public a = 5;
function change(uint256 _value) public {
a = _value;
}
}
contract B{
A instance = new A(); // 컨트랙A 빵틀
function get_A() public view returns(uint256) {
return instance.a(); // 5
}
function change_A(uint256 _value) public {
instance.change(_value); // 받은 벨류값
}
}
constructor
(생성자)
contract A{
string public name;
uint256 public age;
constructor(string memory _name, uint256 _age){
name = _name;
age = _age;
}
function change(string memory _name, uint256 _age) public {
name = _name;
age = _age;
}
}
contract B{
A instance = new A("Alice", 25);
function change(string memory _name, uint256 _age) public {
instance.change(_name,_age);
}
function get() public view returns(string memory, uint256) {
return (instance.name(), instance.age());
}
}
상속
contract Father {}
contract Son is Fateher {}
override
contract Father{
string public familyName = "Shim";
string public givenName = "Jin";
uint256 public money = 100;
constructor(string memory _givenName) public {
givenName = _givenName;
}
function getFamilyName() view public returns(string memory){
return familyName;
}
function getGivenName() view public returns(string memory){
return givenName;
}
function getMoney() view public virtual returns(uint256){
return money;
}
}
contract Son is Father("Lewis"){
uint256 public earning = 0;
function work() public {
earning += 100;
}
function getMoney() view public override returns(uint256){
return money+earning;
}
}
// 주는자: virtual, 받는자: override
event
블록에 저장할 값을 기록(logs)
contract Event {
// event 이벤트명(타입과 이름)
event info(string name, uint256 money);
function sendMoney() public {
// emit 이벤트명(파라미터)
emit info("LewisShim", 1000);
}
}
indexed: 필터하려는 파라미터에 indexed 기입
event numberTracker(uint256 indexed num, string str);
array
delete: 배열의 길이를 유지하면서 디폴트 값으로 0을 할당.
remove: 배열의 길이가 줄어들면서 제거
mapping
Key, Value 구성로 됨
contract example {
// mapping(키 타입 => 벨류 타입) 접근제한자, 변수이름
mapping(string=>uint256) private priceList;
mapping(uint256=>string) private nameList;
mapping(uint256=>uint256) private ageList;
function setAgeList(uint256 _key, uint256 _age) public {
ageList[_key] = _age;
}
function getAge(uint256 _key) public view returns(uint256){
return ageList[_key];
}
function setNameList(uint256 _key, string memory _name) public {
nameList[_key] = _name;
}
function getName(uint256 _key) public view returns(string memory){
return nameList[_key];
}
function setPriceList(string memory _itemName, uint256 _price) public {
priceList[_itemName] = _price;
}
function getPriceList(string memory _key) public view returns(uint256){
return priceList[_key];
}
}
exception handling
assert: gas를 다 소비한 후,
어떤 조건에 맞지 않을때(false일때) 에러를 줌
revert: 조건없이 에러를 줌, gas 환불
require: 어떤 조건에 맞지 않을때(false일때) 에러를 주고, gas 환불
function bulabula() public pure {
assert(false);
revert("error message");
require(false, "error message");
}
modifier
_;
payable
함수, 주소, 생성자에 붙여서 사용
contract Payable {
address payable public owner;
constructor() payable {
owner = payable(msg.sender);
}
function deposit() public payable {}
function notPayable() public {}
function withdraw() public {
uint amount = address(this).balance;
(bool success, ) = owner.call{value: amount}("");
require(success, "Failed to send Ether");
}
function transfer(address payable _to, uint _amount) public {
(bool success, ) = _to.call{value: _amount}("");
require(success, "Failed to send Ether");
}
}
msg.value
송금액
balance
해당주소의 잔액
msg.sender
컨트랙을 사용하는 주체
contract MobileBanking{
event SendInfo(address _msgSender, uint256 _currentValue);
event MyCurrentValue(address _msgSender, uint256 _value);
event CurrentValueOfSomeone(address _msgSender, address _to,uint256 _value);
// 이더 보내기
function sendEther(address payable _to) public payable {
require(msg.sender.balance >= msg.value, "Your balance is not enough");
_to.transfer(msg.value);
emit SendInfo(msg.sender,(msg.sender).balance);
}
// 보낸이 잔액 확인하기
function checkValueNow() public{
emit MyCurrentValue(msg.sender, msg.sender.balance);
}
// 받은이 잔액 확인하기
function checkUserMoney(address _to) public{
emit CurrentValueOfSomeone(msg.sender,_to ,_to.balance);
}
}
contract MobileBanking2{
address owner;
// 컨트랙이 이더를 받을 수 있음
constructor() payable{
// 배포자의 주소를 owner에 넣음
owner = msg.sender;
}
modifier onlyOwner{
// owner만이 함수를 실행할 수 있음
require(msg.sender == owner, "Only Owner!");
_;
}
event SendInfo(address _msgSender, uint256 _currentValue);
event MyCurrentValue(address _msgSender, uint256 _value);
event CurrentValueOfSomeone(address _msgSender, address _to,uint256 _value);
function sendEther(address payable _to) public onlyOwner payable {
require(msg.sender.balance >= msg.value, "Your balance is not enough");
_to.transfer(msg.value);
emit SendInfo(msg.sender,(msg.sender).balance);
}
function checkValueNow() public onlyOwner {
emit MyCurrentValue(msg.sender, msg.sender.balance);
}
function checkUserMoney(address _to) public onlyOwner {
emit CurrentValueOfSomeone(msg.sender,_to ,_to.balance);
}
}
fallback
무기명 함수(이름이 없는 함수)
external (필수)
payable
컨트랙이 이더를 받을 수 있음
이더를 받고 어떤 액션을 줌
call함수를 통해 없는 함수가 호출될 때, 어떤 액션을 줌
recieve: 이더만 받을 때
fallback: 함수 호출과 이더를 보낼 때
call
송금기능
외부 컨트랙 부르기
가변적인 gas
이스탄불 하드포크 이후, gas 가격 상승으로 call 사용 권장 / send, tranfer = 2300gas
Author And Source
이 문제에 관하여(solidity.sol), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@woojinshim103/sol.sol저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)