The Ethereum transaction is it really transaction?

ColnagoriderColnagorider Member Posts: 6
It was more then 20 years ago when we have bought a new core banking system called BankMaster. It was old Cobol software but with some modern words added by Kindle marketing people. They promised the client-server architecture but in fact BankMaster was loading the Cobol code from the server and then run it on users personal computers. It was ok but what we’ve discovered later when have paid all the money and migrated the current general ledger to the BankMaster one was shocking - BankMaster did non support transactions. In the BM database by the end of the day we always have had several single side postings - debit or credit of one account without corresponding credit or debit of another one. Due to this nice feature our support team were spending all nights to clean up the mess before it was became possible to run a close of day procedure.
It was the glorious past and we almost forgot about it but now when we are doing project using Ethereum it looks like the past is not going to leave us alone. Ethereum is cryptocurrency (Ether) and virtual machine (EVM) for running smart contracts - the small programs linked to cryptocurrency accounts. There are two types of account in Ethereum - a personal accounts and a smart contract control accounts, and we can transfer values in Ether between them using secured messages. The messages are changing state of the Ethereum World and recored in transactions, transactions make blocks and blocks linked to each other using cryptographic hash function create blockchain. Nice and simple but not in reality. Each transaction in the Ethereum blockchain must be originated by a message from personal account but can trigger smart contract execution at EVM that can be resulted in other messages invocation targeting personal or contract accounts. The first question - can we see all messages transferring Ether in transaction history (blockchain)? The simple answer - no, we can’t. We can see only the first message that has originated transaction with value in Ether that the sender has send to destination account. The more complicated answer - yes, we can do it with the help of some smart guys who know how to record these internal messages during the EVM execution and show them to public. So, we can easily see first message as transaction in transaction history but it’s difficult to search and see all other messages originated by this first one. The second question - if some internal message inside our transaction is failed to execute does it mean that the whole transaction must be reversed? The simple answer and more obvious one - yes, it must be this way because it’s nature of a transaction. But here we are facing the BankMaster legacy - Ethereum allows a single side posting in complex transactions. It’s possible to debit one account sending money to an another one but never receive value on the destination account due to some problem in the intermediate smart contracts. Let’s have example. Suppose we have personal account P1 that sending Ξ 1.000 to account C1 - contract account and in the same message ask to send the same amount to account C2. Unfortunately smart contract of the C2 has some bug and did not managed to accept the payment and as the result we hang our funds at C1 account but in blockchain everything looks like the transfer is completed and funds are transferred from P1 to C2.
accounts
P1 C1 C2
-------------- ---------------- -----------------
dr cr dr cr dr cr
-----------------------------------------------------------------------
(a) intention Ξ 1.000 — Ξ 1.000 — Ξ 1.000 Ξ 1.000

(b) reality Ξ 1.000 — Ξ 1.000

(c) history Ξ 1.000 — ? Ξ 1.000 ?
-----------------------------------------------------------------------

There is the Solidity code for the two contracts. The C1 account has regaMember contract and in our example we are using send2Pool message, sending Ξ 1.000 to the pool account C2 with regaPool contract:

/* C1 account contract */
contract regaMember {
bytes32 public firstname;
bytes32 public lastname;
bool public authorized;
rega public regaAuth;
regaPool public regaMain;
function ask4Authorization() public constant;
function grandAuthorization(address _rega) public;
function send2Pool(uint _amount) {
address myAddress = this;
if(!authorized || regaMain == address(0) ||
myAddress.balance < _amount)
throw;
regaMain.send(_amount);
}
}
/ * C2 account contract */
contract regaPool {
struct poolMember {
address member;
uint balance;
}
rega public creator;
bytes32 public name;
poolMember[] public poolMembers;
function() { poolMembers.push(poolMember({member:msg.sender,
balance:msg.value}));
}
}

In my personal account in the test Ethereum node (P1) I have about Ξ 58.000 and in my call to regaMember account I’ve set the gasPrice to 20 gWei and gas limit to 5,000,000. There is screenshot for the latest block # 3211 and block # 3202 with our transaction (see below). It’s number 2 in the block transaction list (transactions). It transfers Ξ 1.000 from my personal account to C1 account and it’s also calling send2Pool method that should send the Ξ 1.000 to C2 (pool account). Now we can look at the balances. The first one is balance of my personal account (P1), the second one is C1 (regaMember) account and the last one is regaPool C2 account.

Welcome to the past, guys! Now I need good tool to search Ethereum blockchain for single side postings or there is some hidden switch to make my node transaction friendly?
-----------------------------------------------------------------------------------------------------------------------
th.getBlock('latest');
{
difficulty: 476079,
extraData: "0xd883010302844765746887676f312e352e318664617277696e",
gasLimit: 5928722,
gasUsed: 0,
hash: "0xbb03d3a3a1e0163638b18e47cfa28c0fd26459abeb98c33fecec0dcd196dfed5",
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
miner: "0x580263798ccf642cd300c762db381a26514d0a37",
nonce: "0x52c693a1e55c42d4",
number: 3211,
parentHash: "0xc86ebb266aa8f47179f94b4e9dd45abe8c4cd2e9c6ed474de9beefdfca158d10",
receiptRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: 538,
stateRoot: "0x11d7f20622a4afc48d76e28ff81eee2fe3f1136af7fee3ec6a73dd75c8b9941d",
timestamp: 1458404420,
totalDifficulty: 919709827,
transactions: [],
transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
uncles: []
}
> eth.getBlock(3202);
{
difficulty: 475383,
extraData: "0xd883010302844765746887676f312e352e318664617277696e",
gasLimit: 5980567,
gasUsed: 345283,
hash: "0xef7acb2d9a7e54e693f481b8a743bc874ce8bfcf75cfd09bd37c30d962c7203f",
logsBloom: "0x00000000000000000000000000010000000000000000000000000080000000010010000000000000000000000000000000000000000000000000000000000080000000000000000000008000000040000020000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000008400000000000000000000000000000000000000000004000000000000000000000000000080000000000000000000020000000000000000000000000000000000000000000000000000000000000040000040000000010000000000000002000000000000002000008000000000000000000000000200000000000000",
miner: "0x580263798ccf642cd300c762db381a26514d0a37",
nonce: "0x7b28abc8c779a383",
number: 3202,
parentHash: "0x248e245e0113114cdb1dd0dc4d66d88fafa6bd6961570fa553076fcb740714b6",
receiptRoot: "0xf2afcf48cd163f921e4d79e417e7914021d2854ae60dc1ac78a4092e9caccb1e",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: 796,
stateRoot: "0x4263f4305c7e26fe5d0398e11529d8b83e48f95d2c4f61cbeb405d54fd399e70",
timestamp: 1458393516,
totalDifficulty: 915429756,
transactions: ["0x5967aa6b4ef1cfe3fb46a96f8d2101fafed303a5b191f5618aaa060c5b077d6e", "0xc61b327fda897f41658c0dc2a61ed62ece0725f3d272a9540a39fe817d3101c2"],
transactionsRoot: "0xf3ec7ad5dbffc93120d9eb8deb9d92842344604490962832202f6577d96e0698",
uncles: []
}
> eth.getTransaction("0xc61b327fda897f41658c0dc2a61ed62ece0725f3d272a9540a39fe817d3101c2");
{
blockHash: "0xef7acb2d9a7e54e693f481b8a743bc874ce8bfcf75cfd09bd37c30d962c7203f",
blockNumber: 3202,
from: "0x08c35179d0df4a58c77cb91aaa489f4d73fd3ef6",
gas: 5000000,
gasPrice: 20000000000,
hash: "0xc61b327fda897f41658c0dc2a61ed62ece0725f3d272a9540a39fe817d3101c2",
input: "0x0d955ab60000000000000000000000000000000000000000000000000de0b6b3a7640000",
nonce: 24,
to: "0x4522e0fd421bd75abe5e9815abafba905f4b7b7c",
transactionIndex: 1,
value: 1000000000000000000
}
> eth.getBalance("0x08c35179d0df4a58c77cb91aaa489f4d73fd3ef6");
58483025940000000030
> eth.getBalance("0x4522e0fd421bd75abe5e9815abafba905f4b7b7c");
1100000000000000100
> eth.getBalance(_regaPool.address);
0
>

Comments

  • MilkyWayzMilkyWayz Member Posts: 15
    Hello,
    For your first question, as per my knowledge, you can see the "internal transactions" of a Smart Contract quite easily under EtherCamp or EtherScan for example:
    https://live.ether.camp/account/7D56485e026D5D3881F778E99969D2b1F90c50aF
    http://etherscan.io/address/0x7D56485e026D5D3881F778E99969D2b1F90c50aF#internaltx

    But there is no tool (yet) allowing you to have an "End-to-End" view (from P1 -> C1 -> C2 -> P2).

    Cheers,
  • t9bt9b Member Posts: 3
    From your long description, I think you are possibly trying to use Ether as a unit of value in the same sense as Bitcoin, and in that context you getting your concepts mixed up. I would consider ether not as the unit of value to be transferred, but the means to pay for calling a piece of code.

    If, on the other hand you are wanting to build a system which transfers units of value, this should be better carried out with tokens. The reason why this is a better solution is that firstly, the code needs to be built to explicitly provide a state at all times for both sides of the token transfers, (and rigorously tested) and secondly the blockchain provides an auditable state of all addresses that have tokens assigned to them at all times, and is therefore not subject to the "missing" ether scenario that you describe.

    In other words the token's code performs the transaction not the fact of sending ether.
  • ColnagoriderColnagorider Member Posts: 6
    About blockchain viewers, I know it's possible to see internal transactions but only on the live or test network. What about my local node that I am using for development, is it any tool to trace contact calls that are transferring values ?
  • ColnagoriderColnagorider Member Posts: 6
    Tokens subject. The whole idea behind the fin service on smart contract is that we are selling to customers transparency and security. Nobody can move the money from one account to another one outside of rules of smart contracts. If we have some accounts with real money and tokens as transaction instrument I don't understand how we can guaranty integrity of such system. Tokens will be generated by issuer and then can be transferred by issuer to any storage address. May be I don't understand the idea but for me it does not solve the transaction problem (moving tokens from one location in storage to another one) but introduce the new one : Wei - token integraty and transparency.
Sign In or Register to comment.