Since creating a smart contract with Ethereum involves the user of ether, refilling all of the users' ethers becomes costly for a company. So let's say a company decide to issue a token over the ethereum network, and that token represents a new currency. Can the original creator of the token receive transaction fees everytime each user send tokens to someone else? That way the company could easily refill everyone's token's with ether.
You can't receive Ether paid for gas spent on that transaction, it all goes to the miner of current block.
But you can add support for that fee into your token contract. For example you can require to send some Ether with each token transfer, and then automatically send that Ether value into Token contract itself, or send to some other address.
Something like that:
function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
// accept fees
if (msg.value < FEE) {
return false;
}
if (!MYADDR.send(msg.value) {
throw;
}
// do token transfer (WARNING, no validation here, don't use, it's for current example only)
balances[_to] += _value;
balances[_from] -= _value;
return true;
}
If you look at the problem as a whole, every user should spend some ether (as fees) to perform any transaction. If you are planning to fill the users accounts' with ether paid by users, the net sum is zero (looking at all users as an entity and company as another entity). So, either you have to fill the users accounts with ether from your pocket or Users have to burn their own pockets to make transactions (transfer tokens etc.)
Related
I'm trying to transfer ether from an Account 1 to an Account 2. This is the code:
function pay(address _from, uint256 _tokenId) external payable noReentrant {
uint256 balance = msg.sender.balance;
require(balance > 0.011 ether, "There is not enough eth");
payable(__ADDRESS2__).transfer(0.001 ether);
}
receive() external payable {
}
fallback() external payable {
}
So here the msg.sender is Account 1 and this account wants to transfer eth to Account 2. Both accounts have ethers but it's throwing this error:
Error: Transaction reverted: function call failed to execute
I'm using hardhat to test this function. So I have a couple of doubts:
Is this the correct way to transfer tokens from Account 1 to 2? And here I'm not talking about transfering eth from Account 1 to address of the contract.
If it is, then, what's wrong with it?
First of all, the code you presented trasnfers ether from the contract to ADDRESS2, so the transaction probably reverts because the contract doesn't have enough ether. You should've checked that the caller sends you enough ether to transfer, i.e require(msg.value >= 0.001 ether).
Concerning the last two questions:
No, this code illustrates ether transfers. If you want to transfer ERC20 tokens, the OZ library would be a good start.
The reason it reverts is explained above. Sending ether is very different from sending ERC20 (or any other) tokens, consider checking the OpenZeppelin library.
I want to create a smart contract which people can transfer tokens without ether in their wallet.
Suppose A want to transfer ERC20 tokens to B, but he does not have ether in his wallet.
Does third party C can send the transaction for A and therefore pay the gas? Is it possible to create a function in the contract for this usgae?
I have searched online for a soloution and could not find one.
This is a key issue of Ethereum dApp development, but also of tokens. Here is a very old thread on Ethereum Stack Exchange, and also this one.
There are 2 options with their pros and cons:
Use signatures
Every function in your smart contract must have signature parameter.
People who want to interact with the smart contract must sign the function parameters with their account's private key and send it to the smart contract owner (via any communication channel).
The owner then submits the parameters along with the signature to the blockchain, paying for gas. The signature guarantees that the message was approved by the user.
Refund used gas at the end of the transaction. A modifier refundGasCost can be used for this (see below).
But (1) is really hard to apply to token transfers where you just don't know who uses the token and (2) does not really address the issue.
There is a lot happening recently, there is this blog post about How to save your Ethereum Dapp users from paying gas for transactions, and since you ask about tokens, there is an ERC that suggests to Pay transfers in tokens instead of gas, in one transaction which would be nice if you have tokens but no ETH.
I hope this helps.
Exactly this case is already defined in the ERC20 standard. Its this function:
function transferFrom(address from, address to, uint tokens) public returns (bool success);
But before party C could use it and send tokens from A to B, A would have to approve C to do this via the following function, which is also defined in the ERC20 standard:
function approve(address spender, uint tokens) public returns (bool success);
No, in a standard ERC20 token contract, the token holder must initiate at least one transaction (to call transfer() or approve()), and a transaction must always be paid for by its initiator.
Right now I am working on a smart contract with which, people are able to gamble. I want to introduce a small fee, a user has to pay every time they send ether to the smart contracts address.
The fee should be automatically sent from the smart contract to my private ether wallet whenever someone starts a new game (sends ether to the contract)
since I am new to solidity and blockchain coding, any help is much appreciated
Just transfer the amount you want (your fee) to your address.
i.e.
uint256 yourFee = msg.value * percentFee;
yourAdress.transfer(yourFee);
Don't forget to make the function payable.
I'm trying to develop a set of contracts in where an ERC721 token is auctioned off, then the winner gets the token placed into their wallet. I'm not entirely sure how to structure this. These are the contracts I was thinking would be needed.
WALLET
Contains the mapping of addresses to tokens owned
Upon deployment, creates deploys an AuctionFactory contract and saves the address
AUCTIONFACTORY
Deploys an Auction contract upon command, with the item being the ERC721 token specified
AUCTION
Contains all the logic for an auction
Inherits from Wallet, allowing manipulation of the mapping state variable found in the contract, placing ERC721 tokens won into the winners wallet
The problem is that Auction can't inherit from Wallet. The compiler will throw an error when AuctionFactory tries to deploy an auction - cannot create instance of derived or same contract. And that makes sense to me, since Wallet deploys the factory, and if the factory deploys an Auction that inherits from Wallet, it's technically deploying its parent contract.
So my question is, how can I structure this set of contracts? How can I allow an instance of an auction contract to communicate and manipulate with a store on another contract?
Here is an example contract which can deposit tokens and then auction them off. This is a basic auction model which shows the control flow for transferring possession of the token.
Here is the setup. First we have to import the ERC-721 headers. I am using the reference implementation for ERC-721 for this:
pragma solidity 0.5.1;
import "https://github.com/0xcert/ethereum-erc721/src/contracts/tokens/erc721.sol";
import "https://github.com/0xcert/ethereum-erc721/src/contracts/tokens/erc721-token-receiver.sol";
Here is the contract and the main data structure:
// This implements an ERC-721 auction by taking ownership of tokens
contract CollectableAuction is ERC721TokenReceiver {
mapping (uint256 => AuctionDetails) auctionDetails;
struct AuctionDetails {
ERC721 nftContract;
bool bidIsComplete;
address seller;
address winningBidder;
uint256 tokenId;
}
}
We add in the deposit mechanism. This works by allowing people to send tokens directly to the auction contract. You may implement a different mechanism to start auctions, but this one works just as well.
// Deposit an asset and start an auction
function onERC721Received(
address,
address from,
uint256 tokenId,
bytes calldata
)
external
returns(bytes4)
{
uint256 auctionId = uint256(keccak256(abi.encode(uint256(msg.sender), tokenId)));
auctionDetails[auctionId] = AuctionDetails({
nftContract: ERC721(msg.sender),
bidIsComplete: false,
seller: from,
winningBidder: address(0),
tokenId: tokenId
});
return 0x150b7a02;
}
Here is a mock implementation for your auction process. Your actual auction will certainly be more complicated.
function completeAuction(uint256 auctionId) external {
auctionDetails[auctionId].bidIsComplete = true;
}
Lastly, when the auction is done then the winning bidder needs to take the token.
function withdraw(uint256 auctionId) external {
AuctionDetails storage details = auctionDetails[auctionId];
require(details.bidIsComplete);
require(msg.sender == details.winningBidder);
// Collect money from winning bidder
details.nftContract.safeTransferFrom(address(this), details.winningBidder, details.tokenId);
// Send money to seller
// Do event logging
delete auctionDetails[auctionId];
}
The above is a fully-functioning starting point for this project.
I'm not sure why you need to inherit from a Wallet contract. The Auction structure should be something like:
Owner of token X calls a function createAuction from your contract to create an auction
createAuction(tokenId, minPrice, duration) will:
Store the owner address, token id and some other information (minimum price, duration, etc.) into a mapping. You'll probably use your token id as the mapping key.
Use the transferFrom function from your ERC721 contract to transfer the ownership from current owner to the Auction contract itself, something like: erc721.transferFrom(owner, this, tokenId). This is required later when you have to transfer the ownership to the buyer.
A buyer joins the game, and bid on this auction by calling a bidOnAuction(tokenId). Check the parameters (msg.value > minPrice, duration, etc.). And if these are bid winning conditions, then you transfer the money to the seller (owner) and you transfer the token owrnership from your contract to the buyer, again by calling the erc721 method: erc721.transferFrom(this, msg.sender, tokenId).
The Auction contract works as an escrow, it keeps the ERC721 token ownership until the auction is finished (bought or cancelled). You don't have to "manipulate ownership", you only have to let the owner transfer the token to your contract and then, your contract transfer the ownership back to the previous owner if the auction was cancelled or to the buyer if the auction was completed.
This question is a little conceptual, so hopefully this picture will help clear up my misunderstanding.
Image there is a crowdsale smart contract deployed on address 0x2. A User at address 0x01 buys a token.
Here is my understanding of what happens:
The crowdsale contract (# address: 0x2) accepts ether from the user account (# address: 0x1)
The crowdsale contract stores 0x1 as having purchased a token (important: this information is stored in the smart contract #address 0x2)
Now my Question: If 0x1 is a user account (and not a smart contract) there is no code at address 0x1. I thought a user account just consisted of an address + ether associated with the address, how can it also store the fact that 0x1 owns an ERC20 token? For example, I can login to MetaMask and (before clicking the "add token" option) MetaMask can see that I have a token... how is this possible?
Every ERC20 contract has the following function:
function balanceOf(address _owner) public view returns (uint256 balance) {
return balances[_owner];
}
Your wallet just calls this function from the known token contracts with your address. Since it's a view function it doesn't cost any gas.
I recon most ERC20 token get added rather quickly to a wallet like Metamask or MEW. But if your balance doesn't automatically show, you can add the contract address manually (in MEW at least, not sure about Metamask) and it will show up afterwards.
In solidity there are two ways to get the address of the person who sent the transaction
tx.origin
msg.sender
In your example, in the method inside ERC20 Token.sol, the value tx.origin will be 0x1 and msg.sender will be 0x2
So to answer your question, how does the ERC20 token know about 0x2 is: it depends on how the token contract is written and whether it uses tx.origin or msg.sender. I would imagine it uses msg.sender, because that is the more prevalent one.
If it does use msg.sender you can still make the crowdsale contract work by first buying the tokens and then immediatelly transfering the tokens from the crowdsale contract to the caller.
For more information, refer to What's the difference between 'msg.sender' and 'tx.origin'?
how can it also store the fact that 0x1 owns an ERC20 token?
Token transfers, or transfers in accounting in general, are kept in a ledger. In this case, the ledger is ERC-20 smart contract that internally keeps balances who owns and what in its balances mapping. Or, the smart contract manage the storage (EVM SSTORE instructions) where the records of ownership are kept.
Note that some other blockchains, like Telos and EOS (and mayne Solana) might be opposite and there the storage is maintained on the user account (user account has associated RAM and tables for any token user owns).