메인 콘텐츠로 건너뛰기
OP Stack Hacks는 OP Stack으로 할 수 있지만 현재 프로덕션 사용을 위한 것이 아님이 명시된 작업들입니다.OP Stack Hacks는 가벼운 마음으로 시도할 수 있는 것이 아닙니다. OP Stack Hacks에 대해서는 충분한 개발자 지원을 받을 수 없습니다. 직접 손을 더럽히고 지원 없이 작업할 각오를 하십시오.
OP Stack의 활용 방법 중 하나는 현재 지원되지 않는 연산을 가속화하기 위해 새 프리컴파일(precompile)이 포함된 EVM을 실행하는 것입니다. 이 튜토리얼에서는 4바이트 이하로 호출되면 상수 값을 반환하고, 그보다 많은 바이트로 호출되면 오류를 반환하는 간단한 프리컴파일을 만듭니다. 새 프리컴파일을 생성하려면 op-geth/core/vm/contracts.go 파일을 수정해야 합니다.
1

82번째 줄의 PrecompiledContractsBerlin(또는 프리컴파일 목록이 다시 변경된 경우 이후 포크)에 추가합니다

  • 새 프리컴파일의 이름을 딴 구조체를 추가하고,
  • 표준 프리컴파일과 충돌할 가능성이 낮고 EIP-7587 예약 범위를 피하는 주소(예: 0x1337)를 사용합니다.
2

프리컴파일 코드를 추가합니다

3

op-geth를 중지하고 다시 컴파일합니다.

4

op-geth를 재시작합니다

5

다음 명령을 실행하여 프리컴파일 호출이 성공한 결과와 오류가 발생한 결과를 확인합니다.

작동 방식

다음은 프리컴파일 인터페이스 정의입니다.
즉, 모든 프리컴파일에는 두 개의 함수가 필요합니다.
  • RequiredGas는 호출에 드는 gas 비용을 반환합니다. 이 함수는 바이트 배열을 입력으로 받아 gas 비용이라는 단일 값을 반환합니다.
  • Run은 실제 프리컴파일을 실행합니다. 이 함수도 바이트 배열을 입력으로 받지만, 호출 출력(바이트 배열)과 오류라는 두 개의 값을 반환합니다.
프리컴파일을 변경하는 각 포크마다 주소를 PrecompiledContract 정의에 매핑하는 map이 있습니다.
map의 키는 주소입니다. 주소는 common.BytesToAddress([]byte{<bytes to convert to address go here>})를 사용하여 바이트로부터 생성합니다. 이 경우에는 0x13과 0x37 두 바이트가 있으며, 이를 합치면 0x0…1337 주소가 됩니다. 프리컴파일된 컨트랙트 인터페이스의 구문은 &<variable name>{}입니다. 다음 단계는 프리컴파일된 컨트랙트 자체를 정의하는 것입니다.
먼저 프리컴파일을 위한 구조체를 생성합니다.
그런 다음 해당 구조체의 일부로 함수를 정의합니다. 여기에서는 일정한 양의 gas만 요구하지만, 물론 계산을 훨씬 더 정교하게 할 수도 있습니다.
다음으로 오류를 위한 변수를 정의합니다.
이것이 실제로 프리컴파일을 실행하는 함수입니다.
필요한 경우 오류를 반환합니다. 이 프리컴파일이 최대 4바이트의 입력을 허용하는 이유는 모든 표준 호출(예: cast 사용)에는 함수 시그니처를 위한 최소 4바이트가 포함되기 때문입니다. return a, b는 Go에서 함수가 두 개의 값을 반환하는 방식입니다. 여기에서는 오류를 반환하므로 일반 출력은 아무것도 없는 nil입니다.
마지막으로 출력 버퍼를 생성하고 값을 채운 다음 반환합니다.

결론

추가 프리컴파일이 포함된 OP Stack 체인은 유용하게 활용할 수 있습니다. 예를 들어 암호화 연산을 인터프리트되는 EVM 코드에서 컴파일된 Go 코드로 옮겨 필요한 연산량을 더욱 줄일 수 있습니다.