以太坊简介
基本概念
- 以太坊是一个区块链的网络,由很多节点组成
- 以太坊可以转账,可以做数据存储(合约)(通过交易承载)
- 以太坊可以执行程序,程序叫做智能合约,所有节点都运行这个程序
环境
-
浏览器插件
MetaMask
(仅具有转账功能,合约开发需要配合Remix
编译器) -
Remix
编译器
以太坊网络环境
-
主网络
花费真实的以太币
-
测试网络
-
私有网路
-
公共网络
-
Morden(已退役)
Morden是以太坊官方提供的测试网络 . 2016年11月时,由于难度炸弹已经严重影响出块速度,不得不退役,Morden的共识机制为PoW。
-
Ropsten
Ropsten也是以太坊官方提供的测试网络,是为了解决Morden难度炸弹问题而重新启动的一条区块链,目前仍在运行,共识机制为PoW。
-
Kovan
为了解决测试网络中PoW共识机制的问题,以太坊钱包Parity的开发团队发起了一个新的测试网络Kovan。Kovan使用了权威证明(Proof-of-Authority)的共识机制,简称PoA。
PoW是用工作量来获得生成区块的权利,必须完成一定次数的计算后,发现一个满足条件的谜题答案,才能够生成有效的区块。
PoA是由若干个权威节点来生成区块,其他节点无权生成,这样也就不再需要挖矿。由于测试网络上的以太币无价值,权威节点仅仅是用来防止区块被随意生成,造成测试网络拥堵,完全是义务劳动,不存在作恶的动机,因此这种机制在测试网络上是可行的。
Kovan与主网络使用不同的共识机制,影响的仅仅是谁有权来生成区块,以及验证区块是否有效的方式,权威节点可以根据开发人员的申请生成以太币,并不影响开发者测试智能合约和其他功能。
Kovan目前仍在运行,但仅有Parity钱包客户端可以使用这个测试网络。
-
Rinkeby
Rinkeby也是以太坊官方提供的测试网络,使用PoA共识机制。
(获取测试币比较困难)
-
-
以太坊账户系统
以太坊使用私钥通过 ECDSA算法推导出公钥,继而经过 Keccak-256 单向散列函数推导出地址,没有做base58。
账户类型分类
- 外部账户(普通账户)
- 由私钥来控制
- 没有代码
- 内部账户(合约账户)
- 合约有代码
账户余额
-
整个以太坊维持一个所有账户状态的树,这棵树的hash会打包在每个区块的区块头Root字段里。
-
状态树并不存在于链上,而存在于节点的levelDB中。只有它的根hash存在于区块头Root中,每一个区块头里的Root都是区块被挖出确认时的快照。
交易
- 转账交易:合约无关
-from
-to
-value
-hex data 可有可无
- 部署合约
- from必须有
- to不需要填写
- value可有可无
- hex data一定有,数据就是合约的bytecode
- 调用合约方法
- from必须有
- to一定有,合约地址
- value可有有无
- hex data一定有,是调用的方法
写数据花费gas
,读免费
gas
-
gas(汽油)(油耗)
由于以太坊是公链,所有人都可以自由的参与,为了防止垃圾数据充斥网络,所以以太坊上规定每一个操作都是要有成本的,这个成本由
gas
来体现,你要转账,部署智能合约,调用智能合约方法,都要消耗一定数量的gas。 -
gasprice(汽油价格)(油价)
虽然操作消耗gas,但是最终真正花的还是eth,所以就有一个转换率的问题,gasprice就是起到一个汇率的作用,它代表的是一个gas值多少eth,gas*gasprice就是最终的手续费,也就是从你账户扣除的eth。
这种设计就可以保证用户在以太坊上的操作的手续费不会随着eth的价格而发生剧烈的变动(例如:如果eth涨,那么可以调低gasprice来降低手续费),
-
gaslimit(汽油上限) (油箱)
以太坊规定,每笔交易的gas最少21000,矿工可以调整这个值,所以最终的花费的gas是不确定的,所以以太坊就设置了gaslimit,这个代表的是最多给旷工这么多gas(防止自己写的合约里面有死循环),如果最终使用的gas少于这个gaslimit,剩余的还会返给你的,但是如果你的gaslimit不足以支付这次交易,那就是不会退回的,并且交易也就失败了,转账的额度也是回不来了,所以你转账设置的limit一定要大于21000。
为什么要有gasprice和gas的概念
- 消耗的手续费(eth单位) = gas(int类型) * gasprice(wei单位)
- eth的价格波动剧烈,使用gas和gasprice使得用户可以灵活控制成本
- 1ether = 10^9 gwei = 10^18wei
以太坊开发环境
Remix
官方出的一个在线版的编译器
地址
https://remix.ethereum.org/#optimize=true&version=soljson-v0.5.0+commit.1d4f565a.js&evmVersion=null
示例合约
pragma solidity ^0.5.0; //指定编译器版本。每一句代码后面要加上分号
//每一个合约要使用contract开头,定义一个合约,Inbox合约的名字
contract Inbox{
//定义一个string变量,var已经被废弃了。
//public权限说明,代表公共的,go里面的大写字段
//这个在合约内,函数外的变量,我们叫做状态变量。真正写入区块链的数据
string public message;
//构造函数,合约定义的时候执行且仅执行一次的函数
//在构造函数中一般执行初始化动作:给变量赋值,或者写一个init1函数
constructor() public {
}
//定义普通函数,function关键字
//每一个函数都可以修饰为public/private权限,internal,external
//修改状态变量的函数,是需要花费手续费的。
function setMessage(string memory newMessage) public {
message = newMessage;
}
//读取数据,读免费。
//如果有返回值,需要指定returns关键字修饰,同时标注返回值类型,并且使用圆括号包裹,可以返回多个参数。
function getMessage() public view returns(string memory){
return message;
}
}
remix
编辑器中自动集成了solidity
的编译器,所以可以自动编译我们的合约代码
abi与bytecode
-
bytecode是真正上传到以太坊的合约的二进制码
608060405234801561001057600080fd5b506103af806100206000396000f3fe6080604052600436106100565763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663368b8772811461005b578063ce6d41de14610110578063e21f37ce1461019a575b600080fd5b34801561006757600080fd5b5061010e6004803603602081101561007e57600080fd5b81019060208101813564010000000081111561009957600080fd5b8201836020820111156100ab57600080fd5b803590602001918460018302840111640100000000831117156100cd57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506101af945050505050565b005b34801561011c57600080fd5b506101256101c6565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015f578181015183820152602001610147565b50505050905090810190601f16801561018c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101a657600080fd5b5061012561025d565b80516101c29060009060208401906102eb565b5050565b60008054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156102525780601f1061022757610100808354040283529160200191610252565b820191906000526020600020905b81548152906001019060200180831161023557829003601f168201915b505050505090505b90565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156102e35780601f106102b8576101008083540402835291602001916102e3565b820191906000526020600020905b8154815290600101906020018083116102c657829003601f168201915b505050505081565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061032c57805160ff1916838001178555610359565b82800160010185558215610359579182015b8281111561035957825182559160200191906001019061033e565b50610365929150610369565b5090565b61025a91905b80821115610365576000815560010161036f56fea165627a7a72305820bb7c2c119c932f782011cc39cc120d8c609f10c96785b34c45d2a8e5411b82790029
-
abi: application binary interface,应用二进制码,他负责解析合约二进制码
abi: [ { "constant": false, "inputs": [ { "name": "newMessage", "type": "string" } ], "name": "setMessage", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "getMessage", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "message", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "inputs": [], "payable": false, "stateMutability": "nonpayable", "type": "constructor" } ]
部署合约也是一笔交易,hex data存的就是合约的bytecode