トリュフ、ガナッシュ、solidity 0.8.0、web3.py(python) を使用してプライベート ブロックチェーンを作成しています。
ブロックチェーン上にファイル情報をアップロードしようとしています。ファイル情報は、filehash、filename、filesize tec です。
しかし、何かエラーがあります。
web3.exceptions.ContractLogicError: execution reverted: VM Exception while processing transaction: revert
このコードを使用すると、うまくいきました。
tx_hash = CON_IDX.functions.upload("11", "22", "33", 44)
tx_hash: <Function upload(string,string,string,uint256) bound to ('11', '22', '33', 44)>
しかし、このコードを使用すると機能しません。
tx_hash = CON_IDX.functions.upload("11", "22", "33", 44).transact()
web3.exceptions.ContractLogicError: execution reverted: VM Exception while processing transaction: revert
スマートコントラクトに問題があるのではないかと思い、remixide を使用しましたが問題ありませんでした。
なぜこのエラーが発生したのですか?..助けてください
これが私のコード全体です。Owner_contract.py
import sys
import os
import time
import solcx
from solcx import compile_files
from logzero import logger
from web3 import Web3
w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:7545')) # GANACHE
w3.eth.defaultAccount = w3.eth.accounts[0]
print('install solcx 0.8.0..')
solcx.install_solc('0.8.0')
def deploy(contract_file, contract_name):
compiled_sol = compile_files([contract_file])
interface = compiled_sol['{}:{}'.format(contract_file, contract_name)]
contract = w3.eth.contract(abi=interface['abi'],
bytecode='0x'+interface['bin'],
bytecode_runtime=interface['bin-runtime'])
tx_hash = contract.constructor(transaction={'from':w3.eth.accounts[0]}).transact()
logger.info(f'Owner_tx_hash: {tx_hash}')
tx_receipt = w3.eth.getTransactionReceipt(tx_hash)
logger.info(f'Owner_tx_receipt: {tx_receipt}')
contract_address = tx_receipt['contractAddress']
logger.info(f'Owner_contract_address: {contract_address}')
contract_instance = contract(contract_address)
logger.info(f'Owner_contract_instance: {contract_instance}')
return contract_instance
smartcontract.sol
pragma solidity ^0.8.0;
//pragma solidity >=0.5.0 < 0.9.0;
pragma experimental ABIEncoderV2;
contract Owner {
address public fileowner;
/* 발신자의 값을 fileowner에 저장*/
function Owned() public{
fileowner = msg.sender;
}
/* modifier은 함수의 동작을 변경시키기 위해 사용 */
/* _는 함수의 실행시점 -> 코드 추가시 _을 기준으로 작성*/
/* require은 인자의 값이 false이면 즉시 함수 실행을 중단하고 모든 상태 변환을 되돌림*/
modifier onlyOwner {
require(msg.sender == fileowner); // check if fileowner same msg.sender
_;
}
/* transferOwnership함수가 실행되면 onlyOwner함수가 실행되고 만약 require(false)이면 즉시 중단 */
/* 아니면 새로운 owner을 fileowner로 바꾼다 */
function transferOwnership(address newOwner) public onlyOwner { // if this function call,
fileowner = newOwner; // owner changed
}
/* 리턴 타입을 address(이더리움 주소)로 리턴 */
function getOwner() public view returns (address) { // return fileowner(type: address)
return fileowner;
}
}
contract CopyInfoContract{
uint index;
struct CopyrightStruct {
string Artist;
string Createdtime; // When this file created
string Type; // File Type ex) music, video, photo etc
string Description; // Simple Description of file
uint timestamp;
}
event Copyright(string Artist, string Createdtime, string Type, string Description, uint timestamp);
CopyrightStruct[] public copyright; // dynamic size
function initalized() public{
index = 0;
}
function addCopyright(string memory _Artist, string memory _Createdtime, string memory _Type, string memory _Description, uint timestamp ) public {
copyright.push(CopyrightStruct(_Artist, _Createdtime, _Type, _Description, timestamp));
index++;
emit Copyright(_Artist, _Createdtime, _Type, _Description, timestamp);
}
function getCopyright(uint _idx) public view returns(string memory, string memory, string memory, string memory) {
return (copyright[_idx].Artist, copyright[_idx].Createdtime, copyright[_idx].Type, copyright[_idx].Description);
}
}
contract StorefileHash is Owner {
struct File {
string filename;
uint UploadDate;
uint Filesize;
}
mapping(string => File) private files; // string : key, File : Value
mapping(string => string[]) private fileOwners;
string[] public owners;
uint public ownerID = 0;
event FileUpload(string ownername, string filehash, File file);
function upload(string memory _ownername, string memory _filehash, string memory _filename, uint _filesize) onlyOwner public{
ownerID++;
owners.push(_ownername);
File memory f = File(_filename, block.timestamp, _filesize); // now = block.timestamp
files[_filehash] = f;
emit FileUpload(_ownername, _filehash, f);
}
function Exsistcheck(string memory filehash) onlyOwner public view returns (bool) {
if(files[filehash].Filesize > 0) {
return true;
}
return false;
}
function getOwnerName(uint id) onlyOwner public view returns (string memory) {
return owners[id];
}
function getfileinfo(string memory filehash) onlyOwner public view returns (string memory, uint, uint) {
return (files[filehash].filename, files[filehash].UploadDate, files[filehash].Filesize);
}
}
アップロードファイル.py
import Owner_contract
from werkzeug.utils import secure_filename
from web3 import Web3
from logzero import logger
CON_IDX=None
CON_IDX = Owner_contract.deploy("smartcontract.sol", "StorefileHash")
def recvfile():
if request.method == 'POST':
file = request.files['file']
filename = secure_filename(file.filename)
path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
file.save(path)
logger.info(f'path: {path}')
owner = "test_owner"
filehash = str(sha256_checksum(path))
filesize = 20#getsize(str(path))
tx_hash = CON_IDX.functions.upload("11", "22", "33", 44)#.transact() #here is the error
#logger.info(f'transaction: {transaction}')
#logger.info(f'transcation_compo: {transaction.')
logger.info(f'tx_hash: {tx_hash}')
return 'file upload complete'