狼爱上狸

我胡汉三又回来了

Ubuntu下geth搭建私有链+部署智能合约+与合约交互笔记

最近在学习以太坊,就把一点学习笔记记录分享下来,希望对刚入门跟我一样迷茫的人有点帮助。
首先,所有需要用到的指令都在https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console ,多记住一些方法方便使用
第一步:按照官方文档,安装好Geth客户端(https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum),这个比较简单。
第二步:搭建自己的私有链
搭建私有链之前应该准备的东西:

    Custom Genesis File
    Custom Data Directory
    Custom NetworkID
    (Recommended) Disable Node Discovery


Genesis file: 创世区块是所有区块的根,区块链开始的地方--第一块、区块0、以及仅有的一块没有父区块的区块。协议保证了不会有其他节点根你的版本的区块链达成一致,除非他们跟你有相同的创世区块,因此,只要你想,你就可以创建任意多个私有测试区块链。
CustomGenesis.json
{
"nonce": "0x0000000000000042", "timestamp": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x0", "gasLimit": "0x8000000", "difficulty": "0x400",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x3333333333333333333333333333333333333333", "alloc": { }
}
稍后你将会用到这个文件:geth init /path/to/CustomGenesis.json

用于私有网络的命令行参数
--nodiscover 使用这个参数,你的节点就不会被其他人发现,除非手动添加你的节点。否则,就只有一个被无意添加到一个陌生区块链上的机会,那就是跟你有相同的genesis文件和networkID。
--maxpeers 0 如果你不想有人连上你的测试链,就用maxpeers 0。或者,你可以调整参数,当你确切的知道有几个节点要连接上来的时候。
--rpc 允许RPC操作你的节点。这个参数在Geth上是默认的。
--rpcapi "db,eth,net,web3" 这个命令指示了允许通过RPC访问的命令。默认情况下,Geth允许web3。
--rpcport "8080"
--rpccorsdomain "http://chriseth.github.io/browser-solidity/"
--datadir "/home/TestChain1" 私有链存放路径(最好跟公有链路径不同)
--port "30303" 网络监听端口,用来和其他节点手动连接
--identity “TestnetMainNode" 用来标识你的节点的,方便在一大群节点中识别出自己的节点

了解完上面这几个内容之后,就可以开始搭建自己的私有链了,用如下命令:
geth --identity "MyNodeName" --rpc --rpcport "8080" --rpccorsdomain "*" --datadir "/home/to/TestCahin1" --port "30303" --nodiscover --rpcapi "db,eth,net,web3" --networkid 1999 init /path/to/CustomGenesis.json
上面这条命令就初始化了创世区块,存放区块链数据的路径"/home/to/TestCahin1"根据自己需要修改一下。/path/to/CustomGenesis.json为存放CustomGenesis.json的地方。下面进入geth客户端:
geth --identity "MyNodeName" --rpc --rpcport "8080" --rpccorsdomain "*" --datadir "/home/to/TestCahin1" --port "30303" --nodiscover --rpcapi "db,eth,net,web3" --networkid 1999 console
现在就进入到了自己的私有链中,启动成功之后会显示如下图:
我的就存放在自己用户目录下的etherTest目录下。如果觉得每次进入客户端时要写这么一大堆指令很麻烦,完全可以把它写到一个文件中,给文件赋予可执行权限,就不必这么麻烦了。例如,我把这个指令写在了gethLaunch文件下:
#!/bin/bash
geth --identity "asurily" --rpc --rpcport "8080" --rpccorsdomain "*" --datadir ~/etherTest --port "30303" --nodiscover --rpcapi "db,eth,net,web3" --networkid 1999 console
然后执行chmod +x gethLaunch
这样我就不必每次都都输入那么一长串了,直接输入gethLaunch就可以了。

第三步、创建与部署智能合约
1、首先得有一个有ether的账户
私有链中,ether很容易获得。用personal.newAccount("111")创建一个账户,111为密码。然后可以用eth.accounts查看所有的账户。
可以看见我创建成功,并且查看了有几个账户。
以太坊中默认第一个地址为今后的挖矿分配奖金的地址,当然可以修改这个地址。miner.setEtherbase(eth.accounts[1])进行地址更换;
刚创建的账户中余额为0,可以用eth.getBalance("0xa65bf431f4f07a22296dc93a7e6f4fe57642bee6")查看余额。如果是第一个地址,启用挖矿miner.start(),稍等一下就能有余额了。
如果你不想进行挖矿,也有一个方法获得ether,就是在CustomGenesis.jso文件中加入
"alloc":
{
"<your account address e.g. 0x1fb891f92eb557f4d688463d0d7c560552263b5a>":
{ "balance": "20000000000000000000" }
}
然后再重新初始化,就能在你的账户中出现20个ether。

2、创建和部署智能合约
我就是部署的官网上的示例。
1)编写智能合约源代码:source = "contract test { function multiply(uint a) returns(uint d) { return a * 7; } }"
2)编译:contract = eth.compile.solidity(source).test。本来编译之后得到的是一个map类型,test就是那个key,所以这样就能得到相应的对象了。
保存下其中的code和abiDefinition,后面会用上:
code = contract.code
abi = contract.info.abiDefinition
3)创建智能合约对象:MyContract = eth.contract(abi)。
4)部署合约。部署合约就是向以太坊上发送一个交易,目的地址不写就是发送给区块链。
contract = MyContract.new(arg1, arg2, ..., {from: primaryAddress, data: evmByteCodeFromPreviousSection})
例如:contract = MyContract.new({from:eth.accounts[0],data:code})
此时,可能会提示你账户不可用,就是没有解锁,用personal.unlockAccount()解锁即可。然后在部署,会得到如下所示:
如上所示,此时的地址是undefined,因为交易才发送出去,没有矿工挖矿,没有写进区块链,所以还不知道。现在可以用txpool.status查看到
启动挖矿,把交易写进区块链。miner.start(),然后关闭挖矿miner.stop()
挖矿之后,交易就写进区块链了。此时再查看contract就能看见有地址了:
至此,合约成功部署在了以太坊上。

5)与合约交互
我们把合约部署到以太坊上不是目的,目的是能与部署在以太坊上的合约进行交互。
与合约交互要用到两个东西,abi和address。abi(应用程序二进制接口)用来创建合约对象;合约地址address用来定位在以太坊上的那个地址的合约。
创建合约对象:Multiply7 = eth.contract(abi);
定位在addres处的那个合约:myMultiply7 = Multiply7.at(address)
调用合约中的方法,应该有两种方式进行调用,一是call(),它直接返回结果,不会写进区块链;二是sendTransaction(),它是一笔交易,会写到区块链中,返回值是交易的哈希值。
成功得到结果。

第四步、再次调用部署好的合约
之前一直没有弄明白,既然合约都已经部署好了在区块链上,那么下次肯定还会再次调用它,但是我一直都不知道怎么调用它。虽然现在也不怎么明白,好像有register之类的方法,还没完全弄清楚。现在我的笨方法就是保存下来合约地址根合约的abi。既然调用合约时的两个重要步骤就是用abi创建合约对象和定位区块链中合约,所以就保存下来abi和address。
退出私有链,然后重新进入,那么之前所有的变量都不存在了。
记录abi:
记录地址:
然后就能成功调用address处的合约了。


方法特别笨,手动保存了abi和address,肯定还有别的方法,再接再厉。
---------------------
作者:yooliee
来源:CSDN
原文:https://blog.csdn.net/yooliee/article/details/72818932
版权声明:本文为博主原创文章,转载请附上博文链接!

posted on 2019-05-10 10:39 狼爱上狸 阅读(752) 评论(0)  编辑  收藏 所属分类: LINUX


只有注册用户登录后才能发表评论。


网站导航: