原本的程式码是可以编译后部署的,但我新增两个function之后,一样可以编译,也能在Remix的VM上成功部署,但如果切换成测试链:Goerli、BSC Testnet,部署就会报错:Failed transaction Transaction 2 failed! [ethjs-query] while formatting outputs from RPC '{"value": {"code": -32603,"data": {"message":"Internal Server Error"}}}'
新增两个function:searchCampaigns、getCampaignsByCategory,部署出现错误,请问到底是哪里有问题?
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;
contract CrowdFunding {
struct Campaign{
address owner;
string title;
string description;
string[] categories;
uint256 target;
uint256 deadline;
uint256 amountCollected;
string image;
string details;
address[] donators;
uint256[] donations;
}
mapping(uint256=>Campaign)public campaigns;
uint256 public numberOfCampaigns = 0;
function createCampaign(address _owner, string memory _title, string memory _description,string[] memory _category, uint256 _target, uint256 _deadline, string memory _image,string memory _details) public returns (uint256){
//将类别array push进来
Campaign storage campaign = campaigns[numberOfCampaigns];
// is everything okay?
require(campaign.deadline < block.timestamp, "The deadline should be a date in the future.");
campaign.owner = _owner;
campaign.title = _title;
campaign.description = _description;
for(uint i = 0; i < _category.length; i++){
campaign.categories.push(_category[i]);
}
campaign.target = _target;
campaign.deadline = _deadline;
campaign.amountCollected = 0;
campaign.image = _image;
campaign.details = _details;
numberOfCampaigns++;
return numberOfCampaigns - 1;
}
function donateToCampaign(uint256 _id) public payable {
uint256 amount = msg.value;
Campaign storage campaign = campaigns[_id];
campaign.donators.push(msg.sender);
campaign.donations.push(amount);
(bool sent,) = payable(campaign.owner).call{value: amount}("");
if(sent){
campaign.amountCollected = campaign.amountCollected + amount;
}
}
function getDonators(uint _id) view public returns (address[] memory, uint256[] memory){
return (campaigns[_id].donators, campaigns[_id].donations);
}
function getCampaigns() public view returns (Campaign[] memory) {
Campaign[] memory allCampaigns = new Campaign[](numberOfCampaigns);
for(uint i = 0 ; i < numberOfCampaigns ; i++){
Campaign storage item = campaigns[i];
allCampaigns[i] = item;
}
return allCampaigns;
}
//新增以下两个function之后就出现错误了
function searchCampaigns(string memory _searchText) public view returns (Campaign[] memory) {
Campaign[] memory matchedCampaigns = new Campaign[](numberOfCampaigns);
uint256 count = 0;
for(uint i = 0 ; i < numberOfCampaigns ; i++){
Campaign storage item = campaigns[i];
bytes memory titleBytes = bytes(item.title);
bytes memory searchTextBytes = bytes(_searchText);
if (titleBytes.length >= searchTextBytes.length) {
bool isMatch = true;
for (uint j = 0; j < searchTextBytes.length; j++) {
if (titleBytes[j] != searchTextBytes[j]) {
isMatch = false;
break;
}
}
if (isMatch) {
matchedCampaigns[count] = item;
count++;
}
}
}
Campaign[] memory result = new Campaign[](count);
for(uint i = 0 ; i < count ; i++){
result[i] = matchedCampaigns[i];
}
return result;
}
function getCampaignsByCategory(string memory _category) public view returns (Campaign[] memory) {
Campaign[] memory matchingCampaigns = new Campaign[](numberOfCampaigns);
uint256 matchingCampaignsCount = 0;
for(uint i = 0 ; i < numberOfCampaigns ; i++){
Campaign storage item = campaigns[i];
// 检查当前 Campaign 是否包含选中的类别
bool containsCategory = false;
for(uint j = 0 ; j < item.categories.length ; j++){
if(keccak256(bytes(item.categories[j])) == keccak256(bytes(_category))){
containsCategory = true;
break;
}
}
if(containsCategory){
matchingCampaigns[matchingCampaignsCount] = item;
matchingCampaignsCount++;
}
}
// 复制匹配到的 Campaign 到一个新的数组中,长度为匹配到的数量
Campaign[] memory result = new Campaign[](matchingCampaignsCount);
for(uint i = 0 ; i < matchingCampaignsCount ; i++){
result[i] = matchingCampaigns[i];
}
return result;
}
}