3

This contract should return the sender's address:

contract SimpleExample {
    function getSender() constant returns (address) {
        return msg.sender;
    }
}

The following Javascript calls that contract:

var abi = [{"constant":true,"inputs":[],"name":"getSender","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]
var MyContract = web3.eth.contract(abi);
var myContractInstance = MyContract.at('0x46E286cb00c5e7D5949D18e767447E513d001BBA');

myContractInstance.getSender.call(function(error, result){
    if(!error) {
        console.log("##" + result + "##")
    } else {
        console.error("Error:" + error);
    }
})

Instead of returning the sender's address, it returns 0x0000000000000000000000000000000000000000.

  • .call doesn't create a transaction. It calls the function locally on the client. There is no msg – libertylocked Sep 4 '17 at 21:19
  • Your getSender is a constant function. By default web3 will not craft a transaction to call a constant function. You either remove the constant keyword, or you call .getSender.sendTransaction to force web3 to send a tx. Also, you still won't get the return value from a tx receipt. You will only see event logs if you have any – libertylocked Sep 4 '17 at 21:31
  • The same problem happens if I call the function like this: "myContractInstance.getSender(function(error, result){" Many solidity examples use the msg.sender value in their sample functions which do not create transactions, but just get data. For example, they suggest that the function's constructor stores the msg.sender value in a global 'creator' variable, which also does not appear to work because when I then attempt to get the 'creator' variable in a separate function it returns 0x0. – Tester Sep 4 '17 at 21:35
  • Functions return value are not shown in the tx receipt. It's meant for contracts. Use events if you want data to show up in the tx receipt. – libertylocked Sep 4 '17 at 21:39
  • If you want to access a storage variable, make it public then get it like myContractInstance.creator() – libertylocked Sep 4 '17 at 21:40
3

Currently there are 3 ways to "call" a contract function in web3.

  • You can call it with myContractInstance.foo.call(), which web3 will execute the contract code locally (since the bytecode is visible to all blockchain participants). It returns you the return value by running the function locally. It won't craft a tx, won't submit anything to the network. There is no message.
  • You can call it with myContractInstance.foo.sendTransaction(), which web3 will send a tx to call the function. It returns you a tx hash. You will have to pay for gas, wait for the tx to be mined, then you get your tx receipt. Note that this way you won't get the return value of the function, because they aren't included in the tx receipt. However logs are in the tx receipt.
  • You can just call with myContractInstance.foo(). If your function is constant, then web3 will use .call. If it's not constant, it will use .sendTransaction

For the example to work in a web3 client, you need to

  • Make the function non-constant
    • Because otherwise web3 would not send a transaction to call this function. (Although you can force it with .sendTransaction)
  • Make the function log an event
    • Because function return values are not shown in the tx receipt. Only logs are. Return values are meant for contracts, and you can also use them in constant functions if you .call in your client. (You can't do it here, if you .call then there won't be a msg)

Modified example

contract SimpleExample {
    event LogSender(address sender);
    function getSender() returns (address) {
        LogSender(msg.sender);
        return msg.sender;
    }
}

Now in web3 you would call it like

// replace from with the account you want to send the tx from
const txHash = myContractInstance.getSender({ from: "xxxxxxxx" });
// once the tx has been mined, get the tx receipt
web3.eth.getTransactionReceipt(txHash, (err, receipt) => {
    console.log(receipt.logs[0].args.sender); // you will see sender address here
}

If you just want to get the creator of the contract without spending any gas, it's pretty simple.

You make a state variable called owner, make it public. Set the owner in the constructor.

contract SimpleExample {
    address public owner;
    function SimpleExample() {
        owner = msg.sender;
    }
}

Solidity automatically creates constant getter functions for public state variables. (Although you can also do it explicitly)

Because contract storage, along with the bytecode, is also visible to all participants. In web3 you can get the owner like

const ownerAddress = myContractInstance.owner()

Which in this case since the getter is constant, is equivalent to

const ownerAddress = myContractInstance.owner.call()
  • I made the function non-constant, and it still did not return the msg.sender. How can I utilize the msg.sender value in a non-transaction function? I wish to get data without paying gas, and I only want that function accessible to the creator. If a non-transaction function can't return the msg.sender value, how can it utilize it within the function's logic? – Tester Sep 4 '17 at 21:58
  • You use contract storage to store the owner address – libertylocked Sep 4 '17 at 22:14
  • I want to compare the owner's address to the current user's address. If a non-transaction function can't return the msg.sender value, how can it utilize it within the function's logic (to compare the owner address to the current user's address)? – Tester Sep 4 '17 at 22:22
  • Can't you just do myContractInstance.owner() === userAddress? You can get user's accounts in web3.eth.accounts. – libertylocked Sep 4 '17 at 22:25
  • What is the specific contract method that returns the address of the person that called a non-transaction function? This needs to be accessible from within the contract (not from JS), because that is where the logic needs to compare to the owner's address.. – Tester Sep 4 '17 at 22:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.