Let’s say a a contract calls inline or deferred another contract. Can it choose who pays for the CPU? And in th case of an action called from a user transaction, it is possible to choose who pays for CPU? The caller, the receiver or even a 3rd party ?
Officially, there is not way to decide. The smart contract pays for the CPU and bandwidth. As stated in the white paper:
Traditionally, it is the business that pays for office space, computational power, and other costs required to run the business. The customer buys specific products from the business and the revenue from those product sales is used to cover the business costs of operation. Similarly, no website obligates its visitors to make micropayments for visiting its website to cover hosting costs. Therefore, decentralized applications should not force its customers to pay the blockchain directly for the use of the blockchain.
A launched blockchain that uses the EOS.IO software does not require its users to pay the blockchain directly for its use and therefore does not constrain or prevent a business from determining its own monetization strategy for its products.
While it is true that the receiver can pay, EOS.IO enables the sender to pay for bandwidth, computation, and storage. This empowers application developers to pick the method that is best for their application. In many cases sender-pays significantly reduces complexity for application developers who do not want to implement their own rationing system. Application developers can delegate bandwidth and computation to their users and then let the “sender pays” model enforce the usage. From the perspective of the end user it is free, but from the perspective of the blockchain it is sender-pays.
However, you could force the users to pay for the CPU costs by changing the mechanism in which they call the action for your contract.
Instead of doing something like:
cleos push action account action data
You could do
cleos transfer your_account smart_contract_account "memo says the actual action you want to perform"
Then you use a function that stakes the tokens you receive and calls the appropriate action. When the action is finished you can transfer the tokens back to the user.
It may be possible to do this with a function that listens to
delegatebw, but I haven't tried that yet so can't promise it will work.
To perform any transaction in EOS, you need net and CPU bandwidth. It is not possible to decide who pays for CPU. It is possible in the case of RAM. RAM cost is imposed to who pays for storing app data in RAM.
If a contract calls inline or deferred another contract, then the caller(ie. caller contract account) must have the required amount of CPU bandwidth in order to perform the transaction.