区块链之以太坊初体验——以太坊平台学习总结

各种媒体和技术专家也对该技术的应用前景、对应用领域颠覆性的意义进行了大量的报道和描述,区块链技术会像互联网技术同样改变现有传统领域。业界也不乏技术实践的先行者,像R3区块链联盟、以太坊等,在平台实现、技术应用方面已经有了不少的尝试。javascript

640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy


近期,由于工做须要,对以太坊、区块链等技术和概念进行了学习和研究。本文是做者对前一段时间学习、工做实践和同事交流的一个知识整理。
前端


区块链DISCOVERY

区块链是一种基于点对点(peer-to-peer)网络、分布式的共享帐簿技术。java

640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy


通俗地理解,区块链就是一个公共的、去中心化的数据库,每一个节点(full node)上都保存有一份全量的如出一辙的数据,在一笔交易数据提交到区块链网络时,各个节点(node,也叫矿工)开始基于该交易信息进行数据块的计算,只有第一个被计算出并按照某种共识机制得其余的节点确认的数据块胜出,从而被添加到链上,该过程也叫算力竞争。后续数据块的计算都会基于前一个块的数据的hash值进行。
node


而区块链技术被寄予厚望的缘由正是,该技术的应用能够改变目前中心化的交易机制(目前,我的和组织的交易行为都是基于一个可信任的、中心化的机构来开展的,好比跨境结算,须要经过国际清算银行等中间机构才能完成交易),帮助人们构建一种可信任的、去中心化的交易机制,交易当事方不须要通过第三方机构而直接完成交易。git


这样下降交易的复杂度和中间费用,提升商业效率。同时,区块链经过分布式存储、公私钥加密等技术保证了交易数据的安全、可追溯、不可篡改性。github


以太坊DISCOVERY

以太坊是一个基于区块链技术的开源平台,经过它能够很是容易地构建去中心化的应用(Dapp)。在底层,以太坊基于区块链技术,实现了数据的去中心化、分布式存储和信息交换的信任问题。同时,以太坊实现了一个叫Ethereum Virtual Machine(EVM)的运行时环境,相似JVM,它的主要工做是执行智能合约(该概念下面会介绍)的字节码。
web

640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy


在以太坊中也有挖矿的概念,每一笔交易只有经过网络中的矿工进行挖矿才能提交到以太坊区块链中。数据库


  • 以太币express

相似比特币,以太坊平台上的数字货币,英文缩写ETH。npm


  • Gas

用户提交给EVM执行交易或智能合约时,须要支付的费用,由以太币按必定的比例转而来,当用户中的以太币不足以支付Gas时,EVM会中止执行提交的交易或者智能合约。


  • 帐户

在以太坊中有两类帐户:

  1. 外部帐户(externally owned account,EOA)

    用户能够经过地址和私钥对帐户进行操做。EOA能够在以太坊控制台中经过命令来建立,或者经过IPC方式由外部调用api来建立;


  2. 智能合约(smart contract)

    它在以太坊中的做用有:

    1)维护数据存储

    2)实现复杂的访问控制策略

    3)为其余合约提供方法调用。

    可是智能合约没法本身执行其中的逻辑或者方法,只能由EOA或者其余合约发起调用。

    在以太坊平台,智能合约的编程语言有Solidity(文件扩展名以.sol结尾)和Serpent(文件扩展名以.se结尾),但目前如今最流行并且最稳定的要算是Solidity。


  • 帐户在区块链中的存储结构

以太坊帐户的全部信息也存储在在区块链的结构中,以下图: 


不一样于比特币,在以太坊的区块链结构中,不只包含了对前一个区块的引用信息、区块号、交易和时间戳等信息,它还包含了全部以太坊帐户的信息,存储在以“STATE_ROOT”为根节点的一棵Patricia树(“a specialized kind of Merkle tree”)上。该根节点的值是对整棵数上保存的数据进行hash计算得出。


从图中能够看出,每一个帐户节点中包含四类信息:

  1. NONCE--记录从该帐户发起的交易数;

  2. BALANCE--记录该帐户余额;

  3. CODEHASH--智能合约帐户的代码hash值并指向合约代码,若是为EOA则该值为空;

  4. STORAGE_ROOT--另外一棵Patricia树的根节点,智能合约帐户的内部数据存储空间,当合约帐户调用suicide()方法时,该值将被置为null。


智能合约开发环境搭建DISCOVERY

为了便于智能合约的开发和测试,须要在本地电脑搭建一个以太坊开发环境。本文接下来将介绍如何使用Truffle+Testrpc来搭建环境。


Testrpc的介绍和使用

Testrpc是基于node.js开发的以太坊客户端,整个blockchain的数据驻留在内存空间,testrpc能够模拟一个geth客户端的行为,包括全部的RPC api,发送给testrpc的交易会被立刻处理而不须要等待挖矿时间,让基于以太坊的开发测试工做更加方便快速。


Testrpc安装。在命令行终端输入“npm install -g ethereumjs-testrpc”,等待完成便可。


启动Testrpc。输入命令”testrpc”便可,启动完成后,出现下图信息:

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


从中咱们能够看到,testrpc在启动时默认建立了多个帐号,并开放了rpc端口8545。


Truffle介绍

Truffle是一个基于以太坊的智能合约开发工具,支持对合约代码的单元测试,很是适合TDD。同时它内置了智能合约编译器,只要使用脚本命令就能够轻松完成合约的编译、动态库连接、部署、测试等工做,大大简化了智能合约的开发生命周期。


Truffle的安装很是简单,只要在终端输入命令“sudo npm install -g truffle”,等待安装完成便可。


使用Truffle开发智能合约的过程以下(如何编写合约及solidity语法不在本文范围):

  • 使用testrpc开启一个以太坊节点

  • 建立一个工程目录,并初始化

mkdir myProject

cd myProject

truffle init


初始化完成后,Truffle在工程目录下默认会生成一个叫MetaCoin的智能合约demo及其测试文件,目录结构以下:

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


各目录含义:

app/:存放前端javascript文件和stylesheets文件,在开发Dapps时使用;

contracts/:智能合约文件的存放目录;

migrations/:存放部署脚本;

test/:存放智能合约测试文件;

truffle.js:truffle的主配置文件,在该文件中能够指定以太坊客户端地址和rpc端口,network_id等;


1. 编写智能合约文件并编译,好比有个Multiply.sol,将其放入contracts目录下,执行命令“truffle complie”,代码片断以下:


2. 部署合约,执行命令“truffle deploy”,或者发布合约到以太坊客户端,在migrations目录下增长部署文件,好比3_deploy_multiply.js 文件,修改truffle.js中相关rpc的配置,执行命令“truffle migrate”,终端打印以下信息,表示成功发布;

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


3. 编写测试文件,保存为multiply.js,并放入test目录下(代码以下),执行命令“truffle test”:

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


执行结果以下:

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


智能合约的外部调用DISCOVERY

在某些应用场景下,为了接入以太坊区块链,业务系统须要调用以太坊客户端的api,将用户的交易数据发送给以太坊平台。以太坊客户端已经为外部系统提供了RPC和IPC两种api调用方式。


以RPC方式为例,使用curl命令请求的格式以下:

调用客户端命令:

假设咱们要调用客户端命令eth.getBalance(),查询地址为0x407的帐号的余额,命令以下:

curl --data '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0x407", "latest"],"id":1}' localhost:8123


其中:jsonrpc字段指定JSON-RPC版本号,method字段指定须要调用的api方法名,params字段为传送的参数,id为消息标识字段;


调用合约方法:

假设目前有部署的智能合约,地址为0x6ff93,咱们要调用的合约方法签名为multiply(uint256),传入的参数值为6,那么调用命令的格式以下:



其中,from为扣除GAS的帐户地址,to为智能合约部署的地址,data为调用方法的签名和传入参数,编码方式为:

“0x”+sha3(“multiply(uint256)”).substring(0,8)+to_32bit_Hex_str(6)


to_32bit_Hex_str()方法的实现会依据不一样的变量类型而有不一样,具体规则能够参考Ethereum Contract ABI 文档(HERE)。


从上面的示例能够看出,从外部对智能合约的调用须要进行复杂的编码。万幸,目前以太坊官方提供了使用javascript语言实现的web3.js模块,对RPC和IPC两种调用方式d都进行了封装,对外提供了简洁的接口,使用很是方便。


下面本文将使用web3.js模块在nodejs环境下实现对智能合约的调用,并向外提供RESTful的api。详情以下:

系统环境:

Ubuntu14.04.4+Node V5.1.1;


须要引入的Node模块

express、web三、net,可使用npm命令安装依赖;


主要代码片断

引入模块依赖

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


设置RPC和IPC链接对象

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


调用以太坊客户端方法,查询指定帐户的余额

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


新建以太坊帐户,该方法必须使用IPC api的调用方式

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


新建合约对象,其中contractData为合约代码编译后的16进制字符串


调用智能合约方法

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


开启http server

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


最后使用node启动服务,看到“Example app listening at http://:::9090”服务就启动成功了。这样用户即可经过RESTful的http请求来与以太坊客户端进行交互,并调用智能合约。


结束语

本篇文章是我对最近一段时间学习的以太坊平台和区块链技术的总结,主要介绍了以太坊平台的一些基本概念、智能合约本地开发环境的搭建和外部系统调用智能合约api开发介绍3个方面的内容,即当是一次以太坊区块链知识的概括梳理,也当是一次知识的分享交流。


因为学习的时间有限,文中不免有理解不到位得地方,还请你们指正!同时,很是感谢公司其余同事对我在学习以太坊平台中的帮助,让我受益不浅!最后,文中也引用和参考了不少官网的资料和网友的文章,在此献上真挚的谢意!


参考资料:

  1. https://blog.ethereum.org/2015/06/26/state-tree-pruning/

  2. https://blog.ethereum.org/2014/02/18/ethereum-scalability-and-decentralization-updates/

  3. http://gavwood.com/Paper.pdf

  4. http://truffle.readthedocs.org/en/latest/

  5. https://github.com/ethereumjs/testrpc

  6. http://www.ethdocs.org/en/latest/

  7. https://solidity.readthedocs.io/en/latest/

相关文章
相关标签/搜索