일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- chainlink 설명
- Vue
- 러스트 기초
- nestjs 튜토리얼
- 머신러닝기초
- 러스트 기초 학습
- ethers type
- ambiguous function description
- 프록시배포구조
- 스마트컨트렉트 함수이름 중복 호출
- 스마트컨트렉트테스트
- 러스트기초
- nest.js설명
- ethers typescript
- Vue.js
- git rebase
- 컨트렉트 동일한 함수이름 호출
- 깃허브명령어
- SBT표준
- multicall
- 스마트 컨트렉트 함수이름 중복
- vue기초
- ethers
- 스마트컨트렉트 예약어 함수이름 중복
- 컨트렉트 배포 자동화
- ethers websocket
- ethers v6
- rust 기초
- 스마트컨트렉트프록시
- 체인의정석
- Today
- Total
체인의정석
Nest.js 수정사항 총 정리 03 ) 하나의 API를 2개로 분기시키기 & ether.js 사용하여 이더리움 value값 타입체크하기 본문
Nest.js 수정사항 총 정리 03 ) 하나의 API를 2개로 분기시키기 & ether.js 사용하여 이더리움 value값 타입체크하기
체인의정석 2021. 12. 7. 19:17이더리움 value의 경우 숫자가 커서 빅넘버처리를 안해주면 에러가 나게 된다. 단위가 너무 크기 때문인데 조사해본 결과 빅넘버 처리는 결과 목적에 맞는 모듈을 사용하는것이 정답이라고 한다.
타입스크립트도 사용하였으니 한번 유명한 ether.js를 찾아보았다. 처음 써보는데 너무 편리했다.
일단 ether.js 에서 사용하는 bignumber의 경우에는 elliptic로직에서 쓰이는것과 같은 방법이기 때문에 가장 안전하다고 한다.
오랜기간 서칭을 한 결과 몇가지 케이스에 대한 방안을 알 수 있었다.
1. 이더리움 단위로 만들 경우
//ethers.utils.formatEther( value ) ⇒ string
const value = BigNumber.from("1000000000000000000");
formatEther(value);
// '1.0'
2. 특정 단위로 바꿀 때 (빅넘버 형태 리턴)
//ethers.utils.parseUnits( value [ , unit = "ether" ] ) ⇒ BigNumber
parseUnits("1.0");
// { BigNumber: "1000000000000000000" }
parseUnits("1.0", "ether");
// { BigNumber: "1000000000000000000" }
parseUnits("1.0", 18);
// { BigNumber: "1000000000000000000" }
parseUnits("121.0", "gwei");
// { BigNumber: "121000000000" }
parseUnits("121.0", 9);
// { BigNumber: "121000000000" }
3. 특정단위로 바꿀 때 (스트링 형태로 바꿀때)
const oneGwei = BigNumber.from("1000000000");
const oneEther = BigNumber.from("1000000000000000000");
formatUnits(oneGwei, 0);
// '1000000000'
formatUnits(oneGwei, "gwei");
// '1.0'
formatUnits(oneGwei, 9);
// '1.0'
formatUnits(oneEther);
// '1.0'
formatUnits(oneEther, 18);
// '1.0'
4. 코드에 적용하기 ( API 분기 시키기 & 이더리움 value값 bignumber 형태로 타입체크하기)
일반적인 경우라면 상관이 없었지만 나는 ETL 데이터를 가져와서 그걸 타입체크까지 해줘야 했기 때문에 입력값은 string으로 받고 2개의 객체를 생성해서 bigNumber를 따로 class-validator로 검사 해주는데 사용하였다. 코드는 다음과 같다.
if (searchByRequest.flag == searchTransactionFlag.value) {
const minValue = ethers.utils.parseUnits(
pagingSearchByRequest.minValue,
0,
);
const maxValue = ethers.utils.parseUnits(
pagingSearchByRequest.maxValue,
0,
);
const validValue = new ValidValue(minValue, maxValue);
const errors = await validate(validValue);
if (errors.length > 0) {
this.logger.error(getConstraintsMessage(errors));
return invalidInputError(errors);
} else {
const response_value =
await this.transactionsService.searchTransactionByValue(
pagingSearchByRequest,
);
return response_value;
}
여기서는 api를 하나의 입력값으로 받아와서 하나는 시간검색 하나는 value검색으로 구현하였다. 프론트엔드 페이지가 하나이고 리턴 포멧이 같은 경우 다음과 같이 하나의 api로 만드는것이 좋을 수 있다. 이런 경우 flag 변수를 하나 받아와서 분기처리 시켜준다. 여기서 쓴 ParseUnits의 경우는 bignumber 형태로 값을 리턴해주기 때문에 validValue 부분에서 타입체크가 들어가게 된다.
export class ValidValue {
@IsNumber()
minValue?: BigNumber;
@IsNumber()
maxValue?: BigNumber;
constructor(minValue: BigNumber, maxValue: BigNumber) {
this.maxValue = maxValue;
this.minValue = minValue;
}
}
export enum searchTransactionFlag {
time = 'time',
value = 'value',
}
이는 다음과 같이 enum 타입으로 지정하고 validate를 시키기 위한 생성자를 만듦으로서 사용하였다.
또한 ether.js에 자체적인 logger가 있고 여기서 숫자를 체크하는 함수가 있었지만 어떠한 이유에서인지 작동하지 않아 결국 calss-validator를 사용하였다. ether.js에서 도 어차피 비슷한 방식으로 체크를 해주기 때문에 큰 상관은 없어보인다.
'개발 > backend' 카테고리의 다른 글
비트연산/ type of => " |" vs 논리연산 => "||" 구분하기!! (0) | 2021.12.14 |
---|---|
Nest.js) Swagger에서 변수 optional하게 처리가 안될 경우 해결 방법 (0) | 2021.12.13 |
Nest.js 수정사항 총 정리 02 ) 예외처리 패턴 - Invalid Input 리팩토링 (0) | 2021.12.07 |
Nest.js 수정사항 총 정리 01 ) 예외처리 패턴 - Internal Server Error 리팩토링 (0) | 2021.12.07 |
Nest.js) Validation 하기 , validation Pipe 사용하기 (0) | 2021.12.06 |