搭建属于自己的私有链,部署简单的智能合约

 

下面所有操作都是在root用户下执行的。

 

ubuntu 17.10安装 

sudo apt upgrade -y

sudo apt install software-properties-common

sudo add-apt-repository -y ppa:ethereum/ethereum

sudo apt update

sudo apt install ethereum

sudo apt install solc -y

一条一条复制黏贴,好,你的环境已经搭好了,继续下一步

 

创建创世区块

mkdir -p ethereum && cd ethereum

vim genesis.json

geth init genesis.json

下面这段拷到genesion.json里面,退出,继续下一步

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

 

创建两个矿工: 当前目录 /root/ethereum

geth --datadir miner1 init genesis.json

geth --datadir miner2 init genesis.json

 

编写运行脚本: 

这里我找了一天,后来才发现路径写错了,一直以为是什么情况,我真的是太傻了

没看到有写成脚本的,自己试了一下,给自己挖了个大坑,算是个教训吧

cd ~/ethereum

vim miner1.sh

#脚本内容,下面这段拷进去,记得修改自己的ip,修改ip,ip

#!/bin/bash
geth --networkid 15 --datadir miner1 --rpc --rpcaddr 45.63.61.235 --rpcport 8546 --nodiscover --ipcpath "/root/.ethereum/geth.ipc"    #注意这个路径,有个点(我系统的默认路径)

chmod +x miner1.sh

cd ~/ethereum

vim miner2.sh

#脚本内容,下面这段拷进去,,记得修改自己的ip,修改ip,ip

#!/bin/bash
geth --networkid 15 --datadir miner2 --rpc --rpcaddr 45.63.61.235 --rpcport 8545 --port "30304" --nodiscover --ipcpath "/root/ethereum/miner2/geth.ipc"   #注意这个路径,没有点

chmod +x miner2.sh

 

3.2. 启动节点,开始挖矿

./miner1.sh

#再开一个终端

geth attach   #通过这个终端来操作

personal.newAccount("123456")           # 输入自己想要的密码,记好密码,别忘记了

personal.newAccount("123456")     # 创建两个账户,方便后续操作

miner.setEtherbase(eth.accounts[0])

miner.start(4)  # 4代表cpu核数,填1就行,我买的4核,就填4了,不用白不用

重要:执行之后,会如下结果,等DAG达到一百再操作,一百再操作,操作,作。出现🔨 就可以继续下一步了(先挖一点)。

> miner.start(1)
INFO [04-18|12:18:50] Updated mining threads threads=1
INFO [04-18|12:18:50] Transaction pool price threshold updated price=18000000000
null
> INFO [04-18|12:18:50] Starting mining operation
INFO [04-18|12:18:50] Commit new mining work number=1 txs=0 uncles=0 elapsed=97.855µs
INFO [04-18|12:18:52] Generating DAG in progress epoch=0 percentage=0 elapsed=692.164ms
INFO [04-18|12:18:52] Generating DAG in progress epoch=0 percentage=1 elapsed=1.339s
INFO [04-18|12:18:53] Generating DAG in progress epoch=0 percentage=2 elapsed=2.049s
INFO [04-18|12:18:54] Generating DAG in progress epoch=0 percentage=3 elapsed=2.776s
INFO [04-18|12:18:54] Generating DAG in progress epoch=0 percentage=4 elapsed=3.505s
INFO [04-18|12:18:55] Generating DAG in progress epoch=0 percentage=5 elapsed=4.223s
INFO [04-18|12:18:56] Generating DAG in progress epoch=0 percentage=6 elapsed=4.941s
.....

INFO [04-18|12:19:59] Generated ethash verification cache epoch=0 elapsed=1m8.186s
INFO [04-18|12:20:00] Successfully sealed new block number=1 hash=baed8e…b18f61
INFO [04-18|12:20:00] 🔨 mined potential block number=1 hash=baed8e…b18f61
INFO [04-18|12:20:00] Commit new mining work number=2 txs=0 uncles=0 elapsed=93.514µ

 

查看账户余额和区块高度

#在新开的终端进行操作

miner.stop()

eth.getBalance(eth.accounts[0])    #  wei

web3.fromWei(eth.getBalance(eth.accounts[0]), "ether");   # ether

miner.blockNumber

 

内部转账

在miner1内进行账号财产的转移

#还在原来的终端进行操作 

eth.accounts  #此时应该有两个账户,先解锁

 personal.unlockAccount(eth.accounts[0])

 personal.unlockAccount(eth.accounts[1])  

miner.start()

web3.fromWei(eth.getBalance(eth.accounts[1]), "ether");

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

web3.fromWei(eth.getBalance(eth.accounts[1]), "ether");

miner.stop()

这时看到 账户1 的金额变多了 5 ether,说明我们的交易被成功大包进区块了

 

外部转账

跨账户转移财产,理论上可以在同一个校园网下(我没试过),由于我只有一个电脑,我就在这台电脑开两个账户进行转移

保持原来miner1两个终端不变,新开两个终端

初始化矿工2

./miner2.sh

#再换一个终端

geth attach  /root/ethereum/miner2/geth.ipc   #注意,这里路径和上面设置一样

personal.newAccount("123456")           # 输入自己想要的密码,记好密码,别忘记了

personal.newAccount("123456")     # 创建两个账户,方便后续操作

miner.setEtherbase(eth.accounts[1])  

web3.fromWei(eth.getBalance(eth.accounts[0]), "ether");

web3.fromWei(eth.getBalance(eth.accounts[1]), "ether");

连接到矿工1,并实现转账

admin.nodeInfo.enode   #查看矿工2的enode

eth.accounts[1]  #查看矿工2的账户1的地址

 personal.unlockAccount(eth.accounts[1])    #解锁账户1

#切换到矿工1的终端

admin.addPeer("enode://c0be7867cc66cc6df8b5f75acba397a1fec2e327c2daa6df6d43add39abc22be43613f9d879f2d0ecdec4c55c3e0e6be105d3dd6b7c2722ebfd63449f707bfc5@[::]:30304?discport=0")   #注意,enode里面的内容是自己电脑上面矿工2的enode,在矿工1终端运行

admin.peers  #查看peers,就是矿工2

 

此时应该返回这种格式

> admin.peers
[{ caps: [
"eth/62", "eth/63"], id: "c0be7867cc66cc6df8b5f75acba397a1fec2e327c2daa6df6d43add39abc22be43613f9d879f2d0ecdec4c55c3e0e6be105d3dd6b7c2722ebfd63449f707bfc5", name: "Geth/v1.8.4-stable-2423ae01/linux-amd64/go1.10", network: { inbound: false, localAddress: "[::1]:32810", remoteAddress: "[::1]:30304", static: true, trusted: false }, protocols: { eth: { difficulty: 3684992, head: "0x168749c055de2a4a3f554028b8f4b919f4047f98c775bf4e0d8cadf233b82c05", version: 63 } } }]

发送一笔 从矿工1的账户0 到 矿工2的账户1 的交易

 #矿工1的终端

 personal.unlockAccount(eth.accounts[0])  

 eth.sendTransaction({from: eth.accounts[0], to: "0xd0561d3b291183e2e2c2de999f3403db5a3c46c1", value: web3.toWei(10, "ether")})    to的地址填自己矿工2账户1的地址

 txpool.status  #可以看到有一笔待打包的交易

 eth.pendingTransactions  #查看这笔交易的具体情况

 miner.start()

 miner.stop()  #打包交易

查看交易状况

  txpool.status   #可以看到当前交易已经被打包

  eth.getTransaction("0x4ab93a7fe8cc7f9b49cfb650ba96280f6e7a60e6f1dca30da89ee29848fd3aad")    #可以看到这笔交易已经成功执行

  #切换到矿工2终端,查看这笔交易是否真的成功

  web3.fromWei(eth.getBalance(eth.accounts[1]), "ether");  #可以看到交易已经成功,账户多了10 ether

  eth.getTransaction("0x4ab93a7fe8cc7f9b49cfb650ba96280f6e7a60e6f1dca30da89ee29848fd3aad")    #可以看到这笔交易在矿工2 也是可以查询到的

 

发布智能合约

打开这个网站 https://remix.ethereum.org/#optimize=false

pragma solidity ^0.4.4;

contract Test { 
    string public name;


    function Test()public {
      name = "lajixiaogui";
    }

    function Sample() constant public returns(string){
        return name;
    }

}

把上面这段代码拷过去,点击 start to compile, 然后点击 Details,找到

 

  • from代表合约由哪个账户生成,哪个账户生成,则生成所需的gas就需要该账户承担,默认为eth.accounts[0],因为所有挖矿所得的以太币也默认都存入该账户中。
  • data代表的就是bytecode。是编译后的代码,你的代码越长,这块的字符串越多。
  • gas代表的是为了部署该合约最多准备的gas数量,当然实际上可能用不了这么多gas,具体消耗以实际使用量为准,这里只是设定一个最大量。gas是调用合约要扣除的gas单位,可以理解为以太币,gasether之间有个汇率,汇率受矿机的算率影响会有调整,在公网上,这些gas用于奖励给挖矿者。
  • 最后这段是一个典型的javascript的异步调用的写法,将上面的new方法的结果传递给下一个方法function(e,contract),在下一个方法中处理如果挖矿成功的显示结果。如果合约成功部署在区块上,则在控制台打印出来Contract mined!contract addresstransactionHash等信息。
  • address表示已经部署智能合约的帐户地址,智能合约也相当于一个帐户。
  • transactionHash表示智能合约产生时的hash值,会永久保存到区块链条里面。

 

发起合约

 

 #在矿工1终端,解锁矿工1的账户0

 personal.unlockAccount(eth.accounts[0])  

 # 把上面web3deploy代码拷到终端1,回车(就是下面这个)

var testContract = web3.eth.contract([{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"Sample","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]);
var test = testContract.new(
   {
     from: web3.eth.accounts[0], 
     data: '0x608060405234801561001057600080fd5b506040805190810160405280600b81526020017f6c616a697869616f6775690000000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b6102dd806101166000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde0314610051578063eb5ce181146100e1575b600080fd5b34801561005d57600080fd5b50610066610171565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100a657808201518184015260208101905061008b565b50505050905090810190601f1680156100d35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156100ed57600080fd5b506100f661020f565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561013657808201518184015260208101905061011b565b50505050905090810190601f1680156101635780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102075780601f106101dc57610100808354040283529160200191610207565b820191906000526020600020905b8154815290600101906020018083116101ea57829003601f168201915b505050505081565b606060008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102a75780601f1061027c576101008083540402835291602001916102a7565b820191906000526020600020905b81548152906001019060200180831161028a57829003601f168201915b50505050509050905600a165627a7a72305820201ea51271c341889f0fcc2086bc003ae37bea861c8499a60fe154555a678b150029', 
     gas: '4700000'
   }, function (e, contract){
    console.log(e, contract);
    if (typeof contract.address !== 'undefined') {
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' +
 contract.transactionHash);
    }
 })

  test   #输入可以看到合约

  txpool.status    #可以看到交易池有一笔待确认的交易 

  web3.eth.getTransaction("0xbe0262f026047b101539373f4e19c67505218e0a829437b9dc7f5a0d8dd1e4d7")    #查看合约

 doushiqiana = '0x608060405234801561001057600080fd5b506040805190810160405280600b81526020017f6c616a697869616f6775690000000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b6102dd806101166000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde0314610051578063eb5ce181146100e1575b600080fd5b34801561005d57600080fd5b50610066610171565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100a657808201518184015260208101905061008b565b50505050905090810190601f1680156100d35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156100ed57600080fd5b506100f661020f565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561013657808201518184015260208101905061011b565b50505050905090810190601f1680156101635780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102075780601f106101dc57610100808354040283529160200191610207565b820191906000526020600020905b8154815290600101906020018083116101ea57829003601f168201915b505050505081565b606060008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102a75780601f1061027c576101008083540402835291602001916102a7565b820191906000526020600020905b81548152906001019060200180831161028a57829003601f168201915b50505050509050905600a165627a7a72305820201ea51271c341889f0fcc2086bc003ae37bea861c8499a60fe154555a678b150029'
 
web3.eth.estimateGas({data: doushiqiana})  #查看手续费

  miner.start()  #打包交易

  miner.stop()    #等待挖15个矿之后,取消挖矿

  

 查看合约

eth.getCode(test.address)  #查看合约是否部署成功

web3.eth.getTransaction("0xbe0262f026047b101539373f4e19c67505218e0a829437b9dc7f5a0d8dd1e4d7")   #查看合约

test.Sample.call()   #调用合约方法

返回 "lajixiaogui" 说明 合约部署完成, 恭喜你,搭建第一个简单的私有链

 

posted @ 2018-04-18 21:09  tianlongtc  阅读(1019)  评论(0编辑  收藏  举报