There will be times where you write a smart contract action, and inside of that action you want to call an action on another smart contract. This is referred to as an inline action
This page will explain how to create inline actions, and also will cover some common misconceptions/issues that developers may encounter.
Note: calling inline actions requires your contract to have the eosio.code permission. Setting up this permission is explained at the following page...
The process for creating an inline action is pretty straightforward. First I'll give a code example, then I'll cover some tips/tricks.
ACTION mycontract::dosomething(constname& user){require_auth( user );const symbol WAX_SYMBOL =symbol("WAX",8);const asset amount_to_send =asset(100000000, WAX_SYMBOL);const std::string memo ="you received 1 WAX"; // Transfer 1 WAX to `user` with an inline actionaction( eosio::permission_level{ _self,"active"_n },"eosio.token"_n,"transfer"_n, std::tuple{ _self, user, amount_to_send, memo } ).send();}
The above is an example of using an inline action to transfer WAX to a user. The only permission required here is eosio.code on mycontract, since mycontract is the one calling the transfer action on eosio.token.
However, one common issue that I see developers run into is that they want to use an inline action to move assets from someone else's wallet into their contract. See the following example:
ACTION mycontract::playgame(constname& user,constvector<uint64_t>& nfts_to_play_with){require_auth( user ); // Transfer `nfts_to_play_with` from `user` to `mycontract` // Play the game with NFTsbool user_won_the_game =false;play_game( user, nfts_to_play_with, user_won_the_game );if( user_won_the_game ){ // Transfer WAX to the user and return the user's NFTs to them }}
Notice the comment about Transfer nfts_to_play_with
You would think that this would be possible, since after all, this is how things work on EVM chains like Ethereum. However, this is not how things are done on Antelope chains like WAX.
While it is "technically" possible to change permissions of users to allow this - it is highly discouraged and considered a major red flag if a game tries to do things this way.
This is where we will cover a quick front end development approach to avoid doing things this way.
The above is a default function for submitting transactions on a front end with Wharfkit. To have a user submit a transaction, you would just specify which actions you want them to call, and then pass them to submitTransaction, like this:
constplayGameAction= (asset_ids, wharfSession) => {constdata= {user:wharfSession.actor, nfts_to_play_with: asset_ids};returnmakeAction("mycontract","playgame", data, wharfSession);}<buttonclassName="stake-button"onClick={() => {submitTransaction( [playGameAction(asset_ids, wharfSession)],"You played the game!", setShowTxModal, setTxModalText, setTxIsLoading, wharfSession ); }}> PLAY GAME</button>
If mycontract was not trying to take NFTs out of the user's wallet, this would work perfectly fine. However, the better approach is to have the user transfer NFTs to the contract instead. Then, your contract can react to this NFT transfer by automatically playing the game when you receive the NFTs from the user.
All you need to do is have the user sign atomicassets::transfer and send the NFTs to your contract with a specific memo for playing the game. This avoids running into permission issues, since the user is directly signing the NFT transfer.
consttransferNftsAction= (to, asset_ids, memo, wharfSession) => {constdata= { from:wharfSession.actor, to: to, asset_ids: asset_ids, memo: memo, };returnmakeAction("atomicassets","transfer", data, wharfSession);};<buttonclassName="stake-button"onClick={() => {submitTransaction( [transferNftsAction("mycontract", asset_ids,"game_deposit", wharfSession)],"You played the game!", setShowTxModal, setTxModalText, setTxIsLoading, wharfSession ); }}> PLAY GAME</button>
You may be having the following thoughts:
How do I react to the NFT transfer?
Doesn't this mean I need to pay RAM for the users?
How do I know if I received the correct NFTs?
These questions are mostly covered on the "Having Users Pay RAM" page.