Solidity
未能將乙太幣從父合約轉移到子合約
我創建了一個契約工廠(父契約)來創建一個子契約。在父合約中,有一個功能,通過輸入子合約地址,將父合約的餘額轉移到子合約。我發現當接收函式是普通的(接收函式中沒有其他動作)時,傳輸會成功。當我添加其他操作(例如更改狀態變數)時,事務將失敗並顯示錯誤:
transact to ContractFactory.pay errored: VM error: revert. revert The transaction has been reverted to the initial state. Note: The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information.
這是合約程式碼:
pragma solidity >=0.6.0 <0.8.0; contract ContractFactory { address[] contractsAddress; mapping(address => Contract) private contracts; function createContract(uint price) public { Contract newContract = new Contract(msg.sender, price); contractsAddress.push(address(newContract)); contracts[address(newContract)] = newContract; } receive() external payable{ } function pay(address payable contractAddress) public payable{ contractAddress.transfer(address(this).balance); } function getAllContractsAddress() view public returns(address[] memory) { return contractsAddress; } } contract Contract { enum Status {Unavailable, Available} Status public contractStatus; address payable public contractOwner; address payable public buyer; uint public price; event Occupy(address _occupant); constructor(address payable _contractOwner, uint _price) { contractOwner = _contractOwner; price = _price; contractStatus = Status.Available; } modifier onlyWhenAvailable { require(contractStatus == Status.Available); _; } modifier notOwner { require(msg.sender != contractOwner); _; } modifier payEnoughAmount { uint priceInEther = price * 1 ether; require(msg.value >= priceInEther); _; } receive() external payable onlyWhenAvailable notOwner payEnoughAmount { contractStatus = Status.Unavailable; buyer = msg.sender; } }
你需要改變:
contractAddress.transfer(address(this).balance);
到:
contractAddress.call{value: address(this).balance}("");
為什麼?因為在使用方法時
transfer()
,send()
被呼叫的合約只能使用 2300 gas,這顯然不足以更新狀態。這就是為什麼當receive
合約方法Contract
為空並且不更新被呼叫合約的狀態時您的函式成功的原因。