The documentation is skimpy on details and it took me forever to figure out the correct way with the help of your links, anyways, here is what works for me:
Tested on Geth : 1.6.7 -stable , web3.js :0.20.2 Parity/v1.7.2 & Kovan testnet.
I'll be using the minimal token as example :
pragma solidity ^0.4.0;
contract minimalToken {
mapping (address => uint256) public balanceOf;
function minimalToken(uint256 initialSupply) {
balanceOf[msg.sender] = initialSupply;
}
function transfer(address _to, uint256 _value) {
require(balanceOf[msg.sender] >= _value);
require(balanceOf[_to] + _value >= balanceOf[_to]);
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;
}
}
I'll be focusing on the transfer method which takes 2 arguments,( address, amount) to transfer:
var contract = web3.eth.contract(contractABI).at("0x8caaa1f263ff14d0276ff1a1a6ed15c51159d6e0");
var receiverAddress = '0x00Ce6C92856A657979E7728005DBc9acD002Eb09';
var callData = contract.transfer.getData(receiverAddress, 2000);
var gasEstimate = web3.eth.estimateGas({
from: web3.eth.coinbase,
to: "0x8caaa1f263ff14d0276ff1a1a6ed15c51159d6e0",
data: callData
});
var gasPrice = web3.eth.gasPrice;
console.log('gas Price: ' + gasPrice);
console.log('Estimated Transaction gas: ' + gasEstimate);
// gas Price: 21000000000
// Estimated Transaction gas: 34207
One thing that Threw me off, was that I kept on getting transaction errors due to me not including the from: field on the transaction.
Hope this helps.
First and greatest concern is, 'I hope you're NOT going to store chat messages on the blockchain!'
As others have noted, you can wrap this in a struct. Elements less than 32 bytes are packed into storage slots as best they fit. When using a struct however, elements are packed in the order given.
Compound elements like strings will take a minimum of one slot for length which 'may' be packed with the string data if it's short enough, else will write to some hash index elsewhere in memory for at least another slot cost.
All mapping entries will take at least one slot no matter how small their type. It's with mapping that structs really shine as you can force them to pack.
// 6 elements packed into 5 32 byte slots
struct User {
uint40 time; // cast to 5 bytes - packed with user
address user; // 20 bytes - packed with time
address myAddress; 20 bytes - unpacked, one slot
address owner; // 20 bytes - unpacked, one slot
// Strings are 32byte minimum to store length
string message; // 32 bytes minimum to store length
string response; // 32 bytes minimum to store length
}
So with the above we can have something like:
mapping (address => User) public chats;
And this will generate a public accessor function with a signature of:
chats(address _param);
The return value however will be an unnamed array of struct values in the order of the struct elements.
--edit for secondary question---
Here's one way to load up a struct variable. I'm showing it in the context of your code, but the apparent intention of your code does seem to me quite irresponsible.
contract Chat
{
struct User {
uint40 time;
address user;
address myAddress;
address owner;
string message;
string response;
}
User public message;
function Chat(address _uw, address _a, string _m, string _r)
{
message = User ({
user: _uw,
myAddress: _a,
message: _m,
response:_r,
owner: msg.sender,
time: now
});
}
}
Best Answer
When sending a transaction from an EOA (Externally Owned Account) it always has just one destination with one function call. So you would need to send multiple transactions that way, to interact with multiple contracts.
However, contracts don't have such limitations. A contract can do as much stuff as it wants, as long as the gas limits are respected. So you could create a contract function which does all the work and then you simply need to call that one function.
The tricky part here is that when a contract does things instead of your EOA, the
msg.sender
is the contract. This means that if you want to do any token transfers and stuff like that, the contract has to own the tokens. So basically you need to delegate your asset ownership to the contract.Just be careful and remember to implement all required functionality in the contract to handle the assets. If you forget to implement some wanted functionality and you send assets to the contract, you may never be able to get them out of it anymore.