如何使用 Python 和 web3.py 调用智能合约函数
Posted
技术标签:
【中文标题】如何使用 Python 和 web3.py 调用智能合约函数【英文标题】:How to call a Smart Contract function using Python and web3.py 【发布时间】:2019-12-26 02:06:28 【问题描述】:我在以太坊测试网络上部署了一个合约,其中包含一些功能,并且在使用 Remix 界面时它们都可以正常工作。当尝试在 Python 中使用 web3.py 调用这些函数时,我只能调用公共函数并且该部分工作正常。 问题是调用具有“限制”的函数,例如具有“所有者要求”,这意味着只有创建合约的地址才能调用该特定函数。我已经用谷歌搜索了它,但没有运气。我猜我应该在调用该函数时同时使用该以太坊帐户的“地址”和“密码”作为参数,但我不知道该怎么做。函数称为“set()”,它只需要 2 个字符串值。
这是 Solidity 代码的一部分,它使函数“set()”只能由该合约的所有者访问。
constructor() public
owner = msg.sender;
modifier onlyOwner()
require(msg.sender == owner);
_;
function set(string memory _lastHash,
string memory _fullHash) public onlyOwner
lastHash = _lastHash;
fullHash = _fullHash;
这是我用来从其他 2 个函数中获取返回值的 python 函数,我没有包括:
data = contract.functions.getFullHash().call()
函数称为“getFullHash()”。鉴于 Python 代码不适用于函数“set()”。
【问题讨论】:
设置值你必须调用函数为contract.functions.set(arg1, arg2).transact()
。
这对我不起作用,起作用的是:signed_txn = web3.eth.account.signTransaction(transaction, private_key=private_key)。交易需要如下所示: transaction = contract.functions.set( 'string1', 'string2' ).buildTransaction( 'gas': 70000, 'gasPrice': web3.toWei('1', 'gwei') , 'from': 地址, 'nonce': nonce )
【参考方案1】:
由于我的原始评论被删除了,我会在最后一次发布它。
我已经按照link 上提供的说明完成了这项工作。 这是对我有用的代码:
transaction = contract.functions.set(
'string1',
'string2' ).buildTransaction(
'gas': 70000,
'gasPrice': web3.toWei('1', 'gwei'),
'from': adress,
'nonce': nonce
)
private_key = "enter_your_key_here"
signed_txn = web3.eth.account.signTransaction(transaction, private_key=private_key)
web3.eth.sendRawTransaction(signed_txn.rawTransaction)
我在某处读到 Infura 只接受原始签名交易,不确定它是否属实,但它以这种方式工作。
【讨论】:
sendRawTransaction 返回 Hash,但没有任何事务。 getTransaction 与该哈希显示此 'blockHash': None, 'blockNumber': None, 'from': '0xA6f8021540Ec3609696e22f170144e47c8c88127', 'gas': 118685, 'gasPrice': 1000000000, ..., 'to': 'My address ','transactionIndex':无,'v':42,'值':0 如果您在主网上操作,您需要将“gasPrice”设置为当前喜欢160 gwei。【参考方案2】:Moltenpowa 回答正确。但是,我在定义 nonce 时遇到了问题。以下是完整的解决方案:
CHAIN_ID = 97 # Testnet
GAS_AMOUNT = 65000
GAS_PRICE = 10 # gwei
SC_ADDRESS = '0x....'
SC_OWNER_ADDR = '0x...'
SC_OWNER_ADDR_PRIV_KEY_FILE_PATH = '/opt/.priv_key.txt'
def change_contract_state(wallet):
nonce = w3.eth.getTransactionCount(SC_OWNER_ADDR)
private_key = read_private_key_from_file(SC_OWNER_ADDR_PRIV_KEY_FILE_PATH)
nonce = w3.eth.getTransactionCount(SC_OWNER_ADDR)
private_key = read_private_key_from_file(SC_OWNER_ADDR_PRIV_KEY_FILE_PATH)
transaction = contract.functions.updateWinner(wallet).buildTransaction(
'chainId': CHAIN_ID,
'gas': GAS_AMOUNT,
'gasPrice': Web3.toWei(GAS_PRICE, 'gwei'),
'from': SC_OWNER_ADDR,
'nonce': nonce
)
# print(transaction)
signed_txn = w3.eth.account.signTransaction(transaction, private_key=private_key)
tx_hash = w3.toHex(w3.keccak(signed_txn.rawTransaction))
print(tx_hash)
【讨论】:
以上是关于如何使用 Python 和 web3.py 调用智能合约函数的主要内容,如果未能解决你的问题,请参考以下文章
使用 Python Web3.py 调用 Solidity 函数
如何通过 Python 和 Web3.py 获取 ETH 智能合约的数量?
在 ganache 上调用函数时出现 Web3.py abi keyerror