If I understand your question correctly you want to be able to see who has deposited Eth to your contract address. This is what event logs are for.
(1) Create a contract where there is an event every time there is a transaction. e.g something like:
contract someContract {
address public owner;
// Set the owner of the contract to be the creator of the contract i.e. you
function someContract() {
owner = msg.sender;
}
// This is an event
event DepositMade(address _from, uint value);
event WithdrawalMade(address _to, uint value);
//Catch all function
function() {
// generate an event when someone sends you Eth
if (msg.value > 0)
DepositMade(msg.sender, msg.value);
}
// Only the owner of the site can withdraw Eth
modifier admin { if (msg.sender == owner) _ }
function withdraw(uint amount, address recipient) admin {
if(recipient.send(amount))
WithdrawalMade(msg.sender, msg.value);
else throw;
}
}
The important bits are defining an event type event DepositMade(address _from, uint value)
and generating an event when something happens DepositMade(msg.sender, msg.value);
these events are stored in the event log associated with the address of the deployed contract instance.
(2) You retrieve the events on this contract using rpc eth_newFilter
or web3.eth.filter
e.g something like:
var filter = web3.eth.filter({fromBlock:0, toBlock: 'latest', address: contractAddress, 'topics':['0x' + web3.sha3('DepositMade(hexstring,uint256)')]});
filter.watch(function(error, result) {
if(!error) console.log(result);
})
Here's an intuition. The simplest transaction in Ethereum costs 21000 gas and looks like this:
{from: '0x from', to: '0x to', value: web3.toWei(1, "ether")}
When you're depositing to
the exchange, the exchange can watch for transactions that are sent to
this deposit address. For example, for block 99 they could use web3.eth.getBlock(99, true, ...)
, and for each transaction object check if to
equals the deposit address, and the value
(amount of Ether in wei) that was sent. Relatively straightforward for the exchange to see what you've deposited.
But if you are using a contract to make a deposit, the to
is no longer the deposit address that the exchange gave you. The to
is the address of your contract, and in the transaction there will be an additional data
field. This data
provides instructions to the contract, to execute code, which may then transfer the Ether to the deposit address. The exchange has to also execute the code, if it wants to be sure that it received funds from such execution. (An exchange could use web3.eth.getBalance to monitor balances of deposit addresses, but if it wants to know exactly where the funds came from, it has to execute the code of all transactions.)
That's an overview and to read more, the Ethereum Wiki has links to other material such as the Yellow Paper, and White Paper. Reading this StackExchange for highly voted questions and answers, with tags like transactions and gas is also helpful.
Technically, transactions are only initiated by humans: a contract invoking another contract is a message call
(as defined in the Yellow Paper) not a transaction. Only the transaction is recorded on the blockchain because all further execution can be derived from the transaction.
For why withdrawing from an exchange to a contract wallet/account is not straightforward, it's because more gas is needed than the basic 21000 gas. Different contracts could consume different amounts of gas, and sufficient gas must be provided by the exchange otherwise the transaction does not take effect: the funds remain will remain with the exchange.
Best Answer
Yes, it seems like they are telling you that you've lost it. That really sucks.
Are you sure it has not been credited to your account?
This is not Bitstamp's fault, it's coinexchange.io's fault. coinexchange.io has received the funds, just in a different way from what they are used to. Internal transactions are a unique feature of Ethereum. coinexchange.io knows very well that internal transactions can happen, or at least, they should know if they're working with Ethereum.
In my opinion, they should accept them. Internal transactions are not uncommon or unusual at all.
If I were you, I would send a sternly worded email or support ticket to coinexchange.io, telling them how much money it is, and requesting them to credit it to your account or return it to an address you provide. If they don't reply or tell you they can't do anything, I would escalate and send a certified letter with return receipt requested, and an email confirming the fact that you sent the letter, and the contents of the letter.
Maybe you should threaten legal action, although I don't know how much of a case you have.
If they don't cooperate, you should start complaining publicly on popular Ethereum and cryptocurrency forums, and maybe on Twitter. Try to spread some negative PR about them.
It is unacceptable that funds could be declared 'lost' in this manner, even though they have access to those same funds!
There is no technical reason why coinexchange.io can't credit it to your account and continue running their system as they normally would!
Good luck!