从看雪论坛换了一本《智能合约安全分析和审计指南》,看了一些智能合约相关的内容,因为我之前对于区块链的了解仅仅是只知道世界上有一种叫做比特币的东西,所以对于这些概念的理解还是比较困难的
了解一下区块链是什么东西:
https://ethfans.org/posts/wtf-is-the-blockchain
了解一下以太坊以及智能合约等:
https://ethfans.org/posts/gentle-introduction-ethereum-new-version-with-more-note
geth的操作及相关说明
geth 安装的话,下载直接安装就好了
这里提供一个曲奇云盘的链接:
https://quqi.com/s/3109432/69adjDfUW6UFX5cU
安装好以后在文件目录下打开cmd操作
连接至网络
使用这条命令主网
geth --datadir ./ethdev/chain --networkid 1
搭建私有链
把之前生成的那个 chaindata 删掉,然后在 ethdev 目录下创建一个 genesis.json
代码语言:javascript复制{"config":{ "chainId":2, "homesteadBlock":0, "eip150Block":0, "eip155Block":0, "eip158Block":0 }, "coinbase":"0x0000000000000000000000000000000000000000", "difficulty":"0x40000", "extraDate":"", "gasLimit":"0xffffffff", "nonce":"0x0000000000000042", "mixhash":"0x0000000000000000000000000000000000000000000000000000000000000000", "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000", "timestamp":"0x00", "alloc":{}}
然后使用
代码语言:javascript复制geth init ./ethdev/genesis.json --datadir ./ethdev/chain
生成创世块,现在网络就部署好了,但是还没有区块和账户
运行命令:
代码语言:javascript复制geth --datadir ./ethdev/chain/00 --nodiscover console 2>>./ethdev/chain/00/eth_output.log
实际上上面这条命令的完整形式是这样的:
代码语言:javascript复制geth --identity chainpi --rpc --rpcport 8080 --rpccorsdomain "*" --datadir ./ethdev/chain/00/ --port 30303 --nodiscover --rpcapi "db,eth,net,web3" --networkid 555 console 2>>./ethdev/chain/00/eth_output.log --allow-insecure-unlock
参数介绍:
代码语言:javascript复制--identity 给以太坊节点设置身份--rpc 启动 RPC(Remote Procedure Call,远程过程调用)通信,进行智能合约的部署和调试。不同的 RPC 设置,可以供 API 及远程访问他们的人使用--datadir 与初始化测试使用同一目录--port 网络监听端口,设置端口是为了防止在多条链之间发生端口冲突--nodiscover 表示该节点对外不可见--networkid 是一个数字,表示设置当前区块链的网络 ID,以区分不同的网络,第一次可以随意设置,但之后如果要链接同一条链,需要去取对应的 networkid(主网 ID 为 1,主网的测试网络 ID 为 2)--rpcapi "db,eth,net,web3" 这条命令主要是描述哪些接口可以通过 RPC 来访问,在默认情况下,geth 开启的是 web3 接口--dev 启用开发者网络(模式)开发者模式会使用 POA 共识,默认预分配一个开发者账户,并会自动开启挖矿--allow-insecure-unlock 是新版的 geth 禁用了 HTTP 通道解锁账户,加上这个东西就可以 unlock 了
控制台是一个交互的 javascript 执行环境,这个环境内置了一些用于操作以太坊的 JavaScript 对象
常见操作
eth.accounts 查看现有账户
personal.newAccount() 创建账户,括号里面可以填写密码,第一个创建的账户用户名默认 coinbase
账户数据保存在区块目录下的 keystore 文件夹里面
eth.coinbase(好像返回的是 hash)
eth.getBalance(eth.coinbase) 查看 coinbase 账户的余额
miner.start() 开始挖矿,挖到的以太币归默认 eth.accounts[0] 即 coinbase 所有,在测试网络里面,把 genesis.json 中的 difficulty 的值设置的小一点会更容易挖到以太币
eth.blockNumber 查看当前区块数(一开始显示为零,等会就有了)
miner.stop() 停止挖矿
eth.getBalance(eth.coinbase) 查看 coinbase 当前的余额
web3.fromWei(eth.getBalance(eth.coinbase),"ether") 以以太币的形式显示余额
u0=eth.coinbase 重命名账户
下面我们在创建几个账户,来试一下转账
personal.newAccount()
personal.newAccount()
u1=eth.accounts[1]
u2=eth.accounts[2]
开始交易
从 u0 转 100 个以太币给 u1,报错了,原因是 coinbase 未解锁
代码语言:javascript复制eth.sendTransaction({from:u0,to:u1,value:web3.toWei(100,'ether')})
代码语言:javascript复制personal.unlockAccount(u0,'123456')
解锁 u0 后面跟的 123456 是密码,解锁后就交易成功了
再给 u2 转 100 个
代码语言:javascript复制eth.sendTransaction({from:u0,to:u2,value:web3.toWei(100,'ether')})
交易完成之后并没有变化,使用 txpool.status
看一下
pending 为 2 表示有两笔交易已经提交,但未被处理,因为刚刚的交易还没有被写进区块,而将交易写进区块的办法是挖矿⛏
我们可以通过交易的散列值来查看之前达成的一笔交易
看一下对应的区块 eth.getBlock(209)
账户与密钥
账户在以太坊中扮演着重要的角色,以太坊有两种账户类型,分别是外部账户和合约账户。在这里,外部账户简称为账户,合约账户简称为合约,外部账户和合约账户都是账户的通用概念,这些账户其实都是状态对象
外部账户的余额,就是外部账户的一个状态对象;合约账户的状态,除了余额,还有存储合约。所有账户的状态都是以太坊网络的状态,以太坊网络的状态随着每一个区块的更新而变化
如果对以太坊网络加以限制,使其中只有外部账户且这些账户只能进行交易,就相当于生成了一种只能交易以太币的“山寨币”
账户是使用者对外的身份。在使用公钥对一笔交易进行签名后,以太坊虚拟机就可以安全地对这笔交易的发起者进行身份验证
每个账户都对应一对密钥,一个私玥和一个公玥
账户和地址是一一对应的,账户索引来自密钥的最后20字节
每一个私钥-地址都被编码到一个与密钥文件里面,密钥文件大小是一个 JSON 格式的文本文件
密钥文件的重要组成部分,即账户的私钥,是通过创建账户时输入的密码加密保护的
密钥文件存储在以太坊客户端的 keystore 的目录中,要定期备份
搭建私有链多节点
net 查看网络状态
net. 然后 tab 键有命令补全提示
net.listening 查看网络是否处于监听状态
net.peerCount 查看已连接的结点的数量
admin 查看网络
admin. 查看 admin 可以进行哪些操作
书上不详细,差评,参考:
https://blog.csdn.net/hantangduhey/article/details/81017602
新开一个节点,这里我又设置了一下,把这些节点移动到了 chain 下面
代码语言:javascript复制geth init ./ethdev/genesis.json --datadir ./ethdev/chain/01
进入另一个的控制台:
代码语言:javascript复制geth --identity chainpi --rpc --rpcport 8081 --rpccorsdomain "*" --datadir ./ethdev/chain/01 --port 30304 --nodiscover --rpcapi "db,eth,net,web3" --networkid 555 console 2>>./ethdev/chain/01/eth_output.log --allow-insecure-unlock --ipcdisable
win 下面好像不加后面的参数 --ipcdisable
不能多开 geth
进入另一个节点一的控制台(就是之前一直用的那个控制台)运行如下命令,与节点二连接
代码语言:javascript复制admin.addPeer("enode://928acba0da90d952b3802f7ddab2a99d29164934c407b56f8c47ed52d44e843314457a40e9ff1dd5d2da632b5be6f8d346fddac35b9f2755650a17ed78a2e139@127.0.0.1:30304")
连接成功之后,节点二就会开始同步节点一的区块。同步完成之后只要任意节点开始挖矿,另一节点就会自动同步区块,向任意一个节点发送交易,另一个节点也会收到该交易的信息,书上说的,我这里不会显示
使用 net.peerCount
可以看一下已连接的节点数
当然,除了在控制台用命令添加,也可以在 --datadir 指定的目录里面添加 static-nodes.json 文件,让各个节点取得联系,具体如下:
代码语言:javascript复制{ "enode://xxxxxxxx" //boot node 的地址}
抄书了
Ethereum Wallet
Ethereum Wallet 软件去这里下载:
https://github.com/ethereum/mist/releases
我新版打不开,老的版本可以,曲奇云盘:
https://quqi.com/s/3109432/mlDb0HRmwRSGL871
下下来直接解压出来:先 cmd 中启动节点,然后再打开这个
第一次运行要等一阵,我去吃了个饭,也不知道要具体等多长时间,弹这个下载的框直接关掉就行
然后就这样了
出现这个的时候,点运行就可以
主界面!
实现多重签名
多重签名是指需要多个人同意,交易才能生效。好处是当要从账户里提取较大额度的以太币时,需要多个账户共同认证才能成功提取,因此创建一个多重签名的钱包需要至少创建两个账户
另外,要想主账户添加不少于 0.02 个以太币(用于创建多重签名钱包的账户),这是创建多重签名钱包合约的交易费用,另外至少需要 1 个以太币,因为当前 Mist 需要足够的 gas 来确保多重签名合约能够正确地执行交易,所以一开始主账户里面至少要有 1.02 个以太币
随便点一个
选择右边的 copy address
把那俩的地址都保存出来:
0xE2fA80E6D74b9f63157EcD131Eb11F8130D0416D
0x27EdE661c026b64DdEF9d9D965d710af40afaea0
点击 Wallet Contracts
设置一下
然后创建
然后可以自己设置一下最高交易费用,输入密码就可以了
只有在挖矿状态下才能将合约打包到区块中
使用我们自己的账户,给刚才创建的钱包转个帐
如果转账的金币不够的话就会有提示
正常的话就正常转账