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()
.call
doesn't create a transaction. It calls the function locally on the client. There is nomsg
getSender
is a constant function. By default web3 will not craft a transaction to call a constant function. You either remove theconstant
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 anypublic
then get it likemyContractInstance.creator()