I'm trying to sign locally a transaction to a smart contract method using web3.py.
I'm using ganache and there is one interesting issue when I send a transaction as the contract deployer everything is OK. Whenever I call the contract from a different address I get a message "the tx doesn't have the correct nonce. account has nonce of: 11 tx has nonce of: 0"
and a RPC error is thrown.
It's my code:
from web3 import Web3
import json
import asyncio
class Client:
def __init__(self, provider, contract_address, private_key):
self.web3 = Web3(Web3.HTTPProvider(provider))
with open("abi.json") as abi_file:
abi = json.load(abi_file)
self.contract_instance = self.web3.eth.contract(
address=contract_address, abi=abi)
self.account = self.web3.eth.account.privateKeyToAccount(private_key)
async def asset_emit(self, to_address, meta):
raw_tx = self.contract_instance.functions.assign(to_address, meta).buildTransaction({
'nonce': self.web3.eth.getTransactionCount(self.account._address)
})
signed_tx = self.web3.eth.account.signTransaction(
raw_tx, private_key=self.account._privateKey)
sent_tx = self.web3.eth.sendRawTransaction(signed_tx.rawTransaction)
return Web3.toHex(sent_tx)
provider = "http://localhost:7545"
contract_address = "0x1a6bBC4F4759053A3EAc90ECF2b8458c26C6420f"
private_keys = [
"0a62d720053110c9ece23ca0b1aef887dd8107e246e8ed646cadd8f86c5cff72",
"4867ce02e3d309962375b368065623f9ff33adbf50b754f15f9f0dab3b5311b8",
"0dc0af03cf395fe7d617ca4c2951d4240c4fdcc67cf78b3e0a5e666662b543b6",
"5cf0c6d817044434fc94ca40a2f8434658195575d19d0732034edbc4e63709b6",
"75093f0ec4bdc9e4b442bfd19a0550c939de81d287bcedeca46e6048b19b983d",
"0fd5c5c6e2b641741c59952b78cb7b979a7564c1c7926cc6fbc77d96f5c3a38e"
]
async def test():
for i in range(0, len(private_keys)):
try:
client = Client(provider, contract_address, private_keys[i])
await gts_sdk.asset_emit(
"0x91F64E8D876690b617B252445790B5e3fCc9322D", "0x10")
print(True)
except:
print(False)
await client.asset_emit(
"0x91F64E8D876690b617B252445790B5e3fCc9322D", "0x10")
event_loop = asyncio.get_event_loop()
tasks = [
asyncio.ensure_future(test())
]
event_loop.run_until_complete(asyncio.wait(tasks))
event_loop.close()
Thanks for help