以太坊网建立、合约编译、部署

以太坊网建立、合约编译、部署

在本地建一套以太坊私有链,进行智能合约的开发测试。开发好的智能合约切换接口部署到以太坊公有链上。

开源工具安装

  • 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服务
      // --rpcaddr  HTTP-RPC服务ip地址
      // --rpcport HTTP-RPC服务监听端口号(default:8545)
      // --port 指定和其他节点连接所用的端口号(default:30303)
      // --nodiscover  关闭节点发现机制,防止加入有同样初始配置的陌生节点
    
  • 打开节点

      cd /home/jianhuaixie/blockchain/privateChain/data1
      geth attach ipc:geth.ipc
    

打开一个console,实现一些JS的交互,在这个环境里内置了一些用来操作以太坊的JavaScript对象,可以直接使用这些对象,这些对象主要包括:

- 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 failed        err="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.blockNumber
    
      miner.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")
    

你可能感兴趣的:(以太坊网建立、合约编译、部署)