728x90
반응형
Solidity에서 ether를 전송하는 스마트 컨트랙트를 작성하기 위해선, payable의 개념이 필수적입니다.
"payable means that you can transfer ether with the transaction."
payable엔 두 가지 종류가 있습니다.
1. address payable
2. function payable
address 타입과 함께 사용되면 지불가능한 주소(address payable)의 타입이 되고,
function과 함께 사용되면 지불가능한 함수 (function _ () payable)이 됩니다.
Members of Address Payable Types
: address payable 타입의 멤버엔 .transfer과 .send가 있습니다.
- <address payable>.transfer(uint256 amount) : send given amount of Wei to Address, reverts on failure, forwards 2300 gas stipend, not adjustable.
- <address payable>.send(uint256 amount) returns (bool) : send given amount of Wei to Address, reverts on failure, forwards 2300 gas stipend, not adjustable.
예제로 payable address와 payable function에 대해 설명해 보겠습니다.
* Send Ether to the Smart Contract *
1. VALUE를 사용하여 Smart Contract에 Ether 전송
함수에 payable을 추가함으로써 컴파일러가 이 함수를 통해 돈을 받는다는 걸 인식하게 해 줍니다.
pragma solidity ^0.8.7;
contract SendEtherExample {
uint256 public balanceReceived;
// 함수를 payable로 만들어서 컴파일러가 이 함수로 돈을 받는다는 걸 인식하게 해줌
function receiveMoney() public payable {
balanceReceived += msg.value; // msg.value 안에는 이 트랜잭션으로 전송된 금액이 wei로 들어가 있음
}
}
(.value contains the amount of Wei that was sent to the smart contract.)
위 계약을 실행해서 스마트 계약 잔고에 5 ether를 줘보겠습니다.
balanceReceived를 클릭하면, 아직 아무것도 받지 않았기 때문에 '0'으로 출력됩니다.
이제 Value에 5 ether를 넣은 뒤 receiveMoney를 눌러보겠습니다.
그럼 Smart Contract 주소에 5 ether가 추가된 걸 확인할 수 있습니다.
2. 스마트 계약의 주소 잔고를 리턴
pragma solidity ^0.8.7;
contract SendEtherExample {
uint256 public balanceReceived; // 돈을 얼마나 받았는 지 기록함. 계약이 실행되고 있는 주소의 잔고와 같아야 함
function receiveMoney() public payable {
balanceReceived += msg.value;
}
function getBalance() public view returns (uint) {
// 이 스마트 계약의 주소 잔고를 wei로 리턴
return address(this).balance;
}
}
getBalance를 클릭하면, 현재 이 smart contract가 가진 잔고를 리턴해줍니다.
3. smart contract 주소의 잔고를 출금(다른 주소로 transfer)
3.1) 잔고 값 모두 전송
pragma solidity ^0.8.7;
contract SendEtherExample {
uint256 public balanceReceived;
function receiveMoney() public payable {
balanceReceived += msg.value;
}
function getBalance() public view returns (uint) {
return address(this).balance;
}
// 스마트 계약의 잔고 안에 있는 모든 값을 출금
function withdrawMoney(address payable to) public {
to.transfer(address(this).balance);
balanceReceived = 0;
}
}
3.2) 원하는 값만큼 전송
pragma solidity ^0.8.7;
contract SendEtherExample {
uint256 public balanceReceived;
function receiveMoney() public payable {
balanceReceived += msg.value;
}
function getBalance() public view returns (uint) {
return address(this).balance;
}
function withdrawMoney(address payable to, uint256 amount) public {
require(address(this).balance >= amount, "Error!");
to.transfer(amount); // amount 단위 : Wei
balanceReceived -= amount;
}
}
현재 스마트 계약의 잔고 보다 더 많은 값을 출금하고자 하면 오류가 발생하도록 require 절 추가
잔고의 값과 같거나 작은 값을 입력하면 정상적으로 출금이 됩니다.
this 란?
- this refers to the instance of the contract where the call is made.
- address(this) refers to the address of the instance of the contract where the call is being made.
따라서, 위 코드에서 address(this)라는 문장은 스마트 계약의 주소를 가리키는 것이고,
address(this).balance 형태로 사용하여, wei 형태로 주소의 잔고를 리턴 받습니다.
function getBalance() public view returns (uint256) {
return address(this).balance;
}
require 란?
2023.01.02 - [블록체인/Solidity] - [Solidity] require() 사용 - 공부하는 도비
'Blockchain > Solidity' 카테고리의 다른 글
Send Ether to the Smart Contract (2) 및 block.timestamp 개념 - 공부하는 도비 (0) | 2023.02.01 |
---|---|
Solidity 생성자(constructor) - 공부하는 도비 (1) | 2023.02.01 |
delete element of array and mapping - 공부하는 도비 (0) | 2023.01.02 |
require() 사용 - 공부하는 도비 (0) | 2023.01.02 |
msg.sender 사용 - 공부하는 도비 (0) | 2023.01.02 |