以太坊网建立、合约编译、部署
以太坊网建立、合约编译、部署
在本地建一套以太坊私有链,进行智能合约的开发测试。开发好的智能合约切换接口部署到以太坊公有链上。
开源工具安装
- install Go compiler
- go-ethereum 编译安装
- 以太坊智能合约语言solidity安装
- 【以太坊网建立、合约编译、部署】创建一个文件夹来存储私链数据
mkdir privateChain cd privateChain
- 使用geth来加载
geth --networkid 123 --dev --datadir data1 --rpc --rpcaddr 192.168.11.243 --rpcport 8989 --port 3000 // --identity 指定节点ID // --networkid 是网络id,区分各方区块链的网络id // --dev 开发 // --datadir创建私链数据存储目录 // --rpc 表示开启HTTP-RPC服务 // --rpcaddrHTTP-RPC服务ip地址 // --rpcport HTTP-RPC服务监听端口号(default:8545) // --port 指定和其他节点连接所用的端口号(default:30303) // --nodiscover关闭节点发现机制,防止加入有同样初始配置的陌生节点
- 打开节点
cd /home/jianhuaixie/blockchain/privateChain/data1 geth attach ipc:geth.ipc
- eth:包含一些跟操作区块链相关的方法
- net:包含一些查看p2p网络状态的方法
- admin:包含一些与管理节点相关的方法
- miner:包含启动&停止挖矿的一些方法
- personal:主要包含一些管理账户的方法
- txpool:包含一些查看交易内存池的方法
- web3:包含了以上对象,还包含一些单位换算的方法
- 创建一个帐号
personal.listAccounts//查看帐号列表 personal.newAccount("jianhuaixie")//这个用户名相当于钱包的密码 eth.coinbase//帐号中的第0个帐号 eth.getBalance(eth.coinbase)//查看coinbase帐号余额 miner.start(); //开始挖矿,Block sealing failederr="waiting for transactions" 的警告,Geth启动后,自动开启挖矿,因为没有交易所以执行失败,正常 miner.stop(); //停止挖矿user1=eth.accounts[0] user2=eth.accounts[1] eth.blockNumber//查看区块高度 personal.unlockAccount(user1)//转账测试,首先解锁帐号user1,默认密码为空 eth.sendTransaction({from:user1,to:user2,value:web3.toWei(3,"ether")})// 提交交易立马自动挖矿 eth.blockNumberminer.setEtherbase(eth.accounts[1])//设置矿工地址
- 编写智能合约
pragma solidity ^0.4.21; contract WiairRouteToken { function multiply(uint a) constant returns(uint d){ return a*7; } }
- 获取智能合约字节码和ABI
{
"linkReferences": {},
"object": "6060604052341561000f57600080fd5b60b18061001d6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa1146044575b600080fd5b3415604e57600080fd5b606260048080359060200190919050506078565b6040518082815260200191505060405180910390f35b60006007820290509190505600a165627a7a7230582072d602b915fc4c683527b7f04dbf273e779da8101cb0bcfbe7894b9664c139fb0029",
"opcodes": "PUSH1 0x60 PUSH1 0x40 MSTORE CALLVALUE ISZERO PUSH2 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0xB1 DUP1 PUSH2 0x1D PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x60 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH1 0x3F JUMPI PUSH1 0x0 CALLDATALOAD PUSH29 0x100000000000000000000000000000000000000000000000000000000 SWAP1 DIV PUSH4 0xFFFFFFFF AND DUP1 PUSH4 0xC6888FA1 EQ PUSH1 0x44 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE ISZERO PUSH1 0x4E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x62 PUSH1 0x4 DUP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH1 0x78 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x0 PUSH1 0x7 DUP3 MUL SWAP1 POP SWAP2 SWAP1 POP JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 PUSH19 0xD602B915FC4C683527B7F04DBF273E779DA810 SHR 0xb0 0xbc CREATE2 0xe7 DUP10 0x4b SWAP7 PUSH5 0xC139FB0029 ",
"sourceMap": "26:114:0:-;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
"
}
abi
[
{
"constant": true,
"inputs": [
{
"name": "a",
"type": "uint256"
}
],
"name": "multiply",
"outputs": [
{
"name": "d",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
]
代码拷贝到https://remix.ethereum.org,编译,然后拷贝字节码和ABI。
- 在bejson中渐变ABI转义成字符串 http://www.bejson.com
[{\"constant\":true,\"inputs\":[{\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"multiply\",\"outputs\":[{\"name\":\"d\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]
- 通过abi创建合约对象
> var abi = JSON.parse('[{\"constant\":true,\"inputs\":[{\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"multiply\",\"outputs\":[{\"name\":\"d\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]') > var myContract = web3.eth.contract(abi)
- 预估手续费
> var bytecode = "0x字节码"//0x代表16进制,将字节码贴过来 // 花费gas的多少,就看这个字节码的大小,写入区块链的内容大小决定了花费gas多少 > web3.eth.estimateGas({data:bytecode})
- 部署合约,为了理解方便,设置一个回调函数
> personal.unlockAccount(user1) > var contractInstance = myContract.new({data:bytecode gas:1000000,from:user1}, function(e,contract){ if(!e){ if(!contract.address){ console.log("Contract transaction send:Transation Hash:"+contract.transactionHash+" waiting to be mined..."); }else{ console.log("Contract mined Address:"+contract.address); console.log(contract); } }else{ console.log(e) } } )> miner.start();
- 调用合约方法
> contractInstance.multiply(6)
geth --networkid 123 --datadir data1 --rpc --rpcaddr 192.168.11.243 --rpcport 8989 --port 3000 console
//如果是两台服务器,需要修改rpcaddr地址
//如果是同一台服务器,需要修改不同的rpcport 和 port以及datadir
多节点连接
> admin.nodeInfo.enode
// Enode url 其实是和另外一个节点互动的唯一的id
> web3.net.peerCount//查看连接节点数
> admin.peers//查看节点
> admin.addPeer("enode://...")
通过创世区块来初始化区块链 genesis block file example
{
"config":{
"chainId":15,
"homesteadBlock":0,
"eip155Block":0,
"eip158Block":0
},
"difficulty":"4",
"gasLimit":"2100000",
"alloc":{
"0xd8fac16ffe306a7e0006eb1e3817cc7039796e48":{
"balance":"300000"
},
"0xdc59af2a8c245af2f526fabef80514291bb8b937":{
"balance":"400000"
}
}
}
- 生成创世区块JSON文件
cat > genesis.json//贴genesis file进去
- 初始化区块链,并且创建一个文件夹来存储区块数据
geth init genesis.json --datadir blockchainData
- 打开终端
geth --networkid 123 --datadir blockchainData console
- 设置miner的coinbase帐号
miner.setEtherbase("0xd8fac16ffe306a7e0006eb1e3817cc7039796e48")
推荐阅读
- 股票型公募基金投资要领
- 以太坊中的计量单位及相互转换
- 碎片化阅读,四步教你建立自己的知识体系
- 区块链开发平台(以太坊)
- 明朝建立后,朱元璋大杀功臣,汤和有何过人之处,能够寿终正寝()
- 深圳建立强制立体绿化制度|深圳建立强制立体绿化制度 今年将超额完成46万平方米
- 建立垂直阅读才是最重要的
- 服务器未能释放tcp连接,TCP连接的建立和释放
- 教育|教育 | 如何帮孩子建立起良好的知识结构!
- 诗萱言币|诗萱言币 11.9早间比特币以太坊盘整蓄力 多空转换等待破位