Ethereum - 以太坊项目
以太坊项目进一步扩展了区块链网络的能力,从交易延伸为智能合约(Smart Contract)。
其官网首页为 ethereum.org。
简介
根据以太坊官方的宣称,以太坊(Ethereum)目标是打造成一个运行智能合约的去中心化平台(Platform for Smart Contract),平台上的应用按程序设定运行,不存在停机、审查、欺诈、第三方人为干预的可能。以太坊平台由 Golang、C++、Python 等多种编程语言实现。
当然,为了打造这个平台,以太坊提供了一条公开的区块链,并制定了面向智能合约的一套编程语言。智能合约开发者可以在其上使用官方提供的工具来开发支持以太坊区块链协议的应用(即所谓的 DAPP)。
历史与规划
2014 年,以太坊项目开始众筹计划。
2015 年 7 月,众筹完成,筹到价值 1800 万美金的比特币,第一阶段 Frontier 发布,以太坊区块链网络正式上线。
2016 年 3 月,第二阶段 Homestead 开始运行(区块数 1150000),主要改善了安全性。
2016 年 3Q,发布 Metropolis;
2017 年 1Q,发布 Serenity,发布区块链的 PoS 股权证明(Casper)版本。
特点
以太坊区块链的特点主要包括:
- 单独为智能合约指定编程语言 Solidity;
- 使用了内存需求较高的哈希函数:避免出现算力矿机;
- uncle 块激励机制:降低矿池的优势,减少区块产生间隔为 15 秒;
- 难度调整算法:一定的自动反馈机制;
- gas 限制调整算法:限制代码执行指令数,避免循环攻击;
- 记录当前状态的哈希树的根哈希值到区块:某些情形下实现轻量级客户端;
- 为执行智能合约而设计的简化的虚拟机 EVM。
组织
- 以太坊基金会:2014 年 6 月在瑞士注册的非营利性机构,管理以太坊获得的资金分配。
安装部署
如果你是首次接触 ethereum,推荐使用下面的步骤安装部署。
安装 Go 环境
curl -O https://storage.googleapis.com/golang/go1.5.1.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.5.1.linux-amd64.tar.gz
mkdir -p ~/go; echo "export GOPATH=$HOME/go" >> ~/.bashrc
echo "export PATH=$PATH:$HOME/go/bin:/usr/local/go/bin" >> ~/.bashrc
source ~/.bashrc
安装 ethereum
sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo add-apt-repository -y ppa:ethereum/ethereum-dev
sudo apt-get update
sudo apt-get install ethereum
安装 solc 编译器
sudo add-apt-repository ppa:ethereum/ethereum-qt
sudo add-apt-repository ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install cpp-ethereum
安装后可以使用 geth 命令创建 ethereum 账户
geth account new
Solidity 语言支持
browser-solidity 提供了在线的 Solidity 语言测试。
用户也可以从 这里 下载到包括 Solidity 运行环境的安装包。
相关工具
客户端
官方提供钱包客户端 Mist,支持进行交易,同时支持直接编写和部署智能合约。
所编写的代码编译发布后,可以部署到区块链上。使用者可通过发送调用相应合约方法的交易,由矿工的以太坊虚拟机(EVM)在区块链上执行。
以太坊现在有多种语言实现的客户端,包括:
- ethereumjs-lib:javascript 语言实现;
- Ethereum(J):Java 语言实现;
- ethereumH:Haskell 语言实现;
- go-ethereum:go 语言实现;
- Parity:Rust 语言实现;
- pyethapp:python 语言实现;
- ruby-ethereum:Ruby 语言实现;
IDE
网站资源
已有一些网站提供对以太坊网络的数据查看,包括 EthStats.net、EtherNodes.com 等。
协议设计
核心概念
- EVM:以太坊虚拟机,轻量级虚拟机环境,是以太坊中智能合约的运行环境。
- Account:账户,分两类:合约账户存储执行的合约代码;外部账户为以太币拥有者账户,对应到某公钥。
- Transaction:交易,从一个账户到另一个账户的消息,包括以太币或者合约执行参数。
- Gas:燃料,每执行一条合约指令会消耗一定的燃料,当某个交易还未执行结束,而燃料消耗完时,合约执行终止并回滚状态。
一致性
目前采用了 PoW 作为一致达成保证,未来可能迁移到 PoS 上。
降低攻击
设计核心思想是通过经济激励机制防止少数人作恶:
- 所有交易都要提供交易费用,避免 DDoS 攻击;
- 程序运行指令数通过 gas 来限制,所消耗的费用超过设定上限时会被取消,避免恶意合约。
提高扩展性
以太坊未来希望通过分片机制可以提高整个网络的扩展性。分片之前整个网络的处理取决于单个节点的处理。
分片后,只有同一片内的处理是同步的、一致的,不同分片之间则可以是异步的。
链码示例一:Hello World!
简介
smartContract_example01.sol
合约greeter是一个简单的智能合约,你可以使用这个合约来和其他人交流,它的回复会同你的输入完全一样,当输入为“Hello World!”的时候,合约也会回复“Hello World!”。
目的:
该合约主要面向第一次接触solidity和ethereum的初学者,旨在让大家能够了解如何编写一个简单的智能合约程序, 掌握基本流程。
主要实现如下的功能:
- 返回你预先设置的字符串
主要函数
-
kill
:selfdestruct 是 ethereum 智能合约自带的自毁程序,kill对此方法进行了封装,只有合约的拥有者才可以调用该方法; -
greet
:返回合约 greeter 里的 greeting属性的值;
代码运行分析
第一步 生成智能合约代码对象
我们先把合约代码smartContract_example01.sol 压缩为一行.新建一个ssh session, 切换到geth用户环境su - geth
, 然后输入:cat smartContract_example01.sol | tr 'n' ' '
. 切换到以太坊控制台,把合约代码保存为一个变量:
var greeterSource = 'contract mortal { address owner; function mortal() { owner = msg.sender; } function kill() { if (msg.sender == owner) selfdestruct(owner); } } contract greeter is mortal { string greeting; function greeter(string _greeting) public { greeting = _greeting; } function greet() constant returns (string) { return greeting; } }'
第二步 编译合约代码
然后编译合约代码:
var greeterCompiled = web3.eth.compile.solidity(greeterSource)
greeterCompiled.Token.code
可以看到编译好的二进制代码 greeterCompiled.Token.info.abiDefinition
可以看到合约的ABI
第三步 设置希望返回的字符串
var _greeting = "Hello World!"
第四步 部署合约
接下来我们要把编译好的合约部署到网络上去.
首先我们用ABI来创建一个javascript环境中的合约对象:
var greeterContract = web3.eth.contract(greeterCompiled.greeter.info.abiDefinition);
我们通过合约对象来部署合约:
var greeter = greeterContract.new(_greeting,{from:web3.eth.accounts[0], data: greeterCompiled.greeter.code, gas: 300000}, function(e, contract){
if(!e) {
if(!contract.address) {
console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined...");
} else {
console.log("Contract mined! Address: " + contract.address);
console.log(contract);
}
}})
- greeterContract.new方法的第一个参数设置了这个新合约的构造函数初始化的值
- greeterContract.new方法的第二个参数设置了这个新合约的创建者地址from, 这个新合约的代码data, 和用于创建新合约的费用gas.gas是一个估计值,只要比所需要的gas多就可以 ,合约创建完成后剩下的gas会退还给合约创建者.
- greeterContract.new方法的第三个参数设置了一个回调函数,可以告诉我们部署是否成功.
contract.new执行时会提示输入钱包密码.执行成功后,我们的合约Token就已经广播到网络上了. 此时只要等待矿工把我们的合约打包保存到以太坊区块链上,部署就完成了.
第五步 挖矿
在公有链上,矿工打包平均需要15秒,在私有链上,我们需要自己来做这件事情.首先开启挖矿:
miner.start(1)
此时需要等待一段时间,以太坊节点会生成挖矿必须的数据,这些数据都会放到内存里面. 在数据生成好之后,挖矿就会开始,稍后就能在控制台输出中看到类似:
...
I0714 22:00:19.694219 ethash.go:291] Generating DAG: 97%
I0714 22:00:22.987934 ethash.go:291] Generating DAG: 98%
I0714 22:00:26.543035 ethash.go:291] Generating DAG: 99%
I0714 22:00:29.912655 ethash.go:291] Generating DAG: 100%
I0714 22:00:29.915580 ethash.go:276] Done generating DAG for epoch 2, it took 5m34.983289765s
第六步 停止挖矿(可选)
当生成DAG结束,提示已经挖出至少一个矿以后,我们需要停止挖矿(当然,你也可以不停,就是会一直输出)
miner.stop()
第七步 部署在其他节点上
现在,你已经成功部署了一个智能合约,当运行以下代码时:
//由于该命令未改变blockchain,所以不会有任何花费greeter.greet();
命令行上会出现如下返回结果:
'Hello World!'
好了,我们的第一个智能合约程序 "Hello World!" 已经完成了,但是目前它只有一个节点!
第八步 部署在其他节点上
为了使得其他人可以运行你的智能合约,你需要两个信息:
- 智能合约地址Address
- 智能合约ABI(Application Binary Interface),ABI其实就是一个有序的用户手册,描述了所有方法的名字和如何调用它们。 我们可以使用如下代码获得其ABI和智能合约地址: greeterCompiled.greeter.info.abiDefinition;greeter.address;
然后你可以实例化一个JavaScript对象,该对象可以用来在任意联网机器上调用该合约,此处ABI和Address是上述代码返回值。
+
var greeter = eth.contract(ABI).at(Address);
第九步 自毁程序
一个交易需要被发送到网络需要支付费用,自毁程序是对网络的补充,花费的费用远小于一次常用交易。
你可以通过以下代码来检验是否成功,如果自毁程序运行成功以下代码会返回0:
greeter.kill.sendTransaction({from:eth.accounts[0]})
参考文献
THE GREETER YOUR DIGITAL PAL WHO'S FUN TO BE WITH
以太坊本地私有链开发环境搭建
- 有趣的算法(五) ——Dijkstra双栈四则运算
- CSS深入理解学习笔记之float
- 轻松初探 Python 篇(五)—dict 和 set 知识汇总
- 全面解析C#中的异步编程为什么要异步过去糟糕的体验一个新的方式Tasks基于任务的异步编程模型Async和await时间处理程序和无返回值的异步方法结束语
- CSS深入理解学习笔记之absolute
- 5个经典的JavaScript面试题
- 轻松初探 Python 篇(四)—list tuple range 知识汇总
- CSS深入理解学习笔记之overflow
- Python爬虫实践——简单爬取我的博客
- Python爬虫入门(二)
- 在ASP.NET MVC5应用程序中快速接入QQ和新浪微博OAuth起步创建应用程序使用NUGET更新OWIN中间件启动SSL支持申请腾讯QQ的Oauth申请新浪微博的Oauth快速接入资源地址&源码
- 有趣的算法(六) ——Find-Union算法
- 有趣的算法(七) ——快速排序改进算法
- 编写你人生中第一个机器学习代码吧!
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 二、JSON数据格式
- 一、Ajax的基本用法
- 图解HTTP读书笔记
- Flutter性能调优、复杂业务保证Flutter的高性能高流畅
- requests项目实战--抓取百度热搜
- [代码片段]谷歌的一个不错的CSS样式,不得不说大厂的前端设计师美感就是好。
- 罗马数字转整数
- 找出两个文件中相同的单词(java实现)
- Apache日志变量详解
- 三、jQuery中的Ajax
- SAP ABAP ADBC和Java JDBC的使用比较
- 自己开发的一个SAP CRM订单统计工具
- SAP ABAP和Java跨域请求问题的解决方案
- 使用ABAP Channel实现一个订单跟踪工具,提高日常工作效率
- SAP CRM状态字段下拉列表里数据的填充原理