分类 技术前沿 下的文章 - 六币之门
首页
视频教程
网站导航
活动日历
关于我们
用户投稿
推荐
新闻动态
搜 索
1
融资周报 | 公开融资事件11起;加密技术公司Toposware完成500万美元融资,Polygon联创参投
107 阅读
2
六币日报 | 九只比特币ETF在6天内积累了9.5万枚BTC;贝莱德决定停止推出XRP现货ETF计划
74 阅读
3
六币日报 | 美国SEC再次推迟对灰度以太坊期货ETF做出决定;Do Kwon已出黑山监狱等待引渡
69 阅读
4
融资周报 | 公开融资事件27起;L1区块链Monad Labs完成2.25亿美元融资,Paradigm领投
68 阅读
5
【ETH钱包开发06】查询某个地址的交易记录
43 阅读
新闻动态
每日快报
一周精选
融资情况
项目投研
自治组织
数字藏品
去中心化应用
去中心化游戏
去中心化社交
去中心化金融
区块链交易所
科普知识
小白入门
用户手册
开发文档
行业报告
技术前沿
登录
搜 索
标签搜索
新闻
日报
元歌Eden
累计撰写
1,087
篇文章
累计收到
0
条评论
首页
栏目
新闻动态
每日快报
一周精选
融资情况
项目投研
自治组织
数字藏品
去中心化应用
去中心化游戏
去中心化社交
去中心化金融
区块链交易所
科普知识
小白入门
用户手册
开发文档
行业报告
技术前沿
页面
视频教程
网站导航
活动日历
关于我们
用户投稿
推荐
新闻动态
用户登录
登录
找到
109
篇与
技术前沿
相关的结果
2023-03-24
开源,免费的EOS, ETH,XLM收款插件
无需搭建比特币/以太坊/EOS全节点(每一个都需要几百G空间) 无手续费,你的程序你做主 所有收到的钱实时自动转移到开发者个人账户,即使被拖库也没钱可盗。 开发者访问本地 http 接口,向用户展示付款方法,用户付款后程序会访问本地回调URLGitHub 地址步骤:1. 创建一个Mixin Messenger账户.访问 mixin.one/messenger 下载对应手机端App。中国大陆用户可以访问 a.app.qq.com/o/simple.js… 下载2. 激活开发者账号登陆 developer.mixin.one ,用App扫码登录这个 教程对于新开发者很有用。Clone, build, rungit clone https://github.com/myrual/mixin-network-snapshot-golang cd mixin-network-snapshot-golang 复制代码编辑一部分配置信息 const ( userid = "3c5fd587-5ac3-4fb6-b294-423ba3473f7d" sessionid = "42848ded-0ffd-45eb-9b46-094d5542ee01" private_key = `-----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgQDACTrT4uaB9el9qe0MUOsFrm8kpaDI9PowauMB1Ha25mpfL+5h MFqISLS5z2P89nAsXBg+KyQ2gAVA6rBwW/ZqOc1PKiJhhLBS80nzo3ayfv7OlzNG IxMyqD5izCCtPixnqpuTePoPWq4CNZlxop0VYklsWEfU0U0qqMBgmtqYfQIDAQAB AoGAR8crZed5oTn5fC73m5LjRcxdXqVJ49MtcMuC7jwr41FckRepUkpwjGAgrRMH nJXAd9Q0e4hEkNppHEqciGLXR1dQfZnaM1Gnv7mD3oSgHaH+4qAMnNOCpvwW4Eu3 yp9b1UGj9SvM3D2BrpA+MGf0E/yEJzpRcT956W6SPYYSegECQQDm4uTK+teoxr1Z agJZuCta+IhMzpxIWMob+JN/Huf7OnRcIa9JpXngg4tHOUWmZCDQdqeJMpaQc8SQ 44hba015AkEA1OyJswNIhdmvVp5P1zgREVVRK6JloYwmAtj+Qo4pWJ117LqH4w+b 491r4AeLEGh8VrZ4k6Hp+Cm783S2jTAWJQJARbWdlHdV45xVkQiDuyjy1h2RsXb0 EpfUNcvAZLIlImIMvcBh1x+CA7pTs+Zj1BAJJEee37qJYQXDBGfeRJPKKQJAVG+c x42Ew/eoTZwoIzvLoOkJcFlNHjwaksSER9ZiVQ7URdVOr99vvXQAJG45Wn9k12oy 9LCfvNan/wqIngK0tQJBAL1Wc02seEbMeWyt5jycJEhn6G8F18s9S1v0GXb4U/7/ 6Y87P3TmDLcEuCXkrbZQaCX7jVLu0BkDw8To58TWjh0= -----END RSA PRIVATE KEY-----` ADMIN_MessengerID = ""//this is your mixin messenger id, you can find your id in contact page. ) 复制代码编译 go build mixin_snap.go 复制代码运行 ./mixin_snap 复制代码数据库 同一目录下会生成一个test.db 的sqlite3文件。 如何使用获取数字资产当前价格信息,因此可以计算客户应该付多少数字资产curl -X GET 'http://localhost:8080/assetsprice' 复制代码价格结果如下,其中Full Name是该币种全名,Symbol是在交易所和钱包的缩写符号,USDPrice是当前资产美元价格,BTCPrice同理。[ , , ] 复制代码如果订单价值1美金,那么根据资产价格可以知道客户需要 10 XLM, 或者 0.17 EOS。创建支付请求用POST方法访问 localhost:8080/charges,参数如下POST /chargesAttributes type description currency String Currency code associated with the amount. Only EOS/XLM/ETH is supported currently amount Float64 Positive float customerid String This field is optional and can be used to attach an identifier of your choice to the charge. Must not exceed 64 characters webhookurl String program will visit localhost+webhook when user pay enough currency before charge is expired expiredafter uint the webhook will be expired after xx minutes. User can pay to an expired charge , program keep income record and will transfer asset to admin account 举例: 需要让客户 "client1245" 支付 0.001 ETH, 60分钟内支付完成之后访问用 POST 访问 localhost:9090/123。curl -d '' -H "Content-Type: application/json" 127.0.0.1:8080/charges 复制代码这条指令返回结果{ "Id":3, "Currency":"ETH", "Amount":0.001, "Customerid":"client1245", "Webhookurl":":9090/123", "Expired_after":60, "Paymentmethod":{ "Name":"ETH", "PaymentAddress":"0x130D3e6655f073e33235e567E7A1e1E1f59ddD79", "PaymentAccount":"", "PaymentMemo":"", "Priceinusd":"310.40105841", "Priceinbtc":"0.02374051" }, "Receivedamount":0, "Paidstatus":0} 复制代码客户需要向以太坊地址 0x130D3e6655f073e33235e567E7A1e1E1f59ddD79 支付0.001 ETH来完成支付。如果想收EOS $ curl -d '' -H "Content-Type: application/json" 127.0.0.1:8080/charges 复制代码{ "Id":2, "Currency":"EOS", "Amount":0.001, "Customerid":"client1245", "Webhookurl":":9090/123", "Expired_after":5, "Paymentmethod":{ "Name":"EOS", "PaymentAddress":"", "PaymentAccount":"eoswithmixin", "PaymentMemo":"a01a148f234ea8be0229a4422d21e7f3", "Priceinusd":"4.63264861", "Priceinbtc":"0.00040277" }, "Receivedamount":0, "Paidstatus":0 } 复制代码客户需要向EOS账户 eoswithmixin 支付 0.001 EOS, 并且必须填写支付备注 a01a148f234ea8be0229a4422d21e7f3。如果想收XLMcurl -d '' -H "Content-Type: application/json" 127.0.0.1:8080/charges 复制代码{ "Id":3, "Currency":"XLM", "Amount":0.001, "Customerid":"client1245", "Webhookurl":":9090/123", "Expired_after":5, "Paymentmethod":{ "Name":"XLM", "PaymentAddress":"", "PaymentAccount":"GD77JOIFC622O5HXU446VIKGR5A5HMSTAUKO2FSN5CIVWPHXDBGIAG7Y", "PaymentMemo":"45da67ad857c907a", "Priceinusd":"0.08866487", "Priceinbtc":"0.00000769" }, "Receivedamount":0, "Paidstatus":0 } 复制代码客户需要向Stellar账户 GD77JOIFC622O5HXU446VIKGR5A5HMSTAUKO2FSN5CIVWPHXDBGIAG7Y 支付 0.001 XLM, 并且必须填写支付备注 45da67ad857c907aPayment_method里面有两种类型的支付:比特币/以太坊: PaymentAddress 不是空,PaymentAccount 和 PaymentMemo是空。这种情况下,你只需要给用户展示资产名字 以太坊和PaymentAddress,客户只需要向以太坊地址付款。在这个例子里面,向用户展示资产名称 ETH,以及收款地址 0x365DA43BC7B22CD4334c3f35eD189C8357D4bEd6,以及你期望的以太坊数量。 EOS/行星 : PaymentAddress 是空, PaymentAccount 和 PaymentMemo 都有内容。这种情况下,你需要给用户展示资产名字,收款账户和收款备注,并且严肃的提醒用户同时填写收款账户和收款备注,客户如果忘记填写备注,会导致不能到账,而且无法退款。 Payment_method的记录内容里面有该资产当前的美元价格和比特币价格,开发者可以根据订单的美元价格来计算客户应该支付多少数字货币。 复制代码支持的货币列表Currency 说明 介绍 EOS EOS.io 主网token - XLM Stellar 主网token - BTC 比特币 - UDT Tether USD 基于比特币的USDT,不是ERC20的代币 XRP 锐波币 - LTC 莱特币 - 检查收款状态访问 localhost:8080/charges, 带有参数charge_id例子 curl -X GET 'http://localhost:8080/charges?charge_id=3' 复制代码如果客户还没有支付,结果如下{ "Id":3, "Currency":"ETH", "Amount":0.001, "Customerid":"client1245", "Webhookurl":":9090/123", "Expired_after":60, "Paymentmethod":{ "Name":"ETH", "PaymentAddress":"0x130D3e6655f073e33235e567E7A1e1E1f59ddD79", "PaymentAccount":"", "PaymentMemo":"", "Priceinusd":"310.40105841", "Priceinbtc":"0.02374051" }, "Receivedamount":0, "Paidstatus":0} } 复制代码如果客户已经支付了,那么结果如下{ "Id":3, "Currency":"ETH", "Amount":0.001, "Customerid":"client1245", "Webhookurl":":9090/123", "Expired_after":60, "Paymentmethod":{ "Name":"ETH", "PaymentAddress":"0x130D3e6655f073e33235e567E7A1e1E1f59ddD79", "PaymentAccount":"", "PaymentMemo":"", "Priceinusd":"309.75108846", "Priceinbtc":"0.02369282" }, "Receivedamount":0.002, "Paidstatus":2 } 复制代码支付状态 Paidstatus的解释值 解释 0 还没有支付 1 支付不足 2 支付完毕 3 支付超过需求 payment_records 有支付信息. 其中一个支付信息如下回调URL用户支付完毕后,程序会访问本地+webook url"http://127.0.0.1"+webhookurl 复制代码http 方法为POST,body 参数如下{ "Id":3, "Currency":"ETH", "Amount":0.001, "Customerid":"client1245", "Webhookurl":":9090/123", "Expired_after":60, "Paymentmethod":{ "Name":"ETH", "PaymentAddress":"0x130D3e6655f073e33235e567E7A1e1E1f59ddD79", "PaymentAccount":"", "PaymentMemo":"", "Priceinusd":"309.75108846", "Priceinbtc":"0.02369282" }, "Receivedamount":0.0021, "Paidstatus":2 } 复制代码所有资产都属于开发者自己么?所有资产都会自动被转移到你指定的账户, 免手续费,1秒到账。 在该程序重启,或者意外退出之后,你可以手动发指令要求程序把所有资产都转移到你指定的账户。 例子:curl -X POST -H "Content-Type: application/json" 127.0.0.1:8080/moneygohome 复制代码结果如下total 20 account will send all balance to admin 复制代码支付的确认时间EOS: 3 分钟 Stellar: 2 分钟 Bitcoin/USDT: 60 分钟 Litecoin/Ethererum/DOGE: 120 分钟 什么是确认时间?为什么要关心确认时间?数字货币从用户发起转账请求,到收款方确认这笔付款不能回滚需要一点时间,比特币需要的时间长,其他需要的时间短一点。支持哪些资产理论上Mixin Network支持的都可以接受。现在支持 BTC, USDT, BCH, 以太坊和 ERC20, ETC, EOS 以及EOS上发的token, DASH, Litecoin, Doge, Horizen, MGD, NEM, XRP, XLM, 波场和波场上发的TRC10, Zcash.目前的代码库默认支持的资产现在代码里面默认支持的资产是EOS和恒星,因为他们都可以3分钟完成支付确认。想要支持更多的币,把对应资产的变量放到 default_asset_id_group 里面就可以.const ( BTC_ASSET_ID = "c6d0c728-2624-429b-8e0d-d9d19b6592fa" EOS_ASSET_ID = "6cfe566e-4aad-470b-8c9a-2fd35b49c68d" USDT_ASSET_ID = "815b0b1a-2764-3736-8faa-42d694fa620a" ETC_ASSET_ID = "2204c1ee-0ea2-4add-bb9a-b3719cfff93a" XRP_ASSET_ID = "23dfb5a5-5d7b-48b6-905f-3970e3176e27" XEM_ASSET_ID = "27921032-f73e-434e-955f-43d55672ee31" ETH_ASSET_ID = "43d61dcd-e413-450d-80b8-101d5e903357" DASH_ASSET_ID = "6472e7e3-75fd-48b6-b1dc-28d294ee1476" DOGE_ASSET_ID = "6770a1e5-6086-44d5-b60f-545f9d9e8ffd" LTC_ASSET_ID = "76c802a2-7c88-447f-a93e-c29c9e5dd9c8" SIA_ASSET_ID = "990c4c29-57e9-48f6-9819-7d986ea44985" ZEN_ASSET_ID = "a2c5d22b-62a2-4c13-b3f0-013290dbac60" ZEC_ASSET_ID = "c996abc9-d94e-4494-b1cf-2a3fd3ac5714" BCH_ASSET_ID = "fd11b6e3-0b87-41f1-a41f-f0e9b49e5bf0" XIN_ASSET_ID = "c94ac88f-4671-3976-b60a-09064f1811e8" CNB_ASSET_ID = "965e5c6e-434c-3fa9-b780-c50f43cd955c" XLM_ASSET_ID = "56e63c06-b506-4ec5-885a-4a5ac17b83c1" TRON_ASSET_ID = "25dabac5-056a-48ff-b9f9-f67395dc407c" ........ ) ....... ....... // to support more asset, just add them in the following array default_asset_id_group := []string 复制代码下一步的开发任务:所有的资产可以自动提取到开发者自己的冷钱包,而不是只能转移到Mixin Messenger账户。 可以把收到的资产通过去中心化交易所自动转换成USDT或者比特币。 支持Mixin Messenger用户付款。 可以提供资产对应的美元价格 在commit 8a634e23254e4841c2a9c3114b3eb847d46f55fc 中已经完成。
2023年03月24日
4 阅读
0 评论
0 点赞
2023-03-24
[译] 数字货币钱包详解
原文地址:ethereumbook-wallets 原文作者:ethereumbook 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gold-m… 译者:XatMassacrE 校对者:leviding 「钱包」这个词语在以太坊中表示的并不是它本来的意思。宏观的讲,钱包主要就是为用户提供用户界面的一个应用。它掌管着用户的金钱,管理着密钥和地址,追踪账户余额以及创建交易和签名。除此之外,一些以太坊钱包还可以与智能合约进行交互,例如代币之类的。而从一个程序员的角度更准确的讲,「钱包」这个词语指的就是存储和管理密钥和地址的系统。每一个「钱包」都有一个密钥管理组件。而对于有些钱包来说,这就是钱包的全部。其他的大部分钱包都是「浏览器」,其实就是基于以太坊的去中心化应用的接口。所以这些各式各样的「钱包」之间并没有什么明确的界限。接下来让我们先看一看钱包关于密钥管理和私钥容器部分的功能。钱包技术总览在这个部分我们会总结用于构建用户友好、安全以及灵活的以太坊钱包所需要的各种技术。关于以太坊有一个最常见的误解就是大部分人认为以太坊钱包包含以太坊和其他代币。而实际上,钱包只包含密钥。以太坊和其他代币都被记录在以太坊的区块链中。用户通过使用他们钱包中的密钥对钱包签名来控制代币。所以从某种意义上讲,以太坊钱包就是一个钥匙串。提示以太坊钱包只包含密钥,而没有以太坊和代币。每一个用户的钱包都包含密钥。钱包就是包含公私钥对的钥匙串。用户使用密钥对交易签名,以此来证明这些以太坊就是属于他们的。而真正的以太坊则存储在区块链上。目前主要有两种类型的钱包,他们的区别就是所包含的密钥之间是否有关联。第一种类型叫做非确定性钱包,它的每一个密钥都是通过一个随机数独立生成的。密钥之间相互没有关联。这种钱包也叫做 JBOK 钱包(来自 "Just a Bunch Of Keys")。第二种钱包叫做确定性钱包,它所有的密钥都来源于一个单独的叫做种子的主密钥。在这个钱包中所有的密钥都相互关联,并且任何拥有原始种子的人都可以将这些密钥再生成一遍。这种确定性钱包会使用很多不同的密钥派生方法。而其中使用最普遍的则是一种类似树形结构的方法,这样的钱包被称为分层确定性或者 HD 钱包。分层确定性钱包是通过一个种子来初始化的。而为了便于使用,种子会被编码成英语单词(或者其他语言的单词),这些单词被称为助记词。下面的章节将会在更高级的层面介绍这些技术。非确定性(随机)钱包在第一个的以太坊钱包(以太坊预售时发布的)中,钱包文件会存储一个单独随机生成的私钥。然而这种钱包之后被确定性钱包取代了,因为这种钱包无法管理、备份以及导入私钥。但是随机密钥的缺点是,如果你生成了很多那么你就要把它们全部拷贝下来。每一个密钥都要备份,否则一旦钱包丢失,那些密钥对应的资产也会丢失。进一步讲,以太坊地址的隐私性会因为相互之间关联的多笔交易和地址的重复使用而大大降低。一个类型-0 的非确定性钱包并不是一个好的选择,尤其是当你为了避免地址的重复使用而不得不管理多个密钥并不断频繁的备份它们时。很多以太坊客户端(包括 go-ethereum 和 geth)都会使用一个钥匙串文件,这是一个 JSON 编码的文件,而且它还包含一个单独的(随机生成的)私钥,为了安全性,这个私钥会通过一个密码进行加密。这个 JSON 文件就像下面这样:{ "address": "001d3f1ef827552ae1114027bd3ecf1f086ba0f9", "crypto": { "cipher": "aes-128-ctr", "ciphertext": "233a9f4d236ed0c13394b504b6da5df02587c8bf1ad8946f6f2b58f055507ece", "cipherparams": { "iv": "d10c6ec5bae81b6cb9144de81037fa15" }, "kdf": "scrypt", "kdfparams": { "dklen": 32, "n": 262144, "p": 1, "r": 8, "salt": "99d37a47c7c9429c66976f643f386a61b78b97f3246adca89abe4245d2788407" }, "mac": "594c8df1c8ee0ded8255a50caf07e8c12061fd859f4b7c76ab704b17c957e842" }, "id": "4fcb2ba4-ccdb-424f-89d5-26cce304bf9c", "version": 3 } 复制代码钥匙串格式使用的是Key Derivation Function (KDF),同时还被成为密码拉伸算法,这个算法可以防止暴力破解、字典攻击以及彩虹表攻击。简单来说就是私钥并不是直接通过密码简单的进行加密的。相反,这个密码是通过不断的重复哈希拉伸过的。这个哈希函数会重复 262144 轮,这个数字就是钥匙串 JSON 文件中的 crypto.kdfparams.n 这个参数指定的。一个攻击者试图通过暴力破解的手段来破解密码的话,那么他需要为每一个可能的密码执行 262144 轮哈希,这样对于一个足够复杂和长度的密码来说被破解几乎是不可能的。这里还有一些软件库可以读取和写入钥匙串格式,例如 JavaScript 的库 keythereum:github.com/ethereumjs/…提示除了一些简单的测试之外,我们是不推荐使用非确定性钱包的。我们推荐使用的是拥有助记词种子备份功能的基于行业标准的HD 钱包。确定性钱包(种子)钱包确定性或者说「种子」钱包是指那些所有的私钥都是通过一个普通的种子使用一个单向哈希函数延伸而来的钱包。这个种子是结合一些其他的数据而随机生成的数字,例如利用一个索引数字或者「链码」(查看HD 钱包(BIP-32/BIP-44)来派生出私钥。在一个确定性钱包中,一个种子就足够恢复出所有派生的密钥,因此只需要在创建的时候做一次备份就可以了。同时,这个种子对于钱包来说也是可以导入导出的,可以让所有用户的密钥在各种不同的钱包之间进行简单的迁移。HD 钱包 (BIP-32/BIP-44)确定性钱包的开发就是为了可以简单的从一个「种子」派生出很多个密钥。而这种确定性钱包最高级的实现就是由比特币的 BIP-32 标准定义的 HD 钱包。HD 钱包包含的密钥来源于一个树形的结构,例如一个父密钥可以派生出一系列子密钥,每一个子密钥又可以派生出一系列孙子密钥,不停的循环往复,没有尽头。这个树形结构的示意图如下:HD 钱包相对于随机的(非确定性的)密钥有两个主要的优势。一,树形结构可以表达额外的组织意义,例如当一个子密钥特定的分支用来接收转入支付而另一个不同的分支可以接收转出支付的改变。密钥的分支也可以在一些共同的设置中被使用,例如可以分配不同的分支给部门、子公司、特定的函数或者不同的账单类别。第二个优势就是用户可以使用 HD 钱包在不利用相关私钥的情况下创建一系列公钥。这样 HD 钱包就可以用来做一个安全的服务或者是一个仅仅用来观察和接收的服务,而钱包本身却没有私钥,所以它也无法花费资金。种子和助记词 (BIP-39)HD 钱包对于管理多个密钥和地址来说是一个很强力的机制。如果再结合一个从一系列英语单词(或者其他语言的单词)中创建种子的标准化方法的话,那么通过钱包进行抄写、导出和导入都变得更加简单易用。这就是大家所熟知的由标准 BIP-39 定义的助记词。今天,很多以太坊钱包(还有其他的数字货币钱包)都在使用这个标准来导入导出种子,并使用共同的助记词来进行备份和恢复。让我们来从实践的角度看一下。下面哪个种子在抄写、纸上记录以及阅读障碍这几个方面更优秀呢?一个 16 进制编码的确定性钱包种子FCCF1AB3329FD5DA3DA9577511F8F137 复制代码一个由 12 个单词组成的助记词的钱包种子wolf juice proud gown wool unfair wall cliff insect more detail hub 复制代码钱包最佳实践随着数字货币钱包技术的逐渐成熟,也慢慢形成了共同的行业标准,使得钱包在交互性、易用性、安全性和灵活性等方面大幅度提高。这些标准同时也使得钱包可以仅仅从一个单独助记词就为各种不同的数字货币派生出不同的密钥。这些共同的标准就是下面这些:基于 BIP-39 的助记词 基于 BIP-32 的 HD 钱包 基于 BIP-43 的多用途 HD 钱包结构 基于 BIP-44 的多货币多账户钱包 这些标准或许会改变,也或许会被未来的开发者废弃,但是现在它们组成的这一组连锁技术俨然已经成为了大多数数字货币的实际上的钱包标准。这些标准已经被大部分的软件和硬件钱包所采用,使得这些钱包之间可以相互通用。一个用户可以从这些钱包中的任意一个导出助记词,然后导入到另一个钱包中,并恢复所以的交易、密钥和地址。很多软件钱包都支持这种标准,例如(按字母 排序)Jaxx, MetaMask, MyEtherWallet (MEW)。硬件钱包则有 Keepkey, Ledger, and Trezor。下面的章节会详细讲解这些技术。提示如果你要实现一个以太坊钱包,他应该是一个 HD 钱包,种子会被编码成助记词以供备份,BIP-32、BIP-39、BIP-43、和 BIP-44 这些标准会在下面的章节中详细说明。助记词 (BIP-39)助记词就是代表一个随机数的单词序列,这个助记词会作为种子派生出一个确定性钱包。这个序列的单词能够再次创建种子、钱包和所有派生出的密钥。一个实现了确定性钱包助记词功能的应用将会向在第一次创建钱包的时候向用户展示一组长度为 12 到 24 的单词序列。这个序列就是钱包的备份,它可以在任何兼容的钱包上实现恢复和重建所有的密钥。助记词可以让用户更简单的备份钱包,因为相比于一组随机数助记词可读性更好,抄写的正确率也更高。提示助记词常常与「大脑钱包」想混淆。但是它们并不是一回事。而其中最主要的区别在于大脑钱包是由用户自己选择的单词组成的,而助记词则是钱包代表用户随机创建的。这个重要的区别使得助记词更加的安全,因为人类随机性的来源少的可怜。助记词编码是在 BIP-39 中定义的。注意 BIP-39 只是助记词编码的一个实现。还有很多不同的标准,比特币钱包 Electrum 就是在 BIP-39 之前使用了一组不同的单词。BIP-39 这个标准是由硬件钱包 Trezor 背后的公司提出来的,而且还兼容 Electrum 的实现。但是,BIP-39 现在已经取得了广泛的行业支持,并且兼容十几个相互操作的实现,所以 BIP-39 应该就是现在的行业标准。并且,BIP-39 可以用来生成支持以太坊的多货币钱包,而 Electrum 的种子并不支持。BIP-39 标准定义了助记词编码和种子的生成过程,也就是接下来的九个步骤。为了表达的更清楚,整个过程分成了两个部分:第一步到第六步在生成助记词,第七步到第九步在助记词到种子。生成助记词助记词是钱包使用 BIP-39 中定义的标准化过程自动生成的。钱包起始于一个熵的源头,然后添加一个校验和并将熵映射到一个单词数组中。创建一个 128 位到 256 位的随机序列(熵) 通过取 SHA256 的前(熵长度除以 32)位来创建这个随机序列的校验和。 将校验和添加到随机序列的末尾。 将序列分成几个 11 位的部分。 从预定义的 2048 个单词字典中将每一个 11 位的值映射到一个单词上面。 助记词编码就是一系列单词。 生成熵并编码成助记词将会展示出熵是如何生成助记词的。助记词编码:熵和单词长度 展示出了熵数据的大小和单词中助记词长度的关系。助记词编码: 熵(entropy)和单词(word)长度 Entropy (bits) Checksum (bits) Entropy + checksum (bits) Mnemonic length (words) 128 4 132 12 160 5 165 15 192 6 198 18 224 7 231 21 256 8 264 24 从助记词到种子助记词代表着长度为 128 到 256 位的熵。这个熵会通过密钥拉伸函数 PBKDF2 生成一个更长的(512 位)种子。这个种子再构建一个确定性钱包并派生出它的密钥。密钥拉伸函数需要两个参数:助记词和盐。盐的目的是为了让暴力破解构建查询表的难度提高。在标准 BIP-39 中,盐还有另外一个目的,那就是密码可以作为一个额外的安全因子来保护种子,这部分会在BIP-39 中的可选密码中详细讲述。第七步到第九步的过程:密钥拉伸函数 PBKDF2 的第一个参数第六步中生成的助记词。 密钥拉伸函数 PBKDF2 的第二个参数就是盐。这个盐由字符串常量 "mnemonic" 和一个额外的用户提供的密码字符串拼接构成。 PBKDF2 使用 HMAC-SHA512 算法进行了 2048 轮哈希运算对助记词和盐进行拉伸,生成一个 512 位的值作为最后的输出。这个 512 位的值就是种子。 [fig_5_7] 展示出了一个助记词是如何生成种子的。提示密钥拉伸函数以及它的 2048 轮哈希从某种程度上讲对于暴力破解助记词和密码是一个有效的保护。会让其以昂贵的代价(在计算资源上)不停的尝试成千上万种密码和助记词的组合,而这些组合的数量则犹如汪洋大海(2512)。下面的表格分别展示了 #mnemonic_128_no_pass、#mnemonic_128_w_pass 和 #mnemonic_256_no_pass 这几个类型的助记词和他们产生的种子(没有密码)的例子。128 位(bit)熵(entropy)的助记词编码(mnemonic code),无密码生成的种子(seed) Entropy input (128 bits) 0c1e24e5917779d297e14d45f14e1a1a Mnemonic (12 words) army van defense carry jealous true garbage claim echo media make crunch Passphrase (none) Seed (512 bits) 5b56c417303faa3fcba7e57400e120a0ca83ec5a4fc9ffba757fbe63fbd77a89a1a3be4c67196f57c39 a88b76373733891bfaba16ed27a813ceed498804c0570 128 位(bit)熵(entropy)的助记词编码(mnemonic code),有密码生成的种子(seed) Entropy input (128 bits) 0c1e24e5917779d297e14d45f14e1a1a Mnemonic (12 words) army van defense carry jealous true garbage claim echo media make crunch Passphrase SuperDuperSecret Seed (512 bits) 3b5df16df2157104cfdd22830162a5e170c0161653e3afe6c88defeefb0818c793dbb28ab3ab091897d0 715861dc8a18358f80b79d49acf64142ae57037d1d54 256 位(bit)熵(entropy)的助记词编码(mnemonic code),无密码生成的种子(seed) Entropy input (256 bits) 2041546864449caff939d32d574753fe684d3c947c3346713dd8423e74abcf8c Mnemonic (24 words) cake apple borrow silk endorse fitness top denial coil riot stay wolf luggage oxygen faint major edit measure invite love trap field dilemma oblige Passphrase (none) Seed (512 bits) 3269bce2674acbd188d4f120072b13b088a0ecf87c6e4cae41657a0bb78f5315b33b3a04356e53d062e5 5f1e0deaa082df8d487381379df848a6ad7e98798404 BIP-39 中的可选密码BIP-39 标准允许用户在生成种子的时候使用可选密码。如果没有使用密码,那么助记词就会被一个由常量字符串 "mnemonic" 组成的盐拉伸,然后由给定的助记词产生一个特定的 512 位种子。如果使用了密码,则拉伸函数在使用同一个助记词的情况下会产生一个不同的种子。实际上,给定一个助记词,每一个可能的密码都会生成不同的种子。并且基本上没有任何「错误」的 密码。所有的密码都是可用的并且所有的密码都可以生成不同种子,这些不同的助记词会形成一组数量巨大的为初始化的钱包。这些可能的钱包数量是如此之大 (2512),以至于实际情况中暴力破解和意外猜对的可能性几乎为零,只要密码拥有足够的复杂度和长度。提示在标准 BIP-39 中不存在「错误的」密码。每个密码都会生成一个钱包,如果不是之前使用的密码的话那就是一个新的钱包。可选密码会产生两个重要的特性:一个需要记忆的第二个因子可以防止助记词的备份被窃取。 选择密码的这些貌似拥有可信拒绝能力或者说是「监禁的钱包」使得那些小额资金的钱包经常将攻击者的注意力从那些「真正的」大额资金钱包中分散出来。 但是,需要注意的一点是使用密码会面临密码丢失的风险。如果钱包的主人缺乏行动能力或者去世了,那么就没人知道密码了,也没人知道种子是什么,那么钱包中储存的所有资金就全部丢失了。 相反,如果钱包的主人在与种子同样的地方备份了密码,那么它就失去了第二个因素的目的。 虽然密码非常有用,但是也应该结合小心的计划备份和恢复的过程来使用,因为要考虑到钱包主人生还的可能性并可以允许他们的家人来恢复数字货币的资产。助记词的工作BIP-39 在很多不同的编程语言中都有实现的库:python-mnemonic参考了 SatoshiLabs 团队在 BIP-39 中提议的 Python 版本Consensys/eth-lightwallet用于节点和浏览器(基于 BIP-39)的轻量级 JS 以太坊钱包npm/bip39比特币 BIP39 的 JavaScript 实现:用于生成确定性密钥的助记词编码还有一个在单独的网页中实现的 BIP-39 生成器,这个网页在测试和实验中非常有用。BIP-39 生成器展示了一个可以生成助记词、种子以及拓展的私钥的单独的网页。网页(iancoleman.github.io/bip39/)可以在浏览器中离线使用(在线当然也可以)。通过种子创建一个 HD 钱包HD 钱包是通过一个根种子来创建的,这个根种子一般是 128、256 或者 512 位的随机数。通常情况下,这个种子是通过一个助记词来生成的。HD 钱包中的每一个密钥都是派生自这个根种子,这样就使得通过这个种子在其他兼容性钱包中重建整个 HD 钱包成为了可能。同时还使得备份、恢复、导出以及导入包含成千上万个密钥的钱包变的非常简单,仅仅通过转移从根种子派生出的助记词就可以了。[[bip32_bip43/44]] ==== 分层确定性钱包 (BIP-32) 和路径 (BIP-43/44)大多数 HD 钱包都遵循 BIP-32 标准,同时 BIP-32 也是确定密钥生成器的实际上的行业标准。详细的说明可以查看下面的链接:github.com/bitcoin/bip…在这里我们不会讨论 BIP-32,我们只需要理解钱包中使用它的部分就可以了。在其他一些软件库中还有很多关于 BIP-32 彼此协作的实现。Consensys/eth-lightwallet用于节点和浏览器(基于 BIP-39)的轻量级 JS 以太坊钱包这里还有一个标准 BIP-32 的网页版的生成器,对于测试和实验都非常有用。bip32.org/提示这个单独的 BIP-32 生成器不是一个 HTTPS 的站点。就是为了告诉你使用这个工具不是安全的。只是用来做测试的。你不应该在生产环境中(真实的资金)使用这个网页生成的密钥。拓展公钥和私钥在 BIP-32 的术语中,一个父密钥可以拓展的生成「儿子」,这个儿子就是拓展密钥。如果它是一个私钥,那么它就是一个拓展私钥,并通过前缀 xprv 来区分:xprv9s21ZrQH143K2JF8RafpqtKiTbsbaxEeUaMnNHsm5o6wCW3z8ySyH4UxFVSfZ8n7ESu7fgir8imbZKLYVBxFPND1pniTZ81vKfd45EHKX73 复制代码一个拓展公钥通过前缀 xpub 来区分:xpub661MyMwAqRbcEnKbXcCqD2GT1di5zQxVqoHPAgHNe8dv5JP8gWmDproS6kFHJnLZd23tWevhdn4urGJ6b264DfTGKr8zjmYDjyDTi9U7iyT 复制代码HD 钱包中一个非常有用的角色就是从父公钥派生出子公钥,不包含私钥。这会给我们提供两种方法来派生子公钥:从子私钥或者直接从父公钥来派生。一个拓展公钥可以在 HD 钱包的结构中派生出所有的公钥(也只能是公钥)。无论什么情况只要部署的服务和应用有一份拓展公钥并且没有私钥,那么这个快捷方式就可以创建非常安全的公钥。这种部署可以生成无穷个公钥和以太坊地址,但是却不能花费任何发送到这些地址的资金。同时,在另外一个更安全的服务器上,拓展私钥可以派生出所有相关的私钥用来给交易签名,并花费资金。利用这种解决方案的一个常见的应用就是在一个 web 服务器上安装一个拓展公钥,来为电子商务应用服务。这个网页服务器可以使用公钥派生函数为每一笔交易(例如客户的购物车)创造出一个全新的以太坊地址。这个网页服务器没有任何私钥所以盗贼也无法窃取。不使用 HD 钱包的情况下,想做到这个程度唯一的方法就是在一个分割的安全服务器上生成上千个以太坊地址然后在电子商务服务器上预加载他们。这个方法低效笨重,并且需要经常的维护以确保电子商务服务器不会泄露密钥。还有一个常见的应用就是冷存储和硬件钱包。在这种场景下,拓展私钥可以存储在硬件钱包中,但是拓展公钥可以放在线上。用户可以按照他们的意愿创建接收的地址,私钥则会离线安全的保存。想花掉里面的资金的话,用户可以在离线签名的以太坊客户端或者支持交易签名的硬件钱包上使用拓展私钥。硬化密钥派生从 xpub 中派生出一个公钥分支的能力时很有用的,但同时也是具有风险的。知道 xpub 并不意味着知道子密钥。然而,因为 xpub 包含链码,所以如果一个子密钥被别人知道或者暴露了的话,那么它就可以和链码一起派生出所有其他的子密钥。一个单独泄露的子密钥和一个父链码一起可以暴露出所有的子私钥。而更糟糕的是,子私钥和父链码一起还可以推断出父私钥。为了避免这个风险,HD 钱包使用了另外一种叫做硬化派生的派生函数,这个函数可以「破坏」父公钥和子链码的联系。这种硬化派生函数是使用父私钥来派生出子链码的,而不是父公钥。这样会在父或子序列中创造出一个「防火墙」,而这个防火墙并不会威胁到父或者子私钥的安全。简单的来说就是,如果不想承受泄露你自己链码风险,并且还想要方便的使用 xpub 来派生出公钥分支,那么你应该通过硬化父辈来派生它,而不是一个正常的父辈。这其中的最佳实践就是,为了防止威胁到主要的密钥,主要密钥的 level-1 子辈总是通过硬化派生来派生。正常派生和硬化派生的指数BIP-32 中的派生函数使用的是一个 32 位整型的指数。为了方便的区分出正常派生函数和硬化派生函数生成的密钥,这个指数分成了两个区间。0 到 231–1 (0x0 to 0x7FFFFFFF) 只用来表示正常的派生。231 到 232–1 (0x80000000 to 0xFFFFFFFF) 只用来表示硬化派生。因此,如果指数小于 231,则子辈是正常的,如果指数大于等于 231,那么子辈就是硬化的。为了让指数的易读性和显示性更好,硬化子辈的指数是从零开始显示的(有一个素数符合)。第一个正常子密钥则显示为 0,这样第一个硬化子辈(指数为 0x80000000)就会显示为 0'。而第二个硬化密钥指数从 0x80000001 开始,并且显示为1',以此类推。当你看到一个 HD 钱包的指数为 i' 时,就意味着 231+i。HD 钱包密钥标识符(路径)一个 HD 钱包中的密钥是通过「路径」命名规则来标识的,对于树的每一个层级都通过斜杠 (/) 这个字符来分隔(查看HD 钱包路径示例)。 从主私钥派生出的私钥都以 "m." 开头。从主公钥派生出的公钥以 "M." 开头。因此主私钥的第一个子私钥就是 m/0。主公钥的第一个子公钥就是 M/0。第一个子辈的第二个孙子就是 m/0/1,以此类推。一个密钥的「祖先」是从右向左读取的,直到派生出它本身的主密钥为止。举个例子,标识符 m/x/y/z 就是 m/x/y 的第 z 个子密钥、m/x 的第 y 个子密钥、m 的第 x 个子密钥。HD 钱包路径示例 HD path Key described m/0 主私钥 m 的第一个(0)儿子私钥 m/0/0 第一个子辈(m/0)的第一个孙子私钥 m/0'/0 第一个硬化子辈 (m/0') 的第一个标准孙子 m/1/0 第二个子辈(m/1)的第一个孙子私钥 M/23/17/0/0 第 24 个子辈的第 18 个孙子辈的第一个曾孙辈的第一个玄孙的公钥 HD 钱包的树形结构指南HD 钱包的树形结构提供了巨大的灵活性。每一个父拓展密钥都可以拥有 40 亿个子辈:20 亿个普通子辈和 20 亿个硬化子辈。每一个子辈都有另外 40 亿个子辈,以此类推。只要你想,这个树形结构就可以一代一代的无限延伸下去。但是这种灵活性又使得对这个无限的树形结构操作变的复杂。尤其是在各种实现之间转移 HD 钱包变的尤为困难,因为这个内部的结构从分支到子分支的可能性是无限的。现在的两种 BIP 都是通过对 HD 钱包的树形结构创建一些标准来解决这些复杂性的。BIP-43 提议将第一个硬化子指数作为可以表示树形结构「用途」的特殊标识符。而 BIP-43 则认为,HD 钱包应该只使用一个树形结构 level-1 的分支,并通过定义它的用途来让指数来标识结构以及剩余数的命名空间。例如,一个 HD 钱包只使用分支 m/i'/,并打算使用它来指明一个特殊的用途,而这个用途就是用指数 "i" 来标识的。再说明一下这个细则,BIP-44 提议的多货币多账户的结构就是 BIP-43 的「用途」数字 44'。所有的 HD 钱包都遵循 BIP-44 结构,这个结构就是实际中使用树形结构一个分支 m/44'/ 所标识的结构。BIP-44 还指明了五个预定义的树层级:m / purpose' / coin_type' / account' / change / address_index复制代码第一个层级 "purpose" 一直等于 44'。第二个层级 "coin_type" 指明了数字货币的类型,对于多货币的 HD 钱包来每一个种货币都在第二层级下有他自己的子树。这里有几个在标准文档中定义的货币,叫作 SLIP0044:github.com/satoshilabs…举个例子:以太坊是 m/44'/60',以太经典是 m/44'/61',比特币是 m/44'/0',所有这些货币的测试网络都是 m/44'/1'。第三个层级是 "account",它允许用户把他们的钱包再分成几个逻辑子账户,用于会计或者组织的目的。举例来说,一个 HD 钱包可以包含两个以太坊「账户」:m/44'/60'/0' 和 m/44'/60'/1'。而每个帐户都是它自己子树的根。因为 BIP-44 一开始是为比特币创造的,所以它包含的 "quirk" 和以太坊一点关系都没有。路径的第四层级是 "change",一个 HD 钱包有两个子树,一个用来创建接收地址,一个用来创建改变地址。而以太坊中只有「接收」地址,并不需要改变地址。注意,由于上个层级使用了硬化派生,所以这个层级就是普通派生。这是为了让这个层级的树可以在非安全环境下导出可以使用的公钥。可用的地址由 HD 钱包派生出来作为第四层级的子辈,然后形成树第五层级的 "address_index"。举例来说就是,以太坊的第三个接收地址在主账户中的支付将会是 M/44'/60'/0'/0/2。BIP-44 HD 钱包的结构示例:BIP-44 HD 钱包结构示例 HD 路径 密钥描述 M/44'/60'/0'/0/2 主以太坊账户的第三个收到的公钥 M/44'/0'/3'/1/14 第四个比特币账户的第 15 个可变地址的公钥 m/44'/2'/0'/0/1 用于签名交易的莱特币主账户的第二个私钥 掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。
2023年03月24日
3 阅读
0 评论
0 点赞
2023-03-24
如何基于 ETH 快速发布自己的数字货币
原文链接:mp.weixin.qq.com
2023年03月24日
5 阅读
0 评论
0 点赞
2023-03-24
使用 Python 学习和破解古典密码
之前在研究一些数字货币的时候有一个概念深深的吸引了我,那就是零知识证明,它指的是证明者能够在不向验证者提供任何有用的信息的情况下,使验证者相信某个论断是正确的。通俗的讲就是我有一个 secret_key,但是我不会把这个 secret_key 提供给验证者,而让验证者相信我知道这个 secret_key。很神奇吧,但是我们今天并不是要说零知识证明,而是从密码学最基础的地方说起。对零知识证明感兴趣的同学可以去看看 zkSNARKs in a nutshell。古典密码学虽然在现在看起来非常简单,但是对于构建密码的原理和一些解决问题的方法上仍然值得我们学习。今天我们就使用 Python 来对两个著名的加密算法进行加解密和破解。本文源码在这里获取。凯撒密码(Caesar Cipher)介绍凯撒密码属于替换密码的一种,替换密码就是指用一个别的字母来替换当前的字母。比如我和对方约定一个替换表: l -> h,o -> a,v -> t,然后我发送love给对方,对方按照对照表就知道我发送的其实是hate。凯撒密码使用的是将正常的 26 个英文字母进行移位替换,通常设定 shift 值为 3,相当于 a -> d,b -> e,c -> f...加解密方法(encrypt,decrypt)下面给出加解密实现:import string lowercase = string.ascii_lowercase def substitution(text, key_table): text = text.lower() result = '' for l in text: i = lowercase.find(l) if i < 0: result += l else: result += key_table[i] return result def caesar_cypher_encrypt(text, shift): key_table = lowercase[shift:] + lowercase[:shift] return substitution(text, key_table) def caesar_cypher_decrypt(text, shift): return caesar_cypher_encrypt(text, -shift)复制代码为了看起来比较容易,所以在方法中把密文的空格和标点符号都保留了下来。今天的两个例子都会使用下面这段经典密文(德国在一战期间邀请墨西哥进攻美国的密文,源自齐默尔曼电报事件)进行演示:We intend to begin on the first of February unrestricted submarine warfare. We shall endeavor in spite of this to keep the United States of America neutral. In the event of this not succeeding, we make Mexico a proposal of alliance on the following basis: make war together, make peace together, generous financial support and an understanding on our part that Mexico is to reconquer the lost territory in Texas, New Mexico, and Arizona. The settlement in detail is left to you. You will inform the President of the above most secretly as soon as the outbreak of war with the United States of America is certain and add the suggestion that he should, on his own initiative, invite Japan to immediate adherence and at the same time mediate between Japan and ourselves. Please call the President's attention to the fact that the ruthless employment of our submarines now offers the prospect of compelling England in a few months to make peace.使用caesar_cypher_encrypt(text, shift)我们会得到:zh lqwhqg wr ehjlq rq wkh iluvw ri iheuxdub xquhvwulfwhg vxepdulqh zduiduh. zh vkdoo hqghdyru lq vslwh ri wklv wr nhhs wkh xqlwhg vwdwhv ri dphulfd qhxwudo. lq wkh hyhqw ri wklv qrw vxffhhglqj, zh pdnh phalfr d sursrvdo ri dooldqfh rq wkh iroorzlqj edvlv: pdnh zdu wrjhwkhu, pdnh shdfh wrjhwkhu, jhqhurxv ilqdqfldo vxssruw dqg dq xqghuvwdqglqj rq rxu sduw wkdw phalfr lv wr uhfrqtxhu wkh orvw whuulwrub lq whadv, qhz phalfr, dqg dulcrqd. wkh vhwwohphqw lq ghwdlo lv ohiw wr brx. brx zloo lqirup wkh suhvlghqw ri wkh deryh prvw vhfuhwob dv vrrq dv wkh rxweuhdn ri zdu zlwk wkh xqlwhg vwdwhv ri dphulfd lv fhuwdlq dqg dgg wkh vxjjhvwlrq wkdw kh vkrxog, rq klv rzq lqlwldwlyh, lqylwh mdsdq wr lpphgldwh dgkhuhqfh dqg dw wkh vdph wlph phgldwh ehwzhhq mdsdq dqg rxuvhoyhv. sohdvh fdoo wkh suhvlghqwv dwwhqwlrq wr wkh idfw wkdw wkh uxwkohvv hpsorbphqw ri rxu vxepdulqhv qrz riihuv wkh survshfw ri frpshoolqj hqjodqg lq d ihz prqwkv wr pdnh shdfh.注:英国情报局截获的密文并不是这样使用凯撒密码加密的破解如果当时你截获到这样一份电报你会怎么想?在短暂的一面懵逼之后,显然要想办法破解出正常的意思才行。破解的思路其实也非常简单:因为加密时可以人为设定 shift 值,那么我们就从 0-25 循环来一遍看看哪个是有意义的就行了:def crack_caesar_cypher(text): for i in range(26): key_table = lowercase[-i:] + lowercase[:-i] print(substitution(text, key_table)[:12], '| shift is ', i, )复制代码看看结果:哪一行是有意义的呢?维吉尼亚密码(Vigener cipher)介绍凯撒密码显然无法阻挡人类的智慧,其实正常的替换密码的空间大小为 26!,这个数字非常大,相当于 2 的 88 次方,就是随机替换字母表生成加密表,然后按照加密表进行加密和解密,但是在字频分析下也败下阵来。然后就出现了维吉尼亚密码。维吉尼亚密码的加密方式也非常简单,先设定一个key = 'crypto',然后将key循环排列与原信息按照字母一一对应,然后将字母在字母表中的所在位置进行相加得到一个index,然后将 index 模 26,得到加密后的字母在字母表中的位置。例如:we intend tocr yptocr yp相当于:22 4 8 13 19 4 13 3 19 142 17 24 15 19 14 2 17 24 15上下相加我们就得到:24 21 32 28 38 18 15 20 43 29 再模 26 得到:24 21 6 2 12 18 15 20 17 3然后对应字母表我们得到:yv gcmspu rd加解密方法(encrypt,decrypt)下面给出加解密实现:def insert_letter(text, i, l): return text[:i] + l + text[i:] def get_blank_record(text): text = text.lower() blank_record = [] for i in range(len(text)): l = text[i] item = [] if lowercase.find(l) < 0: item.append(i) item.append(l) blank_record.append(item) return blank_record def restore_blank_record(text, blank_record): for i in blank_record: text = insert_letter(text, i[0], i[1]) return text def get_vigener_key_table(text, key): text = text.lower() trim_text = '' for l in text: if lowercase.find(l) >= 0: trim_text += l total_length = len(trim_text) key_length = len(key) quotient = total_length // key_length reminder = total_length % key_length key_table = quotient * key + key[:reminder] return trim_text, key_table def vigener_cypher_encrypt(text, key, is_encrypt=True): blank_record = get_blank_record(text) trim_text, key_table = get_vigener_key_table(text, key) result = '' for i in range(len(trim_text)): l = trim_text[i] index_lowercase = lowercase.find(l) index_key_table = lowercase.find(key_table[i]) if not is_encrypt: index_key_table = -index_key_table result += lowercase[(index_lowercase + index_key_table) % 26] return restore_blank_record(result, blank_record) def vigener_cypher_decrypt(text, key): return vigener_cypher_encrypt(text, key, False)复制代码使用vigener_cypher_encrypt(text, key)我们会得到:yv gcmspu rd usizl dg hjv dxkgv fd uxptlygr ipichmfktrtw gwskpkwpv upktcic. lx gjrja xbfvykhf ke qebhg fd iawu km zxsr kft nbkkcs lhckch ht cdcgbqc ecjmfcc. gc mvg vttgh qw rwbg pfr hnqevcsbbi, nc btyg dcmbqq r nghdqjya ht ccjxtbev mc mvg wmaecyzlv uouzq: btyg nyg mcivrwxf, orit isctc ihugkftk, ugecghiu wgctbezya lirgmgm opu yc nbfvphmopugcz cp fsg iotk rwth ovvxvc kj rd kseflfnst kft ecuk rtkfkkmgr wp kcmtg, pvu bxlktm, pgr cigohbc. kft lsvkjtfspk gc wsvrga bg nvdi mc afs. nhi yzja bbhfpb mvg gptlwfvli ht vyc pucxv kdlh uvagxhnp yh lcqe yh mvg fsiufgri dy kci uxmv vyc jgwvvb hmovvq dy oovpxvo kj atkhczl pgr cub ias ulevxgvzmc mvck ft lvqljs, hb jzq dpb kegibovztt, bbxzrt corrl ih wodcsbovv ysastvlrx opu yi mvg jybx hkdc bxrkrrt usvnctg xcgyc tbf fsglsnmch. izgrqt vonc rwx dtvqxwspkq pmhgerxhb vf rwx tctr iaov kft kivyjtlg gdnahmovli ht qlp hnporpxgsu eml hthvph mvg gpdldgtr dy qqdntezkee tgunrls bb c wcl fcpkfh mc orit isctc.为了看起来比较容易,所以在方法中把密文的空格和标点符号都保留了下来。上面的密文看起来似乎与凯撒密码差不多,但是这种加密方法在当时很难被破解。破解这种加密特点在于同样的字母加密之后并不会指向同样的密文,比如前3个单词we intent to中的 t,在凯撒密码或者常规的替换密码的下都会对应一个特定的字母,但是在这里我们可以看到intent中的t加密为m,to中的t加密为r。这样的话,字频分析也不起作用了。但是道高一尺魔高一丈,这个号称不能被破解的密码还是迎来了被破解的命运:假设我知道这个 key 的长度为 6。那么我们把密文以 6 个一组进行切割,那么一组中每个字母对应的原字母出现的的频率就是符合字频分析的,所谓的字频分析就是:26 个英文字母在句子中出现的频率。然后我们开始对每组的字频进行统计:group 0 : [, , , , , , ]group 1 : [, , , , , , ]group 2 : [, , , , , , ]group 3 : [, , , , , , ]group 4 : [, , , , , , ]group 5 : [, , , , , , ]根据字母频率表我们发现,字母e出现的频率超过了 12%,所以我们假设每组中至少有一个是字母e对应的密文,然后遍历出现次数超过10次的字母,并对另外两个出现频率最高的的字符数组['t', 'a']进行检测记分,然后得出最可能的的key。下面是代码:def get_trim_text(text): text = text.lower() trim_text = '' for l in text: if lowercase.find(l) >= 0: trim_text += l return trim_text def crack_vigener_cypher(text, key_length): blank_record = get_blank_record(text) trim_text = get_trim_text(text) group = ['' for i in range(key_length)] for i in range(len(trim_text)): l = trim_text[i] for j in range(key_length): if i % key_length == j: group[j] += l key = '' letter_stats_group = [] for j in range(key_length): letter_stats = [] for l in lowercase: lt = count = group[j].count(l) lt[l] = count letter_stats.append(lt) letter_stats = sorted(letter_stats, key=lambda x: list(x.values())[0], reverse=True) letter_stats_group.append(letter_stats) # print('group', j, ':', letter_stats[:8]) # gvctxs score_list = [] for i in range(3): current_letter = list(letter_stats[i].keys())[0] index = lowercase.find(current_letter) key_letter = lowercase[index - lowercase.find('e')] item = [] item.append(key_letter) score = 0 for k in range(3): vl = list(letter_stats[k].keys())[0] for fl in ['t', 'a']: #if i == 1 and (k == 1 or k == 2) and j == 1: if (lowercase.find(key_letter) + lowercase.find(fl)) % 26 == lowercase.find(vl): score += 1 item.append(score) score_list.append(item) score_list = sorted(score_list, key=lambda x: x[1], reverse=True) key += score_list[0][0] plain_text = vigener_cypher_decrypt(trim_text, key) return restore_blank_record(plain_text, blank_record)复制代码然后我们通过运行crack_vigener_cypher(cypher_text, 6)就可以得到明文了。然而这个地方大家可以看到,我默认传了一个参数 6 进去,也就是 key 的长度。但是当我们截获到密文的时候连 key 都不知道,显然也不会知道 key 的长度了。所以如果我们可以确定 key 的长度,那么维吉尼亚密码在我们面前就是纸老虎了。实际上,像凯撒密码一样,从 1 到 25 去试也是可以破解的,但是我们这里使用一个叫做重合指数的方法来帮助缩小范围(虽然实际效果并不好,但是还是要理解一下方法)。重合指数法:由26个字母构成的一段有意义文字中,任取两个元素刚好相同的概率约为0.067,所以如果一段明文是用同一个字母加密的话,这个概率依然不会改变。因此我们可以写个方法来计算重合指数: def get_coincidence_index(text): trim_text = get_trim_text(text) length = len(trim_text) letter_stats = [] for l in lowercase: lt = count = trim_text.count(l) lt[l] = count letter_stats.append(lt) index = 0 for d in letter_stats: v = list(d.values())[0] index += (v/length) ** 2 return index复制代码然后我们假设不同的 key 的长度,对每组密文进行重合指数的计算,然后选出和0.067相比方差较小的一部分长度作为备选:def get_var(data, mean=0.067): if not data: return 0 var_sum = 0 for d in data: var_sum += (d - mean) ** 2 return var_sum / len(data) def get_key_length(text): trim_text = get_trim_text(text) # assume text length less than 26 group = [] for n in range(1, 26): group_str = ['' for i in range(n)] for i in range(len(trim_text)): l = trim_text[i] for j in range(n): if i % n == j: group_str[j] += l group.append(group_str) var_list = [] length = 1 for text in group: data = [] for t in text: index = get_coincidence_index(t) data.append(index) var_list.append([length, get_var(data)]) length += 1 var_list = sorted(var_list, key=lambda x: x[1]) return [v[0] for v in var_list[:12]]复制代码[[16, 2.9408699990533694e-05], [9, 3.8755178005797864e-05], [10, 5.415541187702294e-05], [17, 5.5154370298645345e-05], [19, 6.055960902865477e-05], [13, 8.572621594737114e-05], [8, 8.734954157595401e-05], [14, 9.767402405996375e-05], [3, 0.00010208649957333127], [20, 0.00012009258116435503], [11, 0.0001230940714957638], [6, 0.00014687184215509398]]正确长度在第12个,我也很绝望啊...现在万事具备了,直接遍历备选的 key_length,然后看看解密之后的效果吧。12 行,应该一眼就可以看到答案了吧。本文到此结束,欢迎批评指正。
2023年03月24日
5 阅读
0 评论
0 点赞
2023-03-24
全面系统的 Web3 学习路线,助你成为 Web3 开发专家
今天学习 Web3 和区块链开发就像昨天以 10 美元购买比特币一样。区块链行业的薪水是非常可观的,全球范围内从事 Web3 的程序员平均年薪约为 14 万美元,当然国内可能会比这个平均年薪低一些,但仍然高于 Web2.0 的程序员。这可能是作为一个开发人员现在可以做出的最佳投资选择。但是互联网上缺乏关于 Web3 的高质量资源,你很快就会发现,你虽然想学习 Web3 的开发,但是却不知道从哪儿开始。我从 12 年跟着同学玩 BTC,后来把 6 个多 BTC 换了一个 LOL 两百多个皮肤的账号。即使现在 BTC 暴跌,6 个多 BTC 也能值 80 万左右人民币,但是我的那个 LOL 账号估计连卖几百块都难。中间好几年没有怎么继续接触数字货币。直到 17 年左右才开始重新接触数字货币,刚开始和朋友合伙挖矿,那时候天天跑机房,闲鱼买显卡,隐约记得那阵 RX 460 470 480 显卡性价比极高。后来开始炒币,天天盯盘,各种币都买,也碰到过百倍币。赚过一些钱,也赔过很多钱。19 年我和朋友合作开发了一个区块链项目,用在本地一家大型的工业园区的建筑工地中,用来对建材进行追踪治理,很大程度上节约了成本,当然也得罪了一些人,因为区块链的可追溯性让一些原本能够在建材上面偷工减料的人没了钱赚,不过这种方式是园区的总经理大力支持的,实施下来虽然有阻力,但控制成本、追踪治理的效果也很显著。在这个过程中,我也一直关注 Web3 的发展,从只知道概念,到逐渐学会了 solidity 语言、DApp 的开发等。但是从来没有认真细致地系统性归纳自己在 Web3 方面的知识体系。所以趁最近时间充足,多花些时间根据我个人对 Web3 的实际经验,整理一套关于 web3 和 Solidity 的学习路线。这个学习路线足以让你从一个对 web3 完全零基础的 web2.0 开发人员过渡到 Solidity 语言专家和区块链专家。区块链基础知识区块链是 web3 的基础。你首先要了解它是如何工作的,以及它为什么会彻底改变我们交换商品和支付的方式。区块链技术不仅仅是和加密货币有关,而是已经成为真正的分布式云计算系统,能够运行完整的后端(为了和 web2.0 时代的后端进行区分,我有时也习惯称它为链端)来为前端的去中心化应用程序 (DApp) 提供动力。在学习完区块链基础知识后,你应该能够准确回答出以下问题:Web1.0、Web2.0 和 Web3 的区别? 什么是区块链? 什么是分布式账本? 什么是加密货币? 什么是加密钱包? 什么是区块链浏览器? 去中心化应用基础知识当你了解了什么是区块链、Node、共识机制和这些技术的主要组件后,你应该会思考:“我可以使用区块链开发什么样的应用程序?”建立在区块链之上的应用被称为去中心化应用或者被称为 DApp,它在大的结构上和传统 Web2.0 应用很像,包含两个部分:使用 JavaScript 或 React、Vue、Svelte 等框架/库构建的标准前端。 使用 Solidity/Solana/Rust 等语言构建的后端,它们建立在区块链之上。 你除了要了解什么是去中心化应用,还要了解 DApp 的前端和后端是如何通信和交换数据的,你需要学习前端开发和后端开发,并且需要掌握 API 的基本原理。前端开发相关知识前面我有提到,去中心化应用需要有一个标准的前端项目,这就是为什么在开发你的第一个 DApp 之前,需要去学习前端开发的理由。前端框架非常多,也非常复杂。我建议你只选择其中一门就可以了,比如当前使用人数最多的 React。后端开发相关知识DApp 的后端和传统 Web2.0 的后端有很多不同之处,其中最明显的是 DApp 的后端需要使用区块链作为去中心化数据存储的主要方式,而传统后端通常使用数据库或对象存储来存储数据。但是大多数技术原则仍然保持不变。这里我建议你去选择一些比较流行的技术,比如学习 Node 和 Express。或者学习基于 React 和 Express 的全栈框架 Next.js。以太坊概念和原理以太坊是在计算机网络中运行的一种软件,同时也是一种数字货币。大多数 DApp 现在都运行在以太坊区块链之上,智能合约概念也是由以太坊联盟首先推出的,然后被其他区块链抄袭。每个区块链都有自己的生态系统,我们要从其中选择一条。它们各自有各自的特点和优势,但是我推荐以太坊,原因是互联网上面关于以太坊的资料非常丰富。要想在 2022 年成为 web3 和 Solidity 开发人员,了解以太坊的概念和原理是关键。当你学完以太坊的概念和原理有,你应该能够准确回答以下问题:什么是账户? 什么是交易? 什么是块? 什么是以太坊虚拟机? 什么是 Gas? 什么是节点? 什么是以太坊网络? 什么是共识算法? 什么是以太坊三难困境? 什么是信标链? 什么是侧链? 什么是合并? 智能合约的概念以太坊和智能合约的关系就像微信和小程序,两者都需要了解。智能合约是存储在基于区块链的平台上的软件,可以自动执行协议。可以编写智能合约的语言有 Solidity、Rust 和 Vyper,其中最流行的是 Solidity。它是所有 DApp 的关键组件,运行 DApp 的业务逻辑并允许你在区块链上存储信息。Solidity&Remix了解了智能合约,接下来你要学习怎么样编写自己的智能合约,并使用它来支持你自己的 DApp。虽然有多种语言可以编写智能合约,但我仍然推荐你学习 Solidity。Solidity 是一种用于编写智能合约的高级、面向合约的编程语言,它允许程序员编写为区块链 DApp 提供动力的自执行代码。Remix 是一款专门支持 Solidity 编写智能合约的编辑器。它运行在浏览器中,默认情况下,编译部署测试都不需要任何配置。HardHatRemix 虽然很强大,但根据我的经验来看,在本地搭建智能合约开发环境会有更好的体验。而 HardHat 就可以帮助我们实现这个目的,让我们在 VSCode 中编写 Solidity 智能合约项目。HardHat 可以在多条链上创建、测试和部署 DApp,比如 Polygon、Ropsten、Ethereum Mainnet 等。你还可以用它启动本地以太坊节点来测试你的智能合约,不需要将它们部署到公共区块链上。Web3.js/Ethers.js当你能够使用 Solidity 编写智能合约后,你还需要学习如何将你的前端连接到使用 Solidity 开发的后端。虽然和传统的 Web2.0 有些差异,但通讯方式仍然是类似 HTTP 或者 WebSocket 的东西。在这个点上,有两个库可以选择:Web3.js 和 Ethers.js。Web3.js 功能更加全面,Ethers.js 更加轻量。在用户数量上相差不多,但是在 npm 上面 Web3.js 的下载量会更高一些,你可以优先学习 Web3.js。Alchemy在 Web2.0 中有很多云厂商可以为我们提供部署的基础设施服务,国外的有 AWS,国内有阿里云等。我们可以把 Alchemy 想象成 Web3 中的 AWS,它为部署 DApp 提供了所有需要的基础设施。Alchemy 还具有更多功能,比如为我们提供了 API 来部署 NFT 集合,而且不需要编写一条行 Solidity 代码;连接到链上事件的通知;以及带有智能套接字和扩展以太坊 API的增强型 Web3 库。DApp 的类型在开发我们的 DApp 之前,我们要先学习一些其他 DApp,了解我们可以做哪些 DApp。常见的类型有加密货币、加密钱包、区块浏览器、NFT 市场、DeFi 应用和基于区块链的游戏。每一种类型的 DApp 你都应该去了解。开发第一款 DApp当你把上面的东西全部学会后,就应该来做一个 DApp 来验证你的学习成果了。如果你不知道该开发什么样的 DApp,那我给你的建议就是做一个加密货币或者 NFT 市场。如果你实在不知道自己该做什么 DApp,我可以告诉你一个技巧,你可以去一些招聘网站,看看那些高薪招聘 Web3 开发人员的公司都在做些什么,然后你照着做就可以了。truffle&ganache&drizzleWeb2.0 的世界里有各种各样的框架,Web3 同样不例外。truffle 是一款区块链框架,它提供了开发区块链应用中会用到的大多数功能。适用于任何以太坊虚拟机(EVM)区块链的开发环境、测试框架和资产管道。除了 truffle 自身以外,它还提供了 ganache 和 drizzle。ganache 用于开发个人区块链,可以部署合约、开发应用和测试。drizzle 是一组前端库,在编写 DApp 的前端时更加容易和更加可观测。它是基于 Redux 的。测试智能合约和传统的 Web2.0 应用不同,区块链的特别之处在于不可逆转性,一旦添加了智能合约,就无法编辑和召回了,而且在部署时也需要花费 Gas 费。所以测试对 Web3 的 DApp 而言尤其重要。测试智能合约的方式有:节点测试 功能测试 性能测试 API 测试 MoralisMoralis 为区块链项目提供托管后端。自动将你的用户余额同步到数据库中,你还可以设置链上警报、观看智能合约事件、构建索引等等。所有功能都通过易于使用的 SDK 实现的。而且 Moralis 提供的所有功能默认都是跨链的。简单来说,Moralis 可以让你在几秒钟内创建一个成熟的 DApp,利用基于钱包的身份验证系统的强大功能可以直接从区块链获取数据,并把它们保存在 NoSQL 数据库中,这些功能都只需要几行代码就可以轻易实现。总结我的思路是概念优先。在真正开发之前,我从来没有让你写代码。我认为如果你连自己要做什么都不知道的话,是没办法直接写代码的。先从基本概念入手,一定不会错。至今为止,Web3 的变化依然很大,这篇文章也会有时效性,如果有了新的变化我也会同步更新。学习 Web3 什么时候都不晚,希望你可以早日加入 Web3 世界!
2023年03月24日
5 阅读
0 评论
0 点赞
2023-03-24
密码学系列之:1Password的加密基础PBKDF2
小知识,大挑战!本文正在参与“程序员必备小知识”创作活动简介1password是一个非常优秀的密码管理软件,有了它你可以轻松对你的密码进行管理,从而不用再考虑密码泄露的问题,据1password官方介绍,它的底层使用的是PBKDF2算法对密码进行加密。那么PBKDF2是何方神圣呢?它有什么优点可以让1password得以青睐呢?一起来看看吧。PBKDF2和PBKDF1PBKDF的全称是Password-Based Key Derivation Function,简单的说,PBKDF就是一个密码衍生的工具。既然有PBKDF2那么就肯定有PBKDF1,那么他们两个的区别是什么呢?PBKDF2是PKCS系列的标准之一,具体来说他是PKCS#5的2.0版本,同样被作为RFC 2898发布。它是PBKDF1的替代品,为什么会替代PBKDF1呢?那是因为PBKDF1只能生成160bits长度的key,在计算机性能快速发展的今天,已经不能够满足我们的加密需要了。所以被PBKDF2替换了。在2017年发布的RFC 8018(PKCS #5 v2.1)中,是建议是用PBKDF2作为密码hashing的标准。PBKDF2和PBKDF1主要是用来防止密码暴力破解的,所以在设计中加入了对算力的自动调整,从而抵御暴力破解的可能性。PBKDF2的工作流程PBKDF2实际上就是将伪散列函数PRF(pseudorandom function)应用到输入的密码、salt中,生成一个散列值,然后将这个散列值作为一个加密key,应用到后续的加密过程中,以此类推,将这个过程重复很多次,从而增加了密码破解的难度,这个过程也被称为是密码加强。我们看一个标准的PBKDF2工作的流程图:从图中可以看到,初始的密码跟salt经过PRF的操作生成了一个key,然后这个key作为下一次加密的输入和密码再次经过PRF操作,生成了后续的key,这样重复很多次,生成的key再做异或操作,生成了最终的T,然后把这些最终生成的T合并,生成最终的密码。根据2000年的建议,一般来说这个遍历次数要达到1000次以上,才算是安全的。当然这个次数也会随着CPU计算能力的加强发生变化。这个次数可以根据安全性的要求自行调整。有了遍历之后,为什么还需要加上salt呢?加上salt是为了防止对密码进行彩虹表攻击。也就是说攻击者不能预选计算好特定密码的hash值,因为不能提前预测,所以安全性得以提高。标准salt的长度推荐是64bits,美国国家标准与技术研究所推荐的salt长度是128 bits。详解PBKDF2的key生成流程上面一小节,我们以一种通俗易懂的方式告诉大家,PBKDF2到底是怎么工作的。一般来说,了解到这一层也就够了,但是如果你想更加深入,了解PBKDF2的key生成的底层原理,那么还请关注这一小节。我们上面介绍了PBKDF2是一个生成衍生key的函数,作为一个函数,那么就有输入和输出,我们先看下PBKDF2的定义:DK = PBKDF2(PRF, Password, Salt, c, dkLen) 复制代码PBKDF2有5个函数,我们看下各个参数代表什么意思:PRF 是一个伪随机散列函数,我们可以根据需要对其进行替换,比如替换成为HMAC函数。 Password 是主密码用来生成衍生key。 Salt是一个bits序列,用来对密码加盐。 c 是循环的次数。 dkLen 是生成的key要求的bits长度。 DK是最后生成的衍生key。 在上一节中,我们可以看到其实最后的衍生key是由好几部分组成的,上图中的每一个T都代表着衍生key的一部分,最后将这些T合并起来就得到了最终的衍生key,其公式如下:DK = T1 + T2 + ⋯ + Tdklen/hlen Ti = F(Password, Salt, c, i) 复制代码上面的F是c次遍历的异或链。其公式如下:F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc 复制代码其中:U1 = PRF(Password, Salt + INT_32_BE(i)) U2 = PRF(Password, U1) ⋮ Uc = PRF(Password, Uc−1) 复制代码HMAC密码碰撞如果PBKDF2的PRF使用的是HMAC的话,那么将会发送一些很有意思的问题。对于HMAC来说,如果密码的长度大于HMAC可以接受的范围,那么该密码会首先被做一次hash运算,然后hash过后的字符串会被作为HMAC的输入。我们举个例子,如果用户输入的密码是:Password: plnlrtfpijpuhqylxbgqiiyipieyxvfsavzgxbbcfusqkozwpngsyejqlmjsytrmd复制代码经过一次HMAC-SHA1运算之后,得到:SHA1 (hex): 65426b585154667542717027635463617226672a复制代码将其转换成为字符串得到:SHA1 (ASCII): eBkXQTfuBqp'cTcar&g*复制代码所以说,如果使用PBKDF2-HMAC-SHA1的加密方式的话,下面两个密码生成衍生key是一样的。 "plnlrtfpijpuhqylxbgqiiyipieyxvfsavzgxbbcfusqkozwpngsyejqlmjsytrmd" "eBkXQTfuBqp'cTcar&g*" 复制代码PBKDF2的缺点虽然PBKDF2可以通过调节循环遍历的次数来提高密码破解的难度。但是可以为其研制特殊的处理器,只需要很少的RAM就可以对其进行破解。为此bcrypt 和 scrypt 等依赖于大量RAM的加密算法,这样就导致那些廉价的ASIC处理器无用武之地。总结以上就是PBKDF2的简单介绍,想要详细了解更多的朋友,可以参考我的其他关于密码学的文章。本文已收录于 www.flydean.com/41-pbkdf2/最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!
2023年03月24日
3 阅读
0 评论
0 点赞
2023-03-24
程序猿生存指南-9 离职黑屋
(19) 离职黑屋郝公子年前有关丰厚年终奖的小道消息最终被证实是谣传。我们部门非但没有得到可观的奖金,作为不能给集团带来直接利益,每年还需大量资金投入的IT部门,外加集团分管技术领导贪腐等原因,部门年终奖被取消了。我真是欲哭无泪,赔了夫人又折兵。郝公子找到我,为年前放的那个烟雾弹向我表达了深深的歉意。为了安抚我那颗受伤的心,他主动为我打探来了离职的详细流程。我把离职申请交给了组长老周,老周再三挽留,见我去意已决,也不再规劝,在离职申请书上签了字。我带着离职申请书又敲了部门经理办公室的门。经理很是痛快,大笔一挥,就签下了名字,整个过程头都没抬。像我这样的虾兵蟹将,经理平时都没正眼瞧过。我估摸从加入公司到离开公司,他都不晓得我姓甚名谁。谁承想这个国企进来的时候不容易,想要离开更是困难重重。离职申请虽然获得了领导的批准,但我还需要经历一个月的脱密期才能真正地走完离职流程。由于我曾经参与了国家大型项目的研发,掌握着国家的机密,我必须在把所有秘密从脑袋里清除掉后,才被允许离职。事实上,哪里有什么国家机密,我们平常做得最多的就是从网上,从书里摘抄别人的技术方案,然后改改名字,调整下措词,包上一层皮,就变成了不可外泄的核心技术。那些所谓的核心机密在网上随处可见,当然欺骗一些不懂技术的领导还是绰绰有余。技术在这里从来都不是最重要的。不过既然组织上有脱密的规定,谁也不能破例,我坚决服从组织上的安排。离职申请被批准后的第二天,我所有的办公用品立马被公司收回。公司有专门为离职人员提供的脱密办公区,我们称之为小黑屋。集团所有离职人员必须在小黑屋呆上一定日期后才被允许离开。作为入职不满一年的新员工,我的脱密期只有一个月,倒也不算太过漫长。倘若你为公司服务了超过十年,那么你的离职脱密期至少是半年,层级更高的领导甚至是一年。脱密期间,我每天必须来公司报道,按时打卡,跟正常上下班无异。公司会照常发放基本工资,因为没有绩效,所以工资比往常低不少。这种不用干活还给钱、无功受禄的好事听起来似乎还不错。实际上,对于我们这群想赶紧抽身的人却是一种煎熬。其实整日无所事事地坐在一个密室里,倒还不如被雪花般的任务包围,这样日子还能过得快一些。被关小黑屋后,我一边按时上下班,一边在网上投递简历。一二三四五,脱密真辛苦,一台破手机,一坐一上午。许多互联网公司的面试可以在电话里进行,我在小黑屋里经历了几场电话面试。不过,由于小黑屋信号差,外加自身紧张,面试过程沟通不甚流畅。在与几家心仪公司失之交臂后,我决定还是等脱密期结束后再正式找工作。我把简历发给老潘,想让他帮我内推一下他们公司的技术团队。老潘却直摇头,他说并不是对我的技术信不过,而是不建议我去他们公司。在他眼里,他们公司的程序员就是一群混子,拿钱不干事,有事就推脱。难题解决不了,简单事又不愿意干。为了打消我迎难而上,死乞白赖去他们公司的想法,老潘给我讲了不少他所在产品组跟开发组斗智斗勇的事儿。那些互相使绊子,送黑锅的事迹,惊得我是一身冷汗。有人的地方就有江湖,江湖上,人人都想争夺话语权。产品跟技术水火不容的那些事儿,时常被业界讨论,还生出了许多网络段子在技术圈里流传。我先前听过不少,只是没承想在老潘公司,两伙势力对抗之如此激烈。老潘他们公司在业界以产品精良而著称,技术实力并不算很强。程序员在他们公司地位肯定不如产品经理不高。宁做鸡头不做凤尾。我更愿意找一家程序员地位比较高的公司。并不指望对别人颐指气使,但也不至于忍气吞声,被人凌辱。小黑屋很是逼仄,但囿不住我对未来的无限畅想。(20) 求职之路脱密的一个月里,我度日如年。周遭几个同病相怜的人靠玩手游消磨时光,而我没有丝毫懈怠,整日裸泳于知识的海洋。我越学越觉得自己菜,越觉得自己菜就越想学。幸好在学习上形成了一个良性循环。自我感觉进步神速,特别渴望去市场上检验一下自己的卖价。立夏过后没几天,我的离职流程终于顺利走完。我把工牌上交,悄摸地就走了,没有给老东家留下任何挽留我的机会,从此相忘于江湖。虽有了自由之身,我却不敢有片刻清闲,迅速投入到了兵荒马乱地找工作中去。开启一段新的求职历程,我原本以为自己已经准备充足。可是真到了需要面对洗礼的时候,我又不争气了起来,紧张又焦躁。可开弓没有回头箭,我只得硬着头皮就是干。老潘建议我先找一些不知名的企业练练手,见识一下当前互联网技术领域的面试流程与面试难度。等我各个方面都准备得都差不多了,再去投递心仪的公司,这样被录取的几率会更大一些。我接受了老潘的建议,在几大招聘网站上投递了近百封简历,每日焦急地等待着面试邀请。知名国企这个背景在求职过程中并没有给我有所加分。反倒是由于近一年都是在国企里做方案设计,没有从事一线编程,很多公司由此怀疑我的技术能力。投递出去的简历很多都石沉大海,杳无音信。幸好在2014年,中国互联网行业还处于红利期,当时的求职环境对于程序员特别有利。新兴的互联网公司不断涌现,并且急速扩张。老牌知名互联网公司积极拓展新业务。编程人员供不应求。我陆续接到一些小公司的面试邀请,开始忙碌起来。许多小公司出于对成本考虑,一般会选择市郊租金比较便宜的地段。我经常是上午还在昌平跟面试官谈笑风生,下午就得赶到大兴参加笔试。终日在北京城里奔波,几乎每条地铁线路都留下了我的足迹。辛苦倒也谈不上,只是一次又一次地被公司拒绝,让人有些沮丧。别看许多初创公司规模不大,但人家的要求可不低。更希望找一个在方方面面都能上手的人,用技术圈的术语来说就是全栈工程师。在编程上荒废了近一年,我需要恶补的知识实在是太多。专注钻研一个领域就已经耗费了我大部分精力。短时间内,我肯定无法胜任全栈,所以悲剧在所难免。一轮轮面试下来,给人最深的体会就是:公司在面试应聘者的时候,恨不得希望他能有研制出原子弹的本事。事实上,被招进去后,大多数人都成了流水线上的螺丝钉。互联网技术更新换代的速度极快,可以天计。在面试过程中,我已经听到了太多闻所未闻的新技术,新名词。一次次面试失败,一次次总结经验教训。被算法难到了,就恶补算法;被编程框架问住了,就恶补框架。我深知技术这个领域没有什么捷径可走,唯有天道酬勤。业界对于程序员的考察从来都很简单粗暴。不需要你有多么出众的口才,也不需要你有多么好看的皮囊。借用国外开源大神Linus的一句话就是:“Talk is cheap,show me the code。”点击进入下一章点击从第一章开始阅读ps:欢迎各位关注我,文章更新的消息会在「掘金动态」里滚动,同时七筒也欢迎大家在动态的评论区给我评论。此致敬礼,感谢各位厚爱。
2023年03月24日
4 阅读
0 评论
0 点赞
2023-03-24
区块链不谈技术的都是韭菜——区块链技术组成及架构
三个最底层的技术数据关系加密化数据不可篡改点对点网络让数据永不下线核心技术概念区块挖矿和共识机制Merkle Tree区块链适合什么不适合什么?区块链应用交易模型身份认证体系智能合约结语最近一直在研究区块链,算是从以前听说过,到现在大概了解一些。先说下自己学习过程中的感受,那就是“干!能不能把话说明白些。”大部分学习材料都存在结构混乱,或者对一个点单薄,无法深入浅出。至于那些还在拿着露天麦喊什么是区块链,错过后悔一辈子的,都是骗子。我相信现在很多投资机构都在瞄区块链,今年,即使AI也没有区块链这么火爆。那么对于一个区块链项目,到底靠不靠谱,是在画饼,还是真的可能搞成,所有人都应该擦亮眼睛。三个最底层的技术谈区块链最好先抛开各种币的价格,价格这种事你懂的,贵和便宜根本不是人能控制的。但是基于区块链技术去做项目,却是实实在在可以可持续发展。所以,了解区块链技术比炒币来的实在。“区块链”三个字并不能阐明这项技术的全部,如果要非要用可以完整表达的命名,我觉得应该叫“Peer-to-Peer Encrypted Non-Tampered Database”,即“点对点的加密化不可篡改数据库”。它不一个数据库(比如MySQL,MongoDB),也不是一类数据库(比如SQL,NoSQL),它是一种数据库架构,它在数据库本身的技术上还上升了一层,考虑到数据的可靠性如何保证,以及数据库服务如何不下线。因此,你不能把它跟普通的某个有名字数据库拿来类比,甚至,你可以在某一个具体的区块链实现时,使用其他的数据库来帮助存储和检索数据。数据关系加密化在我们普通的数据库中,无论是关系型还是非关系型,我们的不同记录之间可能存在关系,也可能不存在关系,但在区块链中,一条数据一定和另外一条数据存在联系,即使在现实的业务逻辑上没有联系,但是它总是存在于链上,无法脱离链而存在,总有一条路径从一个数据出发到达另外一个数据,不信往下读。“区块”表达了区块链里面数据关系的最终呈现形式,一条记录,无论它是什么信息,最终它(或它的检索信息)都要被放置在一个区块中。而区块与区块之间,是一个“链表”的数据关系,会编程的人都知道什么是链表,就是后一个数据中存在指向前一个数据的索引键。因此,区块链上的任何两个数据永远可以通过这些索引键最终连在一起,数据无法逃离这个逻辑。但是“区块链”这三个字无法阐述这样的数据结构和普通数据库结构之间的不同,因为上面描述的的这种链表数据结构,用普通的数据库也可以构建出来,只要你想要的话。真正的价值在于,区块链用密码学的原理,现有的加密技术,把这些索引关系进行了层层加密,以至于在保存的数据中,这些索引键并没有那么明显,而是需要通过各种计算才能得到。比如区块在保存一堆交易信息时,采用了merkle树的方式进行保存,父节点是两个子节点的double hash得到的结果,而merkle算法确保了交易信息不能被篡改。我们这里还不需要知道具体的加密都有什么用,我们需要了解的是,区块链里面到处是加密,这是一个显著的特点。数据不可篡改区块链上的数据是不可篡改的,大家都这样说。但其实,数据是可以改的,只是说改了以后就你自己认,而且被修改数据所在区块之后的所有区块都会失效。区块链网络有一个同步逻辑,整个区块链网络总是保持所有节点使用最长的链,那么你修改完之后,一联网同步,修改的东西又会被覆盖。这是不可篡改的一个方面。更有意思的是,区块链通过加密校验,保证了数据存取需要经过严格的验证,而这些验证几乎又是不可伪造的,所以也很难篡改。加密并不代表不可篡改,但不可篡改是通过加密以及经济学原理搭配实现的。这还有点玄学的味道,一个纯技术实现的东西,还要靠理论来维持。但事实就是这样。这就是传说中的挖矿。挖矿过程其实是矿工争取创建一个区块的过程,一旦挖到矿,也就代表这个矿工有资格创建新区块。怎么算挖到矿呢?通过一系列复杂的加密算法,从0开始到∞,找到一个满足难度的hash值,得到这个值,就是挖到矿。这个算法过程被称为“共识机制”,也就是通过什么形式来决定谁拥有记账权,共识机制有很多种,区块链采用哪种共识机制最佳,完全是由区块链的实际目的结合经济学道理来选择。挖完矿没完,拿比特币来说,接下来矿工要把被广播到网络中的交易打包到这个区块里,一笔交易是不是合法的呢?发起这笔交易的人是不是伪造了一笔交易?要确保一笔交易的合法性,必须从已经存在的前面的区块里面去找到这笔交易的来源的真实性,而如何验证交易真实性呢?在前面的区块里,保存着交易来源的merkle root hash,只要找出这个交易所在的区块,再做一次merkle校验,就可以判定交易是否是合法的。得到merkle root hash是通过区块内的所有交易不断加密得到的,因此,只要交易是假的,就得不到这个merkle root hash。加密在这里又帮助实现了数据的可靠性。除了这些,区块链里面的加密比比皆是,这些加密规则和算法,使得整个区块链遵循一种规律,让篡改数据的成本特别高,以至于参与的人对篡改数据都没有兴趣,甚至忌惮。这又是玄学的地方。点对点网络让数据永不下线如果区块链没有p2p网络,仅仅是按照前面的描述,有加密体系,有链式特征,然后运行在某一台(组)服务器上,按照我们现在中心化的模式运行,看上去也挺好玩的。但是发明者想玩的更大些,加密体系让数据不可篡改,但是我直接抛颗原子弹把你机房炸掉,不是不可篡改,是直接玩儿完了。为了防止被原子弹炸掉机房,发明者设计了点对点的网络(客户端和客户端直接通信,不经过某一台特定的服务器)到区块链里面。简单说就是在这个点对点网络里面,所有人的电脑里保管着一模一样的一个数据结构(其实就是一个完整的“区块”“链”),他们相互通过网络连接,进行同步,当矿工创建了新的区块,其他人就会把这个区块同步到自己保管的数据结构中。因此,无论这个网络上哪一个节点被炸,其他节点都还活着,新加入的小伙伴就可以从这些节点里同步数据到自己的电脑。想要让区块链数据消失,那把地球炸了吧。而这种加入点对点网络的设计,就叫“去中心化”,只要网络上还有一个节点活着,区块链的数据就不会消失。更让政客们害怕的是,这些保存的数据,节点上的用户可以随便看,无所谓,完全公开。节点用户既然把数据同步过来了,你就可以随便用,就是你的数据了,想怎么用就怎么用。试想一下,哪天淘宝说我要把自己的数据区块链化……目不忍视……核心技术概念前面仅仅阐述的是区块链之所以是区块链的基础。本节要讲的是,现在已经有区块链在你面前了,我们需要去剖析区块链里面所使用的具体技术点或架构。区块前面已经提到区块了。那么到底什么是区块呢?区块是区块链的主要数据存储结构,一个区块包含区块头和区块体两个部分。而区块头则是区块的重头戏。区块链中的一个区块结构示意图(注:漏掉了version信息)对于一个区块而言,它就是一个特殊的数据结构。它的区块头包含了一些固定信息:版本(客户端版本,每次升级客户端软件,这个信息就会不一样),块高度(其实就是表示这是链中的第几个区块),块哈希(这个区块的hash值,是挖矿得到的),上一个块的块哈希(这个字段是重点中的重点,是形成链表结构的关键),时间戳(区块创建时间),难度和Nonce(这两个字段和挖矿有关,后文讲挖矿的时候详细讲),merkle root(区块体的merkle根hash值,后文会简单介绍merkle树,详细会在其他文章讲)。除了这些字段,如果做一个自己的区块链,还可以添加一些其他信息到区块头中。区块体是保存具体内容的位置,在比特币的区块链中,区块体保存的是一段时间的交易信息。在其他区块链中,这里可不一定保存的是交易信息,可能是其他信息,总之区块体是保存该区块链用来做什么业务的具体业务信息。在部分区块链实现中,一个区块还可以有区块尾,用来保存一些区块创建结束之后的信息,这些信息可能是区块头和区块体已经创建完以后,附加上去的,比如区块的长度、容量等信息。这就是一个区块。而一个区块头中的previousHash字段,保存的是上一个区块的hash值,因此,通过这个区块就知道了上一个区块是哪个,上一个区块又能知道上上个区块,直到可以追溯回整个链条的第一个区块。这就是区块链。区块是如何构成链的的示意图就像上图一样,后面一个区块总是指向前一个区块。一旦一个区块生成,并且后面有区块指向它,那它就不能被修改,因为一旦修改,所有的hash都需要重新计算。但是我们知道,hash算法的特点是,想要得到这个hash必须用原始内容进行一遍hash算法,所以,如果给的内容和原始内容不同,是得不到这个hash的,所以,中间某个区块链被修改而得到的hash,不可能被后面的区块指向,区块链就会断掉。断掉的区块链加入到网络中,要么不被认可,别的节点不会把你当作合法节点,要么你要再同步一遍,从网络中重新复制最长的链到你的本机覆盖原来的链。但是你可能会有两个疑问:1.这个blockHash又不是内容的hash,怎么确保区块体内的信息不被修改呢?要是我不改blockHash,只改内容,那不是可以瞒天过海?2.如果有两个区块同时指向了一个区块,而这两个区块的区块体不一样,这该怎么办?第一个问题,我们需要通过后面的挖矿和merkle tree两部分结合,知道这个原理。第二个问题,实际上,这种情况非常常见,挖矿成功的概率其实是100%,关键在于哪一位矿工先挖到矿,一般当矿工挖到矿之后,会向全网广播,其他没有挖到矿的矿工就会停止。但是由于网络延时等情况,可能在短时间内多个矿工一起挖到矿,他们都创建了新的区块,并且广播到了网络中。这种情况叫“分叉”。当分叉发生的时候,有两种办法。但都是顺其自然,不人工干预。后面挖新块的矿工,会自己决定把哪一个分支最后的块作为自己的前一个块。如果在比较短的块数内,一条链明显长于另外一条链,那么长的链会被保留,短的会被抛弃,挖短链的矿工算是白干了一场。所有的网络节点在同步的时候,都会选择当前最长的链进行同步,后面挖矿的矿工创建新块的时候也是选择最长的链。但是还有一种情况,就是短链的矿工不依不饶,或者短时间内两条链无法分出胜负,甚至最后每条链都有了很多块跟在后面。一帮人的转账总不能有两个账单吧,如果两个账单最后发现还不一样就麻烦了。所以遇到这种情况,矿工们会决定分家。也就是一个区块链变成了两个链,其中一条链把前面的所有链复制出来,成为独立的链,从此这两条链再无瓜葛,虽然前面的区块都是一摸一样的,但是后面井水不犯河水。这种情况叫“硬分叉”,BitCoin Cash就是这样诞生的。新产生的链继承了前面的区块,但是后面的区块完全是挖这条链的矿工决定的。硬分叉的好处是,对于原来的用户而言,突然之间,自己的一份资产变成了两份????至于区块体,真的是根据区块链应用的业务需求来设计。比如比特币,就被设计为交易模型,所有区块体里面的交易记录放在一起,就是一个长长的账单,每一分钱的来龙去脉写的一清二楚,如果当初红十字会用区块链来捐款,那就不会有那么大的风波。但是其他区块链应用不一定是交易模型,比如用于记录医疗信息的区块链,用于记录用户位置的区块链……所以,对于区块链技术本身而言,点到这里即止,再往下说就是比特币特有的技术了。挖矿和共识机制前面已经多次说了挖矿。简单说挖矿过程就是一堆矿工在抢创建一个新区块的权利的过程。在加密货币的世界里,抢到这个权利,就会在这个区块的最前面加上一笔转账给自己的交易,而这个交易的钱是凭空而来的,所以又叫“挖矿奖励”,而且数额还不少,所以矿工才挤破脑袋抢这一个记账权。但是在其他非币区块链应用里,假如没有这个奖励,怎么激励矿工挖矿呢?这也是区块链领域里一个玄而又玄的话题,至今没有答案。那么挖矿挖矿,到底是怎么一个技术上的算法过程呢?在矿机程序里,规定了如何得到一个hash,而这个规定,就被称为共识机制,所有矿工按照这个共识机制去进行某个算法,看谁先得到一个符合条件的结果,而这个结果又可以被轻而易举的验证是符合条件的(验证是否符合共识机制)。不同的区块链,共识机制不同,目前比较知名的是PoW和PoS,以及在这两者基础上衍生出来的其他共识机制。为了能够把挖矿过程讲清楚,我们只拿比特币遵循的PoW来进行演示。SHA256(SHA256(version + prevHash + merkleRoot + time + currentDifficulty + nonce )) < TARGET矿机执行上面公式,只要满足上面这个公式(执行结果为真),就算挖到矿。现在对这个公式进行解释。矿机会做一个double sha256的运算,运算的参数其实全部是块头里面的信息,但是因为这个时候区块还没有生成,所以这些信息是暂时保存的,如果抢到记账权,就把这些信息记录进去version是当前运行矿机的客户端软件版本,每次版本升级,可能对一些参数会有影响,比如区块大小从1M扩容到2M,但是对于挖矿算法而言是不变的prevHash是前一个区块的hash值merkleRoot是当前矿机内存里暂存的交易的merkle算法得到的根hash,merkle会在下文讲time是当前时间戳currentDifficulty是当前难度,这个当前难度是由一个公式算出来的,这个公式是 currentDifficulty = diff_1_target/TARGET 这个公式里面的diff_1_target可以认为是一个常量,在比特币客户端里面是不变的,值为0x1d00ffff。当然,其实它也有可能变,但怎么变都差不多这个值,我们还是把它当作常量。而TARGET我们在下面会讲到。nonce是一个正整数,nonce的值就算矿机要找的值。当矿机开始执行double sha256算法时,nonce为0,如果执行完一次,无法满足上面那个公式,那么nonce就自加1,再执行一遍算法,如果不满足公式,继续加1再执行,就是这样一直加上去,直到找到一个nonce满足上面的公式,就算挖到矿。所以,这个nonce每一次挖矿都可能不一样,它是完全随机出现的,到底是多少完全看运气。但不管怎样,你看每个区块里面但nonce值,就知道矿机做了多少次运算,也就知道挖到矿有多难了。TARGET是用以对比的目标值,它是一个特定值,比特币的发明者希望10分钟产生一个区块,所以最初设计的TARGET就是为了让currentDifficulty能够到一个合适的值,保证10分钟一个块。但是实际情况并不可能保证10分钟一定出一个块,如果算力下降,时间就会加长,这时就应该调整一下难度,使出块时间尽可能恢复在10分钟左右。所以2016个区块(2周)TARGET就会调整一次,而如果真实的情况是产生2016个区块的时间超过2周,那么TARGET就会适当增加,从而使currentDifficulty减小,下面2016个区块的难度就会降低一些。相反,则提高难度。这个调整算法本文就不展开了。所以TARGET是一个2016次不变,但总体而言一直在变的值,它的目标就是让产生一个区块的时间大概在10分钟左右。这就算比特币的挖矿,矿工们每天看着自己的机器,反复不断的执行这个公式,寻找那个nonce,日复一日,年复一年。当矿机找到nonce之后,就夺得了记账权,就可以把内存中的交易信息调出来,打包到区块体中。而merkle root是通过交易记录计算得到的,所以不可能矿工在打包时又去做手脚,一旦他伪造了某一条交易,打包进区块体的交易就不能得到他挖矿时使用的那个merkle root,也就无法得到挖矿时找到的那个hash。当然了,实际上比特币挖矿可能还要麻烦一些,比如说还有nonce溢出、矿池……Merkle Tree前面说了好多次Merkle,它到底是什么?Merkle Tree是一种数据结构,比特币里面就是一棵二叉树,也就是每个父节点有两个子节点那种。我之前写过一篇文章《区块链如何运用merkle tree验证交易真实性》里面详细讲了一些Merkle Tree的原理以及问题。这里主要还是做一个科普,不深入讲。区块头里面的Merkle Root是怎么来的呢?它是通过对区块体内的记录做Merkle算法得到的。以比特币为例,一个区块里面包含n个交易,我们把这些交易两两分组,每两个一组,得到n/2组,如果有单数,那么最后一个交易复制一份凑数。先对每个交易做hash提取,这样就得到来n个hash,然后对每组的hash做double hash运算:parentHash = sha256(sha256( hash1 + hash2 ))也就是把这个组里的两个hash连起来,再计算得到一个新hash,这个新hash就算这两个hash的父节点。得到所有组的父节点之后,按照同样的逻辑,得到父父节点,如此一直下去,最后得到一个根节点,这个根节点就是merkle root。merkle算法大致是这样,但它不仅限于区块链领域,在其他任何验证领域都可能用到,而且也不一定是这里讲的必须两个得到一个的算法,也可以是任意个得到一个的算法,总之merkle是一种对多个记录进行运算得到一个根hash的算法。而可以想象,对参与算法的任何一个交易做小小的改动,都会导致得到的merkle root不一样,所以区块里面只需要保存merkle root就可以了。这就算密码学的力量。区块链适合什么不适合什么?区块链数据的特征主要有两点:1.公开透明,任何节点对数据有完全的权利去查看;2.难以伪造或篡改。因此,区块链非常适合两类场景:1.证据;2.监督。如果区块链上的信息得到法律认可,那么但凡拿出区块链上的证据,侵权方将百口莫辩。而试想,如果将税收完全迁移到区块链,每个公民的每一笔税收,最后都用到哪里,一清二楚,这可能是令某些人害怕的点。但区块链有两大缺点:1.要挖矿,还有分叉风险,也就是说一个数据放到区块链上,要等很久才能成为不可篡改的可信数据。2.分区块,数据被割裂存放,这给查询带来巨大的麻烦,非常影响效率。所以,区块链不适合那种即时性要求高的场景,无论是信息交换的即时性(例如聊天)还是查询的即时性(如搜索引擎)。区块链不是万能的,某些服务明明中心化模式效率更高,成本更低,却偏要为了风口搞区块链化,那只能看韭菜长没长齐。还有一点令人担心的是,由于区块链上信息的公开透明,而且不可删除,是否会对个人隐私造成极大的损害,试想一下,当年给冠希哥修电脑的小哥通过区块链网络炫耀自己发现的照片……那对当事人的伤害……连人死了都不会消散……区块链应用随着风口的来临,区块链应用此起彼伏。但目前比较成熟的,无非三种模式:1.比特币;2.以太坊智能合约;3.比特股。其他的,不多说,读者自己看着办。一个区块链应用,它的架构是怎样的呢?在区块链本身之上,还需要有哪些其他的技术来支撑呢?区块链应用体系架构图(邵奇峰等《区块链技术:架构及进展》)区块链应用,如比特币、以太坊,与区块链本身有比较大的耦合度,也就是说区块链作为数据库无法较为独立的成为应用中的一个模块,和我们现在流行的B/S架构稍有不同,区块链应用中会把区块链拆解之后,于应用其他层进行融合,最终实现应用的整体功能。我们以比特币为例来讲一个区块链应用,比单纯一个区块链本身多了哪些部分。比特币是一个基于区块链的账单系统,它除了区块链,还要包含:1.交易模型;2.身份认证体系(类似PKI);3.智能合约。交易模型交易模型就是区块体内保存的交易记录。之所以比特币里面的每一笔钱的来龙去脉都一清二楚,就是依赖于交易模型。我们现实中银行里面的一个账号,只会告诉你一个账号现在有多少钱,曾经花了多少钱,收入多少钱,还欠多少钱。但是不会告诉你“某一笔你花掉的钱,来自你某一笔收入”。但比特币里面必须告诉你这样的逻辑,一条交易包含“输入”和“输出”两个部分,比如你要转10BTC,那么你的账号必须有一个或多个“输入”加起来总和等于或超过10BTC,而输出就是指你要把这10BTC转给谁。但是有一种情况,当所有“输入”加起来为10.5BTC时怎么办,就像你有100块毛爷爷,去买70块的东西一样,需要“找零”。所以“输出”有的时候会有一个是转给自己的,就是“找零”。比特币交易输入与输出示意图而实际上,输出在另外一个交易中,又是这个新交易的输入。在区块体里面,这些交易记录,以及它们的输入输出都被如实记录。除此之外,还要进行merkle计算,将merkle root存到区块头中。身份认证体系既然是交易,那么必然涉及到交易双方的身份。比特币交易的两端是两个账号,至于到底是谁它不管,但它通过加密算法,保证这一笔交易是哪一个账号发起的,发起交易的人要对交易信息进行签名。你可能听过非对称加密、公钥和私钥。比特币账号最关键的就是这个私钥,一旦私钥丢失,你就无法证明自己是这个账号的主人,也就无法从账号中进行转账要做的签名动作,你就不能再花这个账号里面的币,也就丢失了币。那么签名是怎样的一个过程?怎么证明这个交易是我发出的?怎么证明这钱是转给我的?密钥、地址与钱包密钥 通常指的是保护比特币资产的对应于所有权用户的私钥,个别时候也会模糊的统称私钥和公钥为密钥,这里我们以狭义的私钥解释为准。地址 比特币的收款地址,大部分情况下是指对公钥的封装(个别时候除了公钥还有脚本)。钱包 一种比特币客户端软件,是私钥的容器,通常通过有序文件或者简单的数据库实现。比特币钱包包含私钥和公钥数据,尽管公钥数据理论是是不需要存储的。一般来说,用户的公钥和比特币地址可以划等号,但实际上不是。比特币地址是一串比公钥短很多的字符串,主要是为了方便输入。而公钥则用于各种非对称加密。比特币公钥到比特币地址公钥和地址都是公开在比特币网络中的,只有私钥是用户自己保存,不能给任何人。当一个交易发起时,交易发起方用“自己的私钥”和“接收方公钥”对交易进行签名,那么网络中的其他人就可以用发起人的公钥去验证这个交易是不是他发起的,对于接收方而言,要提供自己的私钥进行解密运算,来证明这个交易确实是发送给自己的。而比特币客户端(钱包)就是干这个加密解密和签名的事。智能合约比特币本身已经有智能合约的雏形,只是它所采用的编程语言脚本能力比较弱,能实现的合约逻辑不复杂。以太坊则是在这个基础上扩展链智能合约部分,使智能合约的编程能力大大增强。在上文提到的输入和输出,输出其实就被作为另外一个新交易的输入。比特币的输出不单单是告诉系统要转给哪个地址多少钱,输出实际上是一段比特币脚本。这段脚本也经过复杂的非对称加密,要运行这段,想要得到一个输出里面的钱,把这笔钱作为自己交易的输入,必须用自己的私钥先解密脚本,然后运行脚本,脚本运行完,这笔钱就可以作为自己交易的输入了。结合前面的知识,只有拥有对应的私钥才能解密,所以,只有输出记录对应的比特币地址对应的那个用户才能解密脚本,得到这些钱。在这个过程里面,“脚本”是一个关键,除了上面这种最简单的转账逻辑,还可以通过一些条件判断来实现稍微复杂一些的编程,比如只有当满足某些条件的时候,解密后的脚本才能运行。于是,基于这种设计,比特币的脚本系统可以用来实现多重签名、保证合同等功能,也就是智能合约的雏形。结语对于区块链的研究,我也是刚刚开始,必定有不少地方没有理解透,有些地方也有误解。但对于想要了解这个领域的朋友,希望你们先了解区块链背后的技术原理(不必对技术细节掌握透彻),读一些比较成熟的可信的材料(我一不小心发现前人已经在《计算机学报》上发表类似综述的文章了,读者可以阅读《区块链技术:架构及进展》),而不是道听途说就信以为真。一旦你掌握了这些技术原理,就会发现,其实它的限制挺多,有美好的地方,也有没必要的地方,那些莫名奇妙的项目就坑不到你了。原文载于我的博客:http://www.tangshuang.net/4133.html 如果后期又发现一些错误,会在我的博客去更新,所以请关注我的博客。
2023年03月24日
5 阅读
0 评论
0 点赞
2023-03-24
程序猿生存指南-24 加班狂魔
(52) 放纵自我跟李亚男分手后,恢复单身的老潘跟我约饭多了起来。果然女人是男人友谊的最大羁绊。我几次建议老潘搬回幸福公寓继续跟我一起住,老潘推辞不受。后来,我才发现,原来这厮不愿与我合租,是怕我搅乱他的良宵美景。他破罐子破摔,放飞自我,肆意纵情,在网上不断地撩妹约炮。难道一个李亚男就让他变成了这样?我不知道二人究竟建立了多深的感情?分手对老潘有多大的打击?我只知道老潘如此这般作践自己,对他是百害而无一利。我规劝老潘,嫖海无涯,回头是岸。不知是我面子够大,还是老潘资金有所匮乏,他渐渐也有所收敛。由电商巨头阿里巴巴发起的双十一狂欢购物节已经成为了电商领域年度最大的盛会。去年,阿里巴巴在美国纳斯达克上市,市值一路飙升,可谓风光无限。作为阿里巴巴上市之后的第一个双十一,今年他们大秀肌肉,活动力度特别大。行业龙头吃肉,小弟们喝汤。老潘就职的公司主营奢侈品销售,旗下有一款业内知名的购物App。临近双十一,老潘作为App的产品经理,每天被雪花般的需求压着。为此,他通宵达旦,吃睡公司,甚是忙碌。寒冬将至,雾霾来袭。一年一度的逃离北上广的相关文章再次风靡于朋友圈。文章鞭辟入里,讲述各种缘由,楼价高涨、交通堵塞、空气污染,生活压力加剧......文章素材翔实,有着各种事例,程序员小张,卖煎饼的大李,开黑车的老王......总之,结论就是北上广不欢迎穷人。不过,今年的舆论风向倒是有所改变。有一些人站出来,发表了不同的观点。他们大都是先前逃离北上广、回家乡打拼的人。回到家乡后,他们失望地发现,家乡的楼价也涨了,雾霾也重了,堵车也是家常便饭了。北上广的弊病正迅速在中小城市里蔓延。一向不抱怨生活的老潘,最近频频跟我诉苦。他正犹豫做完双十一后是否离开北京这个伤心之城。换个地方,或许风景独好。2014年11月16日,北京集中供暖后的第一天,重度雾霾席卷华北大地。月朦胧,鸟朦胧,空中雾霾浓。山朦胧,树朦胧,喉咙有点痛。花朦胧,叶朦胧,医院排长龙。公寓附近超市的防霾口罩均已脱销。上班路上,我不得不埋头衣袖,掩鼻前行。双肩包被地铁口的护栏勾住,我一使劲儿变成了单肩包。晨会上,康神说潜龙的开发进度不容乐观,急需增加人手。我跟王旭被安排进了"潜龙"后台开发小组。不知是福是祸,我俩也没有选择的余地,一切听从领导安排。加入潜龙项目这天刚好是我的农历生日。徒增一岁,在他乡的第5个生日,没有礼物也没有蛋糕。晚饭过后,老妈打来电话,对我好一番嘱托。慈母口中语,游子伏案思。电话那头老姚一直在老妈旁边小声嘀咕,老妈充当着我俩的传话筒。成年后,父与子大抵都这样吧,明明互相挂念却故作矜持。老潘把借我的钱还清了,还给我发了个88块钱的大红包。嘘寒问暖不如红包巨款,也算他有良心。沉默许久的大学舍友群里也活跃了起来。昔日兄弟们借着我生日契机发了几个小额红包。等到手机屏幕被红包占满后,我们又开启了漫无边际地扯淡。我一边敲代码调试程序,一边有一搭没一搭地在群里跟他们聊近况。留在邮大读研究生的李冀,被导师外派到一家创业公司做实习生,跟我一样每天加班加点,忙成狗。回老家找了份国企工作的冯振,朝九晚五,老婆孩子热炕头,羡煞众人。去欧洲留学的马天华,整日跨国游荡,不务正业,在朋友圈里晒着巴黎的埃菲尔铁塔,伦敦的大本钟,好个逍遥自在。毕业一年多,大家都还没变,还是那般猥琐。下班回到公寓住所,我躺在床上,像往常一样在网络里四处游荡。在时针逼近12之时,我突然意识到遗漏了一项重要仪式。我快速下床,打开电磁炉,煮了碗面条,还加了个蛋,权当长寿面。待我吃完面条,时针正好划过12。24岁生日就这样过去了。若孤独是人生的必修课,当下我只盼望赶紧修满学分,尽早毕业。(53)生如咸鱼由于潜龙的定位以及开发需求一直在变化,项目排期一再拖延,可交付的时间却雷打不动。于是,开发周期最后被压缩了近三分之一。公司在年底将会举行一场新产品发布会,CEO会在大会上重点推介几款公司新产品,潜龙将会压轴出场。CEO关注的产品,部门领导必然很是重视。工期被压缩,按期上线的形势并不乐观,可延期发布又不可能。于是,整个潜龙项目组开启了无休止的加班模式。我便过上了996的生活(所谓996就是每天上班时间是早九点到晚九点,一周上六天班)。明面上说是996,实际上到了晚上九点,大家根本就走不了,一般都得熬到10点甚至更晚。互联网领域,大部分公司都提倡自愿加班。所谓自愿就是不用支付额外的加班费用。大家心有抱怨,却也无人反抗,为了三五斗米折腰。当然,也不是所有人都厌恶加班。客户端组有个刚入职的应届生,许是技术能力稍逊需要加班加点赶工;或是刚走入职场,体力充沛,拼劲儿十足。他买了张行军床放在工位旁,还从家里带来了洗漱用品。最近一段时间,他一直吃睡在公司,以公司为家。有几次我来公司稍早,瞧见他正躺在行军床上,四仰八叉地酣睡。杀猪般的呼噜声在屋子里回荡。金子总会发光,优秀的人终不会被遗忘。小伙的光荣事迹被同事发到公司内网论坛,一时间他成为了公司热议人物。部门老总知悉后,写了一封催人泪下的表扬信。不过,领导在表扬信的最后明确指出并不提倡大家效仿,老总们希望我们每个人都能有一个健康的体魄,为公司努力奋斗五十年。领导话讲得很是漂亮,可真实的研发任务压在每个人头上,不加班加点根本就干不完。当然,能力强如我师父王旭那般的人,他们能够很快把任务做完。可即便如此,他们也不会干完活就立刻回家,因为有一只无形的手在摁压着他们的脊背。九点过去了,十点过去了,十一点过去了,大家仍端坐在工位上紧张忙碌。各级老大巡视办公区,一个个端着泡满枸杞的茶杯,矗立在一隅,望着兢兢业业的小弟们,满脸欣慰。在这样的气氛烘托下,若是你提前回家,便会有一种在战场上败退,当了个逃兵的感觉。于是,在每个加班到深夜的日子里,有一部分人在大部分时间里都是演员。他们积极地扮演着老板们喜欢的样子。只有老板喜欢,才能有一个好的绩效。有了好的绩效才能有不菲的年终奖。有了不菲的年终奖,日子才能过得舒坦些。学好文武艺,卖与资本家。日子一天天地重复着,我忙得来不及思考人生。每天行尸走肉般地挤着地铁上下班,吃着那仅仅为了饱腹并不可口饭菜,聆听着那繁琐无趣又不可或缺的开发会议。秋分过后,昼短夜长。又是一个漫长的黑夜,大风吹散雾霾,美妙星辰,灿烂霓虹。黑色大幕拉开,我坐在办公室落地窗前,借着喝水的间隙,凝望远处。对面的千度大厦,旧浪大楼如我们朗云大厦一般,灯火通明。加班已经成为我们这个行业的生存常态。十多年前,软件园这里还是一片荒地,遍地飞禽走兽。短短几年光景,这里已经成为了帝都夜生活最丰富的区域之一。北京城的广大出租车司机特喜欢来这片区域接活,因为这里永远有拉不完的客人。我们这群程序员时常会成为司机们忙碌一天的最后一位客人。周五,康神召开组会,他见大家都神情呆滞,面露疲态,便给我们画起了大饼。他说项目交付后,会安排一场出国游犒劳我们。听王旭说,去年组里团建,行政小姐姐给他们提供了十多条旅游路线。上山下海,宝马香车,飞机游轮,应有尽有,活动特别丰富,公司也很大方,提供人均三千元的预算。不过对于那些方案,组里人都不甚满意,要么太累,要么太远,要么太贵。他们又是头脑风暴,集思广益,又是发起投票,尊重民意。几轮磋商,终于达成一致。阳春三月,他们在天津一家五星级宾馆里睡了三天三夜,打了三天的麻将。点击进入下一章阅读点击从第一章开始阅读
2023年03月24日
5 阅读
0 评论
0 点赞
2023-03-24
2个未来技术概念:Web3.0 和元宇宙
最近互联网世界的两个流行语 Web 3.0 和 元宇宙。看到这些新平台提供的发展潜力,许多公司正在探索 Web 3.0 和元宇宙技术所提供的可能性。虽然这两种技术趋势都在描述数字现实和网络的未来,但它们在做什么和如何去做方面是不同的。但是,这两个概念及其功能彼此不同。下面就来了解这两个流行语,以更好地了解互联网的未来发展方向。定义简而言之,元宇宙揭示了将在互联网上拥有的不断扩展的日常体验(例如游戏、社交、学习和工作),而 Web 3.0 试图通过去中心化技术解决互联网当前的问题(例如所有权、隐私和控制)。什么是元宇宙?元宇宙(Metaverse)是来自 1992 年科幻小说《雪崩》出版物存在的一个术语。在小说中,作者将元宇宙(Metaverse)描述为基于虚拟现实的互联网继任者。这本书设想了一个未来,人们可以在虚拟世界中用自己的化身并与他人互动。这就是大多数人理解的元宇宙(Metaverse):使用增强现实 (AR) 和虚拟现实 (VR) 技术构建的 3D 沉浸式世界。在那里,用户可以通过笔记本电脑、台式机和 VR 耳机等设备作为 3D 化身相互交流和互动。元宇宙可以是中心化的、去中心化的或两者兼而有之。什么是 Web 3.0?与此同时,号称网络的第三波浪潮,即 Web 3.0,是以太坊的联合创始人 Gavin Wood 在 2014 年首次提出的一个术语。它的定义要广泛得多,也更难确定。尽管如此,它通常指的是使用分散的基于区块链的机制将用户的数据存储在区块链上并赋予它们控制权。Web 3.0 是从 Web 2.0(万维网开发的第二次浪潮)在后端和基础设施变化方面向前迈出的重要一步。Web 2.0 是关于将网络带给大众,而 Web 3.0 是关于权力下放和从中央当局手中夺回控制权。Web 2.0 和 Web 3.0 最显着的区别在于后者基于区块链技术。区块链是一个分布式数据库,允许安全、透明和防篡改的交易。它还使其成为开发在公共区块链或点对点网络上运行的去中心化应用程序 (dApp) 的理想选择。涉及的技术Web 3.0 由区块链技术支持的去中心化网络组成,它还采用了尖端技术,如人工智能 (AI)、机器学习 (ML) 和语义网(一种新形式的网络内容,关注意义而非数据结构),提供更加民主化、高效和个性化的用户体验;它优先考虑集体所有权、个性化和内容共享。另一方面,元宇宙(Metaverse)专为虚拟世界而设计, 元宇宙(Metaverse) 中的体验构建块包括 AR、VR 和 MR(混合现实)。AR将虚拟物品融入到我们身边的物理环境中,而VR技术让你通过3D计算机建模进入3D虚拟世界。增强现实眼镜和虚拟现实耳机是带我们进入虚拟世界的设备。可能的场景去中心化自治组织 (DAO)、去中心化金融 (DeFi) 和不可替代代币 (NFT) 是 Web3.0 中出现的一些产物。例如,用户现在可以通过购买存在于区块链网络上的代币来拥有互联网的一部分:可替代的(例如比特币和以太币等加密货币)和不可替代的(例如 NFT 艺术收藏品)。至于元宇宙(Metaverse),可以看到不同的领域,如游戏、社交网络/娱乐和房地产,现在都在进入虚拟现实技术,为用户提供更逼真和身临其境的体验。例如,Horizon Worlds 是 Facebook(或 Meta)发布的社交 VR 平台,人们可以在其中与他人互动和玩游戏。还可以使用虚拟办公室应用程序(例如 Nth Floor)安排与元宇宙中的同事的工作会议。它的另一个主要机会是新的营销机会,许多品牌,如耐克、H&M 和沃尔玛,都在创建自己的虚拟世界,用户可以在其中购买产品并与品牌建立联系。此外,元宇宙中还有区块链场景,例如虚拟世界 Decentraland 和视频游戏平台 Sandbox。这些应用程序是完全去中心化的,这意味着它们归用户所有或通过 DAO 控制。总结总而言之,虽然这两个概念在本质上并不相同,但它们肯定在许多方面相互关联,并彻底改变了未来互联网和世界。
2023年03月24日
7 阅读
0 评论
0 点赞
1
...
6
7
8
...
11