ECDSA是基于椭圆曲线生成公私钥进行数字验证和验证的算法过程。以太坊上两个账户Alice和Bob在以太坊网络中进行ETH转账交易的过程如下。
(1)Alice的DApp工具生成一个随机数,作为她账户的私钥k
(2) 在椭圆曲线secp256k1 上生成p点,根据等式Q=kp,该曲线上所得Q点的坐标(x,y)经过数学处理后就可以得到Alice的公钥,公钥经过Hash之后再截断便得到了Alice在以太坊中账户的地址
(3) 生成转账的交易信息
(4) Alice的DApp对转账交易tx进行RLP编码,再进行SHA-3的Hash,最后对Hash进行签名,得到签名结果为65字节的(r,s,v)。其中r和s分别为32字节,是签名的主体部分;v=27+(r%2),可看做签名结果的一种简单校验,在以太坊中作为恢复签名的recoveryID。签名实质上是使用私钥k对交易摘要进行加密的过程。
交易验证过程具体如下:
a. 交易验证节点接收到Alice发起转账原始交易和她的签名。
b.校验Alice签名,包括交叉recoveryID, 然后结合签名和交易Hash恢复出Alice的公钥Q。
c.对公钥Q进行Hash,截取后20位字节,得到Alice的账户地址。
d.对比原始交易中的from地址和演算恢复的Alice地址是否相同,如果相同则证明本次Alice转账交易是合法的,否则拒绝该交易。
签名验证实质上是使用公钥Q对交易进行解密的过程。以太坊Go客户端代码,通过cgo实际集成了比特币的secp256k1库,Go代码封装了签名并依据签名恢复公钥。
以太坊中的账户地址和比特币不同,转换相对简单。具体来说就是Hash结果取前20个字节,这里的Hash算法是SHA3-256,可以用如下代码来表示:
crypto.Keccak256(pubKey)[12:]
func PubKeyToAddress(p ecdsa.PublicKey) common.Address{
pubBytes := FromECDSAPub(&p)
return common.bytesToAddress(Keccak256(pubBytes[1:])[12:])
}
最近琐事太多+拖延症 使得写博客的计划一拖再拖,以后力争每月至少更新一篇博客。