环境:
1. centos 7.3
2. etheruem 1.7.3
3. go-etheruem
4. golang
安装
1. golang环境
yum -y install golang
2. 安装git 工具
yum -y install git
3. 下载go-etheruem源码包并且安装
git clone https://github.com/ethereum/go-ethereum.git
cd go-ethereum
git checkout v1.7.2 git checkout v1.7.3
make geth
make all
4. 查看是否安装成功
# build/bin/geth version
5. 设置 geth 环境变了
export PATH=/eth/go-ethereum/build/bin:$PATH
[root@lt-test-mongodb eth]# geth version
Geth
Version: 1.7.2-stable
Git Commit: 1db4ecdc0b9e828ff65777fb466fc7c1d04e0de9
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.8.3
Operating System: linux
GOPATH=
GOROOT=/usr/lib/golang
[root@lt-test-mongodb eth]#
以上 geth环境就安装好了
创建以太坊私有链
初始化一个创世区块,首先创建一个 genesis.json文件 内容如下
{
"config": {
"chainId": 10,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"coinbase" : "0x0000000000000000000000000000000000000000",
"difficulty" : "0x20000",
"extraData" : "",
"gasLimit" : "0x2fefd8",
"nonce" : "0x0000000000000042",
"mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp" : "0x00",
"alloc" : {}
}
参数名称 | 参数描述 |
---|---|
mixhash | 与nonce配合用于挖矿,由上一个区块的一部分生成的hash。注意他和nonce的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件。 |
nonce | nonce就是一个64位随机数,用于挖矿,注意他和mixhash的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件。 |
difficulty | 设置当前区块的难度,如果难度过大,cpu挖矿就很难,这里设置较小难度 |
alloc | 用来预置账号以及账号的以太币数量,因为私有链挖矿比较容易,所以我们不需要预置有币的账号,需要的时候自己创建即可以。 |
coinbase | 矿工的账号,随便填 |
timestamp | 设置创世块的时间戳 |
parentHash | 上一个区块的hash值,因为是创世块,所以这个值是0 |
extraData | 附加信息,随便填,可以填你的个性信息 |
gasLimit | 该值设置对GAS的消耗总量限制,用来限制区块能包含的交易信息总和,因为我们是私有链,所以填最大。 |
接下来,我们使用geth init ./genesis.json --datadir "./chain"命令,来进行创世区块的初始化,当前区块链网络数据存放的位置会保存在chain目录中:
初始化 只要在第一次执行就好了
[root@lt-test-mongodb eth]# geth init ./genesis.json --datadir ./chain
WARN [01-19|11:20:28] No etherbase set and no accounts found as default
INFO [01-19|11:20:28] Allocated cache and file handles database=/eth/chain/geth/chaindata cache=16 handles=16
INFO [01-19|11:20:28] Writing custom genesis block
INFO [01-19|11:20:28] Successfully wrote genesis state database=chaindata hash=5e1fc7…d790e0
INFO [01-19|11:20:28] Allocated cache and file handles database=/eth/chain/geth/lightchaindata cache=16 handles=16
INFO [01-19|11:20:28] Writing custom genesis block
INFO [01-19|11:20:28] Successfully wrote genesis state database=lightchaindata hash=5e1fc7…d790e0
启用私有链
geth是一个以太坊客户端,现在利用geth启动一个以太坊网络节点
注意: 在使用go-wallet前 需要先启动 get节点
geth --datadir "./chain" --nodiscover console 2>>eth_output.log //启动了 30303端口
还可以自定义一些参数来启动 启动了 30304和 8545 其他rpc启动相关 https://github.com/ethereum/wiki/wiki/JSON-RPC
geth --datadir "./chain" --networkid 9999 --port 30304 --rpc --rpccorsdomain "*" --rpcapi "db,eth,net,web3" console
[root@lt-test-mongodb eth]# geth \
> --datadir "./chain" \
> --nodiscover \
> console 2>>eth_output.log
Welcome to the Geth JavaScript console!
instance: Geth/v1.7.2-stable-1db4ecdc/linux-amd64/go1.8.3
modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
主网同步数据 列子:
mkdir ./eth
nohup geth --datadir ./eth --syncmode "fast" --cache=512 --rpc --rpcaddr "0.0.0.0" --rpcport 8545 --rpcapi "db,eth,net,web3" --port 30303 --rpccorsdomain "*" >> "./eth/eth-main-geth.log"
主网同步数据的时候 如果内存配置小于8G , 最好不要加上 ethbase 和 mine 等参数,否则进程容易挂掉。 以上主网测试基本没什么问题(4H 8G) CPU %50 内存 40%左右
参数名称 | 参数描述 |
---|---|
datadir | 设置当前区块链网络数据存放的位置 |
console | 启动命令行模式,可以在Geth中执行命令 |
nodiscover | 私有链地址,不会被网上看到 |
gcmode | full or archive. 默认是 full. 若要及时写道磁盘使用 "archive" |
添加--dev 参数,则运行的是POA共识机制,并且不需要先进行geth init了
geth --datadir "./chain" --dev --networkid 9999 --port 30304 --rpc --rpccorsdomain "*" --rpcapi "db,eth,net,web3" console
window启动节点 注意路径 和linux 有点不一样
geth --datadir 'chain' console 2>> eth_output.log
注意: 以上启动方式 可能存在 区块的数据不能及时写道本地磁盘,当geth程序关闭后,可能发现区块高度为0,
我们需要在启动的时候 加上参数 --gcmode "archive"
查看日志输出
tail -f eth_output.log
INFO [01-19|12:15:40] Successfully sealed new block number=379 hash=0dbe3c…7b2d4f
INFO [01-19|12:15:40] block reached canonical chain number=374 hash=f17121…536dbe
INFO [01-19|12:15:40] mined potential block number=379 hash=0dbe3c…7b2d4f
INFO [01-19|12:15:40] Commit new mining work number=380 txs=0 uncles=0 elapsed=157.01µs
INFO [01-19|12:15:42] Successfully sealed new block number=380 hash=ae2d83…bb0eb6
INFO [01-19|12:15:42] block reached canonical chain number=375 hash=f62016…409432
INFO [01-19|12:15:42] mined potential block number=380 hash=ae2d83…bb0eb6
INFO [01-19|12:15:42] Commit new mining work number=381 txs=0 uncles=0 elapsed=151.898µs
INFO [01-19|12:15:43] Successfully sealed new block number=381 hash=7d185e…9b6893
INFO [01-19|12:15:43] block reached canonical chain number=376 hash=62d7eb…06e0d2
INFO [01-19|12:15:43] mined potential block number=381 hash=7d185e…9b6893
INFO [01-19|12:15:43] Commit new mining work number=382 txs=0 uncles=0 elapsed=158.401µs
INFO [01-19|12:15:43] Successfully sealed new block number=382 hash=a1fa15…043c0d
INFO [01-19|12:15:43] block reached canonical chain number=377 hash=2c36b1…1a493e
INFO [01-19|12:15:43] mined potential block number=382 hash=a1fa15…043c0d
INFO [01-19|12:15:43] Commit new mining work number=383 txs=0 uncles=0 elapse
挖矿会默认保存到创建的第一个帐户0xfdbd0fb13c4a7c14e72fa0fe490f3c3c3b7f7fab中。
block number=383,说明我们已经创建了383个区块
在以太坊官方的网络上,平均每15秒产生一个区块
账户 *** 作
账户查看、新建
> eth.accounts
[]
> web3.eth.accounts
[]
> personal.newAccount("star") --star是密码
"0xfdbd0fb13c4a7c14e72fa0fe490f3c3c3b7f7fab" --返回账户
> eth.accounts
["0xfdbd0fb13c4a7c14e72fa0fe490f3c3c3b7f7fab"]
启动挖矿
启动后开始挖矿 miner.start(1) -> 1:表示一个CPU
> miner.start()
查看日志就开始自动挖矿了 我们查看下余额 , 以太币最小的单位是wei(18个0)
> eth.getBalance(eth.accounts[0])
10000000000000000000
新建一个账户
> eth.accounts
["0xfdbd0fb13c4a7c14e72fa0fe490f3c3c3b7f7fab"]
> personal.newAccount('star2')
"0xbb2b0e20937bdff666a85cd723c18250e50c469a"
> eth.accounts
["0xfdbd0fb13c4a7c14e72fa0fe490f3c3c3b7f7fab", "0xbb2b0e20937bdff666a85cd723c18250e50c469a"]
> eth.getBalance(eth.accounts[1])
0
> eth.getBalance(eth.accounts[0])
90000000000000000000
第一个账户往第二个账户转账
从帐户 第一个账户 转10个以太币到第二个账户,如果不指定单位 ether,默认转的是 wei。备注: value:web3.toWei(10,"ether")
> eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:10})
如果出现以下错误, 那么账号需要先解锁
Error: authentication needed: password or unlock
at web3.js:3143:20
at web3.js:6347:15
at web3.js:5081:36
at :1:1
> personal.unlockAccount(eth.accounts[0],"star")
true
再查看余额
> eth.getBalance(eth.accounts[0])
114999999999999999980
> eth.getBalance(eth.accounts[1])
20
停止 go-etheruem
停止挖矿后,以太币则不会产生,同样智能合约、转帐等 *** 作也不会起作用。
>miner.stop()
Hello World 智能合约开发
Solidity安装
强烈建议新手使用Browser-Solidity来进行开发。
Browser-Solidity是一个基于浏览器的Solidity,就可以不用安装Solidity,本文的Hello World教程也将基于Browser-Solidity来进行。
如果你想自己安装请参考Solidity安装指引。
本地安装
git clone https://github.com/ethereum/browser-solidity
cd browser-solidity
npm install
npm run prepublish
npm start
然后打开浏览器,在地址栏输入:http://127.0.0.1:8080
编写合约代码
现在我们来开始编写第一个智能合约代码,solidity代码如下:
pragma solidity ^0.4.20;
contract hello {
string greeting="hello world";
function hello(string _greeting) public{
greeting =_greeting;
}
function setHello(string _greeting) payable public {
greeting =_greeting;
}
function sayHello() view public returns(string){
return greeting;
}
}
简单解释下,我们定义了一个名为hello的合约,在合约初始化时保存了一个字符串(我们会传入hello world),每次调用say返回字符串。
把这段代码写(拷贝)到Browser-Solidity,如果没有错误,点击Details获取部署代码,如:
在d出的对话框中找到WEB3DEPLOY部分,点拷贝,粘贴到编辑器后,修改初始化字符串为hello world。
solidity,版本为0.4.18,solidity发展非常快,solidity版本之间有可能不能兼容,这是你可以在Browser-Solidity的Settings里选择对应的编译器版本。
Browser-Solidity也不停的更新中,截图可能和你看到的界面不一样。
部署合约
var _greeting ="hello,world";
var helloContract = web3.eth.contract([{"constant":false,"inputs":[{"name":"_greeting","type":"string"}],"name":"setHello","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"sayHello","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: '0x60606040526040805190810160405280600b81526020017f68656c6c6f20776f726c640000000000000000000000000000000000000000008152506000908051906020019061004f929190610094565b50341561005b57600080fd5b60405161042038038061042083398101604052808051820191905050806000908051906020019061008d929190610094565b5050610139565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100d557805160ff1916838001178555610103565b82800160010185558215610103579182015b828111156101025782518255916020019190600101906100e7565b5b5090506101109190610114565b5090565b61013691905b8082111561013257600081600090555060010161011a565b5090565b90565b6102d8806101486000396000f30060606040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063435ffe9414610051578063ef5fb05b146100a3575b600080fd5b6100a1600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050610131565b005b34156100ae57600080fd5b6100b661014b565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f65780820151818401526020810190506100db565b50505050905090810190601f1680156101235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b80600090805190602001906101479291906101f3565b5050565b610153610273565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156101e95780601f106101be576101008083540402835291602001916101e9565b820191906000526020600020905b8154815290600101906020018083116101cc57829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061023457805160ff1916838001178555610262565b82800160010185558215610262579182015b82811115610261578251825591602001919060010190610246565b5b50905061026f9190610287565b5090565b602060405190810160405280600081525090565b6102a991905b808211156102a557600081600090555060010161028d565b5090565b905600a165627a7a72305820416b762e5c484970552c447f5e80665d36d2730f97820b306dbdcb9d62bdf7cc0029',
gas: '300000'
}, function (e, contract){
console.log(e, contract);
if (typeof contract.address !== 'undefined') {
console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
}
})
第1行:修改字符串为Hello World
第2行:修改合约变量名
第3行:修改合约实例变量名,之后可以直接用实例调用函数。
第6行:修改部署账户为新账户索引,即使用新账户来部署合约。
第8行:准备付的gas费用,IDE已经帮我们预估好了 需要gas 到300000(若错误Error: exceeds block gas limit undefined )。
第9行:设置部署回调函数。
拷贝会geth控制台里,回车后,看到输出如: 注意: 有可能在 geth客户端比较慢 可能在 miner.start()后 一段时间才能被打包到区块
请耐心等待 。还可以 这样写 miner.start(2);admin.sleepBlocks(1);miner.stop() 表示挖到一个区块就停止
Contract mined! address: 0x6d9abea47d43fbc425160f9515ac4dd41c7f1a07 transactionHash: 0xc07ae58e654ae9d8a2d6506e1f341134ec53d4ff796fba99a8f55d6a74cbc06a
同时 日志部分也有相关信息
INFO [01-19|12:58:06] Submitted contract creation fullhash=0xc07ae58e654ae9d8a2d6506e1f341134ec53d4ff796fba99a8f55d6a74cbc06a contract=0x6D9abeA47D43fBc425160f9515AC4DD41C7F1a07
说明合约已经部署成功。
如果没有成功。 看看有没有启动 私有链 miner.start()
输入合约名称 hello 如果出现
> hello
{
abi: [{
constant: false,
inputs: [{...}],
name: "setHello",
outputs: [],
payable: true,
stateMutability: "payable",
type: "function"
}, {
constant: true,
inputs: [],
name: "sayHello",
outputs: [{...}],
payable: false,
stateMutability: "view",
type: "function"
}, {
inputs: [{...}],
payable: false,
stateMutability: "nonpayable",
type: "constructor"
}],
address: "0x595d69c7bacc1c6d37588810fe6f2f10da2795c2",
transactionHash: "0x5f0a5f2b3c3d9409b4179b99ce0a4639838496a3814
eed3c5",
allEvents: function(),
sayHello: function(),
setHello: function()
}
出现最后的3行 表示已经写到区块
注意 节点启动最好启用 --rpc --rpcaip "eth.net.web3"
web3方式调用合约:
> hello.sayHello() # 合约查询
"hello,world"
> hello.sayHello.call() #合约查询
"hello,world"
> hello.setHello.sendTransaction("hello,andrew",{from:web3.eth.accounts[0]});
Error: authentication needed: password or unlock
at web3.js:3143:20
at web3.js:6347:15
at web3.js:5081:36
at web3.js:4137:16
at :1:1
> personal.unlockAccount(eth.accounts[0],'andrew')
true
> hello.setHello.sendTransaction("hello,andrew",{from:web3.eth.accounts[0]}); //修改区块数据
INFO [03-11|15:28:57] Submitted transaction fullhash=0xc97b58
77708362ffafe5faa0829e8045f23b5658f99c6584fc072cc1f9a911e3 recipient=0x595d69C7B
Acc1c6d37588810fE6F2f10da2795C2
"0xc97b5877708362ffafe5faa0829e8045f23b5658f99c6584fc072cc1f9a911e3"
> hello.sayHello.call()
"hello,world"
> miner.start(1);admin.sleepBlocks(1);miner.stop()
INFO [03-11|15:29:39] Updated mining threads threads=1
INFO [03-11|15:29:39] Transaction pool price threshold updated price=18000000000
INFO [03-11|15:29:39] Starting mining operation
INFO [03-11|15:29:39] Commit new mining work number=56 txs=1
uncles=0 elapsed=0s
INFO [03-11|15:29:40] Successfully sealed new block number=56 hash=0
84b05…0377a0
INFO [03-11|15:29:40]
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)