0

hello dear community I wanted to ask why the transaction is not executed correctly.

Code Solidity:

// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.8.9;
contract main{
    struct data{ 
        string data;       
        uint num1;
        uint num2;
        uint num3;
    }

    mapping(string => data[]) public Data;

    address internal owner;

    
    function getOwner() public view returns(address){
        return owner;
    }

    modifier onlyOwner(){
        require(getOwner()==msg.sender, "solo el creado puede modificar.");
        _;
    }
    
    function arrayStructData( data[] memory _data) public{
        for(uint i=0; i<_data.length; i++){ 
            Data[_data[i].data].push(data(_data[i].data,_data[i].num1,_data[i].num2,_data[i].num3));
           
        }
    }
}

Code Python:

publicKey="0x..."
privateKey= "0x..."
addresscontract= "0x..."
abi="[[...]...]"
contrato= web3.eth.contract(address=addresscontract,abi=abi)
data=[["data",123,321,456],["data2",123,321,456]]
nonce = web3.eth.getTransactionCount(publicKey)
tx= contrato.functions.arrayStructData(data).buildTransaction({
    "from":publicKey,
    "chainId": web3.eth.chain_id,
    "gas": 70000,
    "gasPrice": web3.toWei("40", "gwei"),
    "nonce": nonce,
    })
signed_txn =web3.eth.account.signTransaction(tx, private_key=privateKey)
tx_hash=web3.eth.sendRawTransaction(signed_txn.rawTransaction)
txid = tx_hash.hex()
print({"Tx Hash":txid})

I have tried the combinations with this variable 'data' in Python:

Num= Decimal(3321)

data= (("node1",Num,Num,Num),("node1",Num,Num,Num))

data= (["node1",3123,3321,3456],["node1",3123,3321,3456])

data= (["node1",Num,Num,Num],["node1",Num,Num,Num])

data= ["node1",Num,Num,Num,"node1",Num,Num,Num]

data= (["node1",str(Num),str(Num),str(Num)],["node1",str(Num),str(Num),str(Num)])

data= (["node1",str(3123),str(3321),str(3456)],["node1",str(3123),str(3321),str(3456)])


With these two combinations it is confirmed in the blockchain but fail and not append data.

data= [["node1",3123,3321,3456],["node1",3123,3321,3456]]
data= [("node1",3123,3321,3456),("node1",3123,3321,3456)]

Now my question is what am I doing wrong?

How do I organize it so that the transaction is confirmed and it is successful to add to the contract?

How do you pass a struct in Python by parameter so that it processes it correctly in the contract??

Thank you very much for your answers in advance.

2 Answers 2

1

Not familiar with web3.py, but have you tried passing them as dicts?

data = [
    {"data": "node1", "num1": 3123, "num2": 3321, "num3": 3456},
    {"data": "node2", "num1": 3123, "num2": 3321, "num3": 3456},
]

PS: Cleaned up the names a bit here, since it was confusing (you'd have to change Data.data => Data.identifier above to use this)

// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.8.9;

contract main{
    struct Data { 
        string identifier;       
        uint num1;
        uint num2;
        uint num3;
    }

    mapping(string => Data[]) public data;

    // ...

    
    function pushData(Data[] calldata _data) public {
        for(uint i=0; i<_data.length; i++){ 
            data[_data[i].identifier].push(_data[i]);
        }
    }
}
2
  • Thank you very much for your answer. I added your answer but the contract still fails. with that 'data' variable. in remix it works but in web3.py it fails . data = [ {"data": "node1", "num1": 3123, "num2": 3321, "num3": 3456}, {"data": "node2", "num1": 3123, "num2": 3321, "num3": 3456}, ] Jun 20, 2022 at 21:29
  • Thank you very much for your collaboration Jun 21, 2022 at 0:51
0
def estimateGas_arrayStructData(data,nonce):
    return web3.eth.estimate_gas(myContract.functions.arrayStructData(data).buildTransaction({
    "from":_publicKey,
    'chainId' : web3.eth.chain_id,
    'nonce' : nonce,
}))


nonce = web3.eth.getTransactionCount(_publicKey)
data = [
{"data": "node1", "num1": 3123, "num2": 3321, "num3": 3456},
{"data": "node2", "num1": 3123, "num2": 3321, "num3": 3456},
]
estimate_gas= estimateGas_arrayStructData(data,nonce)

print("estimate_gas:",estimate_gas)



tx_dict2 = myContract.functions.arrayStructData(data).buildTransaction({
"from":_publicKey,
'chainId' : web3.eth.chain_id,
'gas' : estimate_gas, # 210000
'gasPrice' : web3.eth.gasPrice,
'nonce' : nonce,
})

signed_tx = web3.eth.account.sign_transaction(tx_dict2, _privateKey)
tx_hash = web3.eth.sendRawTransaction(signed_tx.rawTransaction)
tx_receipt = web3.eth.waitForTransactionReceipt(tx_hash, timeout=120, poll_latency=0.1)
print(tx_receipt)

Everything was the gas estimate.

In the 'buildTransaction' function I had gas:70000 , insufficient gas

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.