• 【超完整懶人包】認識比特幣!原理與應用全面解析|動區新手村
  • Account
  • Account
  • BlockTempo Beginner – 動區新手村
  • Change Password
  • Forgot Password?
  • Home 3
  • Login
  • Login
  • Logout
  • Members
  • Password Reset
  • Register
  • Register
  • Reset Password
  • User
  • 不只加密貨幣,談談那些你不知道的區塊鏈應用|動區新手村
  • 動區動趨 BlockTempo – 最有影響力的區塊鏈新聞媒體 (比特幣, 加密貨幣)
  • 所有文章
  • 最完整的「區塊鏈入門懶人包」|動區新手村
  • 服務條款 (Terms of Use)
  • 關於 BlockTempo
  • 隱私政策政策頁面 / Privacy Policy
動區動趨-最具影響力的區塊鏈新聞媒體
  • 所有文章
  • 搶先看
  • 🔥動區專題
  • 🔥Tempo 30 Award
  • 加密貨幣市場
    • 市場分析
    • 交易所
    • 投資分析
    • 創投
    • RootData
  • 區塊鏈商業應用
    • 金融市場
    • 銀行
    • 錢包
    • 支付
    • defi
    • 區塊鏈平台
    • 挖礦
    • 供應鏈
    • 遊戲
    • dApps
  • 技術
    • 比特幣
    • 以太坊
    • 分散式帳本技術
    • 其他幣別
    • 數據報告
      • 私人機構報告
      • 評級報告
  • 法規
    • 央行
    • 管制
    • 犯罪
    • 稅務
  • 區塊鏈新手教學
  • 人物專訪
    • 獨立觀點
  • 懶人包
    • 比特幣概念入門
    • 從零開始認識區塊鏈
    • 區塊鏈應用
  • 登入
No Result
View All Result
  • 所有文章
  • 搶先看
  • 🔥動區專題
  • 🔥Tempo 30 Award
  • 加密貨幣市場
    • 市場分析
    • 交易所
    • 投資分析
    • 創投
    • RootData
  • 區塊鏈商業應用
    • 金融市場
    • 銀行
    • 錢包
    • 支付
    • defi
    • 區塊鏈平台
    • 挖礦
    • 供應鏈
    • 遊戲
    • dApps
  • 技術
    • 比特幣
    • 以太坊
    • 分散式帳本技術
    • 其他幣別
    • 數據報告
      • 私人機構報告
      • 評級報告
  • 法規
    • 央行
    • 管制
    • 犯罪
    • 稅務
  • 區塊鏈新手教學
  • 人物專訪
    • 獨立觀點
  • 懶人包
    • 比特幣概念入門
    • 從零開始認識區塊鏈
    • 區塊鏈應用
  • 登入
No Result
View All Result
動區動趨-最具影響力的區塊鏈新聞媒體
No Result
View All Result
Home 技術 以太坊

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

慢霧科技 Slow Mist by 慢霧科技 Slow Mist
2021-09-30
in 以太坊, 專欄作者, 技術
A A
天價手續費分析:Bitfinex「2,300萬鎂ETH」Gas費案例背後原因解析

Bitfinex「2,300萬鎂ETH」天價 Gas 費用案例分析,圖源:Haberler Ankara

179
SHARES
分享至Facebook分享至Twitter

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

本文目錄

  • 事件背景
  • 關鍵程式碼分析
  • 處理方式分析:瀏覽器 js
  • 處理方式分析:nodejs
  • 執行結果的比較
  • 問題的原因
  • 吸取的教訓
    • 完整解析|以太坊天價手續費的真相: 資金盤直銷騙局GoodCycle上演誤殺瞞天記!
    • 「我只是付了 1 美元USDT,為什麼其他幣都沒了?」— 小心轉帳權限騙局
    • 最狂胖手指!有人轉帳「133美元」,卻付了「265萬美元」手續費,幸運礦工是星火礦池

事件背景

分析源自一筆轉帳金額 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 不定期為大家服務

加入好友

加入好友 

Tags: ETH天價手續費


關於我們

動區動趨

為您帶來最即時最全面
區塊鏈世界脈動剖析
之動感新聞站

訂閱我們的最新消息

動區精選-為您整理一週間的國際動態

戰略夥伴

Foresight Ventures Foresight News

主題分類

  • 關於 BlockTempo

動區動趨 BlockTempo © All Rights Reserved.

No Result
View All Result
  • 所有文章
  • 搶先看
  • 市場脈動
  • 商業應用
  • 區塊鏈新手教學
  • 區塊鏈技術
  • 數據洞察
  • 政府法規
  • RootData
  • 登入

動區動趨 BlockTempo © All Rights Reserved.