Submitted by admin on 2016, December 20, 11:39 PM
上一篇文章介绍了以太坊5个核心概念:以太坊虚拟机(EVM)、账户(Accounts)、交易(Transactions)、Gas、存储,主存和栈(Storage, Memory and the Stack)。这篇文章将谈谈其他几个核心概念。
指令集(Instruction Set)
EVM的指令集被刻意保持在最小规模,以尽可能避免可能导致共识问题的错误实现。所有的指令都是针对256比特这个基本的数据类型的操作。具备常用的算术,位,逻辑和比较操作。也可以做到条件和无条件跳转。此外,合约可以访问当前区块的相关属性,比如它的编号和时间戳。
消息调用(Message Calls)
合约可以通过消息调用的方式来调用其它合约或者发送以太币到非合约账户。消息调用和交易非常类似,它们都有一个源,一个目标,数据负载,以太币,gas和返回数据。事实上每个交易都可以被认为是一个顶层消息调用,这个消息调用会依次产生更多的消息调用。
一个合约可以决定剩余gas的分配。比如内部消息调用时使用多少gas,或者期望保留多少gas。如果在内部消息调用时发生了out-of-gas异常(或者其他异常),合约将会得到通知,一个错误码被压在栈上。这种情况只是内部消息调用的gas耗尽。在solidity中,这种情况下发起调用的合约默认会触发一个人工异常。这个异常会打印出调用栈。
就像之前说过的,被调用的合约(发起调用的合约也一样)会拥有崭新的主存并能够访问调用的负载。调用负载被存储在一个单独的被称为calldata的区域。调用执行结束后,返回数据将被存放在调用方预先分配好的一块内存中。
调用层数被限制为1024,因此对于更加复杂的操作,我们应该使用循环而不是递归。
代码调用和库(Delegatecall / Callcode and Libraries)
存在一种特殊类型的消息调用,被称为callcode。它跟消息调用几乎完全一样,只是加载自目标地址的代码将在发起调用的合约上下文中运行。
这意味着一个合约可以在运行时从另外一个地址动态加载代码。存储,当前地址和余额都指向发起调用的合约,只有代码是从被调用地址获取的。
这使得Solidity可以实现”库“。可复用的库代码可以应用在一个合约的存储上,可以用来实现复杂的数据结构。
日志(Logs)
在区块层面,可以用一种特殊的可索引的数据结构来存储数据。这个特性被称为日志,Solidity用它来实现事件。合约创建之后就无法访问日志数据,但是这些数据可以从区块链外高效的访问。因为部分日志数据被存储在布隆过滤器(Bloom filter) 中,我们可以高效并且安全的搜索日志,所以那些没有下载整个区块链的网络节点(轻客户端)也可以找到这些日志。
创建(Create)
合约甚至可以通过一个特殊的指令来创建其他合约(不是简单的向零地址发起调用)。创建合约的调用跟普通的消息调用的区别在于,负载数据执行的结果被当作代码,调用者/创建者在栈上得到新合约的地址。
自毁(Selfdestruct)
只有在某个地址上的合约执行自毁操作时,合约代码才会从区块链上移除。合约地址上剩余的以太币会发送给指定的目标,然后其存储和代码被移除。 注意,即使一个合约的代码不包含自毁指令,依然可以通过代码调用(callcode)来执行这个操作。
好了,通过前面的2篇文章,我们了解了以太坊的核心概念,接下来就可以通过编程来深入理解这些概念了。
以太坊 | 评论:0
| Trackbacks:0
| 阅读:552
Submitted by admin on 2016, December 20, 11:39 PM
以太坊虚拟机(EVM)
以太坊虚拟机(EVM)是以太坊中智能合约的运行环境。它不仅被沙箱封装起来,事实上它被完全隔离,也就是说运行在EVM内部的代码不能接触到网络、文件系统或者其它进程。甚至智能合约之间也只有有限的调用。
账户(Accounts)
以太坊中有两类账户,它们共用同一个地址空间。外部账户,该类账户被公钥-私钥对控制。合约账户,该类账户被存储在账户中的代码控制。 外部账户的地址是由公钥决定的,合约账户的地址是在创建合约时确定的(这个地址由合约创建者的地址和该地址发出过的交易数量计算得到,地址发出过的交易数量也被称作”nonce”)
两类账户唯一的区别是:合约账户存储了代码,外部账户则没有。
每个账户有一个key-value形式的持久化存储。key,value的长度都是256bit。
另外,每个账户都有一个以太币余额(单位是“Wei”),该账户余额可以通过向它发送带有以太币的交易来改变。
交易(Transactions)
一笔交易是一条消息,从一个账户发送到另一个账户。交易可以包含二进制数据(payload)和以太币。
如果目标账户包含代码,该代码和输入数据会被执行。
如果目标账户是零账户(账户地址是0),交易将创建一个新合约。正如上文所讲,这个合约地址不是零地址,而是由合约创建者的地址和该地址发出过的交易数量计算得到。创建合约交易的payload被当作EVM字节码执行。执行的输出做为合约代码被永久存储。这意味着,为了创建一个合约,你不需要向合约发送真正的合约代码,而是发送能够返回真正代码的代码。
Gas
以太坊上的每笔交易都会被收取一定数量的gas,gas的目的是限制执行交易所需的工作量,同时为执行支付费用。当EVM执行交易时,gas将按照特定规则被逐渐消耗。
gas price(gas价格,以太币计)是由交易创建者设置的,发送账户需要预付的交易费用 = gas price * gas amount。 如果执行结束还有gas剩余,这些gas将被返还给发送账户。
无论执行到什么位置,一旦gas被耗尽(比如降为负值),将会触发一个out-of-gas异常。当前调用帧所做的所有状态修改都将被回滚。
存储,主存和栈(Storage, Memory and the Stack)
每个账户有一块持久化内存区域被称为存储。其形式为key-value,key和value的长度均为256比特。在合约里,不能遍历账户的存储。相对于另外两种,存储的读操作相对来说开销较大,修改存储更甚。一个合约只能对它自己的存储进行读写。
第二个内存区被称为主存。合约执行每次消息调用时,都有一块新的,被清除过的主存。主存可以以字节粒度寻址,但是读写粒度为32字节(256比特)。操作主存的开销随着其增长而变大(平方级别)。
EVM不是基于寄存器,而是基于栈的虚拟机。因此所有的计算都在一个被称为栈的区域执行。栈最大有1024个元素,每个元素256比特。对栈的访问只限于其顶端,方式为:允许拷贝最顶端的16个元素中的一个到栈顶,或者是交换栈顶元素和下面16个元素中的一个。所有其他操作都只能取最顶的两个(或一个,或更多,取决于具体的操作)元素,并把结果压在栈顶。当然可以把栈上的元素放到存储或者主存中。但是无法只访问栈上指定深度的那个元素,在那之前必须要把指定深度之上的所有元素都从栈中移除才行。
下一篇文章将继续介绍以太坊核心概念。
以太坊 | 评论:0
| Trackbacks:0
| 阅读:420
Submitted by admin on 2016, December 20, 11:38 PM
如果你想测试一段简单的Solidity合约,你不需要安装任何东西,只要访问基于浏览器的Solidity就可以:https://chriseth.github.io/browser-solidity/
通过NPM / node.js命令在线安装
如何使用nodejs包的详细信息可以在代码库中找到:https://github.com/chriseth/browser-solidity#nodejs-usage%E3%80%82
二进制安装包
包括Mix IDE的二进制Solidity安装包在Ethereum网站C++ bundle中下载:https://github.com/ethereum/webthree-umbrella/releases%E3%80%82
从源码构建
在MacOS X、Ubuntu和其它类Unix系统中编译安装Solidity非常相似。这个指南开始讲解如何在每个平台下安装相关的依赖软件,然后构建Solidity。
MacOS X
系统需求:
安装Homebrew:
1 2 3 4 5 6
|
brew update brew install boost --c++11 # 需要等待一段时间 brew install cmake cryptopp miniupnpc leveldb gmp libmicrohttpd libjson-rpc-cpp # 仅仅安装Mix IDE和Alethzero brew install xz d-bus brew install llvm --HEAD --with-clang brew install qt5 --with-d-bus # 避免长时间的等待没有提示,可以添加 —verbose 输出信息。
|
安装:xcode
Ubuntu系统
Ubuntu系统下面是在最新版Ubuntu系统上编译安装Solidity的指南。最佳的支持平台是2014年11月发布的64位Ubuntu 14.04
安装依赖软件:在你从源码编译之前,你需要准备一些工具和依赖软件。 首先,升级你的代码库。Ubuntu主代码库不提供所有的包,你需要从Ethereum PPA和LLVM获取。 注意
Ubuntu 14.04的用户需要使用:
1
|
sudo apt-add-repository ppa:george-edison55/cmake-3.x
|
获取最新版本的cmake。
现在加入其它的包:
1 2 3 4 5 6 7 8
|
sudo apt-get -y update sudo apt-get -y install language-pack-en-base sudo dpkg-reconfigure locales sudo apt-get -y install software-properties-common sudo add-apt-repository -y ppa:ethereum/ethereum sudo add-apt-repository -y ppa:ethereum/ethereum-dev sudo apt-get -y update sudo apt-get -y upgrade
|
对于Ubbuntu 15.04(Vivid Vervet)或者更老版本,使用下面的命令获取开发相关的包:
1
|
sudo apt-get -y install build-essential git cmake libboost-all-dev libgmp-dev libleveldb-dev libminiupnpc-dev libreadline-dev libncurses5-dev libcurl4-openssl-dev libcryptopp-dev libjson-rpc-cpp-dev libmicrohttpd-dev libjsoncpp-dev libedit-dev libz-dev
|
对于Ubbuntu 15.10(Wily Werewolf)或者更新版本,使用下面的命令获取开发相关的包:
1
|
sudo apt-get -y install build-essential git cmake libboost-all-dev libgmp-dev libleveldb-dev libminiupnpc-dev libreadline-dev libncurses5-dev libcurl4-openssl-dev libcryptopp-dev libjsonrpccpp-dev libmicrohttpd-dev libjsoncpp-dev libedit-dev libz-dev
|
不同版本使用不同获取命令的原因是,libjsonrpccpp-dev已经在15.10以后的Ubuntu的通用代码仓库中。
编译
如果你只准备安装solidity,忽略末尾Alethzero和Mix的错误。
1 2 3 4 5
|
git clone --recursive https://github.com/ethereum/webthree-umbrella.git cd webthree-umbrella ./webthree-helpers/scripts/ethupdate.sh --no-push --simple-pull --project solidity # 更新Solidity库 ./webthree-helpers/scripts/ethbuild.sh --no-git --project solidity --all --cores 4 -DEVMJIT=0 # 编译Solidity及其它 # 在OS X系统加上DEVMJIT将不能编译,在Linux系统上则没问题
|
如果你选择安装Alethzero和Mix:
1 2 3
|
git clone --recursive https://github.com/ethereum/webthree-umbrella.git cd webthree-umbrella && mkdir -p build && cd build cmake ..
|
好了,正常的话所有安装完毕。
以太坊 | 评论:0
| Trackbacks:0
| 阅读:487
Submitted by admin on 2016, December 20, 11:36 PM
以太坊是区块链开发领域最好的编程平台,而truffle是以太坊(Ethereum)最受欢迎的一个开发框架,这是我们第一篇区块链技术文章介绍truffle的原因,实战是最重要的事情,这篇文章不讲原理,只搭建环境,运行第一个区块链程序(Dapp)。
安装truffle
$ npm install -g truffle
依赖环境 NodeJS 访问https://nodejs.org 官方网站下载安装
系统:Windows, Linux or Mac OS X,推荐Mac OS X,不建议使用Windows,会碰到各种各样的问题,导致放弃。
需要安装Ethereum客户端,来支持JSON RPC API调用 开发环境,推荐使用EthereumJS TestRPC: https://github.com/ethereumjs/testrpc
安装命令: $ npm install -g ethereumjs-testrpc
新建第一个项目
$ mkdir zhaoxi
$ cd zhaoxi
$ truffle init
默认会生成一个MetaCoin的demo,可以从这个demo中学习truffle的架构
项目目录结构如图:

项目所有文件目录如图:

编译项目
$ truffle compile 
部署项目
部署之前先启动TestRPC
$ testrpc
$ truffle deploy(在Truffle 2.0以上版本中,命令变成了:truffle migrate)
$ truffle migrate 执行结果 
启动服务
$ truffle serve 
启动服务后,可以在浏览器访问项目: http://localhost:8080/ ,网页界面如下:

好了,第一个区块链程序跑起来了
以太坊 | 评论:0
| Trackbacks:0
| 阅读:505
Submitted by admin on 2016, December 20, 9:54 PM
1、安装Nodejs
官网地址为http://nodejs.org
但国外地址下载太慢了,建议从淘宝下载(https://npm.taobao.org/mirrors/node/)
wget https://npm.taobao.org/mirrors/node/latest-v4.x/node-v4.4.7-linux-x64.tar.gz
解压:
tar -zxvf node-v4.4.7-linux-x64.tar.gz
设置环境变量:
export PATH=$PATH:/opt/node-v4.4.7-linux-x64/bin
-----
wget https://npm.taobao.org/mirrors/node/latest-v6.x/node-v6.9.2.tar.gz
tar zxvf
./configure;make;make install
---------------------
2、安装NMP
下载nmp安装包,一般nodejs包中已经包含了,设置过环境变量就可以直接使用nmp命令了,如果没有安装,先下载:
官网地址:www.npmjs.com
淘宝地址:https://npm.taobao.org/mirrors/npm/
安装使用如下命令:
node cli.js install npm -gf
3、安装CNMP(非必要)
由于NMP源都在国外,下载相关资源很慢,所以建议用国内的淘宝NPM镜像(http://npm.taobao.org/)
通过cnmp命令安装的包都会从淘宝NMP下载,速度很快。
$ npm install -g cnpm --registry=https://registry.npm.taobao.org
安装完之后,安装模块的命令就变为:
同步模块命令为:
linux | 评论:0
| Trackbacks:0
| 阅读:625
Submitted by admin on 2016, December 18, 7:56 PM
wget https://www.python.org/ftp/python/3.4.3/Python-3.4.3.tar.xz -c
xz -d Python-3.4.3.tar.xz
tar xvf Python-3.4.3.tar
cd Python-3.4.3
./configure --prefix=/usr
make
make install
ln -sf /usr/bin/python3.4 /usr/bin/python
pytyon | 评论:0
| Trackbacks:0
| 阅读:521
Submitted by admin on 2016, December 18, 7:55 PM
pip安装方法
Pip 是安装python包的工具,提供了安装包,列出已经安装的包,升级包以及卸载包的功能。
Pip 是对easy_install的取代,提供了和easy_install相同的查找包的功能,因此可以使用easy_install安装的包也同样可以使用pip进行安装。
安装Pip
Pip的安装可以通过源代码包,easy_install或者脚本。
下面介绍一下各种安装方法:
源代码方式:
$ wget https://pypi.python.org/packages/source/p/pip/pip-1.2.1.tar.gz (替换为最新的包)
$ tar xzf pip-1.2.1.tar.gz
$ cd pip-1.2.1.tar.gz
$ python setup.py install
easy_install:
$ easy_install pip
get_pip.py 脚本:
$ curl -0 https://raw.github.com/pypa/pip/master/contrib/get-pip.py
$ sudo python get-pip.py
OK, 下面来看一下Pip的使用
安装package
$ pip install Markdown
列出安装的packages
$ pip freeze
安装特定版本的package
通过使用==, >=, <=, >, <来指定一个版本号。
$ pip install 'Markdown<2.0'
$ pip install 'Markdown>2.0,<2.0.3'
升级包
升级包到当前最新的版本,可以使用-U 或者 --upgrade
$ pip install -U Markdown
卸载包
$ pip uninstall Markdown
查询包
pip search "Markdown"
pytyon | 评论:0
| Trackbacks:0
| 阅读:537
Submitted by admin on 2016, December 18, 7:34 PM
XZ压缩最新压缩率之王
xz这个压缩可能很多都很陌生,不过您可知道xz是绝大数linux默认就带的一个压缩工具。
之前xz使用一直很少,所以几乎没有什么提起。
我是在下载phpmyadmin的时候看到这种压缩格式的,phpmyadmin压缩包xz格式的居然比7z还要小,这引起我的兴趣。
最新一段时间会经常听到xz被采用的声音,像是最新的archlinux某些东西就使用xz压缩。不过xz也有一个坏处就是压缩时间比较长,比7z压缩时间还长一些。不过压缩是一次性的,所以可以忽略。
xz压缩文件方法或命令
xz -z 要压缩的文件
如果要保留被压缩的文件加上参数 -k ,如果要设置压缩率加入参数 -0 到 -9调节压缩率。如果不设置,默认压缩等级是6.
xz解压文件方法或命令
xz -d 要解压的文件
同样使用 -k 参数来保留被解压缩的文件。
创建或解压tar.xz文件的方法
习惯了 tar czvf 或 tar xzvf 的人可能碰到 tar.xz也会想用单一命令搞定解压或压缩。其实不行 tar里面没有征对xz格式的参数比如 z是针对 gzip,j是针对 bzip2。
创建tar.xz文件:只要先 tar cvf xxx.tar xxx/ 这样创建xxx.tar文件先,然后使用 xz -z xxx.tar 来将 xxx.tar压缩成为 xxx.tar.xz
解压tar.xz文件:先 xz -d xxx.tar.xz 将 xxx.tar.xz解压成 xxx.tar 然后,再用 tar xvf xxx.tar来解包。
linux | 评论:0
| Trackbacks:0
| 阅读:458