I have a problem that's probably very basic, but I cannot seem to figure the issue out

function _CreateBike(uint id, uint generation, string model, string ability, uint8 tier) internal returns(Bike){
    Bike memory bike = Bike(id, generation, 1, tier, model, ability, msg.sender);
    return bike;

I have this function above that creates a struct and pushes it to an array, and it works as intended

function BuyBike(string model, string ability, uint8 tier) public payable costs(basePrice*tier) {
    Bike memory bike = _CreateBike(garage.length, current_generation, model, ability, tier);
    ownedBikes[msg.sender] = [bike.id];

however when I run this function which calls on the earlier function, the struct doesn't get added to the array. I assume this has something to do with reference variables and storage in the blockchain vs local memory, but I still cannot figure out how to fix the problem after checking stackoverflow and the solidity docs. Can someone please tell me what's going on?

  • Your second function seems to be missing a semicolon. That shouldn't compile. Make sure you're sharing the actual code you're using.
    – user19510
    Commented Jan 13, 2018 at 2:13
  • Sure, I edited the code to make it a bit more general purpose, but I modified my question to include the actual code. Commented Jan 13, 2018 at 2:16
  • This code seems to be working fine for me. I made up a struct Bike { ... } with the seven fields you were passing and a Bike[] public garage and a hardcoded uint current_generation = 1, I dropped the costs modifier from BuyBike, and then I called BuyBike("model", "ability", 8) and verified that both garage[0] and garage[1] had the expected Bike struct in them. (It gets added twice, since it gets added in both _CreateBike and BuyBike.)
    – user19510
    Commented Jan 13, 2018 at 2:21
  • Looks like you just dropped one of the pushes. With that modification, it only gets added to garage once. (I also dropped the ownedBikes line rather than declare another variable.)
    – user19510
    Commented Jan 13, 2018 at 2:22
  • I should add that my testing was in Remix via the JavaScript VM. If you're still seeing issues, perhaps share any other relevant code (like the actual variable declarations and the modifier you're using), tell us how you're deploying and testing the contract, and show us how you're calling BuyBike and how you're checking the result.
    – user19510
    Commented Jan 13, 2018 at 2:24

2 Answers 2


Summarizing the comments into an answer:

The issue is the costs modifier, which presumably tests msg.value. Since there's no way (that I'm aware of) to attach ether to a transaction in Remix when using the JavaScript VM, there's no way to satisfy the msg.value requirement, so the function presumably reverted.

  • I just tested this and I can send Ether to a contract using the "Value" field below where the Environment is selected in Remix.
    – willjgriff
    Commented Jan 18, 2018 at 11:53

Adding to smarx's answer, a way to test in a more production-like enviroment is using a private net, wch could be either ganache or ganache-cli, or a coustom private testnet built with geth. I'm sure there are other optios, but those are the ones i use and know that work.

Friendly disclaimer: some private testnets have their own issues (e.g. ganache doesn't have support for websockets, so event's won't work with web3 1.0, private testnets with geth can have different consensus algorithms than mainnet), so don't use them as a final test before sending code to the main net unless you are sure your code will work the same way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.