# 使用web3.py与智能合约交互 **Published by:** [Yooma](https://paragraph.com/@yooma/) **Published on:** 2022-12-26 **URL:** https://paragraph.com/@yooma/web3-py ## Content 注:本篇文章交互用到的合约以及 infura 的创建与项目链接在本篇文章中提到一:安装二:使用1:通过infura链接来与以太坊合约交互输出为True话代表链接成功infura截图https://连接成功之后我们把本篇文章中的abi与部署的合约地址用到这里 abi文件(rent_nft_test.json)在 brownie_test/build/contracts 中 那么如何获取到该合约中发生得mint/transfer等信息from web3 import Web3 import json # 首先通过infura节点链接 w3=Web3(Web3.HTTPProvider('https://<your-provider-url>')) # 合约abi文件 with open('./brownie_test/build/contracts/ERC4907.json', 'r') as f: abi_contract = json.loads(f.read())['abi'] # 与infura节点链接成功后 指定address以及abi与该合约建立连接 # address是合约地址 abi是该合约对应的abi my_contract = w3.eth.contract(address='0xADD22a3efa6f22dd60DF65CDfE096da0366eE002', abi=abi_contract) # 现在来测试获取到的该合约的信息 # ownerOf是合约中定义的方法,获取tokenId为1的owner地址,通过functions来调用它 print('token_id 1 owner: 'my_contract.functions.ownerOf(1).call()) # result >>> token_id 1 owner: 0x60EA96f57B3a5715A90DAe1440a78f8bb339C92e # 这个地址是在我部署该合约时mint tokenId为1的nft的钱包地址 # 证明获取该合约信息成功 上面获取合约信息成功,下面来给合约进行一次mint事件接上面代码: # 要给address去mint一个nft address = '0x60EA96f57B3a5715A90DAe1440a78f8bb339C92e # 生成nonce nonce = w3.eth.getTransactionCount(address) # mint token id 为 2 的nft, # 通过functions调用mint 合约代码中mint # buildTransaction构建交易字典,以此来传入合约中需要接受得msg.sender(address) mint = my_contract.functions.mint(2).build_transaction({'from': address, 'nonce': nonce}) # 签名 sign = w3.eth.account.sign_transaction(mint, '钱包地址私钥,在metamask查看') # 给链上发送这次mint w3.eth.send_raw_transaction(sign.rawTransaction) 关于nonce: 为了防止交易重播,ETH(ETC)节点要求每笔交易必须有一个nonce数值。每一个账户从同一个节点发起交易时,这个nonce值从0开始计数,发送一笔nonce对应加1。当前面的nonce处理完成之后才会处理后面的nonce。 在 send_raw_transaction 后去goerli测试官网查看该合约会有一次新的mint记录再来测试下给该nft设定一个user(租赁此nft的用户)python:就像发送一次mint请求一样来setUserfrom web3 import Web3 import json # 首先通过infura节点链接 w3=Web3(Web3.HTTPProvider('https://<your-provider-url>')) # 合约abi文件 with open('./brownie_test/build/contracts/ERC4907.json', 'r') as f: abi_contract = json.loads(f.read())['abi'] # 与infura节点链接成功后 指定address以及abi与该合约建立连接 # address是合约地址 abi是该合约对应的abi my_contract = w3.eth.contract(address='0xADD22a3efa6f22dd60DF65CDfE096da0366eE002', abi=abi_contract) # nft owner address = '0x60EA96f57B3a5715A90DAe1440a78f8bb339C92e # 生成nonce nonce = w3.eth.getTransactionCount(address) # 上面代码与上方的一样 # 通过chain.time(来获取链上时间) from brownie import chain # 调用setUser 给传入接收的值只有这里与mint是有区别的 # 1: nft tokenId # 0x450AF1Ea236932c0e18B53BC1FeB15E47AA292df user地址 # 到期时间 # 到期后这个nft user地址自动清零 x = my_contract.functions.setUser(1, '0x450AF1Ea236932c0e18B53BC1FeB15E47AA292df', 10*60+chain.time()).build_transaction({'from': address, 'nonce': nonce}) signed_txn = w3.eth.account.sign_transaction(x, '钱包地址私钥,在metamask查看') w3.eth.send_raw_transaction(signed_txn.rawTransaction) 以太坊goerli测试网官网查看数据会看到这里有一条我们刚刚setUser的数据此时在代码中查看下tokenId是1的nft的userprint(my_contract.functions.userOf(1).call()) # result >>>0x450AF1Ea236932c0e18B53BC1FeB15E47AA292df 以上是使用web3.py与智能合约交互的方式,流程如此,如需进行Transfer事件或获取其他信息可以修改mint,ownerOf等(合约中定义的function以及event),也可以查阅官方文档找到更多的操作。 ## Publication Information - [Yooma](https://paragraph.com/@yooma/): Publication homepage - [All Posts](https://paragraph.com/@yooma/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@yooma): Subscribe to updates - [Twitter](https://twitter.com/_yoonama): Follow on Twitter