区块链基础 - 以太坊

1、搭建私链,能够挖矿。

创世区块

# geth  --datadir /data/eth init genesis.json 
genesis.json 
{
  "config": {
        "chainId": 11,  #公共预测试发布网络
        "homesteadBlock": 0, #Homestead  硬分叉区块高度,填写官网的默认值即可,后续硬分叉时才需要调整
        "eip150Block": 0,  
        "eip155Block": 0, #EIP 155 硬分叉高度,填写官网的默认值即可,后续硬分叉时才需要调整 
        "eip158Block": 0 #EIP 158 硬分叉高度,填写官网的默认值即可,后续硬分叉时才需要调整 
    },
  "alloc"      : {}, #预设账号以及账号的以太币数量,私有链挖矿比较容易可以不配置
  "coinbase"   : "0x0000000000000000000000000000000000000000", #矿工账号
  "difficulty" : "0x20000", # 难度值,越大越难
  "extraData"  : "", # 附加信息,以0x开头填写,可以不填
  "gasLimit"   : "0x2fefd8", # gas 的消耗总量限制,用来限制区块能包含的交易信息总和,因为我们是私有链,所以填的很大
  "nonce"      : "0x0000000000000042", # 64 位随机数,默认即可
  "mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000", #与 nonce 配合用于挖矿,由上一个区块的一部分生成的 hash,默认即可。因为是第一个区块,因此,默认就是0了。
  "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", #上一个区块的 hash 值,默认即可。因为是第一个区块,因此,默认就是0了。
  "timestamp"  : "0x00"
}

启动geth

geth \
--nodiscover \
--maxpeers 300 \
--identity "rh_test" \
--rpc --rpccorsdomain "*" --rpcport 8545 \
--datadir "/data/eth" \
--port "30303" \
--allow-insecure-unlock \
--rpcapi "eth,net,web3,personal" \
--networkid 11 \
--cache 512 \
--verbosity 4 \
--shh

nodiscover  关闭节点自动发现
maxpeers  最大节点连接数
identity  设置节点名称
rpc组  --rpc --rpccorsdomain "" --rpcport 8545,这是一组参数,rpc端口默认就是8545,访问域如果写的话代表是任何域名都可以访问,也可以指定特殊的域名访问。
datadir geth安装的目录,这个与初始化时候的路径一样即可
port  geth节点的端口,默认也是30303
rpcapi  允许rpc接入的方式
networkid 网络id,该值与创世纪区块中的chainId一致即可,否则就会连到别人的服务上去了
cache 调整内存分配 最小16MB,默认128MB
verbosity 日志等级:0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail (default: 3)

进入控制台

geth attach ipc:/data/eth/geth.ipc
> eth.getBlock(0)
{
  difficulty: 131072,
  extraData: "0x",
  gasLimit: 3141592,
  gasUsed: 0,
  hash: "0x5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0x0000000000000000000000000000000000000000",
  mixHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
  nonce: "0x0000000000000042",
  number: 0,
  parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
  receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 507,
  stateRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  timestamp: 0,
  totalDifficulty: 131072,
  transactions: [],
  transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  uncles: []
}

difficulty  挖矿难度,这里转化为 10 进制,等于”0x2000”,后面区块难度会随着区块高度升高而提高
extraData 当前区块附加信息,若创世区      块该值为空,在第二个区块中会保存,创建该私有链时的 geth,go,及操作系统版本,保存信息为第一个挖到该区块的矿工信息,例如:0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421
gasLimit  十进制的 gasLimit 值,会随之区块高度提高而提高
gasUsed gas 花费,在以太坊中交易和部署智能合约会消耗 gas,暂时可以理解为以太币
hash  当前区块hash值
logsBloom 保存当前区块日志
miner 挖到该区块的矿工地址,当前尚未分配矿工,因此,无挖矿矿工信息
mixHash 与 nonce 配合用于挖矿,由上一个区块的一部分生成的 hash
nonce 工作量证明的随机数,因为是第一块,这个是由我们人工创建的
number  当前区块高度
parentHash  上一个区块 hash 值
receiptsRoot  块的收益树根结果
sha3Uncles  对树区块进行 hash 运算的结果
size  区块大小,以字节为单位
stateRoot 块的状态树根结果
timestamp 时间戳
totalDifficulty 达到该区块的难度总数
transactions  以数组的形式保存交易的 tx 值
transactionsRoot  交易的默克尔树根
uncles  以数组表示数区块的哈希
查看账户
> eth.accounts
创建账户
> personal.newAccount()
查看余额
> web3.fromWei(eth.getBalance(eth.accounts[0]),'ether')

2、掌握节点api。怎么查询最新高度,区块详情,交易详情。

查询最新高度
curl -s -X POST -H "Content-Type":application/json --data '{"jsonrpc":"2.0", "method":"eth_blockNumber","params":[],"id":67}'  localhost:8545
查询区块详情
curl -s -X POST -H "Content-Type":application/json --data '{"jsonrpc":"2.0","method":"eth_getBlockByHash","params":["0x5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0", false],"id":1}'  localhost:8545
查询交易详情
 curl -s -X POST -H "Content-Type":application/json --data '{"jsonrpc":"2.0","method":"eth_getTransactionByHash","params":["0x377373a7056a25a10e7d747adede9f51bdb7dd101de515953f4a56ef9488a3e9"],"id":1}'  localhost:8545
解锁账户
> personal.unlockAccount(eth.accounts[0])
Unlock account 0xcb49271b7d64de18053c79708fdd45565a8515ed
Passphrase: 
true
发起交易
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei("0.1", "ether")})
> web3.fromWei(eth.getBalance(eth.accounts[1]),'ether')
0
> miner.start()
null
> miner.stop()
null
> eth.getBalance(eth.accounts[1])
100000000000000000
> 

3、使用节点工具完成生成地址和转账

# geth account new
创建账户
> personal.newAccount()
解锁账户
> personal.unlockAccount(eth.accounts[0])
Unlock account 0xcb49271b7d64de18053c79708fdd45565a8515ed
Passphrase: 
true
发起交易
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei("0.1", "ether")})
> web3.fromWei(eth.getBalance(eth.accounts[1]),'ether')
0
> miner.start()
null
> miner.stop()
null
> eth.getBalance(eth.accounts[1])
100000000000000000
> 

4. 判断eth交易是否成功

transactionHash: DATA, 32字节 - 交易哈希
transactionIndex: QUANTITY - 交易在块内的索引序号
blockHash: DATA, 32字节 - 交易所在块的哈希
blockNumber: QUANTITY - 交易所在块的编号
from: DATA, 20字节 - 交易发送方地址
to: DATA, 20字节 - 交易接收方地址,对于合约创建交易该值为null
cumulativeGasUsed: QUANTITY - 交易所在块消耗的gas总量
gasUsed: QUANTITY - 该次交易消耗的gas用量
contractAddress: DATA, 20字节 - 对于合约创建交易,该值为新创建的合约地址,否则为null
logs: Array - 本次交易生成的日志对象数组
logsBloom: DATA, 256字节 - bloom过滤器,轻客户端用来快速提取相关日志

5、使用任何编程语言,完成生成地址、构造交易、离线签名、广播并上链。不准使用钱包功能。

from web3 import Web3
w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545'))
#
# print(w3.geth.shh.new_key_pair())
# new_account = w3.eth.account.create()
# print(new_account.privateKey)
# print(new_account.address)
key_file = "/data/eth/keystore/UTC--2020-10-08T04-03-04.009027274Z--cb49271b7d64de18053c79708fdd45565a8515ed"
with open(key_file) as keyfile:
    encrypted_key = keyfile.read()
    private_key = w3.eth.account.decrypt(encrypted_key,'12345')
    print(private_key)
signed_txn = w3.eth.account.signTransaction(dict(
    nonce=w3.eth.getTransactionCount(w3.eth.coinbase),
    gasPrice=w3.eth.gasPrice,
    gas=100000,
    to='0xaC6D80856Dc3e8abe7DEafa46703DEb89c019517',
    value=1000000000000000000,
    data=b'',
  ),
  b'\x97\xf5@\xa8\xce\x1c\xc5\x8a\xcbt\x82,b\xa3\xccj\xe26\xcb$\xb1\xc5y\x91\xfb\xaf^X\xae\x7f:\xe3',
)
res = w3.eth.sendRawTransaction(signed_txn.rawTransaction)
print(res.hex())
print(w3.eth.getTransactionReceipt("0x904b4e5337f396bdcf34528a92cc17dd7ae82bcbbba0948bf01e28b62481568f"))

 

posted @ 2020-10-27 17:01  Redheat  阅读(428)  评论(0编辑  收藏  举报