摘要:备注:安装时间可能有点长,请耐心等待… 备注:安装时间可能有点长,请耐心等待… 备注:安装时间可能有点长,请耐心等待…


以太坊(Ethereum)私链建立 、合约编译、部署完全教程(1)-区块读刊

开源工具和语言

一、brewMacOS包管理器

 /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 

二、Solidity以太坊智能合约语言

 brew install solidity 

备注:安装时间可能有点长,请耐心等待… 备注:安装时间可能有点长,请耐心等待… 备注:安装时间可能有点长,请耐心等待…

如果碰见下面的错误,请移步:http://blog.csdn.net/Sico2Sico/article/details/71082130

 The GitHub credentials in the macOS keychain may be invalid. Clear them with:   printf "protocol=https/nhost=github.com/n" | git credential-osxkeychain erase Or create a personal access token:  https://github.com/settings/tokens/new?scopes=gist,public_repo&description=Homebrew  

三、geth运行以太坊节点

下载Source code (tar.gz)

 liyuechun:Downloads yuechunli$ cd go-ethereum-1.5.9 liyuechun:go-ethereum-1.5.9 yuechunli$ pwd /Users/liyuechun/Downloads/go-ethereum-1.5.9 liyuechun:go-ethereum-1.5.9 yuechunli$ make geth 

建立私链

1. 创建一个文件夹来存储你的私链数据

 liyuechun:1015 yuechunli$ mkdir privchain liyuechun:1015 yuechunli$ pwd /Users/liyuechun/Desktop/1015 liyuechun:1015 yuechunli$ ls privchain liyuechun:1015 yuechunli$  

2. 使用geth来加载

 geth --rpc --rpcaddr 127.0.0.1 --rpcport 8545 --dev --datadir privchain 

执行上面的命令,你应该能看到下面的信息:

INFO [10-15 03:14:50] IPC endpoint opened: /Users/liyuechun/Desktop/1015/privchain/geth.ipc
INFO [10-15 03:14:50] HTTP endpoint opened: http://127.0.0.1:8545

如果你切换到privchain文件夹里面,你会看到gethgeth.ipc, 和 keystore

 liyuechun:1015 yuechunli$ cd privchain/ liyuechun:privchain yuechunli$ ls geth  geth.ipc keystore liyuechun:privchain yuechunli$  

  • 保持节点的运行,不要关闭终端,重新打开一个终端,使用geth attach连接节点,并且打开geth console
 liyuechun:privchain yuechunli$ geth attach ipc:/Users/liyuechun/Desktop/1015/privchain/geth.ipc  Welcome to the Geth JavaScript console!  instance: Geth/v1.7.1-stable-05101641/darwin-amd64/go1.9.1  modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 shh:1.0 txpool:1.0 web3:1.0  >  

3. 相关api命令

查看账户

 > personal.listAccounts [] >  

创建账户

 > personal.newAccount('liyuechun')  "0xb6d7d842e7dc9016fa6900a183b2be26fc90b2d8" >  

PS:里面的liyuechun是你账户的密码,输入你自己喜欢的密码。

查看账户

 > personal.listAccounts  ["0xb6d7d842e7dc9016fa6900a183b2be26fc90b2d8"] >  

4. web3命令

https://ethereumbuilders.gitbooks.io/guide/content/en/ethereum_javascript_api.html

 > web3.eth.coinbase  "0xb6d7d842e7dc9016fa6900a183b2be26fc90b2d8" >  

5. 编写智能合约代码

 pragma solidity ^0.4.4;  contract test {       function multiply(uint a) returns(uint d){          return a * 7;     }  } 

6. 获取智能合约字节码和abi

代码拷贝到https://remix.ethereum.org,编译,然后拷贝字节码。

 6060604052341561000f57600080fd5b5b60ab8061001e6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa114603d575b600080fd5b3415604757600080fd5b605b60048080359060200190919050506071565b6040518082815260200191505060405180910390f35b60006007820290505b9190505600a165627a7a7230582067d7c851e14e862886b6f53dad6825135557fb3a4b691350c94ea5b80605f6770029 

 {   "contract_name": "test",   "abi": [     {       "constant": false,       "inputs": [         {           "name": "a",           "type": "uint256"         }       ],       "name": "multiply",       "outputs": [         {           "name": "d",           "type": "uint256"         }       ],       "payable": false,       "type": "function"     }   ],   "unlinked_binary": "0x60606040523415600e57600080fd5b5b60978061001d6000396000f300606060405263ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663c6888fa18114603c575b600080fd5b3415604657600080fd5b604f6004356061565b60405190815260200160405180910390f35b600781025b9190505600a165627a7a723058203da73c4161a1751d52899e2da724076a62a935cb5e7ed4b29f7f49560675ab8d0029",   "networks": {},   "schema_version": "0.0.5",   "updated_at": 1508016118593 } 

7. 在bejson中转义成字符串

http://www.bejson.com

 {/"contract_name/":/"test/",/"abi/":[{/"constant/":false,/"inputs/":[{/"name/":/"a/",/"type/":/"uint256/"}],/"name/":/"multiply/",/"outputs/":[{/"name/":/"d/",/"type/":/"uint256/"}],/"payable/":false,/"type/":/"function/"}],/"unlinked_binary/":/"0x60606040523415600e57600080fd5b5b60978061001d6000396000f300606060405263ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663c6888fa18114603c575b600080fd5b3415604657600080fd5b604f6004356061565b60405190815260200160405180910390f35b600781025b9190505600a165627a7a723058203da73c4161a1751d52899e2da724076a62a935cb5e7ed4b29f7f49560675ab8d0029/",/"networks/":{},/"schema_version/":/"0.0.5/",/"updated_at/":1508016118593} 

7. 通过abi创建合约对象

 > var contractInfo = JSON.parse('{/"contract_name/":/"test/",/"abi/":[{/"constant/":false,/"inputs/":[{/"name/":/"a/",/"type/":/"uint256/"}],/"name/":/"multiply/",/"outputs/":[{/"name/":/"d/",/"type/":/"uint256/"}],/"payable/":false,/"type/":/"function/"}],/"unlinked_binary/":/"0x60606040523415600e57600080fd5b5b60978061001d6000396000f300606060405263ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663c6888fa18114603c575b600080fd5b3415604657600080fd5b604f6004356061565b60405190815260200160405180910390f35b600781025b9190505600a165627a7a723058203da73c4161a1751d52899e2da724076a62a935cb5e7ed4b29f7f49560675ab8d0029/",/"networks/":{},/"schema_version/":/"0.0.5/",/"updated_at/":1508016118593}') > myContract = web3.eth.contract(contractInfo.abi) {   abi: [{       constant: false,       inputs: [{...}],       name: "multiply",       outputs: [{...}],       payable: false,       type: "function"   }],   eth: {     accounts: ["0x2abf46d8b0d940cdeedd55872bc0648add40227d"],     blockNumber: 384,     coinbase: "0x2abf46d8b0d940cdeedd55872bc0648add40227d",     compile: {       lll: function(),       serpent: function(),       solidity: function()     },     defaultAccount: undefined,     defaultBlock: "latest",     gasPrice: 0,     hashrate: 0,     mining: false,     pendingTransactions: [],     protocolVersion: "0x3f",     syncing: false,     call: function(),     contract: function(abi),     estimateGas: function(),     filter: function(fil, callback),     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),     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() } 

8. 检查coinbase账号余额

 > account1 = web3.eth.coinbase "0x2abf46d8b0d940cdeedd55872bc0648add40227d" > web3.eth.getBalance(account1) 0 >  

如果余额大于0,继续,否则,开始挖矿。

 > miner.start(); null >  

挖矿过程中,切换到节点终端,你会发现一直在挖矿。

以太坊(Ethereum)私链建立 、合约编译、部署完全教程(1)-区块读刊

如果你觉得差不多了,可以运行下面的命令停止挖矿。

 miner.stop(); 

9. 停止挖矿,并且查余额

 > miner.start(); null > miner.stop(); true > web3.eth.getBalance(account1) 1.152e+21 >  

10. 解锁coinbase账号,我们通过coinbase账号来付费部署合约

liyuechun: 换成你的密码。

 > personal.unlockAccount(account1, 'liyuechun')  true >  

11. 预估手续费

 > bytecode = "6060604052341561000f57600080fd5b5b60ab8061001e6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa114603d575b600080fd5b3415604757600080fd5b605b60048080359060200190919050506071565b6040518082815260200191505060405180910390f35b60006007820290505b9190505600a165627a7a7230582067d7c851e14e862886b6f53dad6825135557fb3a4b691350c94ea5b80605f6770029" "6060604052341561000f57600080fd5b5b60ab8061001e6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa114603d575b600080fd5b3415604757600080fd5b605b60048080359060200190919050506071565b6040518082815260200191505060405180910390f35b60006007820290505b9190505600a165627a7a7230582067d7c851e14e862886b6f53dad6825135557fb3a4b691350c94ea5b80605f6770029" > web3.eth.estimateGas({data: bytecode}) Error: invalid argument 0: json: cannot unmarshal hex string without 0x prefix into Go struct field CallArgs.data of type hexutil.Bytes     at web3.js:3104:20     at web3.js:6191:15     at web3.js:5004:36     at <anonymous>:1:1  > bytecode = "0x6060604052341561000f57600080fd5b5b60ab8061001e6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa114603d575b600080fd5b3415604757600080fd5b605b60048080359060200190919050506071565b6040518082815260200191505060405180910390f35b60006007820290505b9190505600a165627a7a7230582067d7c851e14e862886b6f53dad6825135557fb3a4b691350c94ea5b80605f6770029" "0x6060604052341561000f57600080fd5b5b60ab8061001e6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa114603d575b600080fd5b3415604757600080fd5b605b60048080359060200190919050506071565b6040518082815260200191505060405180910390f35b60006007820290505b9190505600a165627a7a7230582067d7c851e14e862886b6f53dad6825135557fb3a4b691350c94ea5b80605f6770029" > web3.eth.estimateGas({data: bytecode}) 98391 >  

备注:字节码前面需要添加0x。手续费大概为98391wei

12. 部署合约,为了方便理解,设置一个回调函数

 > contractInstance = myContract.new({data: bytecode gas: 1000000, from: account1}, function(e, contract){   if(!e){     if(!contract.address){       console.log("Contract transaction send: Transaction Hash: "+contract.transactionHash+" waiting to be mined...");     }else{       console.log("Contract mined! Address: "+contract.address);       console.log(contract);     }   }else{     console.log(e)   } }) Contract transaction send: Transaction Hash: 0x5e2aebbf400d71a32e807dc3f11f1053b6ee3b2a81435ed8ace2fa54eebb9f3d waiting to be mined... {   abi: [{       constant: false,       inputs: [{...}],       name: "multiply",       outputs: [{...}],       payable: false,       type: "function"   }],   address: undefined,   transactionHash: "0x5e2aebbf400d71a32e807dc3f11f1053b6ee3b2a81435ed8ace2fa54eebb9f3d" } >  

13. 你的合约等待挖矿,开始挖矿,等一会儿,停止

 > miner.start() null > Contract mined! Address: 0xbf8b24283f2516360d3a4ba1db0df78ae74689db [object Object] > miner.stop() true >  

以太坊(Ethereum)私链建立 、合约编译、部署完全教程(1)-区块读刊以太坊(Ethereum)私链建立 、合约编译、部署完全教程(1)-区块读刊

14. 检查合约是否部署成功

 > eth.getCode(contractInstance.address) "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa114603d575b600080fd5b3415604757600080fd5b605b60048080359060200190919050506071565b6040518082815260200191505060405180910390f35b60006007820290505b9190505600a165627a7a7230582067d7c851e14e862886b6f53dad6825135557fb3a4b691350c94ea5b80605f6770029" >  

15. 调用合约方法

 > contractInstance.multiply.call(6) 42 >  

PS: 这里添加call的原因是因为multiply函数没有添加constant

 pragma solidity ^0.4.4;  contract test {      function multiply(uint a) returns(uint d){          return a * 7;     }  } 

Over Game!!!!

技术交流

  • 区块链技术交流QQ群:348924182
发文时比特币价格 ¥40600
 

作者:黎跃春
来源:孔壹学院
微信:liyc1215

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。