是否檢查了傳入塊中以前未見過的交易的 scriptPubKey?如果有,在哪裡?
今天我正在閱讀 bitcoind src,並試圖找出當節點收到帶有交易的新塊時 scriptPubKey 在哪裡執行,例如來自新塊的交易可能不存在於 mempool 中。
- 查找執行腳本的函式:
<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
- 查看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(),然後該塊最終被接受為小費。