EIP4337(三):Argent的实现思路 EIP4337(四):Contract wallet技术背景和产品概念
EIP4337(三):Argent的实现思路
本文非Vitalik的medium文章分析了,是从EIP4337出发,分析下可行的contract wallet 方案,要知道,layer2还没有较为出彩的contract wallet呢。
对于大部门Web3用户来说,小狐狸的类似操作界面,在没有出现飞跃式体验提升的前提下,更换使用习惯,是惯性成本非常高的。因此,基于小狐狸的Chrome插件模式,是一个较为稳妥的选择。
Argent是在layer2的zksync+zksnark实现了4337抽象钱包的一个项目:github.com/argentlabs/argent-x
从文档可知,docs.argent.xyz/wallet-connect-and-argent,使用EIP1217替换了传统的EOA的EIP712签名,这也带来了传统DApp兼容问题,因为过往的签名部分,是遵守EIP712的。
我们来看下插件实现的核心架构:

完整的smart contract wallet四部分部分组成:
1.对EIP4337协议的实现,不同链,可能有不同的tricks。
2.适配DApp的wrapper,用来链接钱包,输出常规的provider等接口服务。
3.一个类似Metamask的Chrome plugin,包括relay服务(可定制,复杂)。
4.一个用来示范如何连接使用wrapper的DApp demo。
5.paymaster,工作量,可以后置(GSN基础上改造)
Open Nest startup!
基于历史黑客松合作的默契和信任,我们再出发,做一些有益的尝试!
github.com/proofofsoulprotocol/smart-contra..
History:
gitcoin.co/grants/6231/proof-of-soul-soulbo..
EIP4337(四):Contract wallet技术背景和产品概念
UTXO和Account
Account是传统IT世界的概念,尤其在电商和财务系统的抽象模型中会用到,一般Account代表了账户体系,包括Balance,order book念,初始可能是零或者充值余额,之后是通过每次交易实时扣减,记录到独立的余额字段。当然,和账户关联的支付交易、购买交易,会通过账户的唯一Key,例如AccountID,以及联合主键或者外键进行索引和查询,从而提供账户服务。银行的账户服务,背后的核心逻辑,基本也是这些:存款(充值)、转账、自动扣减支付、自动收款、利息结息等等的。
而UTXO是Unspent Transaction output,直译是未花费交易输出,是比特币为了精简其架构设计,匹配Block,区块的架构而采用的一种设计。核心是没有明确余额而是靠计算。我们来看下一个比特币区块的数据结构:
{
"hash":"00000000000000000018b0a6ae560fa33c469b6528bc9e0fb0c669319a186c33",
"confirmations":1009,
"strippedsize":956228,
"size":1112639,
"weight":3981323,
"height":514095,
"version":536870912,
"versionHex":"20000000",
"merkleroot":"5f8f8e053fd4c0c3175c10ac5189c15e6ba218909319850936fe54934dcbfeac",
"tx":[
// ...
],
"time":1521380124,
"mediantime":1521377506,
"nonce":3001236454,
"bits":"17514a49",
"difficulty":3462542391191.563,
"chainwork":"0000000000000000000000000000000000000000014d2b41a340e60b72292430",
"previousblockhash":"000000000000000000481ab128418847dc25db4dafec464baa5a33e66490990b",
"nextblockhash":"0000000000000000000c74966205813839ad1c6d55d75f95c9c5f821db9c3510"
}
可以看到,三个hash:hash、previousblockhash、nextblockhash以及merkleroot,是本数据块的核心自动,挂载的tx交易数据是从属关系。hash是保持整体区块之间的链接关系和唯一性的保障,merkleroot是当前区块的所有交易的树形结构的root,确保交易不被篡改。
而以太坊区块也是类似的机制:
{
"jsonrpc":"2.0",
"result":{
"author":"0x00d8ae40d9a06d0e7a2877b62e32eb959afbe16d",
"difficulty":"0x785042b0",
"extraData":"0x414952412f7630",
"gasLimit":"0x47b784",
"gasUsed":"0x44218a",
"hash":"0x4de91e4af8d135e061d50ddd6d0d6f4119cd0f7062ebe8ff2d79c5af0e8344b9",
"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"miner":"0x00d8ae40d9a06d0e7a2877b62e32eb959afbe16d",
"mixHash":"0xb8155224974967443d8b83e484402fb6e1e18ff69a8fc5acdda32f2bcc6dd443",
"nonce":"0xad14fb6803147c7c",
"number":"0x2000f1",
"parentHash":"0x31919e2bf29306778f50bbc376bd490a7d056ddfd5b1f615752e79f32c7f1a38",
"receiptsRoot":"0xa2a7af5e3b9e1bbb6252ba82a09302321b8f0eea7ec8e3bb977401e4f473e672",
"sealFields":[
"0xa0b8155224974967443d8b83e484402fb6e1e18ff69a8fc5acdda32f2bcc6dd443",
"0x88ad14fb6803147c7c"
],
"sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"size":"0x276",
"stateRoot":"0x87e7e54cf229003014f453d64f0344e2ba4fc7ee3b95c7dd2642cca389fa1efe",
"timestamp":"0x5a10968a",
"totalDifficulty":"0x1804de0c47ffe1",
"transactions":[...],
"transactionsRoot":"0xc2091b032961ca23cf8323ea827e8956fe6dda9e68d75bcfaa8b910035397e35",
"uncles":[]
},
"id":1
}
同样有hash、parentHash、mixHash以及transactionsRoot,是和比特币类似的目的,保持区块链接和唯一性(不可篡改),以及当前区块的交易不可篡改的树形结构。
UTXO就是建立在上面的区块结构的Txs,对于某个地址的而言,它的余额由UTXO模型来提供,并非传统的Account模型,有一个绝对唯一的余额数字,而是所有Unspent Transaction output 在对一个交易进行输入,满足:inputs = price + change + fee,类似于你把身上所有10块、20块、100块等归属于你的UTXO,作为输入给Tx,Tx会扣除交易value(例如转账金额等,别人的UTXO)和矿工fee,剩下的余额change(你的新的UTXO)。
从这个角度出发,就用到了签名机制。
{
"addr":"14uhqGYDEhqwfdoP59QdLWdt4ha5CHttwQ",
"n":1,
"script":"76a9142ae017a5bd24a3f935897085253e503fbfd66f4e88ac",
"spent":false,
"tx_index":335926477,
"type":0,
"value":21680000
}
"txid":"5be7a9e47f56c98e5297a44df52da0475f448ece98bb51489103cdf70653092f",
"hash":"5be7a9e47f56c98e5297a44df52da0475f448ece98bb51489103cdf70653092f",
"version":1,
"size":224,
"vsize":224,
"locktime":0,
"vin": [...],
"vout": [...],
"hex":"0100000001a90b4101e6cbb75e1ff885b6358264627581e9f96db9ae609acec98d72422067000000006b483045022100c42c89eb2b10aeefe27caea63f562837b20290f0a095bda39bec37f2651af56b02204ee4260e81e31947d9297e7e9e027a231f5a7ae5e21015aabfdbdb9c6bbcc76e0121025e6e9ba5111117d49cfca477b9a0a5fba1dfcd18ef91724bc963f709c52128c4ffffffff02a037a0000000000017a91477df4f8c95e3d35a414d7946362460d3844c2c3187e6f6030b000000001976a914aba7915d5964406e8a02c3202f1f8a4a63e95c1388ac00000000",
"blockhash":"0000000000000000000c23ca00756364067ce5e815deb5982969df476bfc0b5c",
"confirmations":5,
"time":1521981077,
"blocktime":1521981077
}
{
"vin":[
{
"txid":"672042728dc9ce9a60aeb96df9e9817562648235b685f81f5eb7cbe601410ba9",
"vout":0,
"scriptSig":{
"asm":"3045022100c42c89eb2b10aeefe27caea63f562837b20290f0a095bda39bec37f2651af56b02204ee4260e81e31947d9297e7e9e027a231f5a7ae5e21015aabfdbdb9c6bbcc76e[ALL] 025e6e9ba5111117d49cfca477b9a0a5fba1dfcd18ef91724bc963f709c52128c4",
"hex":"483045022100c42c89eb2b10aeefe27caea63f562837b20290f0a095bda39bec37f2651af56b02204ee4260e81e31947d9297e7e9e027a231f5a7ae5e21015aabfdbdb9c6bbcc76e0121025e6e9ba5111117d49cfca477b9a0a5fba1dfcd18ef91724bc963f709c52128c4"
},
"sequence":4294967295
}
]
}
请参考最后一个的scriptSig,因为每笔交易,如同签名描述,都会有多个UTXO作为输入,输入的就是UTXO+签名。
一句话概述:传统系统面临的问题是高并发,因为都要去修改那个Account的唯一余额,对数据库来说,就是一次互斥锁定,而一个表在物理上的锁定是有限的,带来了并发的问题,当然,也引入了队列等等技术手段来解决。而UTXO是一张张纸币一样的余额,归属于某个地址所有,可以并行的处理UTXO而不会带来并发问题,当然也有缺点,例如双花的可能。
以太坊使用的Account账户模型,核心字段:nonce, ether_balance, contact_code, storage,这一类账户有两种:无代码的被私钥控制的Account,以及有代码的合约Account,都可以拥有余额。合约账户一般拥有的是ERC20、ERC721等类型的合约账户,也就是大家所熟知的发行Token和NFT。
因为不需要使用UTXO的输入输出模型,以太坊交易很简单:
{
"blockHash":"0xb4a992ff99a487db8421f516be998920f06dfe5d355d88e3b7f22b7422e6340d",
"blockNumber":"0x24f85c",
"chainId":null,
"condition":null,
"creates":null,
"from":"0x8b56adcf332ff80a1f1bf433975dcb28b730d110",
"to":"0xe94b04a0fed112f3664e45adb2b8915693dd5ff3",
"value":"0x10d43fb8311ca800",
"gas":"0x2062a",
"gasPrice":"0x560aab7c5",
"hash":"0xfea448d11cfa863c8b3c38d3b65649e66c1957f9ac16638e3a0edff45a6b3d84",
"input":"0x0f2c9329000000000000000000000000fbb1b73c4f0bda4f67dca266ce6ef42f520fbb98000000000000000000000000e592b0d8baa2cb677034389b76a71b0d1823e0d1",
"nonce":"0x3fe",
"publicKey":"0x765b0f012e49f6a4cc5c917fb176984b24814bdaf5f9464db1a7f9ffcc730cb678f69e49f78aa9de8249cce138bbc25cf8842374d8d09089dff7f1ef6906f4fb",
"r":"0x4275d35821dec971f6d58c2adae077ffcdfa3ec74af542a2d29ab4e5239d8b25",
"raw":"0xf8b48203fe850560aab7c58302062a94e94b04a0fed112f3664e45adb2b8915693dd5ff38810d43fb8311ca800b8440f2c9329000000000000000000000000fbb1b73c4f0bda4f67dca266ce6ef42f520fbb98000000000000000000000000e592b0d8baa2cb677034389b76a71b0d1823e0d11ca04275d35821dec971f6d58c2adae077ffcdfa3ec74af542a2d29ab4e5239d8b25a036221b525c758c45e60f964eec698ae33208dfa74bea7f77dff002ceec418b0a",
"s":"0x36221b525c758c45e60f964eec698ae33208dfa74bea7f77dff002ceec418b0a",
"standardV":"0x1",
"transactionIndex":"0x8",
"v":"0x1c"
}
from、to,以及单独出来的gas和gas price,交易核心字段:nonce, from, to, value, input,和UTXO的类似。
以上如果感兴趣,可以自行搜索相关概念学习。
参考资料:draveness.me/utxo-account-models(写了一大半才发现这个文章不错,借鉴了交易数据)