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

时间:2019-08-20 19:53:46

标签: python blockchain ethereum web3

我有一个部署在以太坊测试网络上的合同,其中包含一些功能,并且它们都在使用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;
}

这是我正在使用的python函数,用于从我未包括的其他2个函数中获取返回值:

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

函数称为“ getFullHash()”。给定的Python代码不适用于功能“ set()”。

2 个答案:

答案 0 :(得分:0)

自从我的原始评论被删除以来,我将在最后一次发布。

我已经按照此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仅接受原始签名的交易,不确定它是否属实,但这种方式起作用。

答案 1 :(得分:0)

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)