While playing a game on Dapp if we want the user to donate some tokens in order to join the game, how can we accomplish it in the smart contract?
2 Answers
You would add a transfer command to your token's contract as can be seen here. There is also a simple token contract example here if you don't need all the bells and whistles.
.hpp
void transfer( account_name from,
account_name to,
asset quantity,
string memo );
.cpp
void token::transfer( account_name from,
account_name to,
asset quantity,
string memo )
{
eosio_assert( from != to, "cannot transfer to self" );
require_auth( from );
eosio_assert( is_account( to ), "to account does not exist");
auto sym = quantity.symbol.name();
stats statstable( _self, sym );
const auto& st = statstable.get( sym );
require_recipient( from );
require_recipient( to );
eosio_assert( quantity.is_valid(), "invalid quantity" );
eosio_assert( quantity.amount > 0, "must transfer positive quantity" );
eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" );
sub_balance( from, quantity );
add_balance( to, quantity, from );
}
Then you would make an RPC API call using eosjs + wallet provider of choice (scatter) to broadcast the transaction as a part of the logic to join the game.
You can see how I'm doing this in my EOS Chess application here.
class Scatter {
constructor() {
this.CHAIN_PROTOCOL = 'http';
this.CHAIN_HOST = '127.0.0.1'; //'mainnet.eoscalgary.io' //'nodes.get-scatter.com' //'br.eosrio.io'
this.CHAIN_PORT = '8888' //8080' //80
// const CHAIN_ADDRESS = CHAIN_PROTOCOL + '://' + CHAIN_HOST + ':' + CHAIN_PORT;
this.CHAIN_ID = 'cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f';
/* Eos and Scatter Setup */
this.network = {
protocol: this.CHAIN_PROTOCOL,
blockchain: 'eos',
host: this.CHAIN_HOST,
port: this.CHAIN_PORT,
chainId: this.CHAIN_ID,
broadcast: true,
sign: true
}
document.addEventListener('scatterLoaded', function() {
this.scatter = window.scatter
window.scatter = null // very important to null out
document.getElementById("scatterLogout").addEventListener('click', function() {
this.scatter.forgetIdentity().catch(error => {
alert(error)
});
alert("logged out of scatter");
}.bind(this))
document.getElementById("scatterLogin").addEventListener('click', function(event) {
let getIdentity = () => {
this.scatter.getIdentity({accounts:[this.network]}).then(identity => {
console.log(identity, "identitySuccess")
}).catch(error => {
console.log(error, "identityCrisis")
})
}
getIdentity()
}.bind(this));
}.bind(this))
}
}
You can also see a more polished example in MonsterEOS's index.js.
The question is a little outdated but still not answered. You do not need to create your own token. To handle any transfers to contract you need to write some handler method with the exact signature:
[[eosio::on_notify("eosio.token:transfer")]]
void transfer( account_name from,
account_name to,
asset quantity,
string memo );
And do not forget to annotate with the appropriate on_notify annotation where one parameters consists of two parts: token contract name and method. With a handler from the example, if somebody transfers eosio.token to your contract, token will invoke the notification and you can handle this action.