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