The text is misleading. There are still 2 contracts involved despite what is being said. To be sure
Proxy’s active would delegate to contract’s eosio.code
cannot be true unless there are 2 contracts in play.
That being said, this is an alternative method. In the original example, the host contract would send inline to the proxy contract using its own eosio.code permission level with a memo starting with the end user's account_name, then the proxy contract would remove the name from the memo, and create an account_name type to use in order to send an inline eosio::token, transfer
to the end user with the edited memo. The action receivedTokens
is passed a code
param which is the contract that is hosting the token contract.
/**
* Send inline action
*
* @brief Send inline action
* @param CONTRACT - The account this action is intended for
* @param NAME - The name of the action
* @param ... - The member of the action specified as ("action_member1_name", action_member1_value)("action_member2_name", action_member2_value)
*/
#define SEND_INLINE_ACTION( CONTRACT, NAME, ... )\
INLINE_ACTION_SENDER(std::decay_t<decltype(CONTRACT)>, NAME)( (CONTRACT).get_self(),\
BOOST_PP_TUPLE_ENUM(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__)) );
Effectively the two contract's permission levels would not overlap and the separation between the contracts is to prevent the end user from occupying RAM in the host contract's tables. Here's a breakdown of the receivedTokens
action in the proxy:
void receivedTokens( const currency::transfer& t, account_name code ) {
if( t.to == _self ) { // checking if tokens were sent to proxy's contract name
string cMemo = t.memo; // pulling memo
string stringName(getAccountNameFromMemo(cMemo)); //extracting account name
account_name to = string_to_name(stringName.c_str()); // assigning to type account_name
string memo = cMemo.replace(0, cMemo.size() > stringName.size() ? stringName.size()+1 : stringName.size(), ""); // removing account name from memo to pass original memo
INLINE_ACTION_SENDER(eosio::token, transfer)( code, {{_self,N(active)}}, {_self, to, t.quantity, memo} );
//sending to "to" which was pulled from memo and using "t.quantity" which was passed from transfer effectively passing on all tokens
}
}
The original contract in the alternative example is sending both actions in this case because the active permission from the proxy contract is added to the host contract's eosio.code permission level.
On eosio.code from docs:
In order for an inline action to be sent from an account, add the
eosio.code permission to the contract account's active permission.
The eosio.code authority is a pseudo authority implemented to enhance
security, and enable contracts to execute inline actions.
./cleos set account permission proxy_account active host_account eosio.code -p proxy_account@owner
Cleos command
This allows the host contract to perform an inline action to the proxy contract (using its own eosio.code permission level which it had to add to its active) and then another on behalf of the proxy's contract because "Proxy’s active would delegate to contract’s eosio.code" ... "but with a different auth". Now I believe by "a different auth" meaning the active permission level from the proxy's account added to the host account's eosio.code permission level for signing inline actions.
I think the code example he's referring to is this where there is a forward_auth param:
void forward( action_name reqauth, account_name forward_code, account_name forward_auth ) {
require_auth( reqauth );
INLINE_ACTION_SENDER(testinline, reqauth)( forward_code, {forward_auth,N(active)}, {forward_auth} );
}
Link: https://github.com/EOSIO/eos/blob/905e7c85714aee4286fa180ce946f15ceb4ce73c/contracts/test.inline/test.inline.hpp
Also, I tried to compile the contract to test some things; however, the eosiolib is way out of date and those contracts are either not named that any more or are not included in the lib.