Windows下以太坊Geth客户端安装使用以及简单合约的部署

操作系统:Windows 10
参考资料:如何搭建以太坊私有链、智能合约开发环境搭建及Hello World合约

以太坊安装

以太坊客户端与Java虚拟机和.NET运行环境类似,能够让你在电脑上运行"以太坊程序"。

以太坊的客户端有很多版本,在这里选择Geth(Go-ethereum)。只需要直接到官网下载Windows对应.exe可执行文件,并安装即可。

安装完成后,打开cmd命令提示符,输入命令geth --help显示以下信息,表明安装成功。
Windows下以太坊Geth客户端安装使用以及简单合约的部署_第1张图片
PS:如果不加任何参数,只使用geth命令执行,或双击安装目录下的geth.exe,会自动连接到以太坊公网,并开始同步区块(你会发现一直卡着不动),此时区块数据存储的路径可以在geth --help中查看到。

私有链创世区块搭建

以太坊支持自定义创世区块,要运行私有链,我们就需要定义自己的创世区块,创世区块信息写在一个 json 格式的配置文件中。

在磁盘的某个地方创建一个新文件夹,在该文件夹中新建创世区块配置文件genesis.json,内容如下:

{
  "config": {
        "chainId": 15,
        "homesteadBlock": 0,
        "eip155Block": 0,
        "eip158Block": 0
    },
    "coinbase" : "0x0000000000000000000000000000000000000000",
    "difficulty" : "0x07000",
    "extraData" : "",
    "gasLimit" : "0xffffffff",
    "nonce" : "0x0000000000000042",
    "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
    "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
    "timestamp" : "0x00",
    "alloc": { }
}

字段的具体含义在这里就不展开叙述了。之后在cmd窗口进入该文件夹,执行如下命令:

geth --datadir data init genesis.json

上面命令的主体是 geth init,表示初始化区块链,命令可以带有选项和参数,其中 --datadir 选项后面跟一个目录名,这里为 data,表示指定数据存放目录为 datagenesis.jsoninit 命令的参数。执行后结果如下,可以看到,私有链搭建成功。
Windows下以太坊Geth客户端安装使用以及简单合约的部署_第2张图片
PS:在data目录下,会有两个文件:gethkeystore,前者保存区块数据,后者存放账户信息。

私有链节点的加入

在完成上述步骤后,就已经有了一条自己的私有链了,可以加入自己的私有链节点,使用以下命令启动节点:

geth --datadir data --networkid 2629 console

命令的主体是 geth console,表示启动节点并进入交互式控制台,--datadir 选项指定使用 data 作为数据目录,--networkid 选项后面跟一个数字,这里是 2629,表示指定这个私有链的网络 id 为 2629。网络 id 在连接到其他节点的时候会用到,以太坊公网的网络 id 是 1,为了不与公有链网络冲突,运行私有链节点的时候要指定自己的网络 id 。执行后,结果如下:

如图,会进入到一个交互式的 Javascript 执行环境,里面可以执行 Javascript 的代码,如输入1+1会输出2。 在这个环境中,可以进行很多操作,例如:查看区块和交易、创建账户、挖矿、发送交易、部署智能合约等。

然后执行如下一系列的操作,进行创建用户,挖矿,就不展开叙述了:

personal.newAccount("123") //创建用户,引号中的是账户密码

eth.accounts //可查看账户信息

miner.start(2) 	//启动挖矿,参数表示使用的线程数。启动后就会被挖矿信息刷屏
				//挖矿所得以太币默认存入第一个账户
miner.start();admin.sleepBlocks(1);miner.stop()//使用这个命令会在挖到一次矿后自动停止

miner.stop() //停止挖矿

eth.getBalance(eth.accounts[0]) //可以查看账户余额,单位是wei
web3.fromWei(eth.getBalance(eth.accounts[0]),'ether') //将余额单位换算成以太币

交易

PS:下文的操作我换用了Windows PowerShell

按照相同方式再创建一个账户,此时先前的账户有余额,而新创建的账户余额为0,可以通过以下命令将10个以太币从账户0转移到账户1:

amount = web3.toWei(10,'ether')
eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:amount})

此时会报错如下:
Windows下以太坊Geth客户端安装使用以及简单合约的部署_第3张图片
原因是账户每隔一段时间就会被锁住,要发送交易,必须先解锁账户,由于我们要从账户 0 发送交易,所以要解锁账户 0,执行图中所示命令(需要输入密码):
在这里插入图片描述
解锁后,重新执行之前的命令。

交易后,查看账户1余额,会发现还是0,这是因为交易已经提交到区块链,但还未被处理。正如之前所学到的,需要矿工进行挖矿,处理并记录这个交易。所以我们进行挖矿后,得到如下结果:
Windows下以太坊Geth客户端安装使用以及简单合约的部署_第4张图片
可以看到,账户1的余额已经变成10了,说明交易已被处理。

查看区块

使用命令eth.blockNumber查看当前的区块总数,eth.getBlock(10)查看具体的区块,执行结果如下:
Windows下以太坊Geth客户端安装使用以及简单合约的部署_第5张图片
区块的各字段含义如下:

  • difficulty:表示当前区块的难度
  • extraData:与此区块相关的附加数据
  • gasLimit:当前区块允许使用的最大gas
  • gasUsed:当前区块累计使用的gas
  • hash:区块的哈希值。如果区块没有被确认,字段值为null
  • logsBloom:区块日志的布隆过滤器,区块没被确认时值为null
  • miner:取得该区块记账权的矿工
  • mixHash:一个Hash值,当与nonce组合时,证明此区块已经执行了足够的计算
  • nonce:PoW生成的哈希值
  • number:区块号(创世纪块的区块序号为0,对于每个后续区块,区块序号都增加1)
  • parentHash:前一个区块的哈希值
  • receiptsRoot:收据树的根哈希值
  • sha3Uncles:数据块的哈希值
  • size:该区块的字节大小
  • stateRoot:状态树的根哈希值
  • timestamp:区块打包时的unix时间戳
  • totalDifficulty:区块链到当前区块的总难度
  • transactions:交易的对象
  • transactionsRoot:交易树的根哈希值
  • uncles:叔哈希的数组

查看交易

使用命令eth.getTransaction(" ")查看交易,其中引号需加上交易的hash值,在交易执行后会有显示。执行结果如下,该交易是上文所述交易:
Windows下以太坊Geth客户端安装使用以及简单合约的部署_第6张图片
交易的各字段含义如下:

  • blockHash:这个交易所在的区块的哈希值
  • blockNumber:这个交易所在的区块的编号
  • from:发起交易的账户
  • gas:执行这个交易所需要的gas
  • gasPrice:当前gas与以太币换算的汇率
  • hash:这个交易的哈希值
  • input:合约的16进制代码
  • nonce:交易下的nonce值,是账户发起交易所维护的nonce,一个交易对应一个nonce值
  • r,s,v:交易签名后的值,它们可以被用来生成签名者的公钥;r,s是ECDSA椭圆加密算法的输出值,v是用于恢复结果的ID
  • to:交易接收账户。如果是一个创建智能合约的交易,to为空
  • transactionIndex:这个交易在其对应区块的序号
  • value:交易的以太币数量。如图所示,正是10个以太币

查看日志

进行到这里才发现有日志功能…

日志功能开启方法:在上文启动以太坊节点时在后面加上2>> test.log,日志的名称可以自己随意设置。

简单来说,日志的作用就是将我之前在执行命令时会输出的各种提示信息,例如INFOWARN,不直接输出到屏幕上,而是重定向写入到我们指定的日志文件中。日志文件部分内容如下:

上图显示的内容就是启动节点后,geth初始化的一些信息。

对于选择将这些提示信息输入到日志中,我认为有好处也有坏处:好处就是没有这些提示信息后,geth命令行界面和之前相比显得更加简介了,同时有了日志的记录,方便日后的查看;坏处就是似乎少了一些什么的感觉,比如挖矿时刷屏的快感。

编写简单的智能合约

使用Remix - Ethereum IDE直接在浏览器中编写和编译Solidity代码

参考网上博客(见本文开头部分的参考资料),创建helloworld.sol,并编写代码如下:

pragma solidity ^0.4.22;
contract hello {
    
    string greeting;
    
    function hello(string _greeting) public {
        greeting = _greeting;
    }
    
    function say() constant public returns (string) {
        return greeting;
    }
    
}

上述代码创建了一个hello合约。点击页面中的Compile进行编译。对于博客提供的代码似乎给了警告,意思好像是要求写构造函数,不过既然不是报错,暂时先不管。

编译通过后,点击下方的 Compilation Details,找到 WEB3DEPLOY 选项旁的复制按钮进行复制,得到如下结果:

var _greeting = /* var of type string here */ ;
var helloContract = web3.eth.contract([{"constant":true,"inputs":[],"name":"say","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_greeting","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]);
var hello = helloContract.new(
   _greeting,
   {
     from: web3.eth.accounts[0], 
     data: '0x608060405234801561001057600080fd5b506040516102a83803806102a8833981018060405281019080805182019291905050508060009080519060200190610049929190610050565b50506100f5565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061009157805160ff19168380011785556100bf565b828001600101855582156100bf579182015b828111156100be5782518255916020019190600101906100a3565b5b5090506100cc91906100d0565b5090565b6100f291905b808211156100ee5760008160009055506001016100d6565b5090565b90565b6101a4806101046000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063954ab4b214610046575b600080fd5b34801561005257600080fd5b5061005b6100d6565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561009b578082015181840152602081019050610080565b50505050905090810190601f1680156100c85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b606060008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561016e5780601f106101435761010080835404028352916020019161016e565b820191906000526020600020905b81548152906001019060200180831161015157829003601f168201915b50505050509050905600a165627a7a72305820bd9c8f1aad9fb4da7211d57eeaea5ede4555a3d028220142c0fa5bfe05d3874d0029', 
     gas: '4700000'
   }, function (e, contract){
    console.log(e, contract);
    if (typeof contract.address !== 'undefined') {
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
    }
 })

继续按照博客要求,将第一行的注释部分改为“Hello World”(可以先复制到文本中进行修改)。修改完成后,拷贝到geth控制台中。注意先要解锁合约中from字段对应的账户!

**然后需要进行挖矿!**我起初没有进行挖矿,所以一直以为哪里出错了。查看Log日志可以看到,当我们将上述内容拷贝到控制台后,日志中提示以下信息:

INFO [10-09|21:44:27.864] Submitted contract creation

在开始挖矿一段时间后,可以看到如下所示的提示信息,表示合约已经部署成功了。

在这里插入图片描述
此时查看对应账户余额,可以看到,余额变少了。

运行hello合约,得到如下结果:
在这里插入图片描述
结果符合预期,即输出了Hello World,合约成功运行!

你可能感兴趣的:(区块链)