以太坊 nonce, 公私钥和地址,BASE64/BASE58

  • 辉哥
  • 更新于 2019-07-09 14:41
  • 阅读 6159

搞懂以太坊易错 nonce、公私钥和地址、BASE64/BASE58 之间的关系

1. nonce

以太坊里的nonce有两种意思,一个是proof of work nonce,一个是account nonce。

  • Proof of Work nonce :一个无意义的值,可以通过调整值得大小来试图满足proof of work的condition。这其实就是挖矿的本质。这个值使得找出满足proof of work condition的值变成了一个依靠运气的计算密集型的工作。
  • Account nonce :每个帐户中用来防止 重放攻击的 交易计数器。例如,一笔从A到B发送20个币的交易可以被B不断重复来消耗A的余额。 这是为了防止双花攻击啦。举个例子比如说
  • 你发出了一笔带有normal GASPRICE的交易,正等着被矿工加到块里。
  • 你发出了另一笔带有high GASPRICE的交易想使得在第一次交易之前进行第二次交易, 使得第一笔交易无效。 在以太坊中交易中有一个nonce域,double-spends就不会发生,nonce2的交易不会在nonce1的交易之前被添加进块(也就是be mined),还要注意的是nonce不能被跳过,也就是说要是你发送了一个nonce3的交易但是没有发送nonce2,那么这个交易就没用。nonce一定要是顺序的, no skips .

在智能合约里,nonce的值代表的是该合约创建的合约数量。只有当一个合约创建另一个合约的时候才会增加nonce的值。但是当一个合约调用另一个合约中的method时 nonce的值是不变的。 在以太坊中nonce的值可以这样来获取(其实也就是属于一个账户的交易数量):

eth.getTransactionCount(accountAddress)

但是这个方法只能获取交易once的值。目前是没有内置方法来访问contract中的nonce值的

2,以太坊的公私钥,地址的关系

通过椭圆曲线算法生成钥匙对(公钥和私钥),以太坊采用的是secp256k1曲线, 公钥采用uncompressed模式,生成的私钥为长度32字节的16进制字串,公钥为长度64的公钥字串。公钥04开头。 把公钥去掉04,剩下的进行keccak-256的哈希,得到长度64字节的16进制字串,丢掉前面24个,拿后40个,再加上"0x",即为以太坊地址。

整个过程可以归纳为:

Get Private-key[32字节] -> Public-key[64字节]-> (Keccak-256( Public-key))-> Address [20字节] secp256k1 -> 19784D0BCAE8E040DE1A33DAA74C749A1309BBD5E7776B3881F83531CE279636 -> ... -> 0xDD55dA111fBfcc671966D138dE7DFA249a6e76cC

3, BASE64和BASE58的区别?

2)有些网关或系统只能使用ASCII字符。Base64就是用来将非ASCII字符的数据转换成ASCII字符的一种方法,而且base64特别适合在http,mime协议下快速传输数据。Base64使用【字母azAZ数字09和+/】这64个字符编码。原理是将3个字节转换成4个字节(3 X 8) = 24 = (4 X 6) 当剩下的字符数量不足3个字节时,则应使用0进行填充,相应的,输出字符则使用'='占位,因此编码后输出的文本末尾可能会出现1至2个'='。

1)Base58是用于Bitcoin中使用的一种独特的编码方式,主要用于产生Bitcoin的钱包地址。相比Base64,Base58不使用数字"0",字母大写"O",字母大写"I",和字母小写"l",以及"+"和"/"符号。

Base58Check是一种常用在比特币中的Base58编码格式,增加了错误校验码来检查数据在转录中出现的错误。 校验码长4个字节,添加到需要编码的数据之后。校验码是从需要编码的数据的哈希值中得到的,所以可以用来检测并避免转录和输入中产生的错误。使用 Base58check编码格式时,编码软件会计算原始数据的校验码并和结果数据中自带的校验码进行对比。二者不匹配则表明有错误产生,那么这个 Base58Check格式的数据就是无效的。例如,一个错误比特币地址就不会被钱包认为是有效的地址,否则这种错误会造成资金的丢失。

为了使用Base58Check编码格式对数据(数字)进行编码,首先我们要对数据添加一个称作“版本字节”的前缀,这个前缀用来明确需要编码的数 据的类型。例如,比特币地址的前缀是0(十六进制是0x00),而对私钥编码时前缀是128(十六进制是0x80)。 表4-1会列出一些常见版本的前缀。

接下来,我们计算“双哈希”校验码,意味着要对之前的结果(前缀和数据)运行两次SHA256哈希算法:

checksum = SHA256(SHA256(prefix+data)) 在产生的长32个字节的哈希值(两次哈希运算)中,我们只取前4个字节。这4个字节就作为校验码。校验码会添加到数据之后。

结果由三部分组成:前缀、数据和校验码。这个结果采用之前描述的Base58字母表编码。下图描述了Base58Check编码的过程。

相同:

  1. 一般都用于URL, 邮件文本, 可见字符显示.
  2. 都会造成信息冗余, 数据量增大, 因此不会用于大数据传输编码. 区别:
  3. 编码集不同, base 58 的编码集在 base 64 的字符集的基础上去掉了比较容易混淆的字符.
  4. base 64 采用直接切割 bit 的方法(8->6), 而 base 58 采用大数进制转换, 效率更低, 使用场景更少. Note: base 58 解码时需要将长度传入, 这点与 base 64 有区别, 在代码实现时应注意.

10,参考

1) 哈希算法、Merkle树、公钥密码算法 https://blog.csdn.net/s_lisheng/article/details/77937202?from=singlemessage

2)全新的 SHA-3 加密标准 —— Keccak https://blog.csdn.net/renq_654321/article/details/79797428

3)在线加密算法 http://tools.jb51.net/password/hash_md5_sha

4)比特币地址生成算法详解 https://www.cnblogs.com/zhaoweiwei/p/address.html

5)Base58Check编码实现示例 https://blog.csdn.net/QQ604666459/article/details/82419527

6) 比特币交易中的签名与验证 https://www.jianshu.com/p/a21b7d72532f

点赞 1
收藏 0
分享

0 条评论

请先 登录 后评论
辉哥
辉哥
0x5bAe...0BE7
HiBlock技术社区上海合伙人,区块链落地产业应用布道者