1

I have a claim smart contract and I want to call the function to python. This is the function

struct ClaimList{
        uint256 claimCounts;
        uint256 amount;
        address agentAddress;
        string icon;
        string tokenName;
        string remarks;
        IERC20 token;
        bool is_Claimed;
    }

    mapping(uint256 => mapping(address => ClaimList)) public claimList;
    mapping(address => uint256[])  mcounts;

function setClaimables (
        uint256 [] memory amount,
        address [] memory agentAddress,
        string [] memory icons,
        string [] memory tokenNames,
        string [] memory remarks,
        IERC20 [] memory token
    ) external onlyAdmin {

        for (uint256 i = 0; i < agentAddress.length; i++) {
            ClaimList storage listClaim = claimList[counter][agentAddress[i]];

            listClaim.claimCounts = counter;
            listClaim.amount = amount[i];
            listClaim.agentAddress = agentAddress[i];
            listClaim.icon = icons[i];
            listClaim.tokenName = tokenNames[i];
            listClaim.remarks = remarks[i];
            listClaim.token = token[i];
            listClaim.is_Claimed = false;

            mcounts[agentAddress[i]].push(counter);
            counter += 1;
        }

    }

1 Answer 1

1

Hi Dev advocate at Chainstack here!

When you use web3.py to interact with smart contracts, you can divide the script into three parts:

  • Connect to the network.
  • Initialize the smart contract & account to sign the transactions from.
  • Call functions and transactions.

The following example calls functions from an ERC20 smart contract, but you can adapt it to your contract by using your contract's ABI and address.

Connect to the network

I always use this syntax to connect my scripts to a network, you can also use an environment variable, but I usually keep it simple for test scripts.

from web3 import Web3

# Initialize endpoint URL
node_url = "CHAINSTACK_NODE_URL"

# Create the node connection
web3 = Web3(Web3.HTTPProvider(node_url))

I usually add an if statement to give a message on the console to verify if the connection is successful (non-required but excellent for the user).

# Verify if the connection is successful
if web3.isConnected():
    print("-" * 50)
    print("Connection Successful")
    print("-" * 50)
else:
    print("Connection Failed")

Initialize smart contract and account

To call functions from a smart contract, we need to specify its address and ABI first.

# Initialize the address calling the functions/signing transactions
caller = "YOUR_ADDRESS"
private_key = "PRIVATE_KEY"  # To sign the transaction

# Initialize address nonce
nonce = web3.eth.getTransactionCount(caller)

# Initialize contract ABI and address
abi = '[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"balanceLeft","type":"uint256"}],"name":"balance","type":"event"},{"inputs":[{"internalType":"address payable","name":"recipient","type":"address"}],"name":"destroy","outputs":[],"stateMutability":"nonpayable","type":"function"}'

contract_address = "CONTRACT_ADDRESS"

# Create smart contract instance
contract = web3.eth.contract(address=contract_address, abi=abi)

Call functions and transactions

Now we can start calling functions; we can do it two ways:

  • Build a transaction to call a function that modifies the state of the network.

  • .call in case the function is only reading from the blockchain (if it's a view or pure function).

Call a function that modifies the state

For this, we need to build a transaction to send.

The following example calls a function with no parameters named testFunc(), but you can put your setClaimables() function in it and add the parameters.

# initialize the chain id, we need it to build the transaction for replay protection
Chain_id = web3.eth.chain_id

# Call your function
call_function = contract.functions.testFunc().buildTransaction({"chainId": Chain_id, "from": caller, "nonce": nonce})

# Sign transaction
signed_tx = web3.eth.account.sign_transaction(call_function, private_key=private_key)

# Send transaction
send_tx = web3.eth.send_raw_transaction(signed_tx.rawTransaction)

# Wait for transaction receipt
tx_receipt = web3.eth.wait_for_transaction_receipt(send_tx)
# print(tx_receipt) # Optional

Call a pure or view function

Then if you want to call a function that only reads from the network (view or pure), you only need to "call" it since it will not make an actual transaction.

For example the totalSupply() function from an ERC20 token contract.

totalSupply = contract.functions.totalSupply().call()  # read the coin total supply - call means we are reading from the blockchain
print(totalSupply) 

You can check the Ethereum API reference page on the Chainstack docs to see more web3.py code examples!

I hope this helps you!

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.