일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- ethers type
- 머신러닝기초
- 스마트컨트렉트테스트
- 티스토리챌린지
- 러스트 기초
- multicall
- 컨트렉트 배포 자동화
- 스마트 컨트렉트 함수이름 중복
- Vue.js
- ethers
- 스마트컨트렉트 예약어 함수이름 중복
- git rebase
- 체인의정석
- chainlink 설명
- nest.js설명
- ambiguous function description
- 컨트렉트 동일한 함수이름 호출
- 스마트컨트렉트 함수이름 중복 호출
- 러스트기초
- Vue
- 러스트 기초 학습
- 프록시배포구조
- ethers websocket
- rust 기초
- 스마트컨트렉트프록시
- ethers v6
- SBT표준
- 오블완
- ethers typescript
- vue기초
- Today
- Total
체인의정석
Solidity) 스마트컨트렉트에서 이더리움을 보내는 방법 본문
스마트컨트렉트에서 이더리움을 보내는 방법은 총 3가지가 있다고한다.
https://solidity-by-example.org/sending-ether/
- transfer (2300 gas, throws error)
- send (2300 gas, returns bool)
- call (forward all gas or set gas, returns bool)
이렇게 3가지 인데, 원래 예전에는 call을 쓰면 재진입 공격이 가능하기 때문에 잘 쓰지 않는고 배웠었다. transfer나 send를 쓰라고 했는데
예전에 어느 시점의 메인넷 업데이트 이후 가스비가 변경되어 send나 transfer에 문제가 생기는 경우가 있었던 이야기를 전에 들은거 같다. 결국 나중에 업데이트 되면 고정 가스비는 위험하기 때문에 call을 쓰는것이 좋은거 같다.
또한 프록시 배포를 한 경우 이더리움 전송은 call을 통해서만 가능하니 call을 써야한다.
각 전송 방식에 대한 예시는 아래와 같은데 sent를 통해서 전송이 되었는지 여부를 체크하고 전송이 안되었을 경우 오류가 나오게 코딩해주어야 한다.
contract SendEther {
function sendViaTransfer(address payable _to) public payable {
// This function is no longer recommended for sending Ether.
_to.transfer(msg.value);
}
function sendViaSend(address payable _to) public payable {
// Send returns a boolean value indicating success or failure.
// This function is not recommended for sending Ether.
bool sent = _to.send(msg.value);
require(sent, "Failed to send Ether");
}
function sendViaCall(address payable _to) public payable {
// Call returns a boolean value indicating success or failure.
// This is the current recommended method to use.
(bool sent, bytes memory data) = _to.call{value: msg.value}("");
require(sent, "Failed to send Ether");
}
}
일단 이번에는 프록시 배포를 나중에 쓸 수도 있고 메인넷 업데이트에 영향을 안받고 사용하기 위해서 call을 쓰고 재진입 공격을 막는 형태로 사용하기로 결정했다. 여기에 대해서는 추후 오픈제플린의 재진입 방지 코드를 상속받아서 사용할 생각이다.
위의 예시를 보고 그대로 코드를 작성하려고 하는데
ParserError: Expected ';' but got '{'
(bool sent, bytes memory data) = depositReceiver.call{value: msg.value}("");
이런 에러가 떴다.
찾아본 과 0.7.0 버전 밑에서의 문법이 달라서 난 에러였다.
https://stackoverflow.com/questions/66388642/solidity-parsererror-expected-but-got
찾아보니 0.5.0 버전에서 이더리움을 보내는 식은달랐다.
address payable targetAddress = ....;
(bool sent, bytes memory data) = targetAddress.call.value(msg.value)("");
이런식으로 바꾸니까 컴파일이 잘 되었다.
'블록체인 > Solidity' 카테고리의 다른 글
Openzepplin - Address 라이브러리 분석 (0) | 2022.10.27 |
---|---|
payable 사용시 발생하는 에러 ParserError: Expected primary expression. (0) | 2022.08.11 |
스마트컨트렉트 테스트에 Infinite Approve 적용하기 (0) | 2022.07.25 |
스마트컨트렉트에서 소수점 처리하는법과 엑셀에서 검산하는 방법 및 유의점 (0) | 2022.07.25 |
Solidity 0.8.0 버전에서 HashStruct안에 UUID 넣는 법 (0) | 2022.07.21 |