The compiler is complaining because you've wandered into reference variables. Not to worry, we don't want to be there.
Another issue is you've got a dynamic array in the function arguments. It's not possible because the interface doesn't support it. That's okay, too. We don't want that either.
We need to break it down so we're only ever passing in fixed size, non-complex values, which means tiny single-purpose functions.
I ended up restructuring the storage to a layout I think is more appropriate. Then created some exemplary functions to work with the data.
- Insert question
- Insert answer
- Get question by key
- Get answer by question key and answer key
- Get question count
- Get question key by row number
- Get answer count for a question by question key
- Get answer key for a question by question key and row number
Here's a way to combine structs with arrays and mappings in a way I think is a good start given the one-to-many Q&A relationship. And, some examples of simple functions that don't pass arguments that are too complex for Solidity.
No warranty, but hopefully this gives you some ideas.
pragma solidity ^0.4.6;
contract Quiz {
struct Answer
{
bytes32 text;
uint voteCount; // number of accumulated votes
// add more non-key fields as needed
}
struct Question
{
bytes32 text;
bytes32[] answerList; // list of answer keys so we can look them up
mapping(bytes32 => Answer) answerStructs; // random access by question key and answer key
// add more non-key fields as needed
}
mapping(bytes32 => Question) questionStructs; // random access by question key
bytes32[] questionList; // list of question keys so we can enumerate them
function newQuestion(bytes32 questionKey, bytes32 text)
// onlyOwner
returns(bool success)
{
// not checking for duplicates
questionStructs[questionKey].text = text;
questionList.push(questionKey);
return true;
}
function getQuestion(bytes32 questionKey)
public
constant
returns(bytes32 wording, uint answerCount)
{
return(questionStructs[questionKey].text, questionStructs[questionKey].answerList.length);
}
function addAnswer(bytes32 questionKey, bytes32 answerKey, bytes32 answerText)
// onlyOwner
returns(bool success)
{
questionStructs[questionKey].answerList.push(answerKey);
questionStructs[questionKey].answerStructs[answerKey].text = answerText;
// answer vote will init to 0 without our help
return true;
}
function getQuestionAnswer(bytes32 questionKey, bytes32 answerKey)
public
constant
returns(bytes32 answerText, uint answerVoteCount)
{
return(
questionStructs[questionKey].answerStructs[answerKey].text,
questionStructs[questionKey].answerStructs[answerKey].voteCount);
}
function getQuestionCount()
public
constant
returns(uint questionCount)
{
return questionList.length;
}
function getQuestionAtIndex(uint row)
public
constant
returns(bytes32 questionkey)
{
return questionList[row];
}
function getQuestionAnswerCount(bytes32 questionKey)
public
constant
returns(uint answerCount)
{
return(questionStructs[questionKey].answerList.length);
}
function getQuestionAnswerAtIndex(bytes32 questionKey, uint answerRow)
public
constant
returns(bytes32 answerKey)
{
return(questionStructs[questionKey].answerList[answerRow]);
}
}
A notable shortcoming with this example is it isn't checking if keys exist or enforcing uniqueness. I left that out for brevity but it's easily added to this pattern. More details here. https://medium.com/@robhitchens/solidity-crud-part-1-824ffa69509a#.gvh9pf1gj
Hope it helps.