Web3js

如何以程式方式檢測和接受 ETH 和 ERC20 存款

  • February 19, 2021

在存放 ETH 和代幣時,我希望複製 Kraken 和 Poloniex 等加密貨幣交易所提供的功能。即:

  • 使用者可以為 ETH、EOS、OMG 和其他代幣生成和發送資金到一個或多個存款地址
  • 當檢測到給定代幣或資產的存款時,會更新相關使用者的餘額
  • 發送的資金儲存在交易所控制的賬戶中

實現這一目標的最佳方法是什麼?


我有一些使用 web3 的想法,但我不確定它們是最有效或可擴展的解決方案:

乙太坊

  • 對於每個想要存款的使用者,使用 . 生成一個 ETH 地址和私鑰web3.eth.accounts.create()。將生成的地址映射到使用者並儲存私鑰。
  • 用於web3.eth.filter監控 ETH 區塊鏈上的最新區塊。將區塊中的交易與儲存的使用者地址進行匹配,並酌情更新使用者餘額。

這種方法的問題:監視每個塊並與儲存的地址進行匹配是計算密集型的,特別是如果跟踪的地址數量變得很大(數十萬)。這個規模怎麼來的?

ERC20 代幣

  • 對於每個想要存款的使用者,使用 . 生成一個 ETH 地址和私鑰web3.eth.accounts.create()。將生成的地址映射到使用者和相關令牌,並儲存私鑰。
  • Transfer當合約上發生交易時,ERC20 合約會發出事件。使用 監視此事件web3.eth.filter。當Transfer我們數據庫中存在的地址發生事件時,用轉賬金額更新相關使用者在交易所的餘額。

這種方法的問題:如何設置 web3 過濾器以Transfer僅從相關令牌而不是整個網路中檢測事件?我應該為每個地址設置 1 個過濾器,還是為所有使用者地址設置 1 個過濾器?web3一次可以過濾多少個地址?如果跟踪地址變得非常高(數十萬)怎麼辦?


這是思考這一切的正確方式還是我錯過了什麼?我很驚訝沒有關於這個流程的更明顯的文件,因為它非常流行(在交易所和任何其他接受數字貨幣支付的服務中)。

它可能會是這樣的:

  1. 使用者想要將代幣存入您的交易所

  2. 如果這是使用者第一次存入該令牌,則會發生這種情況:

    1. 在伺服器端生成一個新的錢包密鑰/對
    2. 使用只有伺服器知道的秘密/鹽來加密私鑰,並將加密的私鑰和公共地址儲存在您的數據庫中,以及有關他們為其生成令牌的資訊以及啟動它的使用者 ID
  3. 下次他們點擊存款按鈕獲取存款地址時,您已經擁有儲存在數據庫中的使用者唯一存款地址,您可以將其呈現給使用者

  4. 使用者將代幣存入存款地址

  5. 在你的伺服器上有一個監聽所有乙太坊區塊鏈事件的工作人員。檢查交易的“收件人”地址,並對照您儲存的存款地址進行檢查。當有匹配時,向使用者發送有關存款事件的通知

  6. 呼叫代幣合約 balanceOf 方法,將您生成的與使用者綁定的存款地址傳遞給它,以便在交易所中顯示使用者的代幣餘額。您只顯示該特定代幣餘額,而不顯示該地址的其他任何內容。

  7. 使用者想要提取他們的代幣

  8. 您的交易所將有一個流動資金池待命。您必須將一些 ETH 從您的流動性池中轉移到使用者的存款地址,以支付 gas 費用。您將此費用作為提款費的一部分。您已經儲存了加密的私人資訊,因此您可以使用密鑰/鹽對其進行解密,簽署傳輸交易並將其廣播到乙太坊網路

我對實施也有同樣的想法。而且我認為您提出的解決方案很好。但對於乙太幣和 ERC20 代幣,我不建議監控區塊鏈。

對於乙太幣餘額,您將呼叫web3.eth.getBalance傳遞地址以在使用者進入頁面時檢查值,並放置一個 javascript 計時器以例如每 15 秒執行一次呼叫。

同樣,關於您對 ERC20 代幣餘額的 Ether 餘額問題:“您如何設置 web3 過濾器以僅檢測來自相關代幣而不是整個網路的傳輸事件? ”。我認為最好的方式是呼叫ERC20代幣的智能合約來查詢每個代幣的餘額。這是通過呼叫方法:function balanceOf(address _owner)對於使用者進入頁面後的每個令牌。例如,您可以設置一個 javascript 計時器以每 15 秒刷新一次值。

例如,我認為這就是 Kraken 所做的,因為頁面內容每隔幾秒鐘就會重新載入一次。

請注意,您將執行 ajax 呼叫來刷新余額的值,而無需刷新所有頁面。此外,呼叫balanceOf是免費的,因為它是只讀方法,將在您直接連接的節點上執行,無需任何 gas 費用。

引用自:https://ethereum.stackexchange.com/questions/27805