How to save your Ethereum Dapp users from paying gas for transactions
以太坊dapp采用的一個摩擦點是用戶必須支付一筆支付天然氣(交易(txn)費)才能讓他們的交易記錄在區塊鏈上。 例如,我有一個簡單的投票dapp ,讓任何人都可以為候選人投票,并將選票存儲在區塊鏈中。 想要在區塊鏈上記錄投票的用戶必須支付交易/燃氣費。 這并不理想,因為作為一個dapp所有者,您希望您的應用程序用戶擁有以太網來支付燃氣費用,因為他們所要做的只是執行與轉賬無關的簡單操作。 但是如果交易需要在區塊鏈上執行,除了支付費用之外別無選擇。 如果用戶有安全地執行交易的方式(如我們的例子中為候選人投票),并讓其他人(可能是合同擁有者)在區塊鏈上記錄交易并自行付款?
感謝John Backus發來的這條推文,我只有足夠的信息來幫助我為我的投票dapp實現這樣的解決方案。
我想分享有關我如何為我的簡單dapp實施此解決方案的詳細信息,以便更多人可以在他們自己的dapps中采用這種技術,并且可以有所改進。 這篇文章涵蓋以下內容:
數字簽名
要使這個解決方案合理化,您需要對數字簽名如何在加密中起作用有一個基本的了解。 如果您知道公鑰密碼術,請隨意跳過本節。 我將盡力在非常高的層次上解釋公鑰/私鑰和數字簽名的概念,但我強烈建議詳細學習 - 維基百科是一個很好的開始 。
公鑰密碼術是一個密碼系統,你有兩個密鑰 - 公鑰(Pu)和私鑰(Pr)。 你把你的公鑰交給整個世界,把私鑰留給自己。 例如:您的以太坊地址是一個公鑰(它實際上是從公鑰導出的,但是對于這個練習,我們只是將其視為公鑰),并將您的私鑰存儲在瀏覽器或手機/計算機上。 如你所知,有人向你發送以太網,他們只需要知道你的公共(帳戶)地址。 但是,只有您可以訪問您擁有的資金,因為您是唯一知道您私鑰的人。
公鑰加密算法具有算法,可讓您使用一對密鑰對消息進行加密,解密,簽名和驗證。
讓我們通過一個例子來看看簽名和驗證消息的含義。 假設用戶Kim有一對公鑰/私鑰
Pu =“0x44ac12c1e3dfd8edaf83b6f65918229d5279a6f5”
Pr =“dbc226043e390cf39280e5edfd418d7ad61931c76509270867d300f110c46506”
為了簽署消息,Kim執行輸出字母數字字符串的功能符號(“投票給愛麗絲”,Pr)
簽名= 0x9127112de0033555c7f6508d963d484965a953844dfcff092712102c236467a25af57edc53b63880ea39af8ce7334f6d77a8206e805305e7c6ad919d12bfae5c1b
這是Kim用她的私人密鑰Pr簽名的消息“投票給愛麗絲”的數字簽名。
現在,任何人都可以通過執行驗證功能驗證該消息“投票給愛麗絲”,由Kim執行驗證(“投票給愛麗絲”,簽名),其輸出“0x44ac12c1e3dfd8edaf83b6f65918229d5279a6f5”。 如果你注意到,那輸出是Kim的公鑰Pu(記住,每個人都知道它是Kim的公鑰),這意味著這個消息肯定是由Kim簽署的。 如果篡改簽名或消息(通過更改一個字符),驗證算法會輸出完全不同的公鑰,并且您將知道該消息被篡改,因為公鑰與Pu不同。
解決方案詳情
如果你理解數字簽名,解決方案是非常微不足道的。 讓我們看看如何在我們的投票應用程序中使用它,以免用戶在不損害投票的情況下支付燃氣費。 您可以在下面看到dapp的所有用戶以及他們執行的操作。
實施細節
現在讓我們來看看實際的實現以及所有部分如何組合在一起。
第1步:簽署消息
第一步是以選民的身份簽署消息。 我們將使用eth_signTypedData函數來簽署我們的消息。 這個功能已經在Metamask中實現,這使得簽名消息變得非常簡單。 你可以在這里找到關于這個建議的更多細節和討論: https : //github.com/ethereum/EIPs/pull/712 。 您可以在下面找到代碼以簽署消息。
一個非常重要的要注意的是,內部eth_signTypedData散列消息,散列消息是簽名。 您可以在這里參考typedSignatureHash函數以獲取有關散列的更多細節。
第2步:將已簽署的投票提交給區塊鏈
由于這只是一個演示應用程序,因此我們不會在任何地方存儲簽名和其他細節。 它在消息簽名后直接顯示在頁面上。 任何人都可以采取這些細節并提交給區塊鏈。 以下是向區塊鏈提交投票的代碼:
第3步:驗證智能合約中的投票詳情
我們現在在智能合約中驗證提交的投票信息是否有效,然后記錄投票結果。
Zeppelin有一個名為ECRecovery的方便庫,我們可以使用它來驗證簽名的消息。 voteForCandidate函數驗證簽名的消息(恢復功能),并在驗證成功時更新投票計數。
如果你還記得,我剛才提到eth_signTypedData在簽名之前散列消息(“為Alice投票”)? solidity recover函數沒有關于eth_signTypedData中使用的散列函數的任何知識,因此它不能驗證消息“為Alice投票”。 它必須生成消息“投票給愛麗絲”的散列,然后驗證它。 我們不是在合約內部生成哈希,而是事先對所有消息進行哈希處理,并在構造函數中傳遞它,這樣在驗證時很容易查找。 生成哈希的代碼位于下面的遷移文件中
這就是獲得新應用程序所需的所有代碼!
我創建了一個快速演示來展示這個應用程序如何工作
整個工作代碼在這里: https : //github.com/maheshmurthy/ethereum_voting_dapp/tree/master/chapter4
演示應用程序位于: https : //www.zastrin.com/voting-dapp-without-paying-gas.html
可能需要解決的問題
使用這種技術構建真正的dapp時需要考慮幾個問題。 其中一些列在下面:
如果您對如何解決這些問題有所想法,或者如果您發現此解決方案中存在任何缺陷,請發表評論!
注意:顯然,eth_signTypedData API仍然不穩定,只能通過metamask實現。 如果您打算在mainnet / production中使用這種技術,請小心這一點。
進一步閱讀
https://en.wikipedia.org/wiki/Public-key_cryptography
https://en.wikipedia.org/wiki/Digital_signature
https://github.com/danfinlay/js-eth-personal-sign-examples/
https://danfinlay.github.io/js-eth-personal-sign-examples/
https://github.com/ethereum/EIPs/pull/712
感謝Chris Whinfrey和Febin John James審閱本文的草稿。
https://medium.com/blockchannel/how-to-save-your-ethereum-dapp-users-from-paying-gas-for-transactions-cfc665891ab4
總結
以上是生活随笔為你收集整理的How to save your Ethereum Dapp users from paying gas for transactions的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Cold-Staking | TPoS
- 下一篇: 【译】Hard Forks, Soft