当前位置: 首页 > news >正文

交互做的好的网站seo研究

交互做的好的网站,seo研究,开网店的流程有哪些,17网一起做网店广州货源网学习 NEO 钱包的 O3 项目 ,其中有用到 NeoSwift 库,记录一下。私钥是怎么来的?私钥是一个32字节的随机数,这个数的范围是介于 1 ~ 0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE BAAE DCE6 AF48 A03B BFD2 5E8C D036 4141 之间。见 …

学习 NEO 钱包的 O3 项目 ,其中有用到 NeoSwift 库,记录一下。

私钥是怎么来的?

私钥是一个32字节的随机数,这个数的范围是介于 1 ~ 0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE BAAE DCE6 AF48 A03B BFD2 5E8C D036 4141 之间。

见 Account.swift 类:

public init?() {var pkeyData = Data(count: 32)let result = pkeyData.withUnsafeMutableBytes {SecRandomCopyBytes(kSecRandomDefault, pkeyData.count, $0)}if result != errSecSuccess {fatalError()}var error: NSError?guard let wallet = NeoutilsGeneratePublicKeyFromPrivateKey(pkeyData.fullHexString, &error) else { return nil }self.wif = wallet.wif()self.publicKey = wallet.publicKey()self.privateKey = pkeyDataself.address = wallet.address()self.hashedSignature = wallet.hashedSignature()//default to mainnetself.neoClient = NeoClient.sharedMain}

它是通过 Security.framework 库里的 SecRandomCopyBytes 方法,生成一组密码安全的随机字节:

/*!@function SecRandomCopyBytes@abstract Return count random bytes in *bytes, allocated by the caller.It is critical to check the return value for error@result Return 0 on success, any other value on failure.
*/
@available(iOS 2.0, *)
public func SecRandomCopyBytes(_ rnd: SecRandomRef?, _ count: Int, _ bytes: UnsafeMutableRawPointer) -> Int32

随机生成一个32字节的 Data 数据,即 privatekeyData

var pkeyData = Data(count: 32)let result = pkeyData.withUnsafeMutableBytes {SecRandomCopyBytes(kSecRandomDefault, pkeyData.count, $0)}

然后根据私钥(用 privatekeyDataHexString 作为参数)生成一个钱包,见 neo-utils:

var error: NSError?
guard let wallet = NeoutilsGeneratePublicKeyFromPrivateKey(pkeyData.fullHexString, &error) else { return nil }
// Generate a wallet from a private key
func GenerateFromPrivateKey(privateKey string) (*Wallet, error) {pb := hex2bytes(privateKey)var priv btckey.PrivateKeyerr := priv.FromBytes(pb)if err != nil {return &Wallet{}, err}wallet := &Wallet{PublicKey:       priv.PublicKey.ToBytes(),PrivateKey:      priv.ToBytes(),Address:         priv.ToNeoAddress(),WIF:             priv.ToWIFC(),HashedSignature: priv.ToNeoSignature(),}return wallet, nil
}

公钥是怎么来的?

公钥是用私钥通过椭圆曲线算法得到的,但是无法从公钥算出私钥。

见neowallet.go 和 btckey.go:

// Generate a wallet from a private key
func GenerateFromPrivateKey(privateKey string) (*Wallet, error) {pb := hex2bytes(privateKey)var priv btckey.PrivateKeyerr := priv.FromBytes(pb)if err != nil {return &Wallet{}, err}wallet := &Wallet{PublicKey:       priv.PublicKey.ToBytes(),PrivateKey:      priv.ToBytes(),Address:         priv.ToNeoAddress(),WIF:             priv.ToWIFC(),HashedSignature: priv.ToNeoSignature(),}return wallet, nil
}
// derive derives a Bitcoin public key from a Bitcoin private key.
func (priv *PrivateKey) derive() (pub *PublicKey) {/* See Certicom's SEC1 3.2.1, pg.23 *//* Derive public key from Q = d*G */Q := secp256r1.ScalarBaseMult(priv.D)/* Check that Q is on the curve */if !secp256r1.IsOnCurve(Q) {panic("Catastrophic math logic failure in public key derivation.")}priv.X = Q.Xpriv.Y = Q.Yreturn &priv.PublicKey
}

地址脚本是怎么来的?

地址脚本是由公钥前后各加了一个字节得到的,这两个字节是固定的:

  • 前面是:0x21
  • 后面是:0xAC

见 btckey.go:

/* Convert the public key to bytes */pub_bytes := pub.ToBytes()pub_bytes = append([]byte{0x21}, pub_bytes...)pub_bytes = append(pub_bytes, 0xAC)

地址ScriptHash是怎么来的?

地址ScriptHash就是地址脚本取了个Hash,一次 sha256,一次ripemd160

见 btckey.go:

/* SHA256 Hash */sha256_h := sha256.New()sha256_h.Reset()sha256_h.Write(pub_bytes)pub_hash_1 := sha256_h.Sum(nil)/* RIPEMD-160 Hash */ripemd160_h := ripemd160.New()ripemd160_h.Reset()ripemd160_h.Write(pub_hash_1)pub_hash_2 := ripemd160_h.Sum(nil)program_hash := pub_hash_2

地址是怎么来的?

地址是由地址ScriptHash加了盐,加了验证功能,然后 Base58 编码得到的:

  • 加盐:前面加了一个字节 0x17
  • 加验证功能:把加盐后的字节做了一个 hash,两次 sha256,取前四个字节
  • 编码:Base58 编码

见 btckey.go 完整的由公钥生成地址的代码:

// ToAddress converts a Bitcoin public key to a compressed Bitcoin address string.
func (pub *PublicKey) ToNeoAddress() (address string) {/* See https://en.bitcoin.it/wiki/Technical_background_of_Bitcoin_addresses *//* Convert the public key to bytes */pub_bytes := pub.ToBytes()pub_bytes = append([]byte{0x21}, pub_bytes...)pub_bytes = append(pub_bytes, 0xAC)/* SHA256 Hash */sha256_h := sha256.New()sha256_h.Reset()sha256_h.Write(pub_bytes)pub_hash_1 := sha256_h.Sum(nil)/* RIPEMD-160 Hash */ripemd160_h := ripemd160.New()ripemd160_h.Reset()ripemd160_h.Write(pub_hash_1)pub_hash_2 := ripemd160_h.Sum(nil)program_hash := pub_hash_2//wallet version//program_hash = append([]byte{0x17}, program_hash...)// doublesha := sha256Bytes(sha256Bytes(program_hash))// checksum := doublesha[0:4]// result := append(program_hash, checksum...)/* Convert hash bytes to base58 check encoded sequence */address = b58checkencodeNEO(0x17, program_hash)return address
}
// b58checkencode encodes version ver and byte slice b into a base-58 check encoded string.
func b58checkencodeNEO(ver uint8, b []byte) (s string) {/* Prepend version */bcpy := append([]byte{ver}, b...)/* Create a new SHA256 context */sha256_h := sha256.New()/* SHA256 Hash #1 */sha256_h.Reset()sha256_h.Write(bcpy)hash1 := sha256_h.Sum(nil)/* SHA256 Hash #2 */sha256_h.Reset()sha256_h.Write(hash1)hash2 := sha256_h.Sum(nil)/* Append first four bytes of hash */bcpy = append(bcpy, hash2[0:4]...)/* Encode base58 string */s = b58encode(bcpy)// /* For number of leading 0's in bytes, prepend 1 */// for _, v := range bcpy {//  if v != 0 {//      break//  }//  s = "1" + s// }return s
}

WIF 是怎么来的?

WIF(Wallet Import Format)是由私钥在前面加了一个版本号字节 0x80,在后面加了一个压缩标志的字节 0x01,然后对这34个字节进行哈希,取哈希值的前4个字节作为校验码加在最后面,最后经过 Base58 编码得到:

  • 前面加版本字节:0x80
  • 后面加压缩标志字节:0x01
  • 对这34个字节进行哈希:取哈希值的前4个字节加在最后面
  • 编码:Base58 编码

【注】其中“对这34个字节进行哈希”,我找的在线工具做的Hash计算,结果跟 NEO学习笔记,从WIF到地址 文章中的结果不一致,不知道怎么计算的,有了解的请留言,谢谢!

图解:

NEO 之从私钥到地址

总结

欢迎留言讨论,有错误请指出,谢谢!

QQ:3500229193
QQ群:685698708(辞のNEO技术开发交流)

参考链接
  • http://www.cnblogs.com/crazylights/p/8166690.html
  • https://github.com/CityOfZion/neo-swift/blob/master/NeoSwift/Account.swift
  • https://developer.apple.com/documentation/security/1399291-secrandomcopybytes
  • https://github.com/apisit/neo-wallet-address-go/blob/master/neowallet.go
  • https://github.com/O3Labs/neo-utils/blob/master/neoutils/neowallet.go
  • https://github.com/apisit/btckeygenie/blob/master/btckey/btckey.go
  • https://www.zhihu.com/question/22399196
  • https://mp.weixin.qq.com/s/jOcVk7olBDgBgoy56m5cxQ
  • https://www.jianshu.com/p/af6328cc693e
  • https://en.bitcoin.it/wiki/Wallet_import_format
  • http://gobittest.appspot.com/PrivateKey
更新日志
  • 2018.03.13 第一次更新
  • 2018.03.14 第二次更新
  • 2018.03.15 第三次更新
  • 2018.03.21 第四次更新


作者:宅小馒
链接:https://www.jianshu.com/p/4d82bc67c6b5
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。



http://www.lbrq.cn/news/2429569.html

相关文章:

  • 兴化网站制作全国疫情最新信息
  • 网站悬浮窗口徐州seo排名公司
  • 鬼畜做的青龙游戏网站百度搜索什么关键词排名
  • 云南做网站报价百度指数搜索热度
  • 什么网站百度收录快推广app下载
  • 宁波门户网站建设国家市场监管总局
  • 网站开发代理第一营销网
  • 江苏连云港网站建设公司北京seo全网营销
  • 济南城乡建设局官网锦绣大地seo官网
  • 做终端客户网站网络推广seo怎么做
  • 网站上传的图片怎么做的清晰合肥网
  • 好看的个人博客主页系统优化方法
  • 背投广告典型网站网站空间
  • 搭建网站用服务器还是虚拟主机做网站找哪家好
  • 思政部网站建设总结关键字挖掘机爱站网
  • 加上强机关网站建设管理的通知seo优化推广公司
  • 上海知名的网站建设公百度网首页官网
  • 南京做网站南京乐识最优百度大数据搜索引擎
  • 兰州百度公司网站建设常州免费网站建站模板
  • 南京h5 网站建设百度下载链接
  • 做网站字体格式用锐利吗要怎么网络做推广
  • wordpress 企业站模板建网站平台
  • 青岛做物流网站最新全国疫情实时大数据
  • 网站开发技术网站模板关键词广告
  • 建e网室内设计图seo推广如何做
  • 淘宝购物网站开发有什么功能网络营销专业代码
  • 犀牛建筑网校seo排名诊断
  • 上海网络平台网站建设网络服务提供者知道或者应当知道
  • 网站建设的主要内容包括网络营销期末考试试题及答案
  • 厦门建设局网站中标结果查询昆明seo建站
  • 遇到JAVA问题
  • Java函数指南:从Function到BiFunction的深度解析
  • 第十一章 用Java实现JVM之异常处理
  • 深入理解 Qt 中的 QImage 与 QPixmap:底层机制、差异、优化策略全解析
  • 音视频学习(四十二):H264帧间压缩技术
  • vxe-table 通过配置 ajax 方式自动请求数据,适用于简单场景的列表