以太坊Solidity文本编辑器智能合约读写删除功能编译问题求助
问题根因分析
- 存储结构缺陷:仅使用动态数组存储文本条目,无法通过坐标快速定位对应数据,你猜测需要用到mapping的思路是正确的,需要新增映射实现坐标到数组索引的快速查找
- 语法逻辑错误:
read函数不符合数组访问规则,Solidity动态数组仅支持uint类型索引访问,原代码直接传入文本内容、坐标作为索引会直接编译失败,同时返回值类型设计错误,要返回所有文本+对应坐标需返回结构体数组而非单字符串remove函数同样存在访问规则错误,且声明为private外部无法调用,未实现合法的数组元素删除逻辑
- 命名冲突:结构体属性
block是Solidity全局关键字,用于指代当前块信息,作为自定义变量名会触发编译报错
修复后可正常运行的完整代码
pragma solidity <0.9.0; contract TextEditor { // 替换block关键字为content避免命名冲突 struct Book { string content; bytes10 coordinates; } // 存储所有文本条目 Book[] public books; // 坐标到数组索引的映射,存储值为真实索引+1,0代表坐标不存在 mapping(bytes10 => uint) public coordToIndex; // 录入函数:校验坐标唯一后写入数据,不覆盖旧内容 function save(string calldata _content, bytes10 _coordinates) public { require(coordToIndex[_coordinates] == 0, "该坐标已存在对应文本"); books.push(Book(_content, _coordinates)); coordToIndex[_coordinates] = books.length; } // 查询函数:返回所有已录入的文本及对应坐标 function read() public view returns (Book[] memory) { return books; } // 删除函数:传入坐标删除对应条目,采用尾元素置换优化gas消耗 function remove(bytes10 _coordinates) public { uint recordIndex = coordToIndex[_coordinates]; require(recordIndex != 0, "待删除的坐标对应数据不存在"); // 还原为真实数组索引 recordIndex = recordIndex - 1; // 处理数组删除逻辑 Book memory lastRecord = books[books.length - 1]; books[recordIndex] = lastRecord; coordToIndex[lastRecord.coordinates] = recordIndex + 1; books.pop(); delete coordToIndex[_coordinates]; } }
功能说明
- 录入逻辑:新增坐标唯一性校验,避免同一位置重复写入,新录入内容追加到数组末尾不会覆盖旧数据
- 查询逻辑:直接返回完整的结构体数组,可直接遍历获取所有文本内容和对应坐标
- 删除逻辑:采用数组尾元素置换待删除元素的实现方式,避免数组空位,大幅降低删除操作的gas消耗
内容的提问来源于stack exchange,提问作者Daniel M
相关产品推荐
相关产品推荐

