Centos7安装geth、搭建私有链、部署solidity合约、调用合约函数

跟着视频学习了以太坊相关的东西,遇到了一系列坑,今天整理成笔记。

一、安装nodejs

# 安装相关依赖
yum -y install git bzip2 gcc gcc-c++ ntp epel-release

# 源码安装
wget https://npm.taobao.org/mirrors/node/v11.0.0/node-v11.0.0.tar.gz
tar -zxvf node-v11.0.0.tar.gz
cd node-v11.0.0
./configure
make
make install 
node -v # 检测是否安装成功

# 配置npm仓库
npm install -g cnpm --registry=https://registry.npm.taobao.org

二、安装geth

# 安装cmake
wget https://cmake.org/files/v3.15/cmake-3.15.2.tar.gz
tar zxvf cmake-3.15.2.tar.gz
mv cmake-3.15.2 /usr/local/
cd /usr/local/cmake-3.15.2
./bootstrap
gmake
gmake install

echo "export PATH=/usr/local/cmake-3.15.2/bin:$PATH" >> /etc/profile
source /etc/profile
cmake -version	# 检测cmake是否安装成功


# 安装go语言环境
wget https://storage.googleapis.com/golang/go1.10.2.linux-amd64.tar.gz
tar -zxvf go1.10.2.linux-amd64.tar.gz
mv  go1.10.2.linux-amd64 /usr/local/

echo "export GOROOT=/usr/local/go" >> /etc/profile
echo "export PATH=/usr/local/go/bin:$PATH" >> /etc/profile
source /etc/profile
go version	# 检测go环境是否安装成功


# 安装以太坊,需要下载release版本的
cd /usr/local
git clone https://github.com/ethereum/go-ethereum.git  # 一定要下载release版本的
cd go-ethereum/
make all

echo "export PATH=$PATH:/usr/local/go-ethereum/build/bin" >> /etc/profile
source /etc/profile
geth version	# 检测geth是否安装成功


# 开启时间同步(使用chrony也可以)
systemctl enable ntpd 
systemctl start ntpd

# 关闭防火墙,或者打开8087,30303端口
systemctl stop firewalld
systemctl disable firewalld

三、创建以太坊私有链

# 用于初始化链的配置文件
vim genesis.json
{
  "config": {
        "chainId": 15,		# 私有链网络id不要和公开的链的id相同
        "homesteadBlock": 0,
        "eip155Block": 0,
        "eip158Block": 0
    },
    "coinbase" : "0x0000000000000000000000000000000000000000",
    "difficulty" : "0x2000",	# 挖矿难度设置
    "extraData" : "",
    "gasLimit" : "0xffffffff",	# 一个块中gas的上线
    "nonce" : "0x0000000000000042",
    "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
    "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
    "timestamp" : "0x00",
    "alloc": { }		# “address”:{“balance”: “300000”}		# 账户初始化wei个数,指定账户有这么多钱,账户并没有添加到链中
}


# 初始化私有链
geth --datadir dir init genesis.json	# dir代表数据以及配置存放的位置


# 启动私有链
geth --datadir dir --networkid 15	# networkid要和genesis.json中的chainId相同
或者
geth --datadir dir --networkid 15 2>logdata.log		# 启动私有链,将日志重定向到文件中
或者
geth --datadir dir --networkid 15 console 2>logdata.log	# 进入控制台
或者
geth --datadir dir --networkid 15 --rpc --rpcport 8545  --rpcaddr "192.168.31.112" console 2>/srv/blocklogdata.log	# --rpc表示启动远程调用,启动链的时候指定对应的端口和ip


# 以太坊提供了一条测试链,给定一个初始化的账户,默认有一定金额的以太币,并且这个账户一直处于挖矿状态
geth --datadir dir --dev --rpc --rpcport 8545  --rpcaddr "192.168.31.112" console 2>/srv/blocklogdata.log	# --dev就表明了启动的是测试链,不需要再指定networkid

四、安装solcjs

# solcjs是solidity的编译器,安装solcjs需要nodejs的支持

npm install -g solc	# 安装默认版本,我这里是0.6.2

# 在solidity中应该注意编译器的版本,需要小于等于0.6.2
pragma solidity >=0.4.22 <0.6.3

五、编写合约

# 这里是一个简单的投票合约

vim Voting.sol

pragma solidity >=0.4.22 <0.6.3;

contract Voting {

    bytes32[] public candidateList; //候选人列表    
    
    mapping(bytes32=>uint8) public votesReceived; //候选人=>得票数

    constructor(bytes32[] memory _candidateList) public { // 构造函数,参数是一个数组
        candidateList = _candidateList;
    }

    function totalVotesFor(bytes32 _candidate) view public returns(uint8){ // 获取票数
        require(validCandidate(_candidate));
        return votesReceived[_candidate];
    }
    
    function voteForCandidate(bytes32 _candidate) public { // 投票
        require(validCandidate(_candidate));
        votesReceived[_candidate] += 1;
    }
     
    function validCandidate(bytes32 _candidate) view public returns(bool){ // 是否在候选人列表
        for(uint i=0;i

六、编译合约

solcjs --bin --abi Voting.sol
# 得到如下两个文件
	Voting_sol_Voting.abi	# 接口,json格式
	Voting_sol_Voting.bin	# 字节码文件

七、启用node部署合约

# 创建一个目录并且初始化(不同的目录可以安装不同版本的模块)
mkdir project
cd project
npm init

# 安装web3模块
npm install [email protected]		# 这里使用的是0.20.1版本的web3

# 为了方便测试,这里使用dev测试链
geth --datadir dir --dev --rpc --rpcport 8545  --rpcaddr "192.168.31.112" console 2>/srv/blocklogdata.log	# 开启测试链,指定ip和端口

# 进入node交互页面
node	

# 获取web3对象
var Web3 = require('web3');
var web3 = new Web3();
web3.setProvider(new Web3.providers.HttpProvider("http://192.168.31.112:8545"));

# 创建抽象合约
var _abi = JSON.parse(将Voting_sol_Voting.abi的内容复制到这里);
var _bin = '0x' +  将Voting_sol_Voting.bin的内容复制到这里;
var myContract = web3.eth.contract(_abi);	# 抽象合约

# 部署合约是通过交易完成的,因此需要创建一个交易的参数
var _option = {from: web3.eth.accounts[0], data: _bin, gas: 2000000}; # 合约部署者,字节码,gas值

# 创建合约实例(部署合约)
var contractInstance = myContract.new(['alex', 'jack', 'jason', 'davie', 'tom', 'ajax', 'spi'], _option );		# 构造函数参数在前(允许有多个用逗号分隔),交易参数在最后
# 由于合约的构造函数是有参数的,因此需要指定参数。
# 在合约中构造函数的类型是bytes32[],这里传入的是string[], 会自动将string转为bytes32,在remix中不会自动转换
# 实例创建完毕之后就得到了一个合约的地址
# 这里得到的合约地址是0xb286332ae0d181103db3a4d3412b4750b6e9c30d

八、调用合约函数

# 通过合约地址得到合约实例
 var contractInstance = myContract.at(‘0xb286332ae0d181103db3a4d3412b4750b6e9c30d’);

# 调用合约函数的三种方法
	1、合约实例.函数名(param1, param2, ..);
	contractInstance.voteForCandidate('davie', {from: web3.eth.accounts[0]});
	# {from: web3.eth.accounts[0]} 是交易时的参数,类似于上面定义的_option
	# 这种方式可以自动判断是 `纯粹的函数调用(call)` 或 `以发送交易的方式调用函数(sendTransaction)`

	2、合约实例.函数名.sendTransaction(param1, param2, ..);
	contractInstance.voteForCandidate.sendTransaction('davie', {from: web3.eth.accounts[0]});
	# 这种方式是以 `发送交易` 的方式调用函数

	3、合约实例.函数名.call(param1, param2, ..);
	contractInstance.totalVotesFor.call('davie').toString();
	# 这种方式是 `纯粹的函数调用`
	
	# 当状态变量(合约中的属性)发生改变的时候,用发送交易的方式调用函数。

如有错误欢迎留言指正。

参考:CentOS7下安装Geth,搭建以太坊私有链

你可能感兴趣的:(Centos7安装geth、搭建私有链、部署solidity合约、调用合约函数)