Saturday, March 19, 2016

Back to the past?

Back to the past

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.


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:

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);
}
}
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. It’s number 2 in the block transaction list (transactions). The transaction is below with. 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?








No comments:

Post a Comment