Geth + smart contract function = bad instruction - ethereum

playing with ethereum smart contracts I encountered a following problem. The contract gets deployed on Ropsten and then I'm trying to call function 'addRecipe' with the following code on geth:
recipes.addRecipe(300, "zupa", "zupa z trupa", {from:web3.eth.accounts[0], gas: 20000000})
The function looks as following:
function addRecipe(uint256 _price, string _name, string _content) public {
recipes[recipeCount].price = _price;
recipes[recipeCount].name = _name;
recipes[recipeCount].content = _content;
recipes[recipeCount].recipeOwner = msg.sender;
recipeCount++;
}
I get the TX hash but looking up the transaction in Etherscan gives
Warning! Error encountered during contract execution [Bad instruction]
You can check it up here:
https://ropsten.etherscan.io/tx/0xe5999c2d122e4871e82f5986397dfd39107cee2056a9280132abeaa460c0f66d
Adding 'payable' modifier to the function or using the following command doesn't give any better results...
recipes.addRecipe.sendTransaction(300, "zupa", "zupa z trupa", {from:web3.eth.accounts[0], gas: 200000000})
The whole contract:
pragma solidity ^0.4.24;
contract Recipes {
address owner;
uint256 recipeCount = 0;
struct Recipe {
string name;
string content;
uint256 price;
address recipeOwner;
}
Recipe[] public recipes;
function () public {
owner = msg.sender;
}
function kill() public {
require (msg.sender == owner);
selfdestruct(owner);
}
function addRecipe(uint256 _price, string _name, string _content) public {
recipes[recipeCount].price = _price;
recipes[recipeCount].name = _name;
recipes[recipeCount].content = _content;
recipes[recipeCount].recipeOwner = msg.sender;
recipeCount++;
}
function showRecipes(uint256 _id) constant returns(string) {
return recipes[_id].content;
}
}

recipes is a dynamic storage array. You need to change the size of the array to add new elements to it. You can either do this by explicitly increasing the length of the array or by pushing a new element into the array.
function addRecipe(uint256 _price, string _name, string _content) public {
recipes.length++;
recipes[recipeCount].price = _price;
recipes[recipeCount].name = _name;
recipes[recipeCount].content = _content;
recipes[recipeCount].recipeOwner = msg.sender;
recipeCount++;
}
Or
function addRecipe(uint256 _price, string _name, string _content) public {
Recipe memory r;
r.price = _price;
r.name = _name;
r.content = _content;
r.recipeOwner = msg.sender;
recipes.push(r);
recipeCount++;
}

Related

DeclarationError: Undeclared identifier. "..." is not visible at this point

I am practising this tutorial in Remix IDE - https://www.youtube.com/watch?v=_aXumgdpnPU
I saw in the Chainlink documentation that their Randomness VRF code has been changed since the development of the video.
I started replacing the parts and trying to deploy the class via Remix but it gives an error which I am not sure how to fix.
Would you be able to check what I have as code and I'll send a screenshot of the error?
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.11;
import "#chainlink/contracts/src/v0.8/ConfirmedOwner.sol";
import "#chainlink/contracts/src/v0.8/VRFV2WrapperConsumerBase.sol";
contract Lottery is
VRFV2WrapperConsumerBase,
ConfirmedOwner
{
address public owner;
address payable[] public players;
uint public lotteryId;
mapping (uint => address payable) public lotteryHistory;
event RequestSent(uint256 requestId, uint32 numWords);
event RequestFulfilled(
uint256 requestId,
uint256[] randomWords,
uint256 payment
);
struct RequestStatus {
uint256 paid; // amount paid in link
bool fulfilled; // whether the request has been successfully fulfilled
uint256[] randomWords;
}
mapping(uint256 => RequestStatus)
public s_requests; /* requestId --> requestStatus */
// past requests Id.
uint256[] public requestIds;
uint256 public lastRequestId;
// Depends on the number of requested values that you want sent to the
// fulfillRandomWords() function. Test and adjust
// this limit based on the network that you select, the size of the request,
// and the processing of the callback request in the fulfillRandomWords()
// function.
uint32 callbackGasLimit = 100000;
// The default is 3, but you can set this higher.
uint16 requestConfirmations = 3;
// For this example, retrieve 2 random values in one request.
// Cannot exceed VRFV2Wrapper.getConfig().maxNumWords.
uint32 numWords = 2;
// Address LINK - hardcoded for Goerli
address linkAddress = 0x326C977E6efc84E512bB9C30f76E30c160eD06FB;
// address WRAPPER - hardcoded for Goerli
address wrapperAddress = 0x708701a1DfF4f478de54383E49a627eD4852C816;
constructor()
ConfirmedOwner(msg.sender)
VRFV2WrapperConsumerBase(linkAddress, wrapperAddress)
{
owner = msg.sender;
lotteryId = 1;
}
function requestRandomWords()
external
onlyOwner
returns (uint256 requestId)
{
requestId = requestRandomness(
callbackGasLimit,
requestConfirmations,
numWords
);
s_requests[requestId] = RequestStatus({
paid: VRF_V2_WRAPPER.calculateRequestPrice(callbackGasLimit),
randomWords: new uint256[](0),
fulfilled: false
});
requestIds.push(requestId);
lastRequestId = requestId;
emit RequestSent(requestId, numWords);
return requestId;
}
function fulfillRandomWords(
uint256 _requestId,
uint256[] memory _randomWords
) internal override {
require(s_requests[_requestId].paid > 0, "request not found");
s_requests[_requestId].fulfilled = true;
s_requests[_requestId].randomWords = _randomWords;
emit RequestFulfilled(
_requestId,
_randomWords,
s_requests[_requestId].paid
);
payWinner();
}
function getRequestStatus(
uint256 _requestId
)
external
view
returns (uint256 paid, bool fulfilled, uint256[] memory randomWords)
{
require(s_requests[_requestId].paid > 0, "request not found");
RequestStatus memory request = s_requests[_requestId];
return (request.paid, request.fulfilled, request.randomWords);
}
/**
* Allow withdraw of Link tokens from the contract
*/
function withdrawLink() public onlyOwner {
LinkTokenInterface link = LinkTokenInterface(linkAddress);
require(
link.transfer(msg.sender, link.balanceOf(address(this))),
"Unable to transfer"
);
}
function getWinnerByLottery(uint lottery) public view returns (address payable) {
return lotteryHistory[lottery];
}
function getBalance() public view returns (uint) {
return address(this).balance;
}
function getPlayers() public view returns (address payable[] memory) {
return players;
}
function enter() public payable {
require(msg.value > .01 ether);
// address of player entering lottery
players.push(payable(msg.sender));
}
//function getRandomNumber() public view returns (uint) {
//return uint(keccak256(abi.encodePacked(owner, block.timestamp)));
//}
function pickWinner() public onlyowner {
requestRandomWords;
}
function payWinner() public {
uint index = lastRequestId % players.length;
players[index].transfer(address(this).balance);
lotteryHistory[lotteryId] = players[index];
lotteryId++;
// reset the state of the contract
players = new address payable[](0);
}
modifier onlyowner() {
require(msg.sender == owner);
_;
}
}
enter image description here

Function Max mint per wallet is not working

learning solidity and curious how i can limit the minting of my NFT to only 2 per wallet address. Trying to prevent people from minting more then 2 tokens i add Maxfreemint and is working but to set max per wallet is not working please if you can provide me code solution because i try lot of solution but is not working.
pragma solidity >=0.8.9 <0.9.0;
import 'erc721a/contracts/extensions/ERC721AQueryable.sol';
import '#openzeppelin/contracts/access/Ownable.sol';
import '#openzeppelin/contracts/utils/cryptography/MerkleProof.sol';
import '#openzeppelin/contracts/security/ReentrancyGuard.sol';
contract DD is ERC721AQueryable, Ownable, ReentrancyGuard {
using Strings for uint256;
string public baseURI = '';
string public uriSuffix = '.json';
uint256 public cost;
uint256 public maxSupply;
uint256 public maxFreeMint = 4;
uint256 public maxMintAmountPerWallet = 2;
mapping(address => uint256) private _freeWalletMints;
bool public paused = true;
constructor(
string memory _tokenName,
string memory _tokenSymbol,
uint256 _cost,
uint256 _maxSupply
) ERC721A(_tokenName, _tokenSymbol) {
setCost(_cost);
maxSupply = _maxSupply;
}
modifier mintCompliance(uint256 _mintAmount) {
require(_mintAmount > 0, 'Invalid mint amount!');
require(totalSupply() + _mintAmount <= maxSupply, 'Max supply exceeded!');
_;
}
function mint(uint256 _mintAmount) public payable mintCompliance(_mintAmount){
if(msg.sender != owner()){
require(!paused, 'The contract is paused!');
require(_freeWalletMints[_msgSender()] + _mintAmount <= 2, 'You have already minted');
if (totalSupply()+_mintAmount > maxFreeMint){
require(msg.value >= cost * _mintAmount, "Insufficient funds!");
}
}
_safeMint(_msgSender(), _mintAmount);
}
function _startTokenId() internal view virtual override returns (uint256) {
return 1;
}
function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) {
require(_exists(_tokenId), 'ERC721Metadata: URI query for nonexistent token');
string memory currentBaseURI = _baseURI();
return bytes(currentBaseURI).length > 0
? string(abi.encodePacked(currentBaseURI, _tokenId.toString(), uriSuffix))
: '';
}
function setCost(uint256 _cost) public onlyOwner {
cost = _cost;
}
function setBaseURI(string memory _url) public onlyOwner {
baseURI = _url;
}
function setUriSuffix(string memory _uriSuffix) public onlyOwner {
uriSuffix = _uriSuffix;
}
function setPaused(bool _state) public onlyOwner {
paused = _state;
}
function withdraw() public onlyOwner nonReentrant {
(bool os, ) = payable(owner()).call{value: address(this).balance}('');
require(os);
}
function _baseURI() internal view virtual override returns (string memory) {
return baseURI;
}
}

Why am i getting an error on the array length in solidity?

I am developing an NFT smart contract with solidity and am encountering a strange error. I use some functions to add data to mappings inside the contract, both of them loop through arrays that are passed into the contract. They look like this.
function addNameDescImagePricesTowers(
uint[] memory ids, string[] memory propertyNames, uint[] memory prices,
string[] memory descs, string[] memory images, string[] memory towers, string[] memory districts, string[] memory neighs
) public onlyOwner() {
console.log("Started to add base data");
for (uint i = 0; i < ids.length; i ++){
defaultProperties[ids[i]-1] =
PropertyAttributes({
id: ids[i],
propertyIndex: ids[i]-1,
name: propertyNames[i],
description: descs[i],
image:images[i],
features: Features({
tower: towers[i],
district: districts[i],
neighborhood: neighs[i],
primary_type: '',//primeTypes[i],
sub_type_1: '',//subType1[i],
sub_type_2: '',//subType2[i],
structure: '',//structures[i],
feature_1: '',//feature1[i],
feature_2: '',//feature2[i],
feature_3: '',//feature3[i],
feature_4: '',//feature4[i],
feature_5: '',//feature5[i],
feature_6: ''//raritys[i]
}),
extensionCount: 0
});
//created minted list with all false
MintedNfts[ids[i]] = false;
//record the mint price
MintPrice[ids[i]] = prices[i] * (1 ether);
}
console.log("added base data");
}
function addNftData(uint[] memory ids, string[] memory primes,string[] memory subs1, string[] memory subs2, string[] memory structures, string[] memory fets1,
string[] memory fets2, string[] memory fets3, string[] memory fets4, string[] memory fets5, string[] memory fets6
) public onlyOwner() {
for (uint i = 0; i < ids.length; i ++){
uint id = ids[i];
PropertyAttributes memory x = defaultProperties[id-1];
// x.neighborhood = neighs[i];
x.features.primary_type = primes[i];
x.features.sub_type_1 = subs1[i];
x.features.sub_type_2 = subs2[i];
x.features.structure = structures[i];
x.features.feature_1 = fets1[i];
x.features.feature_2 = fets2[i];
x.features.feature_3 = fets3[i];
x.features.feature_4 = fets4[i];
x.features.feature_5 = fets5[i];
x.features.feature_6 = fets6[i];
defaultProperties[i] = x;
}
console.log("added the core data");
}
However when i run the contract I get an error on the second function:
TypeError: Cannot read property 'length' of undefined
As I am passing the exactly the same ids array into the function each time I don't understand why the first one runs fine but the second gives the error?
Here is the js code that runs the functions:
let txn;
//add basic property detials
txn = await propertyContract.addNameDescImagePricesTowers(ids,names,prices,descs,images, towers,districts)
await txn.wait();
//add remainign detials
txn = await propertyContract.addNftData( ids, neighs, primes, sub1s, sub2s, structures, fet1s, fet2s, fet3s, fet4s, fet5s, raritys);
await txn.wait();
The whole contract looks like this:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;
import "hardhat/console.sol";
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
//import '#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol';
//access control
import "#openzeppelin/contracts/access/Ownable.sol";
// Helper functions OpenZeppelin provides.
import "#openzeppelin/contracts/utils/Counters.sol";
import "#openzeppelin/contracts/utils/Strings.sol";
import "./libraries/Base64.sol";
contract MetropolisWorldGenesis is ERC721, Ownable {
// The tokenId is the NFTs unique identifier, it's just a number that goes
// 0, 1, 2, 3, etc.
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
string private _contractURI;
struct Extension {
string catergory;
string name;
string contractId;
string tokenId;
}
struct PropertyAttributes {
uint id;
uint propertyIndex;
string name;
string description;
string image;
Features features;
uint extensionCount;
}
struct Features {
string tower;
string district;
string neighborhood;
string primary_type;
string sub_type_1;
string sub_type_2;
string structure;
string feature_1;
string feature_2;
string feature_3;
string feature_4;
string feature_5;
string feature_6;
}
//store a list of all the NFT's available to mint.
//this is built on when the constructor is called.
mapping(uint => PropertyAttributes) defaultProperties;
//PropertyAttributes[] defaultProperties;
//store which has been minted.
mapping(uint => bool) public MintedNfts;
//store mint prices
mapping(uint => uint) public MintPrice;
//map the nft tokenid to the atributes
mapping(uint256 => PropertyAttributes) public nftHolderAttributes;
//map extensions to the token id.
mapping(uint256 => mapping(uint => Extension)) extensions;
// A mapping from an address => the NFTs tokenId. Gives me an ez way
// to store the owner of the NFT and reference it later.
mapping(uint256 => address) public nftHolders;
constructor() ERC721("Metropolis World Genesis", "METGEN") {
console.log("OK I am making the contract, just this once mind");
// I increment _tokenIds here so that my first NFT has an ID of 1.
_tokenIds.increment();
}
function contractURI() public view returns (string memory) {
return _contractURI;
}
function addNameDescImagePricesTowers(
uint[] memory ids, string[] memory propertyNames, uint[] memory prices,
string[] memory descs, string[] memory images, string[] memory towers, string[] memory districts, string[] memory neighs
) public onlyOwner() {
console.log("Started to add base data");
for (uint i = 0; i < ids.length; i ++){
defaultProperties[ids[i]-1] =
PropertyAttributes({
id: ids[i],
propertyIndex: ids[i]-1,
name: propertyNames[i],
description: descs[i],
image:images[i],
features: Features({
tower: towers[i],
district: districts[i],
neighborhood: neighs[i],
primary_type: '',//primeTypes[i],
sub_type_1: '',//subType1[i],
sub_type_2: '',//subType2[i],
structure: '',//structures[i],
feature_1: '',//feature1[i],
feature_2: '',//feature2[i],
feature_3: '',//feature3[i],
feature_4: '',//feature4[i],
feature_5: '',//feature5[i],
feature_6: ''//raritys[i]
}),
extensionCount: 0
});
//created minted list with all false
MintedNfts[ids[i]] = false;
//record the mint price
MintPrice[ids[i]] = prices[i] * (1 ether);
}
console.log("added base data");
}
function addNftData(uint[] memory ids, string[] memory primes,string[] memory subs1, string[] memory subs2, string[] memory structures, string[] memory fets1,
string[] memory fets2, string[] memory fets3, string[] memory fets4, string[] memory fets5, string[] memory fets6
) public onlyOwner() {
for (uint i = 0; i < ids.length; i ++){
uint id = ids[i];
PropertyAttributes memory x = defaultProperties[id-1];
// x.neighborhood = neighs[i];
x.features.primary_type = primes[i];
x.features.sub_type_1 = subs1[i];
x.features.sub_type_2 = subs2[i];
x.features.structure = structures[i];
x.features.feature_1 = fets1[i];
x.features.feature_2 = fets2[i];
x.features.feature_3 = fets3[i];
x.features.feature_4 = fets4[i];
x.features.feature_5 = fets5[i];
x.features.feature_6 = fets6[i];
defaultProperties[i] = x;
}
console.log("added the core data");
}
//Public payable mint
//check enough eth sent
function publicMint(uint id) public payable {
//get current tokenId (starts at 1)
uint256 newItemId = _tokenIds.current();
uint _propertyIndex = id - 1;
//check if minted
require(MintedNfts[_propertyIndex]==false, "Already Minted");
//check if paid enough
require(MintPrice[_propertyIndex] <= msg.value, "Not enough eth paid");
_safeMint(msg.sender, newItemId);
nftHolderAttributes[newItemId] = PropertyAttributes({
id: defaultProperties[_propertyIndex].id,
propertyIndex: _propertyIndex,
name: defaultProperties[_propertyIndex].name,
description: defaultProperties[_propertyIndex].description,
image: defaultProperties[_propertyIndex].image,
features: Features({
tower: defaultProperties[_propertyIndex].features.tower,
district: defaultProperties[_propertyIndex].features.district,
neighborhood: defaultProperties[_propertyIndex].features.neighborhood,
primary_type: defaultProperties[_propertyIndex].features.primary_type,
sub_type_1: defaultProperties[_propertyIndex].features.sub_type_1,
sub_type_2: defaultProperties[_propertyIndex].features.sub_type_2,
structure: defaultProperties[_propertyIndex].features.structure,
feature_1: defaultProperties[_propertyIndex].features.feature_1,
feature_2: defaultProperties[_propertyIndex].features.feature_2,
feature_3: defaultProperties[_propertyIndex].features.feature_3,
feature_4: defaultProperties[_propertyIndex].features.feature_4,
feature_5: defaultProperties[_propertyIndex].features.feature_5,
feature_6: defaultProperties[_propertyIndex].features.feature_6
}),
extensionCount: 0
});
console.log("Minted NFT w/ tokenId %s and characterIndex %s", newItemId, _propertyIndex);
// Keep an easy way to see who owns what NFT. Maps token id to address
nftHolders[newItemId] = msg.sender;
// update the minted list
MintedNfts[_propertyIndex] = true;
// Increment the tokenId for the next person that uses it.
_tokenIds.increment();
}
//free owner only mint
function mintPropertyNft(uint id, address toWallet) public onlyOwner(){ //payable
//get current tokenId (starts at 1)
uint256 newItemId = _tokenIds.current();
uint _propertyIndex = id - 1;
//check if minted
require(MintedNfts[_propertyIndex]==false, "Already Minted");
_safeMint(toWallet, newItemId);
nftHolderAttributes[newItemId] = PropertyAttributes({
id: defaultProperties[_propertyIndex].id,
propertyIndex: _propertyIndex,
name: defaultProperties[_propertyIndex].name,
description: defaultProperties[_propertyIndex].description,
image: defaultProperties[_propertyIndex].image,
features: Features({
tower: defaultProperties[_propertyIndex].features.tower,
district: defaultProperties[_propertyIndex].features.district,
neighborhood: defaultProperties[_propertyIndex].features.neighborhood,
primary_type: defaultProperties[_propertyIndex].features.primary_type,
sub_type_1: defaultProperties[_propertyIndex].features.sub_type_1,
sub_type_2: defaultProperties[_propertyIndex].features.sub_type_2,
structure: defaultProperties[_propertyIndex].features.structure,
feature_1: defaultProperties[_propertyIndex].features.feature_1,
feature_2: defaultProperties[_propertyIndex].features.feature_2,
feature_3: defaultProperties[_propertyIndex].features.feature_3,
feature_4: defaultProperties[_propertyIndex].features.feature_4,
feature_5: defaultProperties[_propertyIndex].features.feature_5,
feature_6: defaultProperties[_propertyIndex].features.feature_6
}),
extensionCount: 0
});
console.log("Minted NFT w/ tokenId %s and characterIndex %s", newItemId, _propertyIndex);
// Keep an easy way to see who owns what NFT. Maps token id to address
nftHolders[newItemId] = msg.sender;
// update the minted list
MintedNfts[_propertyIndex] = true;
// Increment the tokenId for the next person that uses it.
_tokenIds.increment();
}
}
Any suggestions gratefully received.

How to encode tuple as input parameter to function using web3j

I am attempting to call a solidity function that looks something like the following:
function fillOrder(
Order memory order,
uint256 takerAssetFillAmount,
bytes memory signature
)
Using web3j I would create the function similar to below, however I'm not quite sure how to represent the order which is represented as a struct in Solidity.
List<Type> inputParams = Arrays.asList(???, new
Uint256(takerAssetFillAmount), new Bytes32(signture));
new Function("fillOrder", inputParams, Collections.emptyList());
Any pointers on how I should represent the struct?
Thanks.
You can wrap parameters with square brackets.
For example, let's say I have a contract:
contract Test {
struct Foo {
uint a;
string b;
address c;
}
function bar (Foo memory foo) public {
c = foo.c;
}
}
I can call bar function with web3.js like this:
contract.methods.foo([123, "123", "0xABC...."]).send({ from: '0x...' })
here is the contract address https://goerli.etherscan.io/address/0xd5999bf0ce31a1d9d6a6de2bf03feaff1913cee5#writeContract
in the write function , createSwapOrder is asking nested Tuple . here is the solidity code to show the structure of tuple :
struct Side {
address user;
bytes signedRequiredOutput;
ERC20Component[] erc20s;
ERC721Component[] erc721s;
ERC1155Component[] erc1155s;
}
struct ERC20Component {
uint256 amount;
address underlying;
// A signed approval transaction giving `amount` transfer rights
// of token `underlying` to address(this).
// bytes signedApproval;
}
struct ERC721Component {
uint256 tokenId;
address collection;
// A signed approval transaction giving `tokenId` tranfer rights
// of token `collection` to address(this).
// bytes signedApproval;
}
struct ERC1155Component {
uint256 tokenId;
uint256 amount;
address collection;
// A signed approval transaction giving `tokenId` tranfer rights
// of token `collection` to address(this).
// bytes signedApproval;
}
struct Order {
Side side0;
Side side1;
uint256 expiry;
bytes32 hashlock;
bytes32 preimage;
bool completed;
}
event OrderCreated(address indexed user, bytes32 orderId);
uint256 public totalOrders;
mapping(bytes32 => Order) public orders;
function createSwapOrder(
Side calldata side0,
bytes32 hashlock,
uint256 timelock
) public {
...
}
and in first args side0 is asking a nested tuple and this tuple formet should be like this
["0x5B38Da6a701c568545dCfcB03FcB875f56beddC4","0x00",[["32","0x5B38Da6a701c568545dCfcB03FcB875f56beddC4"]],[["32","0x5B38Da6a701c568545dCfcB03FcB875f56beddC4"]],[["32","32","0x5B38Da6a701c568545dCfcB03FcB875f56beddC4"]]],
i hope you can understand the structure how its provided !! and sure it working
Web3j offers such classes as StaticStruct and DynamicStruct where you define your struct object via primitives. Here is the sample from my project:
class Value: DynamicStruct {
private lateinit var offer: String
private lateinit var availableSince: BigInteger
private lateinit var availabilityEnd: BigInteger
private var isConsumed: Boolean = false
private lateinit var lockedUntil: BigInteger
constructor(
offer: String,
availableSince: BigInteger,
availabilityEnd: BigInteger,
isConsumed: Boolean,
lockedUntil: BigInteger
) : super(
Utf8String(offer), Uint256(availableSince),
Uint256(availabilityEnd), Bool(isConsumed),
Uint256(lockedUntil)
) {
this.offer = offer
this.availableSince = availableSince
this.availabilityEnd = availabilityEnd
this.isConsumed = isConsumed
this.lockedUntil = lockedUntil
}
constructor(
offer: Utf8String,
availableSince: Uint256,
availabilityEnd: Uint256,
isConsumed: Bool,
lockedUntil: Uint256
) : super(offer, availableSince, availabilityEnd, isConsumed, lockedUntil) {
this.offer = offer.value
this.availableSince = availableSince.value
this.availabilityEnd = availabilityEnd.value
this.isConsumed = isConsumed.value
this.lockedUntil = lockedUntil.value
}
}
Ideally you just need to pass this struct instance to you contract method as a parameter where contract is autogenerated over $web3j solidity generate -b /path/to/<smart-contract>.bin -a /path/to/<smart-contract>.abi -o /path/to/src/main/java -p com.your.organisation.name command.
However personally I faced with issue to make this console command working and have to implement required logic by my own. This is in the progress now.

Solidity: Retrieving values of Array of Structs in Mapping

I have some solidity code where I am attempting to gather the ids which are a value stored on a Struct. I have a mapping where the key is an address, and the value is an array of Structs. Whenever I execute the getMediaByAddress function I get an invalid OpCode error. Any help would be greatly appreciated.
pragma solidity ^0.4.24;
contract MediaGallery {
address owner;
uint counter;
struct MediaAsset {
uint id;
string name;
address author;
uint createDate;
string[] tags;
string mediaHash;
}
mapping(address => MediaAsset[]) public mediaDatabase;
constructor () {
owner = msg.sender;
}
function addMedia(string _name, string _mediaHash) public returns (bool success) {
MediaAsset memory currentMedia;
currentMedia.id = counter;
currentMedia.name = _name;
currentMedia.author = msg.sender;
currentMedia.createDate = now;
currentMedia.mediaHash = _mediaHash;
mediaDatabase[msg.sender].push(currentMedia);
return true;
}
function addTag(uint _id, string _tag) public returns (bool success) {
mediaDatabase[msg.sender][_id].tags.push(_tag);
return true;
}
function getMediaByAddress(address _user) public view returns (uint[]) {
uint[] memory mediaAssetIds = new uint[](mediaDatabase[_user].length);
uint numberOfMediaAssets = 0;
for(uint i = 1; i <= mediaDatabase[_user].length; i++) {
mediaAssetIds[numberOfMediaAssets] = mediaDatabase[_user][i].id;
numberOfMediaAssets++;
}
return mediaAssetIds;
}
}
You're trying to read past the end of the array. Your loop variable i has an off-by-one error. Its greatest value is mediaDatabase[_user].length, which is 1 past the end of the array. Try this instead:
for (uint i = 0; i < mediaDatabase[_user].length; i++) {