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 ?
2 Answers
Officially, there is no way to decide. The initial transaction is paid for by the user, all subsequent actions performed by the smart contract are paid for by the smart contract itself. As stated in the white paper:
Receiver Pays
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 even do this by creating a listener function to the delegatebw function. So that if they just stake tokens to you, then they can use your dApp for the duration that the tokens are staked.
-
"The smart contract pays for the CPU and bandwidth." ----- Are you sure about this? Some people say the caller pays for CPU/band and some say the contract. Do you have a source that says the contracts pays for CPU/band?– AlexCommented Aug 10, 2018 at 17:05
-
1I added the quote and link to the white paper where it is implied Commented Aug 10, 2018 at 21:23
-
Thanks for the help. Can you help me with a really quick example... Say I'm making a coinflip contract, where the user guesses heads/tails and the contract pays them bet * 2 or keeps their money. Originally, it would be something like
cleos push action eosio.token transfer '[user, contract, "1.0000 EOS","heads]'
however the user has to pay the CPU for this ... I've tried. How to make this so that user doesn't have to pay for CPU/band?– AlexCommented Aug 10, 2018 at 22:32 -
I updated my answer slightly because you are right. The user pays for the initial cost of sending a transaction, and the contract pays for everything else. You could make it so that the user doesn't have to pay by staking tokens into the users account in accordance with the actions that they perform. So if you know that the CPU used up by the coin toss is 0.1 EOS, then you can delegate 0.1 EOS to them each time they do the coin toss. Then undelegate it 24 hours later. Commented Aug 22, 2018 at 22:50
-
@PhillipHamnett-EOS42 do you have a reference that state that the contract pays for all except the initial transaction? Basically you are saying that a contract with inline actions need CPU and NET staked to function, right? Commented Aug 27, 2018 at 0:07
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.
-
Right, so your answer is that USER or CONTRACT always pays for CPU/band? User does, right? I understand that you can decide who pays the RAM cost...– AlexCommented Aug 10, 2018 at 17:07
eosio::transaction::send()
not paying for CPU in deferred transactions? or is that just ram