TransWikia.com

Use Values Returned from One Function in Another

Ethereum Asked by Kevin Phillips on December 27, 2021

need a little help if you can spare the time.

Making a little card game where people can collect “warrior” cards.

We’ll have an initial 12 master “cards” that supply the initial traits for the warriors. I have a struct “Card” for those and they’re in an array “cards”.

The idea is that someone who wants to collect a particular card will click on it in our dapp, the id of that card will be passed to a function “addWarrior”. That function will first call “getCard” that will retrieve the specifics of that card and then call “createWarrior” to use those details to make a copy of the card. That copy is a Struct called “Warrior” and goes into an array called “warriors”.

I’m pretty close to getting it working in Remix. I’m getting an “Invalid implicit conversion” type error when I try to compile the contract.

browser/warriors.sol:61:23: TypeError: Invalid type for argument in function call. Invalid implicit conversion from type(string storage pointer) to string memory requested.
createWarrior(string, uint16, uint16, uint16, uint16, uint16, uint16, uint16, uint16);
^—-^”

Here’s my contract code:

pragma solidity ^0.5.0;

contract WarriorFactory {

struct Card {
    string cardName;
    uint16 cardLevel;
    uint16 cardAttack;
    uint16 cardDefend;
    uint16 cardStrategy;
    uint16 cardIssued;
    uint16 maxCards;
}
Card[] public cards;

struct Warrior {
    string warName;
    uint16 level;
    uint16 attack;
    uint16 defend;
    uint16 strategy;
    uint16 winCount;
    uint16 lossCount;
    uint16 warNumber;
    uint16 maxWarriors;
}

Warrior[] public warriors;

function createCard(string memory _cardName, uint16 _cardLevel, uint16 _cardAttack, uint16 _cardDefend, uint16 _cardStrategy, uint16 _cardIssued, uint16 _maxCards) public {
    cards.push(Card(_cardName, _cardLevel, _cardAttack, _cardDefend, _cardStrategy, _cardIssued, _maxCards));
}

function getCard(uint256 id) public view returns (
    string memory _warName,
    uint16 _level,
    uint16 _attack,
    uint16 _defend,
    uint16 _strategy,
    uint16 _warNumber,
    uint16 _maxWarriors) {
        Card storage Crd = cards[id];
        _warName = string(Crd.cardName);
        _level = uint16(Crd.cardLevel);
        _attack = uint16(Crd.cardAttack);
        _defend = uint16(Crd.cardDefend);
        _strategy = uint16(Crd.cardStrategy);
        _warNumber = uint16(Crd.cardIssued);
        _maxWarriors = uint16(Crd.maxCards);

    }

function createWarrior(string memory _warName, uint16 _level, uint16 _attack, uint16 _defend, uint16 _strategy, uint16 _winCount, uint16 _lossCount, uint16 _warNumber, uint16 _maxWarriors) public {
    _winCount = 0;
    _lossCount = 0;
    warriors.push(Warrior(_warName, _level, _attack, _defend, _strategy, _winCount, _lossCount, _warNumber, _maxWarriors));
}

function addWarrior(uint256 id) public {
    getCard(id);
    createWarrior(string, uint16, uint16, uint16, uint16, uint16, uint16, uint16, uint16);
}

}

Any ideas on how to clear that up? Or should I be structuring this differently?

I’ve currently got all the functions set to “public” just to keep initial testing easy, I expect to change those so the “helper functions” will only be called internally before going live.

Thanks a bunch in advance for any advice you can give.
Kevin

One Answer

The compiler is upset because the arguments in createWarrior are really types with no values. You can see the errors resolve like this:

function addWarrior(uint256 id) public {
    getCard(id);
    string memory something;
    uint16 something1;
    uint16 something2;
    createWarrior(something, something1, something2, uint16, uint16, uint16, uint16, uint16, uint16);
}

To work with returned values:

function callee(uint arg) public pure returns(bool, uint) {
  return(arg==1, 10);
}

function caller() public pure returns(bool success) {
  bool b;
  uint u;
  (b,u) = callee(1);
}

You're using a very heavy data structure with a lot of data passed around. I'd suggest a leaner approach to this using unique identifiers for both entities.

For example, if mappings are used:

function addCardToWarrior(bytes32 warriorId, bytes32 cardId) public {
  warrior[warriorId].cards.push(cardId);
}

Have a look over here: Are there well-solved and simple storage patterns for Solidity?

Hope it helps.

Answered by Rob Hitchens on December 27, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP