开发基于以太坊智能合约的DApp

最近要找个H5的前端写个简单的DApp,聊过几个H5的工程师,都被跟以太坊交互的部分吓住了。虽然网上有N多的教程,但是对于H5工程师来说,还是有些困难。分析其原因,在于不了解ganache-cli(原来叫testrpc)/web3/以太坊节点/metamask之间的架构关系。

梳理一下架构关系:

web3.js与以太坊通信是通过rpc的方式实现的。

以太坊节点本来提供了rpc的访问方式,但是因为以太坊节点的地址不确定,并且DApp需要访问钱包,所以用web3.js直接访问以太坊节点的rpc服务是不现实的。

ganache-cli模拟了一个以太坊的测试节点并提供对外的rpc访问方式(就是例子里经常说的http://localhost:7545或者http://localhost:8545)。同时在其中内置了M个以太坊帐号,用于测试。

MetaMask是一个以太坊的网络钱包插件,它也提供了web3的访问方式。而且可以通过这个插件指定后面的以太坊节点是什么。因为MetaMask是个钱包插件,所以解决了DApp中的支付问题。所以现在的DApp都依赖它。

开发DApp的基本过程如下:

1、安装NodeJS

2、安装truffle:一个开发DApp的开发框架

nmp install -g truffle

3、安装Ganache(原来用testrpc):在内存中模拟以太坊运行并对外提供rpc服务。

npm install -g ganache-cli

4、运行ganache-cli

ganache-cli

5、生成一个DApp的项目

mkdir project1

truffle init

如果想用truffle中的某个例子,可以用

truffle unbox pet-shop

“pet-shop”是例子名称

6、编写智能合约

具体如何用solidity编写智能合约可参考各种文章,这里不再重复。

编写好的智能合约的Project1.sol文件放到contracts目录下

7、编译和部署智能合约

在migrations目录下创建文件2_deploy_contracts.js:

var Project1 = artifacts.require("Project1");

module.exports = function(deployer) {
  deployer.deploy(Project1);
};

之后执行:

truffle compile

truffle migrate

如果你的智能合约没有问题的话,现在你的智能合约应该已经部署到你用来测试的ganache中去了。

这里可能遇到的问题是:默认的truffle生成的项目,测试用的ganache的地址和端口会被设置成http://localhost:7545,而实际上执行ganache-cli之后的服务端口是http://localhost:8545,需要在truffle.js中修改一下:

module.exports = {
// See <http://truffleframework.com/docs/advanced/configuration>
// for more about customizing your Truffle configuration!
networks: {
development: {
host: “127.0.0.1”,
port: 7545,   //改成8545
network_id: “*” // Match any network id
}
}
};

8、编写前端的js代码跟以太坊交互

通常需要如下的辅助js库:

<!– jQuery (necessary for Bootstrap’s JavaScript plugins) –>
<script src=”js/jquery.min.js”></script>
<!– Include all compiled plugins (below), or include individual files as needed –>
<script src=”js/bootstrap.min.js”></script>
<script src=”js/web3.min.js”></script>
<script src=”js/truffle-contract.js”></script>
在此基础上,编辑你自己业务逻辑的js,通常命名为app.js,app.js的框架如下:

App = {
web3Provider: null,
contracts: {},

init: function() {

//初始化你自己的页面、变量等

return App.initWeb3();
},

initWeb3: function() {
/*
* 初始化web3:
*/
if (typeof web3 !== ‘undefined’){

//如果你的浏览器安装了MetaMask的钱包插件,那么插件会赋值web3.currentProvider
App.web3Provider = web3.currentProvider;
}
else
{

//如果没装插件,那么创建一个基于Http的provider,这里用到的就是用ganache-cli启动所提供的rpc服务,因为ganache-cli启动的时候绑定的是localhost,所以测试所使用的浏览器也要在本机。(如何让ganache-cli绑定其他地址我还没找到)
App.web3Provider = new Web3.providers.HttpProvider(‘http://localhost:8545’);

}
web3 = new Web3(App.web3Provider);

return App.initContract();
},

initContract: function() {
/*
* 初始化智能合约,实际上就是为你的智能合约创建一个对应的js对象,方便后续调用
*/

//通常的做法是使用你的智能合约编译之后生成的abi的json文件,该文件在用truffle compile之后,生成在build/contracts/目录下,因为我用了一个Division.sol,所以用Division.json,你可以根据你的实际情况来写。
$.getJSON(‘Division.json‘, function(data) {
var DivisionArtifact = data;
App.contracts.Division = TruffleContract(DivisionArtifact);
App.contracts.Division.setProvider(App.web3Provider);
//用智能合约中的信息来更新你的web应用,App.refreshPlots()是我例子中获取智能合约中信息并更新UI的函数

return App.refreshPlots();
});

return App.bindEvents();
},

bindEvents: function() {

/*
* 事件绑定,这个可以根据你的UI来设置,例子中就是绑定一个button的点击操作
*/

$(document).on(‘click’, ‘.btn-adopt’, App.handlePlot);
},

refreshPlots: function(plots, account) {
/*
* 这个函数就是上面initContract中调用的用智能合约更新页面
*/

        //继续使用division这个智能合约做例子
         var divisionInstance;
         App.contracts.Division.deployed().then(function(instance){
                 divisionInstance = instance;
                 //getGenPlots是Division的这个智能合约的一个查询函数(不需要gas),需要3个参数
                 return divisionInstance.getGenPlots(0,0,2);
         }).then(function(results){
                 //注意:这个地方有点意思,我原先理解也有问题,后来打印输出才搞明白
                 //智能合约返回的多个结果变量在这里就是一个results数组
                 //数组的每个成员就是智能合约返回的每个结果变量
                 //以getGenPlots为例,Division.json中定义如下:
                 /*"name": "getGenPlots",
                     "outputs": [
                     {
                         "name": "",
                         "type": "uint64[]"
                     },
                     {
                         "name": "",
                         "type": "address[]"
                     },
                     {
                         "name": "",
                         "type": "uint256[]"
                     },
                     {
                         "name": "",
                         "type": "uint8[]"
                     }
                     ],
                     "payable": false,
                     "stateMutability": "view",
                     "type": "function"
                  */
                  //那么:results[0]是uint64[]
                  //      results[1]是address[]...

                 console.log(results[0].length);
         }).catch(function(err){
                 console.log(err.message);
         });
 },
handlePlot: function(event) {

/*
 * 这个函数就是上面bindEvents中调用的响应函数,演示要花eth的函数调用
 */
    event.preventDefault();
    //从event中获取参数,这是jquery的东西,跟web3无关
    var plotId = parseInt($(event.target).data('id'));

    var divisionInstance;
     //获取以太坊帐号信息
     web3.eth.getAccounts(function(error,accounts){
         if(error)
         {
             console.log(error);
         }
         //我随便取帐号列表里的第3个帐号。
         //因为我们连的是ganache-cli的rpc模拟服务,
         //其中给我们预制了几个有eth的帐号
         //如果安装了MetaMask插件,应该获得的就是MetaMask里的帐号
         var account = accounts[2];
         App.contracts.Division.deployed().then(function(instance){
             divisionInstance = instance;
             //调用智能合约的buyPlot函数,该函数需要2个参数,
             //后面的{}中的内容跟发起以太坊交易的时候所带的默认值。
             //from: 使用哪个以太坊帐号
             //value: 要使用的eth数量,以wei为单位(1eth=10^18wei)
             //gas: 矿工费,以wei为单位
             return divisionInstance.buyPlot(plotId, 3, {from: account, value: 100000000000000000, gas:6000000});
        }).then(function(result){
            //返回结果后重新更新UI
            return App.refreshPlots();
        }).catch(function(error){
            console.log(error.message);
        });
     });
 }

};

测试你的基于Web的DApp是否正常,可以使用nodejs里面提供的lite-server模块来当简单的webserver来用。

安装lite-server,在你的truffle项目目录下,执行:

npm install lite-server

安装完之后会在项目目录下声称node_modules目录,lite-server以及依赖的模块都在该目录下了。

要运行lite-server,还需要编写项目目录下的package.json文件:

{
     "name": "项目名称",
     "version": "1.0.0",
     "description": "",
     "main": "truffle.js",
     "directories": {
         "test": "test"
     },
     "scripts": {
         "dev": "lite-server",
         "test": "echo \"Error: no test specified\" && exit 1"
     },
     "author": "",
     "license": "ISC",
     "devDependencies": {
         "lite-server": "^2.3.0"
     },
     "dependencies": {
         "liteserver": "^0.3.0"
     }
}

还需要编写bs-config.json来配置一下lite-server
{
 "server": {
 "baseDir": ["./src", "./build/contracts"]
 }
}

baseDir是用来设置lite-server所提供的web服务的文件路径的。这个设置表明你可以把你上面写的app.js,依赖的各种js放到./src目录下,然后写index.html,把app.js等集成进去,就大功告成了。

启动lite-server,执行:
npm run dev

不仅启动了lite-server,而且会启动一个浏览器去打开页面。

本文的目的是为了澄清一下写DApp的各项工具之间的架构关系,帮助技术人员更快的理解和实现自己的项目。

具体的例子网上多如牛毛,就不去写业务的具体代码了。


基于HyperLedger的Fabric实现私有链–Doing

一、Fabric的架构

Fabric的架构我觉得下面这张图描述的还是比较清楚的。

Fabric的节点类型主要有Peer和Orderer两类。Peer负责背书(Endorser)、向帐本(区块链,Ledger)提交(Committer)、执行智能合约(Chaincode)、维护帐本(Ledger)。Orderer节点负责对交易进行排序(有人把这个过程叫完成共识)。

其他的MemberShip节点实际上就是个CA(证书中心),负责发证书。Fabric的各节点之间是靠数字证书来实现权限管理和身份认证的。

用户(或者客户端)完成一次调用智能合约的过程如下:

(1)生成一次智能合约调用请求(这里叫Proposal),发送给背书节点(Endorser ,包含在Peer节点上)。

(2)背书节点验证请求的正确性,并且调用智能合约(ChainCode)来模拟执行,生成执行操作过程集合(就是把对数据的读写操作过程和结果记录下来),背书节点对其进行签名(就是开个证明说这次调用的过程和结果是正确的),然后返回给请求发起方。

(3)请求发起方再把背书节点返回的结果发给Orderer节点去进行排序(因为同时会有很多人发起请求,需要有人对其排序,然后才能按顺序写入帐本)。

(4)Orderer节点对请求进行排序后,把排序后的请求发送给Peer节点上的Commiter,Commiter负责把这些交易通过Ledger记录下来。

这样就完成了一次智能合约的调用。

从上述过程来看,Fabric实际上适合应用在小范围内的私有环境或者联盟环境中,不适合公链。

Fabric的智能合约实际上就是一个程序,部署在一个docker中,背书节点在需要时调用它执行。

Fabric用一个数据库(类型可选)来用key-value的方式存储智能合约的数据。

二、Fabric的部署

Fabric的部署十分依赖Docker。要部署Fabric,需要先在机器上装Docker。如何装Docker请自行查找资料。因为每个人用的操作系统和版本都不同,所以安装docker时遇到的问题也可能不同。我遇到的最讨厌的问题就是docker安装完成之后一启动dockerd,就报错:

time=”2018-03-07T11:06:03.573781204+08:00″ level=error msg=”[graphdriver] prior storage driver devicemapper failed: devicemapper: Error running deviceCreate (CreatePool) dm_task_run failed”

最后发现是我的Slackware-Current版本使用的是kernel-huge内核,其中对devicemapper的支持有点问题。有人说使用kernel-generic内核就可以了,我懒得改,最后在/etc/default/docker中加入:

DOCKER_OPTS=”$DOCKER_OPTS -s overlay”

使用overlay模式搞定。

装好Docker之后,

(1)mkdir -p go/src/github.com/hyperledger

(2)cd go/src/github.com/hyperledger

(3)git clone https://github.com/hyperledger/fabric.git

(4)cd go/src/github.com/hyperledger/fabric

(5)make orderer

(6)make peer

(7)make configtxgen

(8)make cryptogen

(9)make configtxlator

(10)make orderer-docker

(11)make peer-docker

(12)make tools-docker

(13)make docker

上述过程会有很多坑,折腾吧。主要都是缺少依赖库引起的。有遇到问题可以google/baidu或者在评论区留言。

如果一切顺利,最后执行docker images,会出现:

这表明你的安装差不多对了。

下面开始运行fabric来测试你的部署吧。

(1)cd go/src/github.com/hyperledger/fabric/examples/e2e_cli

(2)sh network_setup.sh

如果最后看到如下的结果,表明你的部署应该对了:

这是个fabric的例子,用命令行cli的方式来实现部署go语言实现的chaincode_example2,为了帮助对fabric的理解,你可以执行:

docker exec -it cli bash

进入cli的docker,然后在docker里执行:

peer chaincode query -C mychannel -n mycc -c ‘{“Args”:[“query”,”a”]}’

这条操作的目的是在chaincode上执行查询a有多少币。执行结果类似:

我的这个改过了,所以显示query result: 910

如果你还想了解更多如何用cli来部署合约、初始化合约、执行合约(invoke),你可以看一下go/src/github.com/hyperledger/fabric/examples/e2e_cli/scripts/script.sh文件,仔细研究一下它的各个命令。

三、智能合约的实现

实际上,链只解决了智能合约(ChainCode)的管理框架、状态数据的存储框架、帐本的记录框架等基础功能。真正实现链的功能多样化要靠各种智能合约才行。

Fabric 1.0 支持Go/Java开发的智能合约。据说今后要支持Python等语言。

下面我们试图要实现一个消息订阅的智能合约。

1、业务逻辑

(1)消息发布者A可以发布接受订阅的智能合约,表明消息的类别等简要说明以及订阅价格。

(2)消息订阅者B可以支付费用成为A的订阅用户,订阅者B的信息保存在智能合约中

(3)当B想阅读A发布的消息时,A的消息订阅服务从智能合约中查询B是否是消息订阅者,如果是,则允许阅读,如果否,则拒绝阅读。

2、与以太坊的代币的交互

B支付费用使用以太坊发行的代币支付。(如何在ChainCode中与以太坊交互部分还在找资料调研中)

3、实现细节

具体的chaincode会发布到github中。

基于区块链的去中心化的同学录–Thinking

同学录承载了70后、80后的回忆,卖给Sohu的ChinaRen,后来成为人人网的校内网,都是以同学录起家。潮起潮落,当年承诺陪你到永远的这些网站最终都雨打风吹去,那些无处安放的青春记忆该走向何方?

去中心化的区块链+Token似乎能够解决上述问题。数据的分散存储不会因为某个公司的业务裁撤而丢失。Token能让用户按需付费。

人人为我,我为人人,共同存储,共同服务。利用区块链将分散的存储能力统一为可持续发展的服务能力

利用智能合约实现同学关系的认证,利用小程序实现区块链与微信的对接,打通社交的最后一公里。

给非技术人员讲比特币+区块链–Blahblah

总要给非技术人员讲比特币、区块链,既要通俗易懂,又要讲到精髓,不能让这些人出去露怯,影响名声,所以总结如下。

一、账本中的比特币

没有像人民币一样有唯一编号的一个个比特币,比特币就是账本中记录的一笔笔交易的汇总:

A挖矿得了50个比特币

A转了15.5个比特币给B

A转了20个比特币给C

C转了5个比特币给B

。。。。。。

A现在有多少个比特币:50-15.5-20=14.5

B现在有多少个比特币:15.5+5=20.5

C现在有多少个比特币:20-5=15

所以说,比特币跟当年生产队会计在账本里给队员记的工分差不多。核心就是:

正确的说法:你有多少比特币

错误的说法:这个比特币是我的

二、区块链是什么

区块链(BlockChain)就是上面的那个账本,在计算机中表现的就是一个个文件:blockchain.001, blockchain.002,blockchain.003,……

这些文件是有格式的:

澄清个概念:Hash是一种密码学中的算法,也叫“Message Digest”,信息摘要。作用是用长度较短的一段值来代表很大很大的数据。比如1G大小的文件,其md5算法的hash值只有20个字节。算法保证了不同的数据不会有相同的hash值。即使两个文件只差了一个字母,其hash值也差别非常大。

PrevHash:指向上一个块,这样就能将这些“块(block)”组成一条前后相连的“链(chain)”,这就是“区块链(blockchain)”这个词的由来。

MerkleTreeRootHash:从上面图中矿工挖矿的公式可以看到,求解的时候没有把交易列表带进公式。这样做的目的是减少计算量。可这样一来怎么证明这些交易保存在这个块里呢?比特币的设计者想了个办法,它用交易列表Tx1、Tx2、Tx3、Tx4。。。来生成一个MerkleTreeRootHash来做代表,参与挖矿计算。借张别人的图来说明,不自己画了:

其中的L1/L2…就相当于我们的Tx1/Tx2…,Top Hash就是我们的MerkleTreeRootHash。只要有人胆敢修改任何一个交易,那最后的MerkleTreeRootHash就会改变,矿工原先求出来的不等式就不成立了,就会被其他人发现。用这种方式来保证已经写到区块链里的交易不会被篡改。

nTime:时间戳,当前块的挖矿的时间。

nBits:挖矿难度的一种表示方法,它和矿工挖矿公式中的targethash是一一对应的。为了让大家有机会当一次专家,把这个转换公式告诉大家,看不懂就不用看了:假设nBits=0x1903a30c,那么targethash = 0x03a30c * 2^(0x08 * (0x19 – 0x03)).

Nonce:随机数。矿工就是从0开始,不断地换这个nonce来看不等式是否成立。直到找到一个nonce能让不等式成立,那么这个矿工就成功挖出了一个块。这个块的奖励(每一块的固定奖励+这一块中的交易的手续费)就归这个矿工所有。当然前提是你算的比别人快,否则你就白算了。

上面这些信息叫做:区块头(BlockChain Header)

交易列表:保存在这一区块中的交易信息列表。

这些信息合在一起叫做一个区块(Block)。以文件的形式存储。

三、矿工挖矿

矿工为什么要挖矿?矿工挖矿就是用求解不等式的方式来声明:我是最聪明的那个生产队会计,我记录的这个块的内容算数,大家都要认。同时矿工拿到了挖这个块的奖励(生产队会计拿到了工资)。用“求解不等式的方式来决定哪个矿工的结果被大家公认”这种行为叫”共识(Consensus),这种办法叫“工作量证明(Proof of Work)“。实际上,也可以用这样的方式来决定:把N个生产队会计关在一个屋子里,让他们打,最后活下来的那个来记账。这也是一种共识。大家也可以试试。

矿工挖矿的过程是怎样的呢?从网上下载个比特币的挖矿程序,运行起来,这个运行起来的程序通常叫做“比特币节点”或者“挖矿节点”。那些要转账的人创建一个转账交易,发送到某个节点上去。挖矿节点会接收到很多笔转账交易请求,它验证这些交易请求的合法性,比如:要转账的人是否有那么多的比特币,这个发起转账交易请求的人是否是这些比特币的真正所有者。

验证完成后,它把这些交易丢到交易池中,并从中选择合适的交易列表放到区块链中的“交易列表”中去。它选择合适交易的原则是:

(1)给自己奖励的这笔交易得写到交易列表的第1位

(2)根据给的交易手续费高低排序,手续费高的排前面

(3)那些手续费低的或者根本不给手续费的往后排。但是一块的容量有限,如果这一次排不进去,就丢到下一次再说。但是也不能总不处理,每向后推迟一次,就把这个交易的优先级提高一点,如果优先级达到最高值,那就不得不处理。每一个块的前50个字节留给这种优先级最高的交易。

选择好交易列表,然后计算出MerkleTreeRootHash,填好区块头中的其他项Version/PrevHash/MerkleTreeRootHash/nTime/nBits,让随机数nonce从0开始尝试,看哪个nonce能让那个不等式成立。一旦运气好,找到了一个nonce让不等式成立,那么恭喜你,你已经成功挖出了一块。赶快将你已经成功挖出的这一块通知给其他也在挖这一块的矿工。其他矿工收到你的通知后,验证你这一块的交易是否正确,再把你挖出的这块的信息带入不等式验证不等式是否成立,如果成立,按照之前已经达成的“共识”,其他矿工把你这块信息保存下来,接受你挖出这一块的事实,认可你这一块里的交易成立。大家停止挖这一块,开始挖下一块。

矿工周而复始地重复上述过程,这样一笔笔交易就被记录到区块链中。

四、交易

比特币系统中矿工挖矿过程实际上就是把验证过的交易数据写到区块链中。

那么交易数据是怎样的?矿工和其他人又是怎么验证交易是正确的呢?

再次来澄清一个概念:非对称加密算法。这类算法的特点是:加解密需要一对秘钥,公钥和私钥。公钥加密的东西只有私钥能解,私钥加密的东西只有私钥能解。在密码学里,人们用这个特性实现了一种叫“签名”的功能:

私钥加密(hash(“blahblahblah”))= 签名             生成签名

公钥解密(签名)是否= hash(“blahblahblah”)     验证签名

验证签名的过程证明了两点:

(1)这个签名确实是私钥签的,因为私钥只有所有者知道,所以这个签名确实是私钥所有者签的。

(2)被签名的内容确实是“blahblahblah”,没有被更改过。

交易的生成过程如下图所示:

矿工收到上述的交易后,开始验证交易是否正确:

(1)从之前的区块中找到输入交易TxIn1和TxIn2,确认之前确实有其他人发送过这两笔比特币给地址ZZZZ

(2)因为地址是从公钥转换而来,和公钥是一一对应的,所以矿工用公钥计算出地址来确认公钥和地址ZZZZ是匹配的。

(3)用公钥验证上图中的“地址ZZZZ的签名”确认本次交易的发起者确实是地址ZZZZ的所有者。

(4)验证TxIns和TxOuts中的比特币数量符合要求

验证通过后,如果运气好,交易被写到区块中,那么本次交易完成。交易必须被写到区块里才被认为交易完成。

五、关于比特币其他你需要知道的

(1)比特币系统中一个区块被挖出(求出那个不等式的解)的时间平均为10分钟。每挖出2016个区块(大约2周),会根据这2016个块的挖出平均时间修改nBits(就是挖矿难度),来保证每块的挖矿时间保持在10分钟左右。

(2)挖出比特币区块的矿工奖励最开始是50个,每挖出210000个块奖励减半(大约需要4年),到目前为止已经减半两次了,所以现在每块的奖励是12.5个。

(3)因为所有的比特币都是矿工挖出来的,所以按照这个减半规则,比特币的总量大约在2100万个(20,999,999,980),大约在2140年左右挖完。

(4)比特币挖完后,矿工的奖励靠交易的手续费提供。

(5)因为比特币的挖矿是谁最先求出不等式的解来谁就胜出,所以有人开始“组队”挖矿,每人计算一段(有人算0-10000,有人算10001-20000…),如果挖成功,按照队员贡献的计算能力来分配所获得的比特币。这就是大家经常说的“矿池”。

(6)分叉:区块链是动态发展的,当某一天有人提出要对比特币或者其他的加密货币进行改进的时候,整个社区会对这些提议进行讨论,就会出现有的人支持改进,有些人不支持。这种分歧可能会导致出现两种比特币程序和两条链。分别有不同的人支持。这就会造成所谓的“分叉”

(7)山寨币:某些人看到比特币能赚钱,有些人想学习区块链提升一下自己的技术能力,这些人会把比特币的程序拿过来,修改修改参数或者某些Pow算法,然后起个其他的名字:例如NiuXXCoin。这就形成了所谓的“山寨币”。

六、其他的数字货币

目前世界范围内的几大主流币:

BTC:比特币,数字货币鼻祖

BCH:比特币现金,从BTC分叉而来,目的是通过加大每个区块的大小来提升交易速度。现在的价格大致6000多CNY

LTC:莱特币,早期山寨比特币而来。目的是通过修改Pow的算法来降低挖矿的难度,让CPU能挖矿。现在价格1000多CNY

ETH:以太币,以太坊中使用的币种。目的是通过加入图灵完备的EVM(以太坊虚拟机)来支持智能合约(运行在EVM上的应用程序),让用户可以在其中实现业务逻辑。以太坊将数字货币带入2.0时代。大量的ICO是基于以太坊的智能合约做的。现在价格4000多CNY

ETC:以太坊经典,从ETH分叉而来。当年ETH出现Bug,造成黑客偷窃了以太坊中其他人的大量以太币。社区中有人提出应该回滚到被偷以前的状态,有些人不同意。最后以太坊分叉成ETH和ETC,支持回滚的跟着ETH走了,不支持回滚的跟着ETC走了。所以ETC成为以太坊经典。现在价格100多CNY

USDT:泰达币,由Tether公司发行。它宣称USDT和USD$是对等的,每发行一个USDT,就在银行里存1USD$. 用户可以随时拿USDT到Tether公司兑换USD$,但是会收取一定比例的手续费。

七、ICO

ICO是Initial Coin Offering的简写。用一个故事来解说ICO是个什么东西:

(1)我想开一家健身房,但是我没钱

(2)我发行10万个健身币,每个5CNY,我的健身房开起来之后任何人都可以拿1个健身币到我的健身房健身1小时。

(3)大家纷纷用5CNY的价格买走了我10万个健身币,我得到了50万CNY,我拿这些钱开始筹备我的健身房。

(4)我完成了健身币的ICO

(5)有些买了我的健身币的人,不想健身了,想把这些币卖掉,这个时候有人开了个交易所,撮合其他想卖和想买健身币的人进行交易。从而实现了健身币的流通。

(6)我的健身房终于开放了。有人拿健身币到我的健身房进行健身。每小时1个健身币。有人算了算,发现以我的健身房的设施,其他健身房都收10块钱一小时。所以有人就通过交易所买健身币。交易所中的健身币的价格从5块涨到了9块。

(7)原先以5块一个买健身币的人在交易所中以9块一个的价格卖掉,赚了4块,非常高兴。以9块买了健身币的人,以比其他健身房便宜1块钱的价格享受了服务,也非常高兴。

(8)这就是ICO的故事的0.5版本。

以太坊(ETH)的智能合约的出现,让上述ICO的过程得以在区块链上实现。它制定了一个叫ERC20的协议,让ICO的代币发行非常方便:

在以太坊上可以实现币的查询和转来转去,而且这些信息都写在区块链里,不可篡改,公开可查询,太方便了。还有雷锋帮大家写好了标准的智能合约,ico发个币只需要15分钟就可完成。

交易所实现了币的变现,聪明的广大人民群众发现了赚钱的好方法,15分钟在以太坊上ico发个币,只要交易所里有人买,价格能上涨,就能赚钱。从此ICO进入了V1.0版本。

八、常见的几种区块链

ICO的出现将区块链的概念推向了高潮。但是币市有风险,投资需谨慎。这样下去会影响安定团结的。所以各国的监管政策开始收紧。一部分有信仰的技术人员开始将数字货币分解为币+链两个概念,形成了“币圈”和“链圈”两个不同的维度。链圈鄙视币圈,宣称我们要用区块链技术来改变世界,从而出现了多种区块链的实现。

(1)比特币一脉:以比特币为原型,作用只产生币及币的交易。BTC/BCH/LTC是这类

(2)ETH一脉:以以太坊为代表,被称为区块链2.0。支持智能合约,能在其上运行受限功能的程序。ETH/ETC/QTUM是这类。

(3)提高交易性能一脉:因为比特币/ETH等以POW共识机制,区块创建周期长,需要消耗额外的(被称为无意义的)计算力,造成每秒能够处理的交易量有限,无法支撑大交易量的需求,有人开始提出了替代Pow的Pos(Proof of Stake,权益证明)共识。以提高交易处理能力为目标,陆续出现Pos、DPos等共识方式,石墨烯技术等提高区块同步方式,这些被整合到一起,形成了提高交易性能一脉。EOS等是这类。

(4)有链无币类:区块链的信仰者觉得区块链作为技术能够改变世界,一些大公司也陆续开源了一些区块链的技术实现。这些区块链以链为中心,不涉及发币。大量应用在一些行业、私有业务上。典型代表是Linux基金会下的HyperLedger(超级账本),HyperLedger项目下有IBM贡献的Fabric以及Intel、Microsoft贡献的其他两种实现。

区块链创业的切入点选择

蛮荒时代的区块链,Fork山寨币,讲故事发空气ICO。因为币的供给少,资金供给(韭菜)多,在交易所上很容易套现,所以能赚到钱。

随着ICO项目数量的爆发,供给增加,投资者开始选择项目。此时的区块链创业要考虑行业和技术两个维度:行业积累和技术经验

当前的区块链创业就是在打时间差:(1)有行业经验,补区块链技术。(2)有区块链技术,颠覆行业传统。

既无行业经验,又无技术积累的状况下去进行区块链创业,成功概率会极低。