以太坊专题 - 钱包地址
2019年2月26日
生成钱包
以太坊的钱包是基于椭圆曲线数字签名算法ECDSA保护的。
因此每一个钱包对应的是一个ECDSA的密钥对。
这个密钥对在 go-ethereum
项目的 crypto/crypto.go
的 GenerateKey()
函数生成,
生成后得到一个ECDSA的私钥 (ecdsa.PrivateKey
)。
以太坊所采用的椭圆曲线是 secp256k1
。由于其特殊构造的特殊性,其优化后的实现比其他曲线性能上可以提高30%,有明显以下两个优点:
- 占用很少的带宽和存储资源,密钥的长度很短;
- 让所有的用户都可以使用同样的操作完成域运算。
生成钱包私钥代码:
1 | func GenerateKey() (*ecdsa.PrivateKey, error) { |
得到私钥后,可以使用 ecdsa.PrivateKey
的 Public()
方法取得公钥 ecdsa.PublicKey
。
生成一般的钱包地址
以太坊钱包地址长度为20字节,来源于前面我们生成的钱包公钥 ecdsa.PublicKey
。
简单来说就是计算一下钱包公钥的 Keccak256
哈希值,再取出末尾20字节作为钱包地址(本身 Keccak256
输出32字节)。
生成钱包地址源代码:
1 | func FromECDSAPub(pub *ecdsa.PublicKey) []byte { |
生成智能合约的地址
智能合约的地址其实与拥有者用户钱包有关。但由于我们不可能直接拿钱包的公钥作为智能合约地址(这样就会与钱包地址冲突),所以就需要在原钱包地址的基础上增加一个唯一的独立数 Nonce
。
这样就可以确保某个钱包的拥有者可以生成出不同的智能合约地址啦。
注意,智能合约的 Nonce
与生成该智能合约的交易 Tx
的交易 nonce
有关。因为每一笔交易的nonce都是独立的,所以可以智能合约的nonce也是可以视为独立的。
生成智能合约的地址源码:
1 | func CreateAddress(b common.Address, nonce uint64) common.Address { |
生成智能合约地址使用参考:
1 | // The contract address can be derived from the transaction itself |
以上是以太坊专题第一部分钱包地址的内容。
除非注明,麦麦小家文章均为原创,转载请以链接形式标明本文地址。