블록체인에서 데이터를 바로 끌어오는 것이 보안상 불가능하기때문에 오라클을 이용해 데이터를 끌어온다.
├── caller
│ ├── contracts
│ ├── migrations
│ ├── test
│ └── truffle-config.js
├── oracle
│ ├── contracts
│ ├── migrations
│ ├── test
│ └── truffle-config.js
└── package.json
caller 컨트랙트가 오라클과 통신하기 위해서는 인터페이스를 정의해야 한다.
FastFood
라는 contract가 있다고 가정pragma solidity 0.5.0;
contract FastFood {
function makeSandwich(string calldata _fillingA, string calldata _fillingB) external {
//Make the sandwich
}
}
FastFood
contract 부르는 PrepareLunch
contract 만들고 인터페이스 정의하기pragma solidity 0.5.0;
//인터페이스 정의하기
//FastFood안에 있는 makeSandwich라는 함수가 컨트랙트를 부른다
interface FastFoodInterface {
function makeSandwich(string calldata _fillingA, string calldata _fillingB) external;
}
call
한다.pragma solidity 0.5.0;
import "./FastFoodInterface.sol";
contract PrepareLunch {
FastFoodInterface private fastFoodInstance;
function instantiateFastFoodContract (address _address) public {
fastFoodInstance = FastFoodInterface(_address);
fastFoodInstance.makeSandwich("sliced ham", "pickled veggies");
}
}
getLatestEthPrice()
를 작동시켜야 한다. id
만 리턴한다.callback
함수가 이더 가격을 업데이트해준다.//맵핑 정의
mapping(address => uint) public balances;
//msg.sender == address
balances[msg.sender] = someNewValue
uint
값은 맨 처음에 0
으로 초기화된다.id
로 부터 호출되었는지 require
써서 검사id
일 경우 myRequests
맵핑에서 제거오라클의 주소
를 담은 변수를 이용해서 확인한다.오라클 주소
인지를 확인하면 된다.msg.sender
를 이용해서 검사한다. modifier onlyOracle() {
require(msg.sender==oracleAddress, "You are not authorized to call this function.");
_;
}
getLatestEthPrice()
와 setLatestEthPrice()
두 개를 implement
해서 사용한다.getLatestEthPrice()
request id
를 계산한다.request id
는 보안상의 이유로 계산하기 힘들게 만들어야 한다.uint randNonce = 0;
uint modulus = 1000;
uint randomNumber = uint(keccak256(abi.encodePacked(now, msg.sender, randNonce))) % modulus;
keccak256
으로 랜덤 넘버를 생성한다.function getLatestEthPrice() public returns (uint256) {
randNonce++;
uint id = uint(keccak256(abi.encodePacked(now, msg.sender, randNonce))) % modulus;
//리퀘스트 트래킹
pendingRequests[id] = true;
//이벤트가 발생했음을 알려줌
emit GetLatestEthPriceEvent(msg.sender, id);
//id 리턴
return id;
}
request id
를 return
해야 함setLatestEthPrice()
setLatestEthPrice()
함수를 불러서 아래 세 가지를 인자로 넘겨준다 function setLatestEthPrice(uint256 _ethPrice, address _callerAddress, uint256 _id) public onlyOwner {
require(pendingRequests[_id], "This request is not in my pending list.");
delete pendingRequests[_id];
}
true
인지 확인힌다.(==true
안해도 저 자체가 boolean
이라 pendingRequests[_id]
만 사용)pendingRequests
에서 해당 아이디 기록을 지워야 한다. function setLatestEthPrice(
uint256 _ethPrice,
address _callerAddress,
uint256 _id
) public onlyOwner {
require(
pendingRequests[_id],
"This request is not in my pending list."
);
delete pendingRequests[_id];
//컨트랙트 인스턴스화
CallerContracInterface callerContractInstance;
callerContractInstance = CallerContracInterface(_callerAddress);
//콜백 함수 작동시킴
callerContractInstance.callback(_ethPrice, _id);
//이벤트 트리거
emit SetLatestEthPriceEvent(_ethPrice, _callerAddress);
}
callback
함수를 작동시켜 이더리움 가격과 리퀘스트의 아이디를 넘긴다.
cat_dev님 안녕하세요,
헤드헌팅사 유니코써치의 김만규 컨설턴트입니다.
블록체인 관련 Job Position JD 중 모르는 사항을 공부 중
cat_dev님의 블로그에서 좋은 자료를 발견, 덕분에 공부하는데 어려움이 다소 해소되었습니다.
감사드리며, 이후에도 좋은 글 기대하겠습니다.
또한 혹시 이직을 준비하고 계시다면 제가 도움 받았듯,
cat-dev님의 이직과정이 즐거운 경험이 될 수 있도록 최선을 다해 지원하겠습니다.
감사합니다.
Tel) 010 4913 7163
Email) leo@unicosearch.com
Linkedin) https://www.linkedin.com/in/no1recruiting/