75

以太坊学习——从私有链、交易到智能合约

 5 years ago
source link: http://phantom0301.cc/2018/06/29/ether/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

纯技术学习

0x00 前言

一直希望能够从技术实现的层面去了解区块链技术,借助其他人的总结,大致以Geth为例了解了一下区块链技术。技术流程主要参照Andrew Back的分享,但是他的技术文章中也有一些小的错误,特别进行记录。

0x01 Geth简介及基本命令

Go Ethereum是以太坊协议的Go语言实现,以太坊和比特币的区别应该很多布道者都讲过,只要去看那些不拿赚钱说事的文章就可以了。

使用Ubuntu系统直接安装

sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum

安装完成后,我们按照创建用户、启动节点、绑定节点并进行基本信息的查询

  • 创建账户
geth account new

iENRbmM.jpg!web

创建时输入口令,成功后输出账户地址

  • 启动一个轻量级的节点
geth --syncmode light --cache 64 --maxpeers 12

如果不跟任何参数,启动的节点将会从同步公有节点的全部信息,因此我们只同步轻量级的区块头信息。

BnaqIbB.jpg!web

可以看到,该节点不断在导入新的区块头

  • 连接节点
geth attach

连接进我们新建的节点后,可以使用geth的基本信息查看指令

基本指令集 作用 示例 eth 区块链相关操作 eth.accounts
查看系统中所有账户
eth.getBlock(0)
获取区块信息 net 网络相关操作 net.peerCount
连接进公网的节点个数 admin 节点管理操作 admin.nodeInfo.enode
当前节点地址 miner 挖矿操作 miner.start()
开始挖矿 personal 账户管理操作 personal.newAccount()
新建账户
personal.unlockAccount()
解锁账户 txpool 交易内存池信息 txpool.status web3 对象及单位换算操作 web3.toWei()
以太币换算

0x02 文件系统

在建立私链实验之前,我们可以看一下,geth节点新建后文件格式。默认情况下,没有指定文件路径的情况下,会在当前用户目录下新建.ethereum文件夹,具体目录如下:

.ethereum
   |-geth
       |-chaindata  # 区块链最后的本地存储
             |-000001.log
             |-CURRENT
             |-LOCK
             |-LOG
             |-MANIFEST-000000
       |-lightchaindata # 轻量级的区块信息存储
   |-history # 操作历史
   |-keystore # 账户信息

BFjQnmr.jpg!web

可以看到这里有刚刚从公有链同步到的区块信息。

0x03 私有链

现在我们来建立一条自己的私有链,并且进行交易和挖矿操作。

  • 新建第一个节点

创建新账户

geth --datadir .phantom account new
Address: {cbd2c54856790f7be7c1d1142e304a7ff20ba329}
  • 新建初始化文件phantom.js
{
    "config": {
        "chainId": 1,
        "homesteadBlock": 0,
        "eip155Block": 0,
        "eip158Block": 0
    },
    "difficulty": "20",
    "gasLimit": "2100000",
    "alloc": {
        "cbd2c54856790f7be7c1d1142e304a7ff20ba329":
        { "balance": "20000000000000000000" }
    }
}

解释几个重要的参数:

chainId,节点ID
difficulty,挖矿难度
gasLimit,每个区块计算消耗gas的限额,后面会再讲这个概念
balance,初始账户中的余额
  • 初始化
geth --datadir .phantom init phantom.json
  • 启动节点并进入客户端
geth --identity chainpi --rpc --rpcport 8080 --rpccorsdomain "*" --datadir .phantom --port 30303 --nodiscover --rpcapi "db,eth,net,web3" --networkid 1 console

不同参数的含义:

- identity,节点名
- rpc,允许RPC操作
- rpcport,暴露的端口
- rpccorsdomain,允许远程访问的域名
- datadir,私有链存放路径
- port,网络监听端口
- nodiscover,防止被公有链发现
- rpcapi,开放的API
- networkid,网络号

进入后,可以查看到初始化设置的账户以及账户余额。

y2IVRrY.jpg!web

  • 用同样的配置文件在另一台主机上建立第二个节点
geth --datadir .ghost account new
geth --datadir .phantom account new
{
    "config": {
        "chainId": 1,
        "homesteadBlock": 0,
        "eip155Block": 0,
        "eip158Block": 0
    },
    "difficulty": "20",
    "gasLimit": "2100000",
    "alloc": {
        "cbd2c54856790f7be7c1d1142e304a7ff20ba329":
        { "balance": "20000000000000000000" }
    }
}
geth --datadir .ghost init ghost.json

geth --identity chainpi1 --rpc --rpcport 8080 --rpccorsdomain "*" --datadir .ghost --port 30303 --nodiscover --rpcapi "db,eth,net,web3" --networkid 1 console
  • 查询第一个节点的地址
admin.nodeInfo.enode
"enode://d439a8f2f17234f4dc5be674fb941355a36578f61dfb22bd927a7353ef36f64fb5a30d3a0532665005f34f30c12d811b817b577034a3e825e96044bfbd089a9d@[::]:30303?discport=0"


[::] 使用第一个节点的IP地址代替
  • 在第二个节点添加地址
admin.addPeer("enode://d439a8f2f17234f4dc5be674fb941355a36578f61dfb22bd927a7353ef36f64fb5a30d3a0532665005f34f30c12d811b817b577034a3e825e96044bfbd089a9d@192.168.88.133:30303?discport=0")

添加节点前后,第一个节点的节点列表信息变化

a6Z7Frb.jpg!web

到这一步,我们就建立了一个有两个节点的私有链。

0x04 交易与挖矿

我们先查看之前两个节点上的余额信息

>web3.fromWei(eth.getBalance(eth.coinbase),"ether")

20
>web3.fromWei(eth.getBalance(eth.coinbase),"ether")

0

然后从第一个节点向第二个节点的账户0x23aa56f577bfb707cba6fee5be1498457d938ec1中转账1个以太币。这需要我们先解锁我们的账户,在进行转账操作。

personal.unlockAccount(eth.coinbase,"之前设置的口令")

eth.sendTransaction({from:eth.coinbase,to:"0x23aa56f577bfb707cba6fee5be1498457d938ec1",value:web3.toWei(1,"ether")})

VRVJNnv.jpg!web

此时我们再查看两个账户,发现余额并没有变化,这是因为并没有其他人为我们做区块的运算服务,这时,矿工的角色就登场了。

我们在第一个节点上进行采矿。

miner.start()

此时我们再查看两个节点的账户,就会发现第一个节点账户因为采矿获取到了更多的以太币,而此时第二个节点账户也获取到了第一个节点转给它的1个以太币。

0x05 智能合约

以太坊的智能合约采用Solidity语言进行编写。采用以下方式安装solc环境。

sudo add-apt-repository ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install solc

Solidity语言使用一种类似JS的语法进行编程,通过建立指定操作,再进行编译,最后使用JS脚本加载进账户。

详细语法学习将在后一篇博客中汇总。

0x06 其他概念

账户,以太坊的账户分为外部账户和合约账户

外部账户,拥有以太币余额;可以发送交易;通过私钥控制;没有关联代码。

合约账户,拥有以太币余额;有相关联代码;代码执行通过交易或其他合约来激活;被执行时拥有随机复杂度

由此可以看到,以太坊一个重要的特点就是能够允许智能合约被执行,并给合约的记录者奖励酬劳。

GAS,一种计算复杂度的衡量单位

gaslimit,这个交易执行最多被允许使用的计算步骤

gasprice,交易发送者愿意支付的费用,一单位gas代表执行一个基本指令


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK