Submitted by admin on 2016, December 21, 11:32 AM
Application Backend
存在的目的:
后端应用程序服务支持应用程序关联到移动设备或者浏览器
关键角色:
1)通过成员服务管理末端使用者和注册者
2)启动交易请求,发送请求到末端
Owned by
Solution provider, Network Proprietor
NVP节点
存在的目的:
构建交易并且将它们发送到VP节点,peer节点保存了一份所有交易的副本以便于solution providers能够在本地查询它们
关键角色:
1.管理或者维护通过成员服务发行的用户证书
2.构建交易并且将交易转发到VP节点
3.维护一个本地账本,允许application owner查询当地的信息
Owned by:
Solution Provider, Network Auditor
VP节点
存在的目的:
创建并且确认交易事物,并且维护chaincode的状态
关键角色:
1)管理并且维护被成员服务发布的用户证书
2)创建交易
3)在区块链网络上和其他VP节点一起执行交易
4)维护本地账本副本
5)参与共识并且更新账本
Owned by:
Network proprietor, Solution provider
membership(在未来的1.0版本中将变成cop)
存在的目的:
末端用户或者组织的身份发行与管理
关键角色:
1)发行登记证书给各个末端使用者或者组织
2)发行交易证书到关联的各个末端使用者
3)发行TSL证书确保在HyperLedger Fabric之间通信
4)发行链特别的Key
Owned by: Third Party service provider
注:目前我们使用的HyperLedger fabric是0.6版本,与将要发布的1.0版本相比较,Fabric有以下变动:
1)HyperLedger Fabric v1.0 membersrvc模块将独立出来成为新的COP模块。
COP将为Hyperledger fabric提供一个类似警方的安全功能
COP的代码将比membership servicev0.6版本更短更简单
2)HyperLedger Fabric v1.0将更具有安全性和扩展性,COP的独立出来将更使基于HyperLedger Fabric改造更简单。
3)交易加密方面也将比v0.6版本加强很多,例如供应链, FOREX market, 健康医疗方面交易更加安全
区块链 | 评论 :0
| Trackbacks :0
| 阅读 :501
Submitted by admin on 2016, December 21, 11:32 AM
一、配置Swagger-UI
1.你可以使用本地的node.js服务来运行rest-api,确保你本机已经安转node.js,如果没有安装,请安转一个
2.命令行下安转node.js
------npm install http-server -g
3.在你本机上启动http-server运行rest-api
------cd /opt/gopath/src/github.com/hyperledger/fabric/core/rest
-------http-server -a 0.0.0.0 -p 5554 --cors
4.浏览器中输入下面语句,确保能成功连接
------http://localhost:5554/rest_api.json
5.使用命令行下载 Swagger-UI包
------git clone https://github.com/swagger-api/swagger-ui.git
6.到 /swagger-ui/dist 下用浏览器打开index.html
7.启动没有连接到leader or validator的peer节点
----cd /opt/gopath/src/github.com/hyperledger/fabric
-----build/bin/peer node start
8.测试
----cd /opt/gopath/src/github.com/hyperledger/fabric/core/rest
----go test -v -run TestServerOpenchain_API_GetBlockCount
二、Node.Js应用程序
构建并且安装 fabric core.
cd /opt/gopath/src/github.com/hyperledger/fabric
make peer
在本地仅仅运行一个节点 (不是一个完整的网络) :
build/bin/peer node start
配置一个测试区块链数据结构通过vagrant来运行测试接下来重启peer进程.
cd /opt/gopath/src/github.com/hyperledger/fabric/core/rest
go test -v -run TestServerOpenchain_API_GetBlockCount
在本地电脑上启动http-server来运行rest_api.json服务.
npm install http-server -g
cd /opt/gopath/src/github.com/hyperledger/fabric/core/rest
http-server -a 0.0.0.0 -p 5554 --cors
下载和解压 Sample_1.zip
unzip Sample_1.zip -d Sample_1
cd Sample_1
如果没有默认的URL地址就在openchain.js文件中更新api_url变量以搭配合适的URL
Update the api_url variable within openchain.js to the appropriate URL if it is not already the default
var api_url = 'http://localhost:5554/rest_api.json';
运行Node.js app
node ./openchain.js
区块链 | 评论 :0
| Trackbacks :0
| 阅读 :570
Submitted by admin on 2016, December 21, 11:31 AM
一、安装docker
1、docker要求Linux内核版本不低于 3.10
>>检查Linux的内核版本,如果内核版本太低,升级内核
>>查看内核的版本命令uname -a
2、根据不同的Ubuntu版本安装docker
>>查看Ubuntu版本命令lsb_release -a
3、对于16.04的Ubuntu版本安装
>>sudo apt-get install docker-engine
4、启动
>>sudo systemctl enable docker
>>sudo systemctl start docker
二、从docker上拉取镜像
1、检验docker是否安装好
>>docker
2、从docker上拉镜像
>>docker pull hyperledger/fabric-peer:latest
>>docker pull hyperledger/fabric-membersrvc:latest
3、校验镜像是否拉取完成
>>docker images
三、安装docker-compose项目
1、安装pip工具
>>pip工具会依赖Python,而Ubuntu下默认已经安转好Python2.7
>>apt-get install python_pip
2、安转docker compose项目
>>sudo pip install -U docker-compose
3、校验docker compose是否安装好
>> docker-compose -h
四、安装并配置nsenter工具
方法一、
>>wget https://www.kernel.org/pub/linux/utils/util-linux/v2.29/util-linux-2.29.tar.xz; tar xJvf util-linux-2.29.tar.xz
>>cd util-linux-2.29
>> ./configure --without-ncurses && make nsenter
>>sudo cp nsenter /usr/local/bin
方法二、建议下载 .bashrc_docker,并将内容放到 .bashrc 中
>>wget -P ~ https://github.com/yeasy/docker_practice/raw/master/_local/.bashrc_docker;
>>echo "[ -f ~/.bashrc_docker ] && . ~/.bashrc_docker" >> ~/.bashrc; source ~/.bashrc
五、启动节点
1、在root的Home目录下创建Docker -compose.yml并写入一下内容
membersrvc: image: hyperledger/fabric-membersrvc ports: - "7054:7054" command: membersrvc vp0: image: hyperledger/fabric-peer ports: - "7050:7050" - "7051:7051" - "7053:7053" environment: - CORE_PEER_ADDRESSAUTODETECT =true - CORE_VM_ENDPOINT =unix: ///var /run/docker .sock - CORE_LOGGING_LEVEL =DEBUG - CORE_PEER_ID =vp0 - CORE_PEER_PKI_ECA_PADDR =membersrvc: 7054 - CORE_PEER_PKI_TCA_PADDR =membersrvc: 7054 - CORE_PEER_PKI_TLSCA_PADDR =membersrvc: 7054 - CORE_SECURITY_ENABLED =true - CORE_SECURITY_ENROLLID =test_vp0 - CORE_SECURITY_ENROLLSECRET =MwYpmSRjupbT links: - membersrvc command: sh -c "sleep 5; peer node start --peer-chaincodedev"
2、通过docker-compose up运行已近配置好的节点
六、进入容器
1、docker -ps 找到要进入的容器的CONTAINER ID
2、用docker-pid指令获取需要进入容器的PID
>>echo PID=(docker-pid b4378c920828)
3、借助PID进入容器
>>sudo nsenter --target 10981 --mount --uts --ipc --net --pid
七、测试环境是否搭建好
1、选择源码中的一个例子chaincode机型编译
>>cd$GOPATH/src/github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
>>go build
2、注册和运行chaincode
>>CORE_CHAINCODE_ID_NAME=mycc CORE_PEER_ADDRESS=0.0.0.0:7051 ./chaincode_example02
3、另起一个终端,进入容器的方式和“六”一样,以WebAppAdmin的形式登录到节点上
>>peer network login WebAppAdmin -p DJY27pEnl16d
4、执行下面的代码,在另外一个终端里面会看到执行结果
安全模式
部署交易
>>CORE_SECURITY_ENABLED=true CORE_SECURITY_PRIVACY=true peer chaincode deploy -u WebAppAdmin -n mycc -c '{"Function":"init", "Args": ["a","100", "b", "200"]}'
调用交易
>>CORE_SECURITY_ENABLED=true CORE_SECURITY_PRIVACY=true peer chaincode invoke -u WebAppAdmin -l golang -n mycc -c '{"Function": "invoke", "Args": ["a", "b", "10"]}'
查询交易
>>CORE_SECURITY_ENABLED=true CORE_SECURITY_PRIVACY=true peer chaincode query -u WebAppAdmin -l golang -n mycc -c '{"Function": "query", "Args": ["b"]}'
区块链 | 评论 :0
| Trackbacks :0
| 阅读 :533
Submitted by admin on 2016, December 21, 12:15 AM
Geth客户端的CPU挖矿效率非常低,纯属鸡肋。如对CPU挖矿感兴趣,请参照 此帖 。下面介绍GPU挖矿。
硬件
GPU挖矿需要1-2GB显存(译者注:1GB显存不可以),显存不够会一直报错。GPU矿机是基于OpenCL的,所以AMD显卡比NVIDI显卡更有效率。
ASIC和FPGA(即专业矿机)是无效的。
根据自己的显卡类型和系统,选择openCL:
AMD SDK openCL
NVIDIA CUDA openCL
Ubuntu系统
AMD显卡
• 地址1
• 地址2
下载: ADL_SDK8.zip 和 AMD-APP-SDK-v2.9-1.599.381-GA-linux64.sh
./AMD-APP-SDK-v2.9-1.599.381-GA-linux64.sh
ln -s /opt/AMDAPPSDK-2.9-1 /opt/AMDAPP
ln -s /opt/AMDAPP/include/CL /usr/include
ln -s /opt/AMDAPP/lib/x86_64/* /usr/lib/
ldconfig
reboot
apt-get install fglrx-updates
// wget, tar, opencl
sudo aticonfig –adapter=all –initial
sudo aticonfig –list-adapters
* 0. 01:00.0 AMD Radeon R9 200 Series
* – Default adapter
Nvidia显卡
使用Ubuntu 14.04和Nvidia显卡的用户请看此帖
MacOSx系统
wget http://developer.download.nvidia.com/compute/cuda/7_0/Prod/local_installers/cuda_7.0.29_mac.pkg
sudo installer -pkg ~/Desktop/cuda_7.0.29_mac.pkg -target /
brew update
brew tap ethereum/ethereum
brew reinstall cpp-ethereum --with-gpu-mining --devel --headless --build-from-source
检查你的冷却状态:
aticonfig –adapter=0 –od-gettemperature
挖矿软件
Frontier阶段默认的客户端Geth只支持CPU挖矿。我们正在开发Geth客户端的GPU挖矿功能,但是在Frontier阶段完成不了。但是,Geth可以和Ethminer配合进行GPU挖矿。
C++客户端可以进行GPU挖矿。C++客户端包括eth(命令行用户界面)、AlethZero(图形用户界面)和ethMiner(独立的挖矿软件)。
在Linux上可以用ppa安装,在MacOS上可以用brew tap安装,或者从源代码安装。
MacOS系统:
brew install cpp-ethereum –with-gpu-mining –devel –build-from-source
Linux系统:
apt-get install cpp-ethereum
Windows系统上查看
利用ethminer进行GPU挖矿
用eth挖矿:
eth -m on -G -a -i -v 8 //
从源代码安装ethminer:
cd cpp-ethereum
cmake -DETHASHCL=1 -DGUI=0
make -j4
make install
进行GPU挖矿,你需要一个coinbase账户。你可以本地或者远程设置此账户。
配合使用ethminer和geth
geth account new
geth –rpccorsdomain localhost 2>> geth.log &
ethminer -G // -G for GPU, -M for benchmark
tail -f geth.log
ethminer与geth通过8545端口通信。你可以使用geth –rpcport optoin改变这一默认端口。Ethminer将发现Geth的任何端口。注意,你需要使用–rpccorsdomain localhost色环指CORS数据头。你也可以使用-F http://127.0.0.1:3301为ethminer设置端口。如果你打算在同一台电脑上设置多个挖矿实例,设置端口是必要的。如果你正在一个私有群(cluster)上进行测试,我们推荐你进行CPU挖矿。
注意,你不许为geth设置–mine参数或者在控制台中开启矿机,除非你想在GPU挖矿之上进行CPU挖矿。
如果ethminer的默认设置不能工作,请用以下命令指定OpenCL设备:–opencl-device X ,X为0,1,2等。如果运行ethminer -M时,你应该看到类似于如下的信息:
Benchmarking on platform: { "platform": "NVIDIA CUDA", "device": "GeForce GTX 750 Ti", "version": "OpenCL 1.1 CUDA" }
Benchmarking on platform: { "platform": "Apple", "device": "Intel(R) Xeon(R) CPU E5-1620 v2 @ 3.70GHz", "version": "OpenCL 1.2 " }
调试geth:
geth –rpccorsdomain “localhost” –verbosity 6 2>> geth.log
调试矿机:
make -DCMAKE_BUILD_TYPE=Debug -DETHASHCL=1 -DGUI=0
gdb –args ethminer -G -M
注意,当进行GPU挖矿时,在geth中hashrate是不可用的。查看ethminer的hashrate,miner.hashrate将一直报告0.
ethminer和eth
通过rpc,ethminer也可以和eth配合使用
eth -i -v 8 -j // -j for rpc
ethminer -G -M // -G for GPU, -M for benchmark
tail -f geth.log
或者你可以单独使用eth进行GPU挖矿:
eth -m on -G -a -i -v 8 //
以太坊 | 评论 :0
| Trackbacks :0
| 阅读 :546
Submitted by admin on 2016, December 20, 11:53 PM
go-ethereum
go-ethereum客户端通常被称为geth,它是个命令行界面,执行在Go上实现的完整以太坊节点。通过安装和运行geth,可以参与到以太坊前台实时网络并进行以下操作:
挖掘真的以太币
在不同地址间转移资金
创建合约,发送交易
探索区块历史
及很多其他
链接:
pyethapp
Pyethapp是以python为基础的客户端,实现以太坊加密经济状态机。python实现旨在提供一个更容易删节和扩展的代码库。Pyethapp利用两个以太坊核心组成部分来实现客户端:
pyethereum —— 核心库,以区块链、以太坊模拟机和挖矿为特征
pydevp2p —— 点对点网络库,以节点发现和运输多码复用和加密连接为特征
链接:
ethereumjs-lib
正如黄皮书中所说,ethereumjs-lib是核心以太坊功能的javascript库。这是个简单的元模块,提供以下模块。大部分JS模块都在ethereumjs上有跟踪。
虚拟机 – 以太坊虚拟机和状态处理功能
区块链 – 区块链管理
区块 – 区块模式定义和验证
交易 – 交易模式定义和验证
账户 – 账户模式定义和验证
rlp – 循环长度前缀序列化
Trie – 改良的Merkle Patricia树
Ethash – 以太坊工作量证明算法
utils – 多样辅助功能
devp2p – 网络协议
devp2p-dpt – 有争议的对等端表
链接:
Ethereum(J)
Ethereum(J) 是以太坊协议的纯Java实现。它作为可以嵌入任何Java/Scala项目的库提供,并为以太坊协议及附属服务提供完全支持。Ethereum(J)最开始由Roman Mandeleil开发,现在受 <ether.camp>资助。
Ethereum(J)支持CPU挖矿。目前它由纯Java实现,可用于私人和测试网络。你甚至可以在实时以太坊网络上挖矿,但是这样从经济角度来说不划算。
链接:
ethereumH
这个程序包提供了写在Haskell上的工具,能使你连接到以太坊区块链。
链接:
Parity
Parity 声称是世界上最快速最轻便的客户端。它用Rust语言写成,可靠性、性能和代码清晰度都有所增强。Parity由Ethcore开发。Ethcore由以太坊基金会的几个会员创建。
Arch Linux 程序包由Afri Schoedon和quininer进行社群维护。
已经有人报告在树莓派2上成功运行了Parity。
ruby-ethereum
ruby-ethereum是以太坊虚拟机上的一个实现,用Ruby语言写成。
链接:
相关:
ruby-serpent: 捆绑在以太坊 Serpent编译器上的Ruby语言.
ethereum-ruby: 一个pure-Ruby JSON-RPC包装,用于和以太坊节点交流。要使用这个库,你需要有运行的以太坊节点和可行的IPC支持(默认)。目前支持go-ethereum 客户端。
参考资料:
文章中的列表对应的链接可以参考《Ethereum Homestead Documentation》第41页1.2.4 go-ethereum
以太坊 | 评论 :0
| Trackbacks :0
| 阅读 :552
Submitted by admin on 2016, December 20, 11:46 PM
账户
账户在以太坊中发挥着中心作用。共有两种账户类型:外部账户(EOAs)和合约账户。我们这里重点讲一下外部账户,以下会简称为账户。合约账户简称为合约, 在合约章节具体讨论。把外部账户和合约账户都归入到帐户的一般概念是合理的,因为这些实体都是所谓的状态对象。这些实体都有状态:账户有余额,合约既有余额也有合约储存。所有账户的状态正是以太坊网络的状态,以太坊网络和每个区块一起更新,网络需要达成关于以太坊的共识。对于用户通过交易和以太坊区块链互动来说,账户是必不可少的。
如果我们把以太坊限制为只有外部账户,只允许外部账户之间进行交易,我们就会进入到“代币”系统,“代币”系统不如比特币本身有力,只能用于转移以太币。
账户代表着外部代理人(例如人物角色,挖矿节点 ,或是自动代理人)的身份。账户运用公钥加密图像来签署交易以便以太坊虚拟机可以安全地验证交易发送者身份。
钥匙文件
每个账户都由一对钥匙定义,一个私钥和一个公钥。 账户以地址为索引,地址由公钥衍生而来,取公钥的最后 20个字节。每对私钥 /地址都编码在一个钥匙文件里。钥匙文件是JSON文本文件,可以用任何文本编辑器打开和浏览。钥匙文件的关键部分,账户私钥,通常用你创建帐户时设置的密码进行加密。钥匙文件可以在以太坊节点数据目录的keystore子目录下找到。确保经常给钥匙文件备份!查看备份和恢复账号章节了解更多。创建钥匙和创建帐户是一样的。
不必告诉任何人你的操作。
不必和区块链同步。
不必运行客户端。
甚至不必连接到网络。
当然新账户不包含任何以太币。但它将会是你的,你大可放心,没有你的钥匙和密码,没有人能进入。
转换整个目录或任何以太坊节点之间的个人钥匙文件都是安全的。
警告:请注意万一你从一个不同的节点向另一个节点添加钥匙文件, 账户的顺序可能发生改变。确保不要回复或改变手稿中的索引或代码片段。
创建账号
警告:记住密码并“备份钥匙文件<backup-and-restore-accounts>”。为了从账号发送交易,包括发送以太币,你必须同时有钥匙文件和密码。确保钥匙文件有个备份并牢记密码,尽可能安全地存储它们。这里没有逃亡路径,如果钥匙文件丢失或忘记密码,就会丢失所有的以太币。没有密码不可能进入账号,也没有忘记密码选项。所以一定不要忘记密码。
使用geth account new
一旦安装了geth客户端,创建账号就只是在终端执行 geth account new指令的问题了。
注意不必运行geth客户端或者和区块链同步来使用geth account指令。
1 2 3 4
Your new account is locked with a password. Please give a password. Do not forget this password. Passphrase: Repeat Passphrase: Address: {168bc315a2ee09042d83d7c5811b533620531f67}
对于非交互式使用,你可以提供纯文本密码文件作为—password标志的变元。文件中的数据包含密码的原始字节,后面可选择单独跟着新的一行。
1
$ geth --password /path/to/password account new
警告:用—password标志只是为了测试或在信任的环境中自动操作。不建议将密码保存在文件中或以任何其他方式暴露。如果你用密码文件来使用—password标志,要确保文件只对你自己可阅读和列表。你可以在 Mac/Linux系统中通过以下指令实现:
1 2 3 4
touch /path/to/password chmod 600 /path/to/password cat > /path/to/password >I type my pass
要列出目前在你的keystore文件夹中的钥匙文件的所有账号,使用 geth account指令的list子指令:
1 2 3
account #0: {a94f5374fce5edbc8e2a8697c15331677e6ebf0b} account #1: {c385233b188811c9f355d4caec14df86d6248235} account #2: {7f444580bfef4b9bc7e14eb7fb2a029336b07c9d}
钥匙文件的文件名格式为UTC—<created_at UTC ISO8601>–
。账号列出时是按字母顺序排列,但是由于时间戳格式,实际上它是按创建顺序排列。
使用geth控制台
为了用geth创建新账号,我们必须先在控制台模式开启geth(或者可以用 geth attach将控制台依附在已经运行着的事例上):
1 2 3 4 5
> geth console 2>> file_to_log_output instance: Geth/v1.4.0-unstable/linux/go1.5.1 coinbase: coinbase: [object Object] at block: 865174 (Mon, 18 Jan 2016 02:58:53 GMT) datadir: /home/USERNAME/.ethereum
控制台使你能够通过发出指令与本地节点互相作用。比如,试一下这个列出账号的指令:
1 2 3 4 5
> eth.accounts { code: -32000, message: "no keys in store" }
这就表明你没有账号。你也可以从控制台创建一个账号:
1 2 3 4
> personal.newAccount() Passphrase: Repeat passphrase: "0xb2f69ddf70297958e582a0cc98bce43294f1007d"
注意:记得用一个安全性强、随机生成的密码。
我们刚刚创建了第一个账号。如果我们再次试着列出账号,就可以看到新创建的账号了。
1 2
> eth.accounts ["0xb2f69ddf70297958e582a0cc98bce43294f1007d"]
使用 Mist 以太坊钱包
对于相反的命令行,现在有一个基于GUI的选项可以用来创建账号:“官方”Mist以太坊钱包。 Mist以太坊钱包,和它的父项目Mist, 是在以太坊基金会的赞助下开发,因此是“官方”地位。钱包应用有Linux, Mac OS X和Windows可用的版本。
警告:Mist钱包是试用软件,使用需风险自担。
用GUI Mist以太坊钱包创建账号再容易不过了。事实上,第一个账号在应用安装期间就创建出来了。
一、根据你的操作程序下载钱包应用最新版本。由于你实际上会运行一个完整的geth节点,打开钱包应用就会开始同步复制你电脑上的整个以太坊区块链。
二、 解锁下载的文件夹,运行以太坊钱包可执行文件。
三、 等待区块链完全同步,按照屏幕上的说明操作,第一个账号就创建出来了。
四、第一次登录Mist 以太坊钱包,你会看到自己在安装过程中创建的账号。它会被默认命名为主账号(以太库)
五、再另外创建账号很容易;只需点击应用主界面上的添加账号,输入所需的密码即可。
注意: Mist钱包仍在开发中,以上列出的具体步骤可能会随着更新有所变更。
以太坊 | 评论 :0
| Trackbacks :0
| 阅读 :545
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
| 阅读 :554
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
| 阅读 :421