Solidity众筹合约kill函数编译报Expected '('及ParseError问题求助
Solidity众筹合约报错修复方案
你遇到的编译报错核心原因是函数嵌套违规,此外还有多处版本兼容、语法拼写、逻辑错位问题,全部问题及修复方式如下:
1 直接报错根因
你将kill()函数定义在了checkGoalReached()函数的内部,Solidity所有版本都不支持函数内嵌套定义合约级函数,编译器无法识别内部的函数定义语法,就会报你遇到的括号匹配、标识符错误。
修复方式:将kill()函数整体移动到checkGoalReached()函数的闭合花括号}外部。
2 其他需修复的语法/版本兼容问题
- 关键字拼写错误:销毁函数名写错,
selfdestrct改为selfdestruct - 全局变量废弃:0.8.9版本已移除
now全局变量,统一替换为block.timestamp - 构造函数写法错误:0.6+版本不再支持用合约名小写作为构造函数,需改为
constructor关键字,同时构造函数内给owner赋值的操作写了双等号==(比较运算符),要改为单等号=(赋值运算符) - 类型不匹配:
isOver是bool类型,赋值时不要加引号,isOver = "false"改为isOver = false - 地址属性语法更新:
this.balance在0.8+版本需改为address(this).balance - 废弃关键字:
throw已在0.4.22+版本弃用,改为transfer+自动回滚逻辑实现同等效果 - 逻辑错位:当前退款逻辑写在了给项目方转账失败的分支中,正确逻辑是众筹未达标时直接进入退款分支,需调整
if/else的配对位置
3 修复后完整代码
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.9; contract CrowdFunding { struct Investor { address addr; uint amount; } address public owner; uint public NumOfInvestors; uint public deadline; string public status; bool public isOver; uint public goalAmount; uint public totalAmount; mapping (uint => Investor) public investors; modifier onlyOwner () { require(msg.sender == owner, "Only owner can call this function"); _; } // 修正为标准constructor写法 constructor(uint _duration, uint _goalAmount) public { owner = msg.sender; // 双等号改单等号 deadline = block.timestamp + _duration; // now替换为block.timestamp goalAmount = _goalAmount; status = "Funding"; isOver = false; // 去掉引号,改为bool类型值 NumOfInvestors = 0; totalAmount = 0; } function fund() payable public { require(!isOver, "Campaign is already over"); Investor storage inv = investors[NumOfInvestors++]; // 增加storage关键字,操作链上存储 inv.addr = msg.sender; inv.amount = msg.value; totalAmount += inv.amount; } function checkGoalReached () public onlyOwner { require(!isOver, "Campaign is already over"); require(block.timestamp >= deadline, "Campaign is not ended yet"); if(totalAmount >= goalAmount) { status = "Campaign succeeded."; isOver = true; // 给项目方转账 payable(owner).transfer(address(this).balance); } else // 修正else配对位置,众筹未达标直接进入退款分支 { uint i = 0; status = "Campaign Failed."; isOver = true; while (i < NumOfInvestors) // 修正边界,避免数组越界 { // 给投资人退款 payable(investors[i].addr).transfer(investors[i].amount); i++; } } } // kill函数移到合约级作用域 function kill() public onlyOwner { selfdestruct(payable(owner)); // 修正拼写,owner转payable类型 } }
内容的提问来源于stack exchange,提问作者Cyan
相关产品推荐
相关产品推荐

