How can I combine 2 smart contract functions in one transaction? - ethereum

I am building two smart contracts, one is casino contract and the other one is lottery contract(planning to deploy it separately). I want to combine both the placebet(casino) function and buyticket(lottery) function in one call. Once user would call placebet on casino contract, he will automatically buys lotteryticket also. Any help will be appreciated. Thank you.
Note: (Pls. respect) I am just a newbie, no formal coding education, I am just studying how to make dapp.

If I understand correctly, you need to make the first method call another method from another contract.
Here is an example:
contract LotteryContract {
function buyTicket() public {
// code to buy ticket
}
}
contract CasinoContract {
function placeBet() public {
// code to place bet
LotteryContract.buyTicket()
}
}
The basic idea in this example is that we call the LotteryContract's method in CasinoContract. In this case, when the user makes a bid via the placeBet method, the contract will call another buyTicket method
If you meant to make two calls to different contracts at once from the user, you can't do that. The user can only call one method from the contract, which will call other methods inside itself.

Related

Solidity: Constructor function needs to be always "public"?

In solidity, while relating a "withdraw" function to be only callable from the admin contract, the "construct" comes handy.
address public owner;
constructor() public { owner =msg.sender;}
Question: How come it has to be set as a "public" function? As we want no one but us to trigger the withdraw, shouldn´t it be entered as "internal" or "private"?
the constructor is just triggered on deploy so no one else can call it before the deploy, it can be public and you will have no problems but in most recent solidity versions is not necessary to mark the constructor as public
A withdraw function should be marked as public or external for you, or its non-contract owner, to be able to withdraw it. Why? If you mark a function as private, only the functions inside the smart contract will be able to interact with it, and by marking a function as internal, functions inside a contract and contracts that inherit from this one will be able to call the function. Why you probably want to make it this way? Because you, as a normal user, wont be able to call this function directly. So by making this function public or external, every user will be able to interact with the function. And here is your question.
How come it has to be set as a "public" function? As we want no one but us to trigger the withdraw, shouldn´t it be entered as "internal" or "private"?
You can set the function as public and create a require statement (it can be a modifier or a conditional "if", as you want.) and just check if the remitent is the owner. And only if it is, then withdraw. Here is an example:
function withdraw() public {
require(msg.sender == owner, "Only the owner can call this function.");
// Withdraw logic here.
}
Hope you find this useful :)

SOLIDITY: Create multiple contracts from one parent contract and listen for events from child contract

What is the best architecture to allow users to deploy their own smart contracts (NFT collections), and still be able to index the tokens created on those dynamically created contracts using something like The Graph subgraphs?
Currently the idea was to have a "Factory" contract deployed by me, so easily indexable, and inside that have a function createCollection that will deploy a contract using the new <ContractName> keyword.
Is this bad architecture? Would this even work?
The end goal is to allow users to deploy contracts from a UI, but still be able to listen for their events through my parent contract, so that I can index everything in a subgraph.
What you can actually do is to save a pointer to the parent contract into each generated contract. Thus, whenever you have an event you want to store into the parent contract, you can maybe interact with a function in it. But you may also want some type of verification to ensure that only child contracts can call the parent functions and not external contracts, so maybe you could make a mapping indexing the address of the generated child contracts, which will be able to call functions from the parent. What you can not do is to make the parent automatically look for events on the child's contracts.
Hope you find this information helpful :)

Saving external event variable into smart contract storage variable

I am trying to save a variable that gets emmited by an event, from a function in another smart contract, that I’m calling, into a storage variable within my smart contract.
So my call looks something like this:
ExternalContract.foo(boo);
The event in ExternalContract that contains the desired variable:
emit Event(bytes desiredVariable)
So I want to save this variable in my contract without relying on an off-chain script. Is there even a way to do it?
The Log and its event data is not accessible from within contracts (not even from the contract that created them).
Source: https://docs.soliditylang.org/en/v0.8.7/contracts.html#events
So unless there's a getter function for the desiredVariable, or unless it's stored in a public property (they have automatically generated getter functions as well), there's no way to get the event log value from a contract, and you'll need to use an off-chain app.

IERC20 public declaration with another address?

I am new to solidity, but checking through a specific contract I found the following line of code in the IERC20 declaration:
IERC20 public "TOKEN NAME" = IERC20("THE ADDRESS OF ANOTHER CONTRACT");
This code was found in a contract that is effectively a fork of another project, but the developers say they are unrelated. Of course, people are just FOMO into the token - I know this forum here is not for this type of discussion so I'll abstain from the same.
However, from a solidity coding perspective, why would one write this line of code directly referencing another contract address (the forked address) when making the IERC20 declaration - what does this do, is there a purpose to this?
It seems to me that this is easier and more reliable. Alternatively, you can pass this address in constructor parameters, or provide a special method to set it.
The IERC20 is an interface that defines expected functions arguments and return values.
It helps validating whether the caller is passing correct data types, amount of arguments, and helps parsing the returned data to expected types.
Let's show it on a very simple interface
interface IGame {
function play(uint256 randomNumber) returns (bool won);
}
Elsewhere in your contract, you define a variable that uses this interface
IGame game = Game("0xthe_game_address");
You can then directly call the other contract's methods defined in the interface and pass the return values to your variables.
bool didIWin = game.play(1);
The call would fail if the game contract didn't have the play method or didn't return any value (plus in few other cases).
As for why is the address hardcoded, it's probably just to simplify the development as Mad Jackal already said in their answer.
One more plausible reason in some cases is to gain more trust by showing users that the contract admins are not able to cheat you by changing the destination address (possibly to a contract made by them doing whatever they want).
Edit: If the another contract's address is really unrelated and useless (meaning, the fork is not calling it), it's probably just a human error and the developer forgot to remove it.

How to get the address of the code being executed from CALLCODE?

I want to write a library which can be callcalled by any contract.
As part of this, I want to write a function which returns the contract address of the library to the contract which callcalled it.
address(this) is normally the solution, but in the case of callcode, it can only be used to check if the contract is being callcalled through if(address(this)==msg.sender) which become always true.
So how to perform this without having to rewrite the code each time because of the requirement to predict the future library’s contract address ?