BTC
ETH
HTX
SOL
BNB
시장 동향 보기
简中
繁中
English
日本語
한국어
ภาษาไทย
Tiếng Việt

ETH와 채팅하는 법을 가르쳐주세요

이 기사는 약 4218자로, 전체를 읽는 데 약 7분이 소요됩니다
블록체인 브라우저에서 자주 볼 수 있는 입력 데이터는 정확히 무엇입니까?
AI 요약
펼치기
블록체인 브라우저에서 자주 볼 수 있는 입력 데이터는 정확히 무엇입니까?

머리말

보조 제목

머리말얼마전 Poly Network 도용 사건 에피소드에서 주소가 해커 주소로 이전되어 입력 데이터에 USDT에 동결되었다고 알렸으니 USDT를 사용하지 마세요. 13.37 ETH를 주소로.Chuangyu 블록체인 보안 연구소 알기

Input data

당신을 위해 대답하십시오.

보조 제목

이더리움 프로토콜에서 트랜잭션(트랜잭션)이 계약 생성일 때 입력 데이터는 계정 초기화 프로그램의 EVM 코드입니다.

그리고 트랜잭션이 메시지 호출인 경우 입력 데이터는 계약 기능 호출 데이터입니다.

정상적인 상황에서 이체 함수 호출과 같은 간단한 메시지 호출은 이체할 주소_to와 이체할 금액_amount를 입력해야 하며, 이러한 기본 정보는 입력 데이터에 포함되어 있습니다.

컨트랙트를 호출하는 이체 트랜잭션의 구체적인 분석을 통해 메시지 호출 시 입력 데이터의 구조를 이해해 보자.

분석 형태:

  • 원형:

  • 분석을 위해 원본 입력 데이터를 세 부분으로 나눕니다.

  • 0xa9059cbb: 함수 식별자

00000000000000000000000345d8e3a1f62ee6b1d483890976fd66168e390f2: 첫 번째 매개변수는 전송하려는 주소인 주소로 32바이트, 즉 64개의 16진수로 채워집니다.

00000000000000000000000000000000000000000054b7d8ed70650b290000: 두 번째 매개 변수는 이체하려는 금액인 value이며 32바이트, 즉 64개의 16진수로 채워집니다.

비교 분석을 통해 입력 데이터의 기본 구조는 함수 식별자 + 매개 변수임을 알 수 있습니다.

기능 식별자"transfer(adddress,uint256)"여기서 함수 식별자는 함수 선택자입니다.공식 문서에 따르면 함수 선택자는 함수 서명(왼쪽에 상위 비트가 있는 빅 엔디안)의 Keccak(SHA-3) 해시의 처음 4바이트입니다.

코드 bytess4(keccake256(

)) 또는 온라인 도구를 사용하여 이 기능 서명을 얻을 수 있습니다.

아래 그림은 암호화 결과(a9059cbb)의 처음 4바이트가 입력 데이터의 함수 식별자와 일치함을 보여줍니다.

함수 서명이 4바이트로 잘린 이유는 가스 비용을 고려하기 위함입니다.

트랜잭션에서 0바이트는 4가스를 지불해야 하는 반면, 0이 아닌 바이트는 0바이트의 17배인 68가스를 필요로 합니다.

SHA-3 암호화에서 생성된 32바이트 임의 문자열은 0이 아닌 바이트가 더 많은 경향이 있으므로 대략적인 비용은 32x68=2176 gas이고 절단 비용은 약 4x68=272 gas로 4개로 절단되었음을 나타냅니다. 바이트 약 8배의 가스비를 절약할 수 있습니다.

함수 식별자의 기능은 호출할 함수를 지정하는 것입니다.동일한 계약에서 두 개의 서로 다른 함수의 SHA-3 서명의 처음 4바이트가 동일할 확률은 매우 작으므로 4바이트로 잘라도 실제로 함수 호출에 영향을 미칩니다.

매개변수

일반적인 정적 유형 요약: uint, bool, Address, bytes[0-32], 동적 배열 유형: bytes, string, address[], bytes32[].....

정적 유형

pyethereum의 ABI 인코딩 기능을 사용하여 다양한 데이터 유형이 인코딩되는 방법을 연구합니다.

import rlp  
from ethereum.abi import encode_abi

정적 유형

> encode_abi(["address", "uint256"],

[345d8e3a1f62ee6b1d483890976fd66168e390f2,1]).hex()

000000000000000000000000345d8e3a1f62ee6b1d483890976fd66168e390f2

0000000000000000000000000000000000000000000000000000000000000001

먼저 encode_abi 함수를 가져옵니다.

> encode_abi(["int8[3]"],[[1, 2, 3]).hex()

transfer(address,uint 256) 함수를 예로 들어보겠습니다.

0000000000000000000000000000000000000000000000000000000000000001

0000000000000000000000000000000000000000000000000000000000000002

0000000000000000000000000000000000000000000000000000000000000003

32바이트보다 작은 고정 길이 배열은 자동으로 32바이트로 채워집니다.

// 자동 채우기 0

> encode_abi(
    ["uint256[]", "uint256[]", "uint256[]"],

    [[0xa1, 0xa2, 0xa3], [0xb1, 0xb2, 0xb3], [0xc1, 0xc2, 0xc3]]

).hex()

동적 유형

동적 유형 인코딩은 조금 더 복잡하며 자리 표시자 처리를 위해 오프셋을 먼저 계산해야 합니다.간단한 예를 들어 설명하겠습니다.

// 파라미터 1의 오프셋: 32*3=96 16진수 0x6000000000000000000000000000000000000000000000000000000000000060

// 파라미터 2의 오프셋 = 파라미터 1의 오프셋 + 파라미터 1의 데이터 부분 길이 = 96+32*4=224 16진수 0xE000000000000000000000000000000000000000000000000000000000000000000000000

// 파라미터 3의 오프셋 = 파라미터 2의 오프셋 + 파라미터 2의 데이터 부분 길이 = 224+32*4=352 16진수 0x1600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000160

// 매개변수 1의 데이터는 오프셋 0x60에서 전달되기 시작합니다.

00000000000000000000000000000000000000000000000000000000000000003//요소

0000000000000000000000000000000000000000000000000000000000000a1//첫 번째 배열 요소

0000000000000000000000000000000000000000000000000000000000000a2//두 번째 배열 요소

0000000000000000000000000000000000000000000000000000000000000003

00000000000000000000000000000000000000000000000000000000000000b1

00000000000000000000000000000000000000000000000000000000000000b2

00000000000000000000000000000000000000000000000000000000000000b3

0000000000000000000000000000000000000000000000000000000000000a3//세 번째 배열 요소

0000000000000000000000000000000000000000000000000000000000000003

00000000000000000000000000000000000000000000000000000000000000c1

00000000000000000000000000000000000000000000000000000000000000c2

00000000000000000000000000000000000000000000000000000000000000c3

// 0xe0 위치. 매개변수 2의 데이터

//0x160 위치. 매개변수 3의 데이터

짧은 주소 공격

이전 분석 후 주소와 같은 정적 유형의 길이가 32바이트 미만인 경우 EVM은 규칙에 따라 길이를 32바이트로 채웁니다. 전송할 때 주소 뒤에 2개의 0이 있으면 EVM은 여전히 ​​address_to가 32비트라고 생각하므로 _value의 상위 비트에서 0을 가져와 보완할 것이며 amount의 비트 수는 2비트가 더 됩니다. 256을 곱합니다.

공격 과정은 다음과 같습니다.

악의적인 전송 주소의 마지막 바이트에서 0을 제거합니다.

000000000000000000000000641988625108585185752230bde001b3ebd0fc

기능 식별자: a9059cbb

00000000000000000000000000000000000000000000000000000000000000001

이전 주소:

이체 금액:

EVM의 채우기 규칙으로 인해 구문 분석 결과는 다음과 같습니다. 0 0000000000000000000000000100

분해 후 이체 금액이 두 자릿수, 즉 1바이트 증가하여 원래 이체 금액의 256배가 된 것을 확인했습니다.

000000000000000000000000641988625108585185752230bde001b3ebd0fc00

이전 주소:

00000000000000000000000000000000000000000000000000000000000000100

이체 금액:

보조 제목

입력 데이터에 정보를 첨부하는 방법

이더리움에서 직접 이체 거래를 위한 입력 데이터 필드에는 기본적으로 내용이 없지만 지갑을 설정하여 글 시작 부분의 "채팅 기능"을 구현할 수 있습니다.

메타마스크 지갑을 예로 들어 전송을 통해 입력 데이터 필드에 추가 정보를 첨부하는 방법을 보여줍니다.

3. 전송이 성공하면 etherscan에서 첨부된 정보를 볼 수 있습니다.

요약하다

보조 제목

ETH
Odaily 공식 커뮤니티에 가입하세요