当前位置:   article > 正文

以太坊geth+web3.py在windows下实践教程与问题总结_valueerror: {'code': -32000, 'message': 'invalid s

valueerror: {'code': -32000, 'message': 'invalid sender'}

windows 应用以太坊Geth和Web3.py进行区块链仿真实验

基础实践教程与问题汇总
仅用于工业物联网的区块链安全解决方案研究!

0 Geth安装

这部分不再赘述。软件官网:https://geth.ethereum.org/downloads/
下载exe直接安装即可(允许改路径)

1. Geth 运行方法 & 多节点运行

写在前头,虽然 geth -help 会出现一堆的参数,但是这个真的要耐心看看

1.1 启动Geth步骤

1)初始化genesis.json文件(建立创世区块)
geth --datadir node1 init genesis.json
  • 1
2)开始运行区块链私链
geth --datadir node1 --networkid 1123  console 2>output.txt --port 30304 --http True --rpccorsdomain "*" --ws --allow-insecure-unlock --nodiscover
  • 1
  • 这里需要注意一下,网上很多的启动私链命令,可能会报错或者启动不成功
  • 原因在于 --http ,不知道是不是版本的问题,这里没有 --rpc 了!
3)一台电脑运行多个区块链节点
  • 这里需要说明一下,每个cmd窗口只能作为一个节点。因此想要运行多个私链节点,就要开启多个cmd窗口。
geth --datadir node2 --nodiscover --ipcdisable --networkid 1123  console 2>node2/output2.txt --port 30305 --authrpc.addr 127.0.1.1 --authrpc.port 8552
  • 1

以太坊客户端Geth命令用法-参数详解:https://learnblockchain.cn/2017/11/29/geth_cmd_options/

这里基本和上述启动私链的命令一样,但是需要注意以下几个问题

  • –networkid 需要和之前的节点一致
  • –port 端口不能和之前的一样
  • –authrpc.addr 地址不能和之前的一样
  • –authrpc.port 端口不能和之前的一样
4)多节点私链报错问题
这里只能做个说明。注意看报错信息。
尤其留意报错提示的 addr 或者port被占用问题。
这个时候就需要指定相应的类似:
--authrpc.addr 和 --authrpc.port 的参数了!
  • 1
  • 2
  • 3
  • 4

2. Web3.py 使用代码 & 问题汇总

2.1 判断连接Geth服务器

需要先运行geth 否则会连接失败

walet = Web3(HTTPProvider("http://localhost:8545"))  # 有疑问请看web3.py官网
if walet.eth.getBlock(0) is None:
     print("连接失败")
 elif walet.isConnected():
     print("连接成功")
  • 1
  • 2
  • 3
  • 4
  • 5

2.2 获取Geth上运行的账户相关信息

print('账户数量:', walet.eth.accounts, 'block数量:', walet.eth.block_number)
account = walet.eth.accounts[0]
balance = walet.eth.getBalance(account)
token = walet.fromWei(balance, 'ether')
print('账户余额:', balance, 'ether=', token)
print('当前chain id:', walet.eth.chainId)
block = walet.eth.get_block('latest')  ## 也可以获取指定序号的区块100
print('最新区块:', block)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2.3 使用web3发起交易

2.3.1 发起交易代码
 signed_txn = walet.eth.account.signTransaction(dict(
 	  nonce=walet.eth.getTransactionCount(walet.eth.coinbase),
      gasPrice=walet.toWei(50, "gwei"),  ##walet.eth.gasPrice,  ##
      gas=520000,
      to=walet.eth.accounts[0],
      value= walet.toWei(1, "ether"),  # 23,  ##
      data=str(dat),  ## 'biao9565',  #
      chainId=123
  ), accountA['private'])  #
  tx_hash = walet.eth.sendRawTransaction(signed_txn.rawTransaction)
 print('发送成功:', tx_hash.hex())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

注意这里的 accountA[‘private’],后面的私钥错误就是指这里。

2.3.2 交易报错问题汇总

注意翻译报错信息的英文, 以下的凭借调试过程的记忆记录

1)账户资金余额不足 (insufficient funds for gas)

ValueError: {'code': -32000, 'message': 'insufficient funds for gas * price + value'})

    1. Geth没有开启挖矿: miner.start()
    1. web3.py的账户里的公钥或者私钥不对。
    1. 交易中的gas和gasPrice设置过大,大于余额。(这种在私链里边一般不会存在问题,主要还是前两个原因)

人就在这第二条折腾了好久。一直在 1和3 之间尝试
如何获取私钥,请看本帖最后

2)gas太低 (intrinsic gas too low)

"intrinsic gas too low"

  • 这个是交易 signed_txn 中的gas或者gasPrice太低
3)需要授权 (authentication needed: password or unlock)

error: authentication needed: password or unlock

  • 这是使用 sendRawTransaction 特有的。因为需要离线签名,walet.eth.account.signTransaction函数必须输入 私钥 。
  • 值得注意的是:如果私钥是错误的,那么这个函数也是不会报错的。
4)其他错误 (already known 、replacement transaction underpriced)

"already known"
replacement transaction underpriced

  • 这个可能是因为(一个账户)交易发起太频繁,导致 nonce没有跟新。 建议在发起交易间设置间隔时间

解释起来就是:
上一个交易发起时(nonce=a),还没有被打包,也就是没有挖矿成功。这个时候还是:nonce=a 。
此时,又发起了一个交易,根据打码规则,还是 nonce=a,因此就会出现上述错误。

2.4 web3获取私钥

2.4.1 私钥文件说明
  • 在Geth创建账户时,会输入一个密码(例如:”biao“),然后创建成功后,Geth会输出一个类似 0x7146e96a50984e3b69b10b979d9a7088c6a96c20 的公钥地址。
  • 同时在 --datadir 目录下的 keystore文件夹中会得到一个文件。类似UTC--2022-07-31T03……--7146e96a50……(文件名省略了部分,注意是UTC开头)
  • 找到这个密码文件后,就可以开始解密出私钥了。
  • (这个密码文件可以用txt打开,但是里边的密码没有一个是私钥,需要使用专门的函数解密)
2.4.2 web3 获取账户私钥

这里可以参考这个网址:http://cw.hubwiz.com/card/c/web3.js-1.0/1/5/9/
具体代码如下:

with open('I:/Program Files/Geth/node1/keystore/UTC--2022-07-31T03-12-39.255879700Z--7146e96a50984e3b69b10b979d9a7088c6a96c20') as keyfile:
    encrypted_key = keyfile.read()
    private_key = w3.eth.account.decrypt(encrypted_key, 'biao')
print('private_key:', private_key.hex())
  • 1
  • 2
  • 3
  • 4
  • 从上面这个代码就可以获得私钥了。
  • 通过 .hex() 获取类似 '0x8a42a667344ea4b56aa57……'的十六进制数据(字符串)
  • 这个”十六进制数据“可以作为 walet.eth.account.signTransaction 的私钥输入。
2.4.3 私钥解密报错 & 问题汇总

这里应该没有什么错误,主要会出现下面这个:

1) MAC检查识别( MAC check failed)

ValueError: MAC check failed

  • 这里不要傻傻的以为是因为运行设备的MAC啥的不一样。其实这个保存就是你的密码 ‘biao’ 输错了。
  • 要是忘记了创建账户时输入的密码,那就重新创建吧!

3. web3.py 查看区块内容

block = walet.eth.get_block('latest')  ## 100
print('最新区块:', block)
  • 1
  • 2

4. web3.py 查找交易内容

tx = walet.eth.getTransaction(tx_hash)  # 获取交易信息
print('获取交易信息:', tx)
  • 1
  • 2

5. 本实验仿真文件已上传

资源地址:https://download.csdn.net/download/tjb132/86269764
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/55802
推荐阅读
相关标签
  

闽ICP备14008679号