[译]按照EIP-712规范签名完成委托和投票

这篇文章主要介绍了[译]按照EIP-712规范签名完成委托和投票 ,文中通过代码以及文档配合进行讲解,很详细,它对在座的每个人的研究和工作具有很经典的参考价值。 如果需要,让我们与区块链资料网一起学习。

https://www.interchains.cc/16711.html

[译]按照EIP-712规范签名完成委托和投票是很好的区块链资料,他说明了区块链当中的经典原理,可以给我们提供资料,[译]按照EIP-712规范签名完成委托和投票学习起来其实是很简单的,

不多的几个较为抽象的概念也很容易理解,之所以很多人感觉[译]按照EIP-712规范签名完成委托和投票比较复杂,一方面是因为大多数的文档没有做到由浅入深地讲解,概念上没有注意先后顺序,给读者的理解带来困难

[译]按照EIP-712规范签名完成委托和投票

通过签名功能函数的好处是用户可以免费完成委托或投票交易,同时会有可信的第三方花费gas费用将投票结果写到区块链blockchain中。在本次教程中,我们重点展示这类函数的例子。

  • 原文链接:https://medium.com/compound-finance/delegation-and-voting-with-eip-712-signatures-a636c9dfec5e 作者:Adam Bavosa
  • 译文出自:登链翻译计划
  • 译者:DIFENG
  • 本文永久链接:learnblockchain.cn/article…
  • 校对: Tiny熊

[译]按照EIP-712规范签名完成委托和投票

Compound的治理体系是由发放给用户的COMP代币来驱动的。COMP代币持有者拥有与持有量1:1的投票权。投票权利可以委托给任意一个地址,让其去给提案投票。

用户可以通过两种方式委托投票或对提案进行投票:可以直接调用函数(delegate, castVote)或通过签名功能函数(delegateBySigcastVotebySig)。

通过签名功能函数的好处是用户可以免费完成委托或投票交易,同时会有可信的第三方花费gas费用将投票结果写到区块链blockchain中。在本次教程中,我们重点展示这类函数的例子。

使用签名实现委托

按照EIP-712 规范定义的结构化数据签名方式,COMP代币持有者可以委托给任何一个以太坊eth地址。任何用户只要有已签名的委托交易,都可以调用COMP智能合约中delegateBySig 函数

这种方式的使用场景可能是,一个委托者希望联合其他COMP持有者将他们的投票委托给被委托人,并希望以非常低的成本来完成这项工作。

被委托者可以创建一个网页,让用户通过Metamask和私钥完成delegateBySig 交易,这样被委托者就能收集到签名信息。之后,被委托者可以将签名信息打包,批量一次写入到以太坊eth中,再执行delegateBySig函数就可以正式的收集到用户的投票权利。

通过签名投票

delegateBySig一样,用户也可以委托第三方给 Compound治理提案投票。任何用户只要有已签名的委投票交易,都可以调用智能合约中castVoteBySig 函数

第三方提交用户签名交易和delegateBySig的情况是一样的,但是投票权利仅限于一个提案,并非无限制的提案。在第三方正式将投票交易发送到以太坊eth之前,原有的用户依然保留自主投票的权利。

在Web3页面中使用签名实现委托

使用此代码,任何人可以创建一个让用户使用签名来委托投票权利的的网页,我们假定访问此页面的所有用户都使用MetaMask来调用Web3函数。

[译]按照EIP-712规范签名完成委托和投票

当一个用户访问这个页面时,他们可以看到自己选中的钱包地址和默认的Compound治理地址。他们可以将被委托人的地址填到这个地址中。在实际应用中,这个地址可以固定写成你要委托的目标地址。

接下来,用户会点击“Create Delegation Signature(创建委托签名)“按钮,这个会触发Metamask执行数据签名。MetaMask的文档里有关于数据签名的详细介绍。

[译]按照EIP-712规范签名完成委托和投票

在用户点击按钮“SIGN(签名)”时,会执行如下触发事件:

sign.onclick = async () => {   const _delegatee = delegateTo.value;   const _nonce = await comp.methods.nonces(myAccount).call();   const _expiry = 10e9; // expiration of signature, in seconds since unix epoch 以时间戳样式的签名过期时间   const _chainId = web3.currentProvider.networkVersion;   const msgParams = createDelegateBySigMessage(compAddress, _delegatee, _expiry, _chainId, _nonce);   web3.currentProvider.sendAsync({     method: 'eth_signTypedData_v4',     params: [ myAccount, msgParams ],     from: myAccount   }, async (err, result) => {     if (err) {       console.error('ERROR', err);       alert(err);       return;     } else if (result.error) {       console.error('ERROR', result.error.message);       alert(result.error.message);       return;     }     const sig = result.result;     delegatee.value = _delegatee;     nonce.value = _nonce;     expiry.value = _expiry;     signature.value = sig;     console.log('signature', sig);     console.log('msgParams', JSON.parse(msgParams));   }); };

代码中使用了Metamask自带eth_signTypedData_v4函数。这个函数可以按照EIP-712规范的完成结构化数据签名。完成一次有效的签名,需要3个参数

  1. 被委托人以太坊eth地址

  2. 使用签名账户从COMP智能合约中获得的的nonce

  3. 以时间戳样式的交易过期时间

这个结构化数据签名函数可以接受签名地址加上JSON格式的字符串。EIP-712规范定义了需要签名的数据的types, struct和domain。这个实现在一个简单的函数里,在按钮触发事件发生时会被调用。

const createDelegateBySigMessage = (compAddress, delegatee, expiry = 10e9, chainId = 1, nonce = 0) => {   const types = {     EIP712Domain: [       { name: 'name', type: 'string' },       { name: 'chainId', type: 'uint256' },       { name: 'verifyingContract', type: 'address' },     ],     Delegation: [       { name: 'delegatee', type: 'address' },       { name: 'nonce', type: 'uint256' },       { name: 'expiry', type: 'uint256' }     ]   };   const primaryType = 'Delegation';   const domain = { name: 'Compound', chainId, verifyingContract: compAddress };   const message = { delegatee, nonce, expiry };   return JSON.stringify({ types, primaryType, domain, message }); };

任何以太坊eth地址都可以使用被委托人地址,nonce,过期时间和签名来发布委托交易。这些是调用COMP合约的delegateBySig函数需要的参数。获得的签名需要分成3个参数,命名为 v, rs

const sig = signature.value; const r = '0x' + sig.substring(2).substring(0, 64); const s = '0x' + sig.substring(2).substring(64, 128); const v = '0x' + sig.substring(2).substring(128, 130);

根据EIP-712实现委托的完整代码可以在compound治理样例代码仓库中查看。

在Web3网页中通过签名投票

和委托一样,投票也可以创建一个网页来完成。用户在委托投票权利的时候,“赞同”和“反对”的委托需要分开发送交易,第三方可以选择最终发布哪一个委托。

const createVoteBySigMessage = (govAddress, proposalId, support, chainId = 1) => {   const types = {     EIP712Domain: [       { name: 'name', type: 'string' },       { name: 'chainId', type: 'uint256' },       { name: 'verifyingContract', type: 'address' },     ],     Ballot: [       { name: 'proposalId', type: 'uint256' },       { name: 'support', type: 'bool' }     ]   };   const primaryType = 'Ballot';   const domain = { name: 'Compound Governor Alpha', chainId, verifyingContract: govAddress };   support = !!support;   const message = { proposalId, support };   return JSON.stringify({ types, primaryType, domain, message }); };

点击“Create Vote Signatures(创建投票签名)”之后,会弹出让用户选择签名“赞成”和“反对”交易。与delegateBySig函数一致,通过传递2个参数来调用castVoteBySig函数。

  1. Compound治理提案唯一编号(自增的整型)
  2. 布尔值来表示赞成还是反对提案

另外用户还要传入分成3部分的签名,通常写作为v, rs

按照EIP-712规范投票完整页面代码可以在compound治理样例代码仓库查看。

通过脚本或者智能合约打包和发布签名

一旦用户收集完Compound治理的已签名的交易后,他们需要将这些交易发布到以太坊eth上。 实现批量发送交易的代码对于对于管理多个用户的私钥交易所和钱包很有帮助。

通过JSON RPC或者智能合约可以一次性将收集好的签名交易发布到区块链blockchain上。以下代码仅使用了Web3.js,代码实现创建然后批量发布由每一个私钥生成的委托签名的功能。

const myWalletAddress = web3.eth.accounts.wallet[0].address; var batch = new web3.BatchRequest(); signatures.forEach((signature) => {   const { delegatee, nonce, expiry, v, r, s } = signature;   batch.add(comp.methods.delegateBySig(delegatee, nonce, expiry, v, r, s).send.request(     {       from: myWalletAddress,       gasLimit: web3.utils.toHex(1000000),       gasPrice: web3.utils.toHex(25000000000),     },       console.log     )   ); }); await batch.execute();

Gas使用量: 306046

web3.BatchRequest对象将delegateBySig 签名打包,然后发布到区块链blockchain上。完整的Node.js代码 可以在compound治理样例码仓库查看。更多关于Web.js打包可以查看文档.

使用Solidity智能合约也可以到达同样的效果,经过对比,这种方式消耗的gas更少。

pragma solidity ^0.5.16; pragma experimental ABIEncoderV2; interface Comp {   function delegateBySig(     address delegatee,     uint nonce,     uint expiry,     uint8 v,     bytes32 r,     bytes32 s   ) external; } contract BatchDelegate {   struct Sig {     address delegatee;     uint nonce;     uint expiry;     uint8 v;     bytes32 r;     bytes32 s;   }   function delegateBySigs(Sig[] memory sigs) public {     Comp comp = Comp(0xc00e94Cb662C3520282E6f5717214004A7f26888);     for (uint i = 0; i < sigs.length; i++) {       Sig memory sig = sigs[i];       comp.delegateBySig(sig.delegatee, sig.nonce, sig.expiry, sig.v, sig.r, sig.s);     }   } }

Gas使用量: 306046

完整的Solidity代码 可以在compound治理样例代码仓库找到,里面还有JSON RPC的代码和智能合约部署代码。

感谢阅读,记得订阅Compound 新闻。欢迎在文末留言或者来Discord和我们交流

  • 发表于 5天前
  • 阅读 ( 87 )
  • 学分 ( 169 )
  • 分类:以太访2.0

部分转自网络,侵权联系删除www.interchains.cchttps://www.interchains.cc/16711.html

区块链毕设网(www.interchains.cc)全网最靠谱的原创区块链毕设代做网站 部分资料来自网络,侵权联系删除! 最全最大的区块链源码站 !
区块链知识分享网, 以太坊dapp资源网, 区块链教程, fabric教程下载, 区块链书籍下载, 区块链资料下载, 区块链视频教程下载, 区块链基础教程, 区块链入门教程, 区块链资源 » [译]按照EIP-712规范签名完成委托和投票

提供最优质的资源集合

立即查看 了解详情