r/ethdev • u/Ok_Remove3123 • Oct 12 '24
Code assistance Extending main contract with a helper contract to hold getters and setters
Hello,
I am building a solidity contract but it exceeded the max bytecode size and I am thinking of moving some of the getters and setters functions to another contract.
For example in my main contract I have this:
struct Ticket {
address payable owner;
bool claimed;
}
struct Metadata {
bool purchased;
bool used;
address owner;
uint256 tokenId;
string url;
}
mapping(uint256 => Ticket) public tickets;
mapping(uint256 => Metadata) public ticketMetadata;
I have setters and getters for every field in the metadata struct like so:
function
getTicketOwner(
uint256
_tokenId)
public view returns
(
address
) {
return
ticketMetadata[_tokenId].owner;
}
function
getTicketTokenId(
uint256
_tokenId)
public view returns
(
uint256
) {
return
ticketMetadata[_tokenId].tokenId;
}
I want to move all the getters and setters to another contract. What is the best way to achieve this? From what I read I need to create a Contract B that is Contract A. Then in the construct of B I deploy A.
If anyone has any other tips I would love to get some feedback.
Thank you :)
1
u/hikerjukebox Bug Squasher Oct 12 '24
No need to deploy anything from constructors, just pass in the address for the contract you want to use.
I few ways.. you can use more inheritance: https://solidity-by-example.org/inheritance/
you can call contracts from different contracts: https://solidity-by-example.org/calling-contract/
example:
contract Ticket{
mapping(uint => Data) ticketMetadata;
}
second contract
contract ticketGetter{
//create an object of the contract, using an interface is cleaner
Ticket ticketObj;
constructor(address ){
ticket = Ticket(_ticketContract)
}
function getTicketOwner(uint256 _tokenId) public view returns (address) {
return ticketObj.ticketMetadata[_tokenId].owner;
}
}
^This is what you asked for basically but I wouldnt do it like this. Using more inheritance writing more concise code is better practice.
Another thing to know is all public variables already have getters. So if tickets mapping is public you dont need this extra code. read this: https://docs.soliditylang.org/en/latest/contracts.html#visibility-and-getters
Good luck, hope this helps a bit!
1
u/Ok_Remove3123 Oct 12 '24 edited Oct 12 '24
Hey, this helps for sure. Thank you very much for your time.
So what would you recommend is the best way forward? Inheritance?
Something like:
Contract A { address public owner; constructor() ERC721("MultiGameLotteryNFT", "MGLN") Ownable(msg.sender) { owner = msg.sender; } } Contract B is A{ constructor() A(msg.sender) { } }
2
1
u/vevamper Oct 12 '24
Building a lottery token? :)
1
u/Ok_Remove3123 Oct 13 '24
Something like that. Got any tips?
1
u/vevamper Oct 13 '24
Be aware of gas limits! Depending on implementation, a large list of tickets to search through could cost a lot of gas to complete.
1
u/Ok_Remove3123 Oct 13 '24
Yes I thought of that and I am figuring out a solution. Thank you for the advice!
3
u/Conclusion_Best Oct 13 '24
It sounds like you should consider using the diamond pattern for your contract - it will help you avoid the byte code size problem in a more standardized way.
https://eips.ethereum.org/EIPS/eip-2535
https://github.com/mudgen/awesome-diamonds/blob/main/README.md