问题描述
我正在 solidity 中探索以太坊和智能合约的开发。在一个简单的待办事项应用程序智能合约中,我收到以下错误:
我的代码如下:
pragma solidity ^0.4.4;
contract Todo {
struct Task{
uint id;
uint date;
string content;
string author;
bool completed;
}
Task[] tasks;
function createTask(string memory _content,string memory _author) public {
tasks.push(Task(tasks.length,block.timestamp,_content,_author,false));
}
function getTask(uint id) public view
returns(
uint,uint,string memory,bool
) {
return(
id,tasks[id].date,tasks[id].content,tasks[id].author,tasks[id].completed
);
}
function getAllTasks() external view returns(Task[]){
return tasks;
}
}
错误行是 20 和 21 在试图返回字符串的 getTask() 函数中。
解决方法
回答原问题
Solidity 中的字符串在内部被处理为字符数组,对于数组等动态值,需要指定返回值的数据位置(见下图)。
那是因为 Solidity 作为一种语言,是基于 C++ 和 JS 的。
此外,(“官方”)Solidity 编译器和相关实用程序是用 C++ 编写的,并且您没有 C 或 C++ 中的字符串。只是字符数组,所以这可能是将 Solidity 中的字符串作为字符数组处理的原因。
...
// You should consider using "blockchain.timestamp" instead of "now".
function createTask(string memory _content,string memory _author) public {
tasks.push(Task(tasks.length,now,_content,_author,false));
}
function getTask(uint id) public view
returns(
uint,uint,string memory,bool
) {
return(
id,tasks[id].date,tasks[id].content,tasks[id].author,tasks[id].completed // Also,removed the comma here because it would drop an empty tuple error.
);
}
...
回答较新的问题
TypeError: This type is only supported in the new experimental ABI encoder.
确保在代码顶部添加 pragma experimental ABIEncoderV2;
,因为 solidity versions under 0.8.0 don't support dynamic arrays with a depth level deeper than 1 by default,and you'll need to enable the experimental ABI for it to work,例如,数组数组,或者在您的情况下,是结构数组。