Im trying to push a value to an enum array stored in a struct but im not able to push a value. Where am I going wrong? This is my code:
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.12;
contract Test {
address private owner; // owner is Insurance Company
mapping (address => Record) records;
enum Animal {Lion, Tiger, Zebra}
struct Record {
Animal[] animal; // status of the record
}
constructor() { // set owner on deploy as deployer address
owner = msg.sender;
}
function addRecord() public {
Record storage record = records[msg.sender];
record.animal.push(0);
// record.animal[0] = Lion;
// record.animal = [Lion, Tiger};
}
}
My error:
TypeError: Member "push" not found or not visible after argument-dependent lookup in enum Test.Animal[] storage ref.
--> b.sol:21:9:
|
21 | record.animal.push(0);
| ^^^^^^^^^^^^^^^^^^
Try this:
record.animal.push(Animal.Lion);
Related
I want to create a new function based on these codes below, that it can just fill in the ordinal number (first student is started by 1) to track out the struct student info in this case.
That's mean after I give the data of this first student to the struct by addInfo function:["Simon", 20, "CA USA", 10] Then my expected new function is that I just fill in this unit: 1, then it will appear this student detail
\`
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract ReferenceTypes {
address public owner;
struct student {
string Name;
uint Age;
string BirthPlace;
uint8 Marks;
}
constructor() {
owner = msg.sender;
}
mapping (address => student) public Info;
address[] public student_Info;
function addInfo(student memory _student, address _address) public {
require(owner == msg.sender, "Only admin can add Info!!!");
Info[_address] = _student;
student_Info.push(_address);
}
function count() public view returns(uint) {
return student_Info.length;
}
}
\`
Thanks so much guys
I tried a new mapping but failed
You can make another mapping that leads to your mapping Info.
uint public studentsCounter;
mapping (uint => mapping (address => student)) public Info;
function addInfo(student memory _student, address _address) public returns(uint){
require(owner == msg.sender, "Only admin can add Info!!!");
Info[studentsCounter][_address] = _student;
studentsCounter++;
student_Info.push(_address);
return studentsCounter-1;
}
Thus you can reach your struct by passing studentId(studentCounter) which addInfo returns and students address.
Another approach is to remake you array of addresses.
student[] public student_Info;
And push struct in this array.
function addInfo(student memory _student, address _address) public {
require(owner == msg.sender, "Only admin can add Info!!!");
Info[_address] = _student;
student_Info.push(_student);
}
So now you can display studentsInfo buy passing index in student_Info array.
I am trying to create a function that would return me the struct I select from multiple structs.
Here is my code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Structing {
struct DataOne {
uint indexOne;
address toOne;
}
struct DataTwo {
uint indexTwo;
address toTwo;
}
function selectingStruct(string name_struct) public view returns(struct) {
return _name_struct public final_selection;
}
}
This is the error I get:
Parser error, expecting type name.
How to create a function that returns me my selection between more structs in Solidity?
Your snippet only contains struct definitions, but not storage properties storing any data.
You'll need to define the exact datatype that you want to return. There's no magic typing that would allow returning a "1 of N" type in Solidity.
pragma solidity ^0.8;
contract Structing {
// type definition
struct DataOne {
uint indexOne;
address toOne;
}
// type definition
struct DataTwo {
uint indexTwo;
address toTwo;
}
// typed properties
DataOne dataOne;
DataTwo dataTwo;
// TODO implement setters of `dataOne` and `dataTwo` properties
function getDataOne() public view returns (DataOne memory) { // returns type
return dataOne; // property name
}
function getDataTwo() public view returns (DataTwo memory) { // returns type
return dataTwo; // property name
}
}
I have created struct with nested mapping. Consider the following piece of code written inside the contract in solidity:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
contract TestContract {
struct Item {
uint itemId;
uint itemValue;
}
struct OverlayingItemStruct {
mapping(uint => Item) items;
uint overlayingId;
uint itemsCount;
}
mapping(uint => OverlayingItemStruct) public overlayingItems;
uint public overlayCount;
function addOverlayingItemsStruct(uint _value) external {
overlayCount ++;
mapping(uint => Item) memory items;
items[1] = Item(1, _value);
overlayingItems[overlayCount] = OverlayingItemStruct(items, 1, 1);
}
function addItem(uint _value, uint _overlayId) external {
OverlayingItemStruct storage overlay = overlayingItems[_overlayId];
overlay.itemsCount ++;
overlay.items[overlay.itemsCount] = Item(overlay.itemsCount, _value);
}
}
When compiling the above code, I am getting the error:
TypeError: Uninitialized mapping. Mappings cannot be created dynamically, you have to assign them from a state variable.
--> TestC.sol:21:5:
|
21 | mapping(uint => Item) memory items;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Not sure, how to handle this error.
Secondly, needed to confirm if the method to add new values in the nested mapping dictionary is correct?
A mapping cannot be declare inside a function and in memory state. This type has only storage state.
Said this, to pass a mapping into a struct, you can set the key of nested mapping and pass relative struct inside it.
I tried to adjust your smart contract like this:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
contract TestContract {
struct Item {
uint itemId;
uint itemValue;
}
struct OverlayingItemStruct {
mapping(uint => Item) items;
uint overlayingId;
uint itemsCount;
}
mapping(uint => OverlayingItemStruct) public overlayingItems;
uint public overlayCount;
function addOverlayingItemsStruct(uint _value) external {
overlayCount ++;
// NOTE: I declared a new Item struct
Item memory item = Item(1, _value);
// NOTE: I set into items mapping key value 1, Item struct created in row above this
overlayingItems[overlayCount].items[1] = item;
}
function addItem(uint _value, uint _overlayId) external {
OverlayingItemStruct storage overlay = overlayingItems[_overlayId];
overlay.itemsCount ++;
overlay.items[overlay.itemsCount] = Item(overlay.itemsCount, _value);
}
}
I have 2 contracts.
contract Contract1{
struct Data {
uint data1;
string data2;
}
Data [] newData;
}
Let's assume that I have datas in newData
import "./Contract1.sol";
contract Contract2{
Data storage newOne = newData[0];
}
I want to reach array of struct which is in Contract1 as above.
How can I access to Contract1 from Contract2?
You can extend a contract with the is keyword.
Child contracts (in your case Contract2) can access all non-private parent (in your case Contract1) properties.
pragma solidity ^0.8;
import "./Contract1.sol";
contract Contract2 is Contract1 {
function foo() external {
Data storage newOne = newData[0];
// newOne.data1 = 1;
// newOne.data2 = 'hello';
}
}
Edit: Mind that newData[0] is trying to access index 0 of the array, but when the contract is deployed, the array is empty (does not have index 0). You can create the first item (with index 0 and dummy data) by executing this function:
function add() external {
newData.push(Data(1, 'a'));
}
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.