Linux环境以太坊私有链搭建

一、软件的安装

1.安装node和npm

首先执行下面语句进行安装:

curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
sudo apt-get install -y nodejs

安装完成通过查看版本进行检查:

node -v
npm -v

Node.js官网:https://nodejs.org/en/

2.安装web3

npm install web3

3.安装golang

下载二进制go文件:

wget https://dl.google.com/go/go1.11.2.linux-amd64.tar.gz

解压:

sudo tar -C /usr/local -xzf go1.11.2.linux-amd64.tar.gz

编辑配置文件:

sudo vim /etc/profile

配置文件末尾添加如下内容:

export GOROOT=/usr/local/go
export GOARCH=amd64
export GOOS=linux
export GOPATH=/home/username/gopath
export GOBIN=$GOROOT/bin
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH

更新配置文件:

source /etc/profile

检查安装情况:

go version

4.安装geth、solc:

这是安装以太坊私有链环境的基本架构,可以实现创建账户、余额查询、转帐、挖矿、写入智能合约、智能合约的调用等基础功能,其中交易等功能需要挖矿来确认,与正常以太坊公有链相同。

方法一:https://github.com/ethereum/go-ethereum/releases
方法二:

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

在安装完成之后需要进行验证:

geth --help

如果正确显示提示帮助信息,则说明安装成功了。

在这里需要保证apt source是国内的,否则的话网速会很慢。首先打开源文件:

sudo vi /etc/apt/sources.list

之后再将文件进行修改:

:%s/us./cn./g

最后更新源文件就可以了:

sudo apt-get update

如果网速还是慢的话推荐使用镜像:
Linux镜像资源:https://linux.linuxidc.com/index.php?folder=cHVi
镜像使用方法:https://blog.csdn.net/quuqu/article/details/64121812

二、以太坊私有链生成节点

1.生成一个节点

首先编辑一个文件:init.json,如下实例

{ 
“nonce”:0x0000000000000042, 
“mixhash”:0x0000000000000000000000000000000000000000000000000000000000000000, 
“difficulty”:0x4000, 
“alloc”: {}, 
“coinbase”:0x0000000000000000000000000000000000000000, 
“timestamp”:0x00, 
“parentHash”:0x0000000000000000000000000000000000000000000000000000000000000000, 
“extraData”: “”, 
“gasLimit”:0x0000ffff}

这个json文件的具体内容介绍是这样的:

参数名称参数描述
mixhash与nonce配合用于挖矿,由上一个区块的一部分生成的hash。
noncenonce就是一个64位随机数,用于挖矿。
difficulty设置当前区块的难度,如果难度过大,cpu挖矿就很难,这里设置较小难度。
alloc用来预置账号以及账号的以太币数量,因为私有链挖矿比较容易,所以我们不需要预置有币的账号,需要的时候自己创建即可以。
coinbase矿工的账号,随便填。
timestamp设置创世块的时间戳。
parentHash上一个区块的hash值,因为是创世块,所以这个值是0
extraData附加信息,随便填,可以填你的个性信息。
gasLimit该值设置对GAS的消耗总量限制,用来限制区块能包含的交易信息总和,因为我们是私有链,所以填最大。

通过下面的代码启用节点:

geth init init.json --datadir=.ethereum

2.在同一台电脑上生成不同的节点

博客:https://www.jianshu.com/p/0d4186c8e712
https://blog.csdn.net/koastal/article/details/78749211

在这里如果是简单的开发任务没必要生成多个节点,因为在一个节点上建立多个账户可以实现不少的基本功能。

三、启动私有链

首先输入下面的指令来启动私有链:

geth --datadir=.ethereum --identity "lixp" --networkid 54321 --nodiscover --rpc --rpcaddr 0.0.0.0 --rpcport 30306 --rpccorsdomain '*' --rpcapi 'db,eth,net,web3,personal,admin,mine' console

可以看到以太坊私有链正常启动了,并且进入了命令窗口。
在这里插入图片描述
在这个以太坊私有链中内置了javascript对象,可以直接使用这些对象:

eth:包含一些跟操作区块链相关的方法
net:包含以下查看p2p网络状态的方法
admin:包含一些与管理节点相关的方法
miner:包含启动&停止挖矿的一些方法
personal:主要包含一些管理账户的方法
txpool:包含一些查看交易内存池的方法
web3:包含了以上对象,还包含一些单位换算的方法

一些常用指令:

查看节点信息

admin.nodeInfo

查看当前账户

eth.accounts

建立新帐户(需要输入两次密码)

personal.newAccount()

得到账户的余额(Wei形式)

eth.getBalance(eth.accounts[0])

将账户余额转换成以太币形式输出

web3.fromWei(eth.getBalance(eth.accounts[0]))

开始挖矿

miner.start()

挖矿结束

miner.stop()

发起转帐交易(需要挖矿确认,value设成期望值)

eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:5})

查看当前矿工账号(默认为第一个账户)

eth.coinbase

修改矿工账号

miner.setEtherbase(eth.accounts[1])

解锁帐户

personal.unlockAccount("账户地址", "密码")

例如(用eth.accounts就别加双引号了)

personal.unlockAccount(eth.accounts[0],"123456")

四、智能合约部署

1.编写合约

一个简单的智能合约contract.sol:

pragma solidity ^0.4.2;
contract test {

   function multiply(uint a) returns(uint b) {
       return a * 9;
   }
}

2.编译合约

方法一:Remix
(1)官方在线编译: http://remix.ethereum.org
https://ethereum.github.io/browser-solidity
(2)IDLE使用,细节在博客:https://blog.csdn.net/jerry81333/article/details/78118972
方法二:

sudo apt-get install ethereum solc

通过安装solc之后通过下面代码进行编译:

solc --combined-json=abi,bin,interface contract.sol > contract.sol.js

编译之后得到:Interface 和 Bytecode 和 Web3 deploy

3.部署合约

在部署合约前,我们要明确需要以下几项条件:
(1)一个有Ether的账户。
(2)该账户已解锁。
(3)编译合约得到的abi和code。

第一步: 获取abi信息,即上述编译得到的interface

abi = [{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"b","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]

得到结果:

[{
    constant: false,
    inputs: [{
        name: "a",
        type: "uint256"
    }],
    name: "multiply",
    outputs: [{
        name: "b",
        type: "uint256"
    }],
    payable: false,
    stateMutability: "nonpayable",
    type: "function"
}]

第二步:

multiplyContract = web3.eth.contract(abi)

得到:

{
  abi: [{
      constant: false,
      inputs: [{...}],
      name: "multiply",
      outputs: [{...}],
      payable: false,
      stateMutability: "nonpayable",
      type: "function"
  }],
  eth: {
    accounts: ["0x0b6c5afb465ae37014053603635fe743bd632732", "0x82831328f84d461646d3fc9be308cb3a104e1d76"],
    blockNumber: 96,
    coinbase: "0x0b6c5afb465ae37014053603635fe743bd632732",
    compile: {
      lll: function(),
      serpent: function(),
      solidity: function()
    },
    defaultAccount: undefined,
    defaultBlock: "latest",
    gasPrice: 1000000000,
    hashrate: 0,
    mining: false,
    pendingTransactions: [{
        blockHash: null,
        blockNumber: null,
        from: "0x0b6c5afb465ae37014053603635fe743bd632732",
        gas: 90000,
        gasPrice: 1000000000,
        hash: "0xbeed5163aa8c056e0214cb69aeb0f65607dd1c809b9ff41656f01240f61f47db",
        input: "0x",
        nonce: 4,
        r: "0x819a1d15f27b23345d8a1bc9718a89174d20fb1240e8f1e2e5bd4b906e311c5c",
        s: "0x4a1799099b36569149e7de6e23c72626b7ec3f6e098e849fdfba9748c026829a",
        to: "0x82831328f84d461646d3fc9be308cb3a104e1d76",
        transactionIndex: 0,
        v: "0x3f",
        value: 5
    }],
    protocolVersion: "0x3f",
    syncing: false,
    call: function(),
    chainId: function(),
    contract: function(abi),
    estimateGas: function(),
    filter: function(options, callback, filterCreationErrorCallback),
    getAccounts: function(callback),
    getBalance: function(),
    getBlock: function(),
    getBlockNumber: function(callback),
    getBlockTransactionCount: function(),
    getBlockUncleCount: function(),
    getCode: function(),
    getCoinbase: function(callback),
    getCompilers: function(),
    getGasPrice: function(callback),
    getHashrate: function(callback),
    getMining: function(callback),
    getPendingTransactions: function(callback),
    getProof: function(),
    getProtocolVersion: function(callback),
    getRawTransaction: function(),
    getRawTransactionFromBlock: function(),
    getStorageAt: function(),
    getSyncing: function(callback),
    getTransaction: function(),
    getTransactionCount: function(),
    getTransactionFromBlock: function(),
    getTransactionReceipt: function(),
    getUncle: function(),
    getWork: function(),
    iban: function(iban),
    icapNamereg: function(),
    isSyncing: function(callback),
    namereg: function(),
    resend: function(),
    sendIBANTransaction: function(),
    sendRawTransaction: function(),
    sendTransaction: function(),
    sign: function(),
    signTransaction: function(),
    submitTransaction: function(),
    submitWork: function()
  },
  at: function(address, callback),
  getData: function(),
  new: function()
}

第三步: 复制 Web3 deploy 到命令行

multiply = multiplyContract.new(
   {
     from: web3.eth.accounts[0], 
     data: '0x606060405260308060106000396000f3606060405260e060020a6000350463c6888fa18114601c575b6002565b346002576009600435026060908152602090f3', 
     gas: '300000'
   }, function (e, contract){
    console.log(e, contract);
    if (typeof contract.address !== 'undefined') {
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
    }
 })

得到结果

{
  abi: [{
      constant: false,
      inputs: [{...}],
      name: "multiply",
      outputs: [{...}],
      payable: false,
      stateMutability: "nonpayable",
      type: "function"
  }],
  address: undefined,
  transactionHash: "0xed371f74922f646a24fc6b441d187c207f17d4281d61a1a7aca05252d2096288"
}

如果这里没结果的话需要把用户解锁。

第四步:然后我们需要挖矿确认

miner.start()

会得到一条交互信息

Contract mined! address: 0x4435503ba91f970563cd05f6dc548b87863d6920 transactionHash: 0xed371f74922f646a24fc6b441d187c207f17d4281d61a1a7aca05252d2096288

4.合约交互

MyContract = eth.contract(abi)
myContract = MyContract.at(multiply.address)
myContract.multiply.call(4)

得到结果36

5.调用合约

还是需要解锁:

abi = [{constant:false,inputs:[{name:'a',type:'uint256'}],name:'multiply',outputs:[{name:'b',type:'uint256'}],type:'function'}] 
address = "合约地址"
myContract = web3.eth.contract(abi).at(address)
myContract.multiply.call(4)

一样能得到结果36

文章参考:
1.https://blog.csdn.net/diligent_lee/article/details/79141450
2.http://www.cnblogs.com/studyzy/p/6973334.html
3.https://blog.csdn.net/he012821397/article/details/80983928
4.https://blog.csdn.net/vipshop_fin_dev/article/details/80727980
5.https://www.jianshu.com/p/cd5aed9b06af
6.https://blog.csdn.net/super_wu1992/article/details/76919308
7.https://www.cnblogs.com/beyang/p/8469311.html
8.https://solidity.readthedocs.io/en/v0.4.10/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值