본문 바로가기

코딩(Coding)

OpenZeppelin 및 Ethers.js를 사용하여 Solidity에서 ECDSA로 오프체인 결과 및 화이트리스트 확인

반응형

OpenZeppelin 및 Ethers.js를 사용하여 Solidity에서 ECDSA로 오프체인 결과 및 화이트리스트 확인

 

가스 절약을 위해 값비싼 계산을 오프체인으로 오프로드하는 것은 간단합니다.

Unsplash의 Shubham Dhage의 사진
Table of Contentsi. Introduction ii. Practical example iii. Conclusion

Ethereum의 높은 가스 문제는 암호 거래자, 블록체인 개발자 또는 이 분야의 열광자로서 낯설지 않아야 합니다. $3000 지역에서 Ether의 가격이 강세를 보이고 평균 50–70 Gwei의 가스 가격이 상승함에 따라 모든 거래에 대한 가스 수수료가 점점 더 비싸지고 간단한 송금에 약 $4 USD가 소요됩니다.

가스 문제를 해결하는 방법은 이 계산을 오프체인으로 두고 서버가 작업을 수행하도록 하는 것입니다.

ECDSA를 가르치는 온라인 자습서에는 수학 사용이 포함되어 있습니다. s, r, v에 관한 것우리 모두의 개발자 (코드 원숭이) 동의할 수 있고, 지루하고 버그 없이 구현하기 어렵습니다. 따라서 이 기사에서는 OpenZeppelin 및 Ethers.js가 작성한 계약의 내장 기능을 사용하여 이 기능을 구축할 것입니다.

이 프로젝트에서는 ECDSA의 일반적인 사용 사례를 사용하여 NFT 프로젝트에 대한 화이트리스트를 설정하는 방법을 보여주고 시작하는 데 도움이 되는 코드 조각을 포함할 것입니다.

이 프로젝트는 JavaScript와 Solidity로 작성되었습니다.

1. 설정

ECDSA를 준비하려면 새 지갑을 생성하고 이 프로젝트에서만 서명 서명자로 사용해야 합니다. 이 지갑을 다른 용도로 사용하지 말고 이 프로젝트의 메시지 서명에만 사용하십시오.

지갑을 생성한 후 나중에 사용할 수 있도록 개인 키를 저장합니다.

2. 오프체인 서명

2.1. 시작하려면 먼저 다음을 실행하여 Ether.js를 설치해야 합니다.

npm run ethers

다음을 통해 프로젝트로 가져오기:

import ethers from ethers

2.2. 그런 다음 새 서명자를 생성하여 서명자 인스턴스를 초기화할 수 있습니다. Wallet 라이브러리 사용:

const signer = new ethers.Wallet("0x" + "");

추가하는 것을 잊지 마십시오 0x Metamask에서 직접 내보낸 경우 개인 키의 접두사에 있습니다.

2.3. 메시지를 함께 포장하면 화이트리스트를 위해 주소와 nonce를 포장할 수 있습니다.

let message = ethers.utils.solidityPack(["address", "uint256"], ["0xabc", "0"]);

메시지를 연결하여 다음 섹션에서 해시하기 위한 것입니다. Ethers.js는 다음을 포함한 다양한 변수를 지원합니다. string 와 같은 배열 uint256[]:

2.4. keccak256으로 메시지를 해시하고 서명자 지갑으로 서명합니다.

message = ethers.utils.solidityKeccak256(["bytes"], [message]); const signature = await signer.signMessage(ethers.utils.arrayify(message));

이것 signature 서명자의 개인 키로 메시지에 서명한 서명입니다.

검증된 매개변수와 함께 이 서명을 블록체인에 전달하여 매개변수가 유효한지 확인할 수 있습니다.

전체 코드 스니펫:

3. 온체인 검증

3.1. 온체인 서명을 확인하기 위해 OpenZeppelin이 작성한 계약 EDCSA를 사용할 수 있습니다. 사용하려면 Openzepplin을 로컬로 설치하거나 Remix에서 사용하십시오.

npm install @openzeppelin/contracts

3.2. setter를 사용하여 서명자에 대한 저장소를 온체인으로 설정합니다.

address signer;function setSigner(address _signer) external { signer = _signer; }

3.3. 그런 다음 값을 함께 묶습니다. abi.encodePacked 그리고 그것을 해시 keccack256:

bytes32 hash = keccak256(abi.encodePacked(msg.sender, nonce));

3.4. 서명을 이더리움 서명 메시지로 전환:

bytes32 message = ECDSA.toEthSignedMessageHash(hash);

3.5. 서명에서 서명자 주소 복구:

address receivedAddress = ECDSA.recover(message, signature);

3.6. 메시지 서명자가 체인 상의 서명자 저장소와 일치하는지 확인하고 서명자가 일치하는 경우에만 승인합니다.

require(receivedAddress != address(0) && receivedAddress == signer);

전체 코드 스니펫은 다음과 같습니다.

반응형