Problem:
Remix produces weird behaviors with a string param followed by an array param
Reproduce:
contract ItemMarket is ERC721 {
struct Item {
string name;
uint[3] others;
}
Item[] public items;
function createItem(string _name, uint[6] _others) public {
uint tokenId = items.push(Item({name: _name, traits:_traits})) - 1;
}
}
When you call createItem() in remix with the arguments "hello", [1,2,3] the first argument gets converted to \u0000. The same function call with the same arguments works fine when interacted with the contract through MEW
This now works in the latest version of Remix IDE:
pragma solidity 0.5.1;
import "https://github.com/0xcert/ethereum-erc721/src/contracts/tokens/nf-token.sol";
contract ItemMarket is ERC721 {
struct Item {
string name;
uint[3] traits;
}
Item[] public items;
function createItem(string memory name, uint[3] memory traits) public {
items.push(Item({name:name, traits:traits})) - 1;
}
}
Related
I've a smartcontract in which I've a function getLevels() that returns an array of struct type MLevel, defined at the beginning of smartcontract.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
struct MLevel{
address id;
string levelPrize;
uint levelNo;
uint levelCriteria;
}
contract Test{
MLevel[] public mlevels;
function addLevel(uint _levelCriteria, string memory _levelPrize)public payable{
MLevel memory level;
level.id = msg.sender;
level.levelCriteria = _levelCriteria;
level.levelPrize = _levelPrize;
mlevels.push(level);
}
function getLevels() public view returns(MLevel [] memory){
return mlevels;
}
}
The above smartcontract works absolutely fine in Remix ide. But when I try to create its java wrapper class using web3j, wrapper class does not generate and web3j ends with a weird error part 'struct MLevel' is keyword as shown below in the image
code
trying to create contract using KIP37 as base contract. its works fine for the previous version of #klaytn/contracts - 0.9.0, but it is not working for #klaytn/contracts - 1.0.0
//SPDX-License-Identifier: Unlincesed
pragma solidity ^0.8.0;
import "#klaytn/contracts/contracts/KIP/token/KIP37/KIP37.sol";
// this line showing error "Contract ItemMint should be abstract
contract ItemMint is KIP37 {
string public name;
constructor(string memory _name) {
name = _name;
}
function mint(address to) public pure returns (bool) {
require(msg.sender == to , "your are authorized");
return true;
}
}
using npm i #klaytn/contracts - 1.0.0
The parent KIP37 contract defines a constructor that takes one argument - a string named uri_, so you need to invoke the parent constructor as well.
constructor(string memory _name, string memory uri_) KIP37(uri_) {
name = _name;
}
Issue
There seems to be some issue with this line here family.People.push(people[x]);
I keep getting Member "push" not found or not visible after argument-dependent lookup when I try to compile with brownie.
What have I tried
I saw a few SO posts with similar exceptions but it was related to type casting. I did try to cast my incoming array to its type but it just resulted in more exceptions.
Code
pragma solidity ^0.8.9;
contract Person{
string public FirstName;
string public LastName;
}
contract Family{
Person[] public People;
}
contract FamilyManager{
Family[] Families;
function AddFamily(Person[] memory people) public {
Family family = new Family();
for(uint x; x < people.length; x++){
family.People.push(people[x]);
}
Families.push(family);
}
function GetFamilies() public view returns (Family[] memory){
return Families;
}
}
Can anyone spot what I'm doing wrong here or link to an article that can lead to an answer?
I think it is related to access modifiers. Using the public modifier for your array only generates the getter function for it and not the setter.
As a result, you cannot directly push to an array from another contract. I created a public function to add elements to the array as follows:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
contract Person{
string public FirstName;
string public LastName;
}
contract Family{
Person[] public People;
function addPerson(Person person) public {
People.push(person);
}
}
contract FamilyManager{
Family[] Families;
function AddFamily(Person[] memory people) public {
Family family = new Family();
for(uint x; x < people.length; x++) {
family.addPerson(people[x]);
}
Families.push(family);
}
function GetFamilies() public view returns (Family[] memory){
return Families;
}
}
I want to get the value that is inside of struct in Solidity,
but I have no idea how to get it.
pragma solidity >=0.4.21 <0.6.0;
contract PlaceList {
struct hoge {
uint id;
address user;
}
hoge[] public hoges;
constructor() public {
admin = msg.sender;
}
function set(uint id) public {
hoges.push(hoge(id, msg.sender));
}
function getId() public view returns(uint) {
return (hoges[0].id);
}
}
When I call getId, console command say this,
ƒ () {
if (abiItemModel.isOfType('constructor')) {
return target.executeMethod(abiItemModel, arguments, 'contract-deployment');
}
return targe…
Could you give me any advise how to get id by using solidity function, please?
hoges[0][0] will work as it points to the first element, 'id' .
This is my contract code. Here I'm trying to store the coordinates of a particular trip. While storing the information contract executing fine. But When I retrieve the data, It should give the array of coordinates. But it is throwing an error.
reason: 'insufficient data for uint256 type'
contract TripHistory {
struct Trip {
string lat;
string lon;
}
mapping(string => Trip[]) trips;
function getTrip(string _trip_id) public view returns (Trip[]) {
return trips[_trip_id];
}
function storeTrip(string _trip_id, string _lat, string _lon) public {
trips[_trip_id].push(Trip(_lat, _lon));
}
}
What I'm missing here. Is there any other way to achieve what I'm trying here?
P.S: I'm new to solidity.
First of returning structs is not supported in Solidity directly. Instead you need to return every individual element in the struct as below.
Function xyz(uint256 _value) returns(uint256 User.x, uint256 User.y)
public {}
But then there’s an experimental feature that will help you with returning struct. All that you need to do is add the following after your first pragma line
pragma experimental ABIEncoderV2;
then continue with your code. That should work with no changes to your code.
An example of abiencoderv2 returning struct can be found at this link
It is not possible in solidity to return struct array.
As jlo said in this link, after version 0.8.0, it is possible to return a struct. jlo describes how to set and return an element of array of struct. Here I describe how to set, reset, and return a struct type variable.
I tested it and my test environment is:
private Ethereum network
Geth version 1.10.9-stable (for private network)
Slocjs Compiler version 0.8.7
web3js version 1.5.1
Note, you have to first define the struct type outside of any function inside the contract.
A supper intuitive example code is as follows:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract testContract {
struct funcResultType {
uint[] var1;
string[] var2;
string message;
}
funcResultType private funcResult;
function testSetFunc(string memory inputVar) public payable {
funcResult.var1.push(123);
funcResult.var2.push(inputVar);
funcResult.message = "Done!";
}
function testResetFunc() public payable {
delete funcResult; // reset variales
}
function testGetFunc() public view returns (funcResultType memory){
return funcResult;
}
}
The result of the test with Web3js in the console is as follow:
As you can see the whole variables are accessible. I upload its web3js code in Github in this link.