Attack

是否檢查了傳入塊中以前未見過的交易的 scriptPubKey?如果有,在哪裡?

  • March 6, 2016

今天我正在閱讀 bitcoind src,並試圖找出當節點收到帶有交易的新塊時 scriptPubKey 在哪裡執行,例如來自新塊的交易可能不存在於 mempool 中。

  1. 查找執行腳本的函式:

<https://github.com/bitcoin/bitcoin/search?utf8=%E2%9C%93&q=EvalScript>

  • src/script/interpreter.cpp 這個文件中 EvalScript 函式的原始碼僅在這 2 個文件中使用:

  • src/policy/policy.cpp

  • src/腳本/sign.cpp

  1. 查看sign.cpp

Evalscript -> CombineSignatures -> /src/bitcoin-tx.cpp : MutateTxSign -> MutateTx -> CommandLineRawTx -> main

當我們創建新交易時使用的這個函式 3. 審查 政策.cpp

Evalscript -> AreInputsStandard -> /src/main.cpp: AcceptToMemoryPool

AcceptToMemoryPool

  • src/main.cpp 稍後
  • src/wallet/wallet.cpp -> CommitTransaction - 這是創建自己的交易功能
  • src/rpcrawtransaction.cpp -> sendrawtrnsaction - rpc 函式發送 rawtx
  • src/txmempool.cpp -> 沒有電話,只有評論

最後一個是 src/main.cpp

AcceptToMemoryPool -> ProcessMessage on message “tx” ,新的單個 tx 到池接收 AcceptToMemoryPool -> DisconnectTip

DisconnectTip -> InvalidateBlock 評估塊並將所有交易發送回池,並進行所有驗證和腳本評估

DisconnectTip -> ActivateBestChainStep

 // Disconnect active blocks which are no longer in the best chain.
bool fBlocksDisconnected = false;
while (chainActive.Tip() && chainActive.Tip() != pindexFork) {
   if (!DisconnectTip(state))
       return false;
   fBlocksDisconnected = true;
}

如果我們有孤兒交易從孤兒池中取出並進行所有驗證

沒有找到更多其他連結

由此我可以得出結論,如果帶有 bitcoind 的節點收到新塊,其中包含不在 mempool 中的交易,我們會將這個 tx 添加到區塊鏈而不執行 scriptPubKey。

因此,如果相同的“誠實”礦工包含帶有無效腳本的 tx,例如花費相同的一枚硬幣的不正確簽名,所有 bitcoind 節點將其添加到區塊鏈而不使用 eval 腳本並且不會檢測到這一點

不可能是真的!我的錯誤在哪裡?

記憶體池或孤立交易池的行為根本不應該影響區塊的有效性。

當一個塊進來時:

  • main.cpp:ProcessMessage處理消息處理,並分派到:
  • main.cpp:ProcessNewBlock專門處理塊消息,它使用 AcceptBlock 將其儲存在磁碟上,然後呼叫:
  • main.cpp:ActivateBestChain嘗試驗證潛在的新最佳鏈並切換到它。對於每個原子“重組”步驟,它呼叫:
  • main.cpp:ActivatebestChainStep,它將嘗試使用以下方法驗證要添加到鏈頂端的新塊:
  • main.cpp:ConnectTip,它使用以下方式進行實際處理:
  • main.cpp: ConnectBlock,它將遍歷塊的事務並使用以下方法驗證它們的輸入:
  • main.cpp:CheckInputs,它為要執行的每個腳本執行建立一個 CScriptCheck 對象列表,這些對像是從另一個執行緒驗證的。ConnectBlock 等待這些執行緒完成並處理結果。在這些執行緒中,我們呼叫:
  • main.cpp: **CScriptCheck::operator()**執行單個封裝腳本執行,使用:
  • script/interpreter.cpp:VerifyScript對腳本進行驗證,包括執行 scriptPubKey + 其支出 scriptSig 使用:
  • 腳本**/interpreter.cpp** :評估腳本。

因此,應該為一個塊花費的所有 scriptPubKeys 執行 EvalScript(),然後該塊最終被接受為小費。

引用自:https://bitcoin.stackexchange.com/questions/41016