2020.코딩일지
[solidity] payable/balance와 msg.sender (feat.솔리디티깨부수기) 본문
728x90
payable
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract lec26 {
/*
payable은 이더/토큰과 주고받을때(상호작용시) 필요한 키워드라고 생각하쟈!
즉, send, transfer, call을 이용하여 이더를 보낼때 Payable이라는 키워드가 필요하다.
이 payable은 주로 "함수, 주소, 생성자"에 붙여서 사용된다.
msg.value는 송금 보낸 코인의 값
이더를 보내는 3가지
1. send : 2300 gas를 소비, (에러대신에) 성공여부를 true또는 false로 리턴한다.
2. transfer : 2300 gas를 소비, 실패시 에러를 발생
3. call : 가변적인 gas소비 (gas값 지정 가능), 성공여부를 true 또는 false로 리턴
재진입(re-entrancy) 공격 위험성 있음(엇위험해 무한반복), 2019.12월 이후 call 사용을 추천
0.4.13 버전이후에는 안전한 방법인 ⭐️transfer 권장 했으나
Istanbul하드포크이후 가스가격이 올라서 ⭐️call 사용 권장.
*/
event howMuch(uint256 _value) ;
//gas 32436
function sendNow(address payable _to) public payable { //⭐️_to자리에 스컨도 이더를받을수있다;ㅋㅋ
bool sent = _to.send(msg.value); //(msg.value에는 이더금액이들어있다) return true or false
require(sent, "Failed to send either");
emit howMuch(msg.value);
}
//gas 32436
function transferNow(address payable _to) public payable{
_to.transfer(msg.value); //transfer자체가 에러를 리턴하기때문에 위와같이 require를 안써도된다.
emit howMuch(msg.value);
}
function callNow(address payable _to) public payable {
// (0.6.12로테스트함)~0.7
// (bool, sent, ) = _to.call.gas(1000).value(msg.value)("");
// require(sent, "failed to send either");
// 0.7~ //gas 32695
// (bool sent, ) = _to.call{value: msg.value, gas:1000}("");//가스지정했다가 처리가안될수도있으니; 지정안하는게나을수도
// require(sent, "Failed to send Ether");
emit howMuch(msg.value);
}
}
payable에 생성자적용
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
//34강) modifier로 변경
//payable을 생성자에 넣을 때. 특정 주소에게만 권한 주기
//(payable은 주로 함수, 주소, 생성자에 붙여서 사용된다)
contract MobileBanking {
address owner;
constructor() payable { //컨트랙자체가 입금받을수있다;ㅋㅋ
owner = msg.sender;
}
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 == owner, "Only Owner!"); //추가함 오더여야만이 가능하다.
require(msg.sender.balance >= msg.value, "Your balance is not enough");
_to.transfer(msg.value);
emit SendInfo(msg.sender, (msg.sender).balance); //event로 전송하고 남은 잔액이 나옴
}
function checkValueNow() public {
emit MyCurrentValue(msg.sender, msg.sender.balance);
}
function checkUserMoney(address _to) public{
emit CurrentValueOfSomeone(msg.sender, _to, _to.balance);
//보내는사람주소, 받는사람주소, 받는사람의 잔액이 출력됨
}
}
balance와 msg.sender
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
/*
주소.balance
주소.balance는 해당 특정 주소의 현재 갖고 있는 이더의 잔액을 나타낸다(msg.value는 송금액)
주소.balance와 같은 형태로 사용한다.
msg.sender
msg.sender는 스컨을 사용하는 주체라고 볼 수 있다.
msg.sender는 앞으로 call vs delegate call에서 주요 내용이다.
*/
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); //event로 전송하고 남은 잔액이 나옴
}
function checkValueNow() public {
emit MyCurrentValue(msg.sender, msg.sender.balance);
}
function checkUserMoney(address _to) public{
emit CurrentValueOfSomeone(msg.sender, _to, _to.balance);
//보내는사람주소, 받는사람주소, 받는사람의 잔액이 출력됨
}
}
'Block Chain' 카테고리의 다른 글
[solidity] enum/interface (feat.솔리디티깨부수기) (0) | 2022.12.05 |
---|---|
[solidity] fallback과 receive (feat.솔리디티깨부수기) (0) | 2022.12.05 |
[solidity] modifier (feat.솔리디티깨부수기) (0) | 2022.12.05 |
[solidity] return/SPDX (feat.솔리디티깨부수기) (0) | 2022.12.05 |
[solidity] error/try-catch문 (feat.솔리디티깨부수기) (0) | 2022.12.05 |
Comments