登录
首页精彩阅读你的第一个智能合约「Hello World」,好像也不是很智能
你的第一个智能合约「Hello World」,好像也不是很智能
2018-03-30
收藏

你的第一个智能合约「Hello World」,好像也不是很智能

在看过 我花了 99 个以太坊(Ethereum)来学智能合约开发(http://davidfnck.com/blockchain/ethereum-smart-contract-intro.html/) 之后,相信你对以太坊的整体开发有了一个全局的概念。

开发环境

Solidity 选择

为了快速上手,我们用基于浏览器的方便版本来进行 Browser-Solidity(https://ethereum.github.io/browser-solidity)。

等练习之后,你想自己手动安装一个,可以参考这里 Solidity 安装指南(https://solidity.readthedocs.io/en/develop/installing-solidity.html),教程之后更新。

Geth 配置

Geth 是以太坊的客户端,之前文章  中介绍过。

我的用的 Macbook,之前也安装好了 Homebrew,所以装起来非常方便。

brew tap ethereum/ethereum
brew install ethereum

这样就算安装完成了,下面开始吧。

启动环境

利用 Geth 开始启动一个以太坊(开发者)网络节点:

geth --datadir testNet --dev console 2>> test.log

代码解读:

–dev 启用开发者网络(模式),开发者网络会使用POA共识,默认预分配一个开发者账户并且会自动开启挖矿。
–datadir 后面的参数是区块数据及秘钥存放目录。
testNet 第一次输入命令后,它会放在当前目录下新建一个testNet目录来存放数据。

console 进入控制台
2>> test.log 表示把控制台日志输出到test.log文件

执行完之后,就会进入到 Geth 控制台,这时候就像 Python 界面一样,有一个向右的小箭头,如下图:


这时候你可以看到,文件夹里面出现了这样的文件:

为了更好的理解,建议新开一个命令行终端,实时显示日志:

tail -f test.log

效果如下图:

准备账户

部署智能合约需要一个外部账户,我们先来看看分配的开发者账户,在控制台使用以下命令查看账户:

th.accounts

    也可以使用personal.listAccounts查看账户。
再来看一下账户里的余额,使用一下命令:
eth.getBalance(eth.accounts[0])
eth.accounts[0]表示账户列表第一个账户
回车后,可以看到大量的余额,如:
1.15792089237316195423570985008687907853269… e+77

开发者账户因余额太多,如果用这个账户来部署合约时会无法看到余额变化,为了更好的体验完整的过程,这里选择创建一个新的账户。

创建账户

创建账户
使用以下命令创建账户:

> personal.newAccount("davidfnck")
davidfnck 为新账户的密码,回车后,返回一个新账户。

这时我们查看账户列表:
> eth.accounts
可以看到账户数组你包含两个账户,新账户在第二个(索引为1)位置。
现在看看账户的余额:
> eth.getBalance(eth.accounts[1])
0

回车后,返回的是0,新账户是0。结果如:

给新账户转账

我们知道没有余额的账户是没法部署合约的,那我们就从默认账户转1以太币给新账户,使用以下命令(请使用你自己eth.accounts对应输出的账户):

eth.sendTransaction({
from:
'0x19c3a00836780bd96e787f92b0684beedcdbe216',
to:
'0xe837c346e8545907beae50a827b18734443ea685',
value:
web3.toWei(1, "ether")
})

在打开的tail -f test.log日志终端里,可以同时看到挖矿记录

再次查看新账户余额,可以新账户有1个以太币

解锁账户

在部署合约前需要先解锁账户(就像银行转账要输入密码一样),使用以下命令:

personal.unlockAccount
(eth.accounts[1],"davidfnck")
这一步很关键,如果你解锁,你是无法进行以下操作的,会得到这样的报错。
Error: authentication needed: password or unlock undefined

编写合约

现在我们来开始编写第一个智能合约代码,solidity代码如下:

pragma solidity ^0.4.21;
contract hello {
 string greeting;
        
 function hello(string _greeting) public {
  greeting = _greeting;
            
 }

  function say()
  constant public returns (string) {
                return greeting;
 }

}

简单解释下,我们定义了一个名为hello的合约,在合约初始化时保存了一个字符串(我们会传入hello world),每次调用say返回字符串。

把这段代码复制到 Browser-Solidity,如果没有错误,点击Details获取部署代码,如下图:

在弹出的对话框中找到WEB3DEPLOY部分,点拷贝,粘贴到编辑器后,修改初始化字符串为hello world。

部署合约

代码如下:

var _greeting = "Hello World" ;
var helloContract = web3.eth.contract([
{"constant":true,"inputs":[],"name":"say",
"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[1],
 data: '
 0x6060604052341561000f57600080fd5b604051610
 2b83803806102b88339810160405280805182019190
 5050806000908051906020019061004192919061004
 8565b50506100ed565b828054600181600116156101
 000203166002900490600052602060002090601f016
 020900481019282601f1061008957805160ff191683
 80011785556100b7565b82800160010185558215610
 0b7579182015b828111156100b65782518255916020
 0191906001019061009b565b5b5090506100c491906
 100c8565b5090565b6100ea91905b808211156100e6
 5760008160009055506001016100ce565b5090565b9
 0565b6101bc806100fc6000396000f3006060604052
 60043610610041576000357c0100000000000000000
 0000000000000000000000000000000000000009004
 63ffffffff168063954ab4b214610046575b600080f
 d5b341561005157600080fd5b6100596100d4565b60
 4051808060200182810382528381815181526020019
 1508051906020019080838360005b83811015610099
 57808201518184015260208101905061007e565b505
 05050905090810190601f1680156100c65780820380
 516001836020036101000a031916815260200191505
 b509250505060405180910390f35b6100dc61017c56
 5b60008054600181600116156101000203166002900
 480601f016020809104026020016040519081016040
 5280929190818152602001828054600181600116156
 101000203166002900480156101725780601f106101
 4757610100808354040283529160200191610172565
 b820191906000526020600020905b81548152906001
 019060200180831161015557829003601f168201915
 b5050505050905090565b6020604051908101604052
 806000815250905600a165627a7a72305820df2cce8
 777859296a1396a055f4c0801a5ec58702c4b96d3f3
 ccba1f6a752f340029',
 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行:修改字符串为Hello World
第2行:修改合约变量名
第3行:修改合约实例变量名,之后可以直接用实例调用函数。
第6行:修改部署账户为新账户索引,即使用新账户来部署合约。
第8行:准备付的gas费用,IDE已经帮我们预估好了。
第9行:设置部署回调函数。

将该代码直接拷贝到 Geth 控制台的小箭头后面,回车后,就会看到输出:

说明合约已经部署成功。

现在我们查看下新账户的余额:

> eth.getBalance(eth.accounts[1])
999999999999793757
比之前的少了。
运行合约
> hello.say()
"Hello World"

输出Hello World,我们第一个合约Hello World,成功运行了。

到此为止,你的第一个智能合约就完成了,是不是很简单,确实好像也没多智能,比其他的好像还要复杂,不过确实能够帮助你来了解一下整个的开发过程了。

如何掌握区块链技术

区块链创新的推动以及数字经济的蓬勃发展离不开人才的培育,而CDA数据分析师作为行业的领头羊,紧密结合当前区块链发展实际与人才需求结构,重磅推出CDA区块链学院。

扫描二维码,进入 CDA 区块链学院,学习区块链知识,选择很多,站对未来

数据分析咨询请扫描二维码

客服在线
立即咨询