LLVM을 사용하여 ETC 스마트 컨트랙트 언어 만들기 - 컴파일러 실행

입력 기능을 기능 목록의 시작 부분으로 이동

EVM-LLVM은 정의 된 기능의 순서에 따라 기능을 생성합니다. 따라서 입력 함수 main이 목록에서 첫 번째로 나타나는지 확인해야합니다.


auto *wrapper = GenerateWrapperFunction(FnIR);// You should include "llvm/IR/SymbolTableListTraits.h" here
using FunctionListType = SymbolTableList<Function>;
FunctionListType &FuncList = TheModule->getFunctionList();
FuncList.remove(wrapper);
FuncList.insert(FuncList.begin(), wrapper);

언어 프론트 엔드 컴파일 및 링크 LLVM 백엔드를 통합 할 때 llvm-config를 사용하여 링크 플래그 및 라이브러리를 지정할 수 있습니다. 이 경우 올바른 경로를 검색하려면 EVM-LLVM의 llvm-config를 사용해야합니다. 아래는 컴파일 옵션을 채우기 위해 llvm-config를 호출하는 예입니다.


clang++ -g toy.cpp `~/workspace/evm_llvm/build/bin/llvm-config --cxxflags --ldflags --system-libs --libs core` -o evmtoy

LLVM IR 생성

우리의 작은 컴파일러는 EVM 바이트 코드를 생성하는 데 사용될 특정 LLVM IR을 생성 할 수 있습니다. 다음은 방출 된 출력의 예입니다.



ready> def foo(a b) a*b + 2 * a + 3 * b;
ready> Emitting Smart contract IR:; ModuleID = 'My cool EVM function'
source_filename = "My cool EVM function"define void @main() {
entry:
  call void @llvm.evm.mstore(i256 64, i256 128)
  %0 = call i256 @llvm.evm.calldataload(i256 0)
  %1 = call i256 @llvm.evm.calldataload(i256 32)
  %2 = call i256 @foo(i256 %0, i256 %1)
  call void @llvm.evm.mstore(i256 0, i256 %2)
  call void @llvm.evm.return(i256 0, i256 32)
  unreachable
}define i256 @foo(i256 %a, i256 %b) {
entry:
  %multmp = mul i256 %a, %b
  %multmp1 = mul i256 2, %a
  %addtmp = add i256 %multmp, %multmp1
  %multmp2 = mul i256 3, %b
  %addtmp3 = add i256 %addtmp, %multmp2
  ret i256 %addtmp3
}; Function Attrs: nounwind writeonly
declare void @llvm.evm.mstore(i256, i256) #0; Function Attrs: nounwind readnone
declare i256 @llvm.evm.calldataload(i256) #1; Function Attrs: noreturn nounwind
declare void @llvm.evm.return(i256, i256) #2attributes #0 = { nounwind writeonly }
attributes #1 = { nounwind readnone }
attributes #2 = { noreturn nounwind }

작은 컴파일러 실행 EVM 바이트 코드 생성 생성 된 LLVM IR을 복사하여 파일에 붙여넣고 EVM-LLVM의 llc를 시작하여 EVM 어셈블리를 가져옵니다.

build/bin/llc -print-after-all -debug -mtriple=evm -filetype=asm toy.ll

검사를 위해 생성 된 EVM 어셈블리가 포함 된 toy.s 파일을 생성합니다. EVM 바이너리를 생성하려면 옵션에 -filetype = obj를 지정하십시오.


build/bin/llc -print-after-all -debug -mtriple=evm -filetype=obj toy.ll

이제 toytoys와 toy.o가 있습니다. 그러나 실행하려면 객체 파일 만 있으면됩니다. 마지막 단계 : 명령 행에서 실행하려면 바이너리를 16 진 문자열로 추출해야합니다. 간단한 Python 스크립트를 사용하여 작업을 수행합니다.


#!env python3
import sysdef get_contract(inputfile: str) -> str:
    import binascii
    output = []
    with open(inputfile, 'rb') as file:
        byte = file.read()
        output.append(binascii.hexlify(byte).decode("utf-8"))
    output_str = ''.join(output)
    print(output_str)if __name__ == "__main__":
    get_contract(sys.argv[1])

toy.o를 스크립트의 인수로 지정하면 EVM 바이너리가 일반 문자열로 표시됩니다.


5b6080604052602080356000808035610040909192939091604051806108200152604051610840016040526004580192565b60405160209003516040529052f35b8082029190910290019056

실행! 이제 새로 생성 된 EVM 스마트 계약을 실행할 때입니다! 명령 행에서 Geth의 EVM 도구를 시작하고 로컬에서 명령을 실행해야합니다. 명령 행 옵션은 다음과 같습니다.


evm --input 0000000000000000000000000000000000000000000123456789001234567890000000000000000000000000000000000000000000098765432109876543210 --code 5b6080604052602080356000808035610040909192939091604051806108200152604051610840016040526004580192565b60405160209003516040529052f35b8082029190910290019056 run

여기에 우리가 분석하는 방법이 있습니다. --input은 스마트 계약의 입력 값을 지정하고 --code는 스마트 계약 바이트 코드를 지정합니다. --input 옵션은 스마트 컨트랙트에 대한 입력을 포함하는 16 진 코드 문자열입니다. 일반적으로 함수 서명과 함수에 대한 인수가 포함됩니다. 위에서 구현 된 작은 입력 함수에서 사용자에게 두 개의 256 비트 정수 이외의 정보를 지정하도록 요청하지 않았습니다. 입력 필드에 함수 서명을 추가하고 입력 함수에 함수 선택기 메커니즘을 추가하거나 다른 유형의 인수를 구문 분석하는 등 더 많은 작업을 수행 할 수 있습니다. 입력 필드에서 값을 추출하는 데 특별히 사용되는 CALLDATALOAD 명령을 제외하고 입력 필드는 EVM에 표시되지 않습니다.


파싱 결과 EVM이 실행을 마치면 evm은 스마트 계약에서 반환 된 결과를 내 보냅니다.


0x00000674f561a2226dd39084c7dccd2395a994d8e52577362432026874293089

이 결과는 입력 함수 끝에서 RETURN 명령어를 사용하여 복사 한 32 바이트입니다.


16 views

Recent Posts

See All

ETC 피닉스 하드포크 업데이트 6월 1일 진행 예정

이더리움 클래식 메인넷은 다가오는 10.500.839블록에서 피닉스 하드포크를 활성화합니다. 예상 시점은 2020년 6월 1일입니다. 이번 하드포크는 아틀란티스, 아가타에 이어 이더리움 클래식의 세 번째 업그레이드입니다. 피닉스 하드포크 이후 이더리움 클래식과 이더리움은 완벽하게 호환되며 동일한 기능을 갖게 됩니다. 이번 하드포크의 주요 목표는 이더리움 이

LLVM을 사용하여 ETC 스마트 컨트랙트 언어 만들기 - 기타주제

LLVM IR 코드 생성 allocatea 명령은 현재 기능의 메모리 프레임에 32바이트 프레임 객체(기능-로컬 객체)를 할당. 메모리 공간 인덱싱 보통 EVM 스마트 계약 ABI 정보를 내보내는 것은 언어에 달려 있다. 하지만 우리는 계약서 ABI를 방출하기 위해 LLVM IR 패스를 작성할 수 있다. 제한 사항 EVM은 결정적 실행을 위해 설계되었습니다