最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - Solidity Contract Call Reverting with No Reason via Web3.py – How Can I Diagnose This? - Stack Overflow

programmeradmin3浏览0评论

I’m developing a blockchain-based forensic evidence system using Solidity (deployed via Hardhat/Ganache), a Python Flask backend, and Web3.py. My smart contract is designed to store evidence details (including a file hash, filename, UNIX timestamp, investigator, and location). When I call the addEvidence function from my Flask app, the transaction reverts with no clear error reason.

Error Message:

Blockchain ContractLogicError: ('execution reverted: VM Exception while processing transaction: revert', {'hash': None, 'programCounter': 70, 'result': '0x', 'reason': None, 'message': 'revert'})

Solidity Contract Code (EvidenceStorage.sol):

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

contract EvidenceStorage {
    struct Evidence {
        string fileHash;
        string fileName;
        uint timestamp; // UNIX timestamp
        string investigator;
        string location;
    }

    mapping(string => Evidence) private evidences;
    string[] private evidenceHashes;

    event EvidenceAdded(
        string fileHash,
        string fileName,
        uint timestamp,
        string investigator,
        string location
    );

    function addEvidence(
        string memory _fileHash,
        string memory _fileName,
        uint _timestamp,
        string memory _investigator,
        string memory _location
    ) public {
        // Revert if the evidence already exists.
        require(bytes(evidences[_fileHash].fileHash).length == 0, "Evidence already exists!");

        // Here we use block.timestamp rather than _timestamp
        uint currentTime = block.timestamp;

        Evidence memory newEvidence = Evidence({
            fileHash: _fileHash,
            fileName: _fileName,
            timestamp: currentTime,
            investigator: _investigator,
            location: _location
        });

        evidences[_fileHash] = newEvidence;
        evidenceHashes.push(_fileHash);

        emit EvidenceAdded(_fileHash, _fileName, currentTime, _investigator, _location);
    }

    function getEvidence(string memory _fileHash)
        public
        view
        returns (string memory, string memory, uint, string memory, string memory)
    {
        require(bytes(evidences[_fileHash].fileHash).length != 0, "Evidence not found!");
        Evidence memory e = evidences[_fileHash];
        return (e.fileHash, e.fileName, e.timestamp, e.investigator, e.location);
    }

    function getAllEvidenceHashes() public view returns (string[] memory) {
        return evidenceHashes;
    }
}

Python Code Snippet (from blockchain.py):


from web3 import Web3
import json
import os
from dotenv import load_dotenv

load_dotenv()

GANACHE_URL = os.getenv("GANACHE_RPC_URL")
CONTRACT_ADDRESS = os.getenv("CONTRACT_ADDRESS")

web3 = Web3(Web3.HTTPProvider(GANACHE_URL))
assert web3.is_connected(), "Failed to connect to Ganache!"

with open('hardhat_evidence/artifacts/contracts/EvidenceStorage.sol/EvidenceStorage.json') as f:
    contract_json = json.load(f)
    contract_abi = contract_json['abi']

contract = web3.eth.contract(address=CONTRACT_ADDRESS, abi=contract_abi)
account = web3.eth.accounts[0]

def add_evidence(evidence_hash, filename, timestamp, investigator, location):
    txn = contract.functions.addEvidence(evidence_hash, filename, timestamp, investigator, location).transact({'from': account})
    web3.eth.wait_for_transaction_receipt(txn)

Flask Code Snippet (from evidence_manager.py):

from flask import Flask, render_template, request, redirect
from app.blockchain import add_evidence, get_evidence, get_all_hashes
from app.utils import calculate_hash, get_current_unix_timestamp, unix_to_readable
import os

app = Flask(__name__)

TEMP_FOLDER = 'temp'
if not os.path.exists(TEMP_FOLDER):
    os.makedirs(TEMP_FOLDER)

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        file = request.files['evidenceFile']
        investigator = request.form['investigator']
        location = request.form['location']

        if file:
            file_path = os.path.join(TEMP_FOLDER, file.filename)
            file.save(file_path)

            evidence_hash = calculate_hash(file_path)
            timestamp_unix = get_current_unix_timestamp()

            add_evidence(evidence_hash, file.filename, timestamp_unix, investigator, location)
            os.remove(file_path)
            return redirect('/view')

    return render_template('index.html')

@app.route('/view')
def view():
    hashes = get_all_hashes()
    evidence_list = []

    for h in hashes:
        evi = get_evidence(h)
        readable_time = unix_to_readable(evi[2])
        evidence_list.append({
            'hash': evi[0],
            'filename': evi[1],
            'timestamp': readable_time,
            'investigator': evi[3],
            'location': evi[4]
        })

    return render_template('view_evidence.html', evidence_list=evidence_list)

if __name__ == '__main__':
    app.run(debug=True)

My Environment: Ganache as the local Ethereum node. Hardhat for smart contract development. Python 3.10, Flask, and Web3.py for the backend.

My Problem: When I try to add evidence (i.e., call addEvidence via my Flask app), the transaction reverts with:

ContractLogicError: ('execution reverted: VM Exception while processing transaction: revert', {'hash': None, 'programCounter': 70, 'result': '0x', 'reason': None, 'message': 'revert'})

The revert occurs even though: I’m sending the correct data types (all strings and a uint timestamp). My require in addEvidence should only revert if evidence with the same hash already exists.

Questions: 1.How can I obtain a more detailed revert reason from the transaction? I see no reason (it’s None), so how can I debug or get more insight into what causes the revert?

2.What are common pitfalls that might cause a revert in this context? For example, could it be due to an incorrect contract address, ABI issues, or is there something in my code logic that might lead to a failure?

Any insights or debugging strategies would be very helpful!

发布评论

评论列表(0)

  1. 暂无评论