Solidity
從 etherscan API 讀取 Ledger 與 Emitting Events
考慮來自solidity合約的以下函式:
function createProduct(uint _price, string memory _desc) public payable{ emit UserLedgerUpdated(_desc, -1*int(msg.value)); }
我希望我的 Dapp 顯示一個簡單的分類帳,如下所示:
Created Shoes priced at 100 Wei for a Total Cost of 2345 Wei
我在這裡有兩個選擇:
- 在 Dapp 中捕捉
UserLedgerUpdated
事件- 使用etherscan API獲取 txn 詳細資訊
我的問題是:
a) 如果我選擇選擇 2(即閱讀 txn 詳細資訊),那麼我可以避免發出事件。由於事件會被記錄並佔用空間,它們會消耗燃料,因此比免費閱讀 txn 詳細資訊要貴。我的理解正確嗎?
b) 在閱讀 ethscan API 時,我將函式的輸入作為十六進制。我可以
web3.toAscii
將其轉換為字元串,但請注意該函式的第一個參數實際上是一個數字。因此,當我 在Sample Transaction中轉換輸入數據時,我得到的是. 有沒有辦法正確轉換我們從 ethrscan API 獲得的十六進制數據?{@Shoes``123Shoes
- 是的,你肯定會通過不發出事件來節省氣體。然而,代價是你依賴 Etherscan 讓你的 dapp 執行。如果 Etherscan 宕機了,你的 dapp 就宕機了。您還將失去所有使用多重簽名的使用者,因為他們對該合約的呼叫將永遠不會顯示在 Etherscan 的交易中(儘管 Etherscan 也提供內部交易,因此您可能能夠解決這個問題)。它也肯定失去了它的“dappness”的一個方面,因為它現在依賴於一個集中的服務來讀取數據。如果您堅持使用事件,那麼使用者只需要訪問同步節點即可。這可能來自 Infura、其他節點提供商或本地節點。
- 這是因為 123 (7b) 是
price
變數,它是一個數字,而不是字元串,而 0x7B 恰好是 ascii 中的 {。您可以做的是web3.eth.abi.decodeParameters
在剝離函式簽名(0x 後的前 4 個字節)後將函式的 abi 和 tx 數據傳遞給函式。這將返回解碼後的數據。