動區動趨-最具影響力的區塊鏈新聞媒體
  • Home
    • Home Layout 1
    • Home Layout 2
    • Home Layout 3
  • Browse
    • News
    • Movie
    • Music
    • Technology
    • Howto & Style
    • Entertainment
    • Gaming
  • Features
    • Youtube Video
    • Vimeo Video
    • Dailymotion Video
    • Self-hosted Video
    • User Profile
    • Playlists
    • User-created Playlist
    • Favorite Playlist (Private)
    • Watch Later Playlist (Private)
    • All JNews Features
No Result
View All Result
  • Login
  • Register
UPLOAD
動區動趨-最具影響力的區塊鏈新聞媒體
No Result
View All Result
Currently Playing

ABS獨家專訪》Gitcoin共同創辦人Scott:台灣是現實與Web3治理的重要交匯點

ABS獨家專訪》Gitcoin共同創辦人Scott:台灣是現實與Web3治理的重要交匯點

ABS獨家專訪》Gitcoin共同創辦人Scott:台灣是現實與Web3治理的重要交匯點

搶先看
ABS獨家專訪》Gate.io CEO韓林:無懼銀行進軍加密服務,台北特別有人情味

ABS獨家專訪》Gate.io CEO韓林:無懼銀行進軍加密服務,台北特別有人情味

搶先看

6 Sci-fi Gadgets in Movie We Wish Actually Existed

Movie

The 10 best games to play on your new PlayStation 4

Gaming

Tesla’s Chinese factory just delivered its first cars

News

天價手續費分析:Bitfinex「2,300萬鎂ETH」Gas費案例背後原因解析

Bitfinex 的一個主要錢包在九月底以 7676 ETH (約2,300 萬美元)的天價手續費向非託管交易所 DeversiFi 匯了一筆 10 萬美元 USDT 的轉帳。動區專欄作者 慢霧科技 Slow Mist 以此案例來做關鍵分析,已從中發掘出問題發生的原因,並總結出應該注意的重點教訓。
(前情提要:Bitfinex以「2,300萬鎂的ETH當手續費」轉帳10萬USDT!DeversiFi不明原因導致、遭駭為謠言)

事件背景

分析源自一筆轉帳金額 100,000 USDT,手續費卻高達 7,676 枚 ETH 的天價手續費交易。

關鍵程式碼分析

根據此 Issue 中的描述,開始了分析。

我們以倒敘的方式來說明問題,這樣更方便理解。核心問題是 `ethjs-util` 的 `intToBuffer` 不支持傳入浮點型的數據。

首先看看關鍵的程式碼,提得比較多的是 `ethereumjs` 的問題,主要聚焦討論的是 `maxPriorityFeePerGas` 和 `maxFeePerGas` 這兩個參數的值,由於傳入的浮點型,導致計算錯誤,得到了錯的手續,從而發生了「天價手續的事件」。

經過分析後,這兩個參數都是經過 `toBuffer` 進行處理的,所以開始分析 `toBuffer`。(https://github.com/ethereumjs/ethereumjs-monorepo/blob/cf95e04c6a/packages/tx/src/eip1559Transaction.ts#L200-L201)


this.maxFeePerGas = new BN(toBuffer(maxFeePerGas === '' ? '0x' : maxFeePerGas))
    this.maxPriorityFeePerGas = new BN(
      toBuffer(maxPriorityFeePerGas === '' ? '0x' : maxPriorityFeePerGas)
    )

`toBuffer` 會去調用 `ethjs-util` 的 `intToBuffer` 函數,這個函數主要處理了兩件事情。

(https://github.com/ethjs/ethjs-util/blob/e9aede6681/dist/ethjs-util.js#L1950)


function intToBuffer(i) {
  var hex = intToHex(i);
  return new Buffer(padToEven(hex.slice(2)), 'hex');
}

 

1. 將 int 轉成 Hex

(https://github.com/ethjs/ethjs-util/blob/e9aede6681/dist/ethjs-util.js#L1939)


function intToHex(i) {
   var hex = i.toString(16); // eslint-disable-line
   return '0x' + hex;
 }

 

2. 判斷是否可以被 2 整除,如果不行需要在字符開頭添加一個 0 ,這裡主要是為了能夠成功的將數據 2 個 1 組寫入到 buffer。

(https://github.com/ethjs/ethjs-util/blob/e9aede6681/dist/ethjs-util.js#L1920)


function padToEven(value) {
  var a = value; // eslint-disable-line

  if (typeof a !== 'string') {
    throw new Error('[ethjs-util] while padding to even, value must be string, is currently ' + typeof a + ', while padToEven.');
  }
  if (a.length % 2) {
    a = '0' + a;
  }
  return a;
}

以出錯的示例數據:`33974229950.550003` 進行分析,經過 `intToBuffer` 函數中的 `intToHex` 和 `padToEven` 處理後得到 `7e9059bbe.8ccd` ,這部分瀏覽器 js 和 nodejs 的結果都是一致的。

不一致的地方是在 new Buffer 的操作:

`new Buffer(padToEven(hex.slice(2)), ‘hex’);`

處理方式分析:瀏覽器 js

通過 webpack 打包好 js 文件並對文件進行引用,然後在瀏覽器上進行調試分析。

首先輸入的示例字符 `33974229950.550003` 會進入到 intToBuffer 的函數中進行處理。

同步分析 intToBuffer 的處理過程,這部分和「關鍵程式碼分析」部分的程式碼邏輯是一樣的,處理轉換部分得到的結果是 `7e9059bbe.8ccd`。

接下來分析如何將轉換後的字符填充進入的 buffer 中,通過這步可以得到 buffer 的內容是 `126, 144, 89, 187, 14, 140, 205` 對應的是 `7e, 90, 59, bb, e, 8c, cd`。


> 0x7e -> 126
> 0x90 -> 144
> 0x59 -> 89
> 0xbb -> 187
> 0xe -> 14
> 0x8c -> 140
> 0xcd -> 205

處理方式分析:nodejs

由於瀏覽器上出問題的是 `7e9059bbe.8ccd` 在寫入 buffer 的時候小數點被 `parseInt` 吃掉了導致數據出錯,但是經過分析,node 的數據也是錯誤的,且產生錯誤的原因是和瀏覽器的不一樣。

首先我們先看下如下的示例:

node 三組不同的數據填充到 buffer 得到的結果居然是一樣的,經過分析 node 的 buffer 有個小特性,就是 2 個一組切分後的數據,如果沒法正常通過 hex 解析的,就會把那一組數據以及之後的數據都不處理了,直接返回前面可以被正常處理的那部分數據。可以理解為被截斷了。這部分可以參考 node 底層的 buffer 中 `node_buffer.cc` 中的程式碼邏輯。

執行結果的比較

node 由於會將原始數據 `7e9059bbe.8ccd` 中的 `e.` 及之後的數據進行截斷,所以最終錯誤的值是 `7e9059bb`,相比正確的值 `07e9059bbe` 小。

node 的執行結果:

瀏覽器由於會將原始數據 `7e9059bbe.8ccd` 中的 `.` 吃掉,所以最終錯誤的值是 `7e9059bbe8ccd`,相比正確的值 `07e9059bbe` 大很多。

瀏覽器的執行結果:

問題的原因

`ethjs-util` 的 `intToBuffer` 函數不支持浮點型的數據,且在這個函數中沒有判斷傳入的變量類型,來確保變量類型是預期內的。由於 `ethereumjs` 的 `toBuffer` 引用了 `ethjs-util` 的 `intToBuffer` 進行處理,也沒有對數據進行檢查。導致了這次事件的發生,所幸最終善良的礦工歸還了「天價手續費 7626 ETH」。

吸取的教訓

從第三方的庫的角度來看,在編碼過程中應該要遵循可靠的安全的編碼規範,在函數的開頭要對傳入的數據進行合法性的檢查,確保數據和程式碼邏輯是按照預期內執行。

從庫的使用者的角度來看,使用者應該要自行閱讀第三方庫的開發文檔和對接文檔,並且也要對程式碼中接入第三方庫的邏輯進行測試,通過構造大量的數據進行測試,確保業務上能夠正常按照期望執行,保證高標準的測試用例的覆蓋率。

📍相關報導📍

完整解析|以太坊天價手續費的真相: 資金盤直銷騙局GoodCycle上演誤殺瞞天記!

「我只是付了 1 美元USDT,為什麼其他幣都沒了?」— 小心轉帳權限騙局

最狂胖手指!有人轉帳「133美元」,卻付了「265萬美元」手續費,幸運礦工是星火礦池


讓動區 Telegram 新聞頻道再次強大!!立即加入獲得第一手區塊鏈、加密貨幣新聞報導。

LINE 與 Messenger 不定期為大家服務

加入好友

加入好友 

No Result
View All Result

近期文章

  • 精選文章搶先看!動區登入Access質押訂閱服務,解鎖寶貴資訊快人一步
  • ABS獨家專訪》Gitcoin共同創辦人Scott:台灣是現實與Web3治理的重要交匯點
  • ABS獨家專訪》Gate.io CEO韓林:無懼銀行進軍加密服務,台北特別有人情味
  • 快訊!BTC 現在已來到 58996.2
  • 快訊!BTC 現在已來到 58815.03
Next Post
葉倫警告10/18大限將至,美國眾議院通過《暫停債務上限法案》;美股、比特幣凌晨下跌

葉倫警告10/18大限將至,美國眾議院通過《暫停債務上限法案》;美股、比特幣凌晨下跌

Copyright (c) 2019 by Jegtheme.
  • About
  • Buy JNews
  • Request A Demo
  • Contact

Welcome Back!

Login to your account below

Forgotten Password? Sign Up

Create New Account!

Fill the forms below to register

All fields are required. Log In

Retrieve your password

Please enter your username or email address to reset your password.

Log In

Add New Playlist

- Select Visibility -

    No Result
    View All Result
    • Account
    • BlockTempo Beginner – 動區新手村
    • Change Password
    • Forgot Password?
    • Home 1
    • Home 2
    • Home 3
    • Jin-homepage
    • Latest
    • Login
    • Profile
    • Register
    • Reset Password
    • Trending
    • Users
    • Users List Item
    • 不只加密貨幣,談談那些你不知道的區塊鏈應用|動區新手村
    • 所有文章
    • 關於 BlockTempo

    © 2025 JNews - Premium WordPress news & magazine theme by Jegtheme.