0

Noob here. I've set up a test blockchain using Ganache and have successfully deployed a sample contract to one of the addresses in my environment (using Remix). However, when I try to run my python script to interact with the chain, I get a host of call errors and two exceptions:

Traceback (most recent call last):

File "/Users/jsn/opt/anaconda3/lib/python3.7/site-packages/web3/contract.py", line 1507, in call_contract_function
    output_data = web3.codec.decode_abi(output_types, return_data)
  
File "/Users/jsn/opt/anaconda3/lib/python3.7/site-packages/eth_abi/codec.py", line 181, in decode_abi
    return decoder(stream)
  
File "/Users/jsn/opt/anaconda3/lib/python3.7/site-packages/eth_abi/decoding.py", line 127, in __call__
    return self.decode(stream)
  
File "/Users/jsn/opt/anaconda3/lib/python3.7/site-packages/eth_utils/functional.py", line 45, in inner
    return callback(fn(*args, **kwargs))
  
File "/Users/jsn/opt/anaconda3/lib/python3.7/site-packages/eth_abi/decoding.py", line 173, in decode
    yield decoder(stream)
  
File "/Users/jsn/opt/anaconda3/lib/python3.7/site-packages/eth_abi/decoding.py", line 127, in __call__
    return self.decode(stream)
  
File "/Users/jsn/opt/anaconda3/lib/python3.7/site-packages/eth_abi/decoding.py", line 198, in decode
    raw_data = self.read_data_from_stream(stream)

 
File "/Users/jsn/opt/anaconda3/lib/python3.7/site-packages/eth_abi/decoding.py", line 308, in read_data_from_stream
    len(data),

**eth_abi.exceptions.InsufficientDataBytes: Tried to read 32 bytes.  Only got 0 bytes**

The above exception was the direct cause of the following exception:

Traceback (most recent call last):

File "showSupplyChain.py", line 16, in <module>
    productCount = contract.functions.product_id().call()
  
File "/Users/jsn/opt/anaconda3/lib/python3.7/site-packages/web3/contract.py", line 964, in call
    **self.kwargs
  
File "/Users/jsn/opt/anaconda3/lib/python3.7/site-packages/web3/contract.py", line 1528, in call_contract_function
    raise BadFunctionCallOutput(msg) from e

**web3.exceptions.BadFunctionCallOutput: Could not transact with/call contract function, is contract deployed correctly and chain synced?**

I realize folks on here may have posted similar problems, but can anyone assist me in understanding from these errors what is occurring/not occurring given the calls to other .py scripts?

Thanks,

python code

import json
from web3 import Web3

ganache_url = "http://127.0.0.1:7545"
web3 = Web3(Web3.HTTPProvider(ganache_url))

web3.eth.defaultAccount = web3.eth.accounts[0]

with open('SupplyChain.abi') as f:
    abi = json.load(f)

address = web3.toChecksumAddress('0x10cbcbBF3b4e99d8D7a3f9E21C53162d969D94f0') 
# Initialize supplyChain contract
contract = web3.eth.contract(address=address, abi=abi)

productCount = contract.functions.product_id().call()
participantCount = contract.functions.participant_id().call()
transferCount = contract.functions.owner_id().call()

print()
print('Products: ',productCount)
print('Participants: ',participantCount)
print('Ownership transfers: ',transferCount)

# Display the participants 
for i in range (0, participantCount):
    print(contract.functions.participants(i).call())

print('Participants: ',contract.functions.participant_id().call())

contract

pragma solidity >=0.4.21 <0.6.0;

contract supplyChain {
    uint32 public product_id = 0;       // Product ID
    uint32 public participant_id = 0;   // Participant ID
    uint32 public owner_id = 0;         // Ownership ID

    struct product {
        string UUID;
        string modelNumber;
        string partNumber;
        string serialNumber;
        address productOwner;
        uint32 mfgCost;
        uint32 msrp;
        uint32 mfgTimeStamp;
    }

    mapping(uint32 => product) public products;
    event NewProduct(uint32 productId, uint32 createdTimestamp);
    event UpdateProduct(string UUID, string modelNumber, string partNumber, string serialNumber,
        address productOwner, uint32 mfgCost, uint32 msrp, uint32 mfgTimeStamp);

    struct ownership {
        uint32 productId;
        uint32 ownerId;
        uint32 trxTimeStamp;
        address productOwner;
        uint32 cost;
        uint32 price;
        uint32 qty;
    }
    mapping(uint32 => ownership) public ownerships; // ownerships by ownership ID (owner_id)
    mapping(uint32 => uint32[]) public productTrack;  // ownerships by Product ID (product_id)

    struct participant {
        string UUID;
        string userName;
        string password;
        string participantType;
        address participantAddress;
    }
    mapping(uint32 => participant) public participants;

    event NewParticipant(uint32 participantId, uint32 createdTimestamp);
    event TransferOwnership(uint32 productId, address fromOwner, address toOwner);
    event UpdateParticipant(string participantUUID, string userName, string password, string participantType, address participantAddress);

    function addParticipant(string memory _UUID, string memory _name, string memory _pass, string memory _pType, address _pAdd)
        public returns (uint32){

        uint32 userId = participant_id++;
        participants[userId].UUID = _UUID;
        participants[userId].userName = _name;
        participants[userId].password = _pass;
        participants[userId].participantType = _pType;
        participants[userId].participantAddress = _pAdd;
        emit NewParticipant(participant_id, uint32(now));

        return userId;
    }

    function getParticipant(uint32 _participant_id) public view returns (string memory,string memory,string memory,address) {
        return (participants[_participant_id].UUID, participants[_participant_id].userName,
                participants[_participant_id].participantType,participants[_participant_id].participantAddress);
    }

    function addProduct(string memory _UUID, uint32 _ownerId, string memory _modelNumber, string memory _partNumber, string memory _serialNumber,
            uint32 _productCost, uint32 _productMSRP, uint32 _timestamp) public returns (uint32) {

        if(keccak256(abi.encodePacked(participants[_ownerId].participantType)) == keccak256("Manufacturer")) {
            uint32 productId = product_id++;

            products[productId].UUID = _UUID;
            products[productId].modelNumber = _modelNumber;
            products[productId].partNumber = _partNumber;
            products[productId].serialNumber = _serialNumber;
            products[productId].mfgCost = _productCost;
            products[productId].msrp = _productMSRP;
            products[productId].productOwner = participants[_ownerId].participantAddress;
            if (_timestamp == 0) {
                products[productId].mfgTimeStamp = uint32(now);
            }
            else {
                products[productId].mfgTimeStamp = _timestamp;
            }
            emit NewProduct(productId, products[productId].mfgTimeStamp);

            return productId;
        }

       return 0;
    }

    modifier onlyOwner(uint32 _productId) {
         require(msg.sender == products[_productId].productOwner,"Only the product owner can do this");
         _;
    }

    function getProduct(uint32 _productId) public view returns (string memory,string memory,string memory,string memory,uint32,address,uint32){
        return (products[_productId].UUID,products[_productId].modelNumber,products[_productId].partNumber,products[_productId].serialNumber,
            products[_productId].mfgCost,products[_productId].productOwner,products[_productId].mfgTimeStamp);
    }

    function newOwner(uint32 _prodId, uint32 _user1Id, uint32 _user2Id, uint32 _cost, uint32 _price, uint32 _qty, uint32 _timestamp)
        public onlyOwner(_prodId) returns(bool) {

        participant memory p1 = participants[_user1Id];
        participant memory p2 = participants[_user2Id];
        uint32 ownership_id = owner_id++;

        ownerships[ownership_id].productId = _prodId;
        ownerships[ownership_id].productOwner = p2.participantAddress;
        ownerships[ownership_id].ownerId = _user2Id;
        ownerships[ownership_id].cost = _cost;
        ownerships[ownership_id].price = _price;
        ownerships[ownership_id].qty = _qty;
        if (_timestamp == 0) {
            ownerships[ownership_id].trxTimeStamp = uint32(now);
        }
        else {
            ownerships[ownership_id].trxTimeStamp = _timestamp;
        }
        products[_prodId].productOwner = p2.participantAddress;
        productTrack[_prodId].push(ownership_id);
        emit TransferOwnership(_prodId, p1.participantAddress, p2.participantAddress);

        return (true);
    }

   function getProvenance(uint32 _prodId) external view returns (uint32[] memory) {
       return productTrack[_prodId];
    }

    function getOwnership(uint32 _regId)  public view returns (uint32,uint32,address,uint32) {
        ownership memory r = ownerships[_regId];
        return (r.productId,r.ownerId,r.productOwner,r.trxTimeStamp);
    }

    function authenticateParticipant(uint32 _uid, string memory _uname, string memory _pass, string memory _utype) public view returns (bool){
        if(keccak256(abi.encodePacked(participants[_uid].participantType)) == keccak256(abi.encodePacked(_utype))) {
            if(keccak256(abi.encodePacked(participants[_uid].userName)) == keccak256(abi.encodePacked(_uname))) {
                if(keccak256(abi.encodePacked(participants[_uid].password)) == keccak256(abi.encodePacked(_pass))) {
                    return (true);
                }
            }
        }

        return (false);
    }
}
5
  • What's the solidity and python code used? – Ismael Dec 12 '20 at 14:53
  • @Ismael, I've uploaded the code into the original post. Thank you for taking a look and responding. – Jason Dec 12 '20 at 20:32
  • From the error message and code it seems the address doesn't correspond to a contract. Are you connected to the correct ganache instance? How is ganache launched? Did you restart the ganache? – Ismael Dec 12 '20 at 22:49
  • @Ismael, I'm using the Ganache application. The web3.eth.accounts[0] in the code is the same address in Ganache, and I copied it out from the Remix 'DEPLOY & RUN TRANSACTIONS' tab. I'm following instructions in a book, thought everything was set up correctly. At what point do I need to restart Ganache? Thank you. – Jason Dec 13 '20 at 12:49
  • Restarting ganache will create a new blockchain discarding all transactions, blocks, contracts, etc. I think it has a configuration option to have a persistent blockchain so restarting will keep the changes. – Ismael Dec 13 '20 at 18:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.