数据专栏

智能大数据搬运工,你想要的我们都有

科技资讯:

科技学院:

科技百科:

科技书籍:

网站大全:

软件大全:

【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> 10月31日,万向区块链蜂巢学院联合矩阵元举办了“区块链+隐私计算与数据隐私保护”的分享活动,上海交通大学副教授何建平发表了《网络系统中的数据隐私:量化,分析和设计》的主题演讲,从隐私的量化的角度给大家介绍了保护算法分析与设计,带领大家从技术上深入了解数据隐私保护。以下为何建平教授演讲全文,有部分不影响原意的删减:

大家下午好,今天我演讲的题目是《网络系统中的数据隐私:量化,分析和设计》。今天的演讲主要分为四个方面:背景介绍、量化隐私、分析设计、趋势设计。

背景介绍
随着互联网的发展以及各种智能设备、智能传感器的出现,我们已经到了信息爆炸的阶段。大数据的时代已经到来,在生活当中各个领域:商业大数据、农业大数据、医疗大数据以及工业大数据。

我们基于大数据可以做什么事情,有了这些数据之后可以进行算法设计、优化、预测,可以进行基于数据的控制和维护等等。从工业角度来说,可以通过大数据的分析提升工业生产的制造效率和质量,支持工业设备进行节能降耗。从互联网的思维来看,基于数据分析可以得到用户的喜好、偏好,可以基于这些分析的结果做一些广告的东西,商家可以更加的了解用户,最终推出用户更喜好的产品。

大数据的实用性决定了其价值,狭义的大数据通常指的是专门用于大数据的软件、硬件及服务。我们根据IDC和Wikibon等预测,全球的大数据核心产业规模约为200-300亿美元,据中国信息通信研究院预测,2017年我国大数据产业规模达到4700亿,现在还在持续的增长,增速达到30.6%,预计在今年可以达到6200亿人民币。增长速度在未来的2年内还会进一步维持。

大数据时代下,数据是一个双刃剑,给我们带来便利的同时,当然也可以给我们带来很多问题,最主要的问题就是隐私的问题。今年已经出现了很多隐私泄露的事件。印度10亿公民身份数据库得到攻击,这些信息都已经泄露、名字、电话号码、邮箱、指纹、虹膜等等都泄露了。今年3月份,一家英国的数据分析公司通过调查问卷的方式收集到Facebook 5000万用户的信息,用来做政治上的操作,对Facebook造成了很大的损失。一方面,互联网企业利用大数据给我们很多用户提供了很多的便利,从个人消费者来说,我们享受便利的同时,也有新的担心,就是各种隐私的信息遭到了泄露。如果利用大数据为生活带来便利的同时,利用技术手段保护用户的隐私这是一件非常有意义的事情。

大数据时代下,关于隐私有如下问题:
l 如何保护隐私?
l 怎么刻画隐私保护的程度?
l 数据的有用性和隐私之间的关系?
l 如何防护和优化?
l 大数据下的隐私保护新技术趋势?

量化隐私
为了回答上述问题我们首先需要了解隐私是如何被保护的,目前常用的隐私保护方法主要有两大类, 加密 和 加噪声 。

加密主要是指以算法的形式改变原有的信息数据,将明文进行加密处理后进行发送,收到数据的一方用已掌握的密钥对密文解密,从而还原出原始数据。未被授权的用户即使收到了信息,由于没有掌握密钥仍然无法获得原始数据。加密通常有两种,一种是对称加密,第二种是非对称加密。对称加密中加解密使用相同密钥,非对称加密中加解密使用不同密钥。但是加密方式存在一些问题,密钥有可能被丢,对称加密算法简单但容易破解,非对称复杂性高,但是要用数据的时候效率非常低。

另一种隐私保护方法是加噪声。这种保护隐私的方式有其优点:首先,它具有量化标准来评价隐私保护的等级;而且,通过设计噪声添加机制,在保护隐私的基础上可以保证数据的可用性。常见的添加的噪声有:拉普拉斯噪声、高斯噪声、均匀噪声,下图是它们的分布情况:

我个人比较喜欢加噪法,数据永远掌握在自己手里最安全的。加密你要用的话肯定要有一个解密的方法,一旦这个解密的方法泄露出去了,别人总是能看到的。

差分隐私
2006年C.Dwork提出 差分隐私 的概念,为隐私保护提供了一种量化评估方法。

若ϵ 为一正实数,A为某一随机算法,如果对于两个只相差一个元素的相邻数据库D1和D2,以及所有的S ∈ Range(A) ,存在:
那么随机算法A可以实现 ϵ - 差分隐私,这里Range(A)代表随机算法A 的输出范围。

如下图,假设X和Y是比较近似的两个数据,A是你要去保护的技术,你是隐私保护的方法,在A作用下以后,两个数据的输出,给大家可以看到的O应该是差不多的,在这种情况下我们称之为随机保护的机制是差分隐私。差分隐私已经被苹果、谷歌公司应用于它们的产品当中来保护用户隐私。

分析设计
英国数据公司Cambridge Analytica通过调查申请收集了Facebook用户的信息,并将其滥用于政治目的,超过8000万Facebook用户的个人资料受到威胁,这一丑闻曝光后,Facebook损失了数百亿美元。这个事情背后的原因是:
l 第三方服务请求过多信息
l 用户不知道共享信息的潜在威胁

究其原因主要是这两点,针对这样一个事情,我们设计了一个全新的第三方信息共享的框架。我们的研究目标是 通过控制与第三方共享的信息,最大限度地实现隐私保障下地安全自我信息披露 ,所谓自我隐私披露指的是我为了享受社交网络带给我的正常的服务而愿意暴露的个人信息,为了通过巧妙地隐藏用户信息有效降低推理攻击的准确,减少对用户体验的损害,满足不同用户的隐私问题,我们提出了两种隐私保护数据共享算法,EPPD和D-KP,分别侧重于最大化用户体验和降低计算复杂度。

如下图所示是我们的系统实现的展示,在原有的第三方系统认证OAuth2基础上引入了我们的隐私保护算法。左图我们给用户提供了一个对第三方服务信任度选择的接口,并且清楚的告诉用户第三方所请求的各项服务,方便用户决定暴露多少的个人信息。

通过在实际的数据集上仿真,我们可以看出引入了我们提出的算法之后能够大大降低推理攻击,对于机器学习推测用户习惯,我们的算法大大降低了常见分类器的准确性,保证了就算攻击者在一个应用上学习到了我的一些用户习惯,也不能如法炮制到下一个软件。可见我们的算法在最大限度地提高用户数据公开度的基础上提供了更强的隐私保护。


随着大型互联网系统的快速发展,各种灵活多变的系统架构模型层出不穷,主要分为集中式和分布式两大类:
l 集中式:依赖中心节点,一旦中心节点遭到攻击,整个系统性能都会受到影响,可拓展性差
l 分布式:不存在中心化的节点,任意节点的权利和义务都是均等的,系统中的数据块由整个系统中具有维护功能的节点来共同维护,任一节点停止工作都会不影响系统整体的运作

分布式数据统计正是分布式系统的重大应用之一。与传统的数据统计不同: 分布式数据利用分布式技术对数据进行统计和学习,将原先集中在单节点上的庞大计算任务均衡的分派给若干台可相互通信的计算机上并行处理。 分布式数据统计提供异构的隐私保护一致性框架,这种方法既能准确统计结果,又量身定制般地为每个用户的隐私不同程度地保护。

我们提出了两阶段框架。首先将用户分为不同小组,白色节点表示数据服务器,N个数据服务器构建成分布式网络。一个数据服务器负责从一组用户中收集数据。

阶段一:服务器搜集用户数据
不同的数据服务器从不同的用户组收集私有数据,从用户的角度考虑,用户认为直接上传数据的服务器有泄密风险,因此在数据报告之前,用户首先用高斯噪声扰乱其数据。而噪声方差由用户的隐私需求决定。

阶段二,服务器协作统计数据
当所有服务器完成数据聚合后,如何统计整个用户群体的结果呢?服务器网络执行一致性算法,在一致性过程中,服务器节点要将自己的信息释放出去获得相邻服务器节点的信息从而更新自身的状态。

下图显示了框架的整个工作流程。

首先,节点向服务器报告具有高斯噪声扰动的数据, 相当于一层防火墙。加噪聚合后,收集节点数据的服务器提供的用户隐私保护度增大,相当于自动增强了防火墙 。最后,多个服务器协作执行共识计算。

总的来说,我们的异构隐私保护方案有三大优点: 用户上传,安全聚合以及共识计算。

我们该如何选择添加的噪声以满足用户的个人隐私需求,并且保证数据发布的效用行呢?为了研究这一问题,我们首先需要对问题建模。

在模型一中,我们站在数据收集方考虑,既需要保证用户的隐私确保用户还愿意给自己提供数据,同时需要保证数据的可用性,故而目标函数建立为隐私和效用性的加权。

模型二中,我们考虑在实际生活中,隐私是个人的标准,每个人可能有不同的隐私保护需求,当达到一定的隐私保护水平后,如何最大化数据的效用性是具有实际指导意义的,故而我们将目标函数设置为数据的效用性,限制条件为每个人不同的隐私保护要求。

对上述两种模型我们通过一定合理的假设并给出结论,为了得到最优的整体效益(最大化隐私保护和可用性之和)的噪声是均匀噪声。在保证一定隐私的情况下,为了得到最大的数据发布可用性的噪声添加机制是均匀离散噪声,如下图所示:

趋势分析
区块链作为一种特殊的分布式数据库,是没有管理员的,彻底无中心的,一个个相连的区块(block)组成。区块很像数据库的记录,每次写入数据,就是创建一个区块,是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。以前是靠信誉、靠百年老店、权威机构等,区块链利用技术建立了新的信任方式,这是可以被量化的,从技术的角度实现的,所以说区块链成为了下一个信任的基石。目前区块链的隐私性主要通过匿名方式来保证,然而这种方式有可能被破解——对公开的交易账本信息进行资金流分析。

怎么样完善这个机制呢?当然有一些新的机制出来:
l P2P混合机制:若干用户签订协议,将多个交易混合成一个标准的交易,将多个提供者和接收者分别随机排序,我们也无法知道某一笔资金是从哪一个代号流入到哪一个代号。通过破坏交易的连续性,可使得建立代号之间的关联更为困难。
l 分布式混淆网络:多个用户都会和某一个第三方机构达成如下协议:我先交付给该机构10个币,过一段时间后,该机构会返还给我10个币。通过这种方式,外部人员很难捕获交易之间的关联信息。但是,这种方式也面临着第三方机构不归还资金的风险。
l 零知识证明:资金提供者并不需要通过提供自己的身份信息来验证资金的有效性,而只需证明该笔资金属于一个有效资金的公共列表。

如何在区块链中满足个人、企业、政府等对保护数据隐私要求,推动区块链技术规模化落地应用必须要解决的难题。

蜂巢学院简介:
「蜂巢学院」是万向区块链倾力打造的线下活动品牌,持续关注区块链相关领域前沿技术与热点话题。汇聚全球范围内最具影响力的意见领袖、行业先锋、创业达人、专家学者等,通过小范围的面对面深度交流,力求记录全新科技改变我们所生活时代的每一个重要瞬间。而时代的浪潮之中,面对无限可能的未来,我们每一个人,都是求知者和见证者。
区块链
2018-11-02 15:43:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
在前面的系列文章中我们了解了ERC20 tokens以及ERC721标准,和crypto-collectible。这些知识可以让我们可以和其他玩家交易自己的创造的角色。
在最后一篇我们将了解怎么把智能合约发不到ETH网络上。我们会了解一些关于Web3.js库的知识点。
1
客户端和node之间的通信机制
一个客户端向ETH网络发出请求的时候,我们的客户端需要告诉node 我们需要的智能合约的地址 我们需要哪个功能 和那个功能需要的参数
ETH网络的node只能够识别:JSON-RPC语言,对于人类来说不是那么容易阅读。
在实际中,客户端向node发出的请求是这样的 // Yeah... Good luck writing all your function calls this way! // Scroll right ==> {"jsonrpc":"2.0","method":"eth_sendTransaction","params":[{"from":"0xb60e8dd61c5d32be8058bb8eb970870f07233155","to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","gas":"0x76c0","gasPrice":"0x9184e72a000","value":"0x9184e72a","data":"0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"}],"id":1}
而通过Web3.js库来进行通讯的话,就可以把上面的晦涩难懂的部分包装到盒子里面。而表面上,我们可以使用易懂的语言。
我们可以这样写:
CryptoZombies.methods.createRandomZombie("Vitalik Nakamoto ")  .send({ from: "0xb60e8dd61c5d32be8058bb8eb970870f07233155", gas: "3000000" })
2
安装Web3.js库 // Using NPM npm install web3 // Using Yarn yarn add web3 // Using Bower bower install web3 // ...etc.
你也可以直接下载最小化了的js文件:github( https://github.com/ethereum/web3.js/blob/1.0/dist/web3.min.js)
然后import到你到文件里面。
我们的html文件会是这个样子:             CryptoZombies front-end                  
3
设置Web3 Provider
ETH网络上,有很成千上万的node,通过设置Web3 Provider,我们可以设置我们将对哪个特定的node发出请求。当然你需要自己创建一个node,来做provider。
如果说这些特别的设置,会让很多人困惑,当然ETH社区已经为你准备好了一个工具:Infura
Infura
Infura是一个附带有缓存,高速处理读写的node。 Infura is a service that maintains a set of Ethereum nodes with a caching layer for fast reads, which you can access for free through their API. Using Infura as a provider, you can reliably send and receive messages to/from the Ethereum blockchain without needing to set up and maintain your own node.
可以这样设置Infura为你的Web3 Provider var web3 = new Web3(new Web3.providers.WebsocketProvider("wss://mainnet.infura.io/ws"));
public,private key
区块链上,别人不可能冒名顶替你,是因为别人不知道你的private key。但是一个智能合约在执行的时候,我们需要用户用private key来签名,从而证明这次调用,是我们在调用。我们既然知道private key的重要性,当然不敢轻易的来管理用户的private key了。
所以,在用Infure的功能的基础上,如果想要加上private key的管理的功能的话,Chrome和firefox的extension:Metamask将是一个必备的工具。 Metamask uses Infura's servers under the hood as a web3 provider, just like we did above — but it also gives the user the option to choose their own web3 provider. So by using Metamask's web3 provider, you're giving the user a choice, and it's one less thing you have to worry about in your app.
如果安装了Metamask,也就意味这你装备了Web3.js。
下面这段代码是Metamask提供的,怎么检测是否Metamask已经安装: window.addEventListener('load', function() {   // Checking if Web3 has been injected by the browser (Mist/MetaMask)   if (typeof web3 !== 'undefined') {     // Use Mist/MetaMask's provider     web3js = new Web3(web3.currentProvider);   } else {     // Handle the case where the user doesn't have web3\. Probably      // show them a message telling them to install Metamask in      // order to use our app.   }   // Now you can start your app & access web3js freely:   startApp() })
4
ABI ABI stands for Application Binary Interface。
代表了智能合约函数的JSON形式。Solidity编辑器会告诉我们的ABI。
5
发布
在编辑,发布了你的智能合约之后,我们需要记下下面的内容: 记下我们智能合约在ETH网络上地地址。比如电子猫的地址:0x06012c8cf97BEaD5deAe237070F9587f8E7A266d 还有上面ABI。
6
初始化智能合约 // Instantiate myContract var myContract = new web3js.eth.Contract(myABI, myContractAddress);
Web3.js
我们会通过Web3.js提供的两个接口来和Web3.js进行交互:call 和 send call is used for view and pure functions. It only runs on the local node, and won't create a transaction on the blockchain.
还记得:view and pure么?表示这个函数不会对区块链进行写的操作,只会读取,而且完全是免费的。
Web3.js的call用于激活任何view or pure的函数。
我们可以这样激活Web3.js的call
myContract.methods.myMethod(123).call()
send will create a transaction and change data on the blockchain. You'll need to use send for any functions that aren't view or pure.
Web3.js的call用于激活任何 非view or pure的函数。而且需要用户支付费用
和call一样,你可以这样激活
myContract.methods.myMethod(123).send()
拓展阅读:
十一课堂|通过小游戏学习Ethereum DApps编程(1)
十一课堂|通过小游戏学习Ethereum DApps编程(2)
十一课堂|通过小游戏学习Ethereum DApps编程(3)
十一课堂|通过小游戏学习Ethereum DApps编程(4)
十一课堂|通过小游戏学习Ethereum DApps编程(5) 本系列文章作者:HiBlock区块链技术布道群- Amywu
原文发布于简书
加微信baobaotalk_com,加入技术布道群
Blockathon|48小时极客竞赛,区块链马拉松等你挑战(上海)
时间:2018年10月19-21日
地点:(上海黄浦)露香园路1号(近淮海东路)P2 招募 50名开发者 (识别下图二维码或点击“阅读原文”即可了解详情并报名)
北京blockathon回顾:
Blockathon(北京):48小时极客开发,区块松11个现场交付项目创意公开
成都blockathon回顾:
Blockathon2018(成都站)比赛落幕,留给我们这些区块链应用思考
区块链
2018-10-07 22:16:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
当区块链技术从专业研究走向市场应用,开发者需要考虑用户的使用场景和使用门槛,例如通过ETH支付gas手续费,或者注册一个16进制的用户名,普通用户都难以接受。
10月20日,HiBlock区块链社区邀请NEM 、Tenzorum以及Olympus的核心开发者分别从区块链应用的使用便捷度和区块链应用开发便捷度两个方面分享区块链开发应用实战。
1
时间地点
时间:10月20日 9:00 -  11:30
地点:上海市黄浦区柳泉弄1号2楼P2
本次活动免费
参会人员要求:
1) 技术背景人员,对区块链开发有兴趣;
2) 自带电脑
2
分享嘉宾及主题
课程:如何让大众用户更便捷的使用区块链技术
大纲:
1)    现阶段区块链技术存在的壁垒与不便
2)    TENZORUM项目的两大解决方式
3)    解决方式1:子域名生成工具Tenz ID ENS(Ethereum Name Service,以太坊域名服务)子域名生成工具,只需要两次鼠标点击步骤你就可以注册一个容易识别的用户名(与以太坊地址绑定),而不是像【0xwreJUI8gn4320959Uuiolk……】这样用户体验极差的钱包/账号地址。这对于那些面向于普通用户的应用将十分有用,因为普通用户倾向于使用可识别的短用户名,而不是一个枯燥无趣的长地址。
4)    解决方式2:无GAS交易 (Tenzorum Service Node Network TSNN 天钥服务节点网络) 对于不熟悉区块链技术的大众用户来说,使用以太坊的一个巨大的挑战是,在使用dapp或者相关的区块链产品之前,他们需要有ETH来支付gas手续费。而TSNN服务能够让用户通过一个代理中继节点(Tenzorum Service Node,天钥服务节点)与区块链进行交互,通过这种方式,来消除大众用户初次使用dapp/app的使用门槛。
5)    TENZORUM项目信息与未来的发展
讲师:Daniel Bar
TENZORUM项目创始人, Bitfwd社区创始人, 
纳米技术硕士,以色列技术研究院,新西兰Edmund Hillary 学术奖金获得者
讲师:Radek Ostrowski
TENZORUM项目CTO, 区块链工程师,大数据工程师,前澳大利亚联邦银行大数据顾问
课程:Olympus 协议介绍
大纲:
1)  Olympus 组件介绍 Olympus 代码详解 利用Olympus协议开发自己的基金
讲师:orange
Olympus协议核心开发者,资深以太坊开发者,
比特币老玩家,   Metamask团队成员,
2年智能合约开发经验
课程:如何将NEM融入你的项目
大纲:
1. NEM简介
2. 为什么选择NEM
3. 怎样使用NEM的五大功能
**讲师:Anthony Law(刘永川) ** 
NEM马来西亚Technical Trainer
3
活动流程
4
报名方式
扫描二维码或点击“ 阅读原文 ”即可报名
区块链
2018-10-16 22:50:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>

1.编译智能合约
在eos的源代码下面提供了很多智能合约的例子,目录做contract目录下,我们就以官方的hello这个智能合约为例。打开目录可以看到一个cpp和一个abi文件。在eos里面提供了一个命令eosiocpp,这个命令是用来编译智能合约的,该命令做./build/tools这个目录下。
eosiocpp -o hello.wast hello.cpp
eosiocpp -g hello.abi hello.cpp
第一个是用了编译钱包,第二个是用来编译abi文件的。

2.创建钱包:首先你得有自己的钱包,钱包要安全就要有一个密码。创建钱包如下:
./cleos wallet create -n hello --to-console
"/Users/amei/github/eos/build/programs/keosd/keosd" launched
Creating wallet: hello
Save password to use in the future to unlock this wallet.
Without password imported keys will not be retrievable.
"PW5KHueikjSWMHvUS3vrKcKRrBSaeMiEGnT1T1EEc9pZhSBhG8sgV"

红色字的是命令行,创建了一个名字为hello的钱包,绿色字的为生成的密码,这个需要保持起来。
钱包可以上锁可以解锁,上锁使用 ./cleos wallet lock -n hello
开锁使用:./cleos wallet unlock -n hello --password PW5KHueikjSWMHvUS3vrKcKRrBSaeMiEGnT1T1EEc9pZhSBhG8sgV
开锁必须要使用密码。

3.创建key:下来就是创建一个账户,即要创建一个公钥和私钥了。创建key命令如下:
./cleos create key --to-console
Private key: 5JpjnxzTHV7owvn8KVZcmDXpLCbQP7VcDL61XhZLs8iBQFrZ4U4
Public key: EOS7A6h4FALtyUXCpNH725tH9MQ3c2D7ZT8jhj3k19r3gpvXD22ST
这样就生成了。
将生成的私钥导入到钱包中:
./cleos wallet import -n hello --private-key 5JpjnxzTHV7owvn8KVZcmDXpLCbQP7VcDL61XhZLs8iBQFrZ4U4
imported private key for: EOS7A6h4FALtyUXCpNH725tH9MQ3c2D7ZT8jhj3k19r3gpvXD22ST

4.创建账户:./cleos create account eosio flyup EOS7A6h4FALtyUXCpNH725tH9MQ3c2D7ZT8jhj3k19r3gpvXD22ST
eosio是超级账户,在创建过程中可能会遇到如下问题:
Provided keys, permissions, and delays do not satisfy declared authorizations
这个问题可能是因为默认账户没有导入相应的私钥,所以中创建自己的钱包之前需要个默认的钱包也要导入私钥。

5.发布一个智能合约
./cleos set contract flyup ../../contracts/hello -p flyup

区块链
2018-09-06 17:02:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
比特币不是货币,人民银行下发的通知明确阐明了这一点。
马克思主义政治经济学的一个核心就是关于价值和价格的论断,强调价值为人类无差别劳动的凝结,而价格是价值的表现。货币的根仍然在于价值,没有价值的货币是没有意义的。
承认这一点就会自然承认比特币不是货币。
有趣的是的确有人似乎不承认马克思恩格斯关于价值的论断,老实说,真的有点坐井观天的感觉,林子大了什么鸟都有啊,居然有人不承认马克思主义的价值论——那些承认比特币是货币的人或国家,似乎都不承认马克思的价值论。
比特币的发行没有任何价值参与其中,如果说支撑算力的电费是比特币的价值的话,那么这也是用掉了的价值,不是生成了价值。
比特币或许可以说是区块链技术成就的一种结算手段,但要说它是一种货币,那就是偷换概念了。
如果人民银行在下一版人民币发行过程中,利用类似的技术生成中国版的货币区块链,或许我们可以称之为人民币链。销毁上一版人民币若干数量的纸币,然后在人民币链上生成相应数量的电子货币,如此,这些电子货币才真正具有价值。
虽然很多经济学者并不认为货币必需由国家发行,但是当前世界通行的做法都是由国家来发行货币。
如果你认为货币的价值可以不用国家(或者政权)的力量来维护,那我上面说的都是废话。
我猜比特币的创造者们应该是认为他们具有发行货币的能力,并且是发行的是世界范围内无国界的货币,对此俺深不以为然。

但是,比特币没有死去。

比特币不死,或许有两个发面的原因:
第一,记账货币或许是人类未来的货币形式,因为它的先进性的加持,比特币不死。
第二,人类对去中心化的网络拓扑结构的需要,加持了比特币不死之身。

总之,卸去比特币是货币的金身之后,比特币就成了一个巨大的账本,这个账本具有不可更改,隐私性好,账本本身很难被消灭掉等特点。要想一举灭亡比特币这样的公有区块链,似乎需要在接近同时的情况下将所有计算节点摧毁掉,否者有一台存活的话,之后新的节点连接上这台漏网之鱼,就又能成燎原之势。
很显然,比特币这样的大账本对于很多做大事的人们有很大的意义,比如军火商、毒枭、食品加工商以及药品生产商等,这些人需要大额支付平台,并且需要世界各国政府消灭不了的账本,比特币刚好符合上述需求。
但是比特币市值几十亿美金,也是让我醉了。

人民银行可以在全国各地部署人民币链的节点机器,然后矿机就不需要采用比特币相同的竞争机制来生成区块,只要保证整个链的安全,轮换机制都可以,节约很多算力和支撑算力的电力消耗。
区块链成就的大账本这样的应用是大势所趋,但是迷信这大账本能让金融业摆脱国家的控制而游离于这个星球上所有政府之外,那也是一种狂妄的想法。你们美好的期望只是为了维护一部分人的利益而打击另外一部分人的利益,其中虽然有先进的地方,但是我们不认为你们能成就你们期望的那个样子。
区块链
2018-09-17 17:17:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
如果你是一个Phper,如果你希望学习区块链,那么本文列出的 10个开源的Php比特币项目,将有助于你了解在自己的应用中 如何加入对比特币的支持。 如果你希望快速掌握使用Php对接比特币钱包的方法,可以访问我们的 在线互动课程: 《Php比特币开发详解》 。
1. bitcoin-php
bitcoin-php 是比特币协议的Php实现,支持验证脚本的构建与解析、 分层确定性密钥、裸交易、隔离见证等诸多特性,功能极其丰富:
源代码: https://github.com/Bit-Wasp/bitcoin-php
2. minera
minera 是一个用来监控、管理比特币挖矿设备的开源系统:
源代码: https://github.com/getminera/minera
3. api-v1-client-php
api-v1-client-php 是鼎鼎大名的blockchain.info网站官方提供的Php开发库, 如果你不打算自己部署节点,可以使用它的API:
源代码: https://github.com/blockchain/api-v1-client-php
4. BitWasp
BitWasp 是一个开源的比特币电商交易市场系统,支持多重签名:
源代码: https://github.com/Bit-Wasp/BitWasp
5. bitcoin.php
bitcoin.php 是一个比特币节点旳Php访问库。
源代码: https://github.com/dryphp/bitcoin.php
6. EasyBitcoin-PHP
EasyBitcoin-PHP 是另一个封装比特币钱包RPC的类。
源代码: https://github.com/aceat64/EasyBitcoin-PHP
7. intersango
intersango 是一个Php实现的比特币交易所系统,曾经应用于 intersango.com和britcoin.co.uk:
源代码: https://github.com/dooglus/intersango
8. bitcoind-php
bitcoind-php 是对bitcoind的rpc api的底层封装,可以用来在你的php 代码中节点钱包交互。
推荐使用composer安装bitcoind-php: ~$ composer require nbobtc/bitcoind-php
源代码: https://github.com/nbobtc/bitcoind-php
9. piWallet
piWallet 是一个Php实现的数字加密货币在线钱包,可以支持各种代币
piWallet后端使用Php和MySQL,前端实现则采用了流行的Bootstrap框架。
源代码: https://github.com/johnathanmartin/piWallet
10. coinwidget
__coinwidget__让你可以在自己的网页上轻松地添加一个数字货币捐赠按钮, 目前支持比特币和莱特币:
coinwidget包含后台的php代码和前台的js代码。
源代码: https://github.com/scottycc/coinwidget.com
原文链接: 10个你应当了解的PHP比特币开源项目
区块链
2018-09-23 18:00:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
NEO C# 合约编译器原理解析
NEO合约编译过程牵涉到几个项目 neo-compiler下的neon项目负责code码转换 neo-devpack-dotnetx下的Neo.SmartContract.Framework负责公共接口定义 neo项目实现了framework中的接口
原理
c#的版本很多,从framework2.0到core2.3版本,语法差异很大,但是底层对应MSIL字节码没有变化,Neo的原理是先使用对应的编译器生成MSIL字节码,再把MSIL字节码转换成NEO vm的code码序列。这样做的好处在与利用了C#现有的语法成果,不必自己在设计一门语言,减少了合约编写的门槛。
大道不过三两行,说穿不值一文钱。下面我会通过一个完整的例子来说明这个流程,希望能藉此帮助更多人了解其中的原理细节,写出效率更好,费用更低的合约。
代码是在github上面找的, NEO-NEP5.1 是NEP5的一个token,包含常用的元素,字段,事件与函数。具有常见的数据存储,合约调用及日志信息功能。
代码生成
c# -> MSIL
源码大致结构:实现细节摘除了,需要的请点击上面的链接 using Neo.SmartContract.Framework; using Neo.SmartContract.Framework.Services.Neo; using System; using System.ComponentModel; using System.Numerics; namespace Neo.SmartContract { public class ICO_Template : Framework.SmartContract { public static string Name() => "GagaPay network token"; public static string Symbol() => "GTA"; public static readonly byte[] Owner = "Abdeg1wHpSrfjNzH5edGTabi5jdD9dvncX".ToScriptHash(); public static byte Decimals() => 8; private const ulong factor = 100000000; //decided by Decimals() private const ulong total_amount = 1000000000 * factor; //token amount [DisplayName("transfer")] public static event Action Transferred; public static Object Main(string operation, params object[] args) public static bool Deploy() public static BigInteger TotalSupply() public static BigInteger Allowance(byte[] from, byte[] to) public static bool Approve(byte[] originator, byte[] to, BigInteger amount) public static bool TransferFrom(byte[] originator, byte[] from, byte[] to, BigInteger amountToSend) public static bool Transfer(byte[] from, byte[] to, BigInteger value, bool transferFrom) public static BigInteger BalanceOf(byte[] address) } }
编译 dotnet restore dotnet publish
编译完成后使用工具查看dll的类布局,其中字段还原没有问题,多了个类构造和构造函数,还有event对应出来的两个add/remove方法,后来在转换过程中都需要清除掉的.事实上在neo中event的更多的只是起到了标识的作用。具体的MSIL CODE太多就不贴上来了,下面提到哪里就贴到哪里.如果需要完整的文件,这里推荐一个常用工具ildasm,用来查看dll的语言信息十分方便。 ___[MOD] C:
区块链
2018-08-10 23:55:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
作者:Derek
简介
Github地址: https://github.com/Bytom/bytom
Gitee地址: https://gitee.com/BytomBlockchain/bytom
本章介绍bytom代码P2P网络中addrbook地址簿 作者使用MacOS操作系统,其他平台也大同小异 Golang Version: 1.8
addrbook介绍
addrbook用于存储P2P网络中保留最近的对端节点地址 在MacOS下,默认的地址簿路径存储在~/Library/Bytom/addrbook.json
地址簿格式
** ~/Library/Bytom/addrbook.json ** { "Key": "359be6d08bc0c6e21c84bbb2", "Addrs": [ { "Addr": { "IP": "122.224.11.144", "Port": 46657 }, "Src": { "IP": "198.74.61.131", "Port": 46657 }, "Attempts": 0, "LastAttempt": "2018-05-04T12:58:23.894057702+08:00", "LastSuccess": "0001-01-01T00:00:00Z", "BucketType": 1, "Buckets": [ 181, 10 ] } ] }
地址类型
在addrbook中存储的地址有两种: ** p2p/addrbook.go ** const ( bucketTypeNew = 0x01 // 标识新地址,不可靠地址(未成功连接过)。只存储在一个bucket中 bucketTypeOld = 0x02 // 标识旧地址,可靠地址(已成功连接过)。可以存储在多个bucket中,最多为maxNewBucketsPerAddress个 )
注意: 一个地址的类型变更不在此文章中做介绍,后期的文章会讨论该问题
地址簿相关结构体
地址簿 type AddrBook struct { cmn.BaseService mtx sync.Mutex filePath string // 地址簿路径 routabilityStrict bool // 是否可路由,默认为true rand *rand.Rand key string // 地址簿标识,用于计算addrNew和addrOld的索引 ourAddrs map[string]*NetAddress // 存储本地网络地址,用于添加p2p地址时做排除使用 addrLookup map[string]*knownAddress // 存储新、旧地址集,用于查询 addrNew []map[string]*knownAddress // 存储新地址 addrOld []map[string]*knownAddress // 存储旧地址 wg sync.WaitGroup nOld int // 旧地址数量 nNew int // 新地址数量 }
已知地址 type knownAddress struct { Addr *NetAddress // 已知peer的addr Src *NetAddress // 已知peer的addr的来源addr Attempts int32 // 连接peer的重试次数 LastAttempt time.Time // 最近一次尝试连接的时间 LastSuccess time.Time // 最近一次尝试成功连接的时间 BucketType byte // 地址的类型(表示可靠地址或不可靠地址) Buckets []int // 当前addr所属的buckets }
routabilityStrict参数表示地址簿是否存储的ip是否可路由。可路由是根据RFC划分,具体参考资料: RFC标准
初始化地址簿 // NewAddrBook creates a new address book. // Use Start to begin processing asynchronous address updates. func NewAddrBook(filePath string, routabilityStrict bool) *AddrBook { am := &AddrBook{ rand: rand.New(rand.NewSource(time.Now().UnixNano())), ourAddrs: make(map[string]*NetAddress), addrLookup: make(map[string]*knownAddress), filePath: filePath, routabilityStrict: routabilityStrict, } am.init() am.BaseService = *cmn.NewBaseService(nil, "AddrBook", am) return am } // When modifying this, don't forget to update loadFromFile() func (a *AddrBook) init() { // 地址簿唯一标识 a.key = crypto.CRandHex(24) // 24/2 * 8 = 96 bits // New addr buckets, 默认为256个大小 a.addrNew = make([]map[string]*knownAddress, newBucketCount) for i := range a.addrNew { a.addrNew[i] = make(map[string]*knownAddress) } // Old addr buckets,默认为64个大小 a.addrOld = make([]map[string]*knownAddress, oldBucketCount) for i := range a.addrOld { a.addrOld[i] = make(map[string]*knownAddress) } }
bytomd启动时加载本地地址簿
loadFromFile在bytomd启动时,首先会加载本地的地址簿 // OnStart implements Service. func (a *AddrBook) OnStart() error { a.BaseService.OnStart() a.loadFromFile(a.filePath) a.wg.Add(1) go a.saveRoutine() return nil } // Returns false if file does not exist. // cmn.Panics if file is corrupt. func (a *AddrBook) loadFromFile(filePath string) bool { // If doesn't exist, do nothing. // 如果本地地址簿不存在则直接返回 _, err := os.Stat(filePath) if os.IsNotExist(err) { return false } // 加载地址簿json内容 // Load addrBookJSON{} r, err := os.Open(filePath) if err != nil { cmn.PanicCrisis(cmn.Fmt("Error opening file %s: %v", filePath, err)) } defer r.Close() aJSON := &addrBookJSON{} dec := json.NewDecoder(r) err = dec.Decode(aJSON) if err != nil { cmn.PanicCrisis(cmn.Fmt("Error reading file %s: %v", filePath, err)) } // 填充addrNew、addrOld等 // Restore all the fields... // Restore the key a.key = aJSON.Key // Restore .addrNew & .addrOld for _, ka := range aJSON.Addrs { for _, bucketIndex := range ka.Buckets { bucket := a.getBucket(ka.BucketType, bucketIndex) bucket[ka.Addr.String()] = ka } a.addrLookup[ka.Addr.String()] = ka if ka.BucketType == bucketTypeNew { a.nNew++ } else { a.nOld++ } } return true }
定时更新地址簿
bytomd会定时更新本地地址簿,默认2分钟一次 func (a *AddrBook) saveRoutine() { dumpAddressTicker := time.NewTicker(dumpAddressInterval) out: for { select { case <-dumpAddressTicker.C: a.saveToFile(a.filePath) case <-a.Quit: break out } } dumpAddressTicker.Stop() a.saveToFile(a.filePath) a.wg.Done() log.Info("Address handler done") } func (a *AddrBook) saveToFile(filePath string) { log.WithField("size", a.Size()).Info("Saving AddrBook to file") a.mtx.Lock() defer a.mtx.Unlock() // Compile Addrs addrs := []*knownAddress{} for _, ka := range a.addrLookup { addrs = append(addrs, ka) } aJSON := &addrBookJSON{ Key: a.key, Addrs: addrs, } jsonBytes, err := json.MarshalIndent(aJSON, "", "\t") if err != nil { log.WithField("err", err).Error("Failed to save AddrBook to file") return } err = cmn.WriteFileAtomic(filePath, jsonBytes, 0644) if err != nil { log.WithFields(log.Fields{ "file": filePath, "err": err, }).Error("Failed to save AddrBook to file") } }
添加新地址
当peer之间交换addr时,节点会收到对端节点已知的地址信息,这些信息会被当前节点添加到地址簿中 func (a *AddrBook) AddAddress(addr *NetAddress, src *NetAddress) { a.mtx.Lock() defer a.mtx.Unlock() log.WithFields(log.Fields{ "addr": addr, "src": src, }).Debug("Add address to book") a.addAddress(addr, src) } func (a *AddrBook) addAddress(addr, src *NetAddress) { // 验证地址是否为可路由地址 if a.routabilityStrict && !addr.Routable() { log.Error(cmn.Fmt("Cannot add non-routable address %v", addr)) return } // 验证地址是否为本地节点地址 if _, ok := a.ourAddrs[addr.String()]; ok { // Ignore our own listener address. return } // 验证地址是否存在地址集中 // 如果存在:则判断该地址是否为old可靠地址、是否超过了最大buckets中。否则根据该地址已经被ka.Buckets引用的个数来随机决定是否添加到地址集中 // 如果不存在:则添加到地址集中。并标识为bucketTypeNew地址类型 ka := a.addrLookup[addr.String()] if ka != nil { // Already old. if ka.isOld() { return } // Already in max new buckets. if len(ka.Buckets) == maxNewBucketsPerAddress { return } // The more entries we have, the less likely we are to add more. factor := int32(2 * len(ka.Buckets)) if a.rand.Int31n(factor) != 0 { return } } else { ka = newKnownAddress(addr, src) } // 找到该地址在地址集的索引位置并添加 bucket := a.calcNewBucket(addr, src) a.addToNewBucket(ka, bucket) log.Info("Added new address ", "address:", addr, " total:", a.size()) }
选择最优节点
地址簿中存储众多地址,在p2p网络中需选择最优的地址去连接 PickAddress(newBias int)函数中newBias是由pex_reactor产生的地址评分。如何计算地址分数在其他章节中再讲 根据地址评分随机选择地址可增加区块链安全性 // Pick an address to connect to with new/old bias. func (a *AddrBook) PickAddress(newBias int) *NetAddress { a.mtx.Lock() defer a.mtx.Unlock() if a.size() == 0 { return nil } // newBias地址分数限制在0-100分数之间 if newBias > 100 { newBias = 100 } if newBias < 0 { newBias = 0 } // Bias between new and old addresses. oldCorrelation := math.Sqrt(float64(a.nOld)) * (100.0 - float64(newBias)) newCorrelation := math.Sqrt(float64(a.nNew)) * float64(newBias) // 根据地址分数计算是否从addrOld或addrNew中随机选择一个地址 if (newCorrelation+oldCorrelation)*a.rand.Float64() < oldCorrelation { // pick random Old bucket. var bucket map[string]*knownAddress = nil num := 0 for len(bucket) == 0 && num < oldBucketCount { bucket = a.addrOld[a.rand.Intn(len(a.addrOld))] num++ } if num == oldBucketCount { return nil } // pick a random ka from bucket. randIndex := a.rand.Intn(len(bucket)) for _, ka := range bucket { if randIndex == 0 { return ka.Addr } randIndex-- } cmn.PanicSanity("Should not happen") } else { // pick random New bucket. var bucket map[string]*knownAddress = nil num := 0 for len(bucket) == 0 && num < newBucketCount { bucket = a.addrNew[a.rand.Intn(len(a.addrNew))] num++ } if num == newBucketCount { return nil } // pick a random ka from bucket. randIndex := a.rand.Intn(len(bucket)) for _, ka := range bucket { if randIndex == 0 { return ka.Addr } randIndex-- } cmn.PanicSanity("Should not happen") } return nil }
移除一个地址
当一个地址被标记为Bad时则从地址集中移除。目前bytomd的代码版本并未调用过 func (a *AddrBook) MarkBad(addr *NetAddress) { a.RemoveAddress(addr) } // RemoveAddress removes the address from the book. func (a *AddrBook) RemoveAddress(addr *NetAddress) { a.mtx.Lock() defer a.mtx.Unlock() ka := a.addrLookup[addr.String()] if ka == nil { return } log.WithField("addr", addr).Info("Remove address from book") a.removeFromAllBuckets(ka) } func (a *AddrBook) removeFromAllBuckets(ka *knownAddress) { for _, bucketIdx := range ka.Buckets { bucket := a.getBucket(ka.BucketType, bucketIdx) delete(bucket, ka.Addr.String()) } ka.Buckets = nil if ka.BucketType == bucketTypeNew { a.nNew-- } else { a.nOld-- } delete(a.addrLookup, ka.Addr.String()) }
区块链
2018-08-24 10:26:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
你想了解如何写智能合约,但有非常有限的技术知识?你想了解如何编写智能合约来为你的ICO发布数字货币吗?这里有一个关于如何着手的完整指南。
ICO,或上线数字货币是新的热潮。区块链技术提供了一种独特的方式,鼓励早期采用者参与项目,并通过发布数字货币来获得初始资金。不必害怕在这个领域使用的新术语。下面是一个关于ICO是什么的综合指南,以及如何能够学习更多的关于这些ICO的智能合约。让我们开始吧!
ICO到底是什么?
上线数字货币,通常被称为ICO,是一种筹资机制,其中新项目出售其数字加密货币,以交换比特币和以太币。一个加密数字币,或一个代币,一般只是一个术语,表示一个项目或公司发布的价值单位。这个价值单位可以用来奖励参与项目并执行特定行动的用户,或者它可以作为在网络上获得特定服务的交易费用。例如,以太坊网络使用以太币(ETH)作为数字货币,用于在网络中执行计算。
这些数字货币可以通过美元来购买,或者兑换美元等法定货币来获得,也可以通过在网络上执行特定服务(如挖矿)赚取。这些数字货币的优点在于它们的价格也基于对这些数字货币的需求而升值和贬值。这种行为类似于公司的股票,这反映了公司的部分所有权。数字货币既反映了在网络中用于支付服务的货币,也反映了该数字货币网络中的公平性。
随着数字货币的网络效应增加,其在定价中增值。确定数字货币是否对你的项目有意义的第一步取决于你的项目的目标是什么,并且有一种方法可以“货币化”。正如上面所讨论的,数字货币不仅仅是网络中使用的货币,而且是建立在网络上的业务模型的一个单位。
数字货币对你的项目有意义吗?
如果数字货币对项目有意义,所讨论的项目应该具有以下属性: 网络中的令牌应该具有实用价值。例如,以太坊平台的数字货币是以太币,它是被用作支付在区块链中执行的任何计算的交易费用的货币。 玩家购买数字货币应该有经济上的诱因,数字货币发行机制应该以这样的方式设计,即随着数字货币的使用,它们的价值应该增加。例如,Filecoin是用于在去中心化的硬盘网络中存储文件的IPFS的数字货币。随着越来越多的用户想要以分布式的方式存储文件,他们将需要Filecoin。一般来说,这些数字货币预先定义货币供应将如何随时间演变。这些策略是这样设计的,其中令牌的价值随着网络提供的服务被更多地使用而增加。
ERC20是一个数字货币的标准,这使得我们很容易发布新的加密数字货币。它基于以太坊并描述了以太坊数字货币合约必须实现的功能和事件。但是在我们开始学习如何为自己的项目发放代币之前,我们必须理解什么是“智能合约”。这是本篇文章的主题之一。
什么是智能合约?
智能合约是计算机程序,允许基于预先指定的条件在各方之间自动转移数字资产。智能合约主要用于加密数字货币的交互。最突出的智能合约实现是以太坊区块链平台,它也将其称为去中心化应用程序,或DApp。
传统上,我们习惯于集中托管应用程序。虽然应用程序的代码可以分布在多个物理服务器上,但它们由单个实体控制。例如,facebook是一个集中式应用程序,它由一个叫做facebook公司的实体控制,而去中心化的应用程序不是由一个中心实体控制的,而是由代码和在其中设置的协议来控制的。这些代码通常是开源的,任何人都可以使用它们来创建一个自己的新DAPP。一些已经成功的基于以太坊的DApp是Golem, Augur和Melonport。这些DAPPS已经能够在市场上达到数百万美元的价值。
智能合约开发平台比较
虽然以太坊是最流行的开发智能合约的平台,但它不是唯一的一个。下面是一些用于编写智能合约的其他平台: Script in Bitcoin ,脚本处理文档的能力有限。Bitcoin具有非图灵完备的脚本语言,允许在指定条件下可以兑换。脚本语言是相当有限的,因为它只具有一些基本的算术、逻辑和密码操作(例如hash和验证数字签名)。 Automated Transactions 是另一个图灵完备的智能合约语言,用于像Burstcoin和Qora之类的加密数字货币。它的一个应用例子是原子交叉链交易。原子交叉链交易使交易双方拥有不同的数字加密货币,直接进行交换而不需要第三个受信任方。 NXT :NXT是一个公共的区块链平台,包含智能合约的模板选择有限。你必须使用给定的模版,你不能编写你自己的代码。 Chain 使用Java、Ruby和Node.js提供了带有SDK的企业级区块链基础设施。
智能合约的局限性
智能合约仍处于发展阶段,不能完全取代所有形式的合约。它们对于能够客观定义并完全在数字领域中的术语更有效。更具体地说: 智能合约不应该对外部Web服务、API或外部数据库进行调用。这可能导致相同智能合约代码的多个独立执行产生不同结果。这可能破坏区块链的共识。Oracles,将现实世界中的数据更新到区块链,是解决这个问题的一种方法。 智能合约只能解决事实上可以客观决定的问题。这种约束使得智能合约对法律合约的价值较低,在没有客观事实的情况下靠双方当事人的主观判断容易出现纠纷。 智能合约的最重要的限制是,(目前)它被用于基于 if a, then b 或类似变化模式的简单合约模型。在我国现行的法律用语中,“无不当延误”和“超出合理怀疑”等合约中的主观方面的考虑是很难的。
虽然这些限制目前存在,但团队正在努力使这些智能合约更加智能化。随着物联网的出现,更容易传递实时、真实世界的数据,这些数据可以通过oracles保存在区块链上。许多像Oraclize这样的区块链服务已经启动,将真实世界的数据推到了区块链链中。即使是简单的 if a, then b 的智能合约,也有很多情况下会被破坏。
编写和部署智能合约的工具 Infura:Infura提供了可扩展的区块链基础架构,可以满足运行完整的以太坊节点的需求,并允许开发者专注于它们的代码。它受到开发者社区的欢迎。 Mist Browser:它是浏览和使用DAPPS的工具。它是一个单独的浏览器,可以用来浏览DAPPS并与它们进行交互。 Truffle Framework:Truffle是一种流行的以太坊开发框架。它具有内置的智能合约编译、链接、部署和二进制管理,极大地简化了区块链开发人员的工作。 Metamask:是一个允许人们在浏览器中访问去中心化网络的桥梁。它允许用户在浏览器中运行以太坊DApp,而不需要运行完整的以太坊节点。它是一个浏览器插件,允许用户通过正规网站进行以太坊交易。截至2017年9月,Metamask只能作为一个插件在Chrome浏览器中使用。 Remix:是一个基于Web浏览器的IDE,它允许用户编写Solidity的智能合约,然后部署和运行智能合约。
编写智能合约的语言
两个主要用来写智能合约的语言是Serpent和Solidity。Serpent是一种古老的语言,它在2017年9月就已经过时了。Solidity,它是一种基于JavaScript的语言,现在已经成为编写智能合约的推荐语言。近年来,Serpent也发现了安全漏洞,目前这基本是一个没有吸引力的开发平台了。这些语言的一些关键特征是: solidity:是一种面向合约的高级语言,其语法类似于JavaScript,它的设计目的是完成以太虚拟机(EVM)开发。 Serpent:是一种高级语言,用来写合约。它与Python非常相似,但到了2017年9月,solidity是以太坊开发者的首选语言。
即将到来的智能合约语言
solidity是目前最流行的智能合约语言。有一些即将到来的智能合约语言可能在未来变得重要: Viper:侧重于安全性、语言和编译器的简单性。它有一个类似Python的缩进方案。 Lisk:使用JavaScript作为一种智能合约语言。 Chain:提供了企业级区块链基础设施,并采用了流行的语言,如Ruby、Java和Nodejs。
智能合约实例
让我们来看看一个在Solidity写的例子。solidity是发展智能合约最流行的语言。下面的合约是一个关于如何创建新的数字货币的例子。新数字货币可以凭空挖掘出来,但只能由创建合约的用户使用。这个合约也可以用来进行数字货币的转账即从一个地址发送到另一个地址。 pragma solidity ^0.4.0; contract Coin { address public minter; mapping (address =&amp;gt; uint) public balances; event Sent(address from, address to, uint amount); function Coin() { minter = msg.sender; } function mint(address receiver, uint amount) { if (msg.sender != minter) return; balances[receiver] += amount; } function send(address receiver, uint amount) { if (balances[msg.sender] &amp;lt; amount) return; balances[msg.sender] -= amount; balances[receiver] += amount; Sent(msg.sender, receiver, amount); } }
上面的智能合约显示了它如何被用来铸币并将其转入特定的地址。我们来分析下这段代码。 address public minter;
定义公共可访问的地址变量。地址类型是一个160位变量,用于存储在以太网网络上的地址。 mapping (address =&amp;amp;gt; uint) public balances;
创建地址和单位类型之间的映射,存储每个地址中的数字货币余额。你可以把它看作是记录每个地址有多少数字货币的分类帐。 function Coin() { minter = msg.sender; }
这个函数是一个构造函数,它一旦部署就被执行。这将minter的值设置为已部署合约的地址。这确保了只能合约的所有者铸造新的数字货币,而其他人不行。这可以通过以下功能来保证: function mint(address receiver, uint amount)
只有当minter调用该函数时,才会执行该函数。该功能将数字货币值等于接收地址。如果它是由minter以外的人调用的,那么这个函数什么也不做。 function send(address receiver, uint amount)
这个函数从调用函数的地址向接收方的地址发送一个数字货币。例如,如果Bob用Alice的地址调用这个函数,并且金额是1000,那么1000个硬币将从Bob的帐户转移到Alice的帐户。
在以太坊区块链中部署智能合约
一旦编写了一个合约,就需要通过实际部署它来测试它,并测试它是否像预期一样运行。这就是需要testnets的原因。
什么是测试网?
testnets模拟以太坊网络和EVM。它们使开发人员能够在不支付gas成本的情况下上传和与智能合约进行交互。
智能合约必须为他们的计算支付在以太网络的gas。如果你想在以太坊网络上运行一个智能合约,你需要支付“gas”来完成交易。然而,testnets为开发者提供了测试他们的合约而不支付任何费用的环境。testnets的gas可从许多公共区域免费提供。
什么是Etherscan和我如何浏览智能合约?
Etherscan是区块链的资源管理器。区块链浏览器基本上是一种搜索引擎,允许用户轻松查找、确认和验证在以太坊区块链上发生的交易。使用 这个链接 可以在Etherscan中验证智能合约。
使用智能合约的很少模板开始
为了让你开始使用智能合约,你可以在查看下面的模板。以太坊和solidity文档有简单的合约让你开始。一旦实现了这些,就可以查看IBM提供的更高级的模板。IBM智能合约模板展示了如何使用IoT设备的输出来控制智能合约。Mahesh的以太坊DAPP教程给出了一个关于如何在以太坊上实现和部署投票DAPP的开始到结束的示例。 Ethereum smart contract example Solidity documentation IBM Watson IOT smart contract Samples Ethereum dApp tutorial by Mahesh Murthy
自从发布数字货币成为一种越来越流行的方式,通过你的产品和产生用户参与来赚钱,智能合约变得越来越重要。了解智能合约和学习如何写一个将使你能够发出数字货币,并把你的项目带到你一直梦想的地方。祝你一切顺利!
推荐给大家我们的以太坊教程: 以太坊教程 ,主要介绍智能合约与dapp应用开发,适合入门。 以太坊开发 ,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。 web3j教程 ,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。 python以太坊 ,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。 php以太坊 ,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和事件等内容。 C#以太坊 ,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和事件等。
这里是 原文
区块链
2018-08-22 11:02:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
一、前言:
任何共识机制都必须回答包括但不限于如下的问题: 下一个添加到数据库的新区块应该由谁来生成? 下一个块应该何时产生? 该区块应包含哪些交易? 怎样对本协议进行修改? 该如何解决交易历史的竞争问题?
二、功能描述:
每一个持有比特股的人按照持股比例进行对候选受托人的投票;从中选取投票数最多的前21位代表(也可以是其他数字,具体由区块链项目方决定) 成为权力完全相等的21个超级节点(真正:受托人/见证人);通过每隔3秒轮询方式产出区块;而其他候选受托人无权产出区块;
1、持股人:比特股持有所有人;每个账户按照持币数给证人投票;可以随时更换投票;也可以不投;但投只能投赞成票;
2、见证人(受托人/代表,类似比特币的矿工):
注册成为候选受托人需要支付一笔保证金,这笔保证金就是为了防止节点出现作恶的情况,一般来说,如果成为受托人,也就成为超级节点进行挖矿,超级节点需要大概两周的时间才能达到损益平衡,这就促使超级节点至少挖满两周不作恶。
3、选定代表(实现步骤中未考虑实现它)
代表也是通过类似选举证人的方式选举出来。 创始账户(the genesis account)有权对网络参数提出修改,而代表就是该特殊账户的共同签署者。这些参数包括交易费用,区块大小,证人工资和区块间隔等。 在大多数代表批准了提议的变更后,股东有2周的复审期(review period),在此期间他们可以投票踢出代表并作废被提议的变更。
4.出块规则:每隔3秒轮询受托人;并且每个证人会轮流地在固定的预先计划好的2秒内生产一个区块。 当所有证人轮完之后,将被洗牌。 如果某个证人没有在他自己的时间段内生产一个区块,那么该时间段将被跳过,下一个证人继续产生下一个区块。每当证人生产一个区块时,他们都会获取相应的服务费。 证人的薪酬水平由股东选出的代表(delegate)来制定。 如果某个证人没有生产出区块,那么就不会给他支付薪酬,并可能在未来被投票踢出。
5.算法主要包含两个核心部分:块验证人选举和块验证人调度
(1)第一批块验证人由创世块指定,后续每个周期(周期由具体实现定义)都会在周期开始的第一个块重新选举。验证人选举过程如下: 踢掉上个周期出块不足的验证人 统计截止选举块(每个周期的第一块)产生时候选人的票数,选出票数最高的前 N 个作为验证人 随机打乱验证人出块顺序,验证人根据随机后的结果顺序出块
(2)验证人调度根据选举结果进行出块,其他节点根据选举结果验证出块顺序和选举结果是否一致,不一致则认为此块不合法,直接丢弃。
三、以太坊DPOS共识机制源码分析
1、启动入口:
以太坊入口调试脚本:
以太坊项目的启动:main.go中的init()函数-->调用geth方法-->调用startNode-->backend.go中的函数StartMining-->miner.go中的start函数 func init() { // Initialize the CLI app and start Geth app.Action = geth } func geth(ctx *cli.Context) error { //根据上下文配置信息获取全量节点并将该节点注册到以太坊服务 //makeFullNode函数-->flags.go中函数RegisterEthService中-->eth.New-->handler.go中NewProtocolManager-->InsertChain内进行dpos的区块信息校验 node := makeFullNode(ctx) //启动节点 startNode(ctx, node) node.Wait() return nil }
启动节点说明 func startNode(ctx *cli.Context, stack *node.Node) { //启动当前节点:utils.StartNode(stack) //解锁注册钱包事件并自动派生钱包 //监听钱包事件 if ctx.GlobalBool(utils.MiningEnabledFlag.Name) { //判断是否全量节点,只有全量节点才有 挖矿 权利: var ethereum *eth.Ethereum if err := stack.Service(ðereum); err != nil { utils.Fatalf("ethereum service not running: %v", err) } //设置gas价格 ethereum.TxPool().SetGasPrice(utils.GlobalBig(ctx, utils.GasPriceFlag.Name)) //验证是否当前出块受托人:validator, err := s.Validator() ,启动服务打包区块 if err := ethereum.StartMining(true); err != nil { utils.Fatalf("Failed to start mining: %v", err) } } }
上面StartMining方法会调用miner.go中的start函数,调用启动函数之前已经启动全量节点,并进行相关初始化工作(具体初始化内容如下); func (self *Miner) Start(coinbase common.Address) { atomic.StoreInt32(&self.shouldStart, 1) self.worker.setCoinbase(coinbase) self.coinbase = coinbase if atomic.LoadInt32(&self.canStart) == 0 { log.Info("Network syncing, will start miner afterwards") return } atomic.StoreInt32(&self.mining, 1) log.Info("Starting mining operation") //获取当前节点地址,启动服务 self.worker.start() }
worker.go的start函数调用mintLoop函数 func (self *worker) mintLoop() { ticker := time.NewTicker(time.Second).C //for循环不断监听self信号,当监测到self停止时,则调用关闭操作代码,并直接挑出循环监听,函数退出。 for { select { case now := <-ticker: self.mintBlock(now.Unix())//打包块 case <-self.stopper: close(self.quitCh) self.quitCh = make(chan struct{}, 1) self.stopper = make(chan struct{}, 1) return } } }
2.相关角色说明
dpos_context.go type DposContext struct { epochTrie *trie.Trie //记录每个周期的验证人列表 delegateTrie *trie.Trie //记录验证人以及对应投票人的列表 voteTrie *trie.Trie //记录投票人对应验证人 candidateTrie *trie.Trie //记录候选人列表 mintCntTrie *trie.Trie //记录验证人在周期内的出块数目 db ethdb.Database }
以太坊MPT(Trie树, Patricia Trie, 和Merkle树)树形结构存储,并定期同步[k,v]型底层数据库是LevelDB数据库
3.相关交易类型说明
以太坊DPOS共识算法中,将"成为候选人"、"退出候选人"、"投票(授权)"、"取消投票(取消授权)"等操作均定义为以太坊的一种交易类型
transaction.go const (//交易类型 Binary TxType = iota //之前的交易主要是转账或者合约调用 LoginCandidate //成为候选人 LogoutCandidate //退出候选人 Delegate //投票(授权) UnDelegate //取消投票(取消授权) )
在一个新块打包时会执行所有块内的交易,如果发现交易类型不是之前的转账或者合约调用类型,那么会调用 applyDposMessage 进行处理
在worker.go的createNewWork()-->commitTransactions函数-->commitTransaction函数-->调用state_processor.go中的ApplyTransaction函数-->applyDposMessage func ApplyTransaction(config *params.ChainConfig, dposContext *types.DposContext, bc *BlockChain, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *big.Int, cfg vm.Config) (*types.Receipt, *big.Int, error) { msg, err := tx.AsMessage(types.MakeSigner(config, header.Number)) if err != nil { return nil, nil, err } if msg.To() == nil && msg.Type() != types.Binary { return nil, nil, types.ErrInvalidType } // 创建EVM环境的上下文 context := NewEVMContext(msg, header, bc, author) // Create a new environment which holds all relevant information // 创建EVM虚拟机处理交易及智能合约 vmenv := vm.NewEVM(context, statedb, config, cfg) // Apply the transaction to the current state (included in the env) _, gas, failed, err := ApplyMessage(vmenv, msg, gp) if err != nil { return nil, nil, err } if msg.Type() != types.Binary { //如果是非转账或者合约调用类型交易 if err = applyDposMessage(dposContext, msg); err != nil { return nil, nil, err } } } func applyDposMessage(dposContext *types.DposContext, msg types.Message) error { switch msg.Type() { case types.LoginCandidate://成为候选人 dposContext.BecomeCandidate(msg.From()) case types.LogoutCandidate://取消候选人 dposContext.KickoutCandidate(msg.From()) case types.Delegate://投票 //投票之前需要先检查该账号是否候选人;如果投票人之前已经给其他人投过票则先取消之前投票,再进行投票 dposContext.Delegate(msg.From(), *(msg.To())) case types.UnDelegate://取消投票 dposContext.UnDelegate(msg.From(), *(msg.To())) default: return types.ErrInvalidType } return nil }
4.打包出块过程
worker.go func (self *worker) mintBlock(now int64) { engine, ok := self.engine.(*dpos.Dpos) if !ok { log.Error("Only the dpos engine was allowed") return } //矿工会定时(每隔3秒)检查当前的 validator 是否为当前节点,如果是则说明轮询到自己出块了; err := engine.CheckValidator(self.chain.CurrentBlock(), now) if err != nil { switch err { case dpos.ErrWaitForPrevBlock, dpos.ErrMintFutureBlock, dpos.ErrInvalidBlockValidator, dpos.ErrInvalidMintBlockTime: log.Debug("Failed to mint the block, while ", "err", err) default: log.Error("Failed to mint the block", "err", err) } return } //创建一个新的打块任务 work, err := self.createNewWork() if err != nil { log.Error("Failed to create the new work", "err", err) return } //Seal 会对新块进行签名 result, err := self.engine.Seal(self.chain, work.Block, self.quitCh) if err != nil { log.Error("Failed to seal the block", "err", err) return } //将新块广播到邻近的节点,其他节点接收到新块会根据块的签名以及选举结果来看新块是否应该由该验证人来出块 self.recv <- &Result{work, result} } func (self *worker) createNewWork() (*Work, error) { //...... num := parent.Number() header := &types.Header{ ParentHash: parent.Hash(), Number: num.Add(num, common.Big1), GasLimit: core.CalcGasLimit(parent), GasUsed: new(big.Int), Extra: self.extra, Time: big.NewInt(tstamp), } // 仅在挖掘时设置coinbase(避免伪块奖励) if atomic.LoadInt32(&self.mining) == 1 { header.Coinbase = self.coinbase } //初始化块头基础信息 if err := self.engine.Prepare(self.chain, header); err != nil { return nil, fmt.Errorf("got error when preparing header, err: %s", err) } //主要是从 transaction pool 按照 gas price 将交易打包到块中 txs := types.NewTransactionsByPriceAndNonce(self.current.signer, pending) work.commitTransactions(self.mux, txs, self.chain, self.coinbase) // 打包区块 var ( uncles []*types.Header badUncles []common.Hash ) for hash, uncle := range self.possibleUncles { if len(uncles) == 2 { break } if err := self.commitUncle(work, uncle.Header()); err != nil { log.Trace("Bad uncle found and will be removed", "hash", hash) log.Trace(fmt.Sprint(uncle)) badUncles = append(badUncles, hash) } else { log.Debug("Committing new uncle to block", "hash", hash) uncles = append(uncles, uncle.Header()) } } for _, hash := range badUncles { delete(self.possibleUncles, hash) } // 将 prepare 和 CommitNewWork 内容打包成新块,同时里面还有包含出块奖励、选举、更新打块计数等功能 if work.Block, err = self.engine.Finalize(self.chain, header, work.state, work.txs, uncles, work.receipts, work.dposContext); err != nil { return nil, fmt.Errorf("got error when finalize block for sealing, err: %s", err) } work.Block.DposContext = work.dposContext return work, nil }
疑问:
(1).这里面没看到跟pow一样的工作量难度证明的哈希函数计算,即当有出块权益时,打包验证好交易后是否直接打包,那如何会出现规定时间打包失败的情况呢?是否是只有类似断网或网络不好时会出现?
(2).Seal会对新块进行封装签名;在pow算法中seal是核心是计算工作量得出随机符合条件hash,而在dpos共识中seal是否只做了封装签名操作?从源码中看是这样
5.选举分析
(1)选举实现步骤: 根据上个周期出块的情况把一些被选上但出块数达不到要求的候选人踢掉 截止到上一块为止,选出票数最高的前 N 个候选人作为验证人 打乱验证人顺序
当调用dpos.go中Finalize函数打包新块时 func (d *Dpos) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, dposContext *types.DposContext) (*types.Block, error) { // 累积块奖励并提交最终状态根 AccumulateRewards(chain.Config(), state, header, uncles) header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) parent := chain.GetHeaderByHash(header.ParentHash) epochContext := &EpochContext{ statedb: state, DposContext: dposContext, TimeStamp: header.Time.Int64(), } if timeOfFirstBlock == 0 { if firstBlockHeader := chain.GetHeaderByNumber(1); firstBlockHeader != nil { timeOfFirstBlock = firstBlockHeader.Time.Int64() } } genesis := chain.GetHeaderByNumber(0) //打包每个块之前调用 tryElect 来看看当前块是否是新周期的第一块,如果是第一块则需要触发选举。 err := epochContext.tryElect(genesis, parent) if err != nil { return nil, fmt.Errorf("got error when elect next epoch, err: %s", err) } //更新验证人在周期内的出块数目 updateMintCnt(parent.Time.Int64(), header.Time.Int64(), header.Validator, dposContext) header.DposContext = dposContext.ToProto() return types.NewBlock(header, txs, uncles, receipts), nil }
epoch_context.go中的tryElect选举函数 func (ec *EpochContext) tryElect(genesis, parent *types.Header) error { genesisEpoch := genesis.Time.Int64() / epochInterval prevEpoch := parent.Time.Int64() / epochInterval currentEpoch := ec.TimeStamp / epochInterval prevEpochIsGenesis := prevEpoch == genesisEpoch if prevEpochIsGenesis && prevEpoch < currentEpoch { prevEpoch = currentEpoch - 1 } prevEpochBytes := make([]byte, 8) binary.BigEndian.PutUint64(prevEpochBytes, uint64(prevEpoch)) iter := trie.NewIterator(ec.DposContext.MintCntTrie().PrefixIterator(prevEpochBytes)) //根据当前块和上一块的时间计算当前块和上一块是否属于同一周期,如果是同一周期,意味着当前块不是周期第一块,不需要触发选举;如果不是同一周期,说明当前块是该周期的第一块,则触发选举 for i := prevEpoch; i < currentEpoch; i++ { // 如果前一个周期不是创世周期,触发踢出候选人规则; if !prevEpochIsGenesis && iter.Next() { //踢出规则主要看上一周期是否存在候选人出块少于特定阈值(50%),如果存在则踢出:if cnt < epochDuration/blockInterval/ maxValidatorSize /2 { if err := ec.kickoutValidator(prevEpoch); err != nil { return err } } //对候选人进行计票 votes, err := ec.countVotes() if err != nil { return err } candidates := sortableAddresses{} for candidate, cnt := range votes { candidates = append(candidates, &sortableAddress{candidate, cnt}) } if len(candidates) < safeSize { return errors.New("too few candidates") } //将候选人按照票数由高到低排序 sort.Sort(candidates) if len(candidates) > maxValidatorSize {//如果候选人大于预定受托人数量常量maxValidatorSize,则选出前maxValidatorSize个为受托人 candidates = candidates[:maxValidatorSize] } // 重排受托人,由于使用seed是由父块的hash以及当前周期编号组成,所以每个节点计算出来的受托人列表也会一致; seed := int64(binary.LittleEndian.Uint32(crypto.Keccak512(parent.Hash().Bytes()))) + i r := rand.New(rand.NewSource(seed)) for i := len(candidates) - 1; i > 0; i-- { j := int(r.Int31n(int32(i + 1))) candidates[i], candidates[j] = candidates[j], candidates[i] } sortedValidators := make([]common.Address, 0) for _, candidate := range candidates { sortedValidators = append(sortedValidators, candidate.address) } //保存受托人列表 epochTrie, _ := types.NewEpochTrie(common.Hash{}, ec.DposContext.DB()) ec.DposContext.SetEpoch(epochTrie) ec.DposContext.SetValidators(sortedValidators) log.Info("Come to new epoch", "prevEpoch", i, "nextEpoch", i+1) } return nil }
(2)计票实现 先找出候选人对应投票人的列表 所有投票人的余额作为票数累积到候选人的总票数中
计票实现函数是epoch_context.go中的tryElect选举函数中的countVotes函数 func (ec *EpochContext) countVotes() (votes map[common.Address]*big.Int, err error) { votes = map[common.Address]*big.Int{} delegateTrie := ec.DposContext.DelegateTrie()//记录验证人以及对应投票人的列表 candidateTrie := ec.DposContext.CandidateTrie()//获取候选人列表 statedb := ec.statedb iterCandidate := trie.NewIterator(candidateTrie.NodeIterator(nil)) existCandidate := iterCandidate.Next() if !existCandidate { return votes, errors.New("no candidates") } //遍历候选人列表 for existCandidate { candidate := iterCandidate.Value candidateAddr := common.BytesToAddress(candidate) delegateIterator := trie.NewIterator(delegateTrie.PrefixIterator(candidate)) existDelegator := delegateIterator.Next() if !existDelegator { votes[candidateAddr] = new(big.Int) existCandidate = iterCandidate.Next() continue } //遍历后续人对应的投票人列表 for existDelegator { delegator := delegateIterator.Value score, ok := votes[candidateAddr] if !ok { score = new(big.Int) } delegatorAddr := common.BytesToAddress(delegator) //获取投票人的余额作为票数累积到候选人的票数中 weight := statedb.GetBalance(delegatorAddr) score.Add(score, weight) votes[candidateAddr] = score existDelegator = delegateIterator.Next() } existCandidate = iterCandidate.Next() } return votes, nil }

区块链
2018-08-19 22:08:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
本文首发于 深入浅出区块链社区 原文链接: 程序员如何切入区块链去中心化应用开发 原文已更新,请读者前往原文阅读
前段时间一个以太坊游戏应用: Fomo3D 异常火爆,在短短的几天内就吸引了几万的以太币投入游戏,第一轮游戏一个“黑客”用了一个非常巧妙的利用以太坊规则成为了最终赢家,拿走了1万多以太币奖金。
区块链应用的价值由这个游戏反映的淋漓尽致,Fomo3D游戏能够成功核心所依赖的是以太坊提供的一个可信、不可篡改平台。当游戏的规则确定之后,一切都按规则运行,无人可干预。今天这篇就来介绍一下程序员如何切入去中心化应用开发。
中心化应用
作为对比,先来看看中心化应用,其实就是现有的互联网应用,为什么它是中心化应用,看看它的架构图:
平时我们接触的是应用的前端(或称客户端),前端可以是HTML5的web页面、 小程序、APP, 在前端展现的内容通常发送一个请求到服务器,服务器返回相应的内容给前端。在前端的动作同样也会转化请求发送到服务器,服务器处理之后返回数据到前端。也就是说我们所有看到的内容或者操作都是中心化的服务器控制,因此说是中心化应用。
去中心化应用DAPP
而去中心化应用有什么不同呢? 看看它的架构图: 前端的表现上是一样的, 还是H5页面、 小程序、APP,DAPP和传统App关键是后端部分不同,是后端不再是一个中心化的服务器,而是分布式网络上任意节点,注意可以是 任意一个节点 ,在应用中给节点发送的请求通常称为 交易 ,交易和中心化下的请求有几个很大的不同是:交易的数据经过用户个人签名之后发送到节点,节点收到交易请求之后,会把 请求广播到整个网络 ,交易在网络达成共识之后,才算是真正的执行(真正其作用的执行不一是连接的后端节点,尽管后端也会执行)。以及中心化下的请求大多数都是同步的(及时拿到结果), 而交易大多数是异步的,这也是在开发去中心应用时需要注意的地方,
从节点上获得数据状态(比如交易的结果),一般是通过事件回调来获得。
如何开发
在开发中心化应用最重要两部分是 客户端UI表现 和 后端服务程序 , UI表现通过HTTP请求连接到后端服务程序,后端服务程序运行在服务器上,比如Nginx Apached等等。
开发一个去中心化应用最重要也是两部分: 客户端UI表现 及 智能合约 ,智能合约的作用就像后端服务程序,智能合约是运行在节点的EVM上, 客户端调用智能合约,是通过向节点发起RPC请求完成。
下面是一个对比: 客户端UI <=> 客户端UI HTTP <=> RPC 后端服务程序 <=> 智能合约 Nginx/Apache <=> 节点
因此对于去中心化应用来说,程序员可以从两个方面切入:
一个是 去中心化应用的客户端开发 , 熟悉已经熟悉客户端软件(如Web\APP等)开发的同学,只需要了解一下客户端跟区块链节点通信的API接口,如果是在当前应用最广泛的区块链平台以太坊上开发去中心化应用,那么需要了解Web3 这个库,Web3对节点暴露出来的JSON-RPC接口进行了封装,比如Web3提供的功能有:获取节点状态,获取账号信息,调用合约、监听合约事件等等。
目前的主流语言都有Web3的实现,列举一些实现给大家参考: JavaScript Web3.js Python Web3.py Haskell hs-web3 Java web3j Scala web3j-scala Purescript purescript-web3 PHP web3.php PHP ethereum-php
另一个切入点是 智能合约的开发 ,在以太坊现在推荐的语言是Solidity,有一些同学对新学一门语言有一些畏惧,Solidity的语法其实很简洁,有过一两门其他语言基础(开发经验)的同学三五天就可以学会,我也录制了一个视频课程: 深入详解以太坊智能合约语言Solidity 。
下面用一个Hello合约,体会下Solidity的语法: contract Hello { function hello() public returns(string) { return "Hello World"; } }
如果把上面的contract关键字更改为class,就和其他语言定义一个类一样。
有兴趣的同学可以进一步学习一下这个DApp开发案例 Web3与智能合约交互实战 ,
在DAPP的开发过程中,一些开发工具可以帮助我们事半功倍,如:Truffle开发框架以及Ganache工具来模拟节点等,这篇文章 一步步教你开发、部署第一个去中心化应用
补充
对于想切入到去中心化应用开发的同学,对区块链运行的原理了解肯定会是加分项,尤其是各类共识机制( POW ,POS,DPOS等)的理解,P2P网络的理解,以及各类加密和Hash算法的运用。有一些同学想做区块链底层开发,对区块链运行的原理则是必须项。
欢迎来 知识星球 提问,星球内已经聚集了300多位区块链技术爱好者。 深入浅出区块链 - 系统学习区块链,打造最好的区块链技术博客。
区块链
2018-09-05 15:52:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
简介
对于复杂类型例如array,struct都有一个都有一个额外的注解(annotation),可能是storage,memory,calldata之一。根据上下文总是有一个默认的注解类型。但是一般可以通过storage和memory关键字显示的修改。
对于函数的出参和入参一般默认的是memory类型(external 函数的入参例外是强制的calldata类型)
对于局部变量默认的是storage类型(可以通过memory修改)
对于状态变量强制的是storage类型(不能通过memory修改)
关于Data Location
storage
会写入区块链中
memory
不会持久化(不会写入到区块链中)
calldata
不可修改,不可持久化
关于局部变量和状态变量 pragma solidity ^0.4.18; contract DL{ uint [] stateVariable;//状态变量(state variable) function normal(uint [] inArg) public returns(uint outArg){ uint [] localVar;//局部变量(本地变量,local variable) return 0; } function cd(uint [] inArg) external returns(uint outArg){ return 0; } }
上面代码的stateVariable就是状态变量,inArg就是入参,outArg就是出参
stateVariable的data location就是storage
localVar是局部变量,data location是memory
函数normal的inArg的data location是memory outArg也是memory
函数cd的inArg的data location是calldata outArg是memory
总结
强制的 data location: external 函数的入参: calldata 状态变量:storage
默认的 data location: 一般函数的入参和出参(返回参数):memory 所有局部变量:storage
storage与memory之间的赋值 public的函数的入参的data location不能是storage function storaegPara(Person storage allen) public returns(uint8 age,string name){ person = allen; return (person.age,person.name); }
像上面这种就会出编译错误。 局部变量的memory不能赋值给局部变量的storage,但是可以赋值给状态变量的storage pragma solidity ^0.4.18; contract DL{ struct Person{ uint8 age; string name; } Person person = Person({age:20,name:"tim"});//状态变量,强制storage(state variable) function storaegPara(Person storage allen) internal returns(uint8 age,string name){ person = allen; return (person.age,person.name); } function testStoraegPara() returns(uint8 age,string name){ Person allen = Person({age:22,name:"allen"}); return storaegPara(allen); } }
像上面的就会编译错误。从前面我们知道: Person allen = Person({age:22,name:"allen"});
等价于: Person memory allen = Person({age:22,name:"allen"});
当调用storaegPara(allen)的时候,相当于把一个memory的局部allen变量赋值给一个storage的局部变量allen。
这是因为storage是静态分配存储空间的,对于storage的赋值,更像是对指针的赋值。 pragma solidity ^0.4.18; contract DL{ struct Person{ uint8 age; string name; } Person person = Person({age:20,name:"tim"});//状态变量,强制storage(state variable) function storaegPara(Person memory allen) internal returns(uint8 age,string name){ person = allen; return (person.age,person.name); } function testStoraegPara() returns(uint8 age,string name){ Person memory allen = Person({age:22,name:"allen"}); return storaegPara(allen); } } storage可以对memory进行赋值,执行的是拷贝操作。(修改新的memory变量不会影响原来storage变量) memory对memory的赋值是引用
memory和storage赋值总结 同类赋值(memory对memory,storage对storage)是引用,相当于指针不会执行数据拷贝。 memory和storage相互赋值,执行的是数据拷贝,但是注意 memory不能对局部storage赋值
memory和storage 数组 对于变长数组必须使用new初始化之后才能访问 new 产生的是memory类型的,不能转换为局部的storage,所以可以看到在函数中下面的代码是会出编译错误的: uint [] storage data = new uint[](1); 对于storage的变长数组,可以通过给length赋值调整数组长度。还可以使用后面提到的push()方法,来隐式的调整数组长度 对于memory的变长数组,不支持修改length属性,来调整数组大小。memory的变长数组虽然可以通过参数灵活指定大小,但一旦创建,大小不可调整
区块链
2018-07-07 14:41:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
原文链接:https://steemit.com/eos/@eosio/introducing-eos-io-application-stack
通过BitShares和Steem三年的实践经验,显而易见的是,开发一个分布式应用程序所需要的不仅仅是能快速响应的区块链。它还需要能够为数百万并发用户提供可用体验的基础架构。在steemit.com的早期,用户需要提供自己的图像托管服务。这使得接口难以使用并且易于破碎图像。
通过EOS.IO软件,block.one,我们可以设想这样一种场景,区块生产者向用户提供通用的基础设施,允许开发人员无需自己运行任何服务器即可构建和部署应用程序。包括像 steemit , DTube 和去中心化 交易 这样复杂的应用程序。
EOS.IO存储
EOS.IO存储是一个分布式的文件系统,旨在让世界上每个人都能访问互联网,从而永久存储和托管任何浏览器可访问的合法文件。与当前的替代方案不同,EOS.IO存储没有存储或带宽费用。EOS.IO存储建立在IPFS之上,是区块生产者为持有区块链代币的人提供的服务。EOS.IO区块生产者将在IPFS网络上复制并托管代币持有者的文件,并提供https端点以允许任何具有浏览器的人访问这些文件。
生产者将会就他们愿意提供多少存储来换取他们的报酬(区块奖励)达成共识。为相同奖励提供更多存储空间的区块生产商可能会从代币持有者获得更多投票。
EOS.IO查询服务
除了托管文件之外,区块生产者还需要运行能够代表应用程序查询区块链数据库状态的API节点。这些API可能是Graph QL和基于自定义Web Assembly的查询的组合。这使得应用程序无需运行和维护自己的可扩展托管服务就可以获得所需信息。
block.one将设计和发布开源微服务,阻止生产者可以部署将区块链数据库状态映射到更传统的数据库,以扩展读取访问权限,可维护性和额外索引。该软件将促进应用程序开发人员和块生产者构建与传统数据库API交互的Web应用程序。
资源限制
应用程序会在区块链和接口上消耗带宽,计算和存储空间。块生产商必须限制访问权限以防止滥用。这对于文件下载和API查询来说是相同的,对于区块链更新测量带宽和CPU时间。拥有少量原始令牌的用户应该能够对大部分应用程序拥有合理的自由访问权限。
使用模式将支持平衡资源使用账单与个人用户下载文件或首先上传文件的个人。这反映了网站付费提供托管服务的模式,但增加了透明地将账单和费率限制转移到最终控制其消费的用户的灵活性。这对带宽密集型应用程序(如dtube.com)至关重要。
自定义的应用程序
block.one认识到,使用块生产者提供的通用基础结构可以构建哪种类型的应用程序是有限制的。具体而言,需要服务器端渲染(例如,steemit)或需要由定制微服务(例如,市场历史)维护的定制数据库索引的应用程序可能需要应用程序开发者或其他方所托管的定制服务器基础结构。这些应用程序的开发人员可以从块生产者用来部署他们自己的定制API和查询服务的可扩展架构中受益。这将帮助开发人员迅速将可扩展的应用程序基础架构推向市场
区块链
2018-06-13 11:57:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
作者:freewind
比原项目仓库:
Github地址:https://github.com/Bytom/bytom
Gitee地址:https://gitee.com/BytomBlockchain/bytom
人们常说,“阅读源代码”是学习编程的一种重要方法。作为程序员,我们在平时的学习工作中,都应该阅读过不少源代码。但是对于大多数人来说,阅读的可能更多是一些代码片断、示例,或者在老师、同事的指导下,先对要阅读的项目代码有了整体的了解之后,再进行针对性的阅读。
但是如果我们面对的是一个像比原这样比较庞大的项目,身边又没有人指导,只能靠自己去看,这时应该怎么来阅读呢?也许每个人也都能找到自己的办法,或高效,或低效,或放弃。
我在这次阅读比原源代码的过程中,尝试的是这样一种方法:从外部入手,通过与比原节点进行数据交互,来一步步了解比原的内部原理。就像剥石榴一样,一点点小心翼翼的下手,最后才能吃到鲜美的果肉。
所以这个文章系列叫作“剥开比原看代码”。
说明
在系列中的每一章,我通常都会由一个或者几个相关的问题入手,然后通过对源代码进行分析,来说明比原的代码是如何实现的。对于与当前问题关系不大的代码,则会简单带过,等真正需要它们出场的时候再详细解说。
为了保证文章中引用代码的稳定性,我将基于比原的v1.0.1代码进行分析。随着时间推移,比原的代码也将快速更新,但是我觉得,只要把这个版本的代码理解了,再去看新的代码,应该是一件很容易的事情。
在文章中,将会有一些直接指向github上bytom源代码的链接。为了方便,我专门将bytom v1.0.1的代码放到了一个新的仓库中,这样就不容易与比原官方的最新代码混淆。该仓库地址为: https://github.com/freewind/bytom-v1.0.1
当然,你不必clone这个仓库(clone官方仓库 http://github.com/Bytom/bytom 就够了),然后在必要的时候,使用以下命令将代码切换到 v1.0.1 的tag,以便与本系列引用的代码一致: git fetch git checkout -b v1.0.1
不论采用哪种阅读方法,我想第一步都应该先在本地把比原节点跑起来,试试各种功能。
对于如何下载、配置和安装的问题,请直接参看官方文档 https://github.com/Bytom/bytom/tree/v1.0.1 (注意我这里给出的是v1.0.1的文档),这里不多说。
本篇问题
当我们本地使用 make bytomd 编译完比原后,我们可以使用下面的命令来进行初始化: ./bytomd init --chain_id testnet
这里指定了使用的chain是 testnet (还有别的选项,如 mainnet 等等)。运行成功后,它将会在本地文件系统生成一些配置文件,供比原启动时使用。
所以我的问题是:
比原初始化时,产生了什么样的配置文件,放在了哪个目录下?
下面我将结合源代码,来回答这个问题。
目录位置
首先比原在本地会有一个目录专门用于放置各种数据,比如密钥、配置文件、数据库文件等。这个目录对应的代码位于 config/config.go#L190-L205 : func DefaultDataDir() string { // Try to place the data folder in the user's home dir home := homeDir() dataDir := "./.bytom" if home != "" { switch runtime.GOOS { case "darwin": dataDir = filepath.Join(home, "Library", "Bytom") case "windows": dataDir = filepath.Join(home, "AppData", "Roaming", "Bytom") default: dataDir = filepath.Join(home, ".bytom") } } return dataDir }
可以看到,在不同的操作系统上,数据目录的位置也不同: 苹果系统( darwin ): ~/Library/Bytom Windows( windows ): ~/AppData/Roaming/Bytom 其它(如Linux): ~/.bytom
配置文件内容
我们根据自己的操作系统打开相应的目录(我的是 ~/Library/Bytom ),可以看到有一个 config.toml ,内容大约如下: $ cat config.toml # This is a TOML config file. # For more information, see https://github.com/toml-lang/toml fast_sync = true db_backend = "leveldb" api_addr = "0.0.0.0:9888" chain_id = "testnet" [p2p] laddr = "tcp://0.0.0.0:46656" seeds = "47.96.42.1:46656,172.104.224.219:46656,45.118.132.164:46656"
它已经把一些基本信息告诉我们了,比如: db_backend = "leveldb" :说明比原内部使用了leveldb作为数据库(用来保存块数据、帐号、交易信息等) api_addr = "0.0.0.0:9888" :我们可以在浏览器中打开 http://localhost:9888 来访问dashboard页面,进行查看与管理 chain_id = "testnet" :当前连接的是 testnet ,即测试网,里面挖出来的比原币是不值钱的 laddr = "tcp://0.0.0.0:46656" :本地监听 46656 端口,别的节点如果想连我,就需要访问我的 46656 端口 seeds = "47.96.42.1:46656,172.104.224.219:46656,45.118.132.164:46656" :比原启动后,会主动连接这几个地址获取数据
内容模板
使用不同的 chain_id 去初始化时,会生成不同内容的配置文件,那么这些内容来自于哪里呢?
原来在 config/toml.go#L22-L45 ,预定义了不同的模板内容: var defaultConfigTmpl = `# This is a TOML config file. # For more information, see https://github.com/toml-lang/toml fast_sync = true db_backend = "leveldb" api_addr = "0.0.0.0:9888" ` var mainNetConfigTmpl = `chain_id = "mainnet" [p2p] laddr = "tcp://0.0.0.0:46657" seeds = "45.79.213.28:46657,198.74.61.131:46657,212.111.41.245:46657,47.100.214.154:46657,47.100.109.199:46657,47.100.105.165:46657" ` var testNetConfigTmpl = `chain_id = "testnet" [p2p] laddr = "tcp://0.0.0.0:46656" seeds = "47.96.42.1:46656,172.104.224.219:46656,45.118.132.164:46656" ` var soloNetConfigTmpl = `chain_id = "solonet" [p2p] laddr = "tcp://0.0.0.0:46658" seeds = "" `
可以看到,原来这些端口号和seed的地址,都是事先写好在模板里的。
而且,通过观察这些配置,我们可以发现,如果 chain_id 不同,则监听的端口和连接的种子都不同: mainnet(连接到主网): 46657 ,会主动连接6个种子 testnet(连接到测试网): 46656 ,会主动连接3个种子 solonet(本地单独节点): 46658 ,不会主动连接别人(也因此不会被别人连接上),适合单机研究
写入文件
这里我们需要快速的把 bytomd init 的执行流程过一遍,才能清楚配置文件的写入时机,也同时把前面的内容串在了一起。
首先,当我们运行 bytomd init 时,它对应的代码入口为 cmd/bytomd/main.go#L54 : func main() { cmd := cli.PrepareBaseCmd(commands.RootCmd, "TM", os.ExpandEnv(config.DefaultDataDir())) cmd.Execute() }
其中的 config.DefaultDataDir() 就对应于前面提到数据目录位置。
然后执行 cmd.Execute() ,将根据传入的参数 init ,选择下面的函数来执行: cmd/bytomd/commands/init.go#L25-L24 func initFiles(cmd *cobra.Command, args []string) { configFilePath := path.Join(config.RootDir, "config.toml") if _, err := os.Stat(configFilePath); !os.IsNotExist(err) { log.WithField("config", configFilePath).Info("Already exists config file.") return } if config.ChainID == "mainnet" { cfg.EnsureRoot(config.RootDir, "mainnet") } else if config.ChainID == "testnet" { cfg.EnsureRoot(config.RootDir, "testnet") } else { cfg.EnsureRoot(config.RootDir, "solonet") } log.WithField("config", configFilePath).Info("Initialized bytom") }
其中的 configFilePath ,就是 config.toml 的写入地址,即我们前面所说的数据目录下的 config.toml 文件。
cfg.EnsureRoot 将用来确认数据目录是有效的,并且将根据传入的 chain_id 不同,来生成不同的内容写入到配置文件中。
它对应的代码是 config/toml.go#L10 func EnsureRoot(rootDir string, network string) { cmn.EnsureDir(rootDir, 0700) cmn.EnsureDir(rootDir+"/data", 0700) configFilePath := path.Join(rootDir, "config.toml") // Write default config file if missing. if !cmn.FileExists(configFilePath) { cmn.MustWriteFile(configFilePath, []byte(selectNetwork(network)), 0644) } }
可以看到,它对数据目录进行了权限上的确认,并且发现当配置文件存在的时候,不会做任何更改。所以如果我们需要生成新的配置文件,就需要把旧的删除(或改名)。
其中的 selectNetwork(network) 函数,实现了根据 chain_id 的不同来组装不同的配置文件内容,它对应于 master/config/toml.go#L48 : func selectNetwork(network string) string { if network == "testnet" { return defaultConfigTmpl + testNetConfigTmpl } else if network == "mainnet" { return defaultConfigTmpl + mainNetConfigTmpl } else { return defaultConfigTmpl + soloNetConfigTmpl } }
果然就是一个简单的字符串拼接,其中的 defaultConfigTmpl 和 *NetConfgTmpl 在前面已经出现,这里不重复。
最后调用第三方函数 cmn.MustWriteFile(configFilePath, []byte(selectNetwork(network)), 0644) ,把拼接出来的配置文件内容以权限 0644 写入到指定的文件地址。
到这里,我们这个问题就算回答完毕了。
区块链
2018-06-22 12:37:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
设计模式是许多开发场景中的首选解决方案,本文将介绍五种经典的 智能合约 设计模式并给出 以太坊solidity实现代码:自毁合约、工厂合约、名称注册表、映射表迭代器和提款模式。
1、自毁合约
合约自毁模式用于终止一个合约,这意味着将从区块链上永久删除这个合约。 一旦被销毁,就不可能 调用合约的功能,也不会在账本中记录交易。
现在的问题是:“为什么我要销毁合约?”。
有很多原因,比如某些定时合约,或者那些一旦达到里程碑就必须终止的合约。 一个典型的案例 是贷款合约,它应当在贷款还清后自动销毁;另一个案例是基于时间的拍卖合约,它应当在拍卖结束后 终止 —— 假设我们不需要在链上保存拍卖的历史记录。
在处理一个被销毁的合约时,有一些需要注意的问题: 合约销毁后,发送给该合约的交易将失败 任何发送给被销毁合约的资金,都将永远丢失
为避免资金损失,应当在发送资金前确保目标合约仍然存在,移除所有对已销毁合约的引用。 现在我们来看看代码: contract SelfDesctructionContract { public address owner; public string someValue; modifier ownerRestricted { require(owner == msg.sender); _; } // constructor function SelfDesctructionContract() { owner = msg.sender; } // a simple setter function function setSomeValue(string value){ someValue = value; } // you can call it anything you want function destroyContract() ownerRestricted { suicide(owner); } }
正如你所看到的, destroyContract() 方法负责销毁合约。
请注意,我们使用自定义的 ownerRestricted 修饰符来显示该方法的调用者,即仅允许合约的拥有者 销毁合约。
2、工厂合约
工厂合约用于创建和部署“子”合约。 这些子合约可以被称为“资产”,可以表示现实生活中的房子或汽车。
工厂用于存储子合约的地址,以便在必要时提取使用。 你可能会问,为什么不把它们存在Web应用数据库里? 这是因为将这些地址数据存在工厂合约里,就意味着是存在区块链上,因此更加安全,而数据库的损坏 可能会造成资产地址的丢失,从而导致丢失对这些资产合约的引用。 除此之外,你还需要跟踪所有新 创建的子合约以便同步更新数据库。
工厂合约的一个常见用例是销售资产并跟踪这些资产(例如,谁是资产的所有者)。 需要向负责部署资产的 函数添加payable修饰符以便销售资产。 代码如下: contract CarShop { address[] carAssets; function createChildContract(string brand, string model) public payable { // insert check if the sent ether is enough to cover the car asset ... address newCarAsset = new CarAsset(brand, model, msg.sender); carAssets.push(newCarAsset); } function getDeployedChildContracts() public view returns (address[]) { return carAssets; } } contract CarAsset { string public brand; string public model; address public owner; function CarAsset(string _brand, string _model, address _owner) public { brand = _brand; model = _model; owner = _owner; } }
代码 address newCarAsset = new CarAsset(...) 将触发一个交易来部署子合约并返回该合约的地址。 由于工厂合约和资产合约之间唯一的联系是变量 address[] carAssets ,所以一定要正确保存子合约的地址。
3、名称注册表
假设你正在构建一个依赖与多个合约的DApp,例如一个基于区块链的在线商城,这个DApp使用了 ClothesFactoryContract、GamesFactoryContract、BooksFactoryContract等多个合约。
现在想象一下,将所有这些合约的地址写在你的应用代码中。 如果这些合约的地址随着时间的推移而变化,那该怎么办?
这就是名称注册表的作用,这个模式允许你只在代码中固定一个合约的地址,而不是数十、数百甚至数千个 地址。它的原理是使用一个合约名称 => 合约地址的映射表,因此可以通过调用 getAddress("ClothesFactory") 从DApp内查找每个合约的地址。 使用名称注册表的好处是,即使更新那些合约,DApp也不会受到任何影响,因为 我们只需要修改映射表中合约的地址。
代码如下: contract NameRegistry { struct ContractDetails { address owner; address contractAddress; uint16 version; } mapping(string => ContractDetails) registry; function registerName(string name, address addr, uint16 ver) returns (bool) { // versions should start from 1 require(ver >= 1); ContractDetails memory info = registry[name]; require(info.owner == msg.sender); // create info if it doesn't exist in the registry if (info.contractAddress == address(0)) { info = ContractDetails({ owner: msg.sender, contractAddress: addr, version: ver }); } else { info.version = ver; info.contractAddress = addr; } // update record in the registry registry[name] = info; return true; } function getContractDetails(string name) constant returns(address, uint16) { return (registry[name].contractAddress, registry[name].version); } }
你的DApp将使用 getContractDetails(name) 来获取指定合约的地址和版本。
4、映射表迭代器
很多时候我们需要对一个映射表进行迭代操作 ,但由于Solidity中的映射表只能存储值, 并不支持迭代,因此映射表迭代器模式非常有用。 需要指出的是,随着成员数量的增加, 迭代操作的复杂性会增加,存储成本也会增加,因此请尽可能地避免迭代。
实现代码如下: contract MappingIterator { mapping(string => address) elements; string[] keys; function put(string key, address addr) returns (bool) { bool exists = elements[key] == address(0) if (!exists) { keys.push(key); } elements[key] = addr; return true; } function getKeyCount() constant returns (uint) { return keys.length; } function getElementAtIndex(uint index) returns (address) { return elements[keys[index]]; } function getElement(string name) returns (address) { return elements[name]; } }
实现 put() 函数的一个常见错误,是通过遍历来检查指定的键是否存在。正确的做法是 elements[key] == address(0) 。虽然遍历检查的做法不完全是一个错误,但它并不可取, 因为随着keys数组的增长,迭代成本越来越高,因此应该尽可能避免迭代。
5、提款模式
假设你销售汽车轮胎,不幸的是卖出的所有轮胎出问题了,于是你决定向所有的买家退款。
假设你跟踪记录了合约中的所有买家,并且合约有一个refund()函数,该函数会遍历所有买家 并将钱一一返还。
你可以选择 - 使用buyerAddress.transfer()或buyerAddress.send() 。 这两个函数的区别在于, 在交易异常时,send()不会抛出异常,而只是返回布尔值false ,而transfer()则会抛出异常。
为什么这一点很重要?
假设大多数买家是外部账户(即个人),但一些买家是其他合约(也许是商业)。 假设在 这些买方合约中,有一个合约,其开发者在其fallback函数中犯了一个错误,并且在被调用时抛出一个异常, fallback()函数是合约中的默认函数,如果将交易发送到合同但没有指定任何方法,将调用合约 的fallback()函数。 现在,只要我们在refund函数中调用contractWithError.transfer() ,就会抛出 异常并停止迭代遍历。 因此,任何一个买家合约的fallback()异常都将导致整个退款交易被回滚, 导致没有一个买家可以得到退款。
虽然在一次调用中退款所有买家可以使用send()来实现,但是更好的方式是提供withdrawFunds()方法,它 将单独按需要退款给调用者。 因此,错误的合约不会应用其他买家拿到退款。
实现代码如下: contract WithdrawalContract { mapping(address => uint) buyers; function buy() payable { require(msg.value > 0); buyers[msg.sender] = msg.value; } function withdraw() { uint amount = buyers[msg.sender]; require(amount > 0); buyers[msg.sender] = 0; require(msg.sender.send(amount)); } }
区块链
2018-05-08 12:24:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
区块链作为一种崭新的、颠覆性的技术,是国内外活跃的研究领域和毕业设计选题方向。本文列出最新的一组区块链方面的论文,希望可以对选择区块链毕业设计的同学们有所帮助,这是 汇智网 编辑整理的区块链毕业设计论文系列中的第5篇。
1、EdgeToll - 基于区块链的收费系统
边缘计算是对时间延迟敏感的云应用用于提高服务质量的一种新颖的计算模式。然而,目前的边缘计算都是针对特定应用设计,无法在公共资源中分享资源边。在本论文中,我们利用支付通道技术设计并实现了EdgeTool,一种基于区块链的收费系统,可以用于异构公共边缘服务的分享。我们的测试系统表明论文提出的方案具有时间和成本方面的效率优势。
论文PDF下载: EdgeToll: A Blockchain-based Toll Collection System for Public Sharing of Heterogeneous Edges
2、联盟学习证明 —— 一种新颖的能量寻源共识算法
PoW,即工作量证明,是 比特币 、 以太坊 等区块链中应用的最流行的共识算法,它需要大量能源才能运行,但是除了决定矿工的记账权再无其他有效产出。为了解决PoW共识的缺点,我们提出了一种新颖的能量循环共识算法,PoFL,即联盟学习证明算法。PoFL算法可以将PoW共识中浪费在难度计算上的能力投入联邦学习。
联盟学习和池化挖矿在组织结构方面有着天然的契合度。然而,区块链非结构话数据和属主之间的分离导致模型训练和验证中的数据隐私泄露,从而偏离联盟学习的初衷。为解决这一问题,我们提出了反向的基于游戏的数据交易机制和隐私保护模型验证机制,前者可以保护训练数据不会泄露,后者可以验证训练模型的精度同时保证不破环隐私。据我们所知,本论文是在区块链PoW共识中首次使用联盟学习。基于合成数据与真实数据的仿真展示了本论文所提议机制的有效性。
论文PDF下载: Proof of Federated Learning: A Novel Energy-recycling Consensus Algorithm
3、企业区块链应用的性能调优和规模化
实现区块链的可伸缩性很复杂,并且成本高昂。随着企业开始采用区块链技术来解决业务问题,一个很现实的考量,就是区块链应用是否能够支持生产系统的交易规模。实际上,区块链应用底层所采用的分布式组件和协议让性能优化不是简单的任务,需要一种方法学来削减复杂性和所需的成本。更进一步,已有的性能测试结果通常缺乏生产环境应用的需求、负载和基础设施。在本论文中,我们首次开发了一种用于企业区块链应用性能调优的方法,来增加系统的交易容量和性能。
论文所提出的方法已经应用于一个基于[Hyperledger Fabric]的企业区块链应用的性能优化,并且不需要修改Hyperledger Fabric的源代码,就可以将应用交易吞吐量从30提升到3000TPS。
论文PDF下载: Performance Tuning and Scaling Enterprise Blockchain Applications
论文相关推荐: Hyperledger Fabric开发指南
4、利用轻量级区块链实现监控摄像头的数据完整性
监控摄像头产生的视频片段是支持犯罪调查的重要证据。视频证据可以来自公开(可信)或私有(非可信)监控系统。这引发了非可信视频源的数据完整性和可审计性的问题。在本论文中,我们聚焦于机场生态系统,其中可信度不等的多个实体之间都参与视频监控信息的生产与交换。我们提出了一个框架来确保所存储数据的完整性,以便执法机构可以验证视频片段是否被修改。本论文提议的方案采用一种轻量级的区块链技术,将视频元数据保存为区块链交易来支持对视频完整性的验证。论文提出的框架也可以确保视频的可审计性。我们的测试表明引入区块链来创建和查询交易的开销很小,仅仅引入了毫秒级的延迟。轻量级区块链推荐: Tendermint 。
论文PDF下载: Leveraging lightweight blockchain to establish data integrity for surveillance cameras
5、智能合约概述 - 挑战、进步与平台
智能合约技术正在重构传统的行业以及业务流程。内嵌于区块链的智能合约可以让合同条款自动执行,而无需可信第三方的接入。因此智能合约可以削减管理人员并节约服务成本,提高业务流程的效率并减少潜在的风险。虽然智能合约有潜力驱动商业流程的新一轮创新,还有不少问题需要解决。本论文描述了智能合约的考察情况。我们首先介绍区块链和智能合约,然而描述智能合约的挑战以及近期的技术进步,同时也比较了几种典型的智能合约平台,例如以太坊、EOS、Stellar、Corda等,划分了智能合约应用的范畴,并给出一些代表性的示例。
论文PDF下载: An Overview on Smart Contracts: Challenges, Advances and Platforms
本文整理了最新的可用于区块链毕业设计的参考论文,如果需要访问区块链毕业设计必读论文系列的最新文章,可以持续关注我们的 博客 ,或加入QQ群:532241998。
原文链接: 区块链毕业设计必读论文(五) - 汇智网
区块链
2020-01-02 10:08:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> 本文为万向区块链技术中心研究组撰写,文章尝试对PBFT算法的正确性证明以及算法优化等内容作一个介绍。
1. PBFT算法正确性证明
本部分介绍PBFT算法的正确性证明。
1.1 安全性(Safety)证明
PBFT算法提供的安全性(safety)的具体含义是,对于所有本地确认(commit locally)的客户端请求来说,系统中所有正常副本节点都会就这些请求的消息序号达成一致。
上述的“达成一致”,其含义又分为两种:
同一视图中的消息序号一致:对于所有在同一视图中本地确认的客户端请求来说,各正常副本节点就其消息序号会达成一致。
新旧视图中的消息序号一致:对于在新旧视图中本地确认的客户端请求来说,各正常副本节点就其消息序号会达成一致。
接下来分别证明上述两种“一致”是成立的。
1. 在同一视图中,任何一个请求 m ,如果其已经本地确认过,也就是说,至少对于某一个正常副本节点 i 来说,prepared(m, v, n, i) 为 true , 之前已经证明过,此时,对于任意的正常副本节点 j (j也可以是 i) 来说,prepared(m’, v, n, j) 都为 false 。这里 m’ 是不同于 m 的另一个请求,也就是说 D(m’) 不等于 D(m) 。这就意味着对于所有在同一视图中本地确认的客户端请求来说,各正常副本节点就其消息序号会达成一致,第一个性质成立。
2. 现在考虑存在视图变更的情况。首先,在视图 v 中,对于任意一个请求 m 来说,如果其在 某个正常副本节点 i 完成了本地确认,假设其消息序号为 n 。那么,就有 committed(m, v, n) 为 true 。 这也意味着存在一个节点集合R1, 其中至少含有 f+1 个正常副本节点,并且对于其中每一个节点 i ,prepared(m, v, n, i) 为 true。

然后,考虑系统最终变更视图到 v' 的情况。在从视图 v 变更到 v' 的过程中,此时变更没有完成,正常副本节点在接收到 new-view 消息之前,不会接受视图 v' 上的预准备消息。
但是,对于视图 v 变更到 v'的任意一个有效的 new-view 消息来说,其中包含 2f+1 个有效的view-change 消息。这些消息来自不同的副本节点,记它们组成的集合为R2。R1和R2至少有一个相同的元素,也就是相同的节点。不然的话,它们总的节点个数将为(f+1) + (2f+1) = 3f+2,这与我们假定的系统总节点个数 3f+1 不符。
因此,假设这个共同的正常副本节点为 k 。对于请求 m 来说,只有可能存在下面两种情况:new-view 消息中,存在 view-change 消息,其中包含的最新稳定检查点对应的消息序号大于 m 的序号 n 。new-view 消息中所有的 view-change 消息中包含的最新稳定检查点对应的消息序号不大于m的序号n。
对于第一种情况,根据视图变更协议,新视图 v' 中,所有正常副本节点不会接受序号为n或小于n的消息。
对于第二种情况,m 将会被传播到新视图 v'中,因为根据视图变更协议,min-s≤n。视图变更完成后,在 v' 中,算法将针对编号为 n 的请求 m 重新运行三阶段协议。这就使得所有正常副本节点会达成一致,而不会出现下面这种情况:
另一个不同于 m 的请求 m' , 其在视图 v 中分配的序号为 n ,且在新视图中 v' 完成本地确认。
综合上面 1 和 2 的证明,就证明了算法在同一视图和视图变更过程中,都会保证本地确认的请求的序号在所有正常副本节点中会达成一致,从而保证了算法的安全性(safety)。
1.2 活性(Liveness)保证
对于PBFT算法来说,为了保证系统的活性(liveness),当节点无法执行客户端请求时,需要变更到新的视图。同时,视图变更也需要进行合理控制,只在需要时才进行,否则频繁的视图变更会影响到系统的活性。这就需要保证以下两点:
系统中至少 2f+1 个正常副本节点处于同一视图中时,这种状态尽可能长时间地保持;
每次视图变更时,上述时间间隔需要快速增长,比如以指数形式增长。
PBFT算法通过如下三种方法来保证上述两点:
1. 为了防止视图变更太快开始,当一个节点发送 view-change 消息后,在等待接收 2f+1 个 view-change消息时,会同时启动定时器,其超时时间设置为 T。如果视图变更没有在 T 时间内完成,或者在新视图中请求没有在该时间间隔内完成,则会触发新的视图变更。此时,算法会调整超时时间,将其设置为原来的两倍,即 2T 。
2. 除了上述的定时器超时触发节点发送 view-change 消息外,当其接收到来自 f+1 个不同节点的有效view-change 消息,并且变更的目标视图大于节点当前视图时,也会触发节点发送 view-change 消息。这可以防止节点过晚启动视图变更。
3. 基于上述第二点的规则,失效节点无法通过故意发送 view-change 消息来触发频繁的视图变更从而干扰系统的运行。因为失效节点最多只能发送 f 条消息,达不到 f+1 的触发条件。失效节点是主节点时,可能会触发视图变更,但是连续的视图变更最多只会是 f 个,之后主节点就是正常节点。因此,基于以上的规则,系统可以保证活性。
2. PBFT算法的优化
本部分介绍PBFT算法的优化。这些优化方式应用于算法的正常操作中,可以提升算法的性能,同时可以保持系统的安全性和活性。

2.1 减少系统通信量
可以采用三种方法减少系统通信量:
1. 向客户端发送回复的消息摘要,而不是回复的原始内容客户端指定一个特定的副本节点,从该节点接收完整的回复内容,而只从其他所有节点处接收回复的摘要。通过判读摘要与回复的一致性以及对回复计数,可以确保接收到正确的回复。如果客户端接收不到正确结果,就会按正常流程重新请求系统,并接收不同节点的完整回复。
2. 请求在副本节点prepared后,节点即试探性地执行请求,并发送结果。客户端只要收到 2f+1 个匹配的结果,就可以确保该结果的正确性。也就是说,该请求最终会确认(至少f+1 个正常副本节点的本地确认)。如果客户端无法得到正确结果,就重新发送请求,系统执行正常流程。一个被试探性执行的请求,有可能在视图变更过程中被中断,并被替换为一个空请求。此时,已经执行过请求的节点可以通过 new-view 消息中的最新的稳定检查点或本地的检查点来更新状态(取决于哪个序号更大)。
3. 针对只读操作,客户端将请求广播到每一个副本节点。各节点判断请求确实为只读且满足条件后,直接执行请求,并发送回复到客户端。客户端收到 2f+1 个相同的回复,即为正确结果;否则客户端之前设置的重发请求定时器将触发超时,使得客
户端重发请求,系统执行正常流程。
这种优化的前提条件是,副本节点在执行请求之前,需确保之前所有请求都已确认,并且被执行。

2.1 加快消息验证速度
使用公钥签名的方式验证消息存在如下不足:
类似于RSA这样的签名算法,签名速度比较慢;
其他公钥密码系统,如椭圆曲线公钥密码系统,虽然签名更快,但是验签更慢。

PBFT算法实际上在正常流程中采用 MAC(Message Authentication Code,消息验证码) 认证消息,因为它具有如下优点,使得算法相对于之前的算法性能提升了一个数量级以上:
MAC 计算速度快;
通过适当优化,可以减少其长度;
通过对authenticator(vector of MAC)的使用,可以使验证时间为常量,而生成时间只随着节点数量线性增长。

具体来说,PBFT算法中使用 MAC 和公钥签名的具体场景是:
所有正常操作流程中使用 MAC 验证消息;
视图变更中的消息:view-change, new-view,以及出现错误时,使用公钥签名。这些场景的出现频率相对较低,从而对算法的性能影响较小。

关联阅读:
PBFT算法流程
PBFT算法流程补充(一):视图变更、垃圾回收及状态机不确定性
区块链
2020-01-14 18:25:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
时至今日,区块链已经是家喻户晓了。相信除了业内,区块链正在或已经被传统行业深挖。无论是技术的普及还是场景的应用,亦或是基于技术产生的数字货币,前景都是不容乐观。
首先,区块链技术经过漫长的发展演变,从早期主要用于解决数字货币的双重支付问题,到现如今涉及各行各业;从过去的低性能到今天的高并发;随着技术的不断更新迭代,TPS不断扩展,区块链技术在众多领域尽其所长。
在过去十多年间,数字货币的逐渐普及,无论是个人还是组织,资产配置越来越正规化,传统机构在数字资产方面提供了诸多服务。
从政策方面来看,世界主要经济体在数字货币区块链政策上加强了相关研究,各国央行积极尝试用区块链技术解决法定货币问题,区块链监管和立法也逐步完善。比如日本对比特币和区块链相关交易所颁布了相应的法律法规;香港提出区块链监管沙盒需求等;
纵观整个行业,区块链监管越来越走向规范化、明朗化,行业也在逐步朝着合规化进程。区块链技术的日益成熟,让人们慢慢开始认知数字货币,那么有货币就会有存储,数字货币也不例外,在区块链技术下产生了一款适合数字货币的钱包——数字钱包。
数字钱包是价值互联网的基础,区块链钱包是连接区块链行业的重要桥梁。根据钱包使用时的联网状态可以分为热钱包和冷钱包。
区块链在很大层面上解决了信任问题,并且非常安全,钱包作为区块链生态中重要的入口,一直备受各行各业的广泛关注。
现在区块链技术处于高速发展阶段,DAPP落地已成为一种趋势。然而,钱包又是DAPP生态中最让用户接受的落地入口,区块链很多项目都是从钱包开始,接入各种DAPP应用,参与到这个生态建设中,将整个流程打通。
一、初识“区块链钱包”
钱包本质上也只是一种工具,目前大多数钱包都是在网络中建立了用户单独的区块空间,它是去中心化的。对于传统的银行卡,是由银行这个中心化平台发放,并对我们的资产管理,密码丢失还可以通过银行找回,银行卡丢失了别人拿到后没有密码,一样取不走我们的资产,但我们可以通过银行冻结等方式补办新卡;但是钱包则不然,丢失了打开钱包的钥匙谁也无法帮我们找回钱包。
1.区块链钱包(BlockChain Wallet)
区块链钱包(Block Chain Wallet):是密钥的管理工具,只包含密钥而不是确切的某个代币;钱包中包含了成对的私钥和公钥,用户用私钥进行交易,从而证明了该用户拥有交易的输出权;而输出的交易信息则被存储在区块链中;用户在使用钱包时,你的Keystore, 助记词, 明文私钥,都是钱包;Keystore 是你加了”锁”的钱包,而助记词和明文私钥是完全暴露在外的钱包,没有任何安全性可言,所以在使用助记词和明文私钥时,一定要注意保密。
2.钱包中的几个概念
钱包一般包括:公钥、私钥、助记词、Keystore、密码;本质上,钱包和钥匙是对应关系,固定的钥匙直接可以打开在网络上属于自己的钱包,但为了避免传输过程中信息泄密,密码学家又运用非对称加密技术,发明了公钥和私钥,公钥主要用于传输,私钥用于解密,简单解释就是,公钥是我们的银行卡,私钥就是该银行卡密码。
私钥= Keystore+密码,私钥是由56位包含数字和区分大小写的字母组成,为方便资产交易,一般采用简单密码加上Keystore就能便捷转移我们额数字资产。
助记词,是加密了的私钥,是为了便于导出Keystore而发明的。
3.钱包的类型
(1)热钱包
也就是能被网络访问的私钥存储位置。如在线钱包网站、存放在交易所的钱包、手机APP钱包等都属于热钱包。通常而言,热钱包使用更加便捷。
(2)冷钱包
冷钱包也就是通常我们说的离线、断网也能正常运行的钱包,私钥存储位置不能够被网络访问。如硬件钱包、纸钱包等。冷钱包较热钱包比较安全。
(3)on-chain
即发生在链上,给一个钱包地址发送数字货币,这笔交易在全网被广播、被确认、被打包进区块。称为on-chain交易;on-chain钱包需要自己保管私钥。
(4)off-chain
通常经过交易所进行交易时off-chain的,本人并无私钥。私钥由交易所托管。
(5)全节点钱包
除了保存私钥外,全节点钱包还保存了所有区块的数据,最著名的是bitcoin-core。
(6)中心化钱包
顾名思义,就是在交易过程中通过某平台或银行机构等交易的钱包,如oklink提供的保险柜。
(7)轻钱包
只保存跟自己相关的数据的去中心化钱包。
二、“区块链钱包”中的技术应用
我们经常说中心化的区块链数字货币钱包,实际上就是一个区块链软件。你的数字货币并不是存在钱包公司,也不是自己的手机设备,而是区块链网络的地址中。钱包只是通过网络服务器把区块链的各种代码展现给你,实际上就是建立了一个交易通道,让你把各种操作指令发送到区块链上。所以这类钱包不需要银行这类中心化平台,钱包丢失也不需要找银行冻结,私钥丢失将意味着你的资产再也无法打开。从这个角度看,钱包的安全性实质上是与你的私钥有直接关系。
1.钱包应用密码学原理
数字钱包的生成可以简单的分解为三个步骤:
创建随机私钥(64位16进制字符/256比特/32字节);
从私钥推导出公钥(128位16进制字符/512比特/64字节);
从公钥中导出地址(40位16进制字符/160比特/20字节)。
看似简单的步骤,却隐含着密码学中太多的技术:非对称加密、随机数生成器、散列函数等。
非对称加密
非对称加密算法于1976年提出,它将一般密钥分为加密密钥和解密密钥,即通常所说的公钥和私钥。公钥私钥一一对应,由公钥加密的密文必须由对应的私钥方可解密。
(1)随机数生成器
随机数专门是对随机试验的结果。在区块链钱包中随机数与安全**息相关,因此随机数用于生成私钥。因此,随机数必须具备以下特性:
随机性:不存在统计学偏差,完全杂乱的数列;
不可预测性:无法从过去数列推测到下一个出现的数;
不可重复性:数列在保存的情况下,不能够重复出现相同的数列。
(2)散列函数
散列函数又称Hash函数,它有一个输入和输出,输入称为消息,输出称为散列值。单项散列函数可以把任意长度的输入串变成固定长度的输出,也就是可根据消息的内容计算散列值,而散列值可以用来检查消息的的完整性。
2.区块链钱包中的智能合
(1)私钥
通常是随机生成的,就是一个巨大的随机整数;
(2)公钥
别人给你转账时除不能告诉的私钥外,通过哈希加密技术,把私钥转换得到的一串字符,称之为公钥。
(3)助记词
一般情况下,助记词由一些单词组成,只要你记住这些单词,按照顺序在钱包中输入,就能打开钱包。
(4)Keystore
有的钱包会采用私钥制作成keystore让用户导出保存,这个keystore就是私钥经过加密后的一个文件,需要你自己设置自己的密码才能打开该文件。这有一个好处是,文件即使丢了或是被盗,只要你设置的密码足够长随机,那么短时间内私钥是不会泄露的,我们可以有足够的时间转移我们的资产到其它地址。
3.钱包的单向、不可逆特性
钱包生成私钥,会通过椭圆曲线算法可以从私钥中计算得到公钥。
很难想象未来数字化之后资产的形态和支付场景,但区块链下的数字资产已经逐步趋势化。随着区块链技术日趋完善,在各种应用场景下会使数字资产更加便捷,而那时人就需要数字钱包参与数字时代的数字资产的使用,数字资产钱包必将成为未来的重要基础设施之一。
本文来自于链客社区www.liankexing.com
区块链
2019-10-29 14:27:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
开源已经成为信息技术发展的重要力量。无论是云计算、大数据,还是人工智能、区块链等领域,都大量采用了开源技术。据 GitHub 数据披露,GitHub 注册用户超 4000 万,美国程序员占比 20%,中国开发者数量排名第二。2019年发布的《开源产业白皮书(2019年)》显示,全球开源产业链已经形成,而中国已经应用了开源技术的企业占比达到86.7%,计划应用开源技术的企业占比 10.6%,开源技术已经被企业普遍接受。
2019年11月2-3日,【2019中国开源年会 (COSCon'19) 】于上海正式举办,京东云赞助参与了此次大会。大会共包含9个分会场,分别是开源社区与项目、企业开源、开源操作系统、开源教育、开源硬件、女性参与开源、工作坊/实训营、开源治理以及开源社区与项目&见面会、闪电演讲等。
在大会上,京东云产品研发部高级总监李道兵为技术人员带来了《云上Cloud Native的落地方法》的主题分享,就京东云在Cloud Native上的思考与实践和大家进行了交流。
京东云产品研发部高级总监 李道兵
目前京东云比较关注的开源项目集中在Kubernetes生态,通过京东云的原生容器与Kubernetes的结合,我们希望能将原生容器和Kubernetes通过一个比较紧密的方式结合在一起。比如在Kubernetes里的Kata Container,其在Kubernetes里使用了更安全的容器;还有 Rancher Labs基于K8s推出的轻量级的 Kubernetes 发行版 K3s,可以满足在边缘计算环境中运行在内存和处理能力受限的小型、易于管理的 Kubernetes 集群日益增长的需求。
李道兵指出:“ 目前在京东运营着全世界最大规模的Docker集群、Kubernetes集群,以及最复杂的Vitess集群之一。一直以来,京东云都在利用自身丰富的业务场景来推动开源技术的应用实践,不断为开源生态贡献价值,从而带动整个产业的技术发展 。”
除会场演讲外,京东云还受邀参加了本届“开源高峰圆桌论坛”环节,与Apache软件基金会董事Dave Fisher、Github副总裁Thomas Dohmke、CSDN创始人蒋涛等20多位来自国际基金会、开源社区和企业的代表,共同面向“走出去,带进来”的话题,针对国内企业对于国际基金会和国际开源社区有哪些期望和合作需求,以及国际企业和国际开源基金会对于中国开发者社区、开源项目的深度了解和合作进行了讨论。
COSCon19 “开源高峰圆桌论坛”参会者合影

01 京东云开源项目 BDS
京东云BDS(Blockchain Data Servic,区块链数据服务,产品链接: https://bds.jdcloud.com )是 国内首款提供区块链数据在线分析服务的开源产品 ,也是京东云完成国家网信办区块链信息服务备案的唯一一款产品。通过BDS,用户可以方便快捷地查询主流公链的全节点实时数据,提供了一个交互式的数据可视化 BI 工具,支持通过点击和拖拽的交互方式进行简单的条件查询和自行编写 SQL 语句的方式执行复杂查询;并且能够实时生成各类数据报表、图形化界面,满足小白到极客用户的区块链公链数据查询及使用需求。
当下,京东云区块链数据服务正在打造一个行业标准的区块链的BI+数据搜索服务,但是区块链项目的底层区块存储结构各不相同,需要对不同的项目的数据进行解析与整理,基于此,京东云希望通过开源BDS,让更多的开发者与社区可以参与其中,接入更多公有链、联盟链、私有链等区块链项目。BDS将以区块链数据搜索引擎形式聚合所有区块链相关的内容,最大化区块链上可信数据价值,方便社区能在BDS上进行区块链数据的一站式查询。
京东云BDS开源计划旨在寻找志同道合的技术爱好者,与京东云区块链项目团队一起,共同致力于通过BDS开源项目的平台,打造一个行业标杆级的区块链数据类产品标准,以及一个优秀的开源团队,为开源事业进一步做出贡献 。
开源团队参与方式:
1、发一封自我介绍邮件到邮箱:jdcloud-bds@jd.com;
2、邮件格式: 自我介绍(简单概要即可,需包括手机号码等主要联系方式,方便后期我们与您联系); 从业领域(行业细分领域,当前职位,参与过的项目等); 对BDS的看法(产品描述,问题建议等); 擅长(以技术为主); 熟悉或感兴趣的公链项目名称。
我们会在收到邮件后的1个工作日内与您取得联系

02 京东云开源扶持政策
京东云正在致力于帮助开发者解决在开源项目发展过程中遇到的缺乏底层云资源、技术支持、生态合作等问题,目前可为开源项目最高提供免费云服务及云市场生态资源支持。助力开源项目快速发展,成就开源梦想。
云资源支持
为开源项目免费提供最高时效可达终生的云资源支持;开源项目的合作用户购买京东云服务可享受更多长期优惠。
云市场生态支持
京东云致力携手各行业合作伙伴组建云上大生态联盟,开放赋能,共同为客户带来服务和价值。
技术支持
根据项目合作内容,提供免费数据迁移、定制化服务、技术专家一对一指导、7x24客服支持等。
项目推广&其他支持
京东云开发者社区全力支持开源项目的推广。
经历了20年的发展,开源从最初期的自发行为,到十年前演变成企业的商业行为,再到现在已经逐渐成为一个组织甚至国家的战略,已成为众多巨头眼中的增长点。2015年,国家发出“万众创新”的号召,受到的最大启发之一就是来自于互联网与开源软件。软件是知识产品,从这个意义上而言,开源已经成为人类知识生产的新模式。
京东云也将会持续支持开源,Open Source~Open Mind~
点击“ 阅读 ”了解京东云 开源 产品详情
点击“ 京东云 ”了解更多精彩内容
区块链
2019-11-11 11:12:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
我们说手机挖矿太靠近人们的活动空间,asic挖矿太远离人们的活动空间,而显卡挖矿既不干扰人们的日常活动空间又没有偏离人们活动空间的前进方向拉着能力空间向前行走。
但是这是有范围的,这个判断标准的参照点取的是人们的日常活动中心,如果扩大问题空间更换参照点的话asic也没有偏离方向,但是偏离了人们的日常活动方向。通用设备挖矿永远会存在,因为它在起矫正方向的作用,能力的提升必须发生在人们的活动空间发展的方向上。
开源矿工: https://ntminer.com
区块链
2019-11-06 13:57:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
5.IPSE优化IPFS协议

IPSE将基于IPFS构建一层搜索层,而IPFS的激励层是Filecoin,用户可以提供大量的存储空间,然后抵押到Filecoin的DSN市场,只要有存储需求方愿意购买存储空间,订单就能成交,Filecoin的挖矿激励对IPFS网络稳定有巨大帮助,Filecoin的成功将使得整个IPFS网络稳定下来,节点数量将成几何量级增长。

5.1 Filecoin的出块和存储价格
Filecoin的出块奖励将是丰厚的,Filecoin解决了数据的复制证明以后,数据的存储将变得安全,整个Filecoin的Token体系将会被社会和资本市场所认可,众多参与挖矿的矿工将逐步设置更低的存储价格来竞争有限的存储需求,当然这种有限的存储需求只是一开始的局面,如果存储价格降低到任何一个资源流量大厂无法拒绝的程度,市场将发生巨大的改变。还有不可忽视的开发者社区是最积极拥抱IPFS生态网络的,他们将毫无疑问首选更加便宜和安全的IPFS网络来进行数据的存储。甚至出现这样一个局面,有些激进的挖矿行为将直接将存储价格设置为免费来争夺存储订单。

5.2 Filecoin的矿池
Filecoin的白皮书非常清晰和优雅地论述了两种挖矿方式和DSN市场,存储市场和存储挖矿是否能够轻易设计出类似比特币的矿池呢? Filecoin的存储市场上构建矿池来获得挖矿优势将是比较困难的,每个存储矿机节点都有一个唯一的身份PeerlD,不能够冒充和替代其他节点去DSN市场领取订单,而撮合交易将是无法被攻击的,矿机节点即便通过一些矿池方式获得挖矿优势,这种优势将很可能会被认定为一种攻击,不付出而获得优势的挖矿行为将很可能是一种攻击和作弊,而Filecoin团队将很快通过升级挖矿软件将这种优势抹平。
Filecoin还有另外一种挖矿方式,那就是检索市场和检索挖矿。如果看事情看到本质,数据的保存就是为了能够被检索到,而且大量数据应该被广泛使用到。如何通过获得更多访问流量来提高检索订单的获取,这样的矿池对于Filecoin将不再是一种攻击行为,而是一种正向的带来流量的挖矿行为。IPSE在IPFS的基础上构建一层搜索层,给用户带来免费的检索服务的同时,也给背后提供检索服务的超级节点带来了构建检索挖矿矿池的机会。

5.3 IPSE的流量和检索挖矿
IPSE的流量将掌握在超级节点手里,如何对流量进行引导将是超级节点能够发挥巨大作用的地方,毫无疑问,最容易做的尝试将是自己搭建一个矿池,将接入自己矿池的矿机提供检索流量,让这些矿机获得更高的检索挖矿收益。当然,如果超级节点之间可以组成一个更大的矿池,这样接入的矿机数量将会更加庞大,其内容资源覆盖面积也将更加广泛,这样对于流量的引导将更加高效。

5.4 IPSE的超级节点和矿池服务
IPSE的超级节点是深度参与者,技术解决方案是项目方提供出来,而执行层面需要超级节点努力参与,只有这样利益一致的社区才能够做出一些能够落地的应用出来,如果只是进行hash计算竞赛,实在看不到区块链落地的可能性。超级节点能够自己搭建矿池服务,就可以在矿机硬件销售层面具有巨大的优势,如果观察整个互联网的发展,硬件的销售利润来推动整个行业发展是一个过程,而我们将再次经历这样一个过程,只是我们能否通过技术手段和共识网络增加硬件的盈利能力和销售优势。

5.5 IPSE和Filecoin的未来定位
深入研究Filecoin的基础协议,会发现这样一个让人尴尬的点,数据保存到IPFS网络,数据存储方如果选择用Filecoin的DSN市场,那就需要支付Filecoin来获得存储空间,这样数据的安全保存获得了保障,但数据的检索获取同样也需要支付Filecoin,那些热门的数据将会被无数人检索到,而这些人难道也需要支付Token来获得资源吗?显然这是一个比较尴尬的点,数据是通过P2P的传输方式让用户访问到,而如果数据让一个中心化节点先付费然后分发,那跟传统的HTTP并没有区别。在深入思考这些点之后,IPSE的定位刚好可以解决这个尴尬的点,数据方可以为了数据安全保存一份或者两份到IPFS,并且利用Filecoin进行安全的保障,但数据的访问并不会经过Filecoin的检索市场,而是直接通过IPSE让海量用户能够免费访问到,而数据同样是免费保存的,这样不仅自己可以获得POST的奖励,还能够解决存储成本和带宽成本,同时因为Filecoin保障了数据的安全,在IPSE上数据的丢失并不会影响数据的完整性和安全。
极少的数据将通过Filecoin进行安全的保障,但大部分的数据将通过IPSE进行分发和触达。
区块链
2019-09-30 10:49:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
3.IPSE设计理念

3.1 IPSE的出发点
IPSE(星际搜索引擎)的出发点是解决现实问题,借鉴其它优秀公链技术点,打造一个垂直的、专注于存储索引服务、计算(智能合约)的区块链生态。观察整个区块链生态,IPSE需要找到属于自己的位置。接下来我们将在去中心化维度上,区块链不可能三角论述中,区块链发展的两个流派选择上,找到IPSE的定位。
纵观DAPP发展的这4年,如果按照区块链的快速发展节奏,应该能见到DAPP能承载百万级别用户了,但很可惜,现实中没有出现。一直思考为何会出现这样的局面,区块链创业者跟传统互联网产业着有一个很大的不一样,那就是区块链创业者很多都是根据迭代白皮书中创意分高下,而传统互联网创业者是根据迭代产品分高下。我们可以简单理解区块链创业是设计和实现一套交易规则,重在设计,至于实现结果如何,从币价上都能体现真实情况。互联网创业是打造和迭代一款产品和服务,重在迭代。互联网是一个信息网络,区块链是一个价值网络,都具有网络效应,但要发挥网络效应,也就是梅特卡夫定律要发挥作用,在早期是需要一个艰难的爬坡阶段的。那为何现在的DAPP在早期爬坡为何如此困难呢?
DAPP的发展困境是当下区块链基础设施还不够完善的结果。DAPP的信任来源有三个方向,第一个是可验证,比如不可修改的智能合约,任何人都可以去验证,而不需要选择信任任何第三方,第二个方向是链下的可信任实体将信任背书到链上,可以简单理解成共识网络,第三个方向是链上去中心化治理。过去多年的DAPP发展,链上分布式治理明显是缺位的,同时可验证性跟智能合约迭代冲突,导致很多智能合约并不能工程化实现庞大的落地应用,很多都是简单的游戏和Gambling应用。
在这里,我们要明白一个基本的道理,好的项目并不是开发出来的,更多是演化出来的,从达尔文的演化论的角度看问题,适者生存,现有的DAPP都没有进化能力,都没有办法适应现在一个区块链新人高学习成本的市场。IPSE思考这些困境原因后,毫不犹豫会选择跨链的思路,IPSE如果只是一个小的共识网络,可以通过跨链的方式融入一个更大的共识网络,搭上顺风车,降低用户的学习和管理成本。跨链技术,IPSE将在Polkadot上搭建平行链的方式,将DAPP的发展变道到落地平行链的发展。

3.1.1 三种类型的去中心化
区块链的一个核心就是去中心化,当大家在讨论去中心化的时候,实际上有3种不同维度的去中心化: 结构去中心化——系统由多个节点组成,该系统可容忍多个节点同时发生崩溃。 Politics去中心化——没有个人或者组织控制着整个系统。 逻辑去中心化——系统展现和维护的界面和数据结构看起来更像是无定型的一大群对象,用户可以把系统一分为二,两部分还可以继续 当作独立单元完全运作。
中心化 VS 分布式

从这三个维度去观察一些事物,能抽出一些典型的案例。
传统企业是Politics中心化(CEO能掌控整个公司),结构中心化(可能有多分公司,但总有一个总部作为中心)以及逻辑中心化的(并不能真正一分为二)。
习惯法系统是Politics去中心化的(众多习惯法法庭有很大的自由裁量权),结构去中心化(众多习惯法法庭中没有绝对的中心)以及逻辑中心化的(不同习惯法都是为了共同体的管理)。
语言系统是Politics去中心化的(没有一个组织能掌控一门语言),结构去中心化(众多语言版本并没有绝对的中心)以及逻辑去中心化的 (比如英语系统,一半单词去掉,还是能单独运用)。
BitTorrent系统是Politics中心化的(能被一个公司组织控制),结构去中心化(众多节点加入)以及逻辑去中心化的。
区块链(第一代和第二代技术)是Politics去中心化(没有人或机构能控制区块链),结构去中心化(没有基础设施性的中心失败点),但是逻辑上是中心化的(有一个公认的状态,整个系统行为就像一个计算机一样)。

3.1.2 区块链的不可能三角
在传统货币理论中存在“三元悖论”(Mundellian Trilemma)理论,即一国的货币政策无法同时实现货币政策的独立性(monetary policy)、固定汇率(exchange rate)和资本自由流通(capital mobility),最多只能同时满足两个目标,而放弃另外一个目标。深入思考本质,作为传统金融系统中的价值,流动是其天性,交换是这种天性的延伸,而独立的货币政策是各个主体运用这种价值所不能放弃的,最后浮动的汇率刚好体现价值的平衡态。这种平衡是时刻都在失去的,同时也是无时无刻不在形成的。

相似的,前两代区块链技术也存在“不可能三角”,即无法同时达到可扩展性(Scalability)、去中心化(Decentralization)、安全稳定(Security),三者只能得其二。
深入思考本质,作为区块链系统中的价值,流动也是其天性,安全稳定是其该有的内涵,而可扩展性是大部分用户使用这种价值所追求的,最后部分放弃去中心化是不得已的选择,其实这种去中心化也是价值的平衡态,那也就意味着不存在永恒的去中心化,也不存在长期的完全中心化,整个区块链系统总是在打破和构建一种能承载价值的去中心化平衡态。
首先我们分析一下已有的几种解决方案,比特币是安全和去中心化的组合,牺牲了可扩展性,但去中心化越来越受到挖矿中心化所带来 的质疑,不管如何,尝试改进可扩展性是众多技术的创新点。
比特币现金,针对比特币区块承载能力有限进行的硬分叉,使得节点挖矿的运算门槛提高了,也就是使得部分节点不能再挖矿,从而牺 牲了部分去中心化,优化了可扩展性,提高了区块链的数据吞吐能力,但总的来说还是车水杯薪。
以太坊分片技术,毫无疑问,分片将分散整体的算力,从而造成了安全的隐患,在追求可扩展性和保证去中心化的前提下,牺牲了安全 性也会受到广泛质疑。
DPoS共识机制,在追求可扩展性方面走到极端,同时保证安全性,但无法实现去中心化,当然无法实现去中心化的情况下,还能保证安 全性也将受到广泛质疑。
P2P流媒体播放,这种应用场景能够允许出现数据掉帧,也就是说允许数据出现错误,这样的网络可以追求可扩展性,也能实现去中心 化,但安全性就不是必须要保证的。

3.1.3 属于IPSE的定位
思考这个世界的演化历程,在21世纪的今天,早已经打破了牛顿世界体系中的因果思维定式。深入思考完全去中心化的本质,每个节点都维持同样的信息量,香浓博士在信息论中将世界的不确定性和信息联系起来,完全的去中心化就相当于在整个区块链网络中彻底消灭不确定性,维持一个低熵的网络系统,付出的代价是高昂的外部能量输入。
整个宇宙的演化过程就是一个熵增的过程,如果将地球看作一个系统,为了维持其长期低熵的状态,就需要太阳不断输入能量,但地球内部每个节点(比如大陆)得到的能量并不是均等的,每个节点保持的信息量也不是均等的,如果深入思考这背后的机制,毫无疑问,演化的过程并不是人设计出来的,其中众多不确定性都在说明一个事物:复杂系统。完全去中心化的比特币网络就不是一个复杂系统,其中所有全节点都不存在秩序落差,这样一个系统让我不得不想到机械思维。
从古希腊的思辨思想、逻辑推理出发,经过欧几里得、托勒密、笛卡尔到牛顿的发明和改进,讲究因果逻辑构建的机械思维曾经是人类思维的制高点,也催生出了20世纪的科学大厦。机械思维的核心可以用三句话来概括,第一,世界的变化是确定的;第二,规律是可被认识 且能用简单公式或语言描述清楚;第三,规律放之四海而皆准,可以指导未知领域的实践。总之,机械思维是强调确定性(可预测性)和因果关系。
如果在这种关于去中心化的争论中要谈一个标准,那我将推崇经济学家吉尔德的吉尔德定律(Gilders Law),胜利者浪费定律提出最为成功的商业运作模式,价格最低的资源将会被尽可能的消耗,以此来保存最昂贵的资源。对应到区块链的去中心化思考,资源将会有价格,意味着节点作为保存数据的资源,也将具有价格,价格自然就会有高低,意味着保存的数据并不是完全一致的,至少其价值不是一致的,最低价格的资源将会被尽可能的消耗,也就是存储数据价值低的节点将会被最大程度牺牲。在总体输入能量不变的情况下,遵循吉尔德定律,维持一个低熵系统。
以上论述的只是IPSE关于去中心化的理论出发点。具体到技术层面,我们将采用DPoS来构建IPSE的主链,也就是区块链系统的结算层,然后会有平行链技术来保存不同价值的数据,根据保存数据价值大小来选择节点的数量,这样IPSE在去中心化方面将是有所妥协的,其实现了结构去中心化和Politics去中心化,维持了逻辑中心化,但如果不是仅仅看主链,而是深入区块链系统内部,将会发现将有众多去中心化子网络的尝试,在有限资源消耗的情况下还能维持整个系统的低熵状态。
时间到了2019年下半年,当看到Polkadot接近落地的时候,其整体思想跟IPSE是如何的吻合,处于核心的中继链保证安全,而接入的平行链保证功能的多样性,而不同的平行链将会有不同的安全等级,因为接入的验证节点数量是不一样的,当然不同功能的平行链其安全等级需求也是不同的,这样整体看上去达到了帕累托最优。

3.1.4 两个流派
区块链的玩法基本有两大流派,一种是公司模式,一种是社群模式。所谓的公司模式,比如腾讯做一个BaaS平台,相信币圈的人对BaaS的认识也不是很多,这就是影响力的问题了,公司模式来做区块链,基本投入比较大,准备也会比较充足,技术积累也比较多,申请专利多,想在开源开放的链圈构建自己的壁垒,想要有自己的一亩三分地,结果是你的一亩三分地让利实在太寒酸,影响力很难做起来。而社 群模式做区块链就是完全另外一个景象,投入相对少,基本都是开源,问题和进展都分享,参与者众多,影响力大。
从以上两个流派分析下来,如果说区块链是第三次互联网革命代表着未来,那么企业的运营方式是否是最优昵,专利申请是否还有必要呢?
如果企业的本质是在分散的人群中快速找到有共识的人来做某件事情,那么用区块链的共识是否更加牢固和快速昵?如果申请专利是为 了将技术优势用中心化权威确认来实现价值兑现,那么区块链能将技术优势用去中心化共识确认的方式来实现价值兑现,那么申请专利是否 还是必须的昵?
从已有的众多区块链项目分析,能看到区块链技术被用到溯源与存证,分布式记账,预期价值管理等方面。如果深入思考,区块链的本 质是改变了个人或法人获取收入的方式。

3.1.5 价值的创造和管理
现代社会,除了资本之外,个人或法人获取收入的力量来源可以大概划分如下五个方面: 共同体环境,比如采用哪一种通货,这是一个共同体好坏的重要衡量标准,一个好的国家,其通货不会差,一个发展欠佳国家,其通货好不了。在比特币终极信仰者看来,未来只有两样东西是具有价值的,一个是加密数字货币,一个是土地。 劳力,运用双手加技能获得收入,参与全球分工或者社区分工,是属于亚当·斯密在《国富论》中所描述的无形的手,同样也是属于 上帝的范畴。 现在众多脑力工作者都是进行分工协作,可以逐步登录到区块链的智能合约生态。 机器智商是个人或法人操控众多机器为自己工作的能力。具体就是存储,计算,网络传输,算法,编程等。 以上几个方面都需要考虑信任成本,从上到下,所需信任成本是依次递减。
毫无疑问,IPSE创造价值的方式是分散化资本,极高的机器智商和极低的信任成本的组合。IPSE将鼓励用户自己投资建立节点,将在IPSE上进行挖矿,而IPSE专注数据的存储和计算将为传统互联网和Web3.0提供支撑,充分发挥节点的机器智商,而IPSE本身就能将参与者的共识快速形成,降低参与者之间的信任成本。

3.1.6 关于企业的本质思考
科斯对企业本质的思考是非常值得推崇的,科斯指出,企业本质是一种资源配置的机制,企业与市场是两种可以互相替代的资源配置方式。如果用通俗的语言就是,将商品、服务的生产环节在企业内部降低交易成本。
区块链技术,源于比特币,其思想渊源来自哈耶克的《货币的非国家化》,其核心思想是要改变超主权货币理论。随着区块链的发展,如果按照上面所说的本质是改变了个人或法人获得收入的方式,其实也能证明科斯的交易成本理论:当越来越多的环节交易成本趋于零的时候,企业的边界就消失了,每个人都不再是员工,而是自由人。
IPSE团队对于企业的思考是非常深入的,所以我们将采用社群运营的模式来开发IPSE。

3.2 IPSE的分层设计思考

3 . 2 .1 分级与分层
在讨论区块链的分层设计的时候,要跟分级设计分开来,比特币的闪电网络更像是一种分级设计。闪电网络将小额支付累积起来,然后一起走闪电网络,快速支付通道跟主链是存在级别之分的,同样的道理还有offchain钱包。主链作为第一级是不需要关注第二级的状态变化的,然而第二级的闪电网络或者offchain钱包是需要监控第一级主链的。闪电网络或offchain钱包需要保证其快速支付通道内的支付方不会去主链上做广播欺诈。在分级设计架构中,第二级中出现了异常,并不会影响到第一级主链,受影响的也仅仅只是快速通道本身,但如果第一级主链出现异常情况,第二级闪电网络肯定会出现大问题。
区块链的分层设计是有几个基本原则的,首先层级之间要能够解耦,其次层级内部设计可改变,层级之间互不影响,最后层级之间能通过接口通信。从上面的基本原则出发,设计平行链实现一些功能层的话,就可以设计平行链为完整独立的区块链,跟主链实现完全不一样的功能,主链负责UTXO的转账和账本的更新维护,平行链用特定的双向绑定交易来充当接口与主链打通,然后用平行链实现特定的功能,比如智能合约。

3 . 2 .2 五层架构
从区块链架构设计来看,区块链可以简单分为三个层次,协议层、扩展层和应用层。其中,协议层可以细分为存储层和网络层。
(1)协议层
协议层是最底层的技术,基本就是一个完整的区块链产品,类似电脑的操作系统,维护着网络节点,对外仅仅暴露API调用,一般是提供一个简单的钱包客户端来调用这些API,如果采用分层的设计理念,这个协议层只是负责主链资产(主链Token)的结算,具体就是UTXO的转账和账本的更新维护,不包括平行链的功能,这样对接的客户端的功能也将是非常克制的,只会建立地址、验证签名、转账支付和查看余额等。
这个协议层是其他所有区块链功能的基础,构建了网络环境,搭建了交易主通道,制定了节点挖矿奖励规则,设计且实现了钱包地址等。
协议层的开发包括网络编程(P2P)、分布式共识算法、加密签名和数据存储等4个大的板块,其中分布式共识算法有比较成熟的PoW、 PoS和DPoS等可以借鉴,而加密签名技术是已有成熟方案,数据库存储也可以采用已有的成熟方案,至于点对点网络的实现和开发将是协议层开发的难点,我们将采用go语言来编写协议层代码。
(2)扩展层
如果说底层的协议层类似电脑的操作系统,那么扩展层就相当于电脑的驱动程序,是为了让区块链产品更加实用。IPSE的扩展层主要是两个方向,一个是虚拟机和智能合约,另外一个是平行链技术。
在开发扩展层的时候,除了在交易时与协议层进行交互之外,其他时候尽量不要与协议层的开发混在一起。扩展层跟上面的应用层更加接近,如果用中心化的思维去理解,就好比B/S架构中的服务端(Server)。解耦设计是有明显好处的,可以让主链的数据更小,网络更独立,同时保证扩展层开发不受约束
智能合约需要跑在一个独立的虚拟机上面,而虚拟机是不在协议层的,采用分层设计理念,就不能把虚拟机跑在协议层的主链上,而需要在扩展层开发一条可以让用户跑智能合约的平行链,当然用户也可以自己发行符合自身业务需求的业务公链,然后在上面跑智能合约。扩展层的平行链需要跟结算层的主链进行双向挂钩绑定。
(3)应用层
如果说协议层类似电脑的操作系统,而扩展层类似电脑的驱动,那么应用层就好比电脑中的各种软件程序,是普通用户可以直接使用的 产品,可以理解为B/S架构中的浏览器(Browser)。现在应用层最多的应用是钱包服务,但这是最基础最简单的服务,跟每个用户所需的服 务还有很大空间等待挖掘开发。

3.3 IPSE的接入跨链技术
跨链协议允许资产在主链和其他区块链之间互相转移。主链(Parent chain)和待接入平行链(Parachain)通过双向挂钩(Two-way peg)的方式,实现价值在主链和平行链上流通。在跨链平台Polkadot中是连接桥的角色来将两者打通。

3.3.1 侧链出现的背景

在侧链诞生之前,众多“山寨币”的出现正在碎片化整个数字货币市场,再加上以太坊等项目的竞争,一些比特币开发者希望能借助侧链的形式扩展比特币的底层协议。
侧链负责缠绕结算链用来对接应用链,这样扩展设计是为了实现功能分层、松耦合、各链各司其职又各自透明,可以对接系统工作。结算链是负责不可逆记账,去中心化安全共识。比如比特币就是典型的结算链。这种链要求节点多,充分离散化分布,协议可迭代而不会造成 兼容问题,高安全壁垒。结算链作为区块链架构里面的底层基准代表,目前已经锁定了一系列的事实上的标准,我相信近期不会有变动的需要,长期也可以做到稳定不变,灵活性、扩展性、功能性将会由侧链(缠绕链)、应用链来实现。
在技术创新领域,分层次,松耦合的协议标准开发更能够激发生态活力,有利于技术分工和协作,这也是市场自然选择的结果,结算链的底层事实标准很快会被锁定,以不变应万变,留下的所有的缺陷也好不足也好,统统让位给侧链、应用链去处理。侧链从技术上讲,就是 缠绕结算链和应用链,使应用链数据和结算链数据无缝对接,承上启下。
侧链的主要功能有: 结算链离链交易。 应用链的基础用户数据(用户账号,权限,Token账本)。 应用链的运行承载(智能合约虚拟机,运行平台)。

3.3.2 双向挂钩锁定
侧链协议的设计难点在于如何让资产在主链和侧链之间安全流转。简而言之,接收资产的链必须确保发送资产的链上的币被可靠锁定。
上图演示了侧链和主链双向挂钩锁定的过程。侧链技术协议采用主侧链双向挂钩机制实现资产从主链向侧链转移和返回。主链和侧链需 要对对方的特定交易做SPV验证。
完整过程如下: 当用户要向侧链转移Token时,首先在主链创建交易,待转移的Token被发往一个特殊的输出。这些Token在主链上被锁定。 等待一段确认期,使得上述交易获得足够的工作量缺人。 用户在侧链创建交易提取Token,需要在这笔交易的输入指明上述主链被锁定的输出,并提供足够的SPV证明。 等待一段竞争期,防止双重花费攻击。 Token在侧链上自由流通。 当用户想让Token返回主链时,采取类似的反向操作。
A.首先在侧链创建交易,待返回的Token被发往一个特殊的输出;
B.等待一段确认期;
C.在主链用足够的对侧链输出的SPV证明来解锁最早被锁定的输出;
D.竞争期过后,主链Token恢复流通;
E.竞争期过后,主链Token恢复流通。

3.3.3 IPSE 对 接入跨链 的应用设计
比特币出现后,其提供了充足的分布式节点和算力壁垒,但其拥堵和高延迟导致其无法实现商用落地,而以太坊有了智能合约的功能,但也有太拥堵的问题。根本原因都是在区块链设计之初没有从分层的角度去思考整个问题集。
(1)应用数据和结算数据并不需要在一个区块链上堆积,IPSE将大部分应用数据放在接入的平行链上。
(2)多种应用数据不需要在一个区块链上混合并存,所有智能合约都在主链的一个虚拟机上,是获得了同等的安全保障,但带来的耗费是合理的。IPSE将有一个应用DAPP矩阵,实现多种应用数据有效分离。
(3)平行链的节点规模跟其实现业务是匹配的,数据的重要程度跟区块链平行链链保证数据安全程度是匹配的,IPSE将不迷信完全的去中心化,而注重合理匹配。
(4)所有应用运算不需要交等额的手续费。如果像以太坊只有一条主链,那么其对于所有的智能合约中的操作的价格估算是同质的,其价格缺少分层规划。IPSE将在不同落地应用场景里,设计不同的交易效率,也需要对应的成本,智能合约计算价格分层设计。
(5)所有的交易操作不需要等额的挖矿耗费。不同的交易具有不同的价值,这是事实,IPSE将采用平行链技术,将绝大部分的交易存储放在平行链上。
(6)主链上统一的计算虚拟机是否是不必要的。对于不同的智能合约,其重要性的差别是不言自明的,其需要保存的数据的重要性也 是同样道理,如果采用一条主链垂直实现,就会出现像以太坊类似的严重的性能扩展问题,数据量同步负担过重也会造成安全问题。IPSE平行链能负责这两部分,计算虚拟机拆分解决主链性能不足问题,数据存储拆分解决数据治理的扩展性问题。

3.4 IPSE 对存储和计算的独特思考
在应用层提供最简单的钱包服务以外,IPSE主要提供三大服务:存储检索服务、计算服务、DAPP。

3.4.1 存储检索服务
已有的专注分布式存储的公链项目已有不少,比较成功的方案有IPFS+Filecoin组合,IPSE将基于IPFS网络构建一层搜索服务,用户可以通过一个检索服务器集群提供的稳定检索服务,找到自己想要的数据,然后通过IPFS浏览器查看,当然现在的浏览器也是能够兼容IPFS网络上的部分资源。

3.4.2 计算服务
这里说的计算服务不是比特币挖矿的hash计算,也不是智能合约中进行的计算,而是大数据和人工智能领域的计算服务,所以在节点上加入GPU显卡是必要的,而IPSE的矿机提供商也预备了显卡升级方案。当众多节点加入了 GPU显卡,能让分布式的众多节点拥有强大计算能力,同时配合分布式存储在节点的本地化数据,IPSE将很容易提供大数据运算和人工智能算力服务。这一层提供的计算服务将是标准化的,需要将计算任务量化,并且能够公平定价且防止作弊,构建一个统一、抽象的计算任务订单网络,网络中的各个节点进行订单匹配,节点在接到订单后完成计算任务,同时还需证明计算完成,其他节点帮助验证计算完成,将这样的订单打包在平行链上出区块。

3.4.3 DAPP
在平行链上运行不同的虚拟机,在不同虚拟机上跑不同的DAPP,同时要打通智能合约之间数据的交互,智能合约和外部数据的交互,有利于对接外部的先知机,让不同的智能合约和虚拟机在性能和安全性两个维度取得平衡。
区块链
2019-09-30 10:18:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
在本文中我们将学习如何使用使用coinmarketcap提供的比特币行情API,编写Python程序来获取像比特币、莱特币或以太币之类的区块链数字货币的实时行情/实时价格。
1、比特币行情API调用代码
我喜欢在编写实现逻辑之前先写一个注释来说明程序的用途: # 说明:获取比特币的实时价格
接下来我会导入requests库: # 导入requests库 import requests
现在让我们保存比特币行情API的URL,我们可以使用coinmarketcap.com提供的API: TICKER_API_URL = 'https://api.coinmarketcap.com/v1/ticker/'
现在让我们创建一个函数来获取指定数字货币例如比特币、莱特币或以太坊的价格 def get_latest_crypto_price(crypto): response = requests.get(TICKER_API_URL+crypto) response_json = response.json() return float(response_json[0]['price_usd'])
调用这个函数测试一下: get_latest_crypto_price('bitcoin')
测试结果如下:
现在我们创建一个主函数来获取指定数字货币的当前价格,然后显示输出: def main(): last_price = -1 while True: crypto = 'bitcoin' price = get_latest_crypto_price(crypto) if price != last_price: print('Bitcoin price: ',price) last_price = price
运行主函数即可: main()
运行结果如下:
在上面的代码中,只要简单地替换下crypto变量的值,就可以轻松地查询莱特币、以太币等其他数字货币的实时价格了!
本文的代码可以在 这里 下载。
2、区块链开发学习资源
要系统学习区块链开发技术,可以参考汇智网的区块链系列编程实战教程,涵盖 以太坊、比特币、EOS、Fabric、Tendermint等多种区块链平台: java以太坊 ,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。 python以太坊 ,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。 php以太坊 ,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。 以太坊开发入门 ,主要介绍智能合约与dapp应用开发,适合入门。 以太坊电商 ,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。 ERC721实战 ,课程以一个数字艺术品创作与分享DApp的实战开发为主线,深入讲解以太坊非同质化通证的概念、标准与开发方案。内容包含ERC-721标准的自主实现,讲解OpenZeppelin合约代码库二次开发,实战项目采用Truffle,IPFS,实现了通证以及去中心化的通证交易所。 C#以太坊 ,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。 java比特币 ,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。 php比特币 ,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。 c#比特币 ,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在C#代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是C#工程师不可多得的比特币开发学习课程。 EOS开发入门 ,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。 EOS钱包开发 ,本课程以手机EOS钱包的完整开发过程为主线,深入学习EOS区块链应用开发,课程内容即涵盖账户、计算资源、智能合约、动作与交易等EOS区块链的核心概念,同时也讲解如何使用eosjs和eosjs-ecc开发包访问EOS区块链,以及如何在React前端应用中集成对EOS区块链的支持。课程内容深入浅出,非常适合前端工程师深入学习EOS区块链应用开发。 Hyperledger Fabric NodeJS SDK ,本课程面向初学者,内容即包含Hyperledger Fabric的身份证书与MSP服务、权限策略、信道配置与启动、链码通信接口等核心概念,也包含Fabric网络设计、nodejs链码与应用开发的操作实践,是Nodejs工程师学习Fabric区块链开发的最佳选择。 Hyperledger Fabric java SDK ,课程面向初学者,内容即包含Hyperledger Fabric的身份证书与MSP服务、权限策略、信道配置与启动、链码通信接口等核心概念,也包含Fabric网络设计、java链码与应用开发的操作实践,是java工程师学习Fabric区块链开发的最佳选择。 tendermint ,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。 Flutter以太坊 ,主要是针对Flutter/Dart程序员进行区块链以太坊开发的web3Dart详解。
原文链接: 比特币行情API调用 — 汇智网
区块链
2019-09-21 09:05:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
今天注定是行业的不眠之夜,虽然有不少币圈的网友自黑地调侃道“主席说的是区块链,可是我们玩的是cx”,但其实这次释放的信号中区块链和数字资产被第一次以如此官方的方式被相提并论,其实客观上已经是承认了币与链的一体两面。作为一颗韭菜,期待许久的国家介入数字资产交易场景终于看到了希望。被各类正在cx所埋没的区块链项目,正在踏实在前进的区块链项目我想只有在受到合理监管的中心化交易所以及技术足够成熟的分布式交易所中,才能够得到足够的价值发现。
今天圈内狂轰滥炸的解读也让我对这个行业的认识有了升华,炒的不再是币,而是国家经济的未来啊!BTC,ETH,SIPC应声增长12%,都进入到了mytoken热搜前十,前两个是过去十年在国际领域的两代区块链,后一个是基于过去十年的积累由中国成员主导的的新一代区块链代表,我想2019.10.25也会成为中国新数字经济,以及世界新数字经济起航的一天。
——白糖可塔朵
区块链
2019-10-28 10:42:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
Hyperledger Fabric 开发环境安装不算太复杂,只需要按照本文的步骤进行,相信一定可以的。
1.在Ubuntu 16.04上安装Docker(社区版)
首先通过以下方式更新apt索引: sudo apt-get update
添加Docker的官方GPG密钥: curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
将Docker存储库添加到APT源,Docker存储库有三个基于体系结构的包: AMD64(64位体系结构包): sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" ARMHF(32位体系结构,即基于ARM-86体系结构的软件包): sudo add-apt-repository "deb [arch=armhf] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" 此包的第三个版本是S390X版本,仅适用于基于z内核的Linux: sudo add-apt-repository "deb [arch=s390x] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
现在用新增加的repo更新apt索引: sudo apt-get update
现在从Docker的repo安装: apt-cache policy docker-ce
现在安装Docker: sudo apt-get install -y docker-ce
现在检查Docker引擎的状态: sudo systemctl status docker
在没有sudo的情况下运行docker: 1. sudo groupadd docker b. sudo gpasswd -a $USER docker c.要么执行 newgrp docker ,要么退出并重新登录。
2.在Ubuntu 16.04上安装Docker Compose
首先通过以下方式更新apt索引: sudo apt-get update
在Linux系统上安装Docker Compose: sudo curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
然后运行以将可执行权限应用于下载的二进制文件: sudo chmod +x /usr/local/bin/docker-compose
检查Docker Compose的版本: docker-compose version
3.安装GO编程语言:
首先通过以下方式更新apt索引: sudo apt-get update
我们需要Go编程语言版本1.9.x,因为Hyperledge Fabric在其大部分组件中使用Go的1.9.x版本,以便运行以下命令: cd ~
如果你的Ubuntu是基于x86架构的,那么运行 curl -O https://storage.googleapis.com/golang/go1.9.linux-386.tar.gz
否则,如果你的Ubuntu是基于x64架构的,那么运行: curl -O https://storage.googleapis.com/golang/go1.9.linux-amd64.tar.gz
然后使用以下命令提取:
如果你下载了32位/x86版本 tar xvf go1.9.linux-386.tar.gz
或者如果你下载了64位/x64版本 tar xvf go1.9.linux-amd64.tar.gz
现在将提取的go文件夹的所有权更改为root:root sudo chown -R root:root ./go
现在将这个go文件夹移到/usr/local目录 sudo mv go /usr/local
设置执行路径: cd ~ sudo nano .bashrc
现在在文件的最后添加这些行在执行此操作之前,请确保在/usr/local/directory_中安装了go(即移动的go文件夹)。 export GOPATH=$HOME/myworkspace export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin
现在加载最新更新的bashrc source .bashrc
现在,创建工作区目录,在其中放置Go项目 mkdir $home/myworkspace
现在创建一个项目目录 mkdir -p myworkspace/src/github.com/go_project/hello
现在在go_项目目录下的hello目录下创建一个hello world程序go文件 nano ~/myworkspace/src/github.com/go_project/hello/hello.go
复制其中的以下代码 package main import "fmt" func main() { fmt.Printf("hello, world\n") }
现在把它另存为hello.go,你可以用有效的命名约定来命名你的程序,但是 .go 扩展非常重要。
现在运行以下命令安装Go程序: go install github.com/go_project/hello
现在编译它运行 hello
这应输出为: hello, world!
祝贺你!你已经成功地在Linux系统上安装了Go编程语言。
4.安装node.js:
在安装node.js之前,我们先安装nvm,它会让我们在机器上安装特定版本的节点,也会让我们在同一台机器上下载和管理多个版本的节点,以下载nvm: curl -O- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
或 wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
现在安装node v6.11.2,非常小心地按照hyprledger结构的要求使用这个版本的node。 nvm install 6.11.2
现在,你可以检查要安装的节点版本(具体为V6.11.2),因为我们已经安装了它: node –version
安装节点最终会和它一起安装NPM,所以现在验证NPM的版本,它应该是3.10.10: npm -v
如果系统中没有3.10.10版本的NPM,则运行: npm install npm@3.10.10 -g
5.安装python:
因为Ubuntu附带了python3.5.1作为python3二进制文件。Hyperledge Fabric需要python 2.7才能使 npm install 正常工作,因此要安装pyhton2.7,请运行以下命令: sudo apt-get install python -y
检查python的版本 python --version
6.安装GIT: sudo apt-get install git
7.设置Hyperledger结构: cd ~ mkdir hyperledger-binaries cd hyperledger-binaries/
现在让我们设置我们的machne以实际运行一个hyperledger结构,运行以下命令下载docker图像并标记为最新的,并下载结构二进制文件,从你想要提取结构二进制文件的位置运行它: curl -sSL https://goo.gl/6wtTN5 | bash -s 1.1.0
现在将这些二进制文件的下载位置添加到系统路径中 cd ~ sudo nano .bashrc export FABRICPATH=$HOME/hyperledger-binaries/fabric-samples export PATH=$PATH:$FABRICPATH/bin source .bashrc
现在,让我们运行此示例以测试你的完整设置是否正常运行示例结构网络: cd fabric-samples/first-network
现在要生成CA证书和Docker撰写端到端配置文件,请运行: ./byfn.sh -m generate
现在要实际启动网络并在该结构的每个对等端上安装示例链代码: ./byfn.sh -m up
现在运行以下命令查看是否所有docker映像都在conatiners中运行: docker ps
祝贺你,你已经成功地建立了fabric网络。
现在停止并撕掉fabric: ./byfn.sh -m down
======================================================================
如果你想学习区块链并在Blockchain Technologies建立职业生涯,那么请查看我们分享的一些以太坊、比特币、EOS、Fabric等区块链相关的交互式在线编程实战教程: java以太坊开发教程 ,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。 python以太坊 ,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。 php以太坊 ,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。 以太坊入门教程 ,主要介绍智能合约与dapp应用开发,适合入门。 以太坊开发进阶教程 ,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。 ERC721以太坊通证实战 ,课程以一个数字艺术品创作与分享DApp的实战开发为主线,深入讲解以太坊非同质化通证的概念、标准与开发方案。内容包含ERC-721标准的自主实现,讲解OpenZeppelin合约代码库二次开发,实战项目采用Truffle,IPFS,实现了通证以及去中心化的通证交易所。 C#以太坊 ,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。 java比特币开发教程 ,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。 php比特币开发教程 ,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。 c#比特币开发教程 ,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在C#代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是C#工程师不可多得的比特币开发学习课程。 EOS入门教程 ,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。 深入浅出玩转EOS钱包开发 ,本课程以手机EOS钱包的完整开发过程为主线,深入学习EOS区块链应用开发,课程内容即涵盖账户、计算资源、智能合约、动作与交易等EOS区块链的核心概念,同时也讲解如何使用eosjs和eosjs-ecc开发包访问EOS区块链,以及如何在React前端应用中集成对EOS区块链的支持。课程内容深入浅出,非常适合前端工程师深入学习EOS区块链应用开发。 Hyperledger Fabric 区块链开发详解 ,本课程面向初学者,内容即包含Hyperledger Fabric的身份证书与MSP服务、权限策略、信道配置与启动、链码通信接口等核心概念,也包含Fabric网络设计、nodejs链码与应用开发的操作实践,是Nodejs工程师学习Fabric区块链开发的最佳选择。 Hyperledger Fabric java 区块链开发详解 ,课程面向初学者,内容即包含Hyperledger Fabric的身份证书与MSP服务、权限策略、信道配置与启动、链码通信接口等核心概念,也包含Fabric网络设计、java链码与应用开发的操作实践,是java工程师学习Fabric区块链开发的最佳选择。 tendermint区块链开发详解 ,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。
汇智网原创翻译,转载请标明出处。这里是 Hyperledger Fabric 开发环境安装
区块链
2019-07-04 15:41:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
在本教程中,我们将学习如何使用以太坊的Whisper协议创建简单的聊天CLI。尽管本教程中的所有操作都在你的控制台中进行,但是你应该能够重新使用我们在你自己的应用程序中提供的JS,并对如何发送和显示不同类型的消息有一个很好的了解,以及使用Whisper可以构建什么。
我们了解到,没有多少DAPP开发人员希望以状态的方式使用Whisper(作为一个庞大的多用户消息传递协议),而是将有关DAPP中与其交互的特定(通常是重要的)信息移动。本教程旨在为你提供所需的技能,以适应你的需要:你应该既知道足够容易插入到任何状态聊天,以及如何使用Whisper为你自己的工作到最后。许多其他团队已经开始这样做了,例如,你可以在 Bloom blog 上找到更多关于如何将基本概念扩展到有趣系统的信息。
我们专门为本教程创建了这个存储库。如果你想帮助社区,可以在不同的分支下添加额外的教程。不过,在克隆存储库之前,让我们确保正确设置了所有依赖项,尤其是nodejs和go-ethereum。我们将使用最新版本的Geth、Whisper和EmochtJS来帮助你了解Whisper今天的样子。
NodeJS 8.10+ node version > 8.10+
如果需要更新节点,请 install nvm 并安装/使用LTS版本。下面为你提供了macos/linux命令: curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash nvm install --lts nvm use lts
Go-ethereum 1.8.17+ geth version > 1.8.17+
如果你需要 install geth ,你可以使用下面的MacOS命令: brew tap ethereum/ethereum brew install ethereum /* Just to upgrade */ brew upgrade ethereum
如果你使用的是Linux发行版: sudo add-apt-repository -y ppa:ethereum/ethereum sudo apt-get install ethereum /* Just to upgrade */ sudo apt-get update ethereum
启动geth节点
要使用Whisper,你需要一个正在运行的geth节点。可以执行以下命令以使用所需的最小选项启动节点: geth --testnet --syncmode=light --ws --wsorigins=mychat --shh --wsapi=web3,shh,net
这里,我们连接到Ropsten,确保我们没有验证完整的块(只有headers),确保 websockets 使用特定的源(我们稍后将在JS中使用),确保启用了Whisper,即 shh ,并且 web 、 shh 和 net API对我们可用。
设置和浏览
现在我们已经设置了所有的先决条件,我们需要克隆这个repo并安装依赖项。 git clone https://github.com/status-im/whisper-tutorial.git cd whisper-tutorial npm install
安装完所有依赖项后,可以执行 npm start 来查看教程的内容。这非常简单,只是一个cli界面,它允许你使用 默认主题 和一些其他设置发送悄悄消息。下面我们将介绍如何发送公共和私人消息。为了更好地理解我们为什么要执行以下步骤并更详细地了解我们引入的每个概念,请在完成此操作时阅读上面的 扩展功能 部分。
你可以随时使用 ctrl+c 关闭应用程序。
对聊天客户端进行编码
文件 src/index.js 中充满了我们需要处理的 todo 。以下各节详细介绍了我们将如何以逻辑方式完成这些操作。在每个部分的末尾,可以执行 npm start 以查看进度。
TODO:Web3连接
为了通过Whisper进行交流,我们需要一个Web3连接。确保 geth 正在运行后,我们可以使用以下代码连接到节点: // Web3 connection const web3 = new Web3(); try { web3.setProvider(new Web3.providers.WebsocketProvider("ws://localhost:8546", {headers: {Origin: "mychat"}})); await web3.eth.net.isListening(); } catch(err) { process.exit(); }
调用web3并告诉它将其 provider 设置为正在运行的geth实例(使用上面的选项),将使cli能够连接到我们的节点。它使用 geth 命令的 --wsorigins 标志中指定的源代码 mychat 。如果无法连接,聊天窗口将关闭。
TODO:生成密钥对
我们需要生成一个密钥对,用于对发送的消息进行签名。我们将使用相同的密钥对来接收和解密私有消息。这与调用通过 shh API公开的函数一样简单: // Generate keypair const keyPair = await web3.shh.newKeyPair();
TODO:生成对称密钥
Public 消息是使用对称密钥和主题加密的消息。它们不会针对特定的任何人,而是由在特定频道中收听的任何人接收。在聊天应用程序中,我们的频道由一个共享对称密钥表示,该密钥的 password 就是我们将要使用和收听的频道: // Generate a symmetric key const channelSymKey = await web3.shh.generateSymKeyFromPassword(DEFAULT_CHANNEL);
TODO:获取公钥
我们需要为自己生成公钥,以便能够将自己标识为通过我们的通道发送和接收的作者消息。这是通过以下代码完成的: // Obtain public key const pubKey = await web3.shh.getPublicKey(keyPair);
TODO:发送公共消息
一旦生成了对称密钥,就可以使用 web3.shh.post 发送消息。我们将用 密钥对 签署我们的消息,并将其发送到特定的主题。 // Send a public message web3.shh.post({ symKeyID: channelSymKey, sig: keyPair, ttl: TTL, topic: channelTopic, payload: web3.utils.fromAscii(message), powTime: POW_TIME, powTarget: POW_TARGET }); topic ,是一个4字节的十六进制字符串,可用于筛选消息。 TTL ,是以秒为单位的生存时间。 powtime ,是用于工作证明的最长时间(秒)。 pow target ,是此消息所需的最小pow目标。
TODO:订阅公共聊天消息
你可能已经注意到你发送的消息没有显示在屏幕上。为了在Whisper中看到消息,我们需要订阅 subscribe 对称密钥接收的消息。我们还可以使用相同的主题创建过滤器: // Subscribe to public chat messages web3.shh.subscribe("messages", { minPow: POW_TARGET, symKeyID: channelSymKey, topics: [channelTopic] }).on('data', (data) => { // Display message in the UI ui.addMessage(data.sig, web3.utils.toAscii(data.payload)); }).on('error', (err) => { ui.addError("Couldn't decode message: " + err.message); });
添加此代码后,打开聊天应用程序的两个实例并编写一条消息。你将看到它如何在两个窗口中显示。唯一的问题是,任何收听此频道的人都可以看到你所写的所有消息,所以让我们通过添加私有消息来解决这个问题。
TODO:发送私人消息
为了发送私人消息,我们有一个类似于irc的命令: /msg 0xcontact_public_key message 。因此,如果你想发送消息,只需从chat cli复制联系人的公钥,然后编写消息。
我们已经将联系人的公钥分配给 contactcode 变量,并将消息的正文分配给 messagecontent 。向特定的非对称公钥发送消息与向对称密钥发送消息类似。区别在于,你需要指定 pubkey 属性而不是 symkeyid 。 // Send private message web3.shh.post({ pubKey: contactCode, sig: keyPair, ttl: TTL, topic: channelTopic, payload: web3.utils.fromAscii(messageContent), powTime: POW_TIME, powTarget: POW_TARGET }); 在Ubuntu中,你需要按 shift 并拖动鼠标以选择联系人的公钥。
TODO:订阅私人消息
与从公共通道接收消息类似,我们需要创建一个订阅来接收私有消息,将其用作 privatekeyid 我们的 keypair ,以便订阅接收发送到公共密钥的消息。 // Subscribe to private messages web3.shh.subscribe("messages", { minPow: POW_TARGET, privateKeyID: keyPair, topics: [channelTopic] }).on('data', (data) => { ui.addMessage(data.sig, web3.utils.toAscii(data.payload), true); }).on('error', (err) => { ui.addError("Couldn't decode message: " + err.message); });
添加此代码后,继续打开聊天应用程序的三个实例,在一个窗口中编写一条公共消息,在另一个窗口中复制公共密钥并向创建第一条消息的帐户发送一条私有消息。第一个和第二个窗口将能够看到消息,但第三个窗口将只接收到公共消息。
最后的想法
如你所见,使用Whisper进行去中心化通信非常容易,你可以利用该协议来传递加密安全的链外消息。布鲁姆这样做了,正如 Project Khoka in South Africa 等。
但是,目前没有足够的在线节点可以启用低语(可能是因为缺乏运行此功能的激励措施),因此,除非你像我们在状态下这样引导某些节点,否则消息可能无法传递。你可以通过在启用了 --shh 选项的情况下运行自己的节点来增加可用节点的数量。我们将永远比你少3。
======================================================================
分享一些比特币、以太坊、EOS、Fabric等区块链相关的交互式在线编程实战教程: java比特币开发教程 ,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。 php比特币开发教程 ,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。 c#比特币开发教程 ,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在C#代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是C#工程师不可多得的比特币开发学习课程。 java以太坊开发教程 ,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。 python以太坊 ,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。 php以太坊 ,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。 以太坊入门教程 ,主要介绍智能合约与dapp应用开发,适合入门。 以太坊开发进阶教程 ,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。 ERC721以太坊通证实战 ,课程以一个数字艺术品创作与分享DApp的实战开发为主线,深入讲解以太坊非同质化通证的概念、标准与开发方案。内容包含ERC-721标准的自主实现,讲解OpenZeppelin合约代码库二次开发,实战项目采用Truffle,IPFS,实现了通证以及去中心化的通证交易所。 C#以太坊 ,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。 EOS入门教程 ,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。 深入浅出玩转EOS钱包开发 ,本课程以手机EOS钱包的完整开发过程为主线,深入学习EOS区块链应用开发,课程内容即涵盖账户、计算资源、智能合约、动作与交易等EOS区块链的核心概念,同时也讲解如何使用eosjs和eosjs-ecc开发包访问EOS区块链,以及如何在React前端应用中集成对EOS区块链的支持。课程内容深入浅出,非常适合前端工程师深入学习EOS区块链应用开发。 Hyperledger Fabric 区块链开发详解 ,本课程面向初学者,内容即包含Hyperledger Fabric的身份证书与MSP服务、权限策略、信道配置与启动、链码通信接口等核心概念,也包含Fabric网络设计、nodejs链码与应用开发的操作实践,是Nodejs工程师学习Fabric区块链开发的最佳选择。 Hyperledger Fabric java 区块链开发详解 ,课程面向初学者,内容即包含Hyperledger Fabric的身份证书与MSP服务、权限策略、信道配置与启动、链码通信接口等核心概念,也包含Fabric网络设计、java链码与应用开发的操作实践,是java工程师学习Fabric区块链开发的最佳选择。 tendermint区块链开发详解 ,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。
汇智网原创翻译,转载请标明出处。这里是 以太坊Whisper协议
区块链
2019-07-04 15:35:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
如果说什么是区块链的灵魂,那一定是共识机制。
它是区块链的根基。无论公链或是联盟链,共识机制都从基础上限制了区块链的交易处理能力和扩展性。
2019年6月18日,Facebook 发布了自己 Libra 项目的白皮书,引发广泛关注。作为 Facebook 试图创造国际流通数字货币的重要项目,Libra 区块链采用的是 LibraBFT 共识机制,是一个为 Libra 设计的鲁棒的高效的状态复制系统。它基于一种新型的 BFT 共识算法,HotStuff。
就在 Facebook Libra 项目白皮书发布之前不久,5月17日,比原链发布了 BaaS 平台 Bystack。这是一个一主多侧链架构的商用区块链系统,主链采用 PoW 共识保证多样资产安全和去中心化,侧链提供可插拔的共识以满足不同业务需求。同时,Bystack 本身还针对侧链独创了一种 DPoS+BBFT 的共识算法。
同样是 BFT 类共识机制,LibraBFT 和 BBFT 两者有什么不同呢?
区块链共识机制的意义和现状
共识(Consensus)是分布式系统中节点对数据或网络最终状态达成的协议。由于网络环境和节点状态的不可控,共识机制需要同时考虑性能、可靠性、安全性等多方面问题。
共识机制从大的方面,可分为 PoW 等中本聪共识机制,和拜占庭容错(BFT)类共识机制两大类。BFT 共识机制广泛应用于各类联盟链。
PoW 共识在非许可(Permissionless)链上应用广泛,但是它的概率模型在提供较高可靠性的同时,牺牲了效率,浪费了大量计算资源。在具体商业应用环境中,许可(Permissioned)机制已经保证了一定程度上的节点可信度(Semi-Trust)。这样的前提下,用户更关心执行效率(TPS)和最终确定性(Finality)。这是BFT共识在联盟链中流行的原因。
BFT共识机制
BFT( Byzantine Fault Tolerance)即拜占庭容错。它是分布式计算容错技术。
由于硬件错误、网络拥塞或中断、以及遭到恶意攻击等原因,计算机和网络可能出现不可预料的行为。拜占庭容错技术被设计用来处理这些异常,在容错的基础上达成共识。
与从比特币衍生出的中本聪共识不同,在BFT类协议中,一旦达成共识,则直接形成确定性结果,而不是中本聪共识的概率上的最终一致。
BFT 类共识在金融场景及联盟链场景中应用甚广。同时随着技术进步,公有链场景下应用的 BFT 共识也在不断出现。
PBFT 共识机制
实用拜占庭容错算法(Practical Byzantine Fault Tolerance Algorithm,PBFT)是首个实用的在异步分布式网络中实现拜占庭容错的共识算法。
PBFT 算法可工作在异步环境中,并且优化了原始拜占庭容错算法效率不高的问题,将算法复杂度由指数级降低到多项式级,使得拜占庭容错算法在实际系统应用中变得可行——这点已得到广泛验证。PBFT 算法可以在失效节点不超过总数1/3的情况下同时保证一致性(Safety)和交付保证(Liveness)。
无论 Facebook Libra 的 LibraBFT 共识协议,还是比原链 Bystack 的 BBFT共识机制,都在底层上充分吸收了 PBFT 的优点,采用了已有的经过时间验证的处理方式,并在 PBFT 的一些短板和不足之处分别做出了各自不同方向的革新。
Facebook Libra 的 LibraBFT 共识协议
前面已经说到,Libra 采用基于 HotStuff 的 LibraBFT 共识。
HotStuff 是一个三阶段的 BFT 算法。它将视图切换流程和正常流程进行合并,不再有单独视图切换流程,降低了视图切换的复杂度。
在 HotStuff 中切换视图时,系统中的某个节点无需确认「足够多的节点希望进行视图切换」这一消息再通知新的主节点,而是可以直接切换到新视图并通知新主节点。HotStuff 把确认「足够多的节点希望进行视图切换」这一消息的行为放进了正常流程中。由此把 PBFT 的两阶段确认扩展成了三阶段确认。
HotStuff 的另一个重要改变,是将 PBFT 的网状通信网络拓扑变成了星形通信网络拓扑。HotStuff 中,每次通信都依靠主节点。节点不再通过 p2p 网络将消息广播给其它节点,而是将消息发送给主节点,由主节点处理后发送给其它节点。得益于星型通信网络拓扑,系统的通信复杂度大大降低。和 PBFT 类似,主节点会提议进行状态迁移,其它节点收到该状态迁移要求后,会检查其合法性。
LibraBFT 在 3f+1 个验证节点之间收集投票,这些验证者可能是诚实的节点也可能是拜占庭节点。在网络中存在 2f+1 个诚实节点的前提下,Libra能够抵御 f 个验证节点的双花攻击和分叉攻击。
LibraBFT在一个有全局统一时间(GST),并且网络最大延时(ΔT)可控的部分同步网络中是有效的。并且,LibraBFT在所有验证节点重启的情况下,也能够保证网络一致性。
比原链 Bystack 的 BBFT共识机制

根据 Bystack 白皮书,BBFT 是一种基于实用拜占庭容错 PBFT 的衍生共识,是一种分层拜占庭容错共识算法。在保证拜占庭容错,即允许少量节点(f≤N/3)作恶的情况下,具有以下特性:
(1)配置性(Configurable)
采用模块化可插拔设计,按需配置,并在一定程度上保证对新技术的兼容(Future-Proof)。
这是 Bystack 的一个核心竞争点。跨链概念近几年一直有受到广泛关注,也是区块链发展的重要方向。支持模块化的插拔,使得 Bystack 拥有跨链方向的想象空间,有能力形成一个真正扩展性强、能兼容其他主流共识机制的区块链系统。
这样的兼容能力使得 BBFT 有能力让其他的联盟链公链成为自己的侧链,让自己不仅仅是一个区块链操作系统,而且形成一个区块链操作系统生态。这样一来,想象空间就大了。
不过当然,要达到这样的程度,技术实现上可能任重道远。兼容性是一个动辄消耗大量研发成本的方向,它不难,但是繁琐。BBFT 很难一步登顶一开始就做到最好,目前只能一步一步来。
(2)适应性(Adaptive)
即针对不同网络环境提供稳定的执行效率。
BFT 需要节点之间互相交换验证结果以取得多数共识。一般来说,每个节点需要得到足够多(≥(2/3)*N)的来自其他节点的回复才能做出有效判断。网络延时直接影响信息交互效率,特别在跨地域跨境应用中,延时将成为网络运行的瓶颈。
在 BBFT 中,共识节点维护当前网络拓扑,按最短路径原理相近的节点采取优先通信。对通信的聚合可以进一步降低延时。同时类似PBFT,BBFT 中领导节点(Leader)的角色被弱化,共识节点拿到超过2/3票数就可以做出判定,从而在领导节点通信受到阻塞的情况下,也不会对整个网络决策产生巨大影响。
(3)扩展性(Scalable)
保证共识复杂度随网络容量线性(Linear)或低于线性(Sub-Linear)增加。
一方面共识节点越多网络的可靠性相对越高;另一方面,传统 PBFT 中节点通信的复杂度 O(N^2) 随网络容量指数级增长,极大限制了节点数目。BBFT中对消息的有效聚合可以有效减少消息发送的次数,从而保证 O(N) 的复杂度要求。与网络拓扑相结合,可以把网络分割为多层结构,消息数据可以在同层内有效共享,以多签聚合的形式跨层传播。多签信息验证可以使用现有的成熟的
方案,例如基于 Shnorr 签名的 MuSig 算法,可以在保证多签验证效率的同时,抵御Rogue Key Attack攻击。
(4)异构性(Heterogeneous)
分离共识的验证和通信。
共识达成需要验证和通信,但两者并没有很强的关联。采取低耦合的共识框架可以进一步提高网络可靠性和效率。
验证模块往往取决于具体用户逻辑,对算力和安全性都有一定要求。通信模块和用户逻辑相对独立,主要处理网络连接和请求。网络拓扑和最短路径的计算和选择可以在这里完成。由于和用户逻辑无关,通信模块可以以抽象层(AbstractionLayer)或者中间件(Middleware)的形式和验证对接。
异构带来的优势还体现在用最优的工具做最适合的事。验证和通信允许运行在不同的系统上、不同的操作环境中,针对不同硬件的算力优势和安全保证(TrustZone)来发挥最大效能。
BBFT 的两大主要特点在于:
多层结构。根据网络进行分层。传统 BFT 是单层结构,只有一个领导节点和若干处于同等地位的共识节点。BBFT 的创新在于大领导下面还有小领导,如果领导出问题,不至于对网络产生较大影响,相当于弱化了领导的作用。而且由于是多层结构,可以把网络通信分流再组合,优化网络通信的延时和数量。
传统 PBFT 的通信复杂度是指数级的,难以扩展,网络里面随着节点数暴涨,整个网络延迟可能很严重。BBFT 通过分层和加密签名的聚合,对整个网络结构有效组合,可以保证通信复杂度线性增长,而不是指数级增长。
可配置性。Bystack 上的侧链工程其实分三个模块,一是底层共识算法,二是网络划分,三是签名聚合。其中,网络划分和签名聚合是相对独立的模块,可以使用不同的网络分层算法、签名聚合算法与共识层的算法进行搭配。可以根据具体用户场景灵活选用不同的合理方案。
LibraBFT vs BBFT:共同和差异
LibraBFT 将 PBFT 的网状通信网络拓扑变成了星形通信网络拓扑,以降低系统通信复杂度;BBFT则使用多层结构把网络通信分流再组合,优化网络通信的延时和数量。
LibraBFT 将视图切换流程和正常流程进行了合并,把 PBFT 的两阶段确认扩展成了三阶段确认;BBFT 则将经典 BFT 算法中产生、预最终状态与最终状态三个状态修改为只有一个最终确认状态。
两者都可看做是 PBFT 共识的升级,吸收了现有 BFT 类共识的成果和优点,并在此基础上做出不同方向的扩展。LibraBFT 共识机制更多是 PBFT 基础上的一种革新,更多关注算法本身,对 PBFT 有很多修改和优化的方面;BBFT 更多是在层级上进行分层控制,更多是一种系统全局思维。BBFT 希望达到的,不只是一种高效的共识机制,更是能融合其他共识机制的共识机制。维度上,BBFT 是可以让 LibraBFT 直接接入,在侧链上利用对方所有优势的。LibraBFT 是第一序改变,BBFT 是第二序改变。
可以明显看出,Bystack 更加关注利用好现有共识机制,将不同的共识机制整合、取长补短,这在 Bystack 整体架构上表现就十分突出,比如主侧链采用不同共识并有机结合、侧链使用 DPoS+BBFT 的混合共识算法并具备可配置性……Bystack 不只是想做区块链的操作系统,它实际上有做操作系统的操作系统的意思。
区块链共识机制的研究,已经进行很长一段时间,但从 PoW 共识提出到现在,并没有说得上范式突破的进展。
也许让区块链兼容其他链的共识机制,实现平滑跨链,让任何一条链都可以作为一个侧链接入进来,可以成为区块链方向的一个范式突破,带来全新的想象空间。也许这也是现在跨链概念比较火爆的原因。
也许正像 Bystack 共识算法负责人王炜所说,“单一公链单一算法”这种模式已经行不通了,因为用户场景实在太多,一条公链是解决不了所有问题的。
作者:蜂鸣
区块链
2019-07-03 15:19:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
供应链是区块链的一个应用领域,具有早期发展和相对较高的成熟度。近年来,区块链作为一种新兴的应用模式在不同行业得到了广泛的应用特别是数字货币http://www.gendan5.com/digitalcurrency/btc.html。包括金融、物联网、社会福利、供应链等领域,都有许多探索和尝试的应用。其中,供应链领域因其市场规模大、多信托主体、多协作而成为备受瞩目的区块链技术。
传统供应链的局限性
供应链可被视为供应商、制造商、仓库、分销中心和渠道供应商的网络。供应链概念的核心是在主体之间建立信任与协作,形成以前松散的企业链,整合离散链信息收集。随着供应链范围的不断扩大,企业通过有效的供应链管理来协调自身和外部资源,以满足市场需求。在供应链中,资本流动、信息流和实际物流之间的相互作用极其难以协调。传统的单一连锁业主核心企业协调模式已不能满足多样化、快速发展的市场需求。
在这种模式下,虽然核心企业在整个供应链管理系统中以连锁所有人的身份存在,但由于其对供应链上游和下游的控制有限,存在不对称和不透明的信息问题,甚至信息造假和篡改的风险。一方面,这些问题将使核心企业难以将供应链管理延伸到上游和下游。另一方面,这将使核心企业难以确保供应链中的物流、信息流和金融流的合理整合,导致管理能力和需求的不对称。随着供应链管理技术的发展,市场上出现了一系列帮助供应链提升协同水平的工具,如vmi供应商管理库存、jit即时交付、供应链融资1n模型.然而,这些工具始终依赖于核心企业的统一规划和协调,而不是上游和下游企业之间的直接沟通和协作,仍然难以有效解决问题。
区块链技术应用供应链
区块链提供的信托合作机制为解决供应链中的多重协作等问题提供了可靠的技术支持。根据供应链的技术特点,分析了产业链给供应链带来的创新。
1、阻止供应链数据存储
供应链更加强调数据保存和可搜索性的深度,确保所需记录可追溯到过去的交易层。它的核心是根据其他组件为每个产品创建一个源。区块链技术独特的数据存储方法使得原材料信息涉及到供应链、组件生产信息、每一商品运输信息以及成品的每一数据永久地以区块形式存储在供应链上。根据供应链上企业之间记录的各类信息,容易将数据追溯到源头,也有助于解决假冒伪劣产品等问题。通过这种数据存储,区块链框架满足供应链每个参与者的需要:输入和跟踪原材料来源;记录部件生产的遥测数据;跟踪航运商品的来源。
2、在传统供应链中防止篡改数据
数据大多由核心企业或参与企业以分散和孤立的方式集中保存。当账本上的信息对自己不利时,就存在着账户信息被篡改或者被私下删除的风险。分组链技术中数据的非篡改性和时间戳性质确保所有数据,包括成品的生产、储存、运输、销售和跟踪,不被篡改。数据不被篡改,信息不对称性大大降低,企业间信用征信和通信成本降低。这一应用有助于企业快速建立信任,同时又能分担核心企业所承担的风险。块链技术确保了供应链上游和下游之间数据的无损流动,并有效避免了信息的失真和失真。
国内外供应链应用现状
供应链领域中区块链技术的应用使制造商和分销商能够更有效地监测货物流动,并充分调动供应链上的资源。对于消费者来说,他们对商品的来龙去脉有了更直观、更可靠的理解。
基于块链技术的物流平台可以有效地解决物流运输领域的订单数据分散和信息不透明的问题。用户可以通过连接互联网的设备来监视目标对象,并以透明的方式跟踪货物的来源和中间交易过程。在区块链上,您不仅可以查看产品的静态属性信息,还可以监视产品从生产商到经销商到终端消费者的过境运输过程,跟踪整个产品生命周期,并提高行业整体效率。近年来,国内外许多企业积极探讨了区块链在可追溯性、物流、供应链融资等领域的应用。
区块链技术正逐渐渗透到传统的供应链服务中。例如,马士基联合保险机构、区块连锁公司和其他各方共同建立了世界上首个海上保险区块连锁平台,形成了跨行业的连锁联盟;沃尔玛,世界最大的零售商,已经完成了在中国使用块链技术跟踪猪肉生产和销售全过程的试验计划,大大缩短了跟踪时间。
区块链
2019-08-15 16:13:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
除了数字货币的应用,区块链技术也可以应用于许多市场。根据区块链的分散性质,将使用大量数据,这些数据需要存储和管理。分散存储将整合区块链技术的最佳功能,以满足存储大量数据的实际需求。顾名思义,分散存储可以将数据分发到多个网络节点,类似于区块链的分布式分类账技术。区块链存储是指由区块链励磁构建的分散存储系统,是区块链和存储系统的有效结合。区块链存储池将全局存储节点池化为一个大规模的全局统一共享存储池。
存储是以数字货币http://www.gendan5.com/digitalcurrency/btc.html形式存在的实体经济。其上行链路的过程可以完全由代码控制。此外,分布式存储可以通过将数据分布在多个位置来提高数据的可靠性、可用性、容灾性和其他特性。此外,存储还具有重复数据消除的特性,即用户越多,成本越低,这适合使用区块链刺激。”据优泰连锁创始人王林东称,正是基于以上几点,存储成为区块链技术的最佳登陆应用场景。
目前主流的单一系统甚至云数据库都是集中存储,存储服务器的结构相对容易受到黑客的攻击。或者存储服务器系统受到外围环境的影响,例如电源故障,并且它们仍然有明显的故障点。相比之下,区块链分散存储可以有效避免这些问题,因为它利用分布在不同地方的区域或全局节点。
与企业存储和云存储相比,区块链存储的优势主要体现在四个方面:
1.更高的可靠性
区块链存储在全球数千万个节点上存储数据,不是以多拷贝模式,而是以更高级的冗余编码模式。这有效地避免了单点故障的负面影响。只有在硬盘出现故障的情况下,区块链存储的可靠性才比云存储高几个数量级。
2.服务的高可用性
区块链存储还通过将负载分配给各地的节点来提高可用性。就服务可用性而言,区块链存储比云存储更高效。
3、成本较低
区块链存储成本低的根本原因是区块链技术有很好的解决数据重复率移除问题的能力,可以将成本降低5-10倍。同时,区块链存储可以降低数据冗余率,从而降低成本。此外,每个存储节点的建设成本也较低。据介绍,区块链采用的边缘节点架构需要更少的硬件,这远低于构建集中式数据存储中心的成本。
4.不同地方的容灾能力更强
对于传统的集中存储,两地三中心一般都属于容灾级别最高,建设成本高,这也是目前世界上许多大型企事业单位容灾率很低的原因之一。然而,区块链仓储的“数千个场所、数万个中心”特征可以显著提高容灾水平,将集中仓储奢侈品的“容灾”转化为标准。
值得一提的是,行业专家指出,区块链的边缘存储系统不需要特殊冷却。集中式数据存储中心的制冷需要一个特殊的制冷系统。在该制冷系统的运行过程中,能耗约为服务器能耗的0.5-1倍,这导致了大量的能耗成本支出。而区块链的边缘节点可以作为存储采矿机器自然冷却。
对于目前的数据存储服务提供商来说,最重要的是区块链节点存储服务器设备不是由一家公司拥有,而是属于许多个人。购买数据存储服务的客户可以获得一个全新的供应市场,而不是他们现在面临的寡头垄断市场。
尽管在集中存储中,企业通过内部控制来保存机密数据。然而,在区块链存储中,数据分布在世界各地,不能通过内部控制保密。因此,数据必须加密。对此,YottaChain创始人王林东表示,区块链存储技术的核心在于分布式架构技术和加密技术。在他看来,加密和重复数据消除这两项看似矛盾的技术的结合,将成为中国区块链项目脱颖而出的决定性优势。
区块链分散式数据存储应该成为公众的第一选择,也许时机已经来临。在这个数据量爆炸式增长的时代,它肯定会提供一个更加安全、有趣和可扩展的数据存储解决方案。
区块链
2019-08-29 15:44:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
理解中心化数字货币交易平台上的交易行为需要对它的几种钱包地址进行分析,本文采用可视化的方法来展示不同类型钱包地址之前的交易模式。
在数字货币交易平台上主要有四种类型的钱包地址: 热钱包地址:热钱包是外部和交易所之间的主要交互点。交易平台使用这种 钱包来保证数字资产的交易。 冷钱包地址:交易平台使用冷钱包作为数字加密资产的安全存储。这种 类型的钱包通常会持有大量不需要频繁交易的资产 充值/入金地址:通常是临时性的链上地址,用于将数字资产转入交易平台以便 进行交易。 提现/出金地址:通常是临时性的链上地址,用于将数字资产转出交易所 钱包。有时提现地址和充值地址可以用一个。
这四个组件构成了中心化交易平台的链上架构的核心, 要识别出一个地址属于哪一种需要复杂的假设或机器学习方法。部分挑战在于这些地址间的交互模式可以非常复杂并且还没有被很好的理解。我们利用机器学习分类器的帮助,通过可视化手段来探索区块链数据集,发现了一些迷人的模式。
1、充值地址 -> 交易所主钱包
数字货币交易平台的一个主要模式就是将资产从入金地址转入交易所主钱包。下面的可视化图形清晰地展示了这种运作模式,其中蓝圈表示充值地址,绿圈表示住钱包地址。值得注意的是,这一资金归集操作通常会将许多入金地址打包到单一交易中转入主钱包:
这一模式可以在更大规模观察到:
2、交易所主钱包 -> 提现地址
中心化交易平台的另一个传统模式是发送交易到提币地址。下面的可视化图形 展示了这一模式,其中橙色圈表示提币地址,绿圈表示交易所主钱包:
3、提现地址@A交易所 -> 充值地址@B交易所
有时候,一个交易平台的提现地址,会作为另一个交易平台的充值地址。下图 展示了这一模式。篮圈表示充值地址,绿圈表示提现地址:
4、跨交易所转账
下图展示了Poloniex和币安之间的转账模式:
如果你想学习区块链并在Blockchain Technologies建立职业生涯,那么请查看我们分享的一些以太坊、比特币、EOS、Fabric等区块链相关的交互式在线编程实战教程: java以太坊开发 ,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。 python以太坊开发 ,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。 php以太坊开发 ,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。 以太坊开发入门 ,主要介绍智能合约与dapp应用开发,适合入门。 以太坊电商DApp开发 ,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。 ERC721通证实战 ,课程以一个数字艺术品创作与分享DApp的实战开发为主线,深入讲解以太坊非同质化通证的概念、标准与开发方案。内容包含ERC-721标准的自主实现,讲解OpenZeppelin合约代码库二次开发,实战项目采用Truffle,IPFS,实现了通证以及去中心化的通证交易所。 C#以太坊 ,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。 java比特币开发 ,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。 php比特币开发 ,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。 c#比特币开发 ,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在C#代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是C#工程师不可多得的比特币开发学习课程。 EOS开发入门 ,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。 EOS钱包开发 ,本课程以手机EOS钱包的完整开发过程为主线,深入学习EOS区块链应用开发,课程内容即涵盖账户、计算资源、智能合约、动作与交易等EOS区块链的核心概念,同时也讲解如何使用eosjs和eosjs-ecc开发包访问EOS区块链,以及如何在React前端应用中集成对EOS区块链的支持。课程内容深入浅出,非常适合前端工程师深入学习EOS区块链应用开发。 Hyperledger Fabric Node.js开发 ,本课程面向初学者,内容即包含Hyperledger Fabric的身份证书与MSP服务、权限策略、信道配置与启动、链码通信接口等核心概念,也包含Fabric网络设计、nodejs链码与应用开发的操作实践,是Nodejs工程师学习Fabric区块链开发的最佳选择。 Hyperledger Fabric java 开发 ,课程面向初学者,内容即包含Hyperledger Fabric的身份证书与MSP服务、权限策略、信道配置与启动、链码通信接口等核心概念,也包含Fabric网络设计、java链码与应用开发的操作实践,是java工程师学习Fabric区块链开发的最佳选择。 tendermint开发 ,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。 Flutter以太坊开发 ,主要是针对Flutter/Dart程序员进行区块链以太坊开发的web3Dart详解。
原文链接: 数字货币交易平台的可视化分析 — 汇智网
区块链
2019-09-19 09:45:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
“数据隐私问题、系统主导权争议与性能抉择两难是目前区块链应用落地难的三大因素。”平安金融壹账通区块链团队产品负责人,高级产品总监王梦寒在2019年中国国际大数据产业博览会发表演讲时指出,金融壹账通的区块链FiMAX解决方案已突破瓶颈,实现金融业务场景中的大规模应用。
2019数博会在贵阳隆重开幕,数博会作为全球首个大数据主题博览会,已成功举办了四届,已成为大数据领域的风向标,对产业及相关技术领域产生了深远的影响。在本次会议上,中共中央总书记、国家主席、中央军委主席习近平指出,当前,以互联网、大数据、人工智能为代表的新一代信息技术蓬勃发展,对各国经济发展、社会进步、人民生活带来重大而深远的影响。区块链同样成为各方关注的重点。
金融壹账通打破区块链落地三大瓶颈
近年来,区块链技术非常火爆,各家科技公司、金融机构纷纷抢占风口,发展区块链技术,但是真正能将区块链技术应用在金融场景的少之又少,具体而言还是由于数据隐私问题、系统主导权争议与性能抉择两难等原因难以攻破。在此次会议上,金融壹账通向行业分享了FiMAX解决方案是如何打破瓶颈,实现大规模落地的。
数据隐私问题。传统区块链技术由于竞争对手需要共享账本信息、存在数据隐私泄露风险,同时数据安全及风控难度非常大,许多金融机构不敢“上链”。针对这一难题,FiMAX解决方案打造了全加密区块链框架,运用字段级可授权加解密、3D零知识证明等前沿密码学方案。区块链技术中的加密算法,可以对机构上传的数据进行加密,在链上以密文的形式进行共享。只有拥有私钥的数据所属方,才能对其数据进行增加、删除、修改、查看,链上的其他参与方除非获得了此数据所属方的授权,否则无法查看其明文数据。这样保障了数据所属方对数据信息的绝对控制权,也即保障了其利益的不可侵犯。传统零知识证明可以实现密文状态下的信息验证,FiMAX打造的3D零知识证明则更进一步,能够在所有账本全密文状态下,实现加密数据间的四则运算(+ - /)和大小关系验证,且验证时间小于3毫秒。使用3D零知识证明,即使在复杂业务场景下,仍能使链上各参与方,在无需公开己方数据、保证数据隐私安全的前提下,实现信息的验证及使用。
系统主导权争议。谁来主导区块链系统一直是金融机构关心的问题,主要出于担心中心化平台而丢失客户掌控力,针对这一问题,王梦寒在会议上指出,金融壹账通做的不是平台,而是网络。平安不是做数据的收集,平安区块链只做一个事情,就是把大家链在一起,让数据流通。链上参与方加密数据除了自身不会有别人能看,这也是平安区块链技术上的一个创新与应用。
金融壹账通已陆续与香港监管局、天津口岸办等合作,且项目实现落地应用,因此,金融壹账通拥有非常完善区块链联盟的治理架构,以及比较丰富的建设经验。
系统吞吐量与延迟性的两难抉择。传统区块链存在“大区块”高吞吐量高延迟、“小区块”低延迟低吞吐量问题,低延迟与高吞吐量无法兼得,难以满足实际业务场景。FiMAX解决方案打造的智能区块颠覆性优化底层架构,能够在吞吐量和延时性二者间达到平衡状态:实现高频交易时保证高吞吐量,低频交易时保证低延时,能够在低配八核CPU及国密环境下,实现单链平均TPS大于10,000、延迟小于0.01秒,兼得低延迟与高吞吐量,满足金融机构实际业务运行需求,真正发挥区块链作用。
已实现多个项目落地 金融壹账通打造 区块链全球生态网络
平安集团在区块链行业当中部署了五大板块,分别是金融、医疗、汽车、房产、智慧城市。金融壹账通作为平安集团唯一一个区块链底层建设方,同时承接了平安集团所有的区块链应用的需求。尤其是在金融领域,已经有了丰富的区块链项目落地实践经验。平安在“一带一路”沿线国家和地区积极落地区块链应用。由金融壹账通提供技术支持,在香港建成全球首个由监管部门主导的区块链贸易融资平台“贸易联动”,促进跨境贸易融资,赋能粤港澳大湾区,服务“一带一路”。此外,前不久由金融壹账通提供技术支持的天津口岸区块链验证试点项目也正式落地。
金融壹账通还建设了IFAB贸易融资网络,中小银行作为资方链参与到贸融网络当中,同时打通所有物流环节、商流环节、交易环节、支付信息,能对信息进行多方验证,保证这信息真实可靠。金融壹账通建设了庞大的贸易网络,链接银行与广大中小企业,打通贸易融资信息渠道,打破信息孤岛。
最后,王梦寒还指出,金融壹账通仍在扩大区块链网络部署,在香港、新加坡、泰国、马来西亚以及欧洲都已开始进行。
区块链
2019-06-03 21:33:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
身份(Identity)管理是 区块链 应用的核心元素。在一个不可信、匿名的分布计算生态中,要实现去中心化身份管理并不是一件容易的事情。 Sidetree 是一个基于现有区块链平台的第二层(L2s)协议,专门用于去中心化身份管理。微软最新开源的ION项目,就是Sidetree协议基于比特币区块链的一个实现。本文将分6个部分介绍Sidetree去中心化身份管理协议:DID的核心要素、Sidetree协议的起源、概述、工作原理、设计约束与实现进展。
1、去中心化身份管理的核心要素
去中心化身份管理的挑战并不是单一模块的问题。在去中心化应用(DApp)中,一个身份的生命周期中,有一些需要考虑的关键因素:
表示:用来描述主体身份的可迁移表示 持久化:用来存储、提取主体身份的机制,同时还需要保持其隐私 隐私:在去中心化账本中保护主体身份的模型 断言: 确定主体身份的特定语句 解析:解析、验证特定主体身份的机制
2、Sidetree协议的起源
2017年,去中心化身份组织(DIF)的一些成员开始讨论如何在全球级别实现去中心化身份系统。对于大多数去中心化身份系统而言,最下面的一层是区块链/账本,被称为第一层或L1,用来以某种形式支持去中心化的公钥体系(Decentralized Public Key Infrastructure)以及W3C去中心化身份(DIDs:Decentralized Identifiers)。
区块链的的可伸缩性不是小问题,但是目前已经存在一个有前途的思路来解决基于 区块链的系统的伸缩性问题:第二层协议或L2s,例如:状态通道、侧链和比特币 闪电网络。L2s通过确定性(Deterministic)处理与交易方案来实现可伸缩性,这些交易是在区块链之外完成的,只需要在与所依托的底层区块链交互时进行极少的共识处理。
要实现去中心化身份管理,就需要一个大规模运行的系统,同时具备一些核心特性,例如确定性状态解析以及差分持久化。在过去的18个月中,IDF成员间的思想交流最终形成了一个完整的第二层协议: Sidetree 。
3、Sidetree协议概述
Sidetree协议本身并不是去中心化身份(DID)方法,它由一组代码层级的组件构成,包括确定性处理逻辑、内容寻址存储抽象以及可以部署到第一层的去中心化账本(例如:公有链)上的状态验证过程,从而实现无需许可的、第二层DID网络。通过使用特定链相关的适配器,Sidetree协议可以用来在不同的链上创建不同的第二层去中心化身份网络,这些特定链的适配器负责实现与底层区块链的读写交互。
无论底层采用哪种区块链,Sidetree协议的几乎所有实现代码都保持一致,这使得 它可以适用于多种区块链平台。下面是Sidetree系统的总体结构,以比特币作为目标区块链,不过如前所述,这也适用于其他区块链:
Sidetree协议基于一组模块化组件实现,最重要的包括: Sidetree内核 / Sidetree Core : Sidetree内核是主要的逻辑模块,它监听来自底层区块链的交易输入,并使用CAS模块(下面介绍)提取其中的DID操作,然后组合/验证每个DID的状态。 内容寻址存储 / Content Address Storage : CAS(Content Address Storage)模块是一个基于哈希的存储接口,网络中的第二层节点使用该接口来交换彼此识别的DID操作批次,以便进行本地持久化和网络传播。该接口抽象自所使用的特定CAS协议,但是值得指出的是,DIF成员已经为此功能选择了IPFS。 区块链/账本适配器 / Blockchain/Ledger Adapter : 适配器中包含了任何需要读写特定区块链的代码,以便解除Sidetree主体对特定区块链的依赖。不同的底层链需要分别实现不同的适配器。
4、Sidetree协议工作原理
基于Sidetree的L2节点按如下步骤来创建、读取和处理DID操作: 要将批操作写入基于Sidetree的L2网络的节点首先汇集尽可能多的DID/DPKI操作(基于确定性协议规则确定的上限),然后创建一个L1链上交易并在交易中嵌入该操作批次的哈希。 DID操作的源数据由发起节点本地存储,并推送到IPFS网络。当其他节点获知嵌入Sidetree操作的底层链交易后,这些节点将向原始节点或其他IPFS节点请求该批次数据。 当一个节点收到某个批次后,它会将元数据固定到本地,然后Sidetree核心逻辑模块解压批次数据来解析并验证其中的每个操作。目标链的区块/交易体系是Sidetree协议唯一需要的共识机制,不需要额外的区块链、侧链或咨询权威单元来让网络中的DID达成正确的PKI状态。
下面是关于批次与操作嵌入目标区块链的更详细的示意图:
5、Sidetree协议的设计约束
Sidetree协议在设计时做出了一些关键的假设: DIDs不可转让,协议没有提供一个逻辑实体转让、购买或获取其他逻辑实体的DID的途径。这对于DID/DPKI用例是可行的,但是不适用于资金的双花(double spend -- 讨厌这个名词的翻译,一种轻佻的感觉)。 可以延迟揭示嵌入的批次数据,基于确定性规则集进行处理。 DID状态彼此独立,依次一个DID的持有者智能影响它自己的DID的状态。
6、Sidetree协议的实现进展
目前在DIF成员中,有两个团队分别使用Sidetree协议为比特币和以太坊开发L2层的去中心化身份网络。微软主要聚焦于比特币网络,而Transmute Industries则与ConsenSys合作在开发以太坊版本。你可以在 这里 查看微软ION项目的实现代码。
原文: The Sidetree Protocol: Scalable DPKI for Decentralized Identity
汇智网 / Hubwiz.com 翻译整理,转载请标明出处。
区块链
2019-05-31 13:08:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>

本周,加密货币数据追踪网站Coin Dance宣布他们已经将Cashscript项目添加到该网站的BCH开发跟踪中,Cashscript是一种高级语言,它能帮助BCH更轻松的构建类似于以太坊的智能合约。
Cashscript语言
Cashscript是一种由软件工程师Rosco Kalis创建的高级语言,它可以被编译成比特币脚本。
据Kalis介绍,在使用Cashscript方面,他们目前致力于提供一个Javascript软件开发工具包(SDK)来简化集成,该工具包允许开发人员将Cashscript合同插入到任何web应用程序中。
对于Cashscript的工作流程以及语言的语法,Kalis表示他从以太坊的Solidity语言和Web3.js / Truffle库中获得了很多灵感。他强调:“这么做的目的也是为了让任何一个社区的开发人员更容易参与到别的社区”。
Rosco Kalis撰写的关于高级比特币脚本语言的论文截图
Cashscript仍然是一项正在进行的工作,该项目的正式发布还需要一段时间,开发人员在未来几周会进行大量的测试,以保证该项目的正式上线。在接受Bitcoin.com的采访时,Kalis表示,Cashscript可用于实施零确认罚款,该功能可以加强BCH零确认交易抵御双花攻击的能力。
对于Coin Dance的做法,Bitbox创建者Gabriel Cardona认为,Cashscript背后的一个重要动机是支持来自其它系统的开发者,它的意义在于帮助BCH、ETH或者其它社区优秀的开发者们共同创建一个具有通用工作流程和API的智能合约方案。
钱包和信用卡应用程序Crypto
增加了对比特币现金的支持
总部位于香港的加密货币支付平台Crypto.com于5月29日宣布,它已将BCH添加到钱包和信用卡应用程序中。这意味着用户现在可以从他们的服务中购买和花费BCH,系统也支持信用卡和银行转账。
BCH是第21个被加入该平台的数字资产,在这之前,他们平台拥有一些主流币和稳定币,比如BTC、ETH、LTC、PAX等。
BCH.gg帮助爱好者创建BCH相关网站短链接
BCH.gg是一个易于使用的在线工具,由加密市场统计数据网站Coinsalad.com为比特币现金社区开发,其主要目的是解决对URL缩短器的需求,生成可以在Memo、Blockpress或者其它社交网站的短链接。
通过该网站生成的新链接都将以https://bch.gg/开头,后面跟一个唯一的ID,可以是短号,也可以是字母和数字的组合。另外,保存自定义链接ID可以让你查询到统计数据,例如点击次数,来源地区以及时间等。
Electron Cash SLP版本发布
通过钱包发送和创建基于BCH的SLP代币
本周,Electron Cash 钱包3.4.13(SLP版本)发布,SLP版本兼容Mac、Windows和Linus操作系统,在新版中,钱包增加了SLP金额自定义交易功能,基于BCH的SLP令牌现已自动添加“标记”选项,每一个SLP代币都是独特的。
Electron Cash 是一款SPV(简化付款验证)钱包,用户无需下载完整区块链或运行完整节点,私钥在本地签署交易,钱包自带CashShuffle混币功能,在BCH社区一直有着不错的口碑。
区块链
2019-05-31 10:16:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
runtime中打印
因为runtime中没有引入标准库,所以println!就没法用了,可以改用runtime_io::print;
runtime中打印srml_runtime::Trait::Hash
因为srml_runtime::Trait::Hash包含了srml_support::dispatch::Encode,因此可以使用encode方法转成&[u8],然后就可以使用runtime_io::print打印出来了。 runtime_io::print(my_hash.encode().as_slice());
区块链
2019-06-21 11:59:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
1.基础环境搭建 Docker Client 客户端 Docker Daemon 守护进程 Docker Image 镜像 Docker Container 容器
这块的安装相信大家通过资料都可以完成,重点是下面
2.Fabric环境搭建
2.1 创建singlepeer目录 # cd $GOPATH/github.com/hyperledger/fabric # mkdir singlepeer # cd singlepeer
2.2 下载源码文件
下载链接:https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric/hyperledger-fabric/linux-amd64-1.4.1/
把下载的hyperledger-fabric-linux-amd64-1.4.1.tar.gz二进制文件包解压,把其中的bin目录拷贝到singlepeer目录下 ,记得 chmod -R 755 ./bin
2.3 准备生成证书和区块配置文件
配置crypto-config.yaml和configtx.yaml文件,拷贝到singlepeer目录下 crypto-config.yaml # Copyright IBM Corp. All Rights Reserved. # # SPDX-License-Identifier: Apache-2.0 # # --------------------------------------------------------------------------- # "OrdererOrgs" - Definition of organizations managing orderer nodes # --------------------------------------------------------------------------- OrdererOrgs: # --------------------------------------------------------------------------- # Orderer # --------------------------------------------------------------------------- - Name: Orderer Domain: example.com # --------------------------------------------------------------------------- # "Specs" - See PeerOrgs below for complete description # --------------------------------------------------------------------------- Specs: - Hostname: orderer # --------------------------------------------------------------------------- # "PeerOrgs" - Definition of organizations managing peer nodes # --------------------------------------------------------------------------- PeerOrgs: # --------------------------------------------------------------------------- # Org1 # --------------------------------------------------------------------------- - Name: Org1 Domain: org1.example.com EnableNodeOUs: true # --------------------------------------------------------------------------- # "Specs" # --------------------------------------------------------------------------- # Uncomment this section to enable the explicit definition of hosts in your # configuration. Most users will want to use Template, below # # Specs is an array of Spec entries. Each Spec entry consists of two fields: # - Hostname: (Required) The desired hostname, sans the domain. # - CommonName: (Optional) Specifies the template or explicit override for # the CN. By default, this is the template: # # "{{.Hostname}}.{{.Domain}}" # # which obtains its values from the Spec.Hostname and # Org.Domain, respectively. # --------------------------------------------------------------------------- # Specs: # - Hostname: foo # implicitly "foo.org1.example.com" # CommonName: foo27.org5.example.com # overrides Hostname-based FQDN set above # - Hostname: bar # - Hostname: baz # --------------------------------------------------------------------------- # "Template" # --------------------------------------------------------------------------- # Allows for the definition of 1 or more hosts that are created sequentially # from a template. By default, this looks like "peer%d" from 0 to Count-1. # You may override the number of nodes (Count), the starting index (Start) # or the template used to construct the name (Hostname). # # Note: Template and Specs are not mutually exclusive. You may define both # sections and the aggregate nodes will be created for you. Take care with # name collisions # --------------------------------------------------------------------------- Template: Count: 1 # Start: 5 # Hostname: {{.Prefix}}{{.Index}} # default # --------------------------------------------------------------------------- # "Users" # --------------------------------------------------------------------------- # Count: The number of user accounts _in addition_ to Admin # --------------------------------------------------------------------------- Users: Count: 1 configtx.yaml # Copyright IBM Corp. All Rights Reserved. # # SPDX-License-Identifier: Apache-2.0 # --- ################################################################################ # # Section: Organizations # # - This section defines the different organizational identities which will # be referenced later in the configuration. # ################################################################################ Organizations: # SampleOrg defines an MSP using the sampleconfig. It should never be used # in production but may be used as a template for other definitions - &OrdererOrg # DefaultOrg defines the organization which is used in the sampleconfig # of the fabric.git development environment Name: OrdererOrg # ID to load the MSP definition as ID: OrdererMSP # MSPDir is the filesystem path which contains the MSP configuration MSPDir: crypto-config/ordererOrganizations/example.com/msp # Policies defines the set of policies at this level of the config tree # For organization policies, their canonical path is usually # /Channel/// Policies: Readers: Type: Signature Rule: "OR('OrdererMSP.member')" Writers: Type: Signature Rule: "OR('OrdererMSP.member')" Admins: Type: Signature Rule: "OR('OrdererMSP.admin')" - &Org1 # DefaultOrg defines the organization which is used in the sampleconfig # of the fabric.git development environment Name: Org1MSP # ID to load the MSP definition as ID: Org1MSP MSPDir: crypto-config/peerOrganizations/org1.example.com/msp # Policies defines the set of policies at this level of the config tree # For organization policies, their canonical path is usually # /Channel/// Policies: Readers: Type: Signature Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')" Writers: Type: Signature Rule: "OR('Org1MSP.admin', 'Org1MSP.client')" Admins: Type: Signature Rule: "OR('Org1MSP.admin')" AnchorPeers: # AnchorPeers defines the location of peers which can be used # for cross org gossip communication. Note, this value is only # encoded in the genesis block in the Application section context - Host: peer0.org1.example.com Port: 7051 ################################################################################ # # SECTION: Capabilities # # - This section defines the capabilities of fabric network. This is a new # concept as of v1.1.0 and should not be utilized in mixed networks with # v1.0.x peers and orderers. Capabilities define features which must be # present in a fabric binary for that binary to safely participate in the # fabric network. For instance, if a new MSP type is added, newer binaries # might recognize and validate the signatures from this type, while older # binaries without this support would be unable to validate those # transactions. This could lead to different versions of the fabric binaries # having different world states. Instead, defining a capability for a channel # informs those binaries without this capability that they must cease # processing transactions until they have been upgraded. For v1.0.x if any # capabilities are defined (including a map with all capabilities turned off) # then the v1.0.x peer will deliberately crash. # ################################################################################ Capabilities: # Channel capabilities apply to both the orderers and the peers and must be # supported by both. Set the value of the capability to true to require it. Global: &ChannelCapabilities # V1.1 for Global is a catchall flag for behavior which has been # determined to be desired for all orderers and peers running v1.0.x, # but the modification of which would cause incompatibilities. Users # should leave this flag set to true. V1_1: true # Orderer capabilities apply only to the orderers, and may be safely # manipulated without concern for upgrading peers. Set the value of the # capability to true to require it. Orderer: &OrdererCapabilities # V1.1 for Order is a catchall flag for behavior which has been # determined to be desired for all orderers running v1.0.x, but the # modification of which would cause incompatibilities. Users should # leave this flag set to true. V1_1: true # Application capabilities apply only to the peer network, and may be safely # manipulated without concern for upgrading orderers. Set the value of the # capability to true to require it. Application: &ApplicationCapabilities # V1.1 for Application is a catchall flag for behavior which has been # determined to be desired for all peers running v1.0.x, but the # modification of which would cause incompatibilities. Users should # leave this flag set to true. V1_2: true ################################################################################ # # SECTION: Application # # - This section defines the values to encode into a config transaction or # genesis block for application related parameters # ################################################################################ Application: &ApplicationDefaults # Organizations is the list of orgs which are defined as participants on # the application side of the network Organizations: # Policies defines the set of policies at this level of the config tree # For Application policies, their canonical path is # /Channel/Application/ Policies: Readers: Type: ImplicitMeta Rule: "ANY Readers" Writers: Type: ImplicitMeta Rule: "ANY Writers" Admins: Type: ImplicitMeta Rule: "MAJORITY Admins" # Capabilities describes the application level capabilities, see the # dedicated Capabilities section elsewhere in this file for a full # description Capabilities: <<: *ApplicationCapabilities ################################################################################ # # SECTION: Orderer # # - This section defines the values to encode into a config transaction or # genesis block for orderer related parameters # ################################################################################ Orderer: &OrdererDefaults # Orderer Type: The orderer implementation to start # Available types are "solo" and "kafka" OrdererType: solo Addresses: - orderer.example.com:7050 # Batch Timeout: The amount of time to wait before creating a batch BatchTimeout: 2s # Batch Size: Controls the number of messages batched into a block BatchSize: # Max Message Count: The maximum number of messages to permit in a batch MaxMessageCount: 10 # Absolute Max Bytes: The absolute maximum number of bytes allowed for # the serialized messages in a batch. AbsoluteMaxBytes: 98 MB # Preferred Max Bytes: The preferred maximum number of bytes allowed for # the serialized messages in a batch. A message larger than the preferred # max bytes will result in a batch larger than preferred max bytes. PreferredMaxBytes: 512 KB Kafka: # Brokers: A list of Kafka brokers to which the orderer connects. Edit # this list to identify the brokers of the ordering service. # NOTE: Use IP:port notation. Brokers: - 127.0.0.1:9092 # Organizations is the list of orgs which are defined as participants on # the orderer side of the network Organizations: # Policies defines the set of policies at this level of the config tree # For Orderer policies, their canonical path is # /Channel/Orderer/ Policies: Readers: Type: ImplicitMeta Rule: "ANY Readers" Writers: Type: ImplicitMeta Rule: "ANY Writers" Admins: Type: ImplicitMeta Rule: "MAJORITY Admins" # BlockValidation specifies what signatures must be included in the block # from the orderer for the peer to validate it. BlockValidation: Type: ImplicitMeta Rule: "ANY Writers" # Capabilities describes the orderer level capabilities, see the # dedicated Capabilities section elsewhere in this file for a full # description Capabilities: <<: *OrdererCapabilities ################################################################################ # # CHANNEL # # This section defines the values to encode into a config transaction or # genesis block for channel related parameters. # ################################################################################ Channel: &ChannelDefaults # Policies defines the set of policies at this level of the config tree # For Channel policies, their canonical path is # /Channel/ Policies: # Who may invoke the 'Deliver' API Readers: Type: ImplicitMeta Rule: "ANY Readers" # Who may invoke the 'Broadcast' API Writers: Type: ImplicitMeta Rule: "ANY Writers" # By default, who may modify elements at this config level Admins: Type: ImplicitMeta Rule: "MAJORITY Admins" # Capabilities describes the channel level capabilities, see the # dedicated Capabilities section elsewhere in this file for a full # description Capabilities: <<: *ChannelCapabilities ################################################################################ # # Profile # # - Different configuration profiles may be encoded here to be specified # as parameters to the configtxgen tool # ################################################################################ Profiles: OneOrgsOrdererGenesis: <<: *ChannelDefaults Orderer: <<: *OrdererDefaults Organizations: - *OrdererOrg Consortiums: SampleConsortium: Organizations: - *Org1 OneOrgsChannel: Consortium: SampleConsortium Application: <<: *ApplicationDefaults Organizations: - *Org1
2.4 生成公私钥和证书 # ./bin/cryptogen generate --config=./crypto-config.yaml
2.5 生成创世区块
创世区块是为了Orderer排序启动时用到,Peer节点在启动后需要创建Channel的配置文件在这里也一并生成, # ./bin/configtxgen -profile OneOrgsChannel -outputCreateChannelTx ./channel-artifacts/mychannel.tx -channelID mychannel
2.6 部署Orderer节点
2.6.1配置Orderer节点启动文件docker-orderer.yaml # Copyright IBM Corp. All Rights Reserved. # # SPDX-License-Identifier: Apache-2.0 # version: '2' services: orderer.example.com: container_name: orderer.example.com image: hyperledger/fabric-orderer environment: - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=aberic_default # - ORDERER_GENERAL_LOGLEVEL=error - ORDERER_GENERAL_LOGLEVEL=debug - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 - ORDERER_GENERAL_LISTENPORT=7050 #- ORDERER_GENERAL_GENESISPROFILE=AntiMothOrdererGenesis - ORDERER_GENERAL_GENESISMETHOD=file - ORDERER_GENERAL_GENESISFILE=/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/channel-artifacts/genesis.block - ORDERER_GENERAL_LOCALMSPID=OrdererMSP - ORDERER_GENERAL_LOCALMSPDIR=/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/ordererOrganizations/example.com/msp #- ORDERER_GENERAL_LEDGERTYPE=ram #- ORDERER_GENERAL_LEDGERTYPE=file # enabled TLS - ORDERER_GENERAL_TLS_ENABLED=false - ORDERER_GENERAL_TLS_PRIVATEKEY=/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key - ORDERER_GENERAL_TLS_CERTIFICATE=/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt - ORDERER_GENERAL_TLS_ROOTCAS=[/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt] working_dir: /opt/gopath/src/github.com/hyperledger/fabric/singlepeer/ command: orderer volumes: - ./channel-artifacts/genesis.block:/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/channel-artifacts/genesis.block - ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/ordererOrganizations/example.com/msp - ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls networks: default: aliases: - aberic ports: - 7050:7050
ORDERER_GENERAL_GENESISFILE:指向生成的创世纪区块,我的目录是/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/channel-artifacts/genesis.block
ORDERER_GENERAL_LOCALMSPID:和configtx.yaml中Organizations:节点下的ID的值一致。
ORDERER_GENERAL_LOCALMSPDIR:指向msp,我的目录是/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/ordererOrganizations/example.com/msp
ORDERER_GENERAL_TLS_PRIVATEKEY:指向生成证书文件,我的目录是/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key
ORDERER_GENERAL_TLS_CERTIFICATE:指向生成证书文件,我的目录是/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
ORDERER_GENERAL_TLS_ROOTCAS:指向生成证书文件,我的目录是/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt
同理其它配置信息:working_dir,volumes:找到自己的目录指向

2.7部署peer0.org1节点
2.7.1配置Peer节点启动文件docker-peer.yaml # Copyright IBM Corp. All Rights Reserved. # # SPDX-License-Identifier: Apache-2.0 # version: '2' services: couchdb: container_name: couchdb image: hyperledger/fabric-couchdb # Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service, # for example map it to utilize Fauxton User Interface in dev environments. ports: - "5984:5984" ca: container_name: ca image: hyperledger/fabric-ca environment: - FABRIC_CA_HOME=/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/peerOrganizations/org1.example.com/ca - FABRIC_CA_SERVER_CA_NAME=ca - FABRIC_CA_SERVER_TLS_ENABLED=false - FABRIC_CA_SERVER_TLS_CERTFILE=/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem - FABRIC_CA_SERVER_TLS_KEYFILE=/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/peerOrganizations/org1.example.com/ca/f5617615ea50e08358addecfa264af0a1e01b8825da987a97b58707e7d7571a8_sk ports: - "7054:7054" command: sh -c 'fabric-ca-server start --ca.certfile /opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem --ca.keyfile /opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/peerOrganizations/org1.example.com/ca/f5617615ea50e08358addecfa264af0a1e01b8825da987a97b58707e7d7571a8_sk -b admin:adminpw -d' volumes: - ./crypto-config/peerOrganizations/org1.example.com/ca/:/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/peerOrganizations/org1.example.com/ca peer0.org1.example.com: container_name: peer0.org1.example.com image: hyperledger/fabric-peer environment: - CORE_LEDGER_STATE_STATEDATABASE=CouchDB - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb:5984 - CORE_PEER_ID=peer0.org1.example.com - CORE_PEER_NETWORKID=aberic - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 - CORE_PEER_CHAINCODELISTENADDRESS=peer0.org1.example.com:7052 - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051 - CORE_PEER_LOCALMSPID=Org1MSP - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock # the following setting starts chaincode containers on the same # bridge network as the peers # https://docs.docker.com/compose/networking/ - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=aberic # - CORE_LOGGING_LEVEL=ERROR - CORE_LOGGING_LEVEL=DEBUG - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=aberic_default - CORE_PEER_GOSSIP_SKIPHANDSHAKE=true - CORE_PEER_GOSSIP_USELEADERELECTION=true - CORE_PEER_GOSSIP_ORGLEADER=false - CORE_PEER_PROFILE_ENABLED=false - CORE_PEER_TLS_ENABLED=false - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt volumes: - /var/run/:/host/var/run/ - ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp - ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls working_dir: /opt/gopath/src/github.com/hyperledger/fabric/singlepeer command: peer node start ports: - 7051:7051 - 7052:7052 - 7053:7053 depends_on: - couchdb networks: default: aliases: - aberic cli: container_name: cli image: hyperledger/fabric-tools tty: true environment: - GOPATH=/opt/gopath - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock # - CORE_LOGGING_LEVEL=ERROR - CORE_LOGGING_LEVEL=DEBUG - CORE_PEER_ID=cli - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 - CORE_PEER_LOCALMSPID=Org1MSP - CORE_PEER_TLS_ENABLED=false - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp working_dir: /opt/gopath/src/github.com/hyperledger/fabric/singlepeer volumes: - /var/run/:/host/var/run/ - ./chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/chaincode/go - ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config - ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/channel-artifacts depends_on: - peer0.org1.example.com
以上的配置和自己目录的指向保持一致,请大家自行配置。
Peer启动文件启动的是peer0.org1.example.com节点,所以对应的证书在peer0.org1.example.com下可以找到。
dockerr-peer. yaml中有两处的加密:f5617615ea50e08358addecfa264af0a1e01b8825da987a97b58707e7d7571a8_sk请替换成自己的加密串
我这里是为了执行源码的example02例子,所以在cli下volumes:里配置要执行的智能合约程序
2.8 准备docker配置文件
2.8.1配置客户端启动文件docker-compose-cli.yaml version: '2' services: orderer.example.com: container_name: orderer.example.com image: hyperledger/fabric-orderer environment: - ORDERER_GENERAL_LOGLEVEL=debug - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 - ORDERER_GENERAL_GENESISMETHOD=file - ORDERER_GENERAL_GENESISFILE=/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/channel-artifacts/genesis.block - ORDERER_GENERAL_LOCALMSPID=OrdererMSP - ORDERER_GENERAL_LOCALMSPDIR=/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/ordererOrganizations/example.com/msp # enabled TLS - ORDERER_GENERAL_TLS_ENABLED=false - ORDERER_GENERAL_TLS_PRIVATEKEY=/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key - ORDERER_GENERAL_TLS_CERTIFICATE=/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt - ORDERER_GENERAL_TLS_ROOTCAS=[/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt] working_dir: /opt/gopath/src/github.com/hyperledger/fabric/singlepeer command: orderer volumes: - ./channel-artifacts/genesis.block:/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/channel-artifacts/genesis.block - ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/ordererOrganizations/example.com/msp - ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls ports: - 7050:7050 peer0.org1.example.com: container_name: peer0.org1.example.com image: hyperledger/fabric-peer environment: - CORE_PEER_ID=peer0.org1.example.com - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 - CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052 - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052 - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051 - CORE_PEER_LOCALMSPID=Org1MSP - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock # the following setting starts chaincode containers on the same # bridge network as the peers # https://docs.docker.com/compose/networking/ - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=singlepeer_default #- CORE_LOGGING_LEVEL=ERROR - CORE_LOGGING_LEVEL=DEBUG - CORE_PEER_TLS_ENABLED=false - CORE_PEER_GOSSIP_USELEADERELECTION=true - CORE_PEER_GOSSIP_ORGLEADER=false - CORE_PEER_PROFILE_ENABLED=true - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt volumes: - /var/run/:/host/var/run/ - ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/ordererOrganizations/example.com/msp - ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer command: peer node start ports: - 7051:7051 - 7052:7052 - 7053:7053 cli: container_name: cli image: hyperledger/fabric-tools tty: true environment: - GOPATH=/opt/gopath - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock - CORE_LOGGING_LEVEL=DEBUG - CORE_PEER_ID=cli - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 - CORE_PEER_LOCALMSPID=Org1MSP - CORE_PEER_TLS_ENABLED=false - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer volumes: - /var/run/:/host/var/run/ - ./chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/chaincode/go - ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ - ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts depends_on: - orderer.example.com - peer0.org1.example.com
2.9 启动Fabric网络
2.9.1 启动orderer和peer #docker -compose -f docker-orderer.yaml up -d #docker -compose -f docker-peer.yaml up -d
2.9.2 启动cli容器 # docker exec -it cli bash
2.9.3 创建Channel # peer channel create -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/mychannel.tx
2.9.4 Peer加入Channel # peer channel join -b mychannel.block
2.10 安装与运行智能合约
2.10.1 安装智能合约 # peer chaincode install -n mycc -p github.com/hyperledger/fabric/singlepeer/chaincode/go/example02/cmd/ -v 1.0
2.10.2 实例化智能合约 # peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n mycc -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "AND ('Org1MSP.peer')"
2.10.3 Peer上查询a,显示100 # peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
2.10.4 Peer上进行a向b转10交易 # peer chaincode invoke -C mychannel -n mycc -c '{"Args":["invoke","a","b","10"]}'
2.10.5 Peer上查询a,显示210 # peer chaincode query -C mychannel -n mycc -c ' {"Args":["query","b"]} '
区块链
2019-06-17 19:05:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
从目前已经发布的 DAPP 来看, DAPP 架构大致可以分成3种类型:插件钱包模式、全节点钱包模式和兼容模式。 插件钱包模式是借助封装了钱包的浏览器插件通过 RPC 协议与区块链节点通信,插件在运行时会将 Web3 框架注入到 DAPP 前端页面中,然后 DApp 通过 Web3 来与区块链节点通信。 全节点钱包模式需要项目方同步并持有一个区块链节点,并对外提供一个浏览器环境与用户进行交互。 兼容模式可以在插件钱包和全节点钱包下同时使用,即上述两种方式可以自由切换,安全性能相对较高。
接下来介绍的比原链 DAPP 的架构模式跟账户模型 DAPP 的插件钱包模式有些相似,都是由 DAPP 前端、插件钱包和合约程序共同组成,其中插件钱包需要连接去中心化的区块链服务器 blockcenter ,该服务器主要是为了管理插件钱包的相关信息。此外,比原链是 UTXO 模型的区块链系统,合约程序存在于无状态的 UTXO 中,如果要实现这样一个具体的 DAPP ,就需要在前端和后端多做一些逻辑的处理。
1. 编写、编译并实例化智能合约
编写智能合约
比原链的虚拟机是图灵完备的,理论上可以实现任意图灵计算机能实现的操作。而 Equity 作为比原链的智能合约语言,使用 Equity 语言可以实现许多典型的金融模型案例,但是为了解决停机问题,比原链也设置了手续费的上限,因此用户在设计合约的时候做一下权衡。
合约模板结构如下: contract contract_name(...) locks valueAmount of valueAsset { clause clause_name(...) { ... lock/unlock ... } ... }
Equity 语法结构简单,语句意思明确,有开发经验的童鞋一看基本能明白合约的意思。编写智能合约可以参考 Equity 合约介绍 ,文档中对 Equity 语言的语法和编译方法都做了详细的介绍。此外,文档还对一些典型的 模板合约 进行了介绍,开发者可以自己需求进行参考。
编译并实例化合约
编译合约目前支持两种方式,一种是使用 Equity 编译工具,另一种是调用比原链中编译合约的 RPC 接口 compile ; 而合约实例化是为了将合约脚本按照用户设定的参数进行锁定,编译并实例化合约可以参考 编译并实例化合约 的上半部分说明,该文档不仅介绍了合约的参数构造说明,还对编译合约的步骤进行详细说明。而编译器以及相关工具位于 Equity 编译器 中,是使用 go 语言开发的,用户可以下载源代码并编译使用。
工具编译和实例化示例如下: // compile ./equity [contract_name] --bin // instance ./equity [contract_name] --instance [arguments ...]
2. 部署合约
部署合约即发送合约交易,调用比原链的 build-transaction 接口将指定数量的资产发送到合约 program 中,只需将输出 output 中接收方 control_program 设置为指定合约即可。用户可以参考 合约交易说明 中的锁定合约章节,交易的构造按照文档中介绍进行参考即可。如果合约交易发送成功,并且交易已经成功上链,便可以通过调用 API 接口 list-unspent-outputs 来查找该合约的 UTXO 。
部署合约交易模板大致如下: { "actions": [ // inputs { // btm fee }, { amount, asset, spend_account // spend user asset }, // outputs { amount, asset, contract_program // receive contract program with instantiated result } ], ... }
3. 搭建DAPP架构
Bytom的 blockcenter 服务器是官方开发的去中心化插件钱包服务器,开发者可以按照相关 API 接口来调用即可。比原链的 DAPP 总体框架模型如下:
DAPP前端
搭建 DAPP 前端主要包含两个方面:一个是前端与插件钱包的交互,另一个是前端的逻辑处理、以及与缓冲服务器的交互。插件钱包是与区块链节点服务器通信的窗口,一个 DAPP 为了跟区块链节点进行通信,需要通过借助插件来与后台服务器节点进行交互。比原的插件钱包除了与后台服务器进行交互之外,还包含一些本地业务逻辑处理的接口 API ,具体内容可以参考一下 DAPP开发者向导 。由于比原链是基于 UTXO 模型的区块链系统,交易是由多输入和多输出构成的结构,并且交易输入或输出的位置也需要按照顺序来排列,因此开发 DAPP 需要前端处理一些构建交易的逻辑。除此之外,合约中的 lock-unlock 语句中涉及到数量的计算需要根据抽象语法树来进行预计算,计算的结果将用于构建交易,而 verify 、 if-else 等其他语句类型也需要进行相关的预校验,从而防止用户在执行合约的时候报错。
从功能层面来说,前端主要包含页面的设计、插件的调用、合约交易逻辑的处理、缓冲服务器的交互等。接下来对这几个重要的部分展开说明: 1)前端页面的设计主要是网页界面的设计,这个部分开发者可以自己选择页面模式 2)插件钱包已经进行了结构化的封装,并且提供了外部接口给 DAPP 开发者调用,开发者只需要将插件的参数按照规则进行填充,具体请参考 DAPP开发者向导 3)比原链的合约交易是多输入多输出的交易结构,前端需要进行一些预判断逻辑的处理,然后再选择合适的合约交易模板结构。 4)DAPP的插件连接的是去中心化的 bycoin 服务器,该服务器从比原节点服务器上同步的所有区块信息和交易信息,该部分主要是在插件钱包层进行了高度的封装,用户只需按照接口调用即可。除此之外,需要开发者搭建一个缓冲服务器,不仅可以在管理合约 UTXO 层面做一些性能方面的处理,而且还可以为 DAPP 做一些数据存储。开发者可以根据实际需求来开发一些 RPC 请求接口,然后在前端页面设置相关条件来触发这些 API 的调用。
前端逻辑处理流程大致如下: 调用插件,比原的 chrome 插件源码位于 Bytom-JS-SDK ,开发比原 DAPP 时调用插件的说明可以参考 Dapp Developer Guide ,其网络配置如下: window.addEventListener('load', async function() { if (typeof window.bytom !== 'undefined') { let networks = { solonet: ... // solonet bycoin url testnet: ... // testnet bycoin url mainnet: ... // mainnet bycoin url }; ... startApp(); }); 配置合约参数,可以采用文件配置的方式,该步骤是为了让前端得到需要用到的一些已经固定化的合约参数,其前端配置文件为 configure.json.js ,其示例模型如下: var config = { "solonet": { ... // contract arguments "gas": 0.4 // btm fee }, "testnet":{ ... }, "mainnet":{ ... } } 前端预计算处理,如果合约中包含 lock-unlock 语句,并且 Amount 是一个数值表达式,那么前端来提取计算表达式并进行相应的预计算。此外,前端还需要预判下所有可验证的 verify 语句,从而判定交易是否可行,因为一旦前端对这些验证失败,合约将必然验证失败。此外,如果 define 或 assign 语句涉及的变量,前端也需预计算这些变量的值。 构建合约交易模板,由于解锁合约是解锁 lock 语句条件,构造交易需要根据 lock 语句或 unlock 语句来进行变换。解锁合约交易是由 inputs 和 outputs 构成,交易的第一个 input 输入一般都是是固定的,即合约 UTXO 的 hash 值,除此之外,其他输入输出都需要根据DAPP中的实际合约来进行变更,其模型大致如下: const input = [] input.push(spendUTXOAction(utxohash)) ... // other input const output = [] output.push(controlProgramAction(amount, asset, program)) ... // other output 启动前端服务
编译前端命令如下: npm run build
启动之前需要先启动 bufferserver 缓冲服务器,然后再启动前端服务,其前端启动命令如下: npm start
DAPP缓冲服务器
缓冲服务器主要是为了在管理合约 UTXO 层面做一些效率方面的处理,包括了对 bycoin 服务器是如何同步请求的,此外对 DAPP 的相关交易记录也进行了存储。 bycoin 服务器是比原链的去中心化钱包服务器,缓冲服务器的 UTXO 跟它是同步更新的,比原官方插件钱包默认连接的就是该服务器。尽管 bycoin 服务器的也对比原链的所有 UTXO 进行了管理,但是由于 UTXO 数量比较大,如果直接在该层面处理会导致 DAPP 性能不佳,所以建议用户自己构建自己的缓冲服务器做进一步优化处理。此外, DAPP 开发者也可以搭建了自己的去中心化钱包服务器,并且自己开发相关的插件。
缓冲服务器架构可以参考一下 bufferserver案例 的源代码,其编译和启动步骤如下: 编译 bufferserver 源代码
按照 README 安装部署服务需要的软件包 Mysql 和 Redis ,然后下载源代码并编译: make all
编译完成之后,在 target 目录下会生成可执行文件 api 和 updater 。 启动服务
使用 root 用户创建数据库和数据表,其命令如下: mysql -u root -p < database/dump.sql
修改配置文件 config_local.json ,配置说明参考 README 的 config 配置参数详解。
启动 api 和 updater 服务器,其中 api 是提供 JSON RPC 请求的服务进程, updater 是提供同步 blockcenter 和区块链浏览器数据请求的服务进程。 ./target/api config_local.json ./target/updater config_local.json
启动缓冲服务器之后,便可以启动前端服务,然后打开 DAPP 的网页 URL 即可使用。
附:缓冲服务器的 JSON RPC 接口可以参考 wiki 接口说明 。
Bytom DAPP实例
Bytom DAPP 实例说明,请参考 储蓄分红DAPP
区块链
2019-07-18 10:10:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
宁可满仓被套,不可一次踏空
今年二三月份的时候,比特币在三四千刀横盘已久,恰逢赶上平台币,交易所IEO,模式币等热点行情,不少币圈人拿出被套已久的比特币开始炒山寨币短线。
这个时候比特币好像跟大家开了个玩笑,币价迅速攀升到五千刀,又在大家在等回调再入场的时候,比特币又在两周内暴涨50%到了八千刀。不少人因为踏空拍断大腿,心态崩掉。 在牛市到来前期,炒短线是个“丢西瓜捡芝麻”的行为。比特币的历史也告诉我们,只有拿住,老老实实当一个屯币党,才能获得最大的收益。所以定投,每个月固定投入一点,才能保持良好的心态,无论牛熊,都能笑到最后。

如果决心要屯币的话,最好就不要把币放到交易所里了。第一是因为有风险,无论是规模多大,名声多好的交易所,都可能发生黑天鹅事件。比如曾经占据80%比特币交易量的Mt.Gox门头沟交易所,在2014年弄丢了客户75万个比特币。前段时间币安也被黑客攻击,被盗7000个比特币。大交易所容易被黑客盯上,小交易所还怕跑路,所以如果长期屯币,交易所并不是首选。
第二个屯币不能放交易所的原因,就是容易控制不住自己的手。交易所实在是太方便了,很容易就又用比特币炒短线,再次出现上面一不小心就踏空的局面。

所以这里建议大家,要把屯的币和炒短线的币分开,只把准备炒短线的币放在交易所里,这样最保险。
那屯币一定就要屯在一个靠谱的钱包里了,钱包是管理私钥的工具。有些人会有误区,保管好私钥就可以了,为什么还要用到钱包。首先私钥对应的地址是钱包生成的,屯币不代表置之不理,也会存在转币和收币的需求,所以用钱包比较方便。
还有现在的钱包端会有很多接口,可以连接理财和糖果的应用。既然不会用屯的币炒短线,不如投资一些短线的理财产品,就像余额宝那样币生币,平时用钱包上的糖果DApp薅薅羊毛也是不错的。
那选择钱包要看重哪些呢?首先是安全性,用户要自己掌握自己的私钥和助记词,这个一定是必要的。其次是实用性,有的钱包非常难用,除了能发币外没有其他功能。还有的钱包除了自己的官网,根本找不到地方下载,感觉就不正规。
那下面给大家推荐一款我最近发现好用的钱包,那就是AToken。AToken是个多币种钱包,也就是一个钱包可以管理BTC,ETH,EOS,TRX等多个主流币种,十分方便。

AToken钱包是去中心化钱包,钱包的服务器不会以任何方式触碰和存储用户的助记词或私钥,这是比特币老炮们非常关注的。市面上一些钱包的私钥都会同步到服务器上,更有甚者是不提供私钥的线上钱包,相比这下,AToken这方面做得中规中矩,非常到位的。
创始人边龙飞是曾经火币钱包组资深开发工程师,曾经有百万级用户服务开发经验。火币钱包中存储着几十万的比特币,其安全性无容置疑。那么大家可想而知AToken对安全的理解到了多么恐怖的高度,绝对的业内一线。
AToken钱包在2017年发布,已经运营两年了,也没有出现过任何丢币事件。另外目前在AppStore和google play上就能直接下载,要知道苹果和谷歌的审核都是很严格的,能够同时支持意味着这个钱包是经得起考验的。
在转账的时候,AToken还会贴心的提醒用户网络是否拥堵,以及目前推荐的矿工费是多少,能保证用户在网络拥堵的时候也能转账成功。

还有AToken上开放的DApp入口很多,包括ETH上的理财产品,EOS上的游戏和糖果应用等等,在屯币之余还能薅个羊毛。

最后还有重点,AToken上线了自己的token ATC。目前ATC在钱包里是免费领的,基本上三五分钟就会发一轮红包。现在ATC还没有上交易所,所以不能直接交易。但是在AToken里,用ATC可以挖矿换EOS。当然这个挖矿不是真的“挖矿”,EOS不作为节点是不能挖矿的。我在社群里了解到,这只是AToken官方给大家发福利的方式。

我只用薅羊毛来的币进行了“挖矿”,第一次就得到了0.15 USD,看来现在AToken矿工还是蓝海竞争。
工欲善其事必先利其器,熊市屯币一定要选对钱包,才能在即将到来的牛市中一鸣惊人。
送个福利:
AToken下载链接: https://www.atoken.com/
区块链
2019-05-24 10:52:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
EVM存储数据有两种方式:storage或者memory。在开发智能合约的时候,高度推荐搞清楚这是如何实现的以及本地变量的默认类型。如果不正确的初始化变量也会导致合约漏洞。
攻击原理
取决于变量类型,本地变量默认为storage或者memory。没有初始化的本地storage变量会 指向 不可知的合约变量,导致有意或者无意的留下漏洞
看看下面这个名字登录合约:
// A Locked Name Registrar contract NameRegistrar { bool public unlocked = false; // registrar locked, no name updates struct NameRecord { // map hashes to addresses bytes32 name; address mappedAddress; } mapping(address => NameRecord) public registeredNameRecord; // records who registered names mapping(bytes32 => address) public resolve; // resolves hashes to addresses function register(bytes32 _name, address _mappedAddress) public { // set up the new NameRecord NameRecord newRecord; newRecord.name = _name; newRecord.mappedAddress = _mappedAddress; resolve[_name] = _mappedAddress; registeredNameRecord[msg.sender] = newRecord; require(unlocked); // only allow registrations if contract is unlocked } }

这个简单的名字登录合约只有一个函数。但合约被解锁以后,任何人都可以登录一个名字 (作为一个a bytes32的哈希),同时把名字映射到一个地址上。这个合约一开始是上锁的,而且第23行的require语句防止在上锁状态下的新增名字。但是在合约里有一个漏洞,允许合约在上锁状态下能进行名字登录。
为了讨论这个漏洞,我们必须要理解Storage是如何工作的。Storage槽是线性排布的,所以unlocked存在slot 0, registeredNameRecord 存在slot 1, resolve存在slot 2 依次类推。每个存储槽是32字节。Boolean类型变量unlocked 会被存储为0x000...0 (64个0)(如果是false)或者0x000...1(63个 0) (如果是true)
newRecord变量默认存储在Storage。漏洞在于newRecord没有被初始化。因为它默认是Storage,它就变成了一个指向Storage的指针。因为它没有被初始化,所以它指向slot 0 (unlocked存储的地方)。其后,程序设置nameRecord.name为_name,设置nameRecord.mappedAddress为_mappedAddress, 这两个赋值语句其实修改了slot 0和slot 1。实际上也修改了unlocked和registeredNameRecord所在的存储槽 。 这意味着unlocked可以在register()里被直接修改, 因而,如果_name的最后的字节不为零,它就将修改storage slot 0的最后一个字节,从而直接修改unlocked 为 true。我们可以在Remix里试一下,函数将会通过如果我们使用下面的参数的话_name: 0x0000000000000000000000000000000000000000000000000000000000000001
防护技术
Solidity编译器对未初始化的变量会推出一个警告。开发程序员要仔细的研读那些编译器产生的警告。显式的给变量加上memory或者storage修饰符是一个很好的习惯,以保证复杂类型按预想的运行。
pragma solidity ^0.4.18; contract HodlFraud { uint ownerAmount; uint numberOfPayouts; address owner; struct HoldRecord { uint amount; uint unlockTime; } mapping (address => HoldRecord) balance; function HodlFraud () public payable { owner = msg.sender; ownerAmount = msg.value; } function payIn(uint holdTime) public payable { require(msg.value > 0); HoldRecord newRecord; newRecord.amount += msg.value; newRecord.unlockTime = now + holdTime; balance[msg.sender] = newRecord; } function withdraw () public { require(balance[msg.sender].unlockTime < now && balance[msg.sender].amount > 0); msg.sender.transfer(balance[msg.sender].amount); balance[msg.sender].amount = 0; numberOfPayouts++; } function ownerWithdrawal () public { require(msg.sender == owner && ownerAmount > 0); msg.sender.transfer(ownerAmount); ownerAmount = 0; } }

区块链
2019-03-21 10:40:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>

https://github.com/filecoin-project/go-filecoin/issues/2503
Error go run ./build build
command from root I've faced on this error Building go-filecoin... git log -n 1 --format=%H go build -ldflags -X github.com/filecoin-project/go-filecoin/flags.Commit=1cdea1b6b8a17ea38cac0074241d1b3b9945e102 -v -o go-filecoin . github.com/filecoin-project/go-filecoin/proofs # github.com/filecoin-project/go-filecoin/proofs proofs/rustverifier.go:66:3: cannot use _cgo4 (type *[31]_Ctype_uchar) as type unsafe.Pointer in argument to _Cfunc_verify_seal proofs/rustverifier.go:66:3: cannot use _cgo5 (type *[31]_Ctype_uchar) as type unsafe.Pointer in argument to _Cfunc_verify_seal Command 'go build -ldflags -X github.com/filecoin-project/go-filecoin/flags.Commit=1cdea1b6b8a17ea38cac0074241d1b3b9945e102 -v -o go-filecoin .' fail
Solution Due to our use of cgo , you'll need a C compiler to build go-filecoin whether you're using a prebuilt libfilecoin_proofs (our cgo-compatible rust-fil-proofs library) or building it yourself from source. If you want to use gcc (e.g. export CC=gcc ) when building go-filecoin, you will need to use v7.4.0 or higher.
You can resolve this issue by either: Installing clang and setting the CC environment variable to clang , e.g. export CC=clang Upgrading gcc to a supported version

成功了,哈哈
同步了将近一周,终于完成了:
root@btcpool:/work/gowork/src/github.com/filecoin-project/go-filecoin# ./go-filecoin show block $(./go-filecoin chain head) Block Details Miner: t27gvotilvoudxezxxu2atwfc42otsprm6wvt5x6i Weight: 2567854.534 Height: 372740 Nonce: 0
钱包里的测试用币
Message(对应以太坊里的Transaction)
root@btcpool:/work/gowork/src/github.com/filecoin-project/go-filecoin# ./go-filecoin message wait zDPWYqFCufco1gAxo1o7zJQivy5mX4yZ62a3ZXkEFZhiQ4djs5dG { "meteredMessage": { "message": { "to": "t1yyrs2zdjs3fyzdfctrjxk4ero4orzhlnkcpeloa", "from": "t1f66uecq4mekanhhne5nsehckqerfrhxbwxnufia", "nonce": "12902", "value": "1000", "method": "", "params": null }, "gasPrice": "1", "gasLimit": "0" }, "signature": "SfvwHxX46uh8oS491iGwbBwJMq2683XD1R5ErtAGKOkYXO4k4IbNjYn7xn0MuAtDsdI3RP7OnTmQ4XmdnOf+ogA=" } { "exitCode": 0, "return": null, "gasAttoFIL": "0" }
备忘: root@btcpool:/work/gowork/src/github.com/filecoin-project/go-filecoin# git branch -l * (HEAD detached at 0.2.2)
区块链
2019-04-23 12:42:00
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
区块链钱包是什么?很多人会把它理解为微信支付宝钱包等,然而区块链钱包里没有数字货币,数字货币存储在区块链上,钱包作为公私钥的管理工具,用户通过钱包与区块链平台上的DApp 进行交互。
区块链钱包对于区块链而言好比浏览器对于互联网一样。早期人们对于在浏览器上输入url和域名访问互联网都很陌生,但现在浏览器已经成为互联网的重要入口,被几十亿人使用。在区块链上也将会发生同样的一个演变过程,对大多数人来说,现在区块链是陌生的,随着区块链用户从数百万人激增到数千万人,那么许多团队对钱包的这个入口战略资源的争夺将比互联网时代 的浏览器更加激烈。
在区块链领域,钱包毫无疑问有举足轻重的地位,很容易理解区块链钱包的应用价值:
作为支付的入口
随着闪电网络、雷电网络等链外支付以及分片、子链等技术的成熟,未来一旦数字代币支付成为主流的支付方式之一。那么钱包作为入口,就有很大的想象空间。
作为资产管理的入口
目前比特币、以太坊、EOS等公链越来越多,协议和应用越来越多,token也越来越多,中心化交易所、去中心化交易所、量化交易等都在发展。现在,一些钱包提供了理财的功能,一些长期价值投资的用户把代币存入钱包进行理财。
作为交易的入口
对于用户来说,在钱包就可实现快速的交易。钱包由于沉淀了很多用户的数字资产,当用户需要进行交易时,钱包与一些去中心化或中心化的交易所结合,用户输入自己的理想价格,可以实现尽快的撮合交易。
作为DApp市场入口
随着公链的成熟,尤其是EOS、以太坊等区块链基础设施的逐步完善,一些游戏类、金融类、社交类、泛娱乐类的DApp应用逐步发展起来。随着成千上万,甚至是几十万上百万的DApp,用户需要有一个地方去发现和下载。对于钱包来说,DApp市场入口绝对是最具想象力的前景。
为什么要了解EOS钱包?
有着区块链3.0之称的EOS拥有庞大的用户群体,自2018年6月份主网上线以来,注册帐户已经达到60万,而算上没有EOS帐户但在交易平台持有EOS代币的用户,可能这个数字已经超过百万:
在EOS平台上开发的DApp如雨后春笋般纷纷出世,主网上现在跑的DApp已经超过了200个,其活跃量、交易量也早已超越了以太坊。这些开发团队以及个体开发者选择基于EOS开发,首先是EOS网络对开发者友好,适宜DApp应用程序开发;其次开发者对于EOS生态的未来有信心。
钱包作为数字货币资产的存储和Dapp的超级流量入口,其市场需求较大,创建和管理钱包是进入区块链领域的必修课。因此我们推出本课程,自己来开发一个EOS钱包,旨在帮助区块链用户 和应用开发者全面快速地掌握区块链钱包开发的知识技能与业务流程。
课程项目简介
课程项目是一个手机EOS钱包,最终的实现效果如下图所示:
用户可以导入自己的账号,也可以创建新的测试网账号,可以在钱包的多个账号间切换活动账号。一旦选中的当前活动账号,用户就可以查看自己的资产总览信息,也可以向其他账号转账,或者浏览自己的转账历史记录。
钱包也提供了DApp开发者关心的资源管理功能。使用钱包可以购买或者出售内存资源,也可以抵押EOS获取CPU或者NET资源。
作为区块链的入口,我们的钱包不仅提供了管理自己EOS账号的能力,还可以提供更多的增值服务,例如DApp推荐、市场行情、新闻动态等。
课程项目技术栈概述
本课程项目采用NodeJS的全栈式开发模式,基于npm+webpack的工作流,为了顺利地完成本课程的学习,你应该对以下语言/技术有一些了解:
本课程采用Webpack把项目当做一个整体,从一个给定的主文件(如:index.js)开始找到项目的所有依赖文件(JavaScript,CSS和Fonts以及Image等等),通过合适的loaders处理它们,最后打包为一个浏览器可识别的JavaScript文件。
本课程使用Facebook的Web App解决方案React技术栈(react+redux+react-router)以及基于React实现的UI框架Antd-Mobile,帮助学员快速完成前端H5页面的开发并提供给用户优质的用户体验。
Eosjs是访问EOS区块链的JavaScript库,提供了大量简单易用的EOS的HTTP API封装方法, 其作用就像web3.js对于Ethereum或者neon-js对于Neo一样。
课程内容概述
本课程面向广大对EOS开发感兴趣的朋友,是目前市面上理论与实战相结合最全的EOS开发项目,内容涵盖EOS开发相关的基本概念,并围绕EOS钱包项目开发逐步进行讲解,最终实现一个EOS钱包。
第一章:概述
介绍什么是区块链钱包;分析区块链钱包的应用价值,阐述本课程的目的;并介绍课程项目使用的技术栈,引入对学习者基础知识技能的要求。
第二章:理解EOS账户与钱包
引入EOS账户、密钥、钱包等概念。介绍如何获取第一个EOS账号,以及如何查询账号信息。解释为什么主网中创建账户的是需要费用的。阐述助记词、keystore、密码与私钥的关系。并通过账户权限与钱包相关的操作,学习EOS账户权限和官方钱包命令等知识。
第三章:需求分析与总体设计
项目需求分析与总体设计,阐述项目功能模块划分、系统整体架构、前端服务层设计、前端状态机、第三方服务清单等。
第四章:前端服务组件实现
实现前端服务组件,封装手机钱包的核心功能,例如账号创建、账号导入、转账交易、交易历史查询、资产管理、资源管理等。
第五章:前端UI组件实现
学习如何利用React实现钱包的前端UI组件,如何利用React-Router前端路由切换组件,如何使用Redux状态库实现前端状态管理。
感兴趣的同学可以试试, 深入浅出玩转EOS钱包开发 ,本课程以手机EOS钱包的完整开发过程为主线,深入学习EOS区块链应用开发,课程内容即涵盖账户、计算资源、智能合约、动作与交易等EOS区块链的核心概念,同时也讲解如何使用eosjs和eosjs-ecc开发包访问EOS区块链,以及如何在React前端应用中集成对EOS区块链的支持。课程内容深入浅出,非常适合前端工程师深入学习EOS区块链应用开发。
另外还有一个 EOS入门教程 ,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。
区块链
2019-03-06 11:46:00