I just started to learn Solidity as a personal challenge. I'm not a developer so I've a loooooong way to go.
I'm following the Ethereum.org tutorial, here is what I've got doubt about: What does [msg.sender] stand for? I guess it is the wallet address of who triggered the contract, but I'm not sure.
msg.sender (address): sender of the message (current call)
msg.sender will be the person who's currently connecting with the contract.
Later on, you'll probably deal with contracts connecting with contracts. In that case, the contract that is creating the call would be the msg.sender.
Check out the documentation here: https://docs.soliditylang.org/en/develop/units-and-global-variables.html#block-and-transaction-properties
Let's make it very simple.
There are two types of accounts in the Ethereum Chain
1). Externally Owned Accounts(EOA) [Person]
2). Contracts Accounts [Contracts on Chain]
Both accounts have their addresses.
Now, look at an example.
Wallet address of personA (EOA) is
0x0cE446987406E92DF41614C46F1d6df9Cc925847.
Contract Address of Math.sol is
0x0cE446987406E92DF41614C46F1d6df9Cc753869 and
Math.sol contains ContractA
Contract Address of Addition.sol is
0x0cE446987406E92DF41614C46F1d6df9Cc357241 and
Addition.sol contains ContractB
Here, one of the functions of ContractB is called from ContractA.
So, whenever personA calls any functions of ContractA.
In this scenario, if you print or get `msg.sender` and `tx.origin` inside function of `ContractB` then the result would be like this
msg.sender = `0x0cE446987406E92DF41614C46F1d6df9Cc753869` // You will get address of `ContractA`
tx.origin = `0x0cE446987406E92DF41614C46F1d6df9Cc925847` // personA's (EOA) Wallet Address
Here,
msg.sender (address): means sender of the message (current call)
on the other hand
address owner = msg.sender;
The msg.sender is the address that has called or initiated a function or created a transaction. Now, this address could be of a contract or even a person like you and me.
That's why you may use msg.sender instead of msg.sender()
Related
i had a small question that i creast a contract A and there is 1 busd token in the contract A, now i want to transfer the 1 busd out of contract by owner address
how to set the contractA?
i have use this code to deploy and test
pragma solidity ^0.8;
interface IERC20 {
function transfer(address to, uint256 amount) external returns (bool);
}
contract MyContract {
address owner = 0xFAD69bCefb704c1803A9Bf8f04BC314E78838F88;
function withdrawToken(address tokenContract, uint256 amount) external {
// send `amount` of tokens
// from the balance of this contract
// to the `owner` address
IERC20(tokenContract).transfer(owner, amount);
}
}
the feedback is
This contract may be abstract, it may not implement an abstract parent's methods completely or it may not invoke an inherited contract's constructor correctly.
can someone help me? thanks in advance , i am beginner.
find a way to transfer the busd out of contract .
I recognize this code from my other answer. :)
You're trying to deploy the IERC20 interface - which throws the "This contract may be abstract" error.
You need to deploy the other contract. Depending on how you deploy the contract, there are different ways to do that.
Here's another answer that shows how to select the desired contract in Remix IDE. However, note that this code won't work on the Remix emulated network, as the BUSD contract is not available there. You'll need to deploy the code either to the mainnet or your local fork of the mainnet, where the BUSD contract is available.
I'm trying to understand what this lines of BEP20 code mean, it is written in solidity
constructor () {
_rOwned[owner()] = _rTotal;
IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(0x10ED43C718714eb63d5aA57B78B54704E256024E);
uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory())
.createPair(address(this), _uniswapV2Router.WETH());
uniswapV2Router = _uniswapV2Router;
_isExcludedFromFee[owner()] = true;
_isExcludedFromFee[address(this)] = true;
emit Transfer(address(0), owner(), _tTotal);
In the first lines, he instanciate UniswapV2Router pointing the address router to PancakeSwap. This because, he want to create a liquidity pool with his TOKEN and BNB, indeed after this instanciating operation he call createPair() that allows him to create this pair between his smart contract and the address WETH().
IMPORTANT: WETH() is a function that provider the chain native wrapped coin address where smart contract was deployed. For example: If I create a pair instanciating Uniswap router on Ethereum blockchain then WETH() will return address about WETH (Wrapping Ether) address present into Etheruem. On the contrary if I instanciate Uniswap Router with its address present into binance smart chain (and so I refers to Pancakeswap in this case), the value of WETH() will be WBNB address.
After this lines of code, I assume that he excluded from paying a fee for only transactions the owner() address (who deployed the smart contract for the first time) and smart contract itself.
Finally he emitted a Transfer event passing : address(0) (0x0000000000000000000000000000000000000000), owner() and total supply.
More information about pair on documentation.
// create the fllow to transform the ownership of the nft
//from the item owner(seller) to the contract that will transact to the buyer
IERC721(nftcontract).transferFrom(msg.sender,address(this),tokenId);
//after the marketitem is created
//the market item creation is an event executed by this contract so we must emit it so that the details of the market item will be listned to or used
emit MarketItemcreated(
ItemId,
nftcontract,//the nft because the nft contract address means the nft created
tokenId,
msg.sender,//seller is the msg.sender // we don't do payable because we emit only the details of the cretaedmarketid (what the market id contain)
address(0),//no one yet own this nft
price,
false//not yet solde
);
}
i'am facing the problem in msg.sender and adress 0 i don't know where is the problem
I think the issue is you are not modified the function as payable. You are not showing the full code, I think the code that you posted is inside a function and this function has to be marked as payable. if this is not the case, share the full function code please. A common mistake is not to wrap msg.sender with payable(msg.sender). because since solidity 0.6.0 msg.sender is not payable any more.
I have a erc20 token and in another contract I want to create a token swap function.
So very easily, one send a usdc token and swap my erc20 token in 1:1 ratio.
Problem is how to approve to spend my erc20 token. I tried several times but can't find a way.
interface IERC20 {...}
contract AnotherContract {
function approve(address _spender, uint256 _amount) public returns(bool) {
return IERC20(MyToken).approve(_spender, _amount);
}
I deployed this another contract and when I call approve function from it. So When I set '_spender' to this contract address. The result is weird. So this contract is owner and spender both.. As I think a user should be as a owner and this contract should be a spender. But function calling from onchain. the msg.sender is going to be this contract address self.
I don't understand and am confusing. anybody knows or have some rescoures? Thank you.
When your AnotherContract executes the approve() function in MyToken, the msg.sender in MyToken is AnotherContract - not the original transaction sender.
Which effectively approves AnotherContract's tokens to be spent by _spender.
Unless the MyToken has a way to delegate the approval (e.g. by using a deprecated tx.origin instead of msg.sender, which introdues a security flaw), the user will have to execute the approval manually, and not through your external contract.
Many ERC-20 implementations use this approach for security purposes. For example to prevent a situation, where a scammer would persuade a user to execute their malicious function, because the user would think they are getting an airdrop.
// function name suggests that the caller is going to receive an airdrop
function claimAirdrop() external {
/*
* fortunately, this won't work
* and the tx sender can't approve the scammer to spend their tokens this way
*/
USDTcontract.approve(scammer, 1000000);
}
I want to create a viewable function (needs to return a string to the user) that searches a mapping for msg.sender and if the senders value is x, I want the contract to proceed accordingly. It all does work inside remix but if I upload it to ropsten, it doesn't anymore. Is this a known issue? I have tried tx.origin as well, same result.
That's the problematic code I tried:
function getLink() public view returns(string){
if(tokenBalances[msg.sender]>0){
return link;
}else{
return "You need to purchase a token at first...";
}
}
EDIT: I think the problem is, that when using a viewable function there is no msg.sender because there is no actual transaction? Is there a way to return a value to the user without using the "view" functions?
Short answer
msg.sender does work in a view function, although it is useless as an authorization scheme. The lookup tool you use should have a mechanism to set the sender.
Call vs Transaction
First, it's important to understand the difference between a call and a transaction.
It appears you're running a call, which runs quickly and does not alter the state of the blockchain. msg.sender is set in both a transaction and a call. In a transaction, it cannot be faked: you must have the private key associated with the given account. But in a call, you are free to set the sender to any value you like.
Setting the Sender
How you set the sender depends on what tool you are using to call. That tool might be web3.js, web3.py, Mist, MyEtherWallet, MyCrypto, etc. They all have (or might not have!) a mechanism to set the sender in a call.
MyEtherWallet
In the comments, you mention MyEtherWallet specifically. In a quick search, I didn't find anything about how to set the sender. There is this unanswered question on ethereum.stackexchange that seems worth following, since it is asking roughly the same question: How to check msg.sender balance with MyEtherWallet contract
Contract Workarounds
is it possible to specify such settings for the contract?
There is no way to help someone set the sender from inside the contract. But you can supply a different method that takes an address as an argument. Then tools like MyEtherWallet will allow you to set the address of interest. For example:
function getLink(address account) public view returns(string){
if(tokenBalances[account] > 0){
return link;
}else{
return "You need to purchase a token at first...";
}
}
Hiding Data
It's worth noting that hiding data by checking msg.sender is useless. Anyone can set a fake sender in a call (or directly inspect blockchain state). So, it's trivial to bypass this "protection."