python 之 web3 与智能合约的交互、编译等使用

2023-11-16

一、背景

web3.py是一个用于与以太坊交互的 Python 库。
它常见于去中心化应用程序 (dapps)中,帮助发送交易、与智能合约交互、读取块数据以及各种其他用例。
最初的 API 源自Web3.js Javascript API,但后来不断发展以满足 Python 开发人员的需求和物质享受。

本人在合约审计于模糊测试中需要验证一些基础信息,学习了一下

pip install web3

web3开发文档 https://web3py.readthedocs.io/en/stable/

二、基础应用

  • 连接到以太坊测试节点
    from web3 import Web3
    from web3 import EthereumTesterProvider # 以太网测试程序提供程序
    
    创建区块链链接器 链接到测试节点
    w3 = Web3(EthereumTesterProvider())
    建立web3链接
    w3.is_connected()
    
  • 使用HTTPProvider和web3连接eth节点
    provider_url = 'https://mainnet.infura.io/v3/3c3793ddeca**********299afb1c2dc6458'
    w3 = Web3(Web3.HTTPProvider(provider_url))
    w3.is_connected()
    
  • 获取最新的块信息
    latest_block = w3.eth.get_block('latest')
    
  • 验证智能合约地址是否有效
    is_addr = w3.is_address('0x314ECf414b0987EAf8A3504915******91d24')
    
  • 获取钱包余额有多少eth
    wallet = w3.to_checksum_address('0x314ECf414b0987EAf8A3504915d*****1d24')
    print(w3.eth.get_balance(wallet))
    
  • 将wei转化成eth (wei 是eth最小单位)
    wei = w3.from_wei(111111111111111111111, 'ether')
    print(wei)
    

三、区块链合约交互

  • ABI 包含输入函数名称变量
    ABI 对于每个智能合约都是唯一的,除非代码完全一样 abi = '[]'
    
    abi = '[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]'
    contract_address = '0xda141e275f46F9Df74b29AA3eCf7fF77Bc6781AB'
    
  • 调用合同函数或访问合同变量

    例如: contract_instance.functions.someFunction().call()
    
    contract_instance = w3.eth.contract(address=contract_address, abi=abi)
    result = contract_instance.functions.totalSupply().call()
    result = contract_instance.functions.symbol().call()
    print(result)
    

四、智能合约的编译

from solcx import compile_source, compile_standard

# 指定安装某个版本编译器
# install_solc(version='latest')

# 编译合约代码 输出abi、bin 字节码
compile_solidity = compile_source(
    '''
    // SPDX-License-Identifier: GPL-3.0
    pragma solidity ^0.8.18;
    contract HelloWorld {
        string public message;
        constructor(){
            message = 'HelloWorld!';
        }
        function setMessage(string memory _message) public{
            message = _message;
        }
        function sayMessage() public view returns (string memory) {
            return message;
        }
    }
    ''',
    output_values=['abi', 'bin']
)

# 检索合约接口 compile_solidity.popitem()
contract_id, contract_interface = compile_solidity.popitem()
# print(contract_id)                # 合约name
# print(contract_interface)         # 合约abi、bin
# print(contract_interface['abi'])  # 合约abi

python 与eth智能合约进行交互

# 创建连接到以太坊测试器的Web3实例
w3 = Web3(Web3.EthereumTesterProvider())
# w3 = Web3(Web3.WebsocketProvider)

# 设置默认账户为测试器中的第一个账户
# w3.eth.accounts 是以太坊测试器中已创建的账户列表。通过 w3.eth.default_account = w3.eth.accounts[0],将默认账户设置为测试器中的第一个账户。
# 这意味着当您发送交易或调用合约函数时,如果没有显式指定账户,将默认使用 w3.eth.accounts[0] 作为交易的发送者

w3.eth.default_account = w3.eth.accounts[0]

# 合约的ABI和字节码
abi = contract_interface['abi']
bytecode = contract_interface['bin']

# 创建合约实例
helloworld = w3.eth.contract(abi=abi, bytecode=bytecode)

# 发送合约构造函数的交易
transaction_hash = helloworld.constructor().transact()
# print(transaction_hash)

# 等待交易收据
transaction_receipt = w3.eth.wait_for_transaction_receipt(transaction_hash=transaction_hash)
# print(transaction_receipt)
'''
blockHash: 交易所在区块的哈希值。
blockNumber: 交易所在区块的编号。
contractAddress: 如果交易创建了一个新的合约,该参数表示新合约的地址。如果交易不是创建合约的交易,则为一个空字符串。
cumulativeGasUsed: 该交易之前所有交易的累计消耗的燃气量。
effectiveGasPrice: 交易的有效燃气价格。
from: 发送者(发送交易的账户地址)。
gasUsed: 该交易消耗的燃气量。
logs: 交易产生的日志事件。
state_root: 交易执行后的状态树根哈希。
status: 交易的执行状态,1表示成功,0表示失败。
to: 交易的接收者地址。如果是创建合约的交易,则为一个空字符串。
transactionHash: 交易的哈希值。
transactionIndex: 交易在所在区块的索引位置
# type: 交易类型1表示普通交易,2表示合约创建交易
'''
# # 获取合约对象
# helloworldContract = w3.eth.contract(address=transaction_receipt.contractAddress, abi=abi)
# print(helloworldContract) # 获取合约对象
# # 调用合约中函数sayMessage
# print(helloworldContract.functions.sayMessage().call())
# # 调用合约中函数setMessage,修改一个值,下面获取并没有变化,需要我们重新部署,发起交易
# print(helloworldContract.functions.setMessage('BEY').call())
# # 发现并没有变化
# print(helloworldContract.functions.sayMessage().call())
# # 重新调用合约构造函数的交易
# bye_hash = helloworldContract.functions.setMessage('BEY').transact()
# print(bye_hash)
# # 等待交易收据
# bye_receipt = w3.eth.wait_for_transaction_receipt(transaction_hash=bye_hash)
# print(bye_receipt)
# # 重新构造以后才会修改为bye
# print(helloworldContract.functions.sayMessage().call())
# # print(is_addr)

python 编译智能合约

compiled_solidity = compile_standard({
    "language": "Solidity",
    "sources": {
        "SimpleNumber.sol": {
            # "content": contract_file
        }
    },
    "setting": {
        "outputSelection": {
            "*": {"*": ["abi", "metadata", "evm.bytecode", "evm.sourceMap"]}
        }
    }
},
    solc_version='0.8.12'
)

print(compiled_solidity)

# compiled_solidity: 编译后的Solidity结合的结果
# language: Solidity合约的编程语言,这里是"Solidity"
# sources: Solidity源代码文件的字典,这里只有一个源代码文件"SimpleNumber.sol"
# setting: 编辑设置的字典,包选择输出
# outputSelection: 输入选的字典,选包包括ABI、元数据、EVM字节码和EVM源映像
# solc_version: Solidity编译器的版本,这里是"0.8.12"

使用python 部署智能合约

provider_url = 'https://goerli.infura.io/v3/3c3793ddeca5********fb1c2dc6458'
w3 = Web3(Web3.HTTPProvider(provider_url))
w3.is_connected()

abi = compiled_solidity['contracts']['SimpleNumber.sol']['SimpleNumber']['abi']
bytecode = compiled_solidity['contracts']['SimpleNumber.sol']['SimpleNumber']['evm']['bytecode']['object']

SimpleNumber = w3.eth.contract(abi=abi, bytecode=bytecode)
transaction = SimpleNumber.constructor().build_transaction(
    {
        "gasPrice": w3.eth.gas_price,
        "chainId": 3,
        "from": "wallet 钱包地址 来自metamask账户",
        "nonce": w3.eth.get_block_transaction_count("wallet 钱包地址 来自metamask账户")

    }
)

metamask 添加网络 eth 测试网络

sign_transaction = w3.eth.account.sign_transaction(transaction, private_key='私钥')
print(sign_transaction)
transaction_hash = w3.eth.send_raw_transaction(sign_transaction.rawTransaction)
print(transaction_hash)
transaction_receipt2 = w3.eth.wait_for_transaction_receipt(transaction_hash)
print(transaction_receipt2)

在python 中与部署的智能合约交互

contract_instance = w3.eth.contract(address=transaction_receipt2.contractAddress, abi=abi)

contract_instance.functions.getStoreNumber().call()
contract_instance.functions.updateStoreNumber(200).call()

update_number_transaction = contract_instance.functions.updateStoreNumber(200).call().build_transaction(
    {
        "gasPrice": w3.eth.gas_price,
        "chainId": 3,
        "from": "wallet 钱包地址 来自metamask账户",
        "nonce": w3.eth.get_block_transaction_count("wallet 钱包地址 来自metamask账户") + 1 # 每次加1 不能重复使用 nonce
    }
)

sign_transaction3 = w3.eth.account.sign_transaction(update_number_transaction, private_key='私钥')
print(sign_transaction3)
transaction_hash3 = w3.eth.send_raw_transaction(sign_transaction3.rawTransaction)
print(transaction_hash3)
transaction_receipt3 = w3.eth.wait_for_transaction_receipt(transaction_hash3)
print(transaction_receipt3)
# 此时进行变化
contract_instance.functions.getStoreNumber().call()

# print(latest_block)
# print(w3.is_connected())
# print(Web3)
# print(EthereumTesterProvider)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python 之 web3 与智能合约的交互、编译等使用 的相关文章

  • python中热图的层次聚类

    我有一个 NxM 矩阵 其值范围为 0 到 20 我可以使用 Matplotlib 和 pcolor 轻松获得热图 现在我想使用 scipy 应用层次聚类和树状图 我想重新排序每个维度 行和列 以显示哪些元素相似 根据聚类结果 如果矩阵是方
  • 如何在Python中的BeautifulSoup4中使用.next_sibling时忽略空行

    由于我想删除 html 网站中重复的占位符 因此我使用 BeautifulSoup 的 next sibling 运算符 只要重复项位于同一行 就可以正常工作 参见数据 但有时它们之间有一个空行 所以我希望 next sibling 忽略它
  • Django 如何从 ManyToManyField 序列化并列出全部

    我正在使用 Django 1 9 1 开发移动应用程序后端 我实现了关注者模型 现在我想列出用户的所有关注者 但目前我不得不这样做 我还使用 Django Rest 框架 这是我的 UserProfile 模型 class UserProf
  • Pyinstaller --onefile 警告文件已存在但不应存在

    跑步时Pyinstaller onefile 并开始得到结果 exe 会出现多个弹出窗口 并显示以下警告 WARNING file already exists but should not C Users myuser AppData L
  • 属性错误:类型对象“图像”没有属性“打开”

    Exception in Tkinter callback Traceback most recent call last File C Python34 lib tkinter init py line 1482 in call retu
  • 如何使用 python 操作系统更改驱动器?

    我正在尝试更改当前目录C to Y 我试过 import os os chdir Y 但我不断收到错误消息 提示无法找到驱动器 本质上我正在寻找相当于 cd d cmd 中的命令 你确定吗Y 确实是有效的驱动器号吗 Try os chdir
  • InvalidArgumentException:消息:无效参数:“using”必须是字符串

    我对 python 很陌生 试图创建可重用的代码 当我尝试通过传递 Login 类下使用的所有参数来调用 test main py 中的 Login 类和函数 login user 时 我收到错误 InvalidArgumentExcept
  • 在 MATLAB 中创建共享库

    一位研究人员在 MATLAB 中创建了一个小型仿真 我们希望其他人也能使用它 我的计划是进行模拟 清理一些东西并将其变成一组函数 然后我打算将其编译成C库并使用SWIG https en wikipedia org wiki SWIG创建一
  • 提交表格并上传带有请求的文件

    我正在努力提交特定的表格蟒蛇请求 http www python requests org 我想使用它的网站上的其他表单工作正常 我可以提交登录表单等 这只是我遇到问题的文件上传 显然 提交表单效果很好 因为我从网站收到一条消息 说 请返回
  • 如何在matplotlib中基于x轴更改直方图颜色

    我有根据 pandas 数据框计算出的直方图 我想根据 x 轴值更改颜色 例如 If the value is 0 the color should be green If the value is gt 0 the color shoul
  • Python 垃圾收集有时在 Jupyter Notebook 中不起作用

    我的一些 Jupyter 笔记本经常出现 RAM 不足的情况 而且我似乎无法释放不再需要的内存 这是一个例子 import gc thing Thing result thing do something thing None gc col
  • 为 Python 2.4 改进“with”语句的直接替换

    您能否建议一种方法来编写可在 Python 2 4 中使用的 with 语句的直接替换代码 这将是一个 hack 但它可以让我更好地将我的项目移植到 Python 2 4 EDIT 删除了不相关的元类草图 只需使用 try finally
  • python中打印字符串的长度

    有没有什么方法可以找到 即使是最好的猜测 Python中字符串的 打印 长度 例如 potaa bto 是 8 个字符len但 tty 上只打印 6 个字符宽 预期用途 s potato x1b 01 32mpotato x1b 0 0mp
  • 如何将 pytest 装置与 django TestCase 一起使用

    我如何在TestCase方法 类似问题的几个答案似乎暗示我的例子应该有效 import pytest from django test import TestCase from myapp models import Category py
  • 使用 Flask-SQLAlchemy 进行多对多多数据库连接

    我正在尝试使这个多对多联接与 Flask SQLAlchemy 和两个 MySQL 数据库一起工作 并且它非常接近 只是它为联接表使用了错误的数据库 这是基础知识 我有main db and vendor db 表格设置为main db u
  • 从 C 线程调用 Python 代码

    我对从 C 或 C 线程调用 Python 代码时如何确保线程安全感到非常困惑 The Python 文档 http docs python org c api init html non python created threads似乎是
  • 在 Tensorflow 2.0 中的简单 LSTM 层之上添加 Attention

    我有一个由一个 LSTM 和两个 Dense 层组成的简单网络 如下所示 model tf keras Sequential model add layers LSTM 20 input shape train X shape 1 trai
  • 如何让你的精灵在pygame中跳跃

    目前我已经制作了一个平台游戏 可以左右移动我的角色 他从地上开始 关于如何让他跳的任何想法 因为我不明白 目前 如果我按住向上键 我的玩家精灵将连续向上移动 或者如果我按下它 我的玩家精灵将向上移动并保持向上 我想找个办法远离他 让我重新跌
  • 在Python中从列表中获取n个项目组的惯用方法? [复制]

    这个问题在这里已经有答案了 给定一个列表 A 1 2 3 4 5 6 是否有任何惯用的 Pythonic 方式来迭代它 就好像它是 B 1 2 3 4 5 6 除了索引之外 这感觉像是 C 的遗留物 for a1 a2 in A i A i
  • Shap - 颜色条不显示在摘要图中

    显示summary plot时 不显示颜色条 shap summary plot shap values X train 我尝试过改变plot size 当绘图较高时 会出现颜色条 但它非常小 看起来不应该 shap summary plo

随机推荐

  • VS Code集成终端字体修改 & 字体颜色、大小修改方法

    文章目录 VS Code中设置颜色的方法 字体以及字体大小修改 参考 VS Code中设置颜色的方法 通过将以下内容添加到用户设置中 ctrl 并搜索 workbench 然后点击 Edit in settings json 在最后加上如下
  • 国家智慧教育公共服务平台(2023年暑期教师研修)

    前言 最近又要看2023年暑期教师研修高等教育教师专业发展 抓包发现开启倍数无效了 要一个一个点击看视频 岂不是累死人 于是想个办法解放双手 该网站观看视频时 客户端间隔20 50s向服务端发送一个POST请求 服务器每秒返回ts响应 1
  • python数据分析预处理z-score标准化

    一 z score标准化的python代码 import pandas from pandas import read excel from sklearn import preprocessing dataset read excel p
  • 强化学习入门《Easy RL》

    什么是强化学习 强化学习关注的是智能体 Agent 在复杂的环境 Environment 中如何最大化获得的奖励 Reward 智能体和环境两部分组成了强化学习 在强化学习过程中 智能体与环境一直在交互 智能体在环境中获取某个状态后 它会利
  • python学习笔记#2元组和列表

    python学习笔记 2元组和列表 文章目录 python学习笔记 2元组和列表 前言 一 string包含引号 二 复杂数据类型 1 序列 2 tuple 元组 2 list 列表 总结 前言 学习python的复杂数据类型 tuple和
  • 以element ui为例分析前端各种弹窗和对话框的使用场景与区别

    文章目录 摘要 Dialog 对话框 Drawer 抽屉 Notice 通知 MessageBox 弹框 Popconfirm 气泡确认框 Message 消息提示 Notification 通知 Dialog 对话框与Drawer 抽屉的
  • MySQL中的锁机制详解

    概述 事务的隔离性 隔离级别 是由锁来保证的 并发访问数据的情况分为 1 读 读 即并发事务相继读取相同的记录 因为没涉及到数据的更改 所以不会有并发安全问题 允许这种情况发生 2 写 写 即并发事务对相同记录进行修改 会出现脏写问题 因为
  • python flask 网页适应手机端浏览器的编程方法

    1 使用flask在电脑端开发了一个论坛网址 想在手机端浏览看看 却发现根本装不下 并且导航栏元素还消失了 先看电脑端访问是正常的 而手机端导航条不见了 这是因为手机和电脑屏幕分辨率不同导致的 最简单的办法就是添加自适应宽度 并缩放页面 这
  • 异步(延时)逻辑难题,以及采用lua的解决方法

    在网游程序里混过一阵子的程序员大都知道 异步逻辑 是游戏逻辑里最容易失误的地方之一 刷钱 刷经验 不花钱得到道具 然后关服 回档 删号等等等等 其可能造成的危害不胜枚举 而且实际上银行系统之类的地方遇到这种问题就更有趣了 不同团队对此类问题
  • BUUCTF base 第三题Upload-Labs-Linux1比较省事的方法

    1 安装蚁剑 首先下载蚁剑 链接 https pan baidu com s 1O6Ty2Qmk7AVuY9QU CD9gQ fm lk0 提取码 1234 其次解压蚁剑 共两个文件需解压 在AntSword Loader中双击运行 gt
  • PCB线宽与通流量

    PCB通流能力的计算一直缺乏权威的技术方法 公式 经验丰富的Layout工程师依靠个人经验能作出较准确的判断 但是对于Layout新手 不可谓遇上一道难题 PCB的通流能力取决于以下因素 线宽 线厚 铜箔厚度 容许温升 大家都知道 PCB走
  • 基于Redis的Geo实现附近商铺搜索(含源码)

    微信公众号访问地址 基于Redis的Geo实现附近商铺搜索 含源码 推荐文章 1 springBoot对接kafka 批量 并发 异步获取消息 并动态 批量插入库表 2 SpringBoot用线程池ThreadPoolTaskExecuto
  • 复杂网络数据集下载地址

    1 斯坦福大学公开数据集 Stanford Large Network Dataset Collectionhttp snap stanford edu data 2 那慕尔大学公开数据集 Networks konect cc http k
  • Java1.8之HashMap底层链表变红黑树浅析

    HashMap底层链表变红黑树浅析 广为流传的错误结论 大O表示法 真正的原因 全文浏览约10分钟 从一个错误的结论分析到HashMap链表转化为红黑树的原因 读完对HashMap底层会有更深的理解 广为流传的错误结论 众所周知 Java1
  • 宏基服务器型号,宏基云服务器排名

    宏基云服务器排名 内容精选 换一换 磁盘增强型弹性云服务器自带高存储带宽和IOPS的本地盘 具有高存储IOPS以及读写带宽的优势 同时 本地盘的价格更加低廉 在海量数据存储场景下 具备更高的性价比 磁盘增强型弹性云服务器具备如下特点 本地磁
  • 在multisim14上完成数码管的显示(0-9)

    提前说说 前几天给西电的同学做了一个小的线上课程设计 用到数码管 没想到我们课程设计也是关于数码管 所以在这总结一下如何仿真实现数码管 目标 完成一个数码管的显示 从0 9分别显示 一 首先 确定使用的是共阴极数码管 在元器库中找到 二 接
  • python 二叉树,先序回溯,层序队列,队列基础用法,二叉树深度

    文章目录 1 创建二叉树 先 中 后遍历 2 n个节点有多少种二叉树 递归 3 层序遍历 4 队列基础用法 五 二叉树深度 1 创建二叉树 先 中 后遍历 创建二叉树 class TreeNode def init self data le
  • Java学习路线及步骤详解

    导言 Java是一门广泛应用于软件开发和互联网领域的编程语言 在国内外都具有广泛的应用和需求 对于想要学习Java的初学者来说 了解一个清晰的学习路线是非常重要的 它可以帮助你更好地规划学习进程 逐步提升自己的技能和能力 本篇博客将为你详细
  • k8s安装遇到过的一些问题

    无法获取recomended yaml文件 root k8master1 wget https raw githubusercontent com kubernetes dashboard v2 7 0 aio deploy recomme
  • python 之 web3 与智能合约的交互、编译等使用

    一 背景 web3 py是一个用于与以太坊交互的 Python 库 它常见于去中心化应用程序 dapps 中 帮助发送交易 与智能合约交互 读取块数据以及各种其他用例 最初的 API 源自Web3 js Javascript API 但后来