Solidity智能合约:函数中的return参数的数据位置必须是"memory"或"calldata",但给出了none
Solidity smart contract: Data location must be "memory" or "calldata" for return parameter in function, but none was given
我正在探索 solidity 中的以太坊和智能合约开发。在一个简单的 todo 应用程序智能合约中,我收到以下错误:
我的代码:
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,
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 在试图 return 字符串的 getTask() 函数中。
原问题的答案
Solidity中的字符串内部处理为字符数组,对于数组等动态值需要指定return值的数据位置(见下图)
那是因为 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,
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,例如,数组的数组,或者在您的情况下,结构的数组。
我正在探索 solidity 中的以太坊和智能合约开发。在一个简单的 todo 应用程序智能合约中,我收到以下错误:
我的代码:
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,
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 在试图 return 字符串的 getTask() 函数中。
原问题的答案
Solidity中的字符串内部处理为字符数组,对于数组等动态值需要指定return值的数据位置(见下图)
那是因为 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,
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,例如,数组的数组,或者在您的情况下,结构的数组。