[chainlink functions]Request Computation

채동기·2023년 6월 8일
0

Oracle

목록 보기
11/14

Chainlink Functions 분산화된 Oracle Network (DON)에서 계산을 실행하는 방법에 대해 알아보겠습니다. 예제 코드는 리스트 내 숫자들의 기하 평균을 계산합니다. OCR이 오프 체인 계산과 집계를 완료하면 결과를 스마트 컨트랙트로 반환합니다.

시작하기 전에
사전 준비
링크에 있는 내용을 해보고, 준비하셔야 지금 페이지의 내용을 따라 올 수 있습니다.

Chainlink Functions Starter Kit의 tutorials 브랜치로 깃 체크아웃해야합니다.

git checkout tutorials

이 튜토리얼은 /tutorials/1-simple-computation 디렉토리에 위치해 있습니다.

튜토리얼

이 튜토리얼은 숫자 리스트에서 평균값(기하 평균)을 구성하기 위해 설정되었습니다. 코드 예제의 설명을 자세히 알아보려면 설명 섹션을 읽어보세요.

config.js 파일을 열어보세요. args 값이 ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]로 설정되어 있으므로 소스 코드는 "1,2,3,4,5,6,7,8,9,10"의 평균(기하 평균)을 계산합니다. 다른 집합의 평균을 계산하려면 args 값을 변경할 수 있습니다. 요청 구성 파일에 대한 자세한 정보는 explanation의 config.js를 읽어보세요.

source.js 파일을 열어 JavaScript 소스 코드를 분석하세요. 설명파트의 source.js를 읽으면 소스 코드에 대한 더 자세한 설명을 볼 수 있습니다.

Simulate

Chainlink Functions Hardhat Starter Kit에는 로컬 컴퓨터에서 Functions 코드를 테스트할 수 있는 시뮬레이터가 포함되어 있습니다. functions-simulate 명령을 사용하여 코드를 로컬 런타임 환경에서 실행하고, 엔드 투 엔드 이행을 시뮬레이션하여 Functions을 분산화된 Oracle Network에 제출하기 전에 문제를 해결할 수 있습니다.

functions-simulate 작업을 실행하여 소스 코드를 로컬에서 실행하고, config.js와 source.js가 올바르게 작성되었는지 확인하세요.

npx hardhat functions-simulate --configpath REPLACE_CONFIG_PATH

example

$ npx hardhat functions-simulate --configpath tutorials/1-simple-computation/config.js
secp256k1 unavailable, reverting to browser version

__Compiling Contracts__
Nothing to compile
Duplicate definition of Transfer (Transfer(address,address,uint256,bytes), Transfer(address,address,uint256))

Executing JavaScript request source code locally...

__Console log messages from sandboxed code__
calculate geometric mean of 1,2,3,4,5,6,7,8,9,10
geometric mean is: 4.53

__Output from sandboxed source code__
Output represented as a hex string: 0x00000000000000000000000000000000000000000000000000000000000001c5
Decoded as a uint256: 453

__Simulated On-Chain Response__
Response returned to client contract represented as a hex string: 0x00000000000000000000000000000000000000000000000000000000000001c5
Decoded as a uint256: 453

Gas used by sendRequest: 351895
Gas used by client callback function: 75017

위의 예제 출력을 읽으면 기하 평균이 올바르게 계산되었음을 알 수 있습니다: 4.53입니다. Solidity는 소수를 지원하지 않기 때문에 반환하는 bytes 인코딩된 값 0x00000000000000000000000000000000000000000000000000000000000001c5를 콜백에서 반환하기 전에 소수점을 이동하여 값이 정수 453처럼 보이도록 합니다.
참고: 자세한 설명을 보면 source.js 코드 설명을 읽으세요.

Request

  • 주의: 요청을 성공적으로 수행하기 전에 "사전 준비" 섹션에서 설정 단계를 완료해야 합니다. 각각의 튜토리얼은 별도의 Git 브랜치에 있으며, 일부는 .env.enc 파일에 고유한 값을 요구합니다.

분산화된 Oracle Network에 평균(기하 평균)을 계산하는 요청을 보내세요. functions-request 작업을 subid(구독 ID)와 계약 매개변수와 함께 실행하세요. 이 작업은 Functions JavaScript 소스 코드와 인수 및 비밀값을 FunctionsConsumer의 executeRequest 함수를 호출할 때 전달합니다. 소비자(contract) 계약에 대한 자세한 내용은 functionsConsumer.sol 섹션을 읽어보세요.

npx hardhat functions-request --subid REPLACE_SUBSCRIPTION_ID --contract REPLACE_CONSUMER_CONTRACT_ADDRESS --network REPLACE_NETWORK --configpath REPLACE_CONFIG_PATH

Explanation

FunctionsConsumer.sol

Chainlink Functions 소비자(contract) 계약을 작성하려면 계약에서 FunctionsClient.sol을 가져와야 합니다.

import {Functions, FunctionsClient} from "./dev/functions/FunctionsClient.sol";

Chainlink Functions 요청을 구축하는 데 필요한 모든 함수를 얻기 위해 Functions.sol 라이브러리를 사용하세요. API 참조: Functions를 읽을 수 있습니다.

using Functions for Functions.Request;

최신 요청 ID, 최신 수신 응답 및 최신 수신 오류(있는 경우)는 상태 변수로 정의됩니다. latestResponse 및 latestError는 동적 크기의 byte 배열인 bytes로 인코딩되므로 응답이나 오류를 읽기 위해 여전히 디코딩해야 합니다:

bytes32 public latestRequestId;
bytes public latestResponse;
bytes public latestError;

콜백 중에 스마트 계약에서 발생시킬 OCRResponse 이벤트를 정의합니다.

event OCRResponse(bytes32 indexed requestId, bytes result, bytes err);

계약을 배포할 때 네트워크에 대한 오라클 주소를 전달합니다:

constructor(address oracle) FunctionsClient(oracle)

원하는 경우 updateOracleAddress 함수를 호출하여 오라클 주소를 변경할 수 있습니다.

남은 두 가지 함수는 다음과 같습니다:

  1. executeRequest: 요청을 전송하기 위한 함수입니다. JavaScript 소스 코드, 암호화된 비밀값, 소스 코드에 전달할 인수 목록, 구독 ID 및 콜백 가스 제한을 매개변수로 받습니다. 그런 다음:

Functions 라이브러리를 사용하여 요청을 초기화하고 전달된 암호화된 비밀값이나 인수를 추가합니다. 요청 초기화, 비밀값 추가, 인수 추가에 대한 API 참조를 읽을 수 있습니다.

Functions.Request memory req;
req.initializeRequest(Functions.Location.Inline, Functions.CodeLanguage.JavaScript, source);
if (secrets.length > 0) {
	req.addRemoteSecrets(secrets);
}
if (args.length > 0) req.addArgs(args);

FunctionsClient의 sendRequest 함수를 호출하여 오라클에 요청을 전송합니다. 요청을 보낼 때의 API 참조를 읽을 수 있습니다. 마지막으로, 요청 ID를 latestRequestId에 저장합니다.

bytes32 assignedReqID = sendRequest(req, subscriptionId, gasLimit);
latestRequestId = assignedReqID;
  1. fulfillRequest: 콜백 중에 호출될 함수입니다. 이 함수는 FunctionsClient에서 가상으로 정의되어 있으며 (fulfillRequest API 참조를 읽으세요), 스마트 계약에서 이 함수를 오버라이딩하여 콜백을 구현해야 합니다. 콜백의 구현은 간단합니다: 계약은 OCRResponse 이벤트를 발생시키기 전에 latestResponse와 latestError에 최신 응답과 오류를 저장합니다.
latestResponse = response;
latestError = err;
emit OCRResponse(requestId, response, err);

config.js

각 설정에 대한 자세한 설명은 요청 구성 섹션을 참조하세요. 이 예제에서 다음과 같은 설정이 사용됩니다:

  • codeLocation: Location.Inline: JavaScript 코드가 요청 내에 제공됩니다.
  • codeLanguage: CodeLanguage.JavaScript: 소스 코드는 JavaScript 언어로 개발되었습니다.
  • source: fs.readFileSync(path.resolve(__dirname, "source.js")).toString(): 소스 코드는 스크립트 객체여야 합니다. 따라서 fs.readFileSync를 사용하여 source.js를 읽은 다음 toString()을 호출하여 내용을 문자열 객체로 가져옵니다.
  • args: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]: 이러한 인수들은 소스 코드에 전달됩니다. 이 예제는 1,2,3,4,5,6,7,8,9,10의 평균(기하 평균)을 계산합니다.
  • expectedReturnType: ReturnType.uint256: DON이 수신한 응답은 바이트로 인코딩됩니다. 평균(기하 평균)이 uint256인 경우, ReturnType.uint256를 정의하여 DON이 수신한 응답을 해독하는 방법을 사용자에게 알려줍니다.

source.js

자바스크립트 소스 코드 섹션을 자세히 읽어보면 호환 가능한 자바스크립트 소스 코드 작성 방법에 대한 설명이 나와 있습니다. 코드는 자체적으로 설명되어 있으며 주석을 통해 모든 단계를 이해하는 데 도움이 됩니다. 주요 단계는 다음과 같습니다:

  • args 설정에서 제공된 숫자를 인수로 읽어옵니다. args는 문자열의 배열이므로 문자열을 숫자로 변환하기 위해 parseInt를 호출합니다.
  • 평균(기하 평균)을 계산합니다: 먼저 숫자들의 곱을 계산한 다음, args의 길이를 n으로 하여 곱의 n번째 루트를 계산합니다.
  • Functions.encodeUint256 도우미 함수를 사용하여 결과를 버퍼로 반환합니다. Solidity는 십진수를 지원하지 않기 때문에 결과에 100을 곱하고 결과를 가장 가까운 정수로 반올림합니다. 참고: 자바스크립트 버퍼에 대해 처음 알게 되었다면 그 중요성을 이해하고 싶다면 이 문서를 읽어보세요.
  • 중요한 점은 Functions 요청에서 실행하려는 사용자 지정 소스 코드는 기본적으로 Node.js 기능을 사용할 수 있지만, buffer, crypto, querystring, string_decoder, url, util과 같은 내장 모듈 이외에는 require 문이나 가져온 모듈을 사용할 수 없다는 것입니다.

참조

https://docs.chain.link/chainlink-functions/tutorials/simple-computation

profile
what doesn't kill you makes you stronger

0개의 댓글