如何使用 Python 和 web3.py 调用智能合约函数

How to call a Smart Contract function using Python and web3.py

我在以太坊测试网络上部署了一个合约,其中有一些功能,它们在使用 Remix 界面时都可以正常工作。当尝试在 Python 中使用 web3.py 调用这些函数时,我只能调用 public 函数并且该部分工作正常。 问题是调用带有 "restriction" 的函数,例如 "owner requirement",这意味着只有创建合约的地址才能调用该特定函数。我已经用谷歌搜索了但没有运气。我猜我应该在调用该函数时同时使用该以太坊帐户的 "address" 和 "password" 作为参数,但我不知道该怎么做。函数名为 "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;
}

这里是 python 函数,我用它从我没有包含的其他 2 个函数中获取 return 值:

data = contract.functions.getFullHash().call()

函数被调用 "getFullHash()"。鉴于 Python 代码不适用于函数 "set()".

因为我原来的评论被删除了,所以我会post最后一次。

我已经按照 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 只接受原始签名交易,不确定它是否属实,但它是这样工作的。

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)