以太坊基础—你真的懂吗

以太坊私钥

eg:
fad9c8855b740a0b7ed4c221dbad0f33a83a49cad6b3fe8d5817ac83d38b6a19

由256位;不考虑0x前缀,由32个字节,64个字符构成。

以太坊公共地址

eg:
0x20F8D42FB0F667F2E53930fed426f225752453b3

由160位组成;不考虑0x前缀,由20个字节,40个字符构成。

以太坊公钥与公共地址是一回事吗

一句话,公共地址是公钥的Keccak-256哈希。

具体在以太坊中,用keccak哈希算法来计算公钥的256位哈希,再截取这256位哈希的后160位哈希作为地址值。

所以,在以太坊中它俩个不是一回事。

以太坊地址的大小写—有没有区别

一个现象是我们用钱包的时候,比如ImToken/Metamask/交易所,钱包地址都是大小写混杂的,但是在etherscan和opensea上查看交易信息和NFT信息时却可以不区分大小写的正确进行查询,这是为什么呢?

这还得从以太坊历史说起,起初以太坊内部实际并不区分大小写的,但是用户在钱包的实际使用过程中发现,由于缺乏类似比特币的自带地址校验机制,使用以太坊的公开地址转账时,经常因为误输入字符而转错了账号,这显然很严重。

EIP-55

于是社区用户在以太坊很早期的时候,就已经提出该问题并思考改进的方法,经过整理成文,形成了 EIP-55 提议。该提议按照一定逻辑,将地址中的部分字母大写,与剩余的小写字母来形成校验和,让地址拥有自校验的能力,具体JavaScript实现代码如下:

const createKeccakHash = require('keccak')
function toChecksumAddress (address) {address = address.toLowerCase().replace('0x', '')var hash = createKeccakHash('keccak256').update(address).digest('hex')var ret = '0x'for (var i = 0; i < address.length; i++) {if (parseInt(hash[i], 16) >= 8) {ret += address[i].toUpperCase()} else {ret += address[i]}}return ret
}

实现了上述逻辑,即符合EIP55规范的软件或APP应该对传入的地址进行一次检验,以防止人为书写错误。

EIP-55 机制

EIP-55实际上设计了对账户地址进行keccak256哈希运算,根据运算结果值的二进制位图决定地址十六进制字符串(0-9,a-f)的大写或小些。

带校验地址 (大小写区分)0x7c52e508C07558C287d5A453475954f6a547eC41
普通地址 (全小写)0x7c52e508c07558c287d5a453475954f6a547ec41

EIP-55 特点

  • 向后兼容许多接受混合大小写的十六进制解析器,允许它随着时间的推移轻松引入 保持长度为40个字符
  • 平均每个地址将有15个校验位,如果输入错误,随机生成的地因抄写错误意外通过检查的净概率为0.0247%。
  • 比ICAP提高了约50倍,但不如4字节检查代码好。

BIP39助记词与私钥—有怎样的转换为关系

一般我们所指的助记词都是符合BIP39规范的助记词

首先要说明的是BIP39助记词有12、15、18、24个等区分,但原理都类似,一般钱包更常见的是采用12个助记词。下面以12个助记词来讲解原理:

在实际应用中,助记词往往不是匹配到一个私钥的,常常被使用的是层级钱包,也就是HD钱包,hierarchical deterministic wallet。这种模式中,助记词对应的是原始密码,原始密码可以生成种子秘钥,种子秘钥可以能再生成多级的子公私钥对。这种模式的好处在于,有了助记词,就能获得所有子账户的控制权。同时,子账户中的私钥可以从未生成的和传播,有利于钱包安全。

助记词的原理是什么?

我们知道,以太坊的私钥,看起来是256位的二进制字符串。不便于记忆,也不便于输入。为了便于记忆,我们可以把特定的字符组合映射到某个单词,这样就便于记忆了。

例如,3个字符的组合有2的3次方,一共8种。我们可以设定一种关系,000用moon表示,001用sun表示,010用zero表示,011用zoom表示。这样一个12个字符的串,000010011001我们就可以及意义成 moon sun zero zoom 了,这样输入时不容易出错,也容易记忆。
具体原理图如下:


以太坊私钥到公钥—具体实现原理

首先从一段Go代码具体实现看起,这样整个过程会更清晰。

package mainimport ("crypto/ecdsa""fmt""log""github.com/ethereum/go-ethereum/common/hexutil""github.com/ethereum/go-ethereum/crypto""golang.org/x/crypto/sha3"
)func main() {privateKey, err := crypto.GenerateKey()if err != nil {log.Fatal(err)}privateKeyBytes := crypto.FromECDSA(privateKey)fmt.Println(hexutil.Encode(privateKeyBytes)[2:]) publicKey := privateKey.Public()publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)if !ok {log.Fatal("cannot assert type: publicKey is not of type *ecdsa.PublicKey")}publicKeyBytes := crypto.FromECDSAPub(publicKeyECDSA)fmt.Println(hexutil.Encode(publicKeyBytes)[4:]) address := crypto.PubkeyToAddress(*publicKeyECDSA).Hex()fmt.Println(address)//以下是使用 golang.org/x/crypto/sha3 的 Keccak256函数手动完成的方法。会在keccak环节深入讲解。hash := sha3.NewLegacyKeccak256()hash.Write(publicKeyBytes[1:])fmt.Println(hexutil.Encode(hash.Sum(nil)[12:])) // 0x96216849c49358b10257cb55b28ea603c874b05e
}

代码解析

  1. crypto.GenerateKey() //生成随机私钥
  2. crypto.FromECDSA(privateKey) //将其转换为字节,再次强调一个字节等于2个字符,所以普通的以太坊地址除了0x外是40个字符,20个字节。这个过程完成的ECDSA签名,具体实现的功能在下一节讲解。
  3. fmt.Println(hexutil.Encode(privateKeyBytes)[2:]) //转换为十六进制字符串,该包提供了一个带有字节切片的Encode方法,然后我们在十六进制编码之后删除“0x”;私钥是256位的二进制字符串,也就是32个字节,64个字符。
  4. publicKey := privateKey.Public() //由于公钥是从私钥派生的,加密私钥具有一个返回公钥的Public方法
  5. publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey) //这一步就是EIP55做的事情,生成经过ECDSA校验的Public Address
  6. publicKeyBytes := crypto.FromECDSAPub(publicKeyECDSA) //将其转换为字节
  7. fmt.Println(hexutil.Encode(publicKeyBytes)[4:]) //9a7df67f79246283fdc93af76d4f8cdd62c4886e8cd870944e817dd0b97934fdd7719d0810951e03418205868a5c1b40b192451367f28e0088dd75e15de40c05 将其转换为十六进制的过程与我们使用转化私钥的过程类似。 我们剥离了0x和前2个字符04,它始终是EC前缀,不是必需的。
  8. address := crypto.PubkeyToAddress(*publicKeyECDSA).Hex() //接受一个ECDSA公钥,并返回公共地址;公共地址其实就是公钥的Keccak-256哈希,然后我们取最后40个字符(20个字节)并用“0x”作为前缀
  9. fmt.Println(address) // 0x96216849c49358B10257cb55b28eA603c874b05E

最终,打印出来的0x96216849c49358B10257cb55b28eA603c874b05E的地址就是我们钱包所见的公钥地址了。

不得不说的ECDSA

上面的章节中我们看到了通过代码crypto.FromECDSA(privateKey) 来执行ECDSA签名,那么ECDSA是什么?到底完成了什么功能?

ECDSA定义

ECDSA又名椭圆曲线数字签名算法,是使用椭圆曲线密码(ECC)对数字签名算法(DSA)的模拟。**数字签名算法(DSA)**是联邦信息处理标准FIPS中的数字签名标准,它的安全性基于素域上的离散对数问题。**椭圆曲线密码(ECC)**由Neal Koblitz和Victor Miller于1985年发明。它可以看作是椭圆曲线对先前基于离散对数问题(DLP)的密码系统的模拟,只是群元素由素域中的元素数换为有限域上的椭圆曲线上的点。

一句话总结,ECDSA是ECC与DSA的结合,整个签名过程与DSA类似,所不一样的是签名中采取的算法为ECC,最后签名出来的值也是分为r,s。

ECDSA功能

  • 初始化化秘钥组,生成ECDSA算法的公钥和私钥
  • 执行私钥签名, 使用私钥签名,生成私钥签名
  • 执行公钥签名,生成公钥签名
  • 使用公钥验证私钥签名

Tips:ECDSA属于非对称加密。公钥与私钥匙成对出现。 遵从的原则就是“私钥签名、公钥验证”。

ECDSA原理(签名+验签)

签名原理:
1、选择一条椭圆曲线Ep(a,b),和基点G;
2、选择私有密钥k(k<n,n为G的阶),利用基点G计算公开密钥K=kG;
3、产生一个随机整数r(r<n),计算点R=rG;
4、将原数据和点R的坐标值x,y作为参数,计算SHA1做为hash,即Hash=SHA1(原数据,x,y);
5、计算s≡r - Hash * k (mod n)
6、r和s做为签名值,如果r和s其中一个为0,重新从第3步开始执行

验证原理:
1、接受方在收到消息(m)和签名值(r,s)后,进行以下运算
2、计算:sG+H(m)P=(x1,y1), r1≡ x1 mod p。
3、验证等式:r1 ≡ r mod p。
4、如果等式成立,接受签名,否则签名无效。

不得不说的Keccak

前面代码最后注释部分,进行了手动生成,其中调用了hash := sha3.NewLegacyKeccak256()函数 ,就用到Keccak256算法。

Keccak是一种被选定为SHA3标准的单向散列函数算法。 Keccak可以生成任意长度的散列值,但为了配合SHA-2的散列值长度,SHA-3标准中规定了SHA3-224、SHA3-256、SHA3-384、SHA3-512这4种版本。在输入数据的长度上限方面,SHA1为2的64次方-1比特,SHA2为2的128次方-1比特,而SHA-3则没有长度限制。

在以太坊中,用Keccak哈希算法来计算公钥的256位哈希,再截取这256位哈希的后160位哈希作为地址值。

Keccak和SHA3的区别联系

SHA3由Keccak标准化而来,在很多场合下Keccak和SHA3是同义词,但在2015年8月SHA3最终完成标准化时,NIST调整了填充算法:SHA3-256(M) = KECCAK [512] (M || 01, 256)。所以标准的NIST-SHA3就和Keccak计算的结果不一样。

以太坊在开发的时候SHA3还在标准化中,采用了Keccak,所以Ethereum和Solidity智能合约代码中的SHA3是指Keccak256,而不是标准的NIST-SHA3,为了避免混淆,直接在合约代码中写成Keccak256是最清晰的

为何推出SHA3

推出SHA3不是因为SHA2出现了漏洞,只是当时学术界对于SHA1被成功碰撞的担忧,但目前基于NIST的建议,SHA2和SHA3都是属于可以安全商用的哈希算法,SHA3相当于多了一种安全选择,比特币选用的就是SHA2(SHA256)。

参考

1.https://ethbook.abyteahead.com/ch2/eip55.html

2.https://learnblockchain.cn/docs/eips/eip-55.html#%E8%A7%84%E8%8C%83 EIP55

3.https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md EIP55

4.https://zhuanlan.zhihu.com/p/150125861 助记词到私钥

5.https://blog.csdn.net/m0_37458552/article/details/80250258 ECDSA

6.https://blog.csdn.net/weixin_39860583/article/details/111584269 Keccak256

以太坊BIP39助记词到公钥地址的原理与细节相关推荐

  1. 比特币钱包开发:通过助记词扩展子地址的原理与编码

    [db:标签]标 掌握生成助记词的原理 掌握助记词生成种子的原理 掌握种子生成子秘钥的原理 编程实践:从生成助记词到子地址 前言 为了安全尽量保证比特币地址的公钥未在网络上出现过,这就需要我们每次支付 ...

  2. 关于区块链的助记词以及BTC地址,私钥,公钥,ETH地址获取的方法

    VUE项目中的获取助记词的方式 安装需要的依赖环境 如果你安装了国内的淘宝镜像了 ,建议你用cnpm bip39:npm install bip39 bip32:npm install bip32 e ...

  3. 比特币钱包(4) BIP39 助记词

    1. 定义生成助记词 助记词句子(mnemonic word sequence)作为密码,使用若干个助记词来替换之前直接生成随机数的方式(确定性钱包的种子随机数). 1.1. 生成步骤 1) . 生成 ...

  4. 数字货币钱包 HD Wallet的助记词和种子的生成原理(BIP39)

    BIP39描述了如何生成助记符,并将其转换为二进制种子.该种子可以生成确定性钱包.    如何生层助记词 我们先看看助记词范围--单词表.生成助记词的过程就是这个表里(2048个单词,记住这个数值)选 ...

  5. java助记词反向_GitHub - gangan1345/mnemonic-sdk: Mnemonic bip39 bip32 bip44 生成助记词 私钥...

    mnemonic-sdk Mnemonic bip39 bip32 bip44 支持 BIP39 助记词 支持 BIP32 子私钥 支持 BIP44 多币种管理 Install Gradle: Add ...

  6. 非对称加密, 助记词, PIN, WIF

    一钱包 1.1非对称加密, 助记词, PIN, WIF, 地址 1.1.1 非对称加密算法 非对称加密算法, 加密与解密使用不同的KEY, 我们分别称为私钥与公钥,其中可以通过私钥生成公钥 在比特币中 ...

  7. 助记词是什么,有什么用?

    玩加密货币的朋友相信对助记词都不陌生,我们在使用钱包之前,会让你备份12个单词,在备份期间不允许截图操作,并且不断强调这12个单词非常重要,最好用物理方式备份,备份时身边不要有任何人. 对于普通用户来 ...

  8. android web3j 代币查询_wallet-eth 以太坊代币钱包 助记词 私钥 keystore 转账

    wallet-eth-android wallet-eth 以太坊代币钱包 助记词 私钥 keystore 转账(bip39.bip32.bip44.web3j) 生成钱包地址 // 生成钱包地址 W ...

  9. 助记词创建以太坊钱包源码_墨客科普 | MOAC区块链钱包账号管理

    本文简单描述钱包账号管理的一些方法. 一.术语 1.1 gas,Gas Limit和Gas Price 在墨客区块链上,发送代币或调用智能合约.执行写入操作,需要支付矿工计算费用,计费是按照Gas计算 ...

最新文章

  1. 阿里巴巴开源限流降级神器Sentinel大规模生产级应用实践
  2. 使tomcat和lighttpd使用service启停
  3. 地理投影展开(近似多边形体)
  4. 安全产品研发与落地的一些方法与思考
  5. 计算机应用基础作业北语,北语计算机应用基础作业.doc
  6. LINUX安装JDK1.8(wget rpm)
  7. 声明一个队列,并且指定TTL
  8. HDU4324(强连通的Tarjan算法)
  9. 入门级控件 c# 1615014955
  10. mysql 23000_mysql – SQLSTATE [23000]:完整性约束违规:1452无法添加或更新子行:外键约束失败...
  11. 大数据时代,CRM帮助企业进行升级转型
  12. IDEA和Webstorm主题配色
  13. Visual Studio 安装 FLTK
  14. 网站备案需要买服务器吗,域名备案需要购买服务器吗
  15. 一文了解plc编程、电脑编程、手机APP编程、组态编程、云编程(上)
  16. Linux命令查看Linux服务器内存、CPU、显卡、硬盘使用情况
  17. 7-2 统计英文字母和数字字符[2]
  18. 造车新势力平均月薪 15367 元,自动驾驶算法岗年薪百万
  19. cmd 下登陆ftp及相关操作
  20. 案例驱动式Python学习笔记【第三篇】居民身份证信息提取

热门文章

  1. javascript运动框架(三)
  2. 音视频、即时通讯、IM对传统聊天的影响
  3. GitOps与ChatOps的落地实践
  4. python统计代码行数_python实现统计代码行数的方法
  5. 实验二:交换机基本配置
  6. Mysql数据库索引的理解及聚簇索引和非聚簇索引的区别
  7. 河南2010年全国计算机技术与软件专业技术资格(水平)考试报名时间
  8. 大数据项目(基于spark)--新冠疫情防控指挥作战平台项目
  9. 曙光云计算技术助力解放军联合作战指挥体制
  10. 图像增强工具Augmentor常用功能汇总