來自同一地址的多筆交易
我想同時從同一個地址創建多個交易。由於每筆交易都需要 nonce(發送方地址的 tx 計數),我可以向 geth 詢問目前計數並創建第一個 tx,然後增加 nonce 並創建下一個,依此類推。我看到的問題是:
- 如果一個交易沒有被探勘,以下任何一個都不會被探勘(因為 nonce 是不正確的)。
- 如果一些 tx 被包含在一個塊中而一些在另一個塊中會發生什麼,順序可能會出錯。這個推理正確嗎?
如果不是,我想知道這種情況是否有更好的方法。
您還沒有說明您是在通過 geth 連接到區塊鏈時發送交易(在區塊鏈上),還是在未連接到區塊鏈時(區塊鏈外)製作交易。
Paul S 的回答是指交易的鏈下製作,您必須在隨後在區塊鏈上執行的原始交易中指定一個隨機數。
如果您在區塊鏈上發送交易,您可以使用 eth.sendTransaction(…) 而不使用 nonce。
例如,這裡有 3 筆交易從同一個“發件人”帳戶到同一個“收件人”帳戶。無需指定隨機數,因為它是自動生成的:
> eth.sendTransaction({from: '0x5e83b635f96da0752f991f0ebddc31249f452dea', to: '0x68acc3a13441b69016560d23e134c7931bbb27bb', value: web3.toWei(1, "ether")}); "0x92d6d2285b198b6b5cf80eca6d4292c9675fb53f47f786063df600d3be06dd09" > eth.sendTransaction({from: '0x5e83b635f96da0752f991f0ebddc31249f452dea', to: '0x68acc3a13441b69016560d23e134c7931bbb27bb', value: web3.toWei(2, "ether")}); "0x0c1280c8b2f38aec032494913c1d0e65edd511fcd15e2424483f9bbf51c7172e" > eth.sendTransaction({from: '0x5e83b635f96da0752f991f0ebddc31249f452dea', to: '0x68acc3a13441b69016560d23e134c7931bbb27bb', value: web3.toWei(3, "ether")}); "0x8b6998eea8b343a0f754cf2732a1f28caac3acdfbe97cca69f244f0614ea546a" > eth.getTransaction("0x92d6d2285b198b6b5cf80eca6d4292c9675fb53f47f786063df600d3be06dd09"); { blockHash: "0x8456088424a4cacd8b394b4e11732e3c96ca77ab4a999c6ba62b38ab61116b58", blockNumber: 225, from: "0x5e83b635f96da0752f991f0ebddc31249f452dea", gas: 90000, gasPrice: 20000000000, hash: "0x92d6d2285b198b6b5cf80eca6d4292c9675fb53f47f786063df600d3be06dd09", input: "0x", nonce: 0, to: "0x68acc3a13441b69016560d23e134c7931bbb27bb", transactionIndex: 0, value: 1000000000000000000 } > eth.getTransaction("0x0c1280c8b2f38aec032494913c1d0e65edd511fcd15e2424483f9bbf51c7172e"); { blockHash: "0x8456088424a4cacd8b394b4e11732e3c96ca77ab4a999c6ba62b38ab61116b58", blockNumber: 225, from: "0x5e83b635f96da0752f991f0ebddc31249f452dea", gas: 90000, gasPrice: 20000000000, hash: "0x0c1280c8b2f38aec032494913c1d0e65edd511fcd15e2424483f9bbf51c7172e", input: "0x", nonce: 1, to: "0x68acc3a13441b69016560d23e134c7931bbb27bb", transactionIndex: 1, value: 2000000000000000000 } > eth.getTransaction("0x8b6998eea8b343a0f754cf2732a1f28caac3acdfbe97cca69f244f0614ea546a"); { blockHash: "0x8456088424a4cacd8b394b4e11732e3c96ca77ab4a999c6ba62b38ab61116b58", blockNumber: 225, from: "0x5e83b635f96da0752f991f0ebddc31249f452dea", gas: 90000, gasPrice: 20000000000, hash: "0x8b6998eea8b343a0f754cf2732a1f28caac3acdfbe97cca69f244f0614ea546a", input: "0x", nonce: 2, to: "0x68acc3a13441b69016560d23e134c7931bbb27bb", transactionIndex: 2, value: 3000000000000000000 }
如果您的非區塊鏈應用程序中有交易依賴項,您應該等到之前的交易被探勘後再送出下一個交易。
一般流程是
- 發送一個交易,結果是一個交易雜湊
- 忙輪詢或等待事件以查看該雜湊值的交易是否已被探勘。
我可以在 stackexchange 文章中沒有很好的簡潔範例,但這裡有一些連結顯示了執行此操作的各種方法:
乙太布丁內置了這個,請參閱 index.js 中的 synchronizeFunction 了解它是如何工作的。使用 Promise 使您的應用程式碼非常乾淨。然而 index.js 很難閱讀……相信我它有效;-)
您可以忙於事務輪詢以查看其塊是否有效。這就是乙太布丁的作用。
您可以創建一個事件過濾器,其回調會在每個開采的區塊上觸發,並且每次開採一個區塊時,您都可以使用上述輪詢方法之一來查看您的交易是否已被開採。這可能比忙碌的輪詢要好,儘管我遇到了一些很難重現的事件系統問題。
在所有這些情況下,你不想永遠等待,你會想要某種超時。通常在 javascript 中,您將在交易被探勘時向您的應用程序發起回調或返回已履行的承諾。我想您可以使用其他一些 javascript 習慣用法,例如 RXJS 或 Event,但我還沒有為此嘗試過。