Armando una Blockchain (13)

Published on Author lopezLeave a comment

Anterior Post
Siguiente Post

Una parte importande de una blockchain a la Ethereum, es la ejecución de transacciones de transferencias. Cada cuenta tiene una dirección pública y un estado de cuenta conteniendo su balanca. Los estados de cuenta se almacenan en tries inmutables. Esta semana estuve trabajando en mi proyecto personal de blockchain, escrito en JavaScript/NodeJS:

https://github.com/ajlopez/SimpleBlockchain

para ejecutar una transferencia entre cuentas. Como es habitual, lo codifiqué siguiendo el flujo de trabajo de TDD (Test-Driven Development). Mi primer test:

exports['execute transfer'] = function (test) {
    var from = utils.hash();
    var to = utils.hash();
    var value = 1000;

    var states = tries.states().put(from, { balance: 3000 });

    var tx = transactions.transfer(from, to, value);
    
    test.ok(tx);
    test.equal(tx.from, from);
    test.equal(tx.to, to);
    test.equal(tx.value, value);
    
    var newstates = transactions.execute(tx, states);

    test.ok(newstates);
    
    var oldfromstate = states.get(tx.from);
    
    test.ok(oldfromstate);
    test.equal(oldfromstate.balance, 3000);
    
    var oldtostate = states.get(tx.to);
    
    test.ok(oldtostate);
    test.equal(oldtostate.balance, 0);
    
    var newtostate = newstates.get(tx.to);
    
    test.ok(newtostate);
    test.equal(newtostate.balance, 1000);
    
    var newfromstate = newstates.get(tx.from);
    
    test.ok(newfromstate);
    test.equal(newfromstate.balance, 2000);
}

Luego de la ejecución de una transacción, un nuevo trie de estados de cuenta se arma y se devuelve. Pero también hay que rechazar las transferencias que no tienen fondos:

exports['execute transfer without funds'] = function (test) {
    var from = utils.hash();
    var to = utils.hash();
    var value = 1000;

    var states = tries.states();

    var tx = transactions.transfer(from, to, value);
    
    test.ok(tx);
    test.equal(tx.from, from);
    test.equal(tx.to, to);
    test.equal(tx.value, value);
    
    var newstates = transactions.execute(tx, states);

    test.equal(newstates, null);
    
    var oldfromstate = states.get(tx.from);
    
    test.ok(oldfromstate);
    test.equal(oldfromstate.balance, 0);
    
    var oldtostate = states.get(tx.to);
    
    test.ok(oldtostate);
    test.equal(oldtostate.balance, 0);
}

Para cumplir con esos tests, mi implementación actual, simple, es:

function execute(tx, states) {
    var fromstate = states.get(tx.from);
    var tostate = states.get(tx.to);

    fromstate.balance -= tx.value;
    
    if (fromstate.balance < 0)
        return null;
        
    tostate.balance += tx.value;
    
    return states.put(tx.from, fromstate).put(tx.to, tostate);
}

Próximos posts: ejecutando bloques con transacciones, almacenando permanentemente los tries de estados, smart contracts, etc…

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Leave a Reply

Your email address will not be published. Required fields are marked *