사용자로부터 자금 받기, 자금 인출, USD로 최소 펀딩 금액 설정을 위한 SmartContract를 작성한다. USD를 ETH로 변환하기 위해 Oracles-Chainlink 서비스를 이용할것이다.
contracts/
SimpleStorage.sol
StorageFactory.sol
ExtraStorage.sol
FundMe.sol
fund
함수에 payable
을 명시해 주소로 이더리움을 주고 받을수 있게 한다. require
를 이용해 1이더 이상을 받을 수 있게 조건을 작성 그렇지 않은 경우의 오류메세지를 작성. msg.value
은 송금액을 나타낸다. 1ETH를 의미하는 1e18보다 크기를 원한다. 실제로 1*10**18, 즉 1000000000000000000 wei, 1 ETH를 의미한다.
블록체인 오라클은 외부 데이터 또는 계산을 스마트 계약에 제공하기 위해 오프체인 세계와 상호 작용하는 모든 장치이다.
doc.chain.link
solidity섹션에서 open in Remix를 눌러준다.
faucets
테스넷에 이더가 없다면 넣어주자.
컴파일 후 ENVIRONMENT를 injected Provider - Metamask로 바꿔주고 CONTRACT가 PriceConsumerV3로 맞춰진것을 확인후 deploy를 눌러주자
GetLatestPrice를 눌러 주면 값 127871000000를 얻었고 1ETH = 1,278.71000000USD의 의미이다.
Make a Get Request
Open in Remix
컴파일 후 ENVIRONMENT를 injected Provider - Metamask로 바꿔주고 CONTRACT가 APIConsumer로 맞춰진것을 확인 후 deploy를 눌러주자faucets20 test LINK를 전송.
LINK Token ContractsAdd to wallet 클릭계정에 LINK가 추가 되었다.배포한 컨트렉트 주소를 복사해주고전송보낸 LINK는 fee에 해당된다.
Goerli Testnet ETH / USD address
Chaunlink github
위에서 설명한 계약을 사용할 것이다.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract FundMe {
uint256 public minimumUsd = 50 * 1e18;
function fund() public payable{
require(getConversionRate(msg.value) >= minimumUsd, "Didn't send enough!"); // 1e18 == 1 * 10 ** 18
}
function getPrice() public view returns(uint256){
// ABI
// Address 0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e
AggregatorV3Interface priceFeed = AggregatorV3Interface(0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e);
(,int256 price,,,) = priceFeed.latestRoundData();
// ETH in terms of USD
// 1300.00000000
return uint256(price * 1e10); // 1**10 == 10000000000
}
function getVersion() public view returns (uint256) {
AggregatorV3Interface priceFeed = AggregatorV3Interface(0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e)
return priceFeed.version();
}
function getConversionRate(uint256 ethAmount) public view returns (uint256) {
uint256 ethPrice = getPrice();
// 1300_00000000000000000 = ETH / USD price
// 1_0000000000000000000 ETH
uint256 ethAmountInUsd = (ethPrice * ethAmount) / 1e18;
return ethAmountInUsd;
}
}
외부 계약과 상호 작용하기 위해서는 ABI와 주소가 필요하다.
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
임포트함으로 컨트랙트 내에서 해당 기능을 사용할 수 있다.
오직 int price
만 필요하므로 (,int256 price,,,)
만을 가져온다.
그러나 반환된 USD 가격에는 소수점 이하 8자리가 있다. 따라서 변환하기 위해 1e10을 곱해준다.
이 함수는 ETH 형식의 값을 가져와서 USD 형식으로 내보낸다.uint ethPrice
에 ethAmount
를 곱한다. 그런 다음 USD 형식으로 변환되도록 소수를 없애기 위해 1e18
로 나눈다 . ethAmountInUSD
를 반환.
minimumUsd
변수가 50이 아닌 50 1e18이 되어야 한다. 그 이유는 getConversionRate
가 소수점 뒤에 18개의 0이 있는 숫자를 반환하므로 minimumUsd
를 50 1e18로 바꿔준다.
이 시리즈는 freeCodeCamp.org의 강의를 들으면서 공부한 내용을 정리하기 위해 작성했습니다.