Erc-20
web3 上的 contractLogicError 但正在使用 Remix
我有這個契約程式碼,它在混音上工作得很好,但是我不能在 python 中使用 web3 執行,得到一個 contractLogicError。
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; interface IERC20 { event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function transfer(address receiver, uint256 numTokens) external returns (bool); function approve(address spender, uint256 numTokens) external returns (bool); function transferFrom(address sender, address receiver, uint256 numTokens) external returns (bool); function changeLeader(address newLeader) external returns(bool); } contract ownableERC20 is IERC20 { string private _name; string private _symbol; uint8 private _decimals; uint256 private _totalSupply; address public owner; address public leader; mapping(address => uint256) _balances; mapping(address => mapping (address => uint256)) _allowances; constructor(string memory name_, string memory symbol_,uint256 totalSupply_) { _name = name_; _symbol = symbol_; _totalSupply = totalSupply_; _balances[msg.sender] = _balances[msg.sender] + totalSupply_; emit Transfer(address(0),msg.sender,_totalSupply); } function _transfer(address sender, address receiver, uint256 numTokens) internal { require(receiver != address(0),"ERC20: transfer from zero transfer"); require(sender != address(0),"ERC20: transfer from zero transfer"); require(numTokens <= _balances[sender]); _balances[sender] = _balances[sender]-numTokens; _balances[receiver] = _balances[receiver]+numTokens; emit Transfer(sender, receiver, numTokens); } function _approve(address owning, address spender, uint256 numTokens) internal { require(spender != address(0),"ERC20: transfer from zero transfer"); require(owning != address(0),"ERC20: transfer from zero transfer"); _allowances[owning][spender] = numTokens; emit Approval(owning, spender, numTokens); } // function name() public view returns (string memory) { // return _name; // } // function symbol() public view returns (string memory){ // return _symbol; // } // function decimals() public view returns(uint8) { // return _decimals; // } // function decimals() public override pure returns (uint8) { // return true; // } function _mint(address account, uint256 numTokens) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _totalSupply += numTokens; _balances[account] += numTokens; emit Transfer(address(0), account, numTokens); } function _burn(address account, uint256 numTokens) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); uint256 accountBalance = _balances[account]; require(accountBalance >= numTokens, "ERC20: burn numTokens exceeds balance"); _balances[account] = accountBalance - numTokens; _totalSupply -= numTokens; emit Transfer(account, address(0), numTokens); } function totalSupply() public override view returns (uint256) { return _totalSupply; } function balanceOf(address tokenOwner) public override view returns (uint256) { return _balances[tokenOwner]; } function transfer(address receiver, uint256 numTokens) public override returns (bool) { _transfer(msg.sender,receiver,numTokens); return true; } function approve(address spender, uint256 numTokens) public override returns (bool) { _approve(msg.sender, spender, numTokens); return true; } function allowance(address owning, address spender) public override view returns(uint256) { return _allowances[owning][spender]; } function transferFrom(address sender, address receiver, uint256 numTokens) public override returns(bool) { _transfer(sender, receiver, numTokens); _approve(sender, msg.sender, _allowances[sender][msg.sender] - numTokens); return true; } function changeLeader(address newLeader) public override returns(bool){ require(leader == msg.sender); leader = newLeader; return true; } } contract emissionsTradeToken is ownableERC20{ mapping(address => uint256) GHGEmitted; mapping(address=>address) approvedIot; mapping(address=>bool) approvedAgent; event Buy(address indexed to, uint indexed GHGEmitted, uint indexed amount); event Emission(address indexed to, uint indexed GHGEmitted, uint indexed amount); event Compensate(address indexed to, uint indexed GHGEmitted, uint indexed amount); constructor() ownableERC20("emissionsTradeToken", "ETT", 100000000000000000000){ owner = msg.sender; } modifier onlyLeader(){ require(msg.sender == leader); _; } modifier onlyIOT(address agent){ require(msg.sender == approvedIot[agent]); _; } // function mint(uint amount) public onlyOwner{ // _mint(address(this), amount); // } function addEmissions(address agent,uint emission) public onlyIOT(agent){ GHGEmitted[agent] += emission; emit Emission(agent,emission,emission); } function getEmissions(address agent) public view returns(uint){ return GHGEmitted[agent]; } function getIOTCounter(address agent) public view returns(address){ return approvedIot[agent]; } function compensate(uint amount) public{ require(balanceOf(msg.sender)>= amount, "buy ETT to compensate for GHG emissions!"); //_burn(msg.sender,amount); transfer(owner,amount); GHGEmitted[msg.sender] -=amount; emit Compensate(msg.sender,amount, amount); } function approveAgent(address agent) onlyLeader public{ // eventually, requires no again adding if already added require(approvedAgent[agent]==false, "agent already added"); approvedAgent[agent]=true; } function approveIOTCounter(address spender) public{ require(approvedAgent[msg.sender]==true, "agent must be added ny contract owner - community manager"); bool isApproved = approve(spender,getEmissions(msg.sender)); if(isApproved) approvedIot[msg.sender]=spender; } } contract tradeContract { address public owner; IERC20 public token; event Bought(uint256 numTokens); event Sold(uint256 numTokens); constructor() { token = new emissionsTradeToken(); owner = msg.sender; token.changeLeader(msg.sender); } function buy() payable public { uint256 amountTobuy = msg.value; uint256 dexBalance = token.balanceOf(address(this)); require(amountTobuy > 0, "You need to send some ether"); require(amountTobuy <= dexBalance, "Not enough tokens in the reserve"); token.transfer(msg.sender, amountTobuy); emit Bought(amountTobuy); } // function getbal(address wallet) public view returns (uint){return token.balanceOf(wallet);} // function isOwner() public view returns (address){return owner;} function sell(uint256 numTokens) public { require(numTokens > 0, "You need to sell at least some tokens"); uint256 allow = token.allowance(msg.sender, address(this)); require(allow >= numTokens, "Check the token allowance"); token.transferFrom(msg.sender, address(this), numTokens); payable(msg.sender).transfer(numTokens); emit Sold(numTokens); } }
aparently 結束是在 token.changeLeader(msg.sender) 因為當我把它拿出來的程式碼工作。
在 python 中,我呼叫合約的程式碼就是:
def deploy_contract(w3, acct, contract_interface): tx_hash = w3.eth.contract( abi=contract_interface['abi'], bytecode=contract_interface['bin']).constructor().transact({ # 'type': '0x2', 'from': acct.address, 'nonce': w3.eth.getTransactionCount(acct.address), 'maxFeePerGas': 50000000000, # required for dynamic fee transactions 'maxPriorityFeePerGas': 1000000000, # required for dynamic fee transactions }) print(tx_hash.hex()) contractReceipt = w3.eth.wait_for_transaction_receipt(tx_hash)
謝謝
正如你所說的問題是功能
changeLeader
function changeLeader(address newLeader) public override returns(bool){ require(leader == msg.sender); leader = newLeader; return true; }
它需要
leader
被初始化,但它永遠不會被初始化,因此它將是零地址,並且在呼叫changeLeader
它時會恢復,因為它與msg.sender
.