以太坊的环境容易部署,执行一些命令就OK了。 那就开始搞吧。。。
以太坊环境部署 在安装以太坊之前要先安装下go,go的安装类似jdk,下载tar包,解压然后配置下环境变量。
安装以太坊:
1 2 3 4 5 6 7 8 9 sudo add-apt-repository -y ppa:ethereum/ethereum sudo add-apt-repository -y ppa:ethereum/ethereum-dev sudo add-apt-repository ppa:ethereum/ethereum-qt sudo apt-get update sudo apt-get install ethereum sudo apt-get install cpp-ethereum sudo apt-get install solc
安装结束之后的版本是Geth/v1.8.13-stable-225171a4/linux-amd64/go1.10
认识以太坊 完成以上操作之后,就可以操作以太坊了,可以进行挖矿了。这里先来熟悉下以太坊的客户端geth。
geth的全称是go-ethereum,是一个以太坊客户端,用go语言编写。
进入geth客户端有两种比较方式,一种是以开发方式登录 ,另一种是以私链方式登录 。其中以开发方式登录相对比较简单,我们先来简单的。
输入命令geth --dev --dev.period 1 console 2>> geth-log
(此命令,默认就会挖矿,执行miner.stop()停止 )进入客户端。
执行上述命令会在当前目录生成一个geth-log的文件,可在其中查看运行情况。
挖矿 我们接触到以太坊或者比特币的第一想法就是,自己在测试环境挖个矿,感受下,对这些虚拟的东西来个直观的认识。
在挖矿之前我们先熟悉几个常用的命令,感受下geth。
1 2 3 4 5 6 7 8 9 eth eth.accounts personal.newAccount('bigdatadecode' ) personal.newAccount('bigdatadecode.top' ) eth.accounts user1 = eth.accounts[0] user2 = eth.accounts[1] eth.getBalance(user1)
发现这些账户的余额是0,那么重点就来了,开始挖矿了,
1 2 3 4 5 6 7 8 9 10 11 12 13 miner.start() miner.stop() eth.getBalcance(user1) eth.sendTransaction({from:user1,to:user2,value:8}) eth.getBalance(user2) web3.fromWei(eth.getBalance(eth.accounts[0]), "ether" ) personal.unlockAccount(user3, 'bigdatadecode.top' ) eth.blockNumber eth.getBlock(8) eth.coinbase miner.setEtherbase(eth.coinbase) eth.blockNumber
Note: 如果你进入geth的命令是geth --dev console 2>> geth-log
,当执行miner.start()
时,会返回null, 原因在于geth版本更新之后,–dev模式下新增了一个参数项,加上--dev.period 1
返回null,解决方案原文
HelloWorld 上一节操作了挖矿转账等流程,这节整个智能合约的HelloWorld。直接上合约代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 contract Mortal { address owner; function Mortal ( ) { owner = msg.sender; } function kill ( ) { if (msg.sender == owner) selfdestruct(owner); } } contract Greeter is Mortal { string greeting; function Greeter (string _greeting ) public { greeting = _greeting; } function greet ( ) constant returns (string ) { return greeting; } }
合约greeter是一个简单的智能合约,你可以使用这个合约来和其他人交流,它的回复会同你的输入完全一样,当输入为“Hello World!”的时候,合约也会回复“Hello World!”。
将上述代码写入greeter.sol中。
编译智能合约 编译智能合约可以使用Browser-Solidity 在线编译,也可以使用solc命令本地编译,此处使用solc命令本地编译。 1、生成bytecode 执行solc --bin greeter.sol
生成code,如下:
1 2 3 4 5 6 7 ======= greeter.sol:Greeter ======= Binary: 608060405234801561001057600080fd5b5060405161039b38038061039b83398101806040528101908080518201929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060019080519060200190610089929190610090565b5050610135565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100d157805160ff19168380011785556100ff565b828001600101855582156100ff579182015b828111156100fe5782518255916020019190600101906100e3565b5b50905061010c9190610110565b5090565b61013291905b8082111561012e576000816000905550600101610116565b5090565b90565b610257806101446000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806341c0e1b514610051578063cfae321714610068575b600080fd5b34801561005d57600080fd5b506100666100f8565b005b34801561007457600080fd5b5061007d610189565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100bd5780820151818401526020810190506100a2565b50505050905090810190601f1680156100ea5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610187576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b565b606060018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102215780601f106101f657610100808354040283529160200191610221565b820191906000526020600020905b81548152906001019060200180831161020457829003601f168201915b50505050509050905600a165627a7a723058203f4430a961037d5e7c4870ac4cc8f97d329171e862ae297fd0046255bec602490029 ======= greeter.sol:Mortal ======= Binary: 608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610114806100606000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806341c0e1b5146044575b600080fd5b348015604f57600080fd5b5060566058565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141560e6576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b5600a165627a7a723058206554007d7824c95b6473134490ff9f84381627c8c29d43da39ce468e740abeda0029
2、生成ABI 执行solc --abi greeter.sol
生成ABI,如下:
1 2 3 4 5 6 7 ======= greeter.sol:Greeter ======= Contract JSON ABI [{"constant" :false ,"inputs" :[],"name" :"kill" ,"outputs" :[],"payable" :false ,"stateMutability" :"nonpayable" ,"type" :"function" },{"constant" :true ,"inputs" :[],"name" :"greet" ,"outputs" :[{"name" :"" ,"type" :"string" }],"payable" :false ,"stateMutability" :"view" ,"type" :"function" },{"inputs" :[{"name" :"_greeting" ,"type" :"string" }],"payable" :false ,"stateMutability" :"nonpayable" ,"type" :"constructor" }] ======= greeter.sol:Mortal ======= Contract JSON ABI [{"constant" :false ,"inputs" :[],"name" :"kill" ,"outputs" :[],"payable" :false ,"stateMutability" :"nonpayable" ,"type" :"function" },{"inputs" :[],"payable" :false ,"stateMutability" :"nonpayable" ,"type" :"constructor" }]
ABI(Application Binary Interface)其实就是一个有序的用户手册,描述了所有方法的名字和如何调用它们
设置希望返回的字符串 进入geth命令行,执行var _greeting = "Hello World!"
部署合约 1、用ABI来创建一个javascript环境中的合约对象
1 var greeterContract = web3.eth.contract([{"constant" :false ,"inputs" :[],"name" :"kill" ,"outputs" :[],"payable" :false ,"stateMutability" :"nonpayable" ,"type" :"function" },{"constant" :true ,"inputs" :[],"name" :"greet" ,"outputs" :[{"name" :"" ,"type" :"string" }],"payable" :false ,"stateMutability" :"view" ,"type" :"function" },{"inputs" :[{"name" :"_greeting" ,"type" :"string" }],"payable" :false ,"stateMutability" :"nonpayable" ,"type" :"constructor" }]);
2、通过合约对象来部署合约
1 2 3 4 5 6 7 8 9 10 11 12 var greeter = greeterContract.new( _greeting, { from : web3.eth.accounts[0 ], data : '0x608060405234801561001057600080fd5b5060405161039b38038061039b83398101806040528101908080518201929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060019080519060200190610089929190610090565b5050610135565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100d157805160ff19168380011785556100ff565b828001600101855582156100ff579182015b828111156100fe5782518255916020019190600101906100e3565b5b50905061010c9190610110565b5090565b61013291905b8082111561012e576000816000905550600101610116565b5090565b90565b610257806101446000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806341c0e1b514610051578063cfae321714610068575b600080fd5b34801561005d57600080fd5b506100666100f8565b005b34801561007457600080fd5b5061007d610189565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100bd5780820151818401526020810190506100a2565b50505050905090810190601f1680156100ea5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610187576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b565b606060018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102215780601f106101f657610100808354040283529160200191610221565b820191906000526020600020905b81548152906001019060200180831161020457829003601f168201915b50505050509050905600a165627a7a723058203f4430a961037d5e7c4870ac4cc8f97d329171e862ae297fd0046255bec602490029' , gas : '4700000' }, function (e, contract ) { console .log(e, contract); if (typeof contract.address !== 'undefined' ) { console .log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash); } })
挖矿 1、执行miner.start(1)
开启挖矿 2、有块产生之后,执行miner.stop()
停止挖矿
运行合约 执行命令greeter.greet();
,正常命令行上会出现如下返回结果:Hello World!
OK,我们的第一个智能合约程序 “Hello World!” 已经完成了,但是目前它只有一个节点!
部署在其它节点 为了使得其他人可以运行你的智能合约,你需要两个信息:
智能合约地址Address
智能合约ABI
ABI在上文中已得到,智能合约的地址可以执行greeter.address
得到。
然后你可以实例化一个JavaScript对象,该对象可以用来在任意联网机器上调用该合约,此处ABI和Address是上述代码返回值。var greeter = eth.contract(ABI).at(Address);
自毁程序 一个交易需要被发送到网络需要支付费用,自毁程序是对网络的补充,花费的费用远小于一次常用交易。 你可以通过以下代码来检验是否成功,如果自毁程序运行成功以下代码会返回0:greeter.kill.sendTransaction({from:eth.accounts[0]})
我执行完上述命令返回的貌似是一个地址,如下:
1 2 > greeter.kill.sendTransaction({from:eth.accounts[0]}) "0x117d2066fae468a16077286573b0e3470b20e9ac5bb87291f7733dd453027441"
此时再次执行greeter.greet();
依然能返回Hello World!
,我再次开启挖矿,一段时间后停止挖矿,再执行greeter.greet();
,报错
1 2 3 4 5 6 7 8 9 10 11 > greeter.greet() Error : new BigNumber() not a base 16 number: at L (bignumber.js:3 :2876 ) at bignumber.js:3 :8435 at a (bignumber.js:3 :389 ) at web3.js:1110 :23 at web3.js:1634 :20 at web3.js:826 :16 at map (<native code > ) at web3.js:825:12 at web3.js:4080:18