You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Solidity编译报错:UnimplementedFeatureError问题求助

解决Solidity编译错误:UnimplementedFeatureError

错误原因

你遇到的UnimplementedFeatureError: Copying of type struct ChatGroups.Message memory[] memory to storage not yet supported错误,根源在于isMember和isAdmin函数接收的是Group memory类型参数,但调用时传入的是存储在storage中的Group结构体实例。Solidity 0.6.x版本不支持将包含动态数组(此处为Message[])的结构体从storage拷贝到memory,这类拷贝逻辑尚未实现。

修复方案

将isMember和isAdmin函数的参数类型从Group memory改为Group storage,直接引用storage中的结构体,避免触发不支持的拷贝操作。修改后函数逻辑完全保留,仅参数类型调整。

修改后的完整合约代码

pragma solidity ^0.6.12;

contract ChatGroups {
    struct Group {
        string name;
        address[] members;
        Message[] messages;
    }

    struct Message {
        uint id;
        string text;
        address author;
        bool deleted;
    }

    Group[] groups;

    address[] users;

    event GroupCreated(uint groupId, string groupName);

    event MessagePublished(uint groupId, uint messageId, string messageText, address messageAuthor);

    event MessageDeleted(uint groupId, uint messageId);

    event UserAddedToGroup(uint groupId, address user);

    event UserRemovedFromGroup(uint groupId, address user);

    function createGroup(string memory groupName) public {
        require(isUser(msg.sender), "Unauthorized user");

        groups.push(Group({
            name: groupName,
            members: new address[](1),
            messages: new Message[](0)
        }));
        groups[groups.length - 1].members[0] = msg.sender;

        emit GroupCreated(groups.length, groupName);
    }

    function publishMessage(uint groupId, string memory messageText) public {
        require(isUser(msg.sender), "Unauthorized user");

        Group storage group = groups[groupId - 1];

        require(isMember(group, msg.sender), "Unauthorized user");

        group.messages.push(Message({
            id: group.messages.length + 1,
            text: messageText,
            author: msg.sender,
            deleted: false
        }));

        emit MessagePublished(groupId, group.messages[group.messages.length - 1].id, messageText, msg.sender);
    }

    function deleteMessage(uint groupId, uint messageId) public {
        require(isUser(msg.sender), "Unauthorized user");

        Group storage group = groups[groupId - 1];

        require(isMember(group, msg.sender) && group.messages[messageId - 1].author == msg.sender, "Unauthorized user");

        group.messages[messageId - 1].deleted = true;

        emit MessageDeleted(groupId, messageId);
    }

    function removeUser(uint groupId, address user) public {
        require(isUser(msg.sender), "Unauthorized user");

        Group storage group = groups[groupId - 1];

        require(isAdmin(group, msg.sender), "Unauthorized user");

        require(isMember(group, user), "Unauthorized user");

        uint index = getMemberIndex(group, user);
        group.members[index] = group.members[group.members.length - 1];
        group.members.length--;

        emit UserRemovedFromGroup(groupId, user);
    }

    function addUser(uint groupId, address user) public {
        require(isUser(msg.sender), "Unauthorized user");

        Group storage group = groups[groupId - 1];
        require(isAdmin(group, msg.sender), "Unauthorized user");

        require(!isMember(group, user), "User already member of group");

        group.members.push(user);

        emit UserAddedToGroup(groupId, user);
    }

    function isUser(address user) private view returns (bool) {
        for (uint i = 0; i < users.length; i++) {
            if (users[i] == user) {
                return true;
            }
        }
        return false;
    }

    // 修改:参数类型从Group memory改为Group storage
    function isMember(Group storage group, address user) public view returns (bool) {
        if (group.members[0] == user) {
            return true;
        }

        for (uint i = 1; i < group.members.length; i++) {
            if (group.members[i] == user) {
                return true;
            }
        }
        return false;
    }

    // 修改:参数类型从Group memory改为Group storage
    function isAdmin(Group storage group, address user) public view returns (bool) {
        if (group.members[0] == user) {
            return true;
        }

        for (uint i = 1; i < group.members.length; i++) {
            if (group.members[i] == user) {
                return true;
            }
        }
        return false;
    }

    function getMemberIndex(Group storage group, address user) private view returns (uint) {
        for (uint i = 0; i < group.members.length; i++) {
            if (group.members[i] == user) {
                return i;
            }
        }
        return group.members.length;
    }
}

说明

修改后的代码仅调整了两个辅助函数的参数类型,完全保留了你原有业务逻辑。通过使用Group storage直接引用合约存储中的结构体实例,避免了Solidity不支持的跨位置拷贝操作,从而解决编译错误。

内容的提问来源于stack exchange,提问作者BLF

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 09:35:22